VoicemailStatusHelperImplTest.java revision e0b2f1e2d01d1ac52ba207dc7ce76971d853298e
1/*
2 * Copyright (C) 2011 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
17package com.android.contacts.voicemail;
18
19import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE;
20import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE_CAN_BE_CONFIGURED;
21import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE_NOT_CONFIGURED;
22import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE;
23import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE_NO_CONNECTION;
24import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE_OK;
25import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE;
26import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING;
27import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION;
28import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK;
29
30import android.content.ContentResolver;
31import android.content.ContentValues;
32import android.database.Cursor;
33import android.net.Uri;
34import android.provider.VoicemailContract.Status;
35import android.test.AndroidTestCase;
36
37import com.android.contacts.R;
38import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
39
40import java.util.List;
41
42/**
43 * Unit tests for {@link VoicemailStatusHelperImpl}.
44 */
45public class VoicemailStatusHelperImplTest extends AndroidTestCase {
46    private static final String[] TEST_PACKAGES = new String[] {
47        "com.test.package1",
48        "com.test.package2"
49    };
50
51    private static final Uri TEST_SETTINGS_URI = Uri.parse("http://www.visual.voicemail.setup");
52    private static final Uri TEST_VOICEMAIL_URI = Uri.parse("tel:901");
53
54    private static final int ACTION_MSG_CALL_VOICEMAIL =
55            R.string.voicemail_status_action_call_server;
56    private static final int ACTION_MSG_CONFIGURE = R.string.voicemail_status_action_configure;
57
58    private static final int STATUS_MSG_NONE = -1;
59    private static final int STATUS_MSG_VOICEMAIL_NOT_AVAILABLE =
60            R.string.voicemail_status_voicemail_not_available;
61    private static final int STATUS_MSG_AUDIO_NOT_AVAIALABLE =
62            R.string.voicemail_status_audio_not_available;
63    private static final int STATUS_MSG_MESSAGE_WAITING = R.string.voicemail_status_messages_waiting;
64    private static final int STATUS_MSG_INVITE_FOR_CONFIGURATION =
65            R.string.voicemail_status_configure_voicemail;
66
67    // Object under test.
68    private VoicemailStatusHelper mStatusHelper;
69
70    @Override
71    protected void setUp() throws Exception {
72        super.setUp();
73        mStatusHelper = new VoicemailStatusHelperImpl();
74    }
75
76    @Override
77    protected void tearDown() throws Exception {
78        for (String sourcePackage : TEST_PACKAGES) {
79            deleteEntryForPackage(sourcePackage);
80        }
81        // Set member variables to null so that they are garbage collected across different runs
82        // of the tests.
83        mStatusHelper = null;
84        super.tearDown();
85    }
86
87
88    public void testNoStatusEntries() {
89        assertEquals(0, getStatusMessages().size());
90    }
91
92    public void testAllOK() {
93        insertEntryForPackage(TEST_PACKAGES[0], getAllOkStatusValues());
94        insertEntryForPackage(TEST_PACKAGES[1], getAllOkStatusValues());
95        assertEquals(0, getStatusMessages().size());
96    }
97
98    public void testNotAllOKForOnePackage() {
99        insertEntryForPackage(TEST_PACKAGES[0], getAllOkStatusValues());
100        insertEntryForPackage(TEST_PACKAGES[1], getAllOkStatusValues());
101
102        ContentValues values = new ContentValues();
103        // Good data channel + no notification
104        // action: call voicemail
105        // msg: voicemail not available in call log page & none in call details page.
106        values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
107        values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_OK);
108        updateEntryForPackage(TEST_PACKAGES[1], values);
109        checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_VOICEMAIL_NOT_AVAILABLE,
110                STATUS_MSG_NONE, ACTION_MSG_CALL_VOICEMAIL);
111
112        // Message waiting + good data channel - no action.
113        values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING);
114        values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_OK);
115        updateEntryForPackage(TEST_PACKAGES[1], values);
116        checkNoMessages(TEST_PACKAGES[1], values);
117
118        // No data channel + no notification
119        // action: call voicemail
120        // msg: voicemail not available in call log page & audio not available in call details page.
121        values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_OK);
122        values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
123        updateEntryForPackage(TEST_PACKAGES[1], values);
124        checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_VOICEMAIL_NOT_AVAILABLE,
125                STATUS_MSG_AUDIO_NOT_AVAIALABLE, ACTION_MSG_CALL_VOICEMAIL);
126
127        // No data channel + Notification OK
128        // action: call voicemail
129        // msg: voicemail not available in call log page & audio not available in call details page.
130        values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
131        values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
132        updateEntryForPackage(TEST_PACKAGES[1], values);
133        checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_VOICEMAIL_NOT_AVAILABLE,
134                STATUS_MSG_AUDIO_NOT_AVAIALABLE, ACTION_MSG_CALL_VOICEMAIL);
135
136        // No data channel + Notification OK
137        // action: call voicemail
138        // msg: message waiting in call log page & audio not available in call details page.
139        values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING);
140        values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
141        updateEntryForPackage(TEST_PACKAGES[1], values);
142        checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_MESSAGE_WAITING,
143                STATUS_MSG_AUDIO_NOT_AVAIALABLE, ACTION_MSG_CALL_VOICEMAIL);
144
145        // Not configured. No user action, so no message.
146        values.put(CONFIGURATION_STATE, CONFIGURATION_STATE_NOT_CONFIGURED);
147        updateEntryForPackage(TEST_PACKAGES[1], values);
148        checkNoMessages(TEST_PACKAGES[1], values);
149
150        // Can be configured - invite user for configure voicemail.
151        values.put(CONFIGURATION_STATE, CONFIGURATION_STATE_CAN_BE_CONFIGURED);
152        updateEntryForPackage(TEST_PACKAGES[1], values);
153        checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_INVITE_FOR_CONFIGURATION,
154                STATUS_MSG_NONE, ACTION_MSG_CONFIGURE, TEST_SETTINGS_URI);
155    }
156
157    // Test that priority of messages are handled well.
158    public void testMessageOrdering() {
159        insertEntryForPackage(TEST_PACKAGES[0], getAllOkStatusValues());
160        insertEntryForPackage(TEST_PACKAGES[1], getAllOkStatusValues());
161
162        final ContentValues valuesNoNotificationGoodDataChannel = new ContentValues();
163        valuesNoNotificationGoodDataChannel.put(NOTIFICATION_CHANNEL_STATE,
164                NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
165        valuesNoNotificationGoodDataChannel.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_OK);
166
167        final ContentValues valuesNoNotificationNoDataChannel = new ContentValues();
168        valuesNoNotificationNoDataChannel.put(NOTIFICATION_CHANNEL_STATE,
169                NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
170        valuesNoNotificationNoDataChannel.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
171
172        // Package1 with valuesNoNotificationGoodDataChannel and
173        // package2 with  valuesNoNotificationNoDataChannel. Package2 should be above.
174        updateEntryForPackage(TEST_PACKAGES[0], valuesNoNotificationGoodDataChannel);
175        updateEntryForPackage(TEST_PACKAGES[1], valuesNoNotificationNoDataChannel);
176        List<StatusMessage> messages = getStatusMessages();
177        assertEquals(2, messages.size());
178        assertEquals(TEST_PACKAGES[0], messages.get(1).sourcePackage);
179        assertEquals(TEST_PACKAGES[1], messages.get(0).sourcePackage);
180
181        // Now reverse the values - ordering should be reversed as well.
182        updateEntryForPackage(TEST_PACKAGES[0], valuesNoNotificationNoDataChannel);
183        updateEntryForPackage(TEST_PACKAGES[1], valuesNoNotificationGoodDataChannel);
184        messages = getStatusMessages();
185        assertEquals(2, messages.size());
186        assertEquals(TEST_PACKAGES[0], messages.get(0).sourcePackage);
187        assertEquals(TEST_PACKAGES[1], messages.get(1).sourcePackage);
188    }
189
190    /** Checks that the expected source status message is returned by VoicemailStatusHelper. */
191    private void checkExpectedMessage(String sourcePackage, ContentValues values,
192            int expectedCallLogMsg, int expectedCallDetailsMsg, int expectedActionMsg,
193            Uri expectedUri) {
194        List<StatusMessage> messages = getStatusMessages();
195        assertEquals(1, messages.size());
196        checkMessageMatches(messages.get(0), sourcePackage, expectedCallLogMsg,
197                expectedCallDetailsMsg, expectedActionMsg, expectedUri);
198    }
199
200    private void checkExpectedMessage(String sourcePackage, ContentValues values,
201            int expectedCallLogMsg, int expectedCallDetailsMessage, int expectedActionMsg) {
202        checkExpectedMessage(sourcePackage, values, expectedCallLogMsg, expectedCallDetailsMessage,
203                expectedActionMsg, TEST_VOICEMAIL_URI);
204    }
205
206    private void checkMessageMatches(StatusMessage message, String expectedSourcePackage,
207            int expectedCallLogMsg, int expectedCallDetailsMsg, int expectedActionMsg,
208            Uri expectedUri) {
209        assertEquals(expectedSourcePackage, message.sourcePackage);
210        assertEquals(expectedCallLogMsg, message.callLogMessageId);
211        assertEquals(expectedCallDetailsMsg, message.callDetailsMessageId);
212        assertEquals(expectedActionMsg, message.actionMessageId);
213        if (expectedUri == null) {
214            assertNull(message.actionUri);
215        } else {
216            assertEquals(expectedUri, message.actionUri);
217        }
218    }
219
220    private void checkNoMessages(String sourcePackage, ContentValues values) {
221        assertEquals(1, updateEntryForPackage(sourcePackage, values));
222        List<StatusMessage> messages = getStatusMessages();
223        assertEquals(0, messages.size());
224    }
225
226    private ContentValues getAllOkStatusValues() {
227        ContentValues values = new ContentValues();
228        values.put(Status.SETTINGS_URI, TEST_SETTINGS_URI.toString());
229        values.put(Status.VOICEMAIL_ACCESS_URI, TEST_VOICEMAIL_URI.toString());
230        values.put(Status.CONFIGURATION_STATE, Status.CONFIGURATION_STATE_OK);
231        values.put(Status.DATA_CHANNEL_STATE, Status.DATA_CHANNEL_STATE_OK);
232        values.put(Status.NOTIFICATION_CHANNEL_STATE, Status.NOTIFICATION_CHANNEL_STATE_OK);
233        return values;
234    }
235
236    private void insertEntryForPackage(String sourcePackage, ContentValues values) {
237        // If insertion fails then try update as the record might already exist.
238        if (getContentResolver().insert(Status.buildSourceUri(sourcePackage), values) == null) {
239            updateEntryForPackage(sourcePackage, values);
240        }
241    }
242
243    private void deleteEntryForPackage(String sourcePackage) {
244        getContentResolver().delete(Status.buildSourceUri(sourcePackage), null, null);
245    }
246
247    private int updateEntryForPackage(String sourcePackage, ContentValues values) {
248        return getContentResolver().update(
249                Status.buildSourceUri(sourcePackage), values, null, null);
250    }
251
252    private List<StatusMessage> getStatusMessages() {
253        // Restrict the cursor to only the the test packages to eliminate any side effects if there
254        // are other status messages already stored on the device.
255        Cursor cursor = getContentResolver().query(Status.CONTENT_URI,
256                VoicemailStatusHelperImpl.PROJECTION, getTestPackageSelection(), null, null);
257        return mStatusHelper.getStatusMessages(cursor);
258    }
259
260    private String getTestPackageSelection() {
261        StringBuilder sb = new StringBuilder();
262        for (String sourcePackage : TEST_PACKAGES) {
263            if (sb.length() > 0) {
264                sb.append(" OR ");
265            }
266            sb.append(String.format("(source_package='%s')", sourcePackage));
267        }
268        return sb.toString();
269    }
270
271    private ContentResolver getContentResolver() {
272        return getContext().getContentResolver();
273    }
274}
275