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