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.
5 // Unit tests for helper functions for the Chrome Extensions Proxy Settings API.
7 #include "base/memory/scoped_ptr.h"
8 #include "base/values.h"
9 #include "chrome/browser/extensions/api/proxy/proxy_api_constants.h"
10 #include "chrome/browser/extensions/api/proxy/proxy_api_helpers.h"
11 #include "components/proxy_config/proxy_config_dictionary.h"
12 #include "components/proxy_config/proxy_prefs.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace extensions
{
17 namespace keys
= proxy_api_constants
;
21 const char kSamplePacScript
[] = "test";
22 const char kSamplePacScriptAsDataUrl
[] =
23 "data:application/x-ns-proxy-autoconfig;base64,dGVzdA==";
24 const char kSamplePacScriptAsDataUrl2
[] =
25 "data:;base64,dGVzdA==";
26 const char kSamplePacScriptUrl
[] = "http://wpad/wpad.dat";
28 // Helper function to create a ProxyServer dictionary as defined in the
30 base::DictionaryValue
* CreateTestProxyServerDict(const std::string
& host
) {
31 base::DictionaryValue
* dict
= new base::DictionaryValue
;
32 dict
->SetString(keys::kProxyConfigRuleHost
, host
);
36 // Helper function to create a ProxyServer dictionary as defined in the
38 base::DictionaryValue
* CreateTestProxyServerDict(const std::string
& schema
,
39 const std::string
& host
,
41 base::DictionaryValue
* dict
= new base::DictionaryValue
;
42 dict
->SetString(keys::kProxyConfigRuleScheme
, schema
);
43 dict
->SetString(keys::kProxyConfigRuleHost
, host
);
44 dict
->SetInteger(keys::kProxyConfigRulePort
, port
);
50 namespace proxy_api_helpers
{
52 TEST(ExtensionProxyApiHelpers
, CreateDataURLFromPACScript
) {
54 ASSERT_TRUE(CreateDataURLFromPACScript(kSamplePacScript
, &out
));
55 EXPECT_EQ(kSamplePacScriptAsDataUrl
, out
);
58 TEST(ExtensionProxyApiHelpers
, CreatePACScriptFromDataURL
) {
60 // Verify deserialization of a PAC data:// URL that we created ourselves.
61 ASSERT_TRUE(CreatePACScriptFromDataURL(kSamplePacScriptAsDataUrl
, &out
));
62 EXPECT_EQ(kSamplePacScript
, out
);
64 // Check that we don't require a mime-type.
65 ASSERT_TRUE(CreatePACScriptFromDataURL(kSamplePacScriptAsDataUrl2
, &out
));
66 EXPECT_EQ(kSamplePacScript
, out
);
68 EXPECT_FALSE(CreatePACScriptFromDataURL("http://www.google.com", &out
));
71 TEST(ExtensionProxyApiHelpers
, GetProxyModeFromExtensionPref
) {
72 base::DictionaryValue proxy_config
;
73 ProxyPrefs::ProxyMode mode
;
75 bool bad_message
= false;
77 // Test positive case.
78 proxy_config
.SetString(
79 keys::kProxyConfigMode
,
80 ProxyPrefs::ProxyModeToString(ProxyPrefs::MODE_DIRECT
));
81 ASSERT_TRUE(GetProxyModeFromExtensionPref(&proxy_config
, &mode
, &error
,
83 EXPECT_EQ(ProxyPrefs::MODE_DIRECT
, mode
);
84 EXPECT_EQ(std::string(), error
);
85 EXPECT_FALSE(bad_message
);
87 // Test negative case.
88 proxy_config
.SetString(keys::kProxyConfigMode
, "foobar");
89 EXPECT_FALSE(GetProxyModeFromExtensionPref(&proxy_config
, &mode
, &error
,
91 EXPECT_TRUE(bad_message
);
93 // Do not test |error|, as an invalid enumeration value is considered an
94 // internal error. It should be filtered by the extensions API.
97 TEST(ExtensionProxyApiHelpers
, GetPacUrlFromExtensionPref
) {
100 bool bad_message
= false;
102 base::DictionaryValue proxy_config
;
103 proxy_config
.SetString(
104 keys::kProxyConfigMode
,
105 ProxyPrefs::ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT
));
107 // Currently we are still missing a PAC script entry.
108 // This is silently ignored.
109 ASSERT_TRUE(GetPacUrlFromExtensionPref(&proxy_config
, &out
, &error
,
111 EXPECT_EQ(std::string(), out
);
112 EXPECT_EQ(std::string(), error
);
113 EXPECT_FALSE(bad_message
);
115 // Set up a pac script.
116 base::DictionaryValue
* pacScriptDict
= new base::DictionaryValue
;
117 pacScriptDict
->SetString(keys::kProxyConfigPacScriptUrl
, kSamplePacScriptUrl
);
118 proxy_config
.Set(keys::kProxyConfigPacScript
, pacScriptDict
);
120 ASSERT_TRUE(GetPacUrlFromExtensionPref(&proxy_config
, &out
, &error
,
122 EXPECT_EQ(kSamplePacScriptUrl
, out
);
123 EXPECT_EQ(std::string(), error
);
124 EXPECT_FALSE(bad_message
);
127 TEST(ExtensionProxyApiHelpers
, GetPacDataFromExtensionPref
) {
130 bool bad_message
= false;
132 base::DictionaryValue proxy_config
;
133 proxy_config
.SetString(
134 keys::kProxyConfigMode
,
135 ProxyPrefs::ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT
));
137 // Currently we are still missing a PAC data entry. This is silently ignored.
138 ASSERT_TRUE(GetPacDataFromExtensionPref(&proxy_config
, &out
, &error
,
140 EXPECT_EQ(std::string(), out
);
141 EXPECT_EQ(std::string(), error
);
142 EXPECT_FALSE(bad_message
);
144 // Set up a PAC script.
145 base::DictionaryValue
* pacScriptDict
= new base::DictionaryValue
;
146 pacScriptDict
->SetString(keys::kProxyConfigPacScriptData
, kSamplePacScript
);
147 proxy_config
.Set(keys::kProxyConfigPacScript
, pacScriptDict
);
149 ASSERT_TRUE(GetPacDataFromExtensionPref(&proxy_config
, &out
, &error
,
151 EXPECT_EQ(kSamplePacScript
, out
);
152 EXPECT_EQ(std::string(), error
);
153 EXPECT_FALSE(bad_message
);
156 TEST(ExtensionProxyApiHelpers
, GetProxyRulesStringFromExtensionPref
) {
159 bool bad_message
= false;
161 base::DictionaryValue proxy_config
;
162 proxy_config
.SetString(
163 keys::kProxyConfigMode
,
164 ProxyPrefs::ProxyModeToString(ProxyPrefs::MODE_FIXED_SERVERS
));
166 // Currently we are still missing a proxy config entry.
167 // This is silently ignored.
169 GetProxyRulesStringFromExtensionPref(&proxy_config
, &out
, &error
,
171 EXPECT_EQ(std::string(), out
);
172 EXPECT_EQ(std::string(), error
);
174 base::DictionaryValue
* proxy_rules
= new base::DictionaryValue
;
175 proxy_rules
->Set(keys::field_name
[1], CreateTestProxyServerDict("proxy1"));
176 proxy_rules
->Set(keys::field_name
[2], CreateTestProxyServerDict("proxy2"));
177 proxy_config
.Set(keys::kProxyConfigRules
, proxy_rules
);
180 GetProxyRulesStringFromExtensionPref(&proxy_config
, &out
, &error
,
182 EXPECT_EQ("http=proxy1:80;https=proxy2:80", out
);
183 EXPECT_EQ(std::string(), error
);
184 EXPECT_FALSE(bad_message
);
187 TEST(ExtensionProxyApiHelpers
, GetBypassListFromExtensionPref
) {
190 bool bad_message
= false;
192 base::DictionaryValue proxy_config
;
193 proxy_config
.SetString(
194 keys::kProxyConfigMode
,
195 ProxyPrefs::ProxyModeToString(ProxyPrefs::MODE_FIXED_SERVERS
));
197 // Currently we are still missing a proxy config entry.
198 // This is silently ignored.
200 GetBypassListFromExtensionPref(&proxy_config
, &out
, &error
,
202 EXPECT_EQ(std::string(), out
);
203 EXPECT_EQ(std::string(), error
);
204 EXPECT_FALSE(bad_message
);
206 base::ListValue
* bypass_list
= new base::ListValue
;
207 bypass_list
->Append(new base::StringValue("host1"));
208 bypass_list
->Append(new base::StringValue("host2"));
209 base::DictionaryValue
* proxy_rules
= new base::DictionaryValue
;
210 proxy_rules
->Set(keys::kProxyConfigBypassList
, bypass_list
);
211 proxy_config
.Set(keys::kProxyConfigRules
, proxy_rules
);
214 GetBypassListFromExtensionPref(&proxy_config
, &out
, &error
,
216 EXPECT_EQ("host1,host2", out
);
217 EXPECT_EQ(std::string(), error
);
218 EXPECT_FALSE(bad_message
);
221 TEST(ExtensionProxyApiHelpers
, CreateProxyConfigDict
) {
223 scoped_ptr
<base::DictionaryValue
> exp_direct(
224 ProxyConfigDictionary::CreateDirect());
225 scoped_ptr
<base::DictionaryValue
> out_direct(
226 CreateProxyConfigDict(ProxyPrefs::MODE_DIRECT
,
233 EXPECT_TRUE(base::Value::Equals(exp_direct
.get(), out_direct
.get()));
235 scoped_ptr
<base::DictionaryValue
> exp_auto(
236 ProxyConfigDictionary::CreateAutoDetect());
237 scoped_ptr
<base::DictionaryValue
> out_auto(
238 CreateProxyConfigDict(ProxyPrefs::MODE_AUTO_DETECT
,
245 EXPECT_TRUE(base::Value::Equals(exp_auto
.get(), out_auto
.get()));
247 scoped_ptr
<base::DictionaryValue
> exp_pac_url(
248 ProxyConfigDictionary::CreatePacScript(kSamplePacScriptUrl
, false));
249 scoped_ptr
<base::DictionaryValue
> out_pac_url(
250 CreateProxyConfigDict(ProxyPrefs::MODE_PAC_SCRIPT
,
257 EXPECT_TRUE(base::Value::Equals(exp_pac_url
.get(), out_pac_url
.get()));
259 scoped_ptr
<base::DictionaryValue
> exp_pac_data(
260 ProxyConfigDictionary::CreatePacScript(kSamplePacScriptAsDataUrl
, false));
261 scoped_ptr
<base::DictionaryValue
> out_pac_data(
262 CreateProxyConfigDict(ProxyPrefs::MODE_PAC_SCRIPT
,
269 EXPECT_TRUE(base::Value::Equals(exp_pac_data
.get(), out_pac_data
.get()));
271 scoped_ptr
<base::DictionaryValue
> exp_fixed(
272 ProxyConfigDictionary::CreateFixedServers("foo:80", "localhost"));
273 scoped_ptr
<base::DictionaryValue
> out_fixed(
274 CreateProxyConfigDict(ProxyPrefs::MODE_FIXED_SERVERS
,
281 EXPECT_TRUE(base::Value::Equals(exp_fixed
.get(), out_fixed
.get()));
283 scoped_ptr
<base::DictionaryValue
> exp_system(
284 ProxyConfigDictionary::CreateSystem());
285 scoped_ptr
<base::DictionaryValue
> out_system(
286 CreateProxyConfigDict(ProxyPrefs::MODE_SYSTEM
,
293 EXPECT_TRUE(base::Value::Equals(exp_system
.get(), out_system
.get()));
295 // Neither of them should have set an error.
296 EXPECT_EQ(std::string(), error
);
299 TEST(ExtensionProxyApiHelpers
, GetProxyServer
) {
300 base::DictionaryValue proxy_server_dict
;
301 net::ProxyServer created
;
303 bool bad_message
= false;
305 // Test simplest case, no schema nor port specified --> defaults are used.
306 proxy_server_dict
.SetString(keys::kProxyConfigRuleHost
, "proxy_server");
308 GetProxyServer(&proxy_server_dict
, net::ProxyServer::SCHEME_HTTP
,
309 &created
, &error
, &bad_message
));
310 EXPECT_EQ("PROXY proxy_server:80", created
.ToPacString());
311 EXPECT_FALSE(bad_message
);
313 // Test complete case.
314 proxy_server_dict
.SetString(keys::kProxyConfigRuleScheme
, "socks4");
315 proxy_server_dict
.SetInteger(keys::kProxyConfigRulePort
, 1234);
317 GetProxyServer(&proxy_server_dict
, net::ProxyServer::SCHEME_HTTP
,
318 &created
, &error
, &bad_message
));
319 EXPECT_EQ("SOCKS proxy_server:1234", created
.ToPacString());
320 EXPECT_FALSE(bad_message
);
323 TEST(ExtensionProxyApiHelpers
, JoinUrlList
) {
324 bool bad_message
= false;
325 base::ListValue list
;
326 list
.Append(new base::StringValue("s1"));
327 list
.Append(new base::StringValue("s2"));
328 list
.Append(new base::StringValue("s3"));
332 ASSERT_TRUE(JoinUrlList(&list
, ";", &out
, &error
, &bad_message
));
333 EXPECT_EQ("s1;s2;s3", out
);
334 EXPECT_FALSE(bad_message
);
337 // This tests CreateProxyServerDict as well.
338 TEST(ExtensionProxyApiHelpers
, CreateProxyRulesDict
) {
339 scoped_ptr
<base::DictionaryValue
> browser_pref(
340 ProxyConfigDictionary::CreateFixedServers(
341 "http=proxy1:80;https=proxy2:80;ftp=proxy3:80;socks=proxy4:80",
343 ProxyConfigDictionary
config(browser_pref
.get());
344 scoped_ptr
<base::DictionaryValue
> extension_pref(
345 CreateProxyRulesDict(config
));
346 ASSERT_TRUE(extension_pref
.get());
348 scoped_ptr
<base::DictionaryValue
> expected(new base::DictionaryValue
);
349 expected
->Set("proxyForHttp",
350 CreateTestProxyServerDict("http", "proxy1", 80));
351 expected
->Set("proxyForHttps",
352 CreateTestProxyServerDict("http", "proxy2", 80));
353 expected
->Set("proxyForFtp",
354 CreateTestProxyServerDict("http", "proxy3", 80));
355 expected
->Set("fallbackProxy",
356 CreateTestProxyServerDict("socks4", "proxy4", 80));
357 base::ListValue
* bypass_list
= new base::ListValue
;
358 bypass_list
->Append(new base::StringValue("localhost"));
359 expected
->Set(keys::kProxyConfigBypassList
, bypass_list
);
361 EXPECT_TRUE(base::Value::Equals(expected
.get(), extension_pref
.get()));
364 // Test multiple proxies per scheme -- expect that only the first is returned.
365 TEST(ExtensionProxyApiHelpers
, CreateProxyRulesDictMultipleProxies
) {
366 scoped_ptr
<base::DictionaryValue
> browser_pref(
367 ProxyConfigDictionary::CreateFixedServers(
368 "http=proxy1:80,default://;https=proxy2:80,proxy1:80;ftp=proxy3:80,"
369 "https://proxy5:443;socks=proxy4:80,proxy1:80",
371 ProxyConfigDictionary
config(browser_pref
.get());
372 scoped_ptr
<base::DictionaryValue
> extension_pref(
373 CreateProxyRulesDict(config
));
374 ASSERT_TRUE(extension_pref
.get());
376 scoped_ptr
<base::DictionaryValue
> expected(new base::DictionaryValue
);
377 expected
->Set("proxyForHttp",
378 CreateTestProxyServerDict("http", "proxy1", 80));
379 expected
->Set("proxyForHttps",
380 CreateTestProxyServerDict("http", "proxy2", 80));
381 expected
->Set("proxyForFtp",
382 CreateTestProxyServerDict("http", "proxy3", 80));
383 expected
->Set("fallbackProxy",
384 CreateTestProxyServerDict("socks4", "proxy4", 80));
385 base::ListValue
* bypass_list
= new base::ListValue
;
386 bypass_list
->Append(new base::StringValue("localhost"));
387 expected
->Set(keys::kProxyConfigBypassList
, bypass_list
);
389 EXPECT_TRUE(base::Value::Equals(expected
.get(), extension_pref
.get()));
392 // Test if a PAC script URL is specified.
393 TEST(ExtensionProxyApiHelpers
, CreatePacScriptDictWithUrl
) {
394 scoped_ptr
<base::DictionaryValue
> browser_pref(
395 ProxyConfigDictionary::CreatePacScript(kSamplePacScriptUrl
, false));
396 ProxyConfigDictionary
config(browser_pref
.get());
397 scoped_ptr
<base::DictionaryValue
> extension_pref(CreatePacScriptDict(config
));
398 ASSERT_TRUE(extension_pref
.get());
400 scoped_ptr
<base::DictionaryValue
> expected(new base::DictionaryValue
);
401 expected
->SetString(keys::kProxyConfigPacScriptUrl
, kSamplePacScriptUrl
);
402 expected
->SetBoolean(keys::kProxyConfigPacScriptMandatory
, false);
404 EXPECT_TRUE(base::Value::Equals(expected
.get(), extension_pref
.get()));
407 // Test if a PAC script is encoded in a data URL.
408 TEST(ExtensionProxyApiHelpers
, CreatePacScriptDictWidthData
) {
409 scoped_ptr
<base::DictionaryValue
> browser_pref(
410 ProxyConfigDictionary::CreatePacScript(kSamplePacScriptAsDataUrl
, false));
411 ProxyConfigDictionary
config(browser_pref
.get());
412 scoped_ptr
<base::DictionaryValue
> extension_pref(CreatePacScriptDict(config
));
413 ASSERT_TRUE(extension_pref
.get());
415 scoped_ptr
<base::DictionaryValue
> expected(new base::DictionaryValue
);
416 expected
->SetString(keys::kProxyConfigPacScriptData
, kSamplePacScript
);
417 expected
->SetBoolean(keys::kProxyConfigPacScriptMandatory
, false);
419 EXPECT_TRUE(base::Value::Equals(expected
.get(), extension_pref
.get()));
422 TEST(ExtensionProxyApiHelpers
, TokenizeToStringList
) {
423 base::ListValue expected
;
424 expected
.Append(new base::StringValue("s1"));
425 expected
.Append(new base::StringValue("s2"));
426 expected
.Append(new base::StringValue("s3"));
428 scoped_ptr
<base::ListValue
> out(TokenizeToStringList("s1;s2;s3", ";"));
429 EXPECT_TRUE(base::Value::Equals(&expected
, out
.get()));
432 } // namespace proxy_api_helpers
433 } // namespace extensions