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