1b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook/*
2b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * Copyright (C) 2009 Marc Blank
3b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * Licensed to The Android Open Source Project.
4b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook *
5b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * Licensed under the Apache License, Version 2.0 (the "License");
6b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * you may not use this file except in compliance with the License.
7b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * You may obtain a copy of the License at
8b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook *
9b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook *      http://www.apache.org/licenses/LICENSE-2.0
10b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook *
11b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * Unless required by applicable law or agreed to in writing, software
12b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * distributed under the License is distributed on an "AS IS" BASIS,
13b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * See the License for the specific language governing permissions and
15b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * limitations under the License.
16b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook */
17b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
18b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookpackage com.android.exchange;
19b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
20b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.content.Context;
21b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.test.AndroidTestCase;
22b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.test.suitebuilder.annotation.SmallTest;
23b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport android.util.Base64;
24b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
25b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport com.android.emailcommon.provider.Account;
26b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
27b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport org.apache.http.Header;
28b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport org.apache.http.client.methods.HttpPost;
29b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport org.apache.http.client.methods.HttpRequestBase;
30b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
31b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookimport java.io.IOException;
32b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
33b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook/**
34b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook * You can run this entire test case with:
35b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook *   runtest -c com.android.exchange.EasSyncServiceTests exchange
36b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook */
37b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook@SmallTest
38b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrookpublic class EasSyncServiceTests extends AndroidTestCase {
39b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    static private final String USER = "user";
40b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    static private final String PASSWORD = "password";
41b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    static private final String HOST = "xxx.host.zzz";
42b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    static private final String ID = "id";
43b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
44b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    Context mMockContext;
45b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
46b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    @Override
47b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    public void setUp() throws Exception {
48b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        super.setUp();
49b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        mMockContext = getContext();
50b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
51b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
52b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    public void testAddHeaders() {
53b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        HttpRequestBase method = new HttpPost();
54b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        EasSyncService svc = new EasSyncService();
55b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.mAuthString = "auth";
56b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.mProtocolVersion = "12.1";
57b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.mAccount = null;
58b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // With second argument false, there should be no header
59b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.setHeaders(method, false);
60b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        Header[] headers = method.getHeaders("X-MS-PolicyKey");
61b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals(0, headers.length);
62b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // With second argument true, there should always be a header
63b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // The value will be "0" without an account
64b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        method.removeHeaders("X-MS-PolicyKey");
65b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.setHeaders(method, true);
66b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        headers = method.getHeaders("X-MS-PolicyKey");
67b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals(1, headers.length);
68b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals("0", headers[0].getValue());
69b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // With an account, but null security key, the header's value should be "0"
70b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        Account account = new Account();
71b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        account.mSecuritySyncKey = null;
72b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.mAccount = account;
73b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        method.removeHeaders("X-MS-PolicyKey");
74b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.setHeaders(method, true);
75b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        headers = method.getHeaders("X-MS-PolicyKey");
76b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals(1, headers.length);
77b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals("0", headers[0].getValue());
78b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // With an account and security key, the header's value should be the security key
79b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        account.mSecuritySyncKey = "key";
80b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.mAccount = account;
81b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        method.removeHeaders("X-MS-PolicyKey");
82b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.setHeaders(method, true);
83b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        headers = method.getHeaders("X-MS-PolicyKey");
84b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals(1, headers.length);
85b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals("key", headers[0].getValue());
86b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
87b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
88b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    public void testGetProtocolVersionDouble() {
89b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals(Eas.SUPPORTED_PROTOCOL_EX2003_DOUBLE,
90b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                Eas.getProtocolVersionDouble(Eas.SUPPORTED_PROTOCOL_EX2003));
91b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals(Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE,
92b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                Eas.getProtocolVersionDouble(Eas.SUPPORTED_PROTOCOL_EX2007));
93b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals(Eas.SUPPORTED_PROTOCOL_EX2007_SP1_DOUBLE,
94b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                Eas.getProtocolVersionDouble(Eas.SUPPORTED_PROTOCOL_EX2007_SP1));
95b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
96b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
97b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    private EasSyncService setupService(String user) {
98b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        EasSyncService svc = new EasSyncService();
99b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.mUserName = user;
100b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.mPassword = PASSWORD;
101b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.mDeviceId = ID;
102b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc.mHostAddress = HOST;
103b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        return svc;
104b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
105b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook
106b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    public void testMakeUriString() throws IOException {
107b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // Simple user name and command
108b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        EasSyncService svc = setupService(USER);
109b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        String uriString = svc.makeUriString("Sync", null);
110b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // These next two should now be cached
111b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertNotNull(svc.mAuthString);
112b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertNotNull(svc.mUserString);
113b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals("Basic " + Base64.encodeToString((USER+":"+PASSWORD).getBytes(),
114b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                Base64.NO_WRAP), svc.mAuthString);
115b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals("&User=" + USER + "&DeviceId=" + ID + "&DeviceType=" +
116b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                EasSyncService.DEVICE_TYPE, svc.mUserString);
117b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals("https://" + HOST + "/Microsoft-Server-ActiveSync?Cmd=Sync" +
118b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                svc.mUserString, uriString);
119b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        // User name that requires encoding
120b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        String user = "name_with_underscore@foo%bar.com";
121b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        svc = setupService(user);
122b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        uriString = svc.makeUriString("Sync", null);
123b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals("Basic " + Base64.encodeToString((user+":"+PASSWORD).getBytes(),
124b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                Base64.NO_WRAP), svc.mAuthString);
125b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        String safeUserName = "name_with_underscore%40foo%25bar.com";
126b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals("&User=" + safeUserName + "&DeviceId=" + ID + "&DeviceType=" +
127b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                EasSyncService.DEVICE_TYPE, svc.mUserString);
128b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook        assertEquals("https://" + HOST + "/Microsoft-Server-ActiveSync?Cmd=Sync" +
129b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook                svc.mUserString, uriString);
130b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook    }
131b931f82fa44c2e26e2645c0d5fde9eef3e666efdPaul Westbrook}
132