1/*
2 * Copyright (C) 2014 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.inputmethod.latin.settings;
18
19import static org.mockito.Matchers.any;
20import static org.mockito.Mockito.when;
21
22import android.app.AlertDialog;
23import android.content.Context;
24import android.content.DialogInterface;
25import android.content.Intent;
26import android.test.ActivityInstrumentationTestCase2;
27import android.test.suitebuilder.annotation.MediumTest;
28import android.view.View;
29import android.widget.ListView;
30
31import com.android.inputmethod.latin.utils.ManagedProfileUtils;
32
33import org.mockito.Mock;
34import org.mockito.MockitoAnnotations;
35
36import java.util.concurrent.CountDownLatch;
37import java.util.concurrent.TimeUnit;
38
39@MediumTest
40public class AccountsSettingsFragmentTests
41        extends ActivityInstrumentationTestCase2<TestFragmentActivity> {
42    private static final String FRAG_NAME = AccountsSettingsFragment.class.getName();
43    private static final long TEST_TIMEOUT_MILLIS = 5000;
44
45    @Mock private ManagedProfileUtils mManagedProfileUtils;
46
47    public AccountsSettingsFragmentTests() {
48        super(TestFragmentActivity.class);
49    }
50
51    @Override
52    protected void setUp() throws Exception {
53        super.setUp();
54
55        // Initialize the mocks.
56        MockitoAnnotations.initMocks(this);
57        ManagedProfileUtils.setTestInstance(mManagedProfileUtils);
58
59        Intent intent = new Intent();
60        intent.putExtra(TestFragmentActivity.EXTRA_SHOW_FRAGMENT, FRAG_NAME);
61        setActivityIntent(intent);
62    }
63
64    @Override
65    public void tearDown() throws Exception {
66        ManagedProfileUtils.setTestInstance(null);
67        super.tearDown();
68    }
69
70    public void testEmptyAccounts() {
71        final AccountsSettingsFragment fragment =
72                (AccountsSettingsFragment) getActivity().mFragment;
73        try {
74            fragment.createAccountPicker(new String[0], null, null /* listener */);
75            fail("Expected IllegalArgumentException, never thrown");
76        } catch (IllegalArgumentException expected) {
77            // Expected.
78        }
79    }
80
81    private static class DialogHolder {
82        AlertDialog mDialog;
83        DialogHolder() {}
84    }
85
86    public void testMultipleAccounts_noSettingsForManagedProfile() {
87        when(mManagedProfileUtils.hasWorkProfile(any(Context.class))).thenReturn(true);
88
89        final AccountsSettingsFragment fragment =
90                (AccountsSettingsFragment) getActivity().mFragment;
91        final AlertDialog dialog = initDialog(fragment, null).mDialog;
92        final ListView lv = dialog.getListView();
93
94        // Nothing to check/uncheck.
95        assertNull(fragment.findPreference(AccountsSettingsFragment.PREF_ACCCOUNT_SWITCHER));
96    }
97
98    public void testMultipleAccounts_noCurrentAccount() {
99        when(mManagedProfileUtils.hasWorkProfile(any(Context.class))).thenReturn(false);
100
101        final AccountsSettingsFragment fragment =
102                (AccountsSettingsFragment) getActivity().mFragment;
103        final AlertDialog dialog = initDialog(fragment, null).mDialog;
104        final ListView lv = dialog.getListView();
105
106        // The 1st account should be checked by default.
107        assertEquals("checked-item", 0, lv.getCheckedItemPosition());
108        // There should be 4 accounts in the list.
109        assertEquals("count", 4, lv.getCount());
110        // The sign-out button shouldn't exist
111        assertEquals(View.GONE,
112                dialog.getButton(DialogInterface.BUTTON_NEUTRAL).getVisibility());
113        assertEquals(View.VISIBLE,
114                dialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility());
115        assertEquals(View.VISIBLE,
116                dialog.getButton(DialogInterface.BUTTON_POSITIVE).getVisibility());
117    }
118
119    public void testMultipleAccounts_currentAccount() {
120        when(mManagedProfileUtils.hasWorkProfile(any(Context.class))).thenReturn(false);
121
122        final AccountsSettingsFragment fragment =
123                (AccountsSettingsFragment) getActivity().mFragment;
124        final AlertDialog dialog = initDialog(fragment, "3@example.com").mDialog;
125        final ListView lv = dialog.getListView();
126
127        // The 3rd account should be checked by default.
128        assertEquals("checked-item", 2, lv.getCheckedItemPosition());
129        // There should be 4 accounts in the list.
130        assertEquals("count", 4, lv.getCount());
131        // The sign-out button should be shown
132        assertEquals(View.VISIBLE,
133                dialog.getButton(DialogInterface.BUTTON_NEUTRAL).getVisibility());
134        assertEquals(View.VISIBLE,
135                dialog.getButton(DialogInterface.BUTTON_NEGATIVE).getVisibility());
136        assertEquals(View.VISIBLE,
137                dialog.getButton(DialogInterface.BUTTON_POSITIVE).getVisibility());
138    }
139
140    private DialogHolder initDialog(
141            final AccountsSettingsFragment fragment,
142            final String selectedAccount) {
143        final DialogHolder dialogHolder = new DialogHolder();
144        final CountDownLatch latch = new CountDownLatch(1);
145
146        getActivity().runOnUiThread(new Runnable() {
147            @Override
148            public void run() {
149                final AlertDialog dialog = fragment.createAccountPicker(
150                        new String[] {
151                                "1@example.com",
152                                "2@example.com",
153                                "3@example.com",
154                                "4@example.com"},
155                        selectedAccount, null /* positiveButtonListner */);
156                dialog.show();
157                dialogHolder.mDialog = dialog;
158                latch.countDown();
159            }
160        });
161
162        try {
163            latch.await(TEST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
164        } catch (InterruptedException ex) {
165            fail();
166        }
167        getInstrumentation().waitForIdleSync();
168        return dialogHolder;
169    }
170}
171