diff options
Diffstat (limited to 'tests/src/com/android/messaging/datamodel/action/ReadWriteDraftMessageActionTest.java')
-rw-r--r-- | tests/src/com/android/messaging/datamodel/action/ReadWriteDraftMessageActionTest.java | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/tests/src/com/android/messaging/datamodel/action/ReadWriteDraftMessageActionTest.java b/tests/src/com/android/messaging/datamodel/action/ReadWriteDraftMessageActionTest.java new file mode 100644 index 0000000..0405c90 --- /dev/null +++ b/tests/src/com/android/messaging/datamodel/action/ReadWriteDraftMessageActionTest.java @@ -0,0 +1,482 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.messaging.datamodel.action; + +import android.content.ContentProvider; +import android.content.pm.ProviderInfo; +import android.database.Cursor; +import android.net.Uri; +import android.test.suitebuilder.annotation.SmallTest; +import android.text.TextUtils; + +import com.android.messaging.BugleTestCase; +import com.android.messaging.FakeContext; +import com.android.messaging.FakeFactory; +import com.android.messaging.datamodel.BugleDatabaseOperations; +import com.android.messaging.datamodel.DataModel; +import com.android.messaging.datamodel.DatabaseHelper; +import com.android.messaging.datamodel.DatabaseHelper.ConversationColumns; +import com.android.messaging.datamodel.DatabaseWrapper; +import com.android.messaging.datamodel.FakeDataModel; +import com.android.messaging.datamodel.MediaScratchFileProvider; +import com.android.messaging.datamodel.MessagingContentProvider; +import com.android.messaging.datamodel.action.ActionTestHelpers.StubActionService; +import com.android.messaging.datamodel.action.ActionTestHelpers.StubActionService.StubActionServiceCallLog; +import com.android.messaging.datamodel.action.ActionTestHelpers.StubConnectivityUtil; +import com.android.messaging.datamodel.action.ReadDraftDataAction.ReadDraftDataActionListener; +import com.android.messaging.datamodel.data.MessageData; +import com.android.messaging.datamodel.data.MessagePartData; +import com.android.messaging.datamodel.data.ParticipantData; +import com.android.messaging.util.ContentType; + +import org.mockito.Mock; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; + +@SmallTest +public class ReadWriteDraftMessageActionTest extends BugleTestCase { + + @Mock ReadDraftDataActionListener mockListener; + + // TODO: Add test cases + // 1. Make sure drafts can include attachments and multiple parts + // 2. Make sure attachments get cleaned up appropriately + // 3. Make sure messageId and partIds not reused (currently each draft is a new message). + public void testWriteDraft() { + final String draftMessage = "draftMessage"; + final long threadId = 1234567; + final boolean senderBlocked = false; + final String participantNumber = "5551234567"; + + final DatabaseWrapper db = DataModel.get().getDatabase(); + + final String conversationId = getOrCreateConversation(db, participantNumber, threadId, + senderBlocked); + final String selfId = getOrCreateSelfId(db); + + // Should clear/stub DB + final ArrayList<StubActionServiceCallLog> calls = mService.getCalls(); + + final MessageData message = MessageData.createDraftSmsMessage(conversationId, selfId, + draftMessage); + + WriteDraftMessageAction.writeDraftMessage(conversationId, message); + + assertEquals("Failed to start service once for action", calls.size(), 1); + assertTrue("Action not SaveDraftMessageAction", + calls.get(0).action instanceof WriteDraftMessageAction); + + final Action save = calls.get(0).action; + + final Object result = save.executeAction(); + + assertTrue("Expect row number string as result", result instanceof String); + final String messageId = (String) result; + + // Should check DB + final MessageData actual = BugleDatabaseOperations.readMessage(db, messageId); + assertNotNull("Database missing draft", actual); + assertEquals("Draft text changed", draftMessage, actual.getMessageText()); + } + + private static String getOrCreateSelfId(final DatabaseWrapper db) { + db.beginTransaction(); + final String selfId = BugleDatabaseOperations.getOrCreateParticipantInTransaction(db, + ParticipantData.getSelfParticipant(ParticipantData.DEFAULT_SELF_SUB_ID)); + db.setTransactionSuccessful(); + db.endTransaction(); + return selfId; + } + + private static String getOrCreateConversation(final DatabaseWrapper db, + final String participantNumber, final long threadId, final boolean senderBlocked) { + final ArrayList<ParticipantData> participants = + new ArrayList<ParticipantData>(); + participants.add(ParticipantData.getFromRawPhoneBySystemLocale(participantNumber)); + + final String conversationId = BugleDatabaseOperations.getOrCreateConversation(db, threadId, + senderBlocked, participants, false, false, null); + assertNotNull("No conversation", conversationId); + return conversationId; + } + + public void testReadDraft() { + final Object data = "data"; + final String draftMessage = "draftMessage"; + final long threadId = 1234567; + final boolean senderBlocked = false; + final String participantNumber = "5552345678"; + + final DatabaseWrapper db = DataModel.get().getDatabase(); + + final String conversationId = getOrCreateConversation(db, participantNumber, threadId, + senderBlocked); + final String selfId = getOrCreateSelfId(db); + + // Should clear/stub DB + final ArrayList<StubActionServiceCallLog> calls = mService.getCalls(); + + final MessageData message = MessageData.createDraftSmsMessage(conversationId, selfId, + draftMessage); + + BugleDatabaseOperations.updateDraftMessageData(db, conversationId, message, + BugleDatabaseOperations.UPDATE_MODE_ADD_DRAFT); + + final ActionMonitor monitor = + ReadDraftDataAction.readDraftData(conversationId, null, data, mockListener); + + assertEquals("Unexpected number of calls to service", 1, calls.size()); + assertTrue("Action not of type ReadDraftMessageAction", + calls.get(0).action instanceof ReadDraftDataAction); + + final Action read = calls.get(0).action; + + final Object result = read.executeAction(); + + assertTrue(result instanceof ReadDraftDataAction.DraftData); + final ReadDraftDataAction.DraftData draft = (ReadDraftDataAction.DraftData) result; + + assertEquals("Draft message text differs", draftMessage, draft.message.getMessageText()); + assertEquals("Draft self differs", selfId, draft.message.getSelfId()); + assertEquals("Draft conversation differs", conversationId, + draft.conversation.getConversationId()); + } + + public void testReadDraftForNewConversation() { + final Object data = "data"; + long threadId = 1234567; + final boolean senderBlocked = false; + long phoneNumber = 5557654567L; + final String notConversationId = "ThisIsNotValidConversationId"; + + final DatabaseWrapper db = DataModel.get().getDatabase(); + final String selfId = getOrCreateSelfId(db); + + // Unless set a new conversation should have a null draft message + final MessageData blank = BugleDatabaseOperations.readDraftMessageData(db, + notConversationId, selfId); + assertNull(blank); + + String conversationId = null; + do { + conversationId = BugleDatabaseOperations.getExistingConversation(db, + threadId, senderBlocked); + threadId++; + phoneNumber++; + } + while(!TextUtils.isEmpty(conversationId)); + + final ArrayList<ParticipantData> participants = + new ArrayList<ParticipantData>(); + participants.add(ParticipantData.getFromRawPhoneBySystemLocale(Long.toString(phoneNumber))); + + conversationId = BugleDatabaseOperations.getOrCreateConversation(db, threadId, + senderBlocked, participants, false, false, null); + assertNotNull("No conversation", conversationId); + + final MessageData actual = BugleDatabaseOperations.readDraftMessageData(db, conversationId, + selfId); + assertNull(actual); + + // Should clear/stub DB + final ArrayList<StubActionServiceCallLog> calls = mService.getCalls(); + + final ActionMonitor monitor = + ReadDraftDataAction.readDraftData(conversationId, null, data, mockListener); + + assertEquals("Unexpected number of calls to service", 1, calls.size()); + assertTrue("Action not of type ReadDraftMessageAction", + calls.get(0).action instanceof ReadDraftDataAction); + + final Action read = calls.get(0).action; + + final Object result = read.executeAction(); + + assertTrue(result instanceof ReadDraftDataAction.DraftData); + final ReadDraftDataAction.DraftData draft = (ReadDraftDataAction.DraftData) result; + + assertEquals("Draft message text differs", "", draft.message.getMessageText()); + assertEquals("Draft self differs", selfId, draft.message.getSelfId()); + assertEquals("Draft conversation differs", conversationId, + draft.conversation.getConversationId()); + } + + public void testWriteAndReadDraft() { + final Object data = "data"; + final String draftMessage = "draftMessage"; + + final DatabaseWrapper db = DataModel.get().getDatabase(); + final Cursor conversations = db.query(DatabaseHelper.CONVERSATIONS_TABLE, + new String[] { ConversationColumns._ID, ConversationColumns.CURRENT_SELF_ID }, null, + null, null /* groupBy */, null /* having */, null /* orderBy */); + + if (conversations.moveToFirst()) { + final String conversationId = conversations.getString(0); + final String selfId = getOrCreateSelfId(db); + + // Should clear/stub DB + final ArrayList<StubActionServiceCallLog> calls = mService.getCalls(); + + final MessageData message = MessageData.createDraftSmsMessage(conversationId, selfId, + draftMessage); + + WriteDraftMessageAction.writeDraftMessage(conversationId, message); + + assertEquals("Failed to start service once for action", calls.size(), 1); + assertTrue("Action not SaveDraftMessageAction", + calls.get(0).action instanceof WriteDraftMessageAction); + + final Action save = calls.get(0).action; + + Object result = save.executeAction(); + + assertTrue("Expect row number string as result", result instanceof String); + + // Should check DB + + final ActionMonitor monitor = + ReadDraftDataAction.readDraftData(conversationId, null, data, + mockListener); + + assertEquals("Expect two calls queued", 2, calls.size()); + assertTrue("Expect action", calls.get(1).action instanceof ReadDraftDataAction); + + final Action read = calls.get(1).action; + + result = read.executeAction(); + + assertTrue(result instanceof ReadDraftDataAction.DraftData); + final ReadDraftDataAction.DraftData draft = (ReadDraftDataAction.DraftData) result; + + assertEquals("Draft message text differs", draftMessage, draft.message.getMessageText()); + // The conversation's self id is used as the draft's self id. + assertEquals("Draft self differs", conversations.getString(1), + draft.message.getSelfId()); + assertEquals("Draft conversation differs", conversationId, + draft.conversation.getConversationId()); + } else { + fail("No conversations in database"); + } + } + + public void testUpdateDraft() { + final String initialMessage = "initialMessage"; + final String draftMessage = "draftMessage"; + final long threadId = 1234567; + final boolean senderBlocked = false; + final String participantNumber = "5553456789"; + + final DatabaseWrapper db = DataModel.get().getDatabase(); + + final String conversationId = getOrCreateConversation(db, participantNumber, threadId, + senderBlocked); + final String selfId = getOrCreateSelfId(db); + + final ArrayList<StubActionServiceCallLog> calls = mService.getCalls(); + + // Insert initial message + MessageData initial = MessageData.createDraftSmsMessage(conversationId, selfId, + initialMessage); + + BugleDatabaseOperations.updateDraftMessageData(db, conversationId, initial, + BugleDatabaseOperations.UPDATE_MODE_ADD_DRAFT); + + initial = BugleDatabaseOperations.readDraftMessageData(db, + conversationId, selfId); + assertEquals("Initial text mismatch", initialMessage, initial.getMessageText()); + + // Now update the draft + final MessageData message = MessageData.createDraftSmsMessage(conversationId, selfId, + draftMessage); + WriteDraftMessageAction.writeDraftMessage(conversationId, message); + + assertEquals("Failed to start service once for action", calls.size(), 1); + assertTrue("Action not SaveDraftMessageAction", + calls.get(0).action instanceof WriteDraftMessageAction); + + final Action save = calls.get(0).action; + + final Object result = save.executeAction(); + + assertTrue("Expect row number string as result", result instanceof String); + + // Check DB + final MessageData actual = BugleDatabaseOperations.readDraftMessageData(db, + conversationId, selfId); + assertNotNull("Database missing draft", actual); + assertEquals("Draft text mismatch", draftMessage, actual.getMessageText()); + assertNull("Draft messageId should be null", actual.getMessageId()); + } + + public void testBugleDatabaseDraftOperations() { + final String initialMessage = "initialMessage"; + final String draftMessage = "draftMessage"; + final long threadId = 1234599; + final boolean senderBlocked = false; + final String participantNumber = "5553456798"; + final String subject = "subject here"; + + final DatabaseWrapper db = DataModel.get().getDatabase(); + + final String conversationId = getOrCreateConversation(db, participantNumber, threadId, + senderBlocked); + final String selfId = getOrCreateSelfId(db); + + final String text = "This is some text"; + final Uri mOutputUri = MediaScratchFileProvider.buildMediaScratchSpaceUri("txt"); + OutputStream outputStream = null; + try { + outputStream = mContext.getContentResolver().openOutputStream(mOutputUri); + outputStream.write(text.getBytes()); + } catch (final FileNotFoundException e) { + fail("Cannot open output file"); + } catch (final IOException e) { + fail("Cannot write output file"); + } + + final MessageData initial = + MessageData.createDraftMmsMessage(conversationId, selfId, initialMessage, subject); + initial.addPart(MessagePartData.createMediaMessagePart(ContentType.MULTIPART_MIXED, + mOutputUri, 0, 0)); + + final String initialMessageId = BugleDatabaseOperations.updateDraftMessageData(db, + conversationId, initial, BugleDatabaseOperations.UPDATE_MODE_ADD_DRAFT); + assertNotNull(initialMessageId); + + final MessageData initialDraft = BugleDatabaseOperations.readMessage(db, initialMessageId); + assertNotNull(initialDraft); + int cnt = 0; + for(final MessagePartData part : initialDraft.getParts()) { + if (part.isAttachment()) { + assertEquals(part.getContentUri(), mOutputUri); + } else { + assertEquals(part.getText(), initialMessage); + } + cnt++; + } + assertEquals("Wrong number of parts", 2, cnt); + + InputStream inputStream = null; + try { + inputStream = mContext.getContentResolver().openInputStream(mOutputUri); + final byte[] buffer = new byte[256]; + final int read = inputStream.read(buffer); + assertEquals(read, text.getBytes().length); + } catch (final FileNotFoundException e) { + fail("Cannot open input file"); + } catch (final IOException e) { + fail("Cannot read input file"); + } + + final String moreText = "This is some more text"; + final Uri mAnotherUri = MediaScratchFileProvider.buildMediaScratchSpaceUri("txt"); + outputStream = null; + try { + outputStream = mContext.getContentResolver().openOutputStream(mAnotherUri); + outputStream.write(moreText.getBytes()); + } catch (final FileNotFoundException e) { + fail("Cannot open output file"); + } catch (final IOException e) { + fail("Cannot write output file"); + } + + final MessageData another = + MessageData.createDraftMmsMessage(conversationId, selfId, draftMessage, subject); + another.addPart(MessagePartData.createMediaMessagePart(ContentType.MMS_MULTIPART_MIXED, + mAnotherUri, 0, 0)); + + final String anotherMessageId = BugleDatabaseOperations.updateDraftMessageData(db, + conversationId, another, BugleDatabaseOperations.UPDATE_MODE_ADD_DRAFT); + assertNotNull(anotherMessageId); + + final MessageData anotherDraft = BugleDatabaseOperations.readMessage(db, anotherMessageId); + assertNotNull(anotherDraft); + cnt = 0; + for(final MessagePartData part : anotherDraft.getParts()) { + if (part.isAttachment()) { + assertEquals(part.getContentUri(), mAnotherUri); + } else { + assertEquals(part.getText(), draftMessage); + } + cnt++; + } + assertEquals("Wrong number of parts", 2, cnt); + + inputStream = null; + try { + inputStream = mContext.getContentResolver().openInputStream(mOutputUri); + assertNull("Original draft content should have been deleted", inputStream); + } catch (final FileNotFoundException e) { + } + inputStream = null; + try { + inputStream = mContext.getContentResolver().openInputStream(mAnotherUri); + final byte[] buffer = new byte[256]; + final int read = inputStream.read(buffer); + assertEquals(read, moreText.getBytes().length); + } catch (final FileNotFoundException e) { + fail("Cannot open input file"); + } catch (final IOException e) { + fail("Cannot read input file"); + } + + final MessageData last = null; + final String lastPartId = BugleDatabaseOperations.updateDraftMessageData(db, + conversationId, last, BugleDatabaseOperations.UPDATE_MODE_ADD_DRAFT); + assertNull(lastPartId); + + inputStream = null; + try { + inputStream = mContext.getContentResolver().openInputStream(mAnotherUri); + assertNull("Original draft content should have been deleted", inputStream); + } catch (final FileNotFoundException e) { + } + + } + + private StubActionService mService; + + @Override + public void setUp() throws Exception { + super.setUp(); + + final FakeContext context = new FakeContext(getTestContext()); + + final ContentProvider bugleProvider = new MessagingContentProvider(); + final ProviderInfo bugleProviderInfo = new ProviderInfo(); + bugleProviderInfo.authority = MessagingContentProvider.AUTHORITY; + bugleProvider.attachInfo(mContext, bugleProviderInfo); + context.addContentProvider(MessagingContentProvider.AUTHORITY, bugleProvider); + final ContentProvider mediaProvider = new MediaScratchFileProvider(); + final ProviderInfo mediaProviderInfo = new ProviderInfo(); + mediaProviderInfo.authority = MediaScratchFileProvider.AUTHORITY; + mediaProvider.attachInfo(mContext, mediaProviderInfo); + context.addContentProvider(MediaScratchFileProvider.AUTHORITY, mediaProvider); + + mService = new StubActionService(); + final FakeDataModel fakeDataModel = new FakeDataModel(context) + .withActionService(mService) + .withConnectivityUtil(new StubConnectivityUtil(context)); + FakeFactory.registerWithFakeContext(getTestContext(), context) + .withDataModel(fakeDataModel); + + } +} |