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.emailcommon.utility;
18
19import android.test.AndroidTestCase;
20import android.test.MoreAsserts;
21import android.test.suitebuilder.annotation.SmallTest;
22
23import java.util.Random;
24import java.util.regex.Pattern;
25
26/**
27 * Unit tests for SSLUtils.
28 */
29@SmallTest
30public class SSLUtilsTest extends AndroidTestCase {
31
32    String SAFE_SCHEME_PATTERN = "[a-z][a-z0-9+\\-]*";
33    private void assertSchemeNameValid(String s) {
34        assertTrue(Pattern.matches(SAFE_SCHEME_PATTERN, s));
35    }
36
37    public void testSchemeNameEscapeAlreadySafe() {
38        // Safe names are unmodified.
39        assertEquals("http", SSLUtils.escapeForSchemeName("http"));
40        assertEquals("https", SSLUtils.escapeForSchemeName("https"));
41        assertEquals("ftp", SSLUtils.escapeForSchemeName("ftp"));
42        assertEquals("z39.50r", SSLUtils.escapeForSchemeName("z39.50r"));
43        assertEquals("fake-protocol.yes", SSLUtils.escapeForSchemeName("fake-protocol.yes"));
44    }
45
46    public void testSchemeNameEscapeIsSafe() {
47        // Invalid characters are escaped properly
48        assertSchemeNameValid(SSLUtils.escapeForSchemeName("name with spaces"));
49        assertSchemeNameValid(SSLUtils.escapeForSchemeName("odd * & characters"));
50        assertSchemeNameValid(SSLUtils.escapeForSchemeName("f3v!l;891023-47 +"));
51    }
52
53    private static final char[] RANDOM_DICT = new char[] {
54        'x', '.', '^', '4', ';', ' ', 'j', '#', '~', '+'
55    };
56    private String randomString(Random r) {
57        // 5 to 15 characters
58        int length = (r.nextInt() % 5) + 10;
59        StringBuilder sb = new StringBuilder();
60        for (int i = 0; i < length; i++) {
61            sb.append(RANDOM_DICT[Math.abs(r.nextInt()) % RANDOM_DICT.length]);
62        }
63        return sb.toString();
64    }
65
66    public void testSchemeNamesAreMoreOrLessUnique() {
67        assertEquals(
68                SSLUtils.escapeForSchemeName("name with spaces"),
69                SSLUtils.escapeForSchemeName("name with spaces"));
70
71        // As expected, all escaping is case insensitive.
72        assertEquals(
73                SSLUtils.escapeForSchemeName("NAME with spaces"),
74                SSLUtils.escapeForSchemeName("name with spaces"));
75
76        Random random = new Random(314159 /* seed */);
77        for (int i = 0; i < 100; i++) {
78            // Other strings should more or less be unique.
79            String s1 = randomString(random);
80            String s2 = randomString(random);
81            MoreAsserts.assertNotEqual(
82                    SSLUtils.escapeForSchemeName(s1),
83                    SSLUtils.escapeForSchemeName(s2));
84        }
85    }
86}
87
88