1/*
2 * Copyright (C) 2008 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.email.activity.setup;
18
19import android.content.Context;
20import android.content.Intent;
21import android.test.ActivityInstrumentationTestCase2;
22import android.test.UiThreadTest;
23import android.test.suitebuilder.annotation.MediumTest;
24import android.view.View;
25import android.widget.CheckBox;
26import android.widget.EditText;
27
28import com.android.email.R;
29import com.android.email.setup.AuthenticatorSetupIntentHelper;
30import com.android.emailcommon.provider.Account;
31import com.android.emailcommon.provider.HostAuth;
32
33import java.net.URISyntaxException;
34
35/**
36 * Tests of the basic UI logic in the Account Setup Outgoing (SMTP) screen.
37 * You can run this entire test case with:
38 *   runtest -c com.android.email.activity.setup.AccountSetupOutgoingTests email
39 */
40@MediumTest
41public class AccountSetupOutgoingTests extends
42        ActivityInstrumentationTestCase2<AccountSetupFinal> {
43
44    private AccountSetupFinal mActivity;
45    private EditText mServerView;
46    private AuthenticationView mAuthenticationView;
47
48    public AccountSetupOutgoingTests() {
49        super(AccountSetupFinal.class);
50    }
51
52    /**
53     * Common setup code for all tests.  Sets up a default launch intent, which some tests
54     * will use (others will override).
55     */
56    @Override
57    protected void setUp() throws Exception {
58        super.setUp();
59
60        // This sets up a default URI which can be used by any of the test methods below.
61        // Individual test methods can replace this with a custom URI if they wish
62        // (except those that run on the UI thread - for them, it's too late to change it.)
63        Intent i = getTestIntent("smtp://user:password@server.com:999");
64        setActivityIntent(i);
65    }
66
67    private boolean isNextButtonEnabled() {
68        final View nextButton = mActivity.findViewById(R.id.next);
69        return nextButton.isEnabled();
70    }
71
72    /**
73     * Test processing with a complete, good URI -> good fields
74     */
75    @UiThreadTest
76    public void testGoodUri() {
77        getActivityAndFields();
78        assertTrue(isNextButtonEnabled());
79    }
80
81    /**
82     * No user is not OK - not enabled
83     */
84    public void testBadUriNoUser()
85            throws Throwable {
86        Intent i = getTestIntent("smtp://:password@server.com:999");
87        setActivityIntent(i);
88        getActivityAndFields();
89        runTestOnUiThread(new Runnable() {
90            @Override
91            public void run() {
92                final CheckBox requireLoginView = (CheckBox)
93                        mActivity.findViewById(R.id.account_require_login);
94                requireLoginView.setChecked(true);
95            }
96        });
97        assertFalse(isNextButtonEnabled());
98    }
99
100    /**
101     * No password is not OK - not enabled
102     */
103    public void testBadUriNoPassword()
104            throws URISyntaxException {
105        Intent i = getTestIntent("smtp://user@server.com:999");
106        setActivityIntent(i);
107        getActivityAndFields();
108        assertFalse(isNextButtonEnabled());
109    }
110
111    /**
112     * No port is OK - still enabled
113     */
114    public void testGoodUriNoPort()
115            throws URISyntaxException {
116        Intent i = getTestIntent("smtp://user:password@server.com");
117        setActivityIntent(i);
118        getActivityAndFields();
119        assertTrue(isNextButtonEnabled());
120    }
121
122    /**
123     * Test for non-standard but OK server names
124     */
125    @UiThreadTest
126    public void testGoodServerVariants() {
127        getActivityAndFields();
128        assertTrue(isNextButtonEnabled());
129
130        mServerView.setText("  server.com  ");
131        assertTrue(isNextButtonEnabled());
132    }
133
134    /**
135     * Test for non-empty but non-OK server names
136     */
137    @UiThreadTest
138    public void testBadServerVariants() {
139        getActivityAndFields();
140        assertTrue(isNextButtonEnabled());
141
142        mServerView.setText("  ");
143        assertFalse(isNextButtonEnabled());
144
145        mServerView.setText("serv$er.com");
146        assertFalse(isNextButtonEnabled());
147    }
148
149    /**
150     * Test to confirm that passwords with leading or trailing spaces are accepted verbatim.
151     */
152    @UiThreadTest
153    public void brokentestPasswordNoTrim() throws URISyntaxException {
154        getActivityAndFields();
155
156        // Clear the password - should disable
157        checkPassword(null, false);
158
159        // Various combinations of spaces should be OK
160        checkPassword(" leading", true);
161        checkPassword("trailing ", true);
162// TODO: need to fix this part of the test
163//        checkPassword("em bedded", true);
164//        checkPassword(" ", true);
165    }
166
167    /**
168     * Check password field for a given password.  Should be called in UI thread.  Confirms that
169     * the password has not been trimmed.
170     *
171     * @param password the password to test with
172     * @param expectNext true if expected that this password will enable the "next" button
173     */
174    private void checkPassword(String password, boolean expectNext) throws URISyntaxException {
175        mAuthenticationView.setPassword(password);
176        if (expectNext) {
177            assertTrue(isNextButtonEnabled());
178        } else {
179            assertFalse(isNextButtonEnabled());
180        }
181    }
182
183    /**
184     * TODO:  A series of tests to explore the logic around security models & ports
185     */
186
187    /**
188     * Get the activity (which causes it to be started, using our intent) and get the UI fields
189     */
190    private void getActivityAndFields() {
191        mActivity = getActivity();
192        mServerView = (EditText) mActivity.findViewById(R.id.account_server);
193        mAuthenticationView = (AuthenticationView) mActivity.findViewById(R.id.authentication_view);
194    }
195
196    /**
197     * Create an intent with the Account in it
198     */
199    private Intent getTestIntent(String senderUriString)
200            throws URISyntaxException {
201        final Account account = new Account();
202        final Context context = getInstrumentation().getTargetContext();
203        final HostAuth auth = account.getOrCreateHostAuthSend(context);
204        auth.setHostAuthFromString(senderUriString);
205        final SetupDataFragment setupDataFragment =
206                new SetupDataFragment();
207        setupDataFragment.setFlowMode(AuthenticatorSetupIntentHelper.FLOW_MODE_NORMAL);
208        setupDataFragment.setAccount(account);
209        final Intent i = new Intent(AccountSetupFinal.ACTION_JUMP_TO_OUTGOING);
210        i.putExtra(SetupDataFragment.EXTRA_SETUP_DATA, setupDataFragment);
211        return i;
212    }
213
214}
215