1 /* 2 * Copyright 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.bluetooth.map; 18 19 import static org.mockito.Mockito.*; 20 21 import android.content.ContentValues; 22 import android.content.Context; 23 import android.database.Cursor; 24 import android.database.sqlite.SQLiteException; 25 import android.net.Uri; 26 import android.os.Looper; 27 import android.os.RemoteException; 28 import android.os.UserManager; 29 import android.provider.Telephony.Mms; 30 import android.provider.Telephony.Sms; 31 import android.telephony.TelephonyManager; 32 import android.test.mock.MockContentProvider; 33 import android.test.mock.MockContentResolver; 34 35 import androidx.test.InstrumentationRegistry; 36 import androidx.test.filters.MediumTest; 37 import androidx.test.runner.AndroidJUnit4; 38 39 import com.android.bluetooth.R; 40 41 import org.junit.Assert; 42 import org.junit.Assume; 43 import org.junit.Before; 44 import org.junit.Test; 45 import org.junit.runner.RunWith; 46 import org.mockito.Mockito; 47 48 import java.io.IOException; 49 import java.util.HashSet; 50 51 @MediumTest 52 @RunWith(AndroidJUnit4.class) 53 public class BluetoothMapContentObserverTest { 54 static final String TEST_NUMBER_ONE = "5551212"; 55 static final String TEST_NUMBER_TWO = "5551234"; 56 private Context mTargetContext; 57 58 static class ExceptionTestProvider extends MockContentProvider { 59 HashSet<String> mContents = new HashSet<String>(); ExceptionTestProvider(Context context)60 public ExceptionTestProvider(Context context) { 61 super(context); 62 } 63 64 @Override query(Uri uri, String[] b, String s, String[] c, String d)65 public Cursor query(Uri uri, String[] b, String s, String[] c, String d) { 66 // Throw exception for SMS queries for easy initialization 67 if (Sms.CONTENT_URI.equals(uri)) throw new SQLiteException(); 68 69 // Return a cursor otherwise for Thread IDs 70 Cursor cursor = Mockito.mock(Cursor.class); 71 when(cursor.moveToFirst()).thenReturn(true); 72 when(cursor.getLong(anyInt())).thenReturn(0L); 73 return cursor; 74 } 75 76 @Override insert(Uri uri, ContentValues values)77 public Uri insert(Uri uri, ContentValues values) { 78 // Store addresses for later verification 79 Object address = values.get(Mms.Addr.ADDRESS); 80 if (address != null) mContents.add((String) address); 81 return Uri.withAppendedPath(Mms.Outbox.CONTENT_URI, "0"); 82 } 83 } 84 85 @Before setUp()86 public void setUp() { 87 mTargetContext = InstrumentationRegistry.getTargetContext(); 88 Assume.assumeTrue("Ignore test when BluetoothMapService is not enabled", 89 mTargetContext.getResources().getBoolean(R.bool.profile_supported_map)); 90 } 91 92 @Test testInitMsgList()93 public void testInitMsgList() { 94 if (Looper.myLooper() == null) { 95 Looper.prepare(); 96 } 97 Context mockContext = mock(Context.class); 98 MockContentResolver mockResolver = new MockContentResolver(); 99 ExceptionTestProvider mockProvider = new ExceptionTestProvider(mockContext); 100 mockResolver.addProvider("sms", mockProvider); 101 102 TelephonyManager mockTelephony = mock(TelephonyManager.class); 103 UserManager mockUserService = mock(UserManager.class); 104 BluetoothMapMasInstance mockMas = mock(BluetoothMapMasInstance.class); 105 106 // Functions that get called when BluetoothMapContentObserver is created 107 when(mockUserService.isUserUnlocked()).thenReturn(true); 108 when(mockContext.getContentResolver()).thenReturn(mockResolver); 109 when(mockContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mockTelephony); 110 when(mockContext.getSystemService(Context.USER_SERVICE)).thenReturn(mockUserService); 111 112 BluetoothMapContentObserver observer; 113 try { 114 // The constructor of BluetoothMapContentObserver calls initMsgList 115 observer = new BluetoothMapContentObserver(mockContext, null, mockMas, null, true); 116 } catch (RemoteException e) { 117 Assert.fail("Failed to created BluetoothMapContentObserver object"); 118 } catch (SQLiteException e) { 119 Assert.fail("Threw SQLiteException instead of Assert.failing cleanly"); 120 } 121 } 122 123 @Test testPushGroupMMS()124 public void testPushGroupMMS() { 125 if (Looper.myLooper() == null) { 126 Looper.prepare(); 127 } 128 Context mockContext = mock(Context.class); 129 MockContentResolver mockResolver = new MockContentResolver(); 130 ExceptionTestProvider mockProvider = new ExceptionTestProvider(mockContext); 131 132 mockResolver.addProvider("sms", mockProvider); 133 mockResolver.addProvider("mms", mockProvider); 134 mockResolver.addProvider("mms-sms", mockProvider); 135 TelephonyManager mockTelephony = mock(TelephonyManager.class); 136 UserManager mockUserService = mock(UserManager.class); 137 BluetoothMapMasInstance mockMas = mock(BluetoothMapMasInstance.class); 138 139 // Functions that get called when BluetoothMapContentObserver is created 140 when(mockUserService.isUserUnlocked()).thenReturn(true); 141 when(mockContext.getContentResolver()).thenReturn(mockResolver); 142 when(mockContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mockTelephony); 143 when(mockContext.getSystemService(Context.USER_SERVICE)).thenReturn(mockUserService); 144 145 BluetoothMapbMessageMime message = new BluetoothMapbMessageMime(); 146 message.setType(BluetoothMapUtils.TYPE.MMS); 147 message.setFolder("telecom/msg/outbox"); 148 message.addSender("Zero", "0"); 149 message.addRecipient("One", new String[] {TEST_NUMBER_ONE}, null); 150 message.addRecipient("Two", new String[] {TEST_NUMBER_TWO}, null); 151 BluetoothMapbMessageMime.MimePart body = message.addMimePart(); 152 try { 153 body.mContentType = "text/plain"; 154 body.mData = "HelloWorld".getBytes("utf-8"); 155 } catch (Exception e) { 156 Assert.fail("Failed to setup test message"); 157 } 158 159 BluetoothMapAppParams appParams = new BluetoothMapAppParams(); 160 BluetoothMapFolderElement folderElement = new BluetoothMapFolderElement("outbox", null); 161 162 try { 163 // The constructor of BluetoothMapContentObserver calls initMsgList 164 BluetoothMapContentObserver observer = 165 new BluetoothMapContentObserver(mockContext, null, mockMas, null, true); 166 observer.pushMessage(message, folderElement, appParams, null); 167 } catch (RemoteException e) { 168 Assert.fail("Failed to created BluetoothMapContentObserver object"); 169 } catch (SQLiteException e) { 170 Assert.fail("Threw SQLiteException instead of Assert.failing cleanly"); 171 } catch (IOException e) { 172 Assert.fail("Threw IOException"); 173 } catch (NullPointerException e) { 174 //expected that the test case will end in a NPE as part of the sendMultimediaMessage 175 //pendingSendIntent 176 } 177 178 // Validate that 3 addresses were inserted into the database with 2 being the recipients 179 Assert.assertEquals(3, mockProvider.mContents.size()); 180 Assert.assertTrue(mockProvider.mContents.contains(TEST_NUMBER_ONE)); 181 Assert.assertTrue(mockProvider.mContents.contains(TEST_NUMBER_TWO)); 182 } 183 184 } 185