1c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu/* 2c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * Copyright (C) 2017 The Android Open Source Project 3c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * 4c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * Licensed under the Apache License, Version 2.0 (the "License"); 5c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * you may not use this file except in compliance with the License. 6c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * You may obtain a copy of the License at 7c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * 8c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * http://www.apache.org/licenses/LICENSE-2.0 9c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * 10c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * Unless required by applicable law or agreed to in writing, software 11c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * distributed under the License is distributed on an "AS IS" BASIS, 12c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * See the License for the specific language governing permissions and 14c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * limitations under the License 15c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu */ 16c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 17c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxupackage com.android.providers.telephony; 18c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 19c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.app.AppOpsManager; 20c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.content.ContentValues; 21c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.content.Context; 22c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.content.pm.PackageManager; 23c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.content.pm.ProviderInfo; 24c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.content.res.Resources; 25c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.database.ContentObserver; 26c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.net.Uri; 27c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.provider.Telephony; 28c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.telephony.TelephonyManager; 29c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.test.mock.MockContentResolver; 30c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.test.mock.MockContext; 31c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.test.suitebuilder.annotation.SmallTest; 32c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport android.util.Log; 33c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 34c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport junit.framework.TestCase; 35c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 36c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport org.junit.Test; 37c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxuimport org.mockito.Mockito; 38c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 39c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 40c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu/** 41c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * Tests for testing CRUD operations of SmsProvider. 42c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * Uses a MockContentResolver to test insert 43c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * Uses SmsProviderTestable to set up in-memory database 44c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * 45c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * Build, install and run the tests by running the commands below: 46c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * runtest --path <dir or file> 47c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * runtest --path <dir or file> --test-method <testMethodName> 48c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * e.g.) 49c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * runtest --path tests/src/com/android/providers/telephony/SmsProviderTest.java \ 50c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * --test-method testInsertUri 51c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu */ 52c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxupublic class SmsProviderTest extends TestCase { 53c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu private static final String TAG = "TelephonyProviderTest"; 54c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 55c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu private MockContextWithProvider mContext; 56c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu private MockContentResolver mContentResolver; 57c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu private SmsProviderTestable mSmsProviderTestable; 58c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 59c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu private int notifyChangeCount; 60c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 61c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 62c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu /** 63c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * This is used to give the SmsProviderTest a mocked context which takes a 64c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * SmsProvider and attaches it to the ContentResolver with telephony authority. 65c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu * The mocked context also gives WRITE_APN_SETTINGS permissions 66c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu */ 67c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu private class MockContextWithProvider extends MockContext { 68c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu private final MockContentResolver mResolver; 69c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 70c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu public MockContextWithProvider(SmsProvider smsProvider) { 71c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu mResolver = new MockContentResolver() { 72c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu @Override 73c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork, 74c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu int userHandle) { 75c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu notifyChangeCount++; 76c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 77c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu }; 78c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 79c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu // Add authority="sms" to given smsProvider 80c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu ProviderInfo providerInfo = new ProviderInfo(); 81c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu providerInfo.authority = "sms"; 82c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 83c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu // Add context to given smsProvider 84c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu smsProvider.attachInfoForTesting(this, providerInfo); 85c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu Log.d(TAG, "MockContextWithProvider: smsProvider.getContext(): " 86c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu + smsProvider.getContext()); 87c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 88c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu // Add given SmsProvider to mResolver with authority="sms" so that 89c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu // mResolver can send queries to mSmsProvider 90c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu mResolver.addProvider("sms", smsProvider); 91c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu Log.d(TAG, "MockContextWithProvider: Add SmsProvider to mResolver"); 92c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 93c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 94c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu @Override 95c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu public Object getSystemService(String name) { 96c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu Log.d(TAG, "getSystemService: returning null"); 97c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu switch (name) { 98c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu case Context.APP_OPS_SERVICE: 99c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu return Mockito.mock(AppOpsManager.class); 100c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu case Context.TELEPHONY_SERVICE: 101c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu return Mockito.mock(TelephonyManager.class); 102c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu default: 103c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu return null; 104c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 105c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 106c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 107c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu @Override 108c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu public Resources getResources() { 109c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu Log.d(TAG, "getResources: returning null"); 110c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu return null; 111c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 112c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 113c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu @Override 114c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu public int getUserId() { 115c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu return 0; 116c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 117c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 118c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu @Override 119c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu public MockContentResolver getContentResolver() { 120c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu return mResolver; 121c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 122c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 123c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu @Override 124c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu public int checkCallingOrSelfPermission(String permission) { 125c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu return PackageManager.PERMISSION_GRANTED; 126c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 127c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 128c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 129c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu @Override 130c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu protected void setUp() throws Exception { 131c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu super.setUp(); 132c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu mSmsProviderTestable = new SmsProviderTestable(); 133c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu mContext = new MockContextWithProvider(mSmsProviderTestable); 134c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu mContentResolver = mContext.getContentResolver(); 135c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu notifyChangeCount = 0; 136c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 137c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 138c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu @Override 139c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu protected void tearDown() throws Exception { 140c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu super.tearDown(); 141c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu mSmsProviderTestable.closeDatabase(); 142c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 143c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 144c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu @Test 145c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu @SmallTest 146c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu public void testInsertUri() { 147c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu // insert test contentValues 148c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu final ContentValues values = new ContentValues(); 149c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu values.put(Telephony.Sms.SUBSCRIPTION_ID, 1); 150c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu values.put(Telephony.Sms.ADDRESS, "12345"); 151c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu values.put(Telephony.Sms.BODY, "test"); 152c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu values.put(Telephony.Sms.DATE, System.currentTimeMillis()); // milliseconds 153c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu values.put(Telephony.Sms.SEEN, 1); 154c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu values.put(Telephony.Sms.READ, 1); 155c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu values.put(Telephony.Sms.THREAD_ID, 1); 156c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 157c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu // test for sms table 158c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu Log.d(TAG, "testInsertSmsTable Inserting contentValues: " + values); 159c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu assertEquals(Uri.parse("content://sms/1"), 160c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu mContentResolver.insert(Uri.parse("content://sms"), values)); 161c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu assertEquals(Uri.parse("content://sms/2"), 162c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu mContentResolver.insert(Uri.parse("content://sms"), values)); 163c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu 164c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu // test for attachments table 165c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu values.clear(); 166c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu values.put("sms_id", 1); 167c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu values.put("content_url", "test"); 168c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu values.put("offset", 0); 169c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu Log.d(TAG, "testInsertAttachmentTable Inserting contentValues: " + values); 170c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu assertEquals(Uri.parse("content://sms/attachments/1"), 171c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu mContentResolver.insert(Uri.parse("content://sms/attachments"), values)); 172c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu } 173c1f7e0a116f7d3a20992e50a8e803eca6803370ffionaxu}