From 486c638063ebbea0179a13d65e6690b8bbaba840 Mon Sep 17 00:00:00 2001 From: Kihong Seong <kihongs@google.com> Date: Mon, 12 Dec 2022 02:16:18 +0000 Subject: [PATCH] Add tests for BluetoothMapContentObserverTest Bug: 237467631 Test: atest BluetoothMapContentObserverTest Change-Id: I89f16b5064a65a86eb2ed547a55574b62290c1f5 Merged-In: I89f16b5064a65a86eb2ed547a55574b62290c1f5 (cherry picked from commit 96a49f6330f64c5fdb88b34d8a333e0cf957ba04) --- .../map/BluetoothMapContentObserver.java | 67 +++-- .../map/BluetoothMapContentObserverTest.java | 232 ++++++++++++++---- 2 files changed, 220 insertions(+), 79 deletions(-) diff --git a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java index 31ba0b11bb9..04d80a97b57 100644 --- a/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java +++ b/android/app/src/com/android/bluetooth/map/BluetoothMapContentObserver.java @@ -88,18 +88,30 @@ public class BluetoothMapContentObserver { private static final boolean D = BluetoothMapService.DEBUG; private static final boolean V = BluetoothMapService.VERBOSE; - private static final String EVENT_TYPE_NEW = "NewMessage"; - private static final String EVENT_TYPE_DELETE = "MessageDeleted"; - private static final String EVENT_TYPE_REMOVED = "MessageRemoved"; - private static final String EVENT_TYPE_SHIFT = "MessageShift"; - private static final String EVENT_TYPE_DELEVERY_SUCCESS = "DeliverySuccess"; - private static final String EVENT_TYPE_SENDING_SUCCESS = "SendingSuccess"; - private static final String EVENT_TYPE_SENDING_FAILURE = "SendingFailure"; - private static final String EVENT_TYPE_DELIVERY_FAILURE = "DeliveryFailure"; - private static final String EVENT_TYPE_READ_STATUS = "ReadStatusChanged"; - private static final String EVENT_TYPE_CONVERSATION = "ConversationChanged"; - private static final String EVENT_TYPE_PRESENCE = "ParticipantPresenceChanged"; - private static final String EVENT_TYPE_CHAT_STATE = "ParticipantChatStateChanged"; + @VisibleForTesting + static final String EVENT_TYPE_NEW = "NewMessage"; + @VisibleForTesting + static final String EVENT_TYPE_DELETE = "MessageDeleted"; + @VisibleForTesting + static final String EVENT_TYPE_REMOVED = "MessageRemoved"; + @VisibleForTesting + static final String EVENT_TYPE_SHIFT = "MessageShift"; + @VisibleForTesting + static final String EVENT_TYPE_DELEVERY_SUCCESS = "DeliverySuccess"; + @VisibleForTesting + static final String EVENT_TYPE_SENDING_SUCCESS = "SendingSuccess"; + @VisibleForTesting + static final String EVENT_TYPE_SENDING_FAILURE = "SendingFailure"; + @VisibleForTesting + static final String EVENT_TYPE_DELIVERY_FAILURE = "DeliveryFailure"; + @VisibleForTesting + static final String EVENT_TYPE_READ_STATUS = "ReadStatusChanged"; + @VisibleForTesting + static final String EVENT_TYPE_CONVERSATION = "ConversationChanged"; + @VisibleForTesting + static final String EVENT_TYPE_PRESENCE = "ParticipantPresenceChanged"; + @VisibleForTesting + static final String EVENT_TYPE_CHAT_STATE = "ParticipantChatStateChanged"; private static final long EVENT_FILTER_NEW_MESSAGE = 1L; private static final long EVENT_FILTER_MESSAGE_DELETED = 1L << 1; @@ -337,11 +349,13 @@ public class BluetoothMapContentObserver { } } - private Map<Long, Msg> getMsgListSms() { + @VisibleForTesting + Map<Long, Msg> getMsgListSms() { return mMsgListSms; } - private void setMsgListSms(Map<Long, Msg> msgListSms, boolean changesDetected) { + @VisibleForTesting + void setMsgListSms(Map<Long, Msg> msgListSms, boolean changesDetected) { mMsgListSms = msgListSms; if (changesDetected) { mMasInstance.updateFolderVersionCounter(); @@ -349,13 +363,13 @@ public class BluetoothMapContentObserver { mMasInstance.setMsgListSms(msgListSms); } - - private Map<Long, Msg> getMsgListMms() { + @VisibleForTesting + Map<Long, Msg> getMsgListMms() { return mMsgListMms; } - - private void setMsgListMms(Map<Long, Msg> msgListMms, boolean changesDetected) { + @VisibleForTesting + void setMsgListMms(Map<Long, Msg> msgListMms, boolean changesDetected) { mMsgListMms = msgListMms; if (changesDetected) { mMasInstance.updateFolderVersionCounter(); @@ -363,13 +377,13 @@ public class BluetoothMapContentObserver { mMasInstance.setMsgListMms(msgListMms); } - - private Map<Long, Msg> getMsgListMsg() { + @VisibleForTesting + Map<Long, Msg> getMsgListMsg() { return mMsgListMsg; } - - private void setMsgListMsg(Map<Long, Msg> msgListMsg, boolean changesDetected) { + @VisibleForTesting + void setMsgListMsg(Map<Long, Msg> msgListMsg, boolean changesDetected) { mMsgListMsg = msgListMsg; if (changesDetected) { mMasInstance.updateFolderVersionCounter(); @@ -377,7 +391,8 @@ public class BluetoothMapContentObserver { mMasInstance.setMsgListMsg(msgListMsg); } - private Map<String, BluetoothMapConvoContactElement> getContactList() { + @VisibleForTesting + Map<String, BluetoothMapConvoContactElement> getContactList() { return mContactList; } @@ -387,7 +402,8 @@ public class BluetoothMapContentObserver { * @param contactList * @param changesDetected that is not chat state changed nor presence state changed. */ - private void setContactList(Map<String, BluetoothMapConvoContactElement> contactList, + @VisibleForTesting + void setContactList(Map<String, BluetoothMapConvoContactElement> contactList, boolean changesDetected) { mContactList = contactList; if (changesDetected) { @@ -1117,7 +1133,8 @@ public class BluetoothMapContentObserver { } } - private void sendEvent(Event evt) { + @VisibleForTesting + void sendEvent(Event evt) { if (!mTransmitEvents) { if (V) { diff --git a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java index 71963c3b221..055ec2ea1a7 100644 --- a/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java +++ b/android/app/tests/unit/src/com/android/bluetooth/map/BluetoothMapContentObserverTest.java @@ -23,6 +23,7 @@ import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteException; import android.net.Uri; +import android.os.Handler; import android.os.Looper; import android.os.RemoteException; import android.os.UserManager; @@ -32,28 +33,47 @@ import android.telephony.TelephonyManager; import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; -import androidx.test.InstrumentationRegistry; import androidx.test.filters.MediumTest; import androidx.test.runner.AndroidJUnit4; import com.android.bluetooth.R; +import com.android.obex.ResponseCodes; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import java.io.IOException; import java.util.HashSet; +import java.util.Map; @MediumTest @RunWith(AndroidJUnit4.class) public class BluetoothMapContentObserverTest { static final String TEST_NUMBER_ONE = "5551212"; static final String TEST_NUMBER_TWO = "5551234"; - private Context mTargetContext; + static final int TEST_MAS_ID = 1; + static final long TEST_HANDLE = 1; + + @Mock + private BluetoothMnsObexClient mClient; + @Mock + private BluetoothMapMasInstance mInstance; + @Mock + private TelephonyManager mTelephonyManager; + @Mock + private UserManager mUserService; + @Mock + private Context mContext; + + private ExceptionTestProvider mProvider; + private MockContentResolver mMockContentResolver; + private BluetoothMapContentObserver mObserver; static class ExceptionTestProvider extends MockContentProvider { HashSet<String> mContents = new HashSet<String>(); @@ -83,44 +103,28 @@ public class BluetoothMapContentObserverTest { } @Before - public void setUp() { - mTargetContext = InstrumentationRegistry.getTargetContext(); + public void setUp() throws Exception { Assume.assumeTrue("Ignore test when BluetoothMapService is not enabled", BluetoothMapService.isEnabled()); - } - - @Test - public void testInitMsgList() { + MockitoAnnotations.initMocks(this); if (Looper.myLooper() == null) { Looper.prepare(); } - Context mockContext = mock(Context.class); - MockContentResolver mockResolver = new MockContentResolver(); - ExceptionTestProvider mockProvider = new ExceptionTestProvider(mockContext); - mockResolver.addProvider("sms", mockProvider); - - TelephonyManager mockTelephony = mock(TelephonyManager.class); - UserManager mockUserService = mock(UserManager.class); - BluetoothMapMasInstance mockMas = mock(BluetoothMapMasInstance.class); + mMockContentResolver = new MockContentResolver(); + mProvider = new ExceptionTestProvider(mContext); + mMockContentResolver.addProvider("sms", mProvider); // Functions that get called when BluetoothMapContentObserver is created - when(mockUserService.isUserUnlocked()).thenReturn(true); - when(mockContext.getContentResolver()).thenReturn(mockResolver); - when(mockContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mockTelephony); - when(mockContext.getSystemServiceName(TelephonyManager.class)) + when(mUserService.isUserUnlocked()).thenReturn(true); + when(mContext.getContentResolver()).thenReturn(mMockContentResolver); + when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); + when(mContext.getSystemServiceName(TelephonyManager.class)) .thenReturn(Context.TELEPHONY_SERVICE); - when(mockContext.getSystemService(Context.USER_SERVICE)).thenReturn(mockUserService); - when(mockContext.getSystemServiceName(UserManager.class)).thenReturn(Context.USER_SERVICE); + when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserService); + when(mContext.getSystemServiceName(UserManager.class)).thenReturn(Context.USER_SERVICE); + when(mInstance.getMasId()).thenReturn(TEST_MAS_ID); - BluetoothMapContentObserver observer; - try { - // The constructor of BluetoothMapContentObserver calls initMsgList - observer = new BluetoothMapContentObserver(mockContext, null, mockMas, null, true); - } catch (RemoteException e) { - Assert.fail("Failed to created BluetoothMapContentObserver object"); - } catch (SQLiteException e) { - Assert.fail("Threw SQLiteException instead of Assert.failing cleanly"); - } + mObserver = new BluetoothMapContentObserver(mContext, mClient, mInstance, null, true); } @Test @@ -128,25 +132,8 @@ public class BluetoothMapContentObserverTest { if (Looper.myLooper() == null) { Looper.prepare(); } - Context mockContext = mock(Context.class); - MockContentResolver mockResolver = new MockContentResolver(); - ExceptionTestProvider mockProvider = new ExceptionTestProvider(mockContext); - - mockResolver.addProvider("sms", mockProvider); - mockResolver.addProvider("mms", mockProvider); - mockResolver.addProvider("mms-sms", mockProvider); - TelephonyManager mockTelephony = mock(TelephonyManager.class); - UserManager mockUserService = mock(UserManager.class); - BluetoothMapMasInstance mockMas = mock(BluetoothMapMasInstance.class); - - // Functions that get called when BluetoothMapContentObserver is created - when(mockUserService.isUserUnlocked()).thenReturn(true); - when(mockContext.getContentResolver()).thenReturn(mockResolver); - when(mockContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mockTelephony); - when(mockContext.getSystemServiceName(TelephonyManager.class)) - .thenReturn(Context.TELEPHONY_SERVICE); - when(mockContext.getSystemService(Context.USER_SERVICE)).thenReturn(mockUserService); - when(mockContext.getSystemServiceName(UserManager.class)).thenReturn(Context.USER_SERVICE); + mMockContentResolver.addProvider("mms", mProvider); + mMockContentResolver.addProvider("mms-sms", mProvider); BluetoothMapbMessageMime message = new BluetoothMapbMessageMime(); message.setType(BluetoothMapUtils.TYPE.MMS); @@ -168,7 +155,7 @@ public class BluetoothMapContentObserverTest { try { // The constructor of BluetoothMapContentObserver calls initMsgList BluetoothMapContentObserver observer = - new BluetoothMapContentObserver(mockContext, null, mockMas, null, true); + new BluetoothMapContentObserver(mContext, null, mInstance, null, true); observer.pushMessage(message, folderElement, appParams, null); } catch (RemoteException e) { Assert.fail("Failed to created BluetoothMapContentObserver object"); @@ -182,9 +169,146 @@ public class BluetoothMapContentObserverTest { } // Validate that 3 addresses were inserted into the database with 2 being the recipients - Assert.assertEquals(3, mockProvider.mContents.size()); - Assert.assertTrue(mockProvider.mContents.contains(TEST_NUMBER_ONE)); - Assert.assertTrue(mockProvider.mContents.contains(TEST_NUMBER_TWO)); + Assert.assertEquals(3, mProvider.mContents.size()); + Assert.assertTrue(mProvider.mContents.contains(TEST_NUMBER_ONE)); + Assert.assertTrue(mProvider.mContents.contains(TEST_NUMBER_TWO)); + } + + @Test + public void testSendEvent_withZeroEventFilter() { + when(mClient.isConnected()).thenReturn(true); + mObserver.setNotificationFilter(0); + + String eventType = BluetoothMapContentObserver.EVENT_TYPE_NEW; + BluetoothMapContentObserver.Event event = mObserver.new Event(eventType, TEST_HANDLE, null, + null); + mObserver.sendEvent(event); + verify(mClient, never()).sendEvent(any(), anyInt()); + + event.eventType = BluetoothMapContentObserver.EVENT_TYPE_DELETE; + mObserver.sendEvent(event); + verify(mClient, never()).sendEvent(any(), anyInt()); + + event.eventType = BluetoothMapContentObserver.EVENT_TYPE_REMOVED; + mObserver.sendEvent(event); + verify(mClient, never()).sendEvent(any(), anyInt()); + + event.eventType = BluetoothMapContentObserver.EVENT_TYPE_SHIFT; + mObserver.sendEvent(event); + verify(mClient, never()).sendEvent(any(), anyInt()); + + event.eventType = BluetoothMapContentObserver.EVENT_TYPE_DELEVERY_SUCCESS; + mObserver.sendEvent(event); + verify(mClient, never()).sendEvent(any(), anyInt()); + + event.eventType = BluetoothMapContentObserver.EVENT_TYPE_SENDING_SUCCESS; + mObserver.sendEvent(event); + verify(mClient, never()).sendEvent(any(), anyInt()); + + event.eventType = BluetoothMapContentObserver.EVENT_TYPE_SENDING_FAILURE; + mObserver.sendEvent(event); + verify(mClient, never()).sendEvent(any(), anyInt()); + + event.eventType = BluetoothMapContentObserver.EVENT_TYPE_READ_STATUS; + mObserver.sendEvent(event); + verify(mClient, never()).sendEvent(any(), anyInt()); + + event.eventType = BluetoothMapContentObserver.EVENT_TYPE_CONVERSATION; + mObserver.sendEvent(event); + verify(mClient, never()).sendEvent(any(), anyInt()); + + event.eventType = BluetoothMapContentObserver.EVENT_TYPE_PRESENCE; + mObserver.sendEvent(event); + verify(mClient, never()).sendEvent(any(), anyInt()); + + event.eventType = BluetoothMapContentObserver.EVENT_TYPE_CHAT_STATE; + mObserver.sendEvent(event); + verify(mClient, never()).sendEvent(any(), anyInt()); + } + + @Test + public void testEvent_withNonZeroEventFilter() throws Exception { + when(mClient.isConnected()).thenReturn(true); + + String eventType = BluetoothMapContentObserver.EVENT_TYPE_NEW; + BluetoothMapContentObserver.Event event = mObserver.new Event(eventType, TEST_HANDLE, null, + null); + + mObserver.sendEvent(event); + + verify(mClient).sendEvent(event.encode(), TEST_MAS_ID); } + @Test + public void testSetContactList() { + Map<String, BluetoothMapConvoContactElement> map = Map.of(); + + mObserver.setContactList(map, true); + + Assert.assertEquals(mObserver.getContactList(), map); + } + + @Test + public void testSetMsgListSms() { + Map<Long, BluetoothMapContentObserver.Msg> map = Map.of(); + + mObserver.setMsgListSms(map, true); + + Assert.assertEquals(mObserver.getMsgListSms(), map); + } + + @Test + public void testSetMsgListMsg() { + Map<Long, BluetoothMapContentObserver.Msg> map = Map.of(); + + mObserver.setMsgListMsg(map, true); + + Assert.assertEquals(mObserver.getMsgListMsg(), map); + } + + @Test + public void testSetMsgListMms() { + Map<Long, BluetoothMapContentObserver.Msg> map = Map.of(); + + mObserver.setMsgListMms(map, true); + + Assert.assertEquals(mObserver.getMsgListMms(), map); + } + + @Test + public void testSetNotificationRegistration_withNullHandler() throws Exception { + when(mClient.getMessageHandler()).thenReturn(null); + + Assert.assertEquals( + mObserver.setNotificationRegistration(BluetoothMapAppParams.NOTIFICATION_STATUS_NO), + ResponseCodes.OBEX_HTTP_UNAVAILABLE); + } + + @Test + public void testSetNotificationRegistration_withInvalidMnsRecord() throws Exception { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + Handler handler = new Handler(); + when(mClient.getMessageHandler()).thenReturn(handler); + when(mClient.isValidMnsRecord()).thenReturn(false); + + Assert.assertEquals( + mObserver.setNotificationRegistration(BluetoothMapAppParams.NOTIFICATION_STATUS_NO), + ResponseCodes.OBEX_HTTP_OK); + } + + @Test + public void testSetNotificationRegistration_withValidMnsRecord() throws Exception { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + Handler handler = new Handler(); + when(mClient.getMessageHandler()).thenReturn(handler); + when(mClient.isValidMnsRecord()).thenReturn(true); + + Assert.assertEquals( + mObserver.setNotificationRegistration(BluetoothMapAppParams.NOTIFICATION_STATUS_NO), + ResponseCodes.OBEX_HTTP_OK); + } } -- GitLab