1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/prefs/pref_service.h"
6#include "chrome/browser/extensions/extension_apitest.h"
7#include "chrome/browser/prefs/proxy_config_dictionary.h"
8#include "chrome/browser/profiles/profile.h"
9#include "chrome/browser/ui/browser.h"
10#include "chrome/common/chrome_switches.h"
11#include "chrome/common/extensions/extension.h"
12#include "chrome/common/pref_names.h"
13
14namespace extensions {
15
16namespace {
17
18const char kNoServer[] = "";
19const char kNoBypass[] = "";
20const char kNoPac[] = "";
21
22}  // namespace
23
24class ProxySettingsApiTest : public ExtensionApiTest {
25 protected:
26  void ValidateSettings(int expected_mode,
27                        const std::string& expected_server,
28                        const std::string& bypass,
29                        const std::string& expected_pac_url,
30                        PrefService* pref_service) {
31    const PrefService::Preference* pref =
32        pref_service->FindPreference(prefs::kProxy);
33    ASSERT_TRUE(pref != NULL);
34    EXPECT_TRUE(pref->IsExtensionControlled());
35
36    ProxyConfigDictionary dict(pref_service->GetDictionary(prefs::kProxy));
37
38    ProxyPrefs::ProxyMode mode;
39    ASSERT_TRUE(dict.GetMode(&mode));
40    EXPECT_EQ(expected_mode, mode);
41
42    std::string value;
43    if (!bypass.empty()) {
44       ASSERT_TRUE(dict.GetBypassList(&value));
45       EXPECT_EQ(bypass, value);
46     } else {
47       EXPECT_FALSE(dict.GetBypassList(&value));
48     }
49
50    if (!expected_pac_url.empty()) {
51       ASSERT_TRUE(dict.GetPacUrl(&value));
52       EXPECT_EQ(expected_pac_url, value);
53     } else {
54       EXPECT_FALSE(dict.GetPacUrl(&value));
55     }
56
57    if (!expected_server.empty()) {
58      ASSERT_TRUE(dict.GetProxyServer(&value));
59      EXPECT_EQ(expected_server, value);
60    } else {
61      EXPECT_FALSE(dict.GetProxyServer(&value));
62    }
63  }
64
65  void ExpectNoSettings(PrefService* pref_service) {
66    const PrefService::Preference* pref =
67        pref_service->FindPreference(prefs::kProxy);
68    ASSERT_TRUE(pref != NULL);
69    EXPECT_FALSE(pref->IsExtensionControlled());
70  }
71};
72
73// Tests direct connection settings.
74IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyDirectSettings) {
75  ASSERT_TRUE(RunExtensionTestIncognito("proxy/direct")) << message_;
76  const Extension* extension = GetSingleLoadedExtension();
77  ASSERT_TRUE(extension);
78
79  PrefService* pref_service = browser()->profile()->GetPrefs();
80  ValidateSettings(ProxyPrefs::MODE_DIRECT, kNoServer, kNoBypass, kNoPac,
81                   pref_service);
82}
83
84// Tests auto-detect settings.
85IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyAutoSettings) {
86  ASSERT_TRUE(RunExtensionTestIncognito("proxy/auto")) << message_;
87  const Extension* extension = GetSingleLoadedExtension();
88  ASSERT_TRUE(extension);
89
90  PrefService* pref_service = browser()->profile()->GetPrefs();
91  ValidateSettings(ProxyPrefs::MODE_AUTO_DETECT, kNoServer, kNoBypass, kNoPac,
92                   pref_service);
93}
94
95// Tests PAC proxy settings.
96IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyPacScript) {
97  ASSERT_TRUE(RunExtensionTest("proxy/pac")) << message_;
98  const Extension* extension = GetSingleLoadedExtension();
99  ASSERT_TRUE(extension);
100
101  PrefService* pref_service = browser()->profile()->GetPrefs();
102  ValidateSettings(ProxyPrefs::MODE_PAC_SCRIPT, kNoServer, kNoBypass,
103                   "http://wpad/windows.pac", pref_service);
104}
105
106// Tests PAC proxy settings.
107IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyPacDataUrl) {
108  ASSERT_TRUE(RunExtensionTest("proxy/pacdataurl")) << message_;
109  const Extension* extension = GetSingleLoadedExtension();
110  ASSERT_TRUE(extension);
111  const char url[] =
112       "data:;base64,ZnVuY3Rpb24gRmluZFByb3h5R"
113       "m9yVVJMKHVybCwgaG9zdCkgewogIGlmIChob3N0ID09ICdmb29iYXIuY29tJykKICAgIHJl"
114       "dHVybiAnUFJPWFkgYmxhY2tob2xlOjgwJzsKICByZXR1cm4gJ0RJUkVDVCc7Cn0=";
115  PrefService* pref_service = browser()->profile()->GetPrefs();
116  ValidateSettings(ProxyPrefs::MODE_PAC_SCRIPT, kNoServer, kNoBypass,
117                   url, pref_service);
118}
119
120// Tests PAC proxy settings.
121IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyPacData) {
122  ASSERT_TRUE(RunExtensionTest("proxy/pacdata")) << message_;
123  const Extension* extension = GetSingleLoadedExtension();
124  ASSERT_TRUE(extension);
125  const char url[] =
126      "data:application/x-ns-proxy-autoconfig;base64,ZnVuY3Rpb24gRmluZFByb3h5R"
127      "m9yVVJMKHVybCwgaG9zdCkgewogIGlmIChob3N0ID09ICdmb29iYXIuY29tJykKICAgIHJl"
128      "dHVybiAnUFJPWFkgYmxhY2tob2xlOjgwJzsKICByZXR1cm4gJ0RJUkVDVCc7Cn0=";
129  PrefService* pref_service = browser()->profile()->GetPrefs();
130  ValidateSettings(ProxyPrefs::MODE_PAC_SCRIPT, kNoServer, kNoBypass,
131                   url, pref_service);
132}
133
134// Tests setting a single proxy to cover all schemes.
135IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyFixedSingle) {
136  ASSERT_TRUE(RunExtensionTest("proxy/single")) << message_;
137  const Extension* extension = GetSingleLoadedExtension();
138  ASSERT_TRUE(extension);
139
140  PrefService* pref_service = browser()->profile()->GetPrefs();
141  ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS,
142                 "127.0.0.1:100",
143                 kNoBypass,
144                 kNoPac,
145                 pref_service);
146}
147
148// Tests setting to use the system's proxy settings.
149IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxySystem) {
150  ASSERT_TRUE(RunExtensionTest("proxy/system")) << message_;
151  const Extension* extension = GetSingleLoadedExtension();
152  ASSERT_TRUE(extension);
153
154  PrefService* pref_service = browser()->profile()->GetPrefs();
155  ValidateSettings(ProxyPrefs::MODE_SYSTEM, kNoServer, kNoBypass, kNoPac,
156                   pref_service);
157}
158
159// Tests setting separate proxies for each scheme.
160IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyFixedIndividual) {
161  ASSERT_TRUE(RunExtensionTestIncognito("proxy/individual")) << message_;
162  const Extension* extension = GetSingleLoadedExtension();
163  ASSERT_TRUE(extension);
164
165  PrefService* pref_service = browser()->profile()->GetPrefs();
166  ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS,
167                   "http=1.1.1.1:80;"  // http:// is pruned.
168                       "https=2.2.2.2:80;"  // http:// is pruned.
169                       "ftp=3.3.3.3:9000;"  // http:// is pruned.
170                       "socks=socks4://4.4.4.4:9090",
171                   kNoBypass,
172                   kNoPac,
173                   pref_service);
174
175  // Now check the incognito preferences.
176  pref_service = browser()->profile()->GetOffTheRecordProfile()->GetPrefs();
177  ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS,
178                   "http=1.1.1.1:80;"
179                       "https=2.2.2.2:80;"
180                       "ftp=3.3.3.3:9000;"
181                       "socks=socks4://4.4.4.4:9090",
182                   kNoBypass,
183                   kNoPac,
184                   pref_service);
185}
186
187// Tests setting values only for incognito mode
188IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest,
189                       ProxyFixedIndividualIncognitoOnly) {
190  ASSERT_TRUE(RunExtensionTestIncognito("proxy/individual_incognito_only")) <<
191      message_;
192  const Extension* extension = GetSingleLoadedExtension();
193  ASSERT_TRUE(extension);
194
195  PrefService* pref_service = browser()->profile()->GetPrefs();
196  ExpectNoSettings(pref_service);
197
198  // Now check the incognito preferences.
199  pref_service = browser()->profile()->GetOffTheRecordProfile()->GetPrefs();
200  ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS,
201                   "http=1.1.1.1:80;"
202                       "https=socks5://2.2.2.2:1080;"
203                       "ftp=3.3.3.3:9000;"
204                       "socks=socks4://4.4.4.4:9090",
205                   kNoBypass,
206                   kNoPac,
207                   pref_service);
208}
209
210// Tests setting values also for incognito mode
211// Test disabled due to http://crbug.com/88972.
212IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest,
213                       DISABLED_ProxyFixedIndividualIncognitoAlso) {
214  ASSERT_TRUE(RunExtensionTestIncognito("proxy/individual_incognito_also")) <<
215      message_;
216  const Extension* extension = GetSingleLoadedExtension();
217  ASSERT_TRUE(extension);
218
219  PrefService* pref_service = browser()->profile()->GetPrefs();
220  ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS,
221                   "http=1.1.1.1:80;"
222                       "https=socks5://2.2.2.2:1080;"
223                       "ftp=3.3.3.3:9000;"
224                       "socks=socks4://4.4.4.4:9090",
225                   kNoBypass,
226                   kNoPac,
227                   pref_service);
228
229  // Now check the incognito preferences.
230  pref_service = browser()->profile()->GetOffTheRecordProfile()->GetPrefs();
231  ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS,
232                   "http=5.5.5.5:80;"
233                       "https=socks5://6.6.6.6:1080;"
234                       "ftp=7.7.7.7:9000;"
235                       "socks=socks4://8.8.8.8:9090",
236                   kNoBypass,
237                   kNoPac,
238                   pref_service);
239}
240
241// Tests setting and unsetting values
242IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyFixedIndividualRemove) {
243  ASSERT_TRUE(RunExtensionTest("proxy/individual_remove")) << message_;
244  const Extension* extension = GetSingleLoadedExtension();
245  ASSERT_TRUE(extension);
246
247  PrefService* pref_service = browser()->profile()->GetPrefs();
248  ExpectNoSettings(pref_service);
249}
250
251IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest,
252    ProxyBypass) {
253  ASSERT_TRUE(RunExtensionTestIncognito("proxy/bypass")) << message_;
254  const Extension* extension = GetSingleLoadedExtension();
255  ASSERT_TRUE(extension);
256
257  PrefService* pref_service = browser()->profile()->GetPrefs();
258  ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS,
259                   "http=1.1.1.1:80",
260                   "localhost,::1,foo.bar,<local>",
261                   kNoPac,
262                   pref_service);
263
264  // Now check the incognito preferences.
265  pref_service = browser()->profile()->GetOffTheRecordProfile()->GetPrefs();
266  ValidateSettings(ProxyPrefs::MODE_FIXED_SERVERS,
267                   "http=1.1.1.1:80",
268                   "localhost,::1,foo.bar,<local>",
269                   kNoPac,
270                   pref_service);
271}
272
273// This test sets proxy to an inavalid host "does.not.exist" and then fetches
274// a page from localhost, expecting an error since host is invalid.
275// On ChromeOS, localhost is by default bypassed, so the page from localhost
276// will be fetched successfully, resulting in no error.  Hence this test
277// shouldn't run on ChromeOS.
278#if defined(OS_CHROMEOS)
279#define MAYBE_ProxyEventsInvalidProxy DISABLED_ProxyEventsInvalidProxy
280#else
281#define MAYBE_ProxyEventsInvalidProxy ProxyEventsInvalidProxy
282#endif  // defined(OS_CHROMEOS)
283
284// Tests error events: invalid proxy
285IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, MAYBE_ProxyEventsInvalidProxy) {
286  ASSERT_TRUE(StartEmbeddedTestServer());
287  ASSERT_TRUE(
288      RunExtensionSubtest("proxy/events", "invalid_proxy.html")) << message_;
289}
290
291// Tests error events: PAC script parse error.
292IN_PROC_BROWSER_TEST_F(ProxySettingsApiTest, ProxyEventsParseError) {
293  ASSERT_TRUE(
294      RunExtensionSubtest("proxy/events", "parse_error.html")) << message_;
295}
296
297}  // namespace extensions
298