Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 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 // Unit tests for helper functions for the Chrome Extensions Proxy Settings API.
      6 
      7 #include "base/scoped_ptr.h"
      8 #include "base/values.h"
      9 #include "chrome/browser/extensions/extension_proxy_api_constants.h"
     10 #include "chrome/browser/extensions/extension_proxy_api_helpers.h"
     11 #include "chrome/browser/prefs/proxy_config_dictionary.h"
     12 #include "chrome/browser/prefs/proxy_prefs.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 namespace keys = extension_proxy_api_constants;
     16 
     17 namespace {
     18 
     19 const char kSamplePacScript[] = "test";
     20 const char kSamplePacScriptAsDataUrl[] =
     21     "data:application/x-ns-proxy-autoconfig;base64,dGVzdA==";
     22 const char kSamplePacScriptUrl[] = "http://wpad/wpad.dat";
     23 
     24 // Helper function to create a ProxyServer dictionary as defined in the
     25 // extension API.
     26 DictionaryValue* CreateTestProxyServerDict(const std::string& host) {
     27   DictionaryValue* dict = new DictionaryValue;
     28   dict->SetString(keys::kProxyConfigRuleHost, host);
     29   return dict;
     30 }
     31 
     32 // Helper function to create a ProxyServer dictionary as defined in the
     33 // extension API.
     34 DictionaryValue* CreateTestProxyServerDict(const std::string& schema,
     35                                            const std::string& host,
     36                                            int port) {
     37   DictionaryValue* dict = new DictionaryValue;
     38   dict->SetString(keys::kProxyConfigRuleScheme, schema);
     39   dict->SetString(keys::kProxyConfigRuleHost, host);
     40   dict->SetInteger(keys::kProxyConfigRulePort, port);
     41   return dict;
     42 }
     43 
     44 }  // namespace
     45 
     46 namespace extension_proxy_api_helpers {
     47 
     48 TEST(ExtensionProxyApiHelpers, CreateDataURLFromPACScript) {
     49   std::string out;
     50   ASSERT_TRUE(CreateDataURLFromPACScript(kSamplePacScript, &out));
     51   EXPECT_EQ(kSamplePacScriptAsDataUrl, out);
     52 }
     53 
     54 TEST(ExtensionProxyApiHelpers, CreatePACScriptFromDataURL) {
     55   std::string out;
     56   ASSERT_TRUE(CreatePACScriptFromDataURL(kSamplePacScriptAsDataUrl, &out));
     57   EXPECT_EQ(kSamplePacScript, out);
     58 
     59   EXPECT_FALSE(CreatePACScriptFromDataURL("http://www.google.com", &out));
     60 }
     61 
     62 TEST(ExtensionProxyApiHelpers, GetProxyModeFromExtensionPref) {
     63   DictionaryValue proxy_config;
     64   ProxyPrefs::ProxyMode mode;
     65   std::string error;
     66 
     67   // Test positive case.
     68   proxy_config.SetString(
     69       keys::kProxyConfigMode,
     70       ProxyPrefs::ProxyModeToString(ProxyPrefs::MODE_DIRECT));
     71   ASSERT_TRUE(GetProxyModeFromExtensionPref(&proxy_config, &mode, &error));
     72   EXPECT_EQ(ProxyPrefs::MODE_DIRECT, mode);
     73   EXPECT_EQ(std::string(), error);
     74 
     75   // Test negative case.
     76   proxy_config.SetString(keys::kProxyConfigMode, "foobar");
     77   EXPECT_FALSE(GetProxyModeFromExtensionPref(&proxy_config, &mode, &error));
     78 
     79   // Do not test |error|, as an invalid enumeration value is considered an
     80   // internal error. It should be filtered by the extensions API.
     81 }
     82 
     83 TEST(ExtensionProxyApiHelpers, GetPacUrlFromExtensionPref) {
     84   std::string out;
     85   std::string error;
     86 
     87   DictionaryValue proxy_config;
     88   proxy_config.SetString(
     89       keys::kProxyConfigMode,
     90       ProxyPrefs::ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT));
     91 
     92   // Currently we are still missing a PAC script entry.
     93   // This is silently ignored.
     94   ASSERT_TRUE(GetPacUrlFromExtensionPref(&proxy_config, &out, &error));
     95   EXPECT_EQ(std::string(), out);
     96   EXPECT_EQ(std::string(), error);
     97 
     98   // Set up a pac script.
     99   DictionaryValue* pacScriptDict = new DictionaryValue;
    100   pacScriptDict->SetString(keys::kProxyConfigPacScriptUrl, kSamplePacScriptUrl);
    101   proxy_config.Set(keys::kProxyConfigPacScript, pacScriptDict);
    102 
    103   ASSERT_TRUE(GetPacUrlFromExtensionPref(&proxy_config, &out, &error));
    104   EXPECT_EQ(kSamplePacScriptUrl, out);
    105   EXPECT_EQ(std::string(), error);
    106 }
    107 
    108 TEST(ExtensionProxyApiHelpers, GetPacDataFromExtensionPref) {
    109   std::string out;
    110   std::string error;
    111 
    112   DictionaryValue proxy_config;
    113   proxy_config.SetString(
    114       keys::kProxyConfigMode,
    115       ProxyPrefs::ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT));
    116 
    117   // Currently we are still missing a PAC data entry. This is silently ignored.
    118   ASSERT_TRUE(GetPacDataFromExtensionPref(&proxy_config, &out, &error));
    119   EXPECT_EQ(std::string(), out);
    120   EXPECT_EQ(std::string(), error);
    121 
    122   // Set up a PAC script.
    123   DictionaryValue* pacScriptDict = new DictionaryValue;
    124   pacScriptDict->SetString(keys::kProxyConfigPacScriptData, kSamplePacScript);
    125   proxy_config.Set(keys::kProxyConfigPacScript, pacScriptDict);
    126 
    127   ASSERT_TRUE(GetPacDataFromExtensionPref(&proxy_config, &out, &error));
    128   EXPECT_EQ(kSamplePacScript, out);
    129   EXPECT_EQ(std::string(), error);
    130 }
    131 
    132 TEST(ExtensionProxyApiHelpers, GetProxyRulesStringFromExtensionPref) {
    133   std::string out;
    134   std::string error;
    135 
    136   DictionaryValue proxy_config;
    137   proxy_config.SetString(
    138       keys::kProxyConfigMode,
    139       ProxyPrefs::ProxyModeToString(ProxyPrefs::MODE_FIXED_SERVERS));
    140 
    141   // Currently we are still missing a proxy config entry.
    142   // This is silently ignored.
    143   ASSERT_TRUE(
    144       GetProxyRulesStringFromExtensionPref(&proxy_config, &out, &error));
    145   EXPECT_EQ(std::string(), out);
    146   EXPECT_EQ(std::string(), error);
    147 
    148   DictionaryValue* proxy_rules = new DictionaryValue;
    149   proxy_rules->Set(keys::field_name[1], CreateTestProxyServerDict("proxy1"));
    150   proxy_rules->Set(keys::field_name[2], CreateTestProxyServerDict("proxy2"));
    151   proxy_config.Set(keys::kProxyConfigRules, proxy_rules);
    152 
    153   ASSERT_TRUE(
    154       GetProxyRulesStringFromExtensionPref(&proxy_config, &out, &error));
    155   EXPECT_EQ("http=proxy1:80;https=proxy2:80", out);
    156   EXPECT_EQ(std::string(), error);
    157 }
    158 
    159 TEST(ExtensionProxyApiHelpers, GetBypassListFromExtensionPref) {
    160   std::string out;
    161   std::string error;
    162 
    163   DictionaryValue proxy_config;
    164   proxy_config.SetString(
    165       keys::kProxyConfigMode,
    166       ProxyPrefs::ProxyModeToString(ProxyPrefs::MODE_FIXED_SERVERS));
    167 
    168   // Currently we are still missing a proxy config entry.
    169   // This is silently ignored.
    170   ASSERT_TRUE(
    171       GetBypassListFromExtensionPref(&proxy_config, &out, &error));
    172   EXPECT_EQ(std::string(), out);
    173   EXPECT_EQ(std::string(), error);
    174 
    175   ListValue* bypass_list = new ListValue;
    176   bypass_list->Append(Value::CreateStringValue("host1"));
    177   bypass_list->Append(Value::CreateStringValue("host2"));
    178   DictionaryValue* proxy_rules = new DictionaryValue;
    179   proxy_rules->Set(keys::kProxyConfigBypassList, bypass_list);
    180   proxy_config.Set(keys::kProxyConfigRules, proxy_rules);
    181 
    182   ASSERT_TRUE(
    183       GetBypassListFromExtensionPref(&proxy_config, &out, &error));
    184   EXPECT_EQ("host1,host2", out);
    185   EXPECT_EQ(std::string(), error);
    186 }
    187 
    188 TEST(ExtensionProxyApiHelpers, CreateProxyConfigDict) {
    189   std::string error;
    190   scoped_ptr<DictionaryValue> exp_direct(ProxyConfigDictionary::CreateDirect());
    191   scoped_ptr<DictionaryValue> out_direct(
    192       CreateProxyConfigDict(ProxyPrefs::MODE_DIRECT, "", "", "", "", &error));
    193   EXPECT_TRUE(Value::Equals(exp_direct.get(), out_direct.get()));
    194 
    195   scoped_ptr<DictionaryValue> exp_auto(
    196       ProxyConfigDictionary::CreateAutoDetect());
    197   scoped_ptr<DictionaryValue> out_auto(
    198       CreateProxyConfigDict(ProxyPrefs::MODE_AUTO_DETECT, "", "", "", "",
    199                             &error));
    200   EXPECT_TRUE(Value::Equals(exp_auto.get(), out_auto.get()));
    201 
    202   scoped_ptr<DictionaryValue> exp_pac_url(
    203       ProxyConfigDictionary::CreatePacScript(kSamplePacScriptUrl));
    204   scoped_ptr<DictionaryValue> out_pac_url(
    205         CreateProxyConfigDict(ProxyPrefs::MODE_PAC_SCRIPT, kSamplePacScriptUrl,
    206                               "", "", "", &error));
    207   EXPECT_TRUE(Value::Equals(exp_pac_url.get(), out_pac_url.get()));
    208 
    209   scoped_ptr<DictionaryValue> exp_pac_data(
    210       ProxyConfigDictionary::CreatePacScript(kSamplePacScriptAsDataUrl));
    211   scoped_ptr<DictionaryValue> out_pac_data(
    212           CreateProxyConfigDict(ProxyPrefs::MODE_PAC_SCRIPT, "",
    213                                 kSamplePacScript, "", "", &error));
    214   EXPECT_TRUE(Value::Equals(exp_pac_data.get(), out_pac_data.get()));
    215 
    216   scoped_ptr<DictionaryValue> exp_fixed(
    217       ProxyConfigDictionary::CreateFixedServers("foo:80", "localhost"));
    218   scoped_ptr<DictionaryValue> out_fixed(
    219           CreateProxyConfigDict(ProxyPrefs::MODE_FIXED_SERVERS, "", "",
    220                                 "foo:80", "localhost", &error));
    221   EXPECT_TRUE(Value::Equals(exp_fixed.get(), out_fixed.get()));
    222 
    223   scoped_ptr<DictionaryValue> exp_system(ProxyConfigDictionary::CreateSystem());
    224   scoped_ptr<DictionaryValue> out_system(
    225       CreateProxyConfigDict(ProxyPrefs::MODE_SYSTEM, "", "", "", "", &error));
    226   EXPECT_TRUE(Value::Equals(exp_system.get(), out_system.get()));
    227 
    228   // Neither of them should have set an error.
    229   EXPECT_EQ(std::string(), error);
    230 }
    231 
    232 TEST(ExtensionProxyApiHelpers, GetProxyServer) {
    233   DictionaryValue proxy_server_dict;
    234   net::ProxyServer created;
    235   std::string error;
    236 
    237   // Test simplest case, no schema nor port specified --> defaults are used.
    238   proxy_server_dict.SetString(keys::kProxyConfigRuleHost, "proxy_server");
    239   ASSERT_TRUE(
    240       GetProxyServer(&proxy_server_dict, net::ProxyServer::SCHEME_HTTP,
    241                      &created, &error));
    242   EXPECT_EQ("PROXY proxy_server:80", created.ToPacString());
    243 
    244   // Test complete case.
    245   proxy_server_dict.SetString(keys::kProxyConfigRuleScheme, "socks4");
    246   proxy_server_dict.SetInteger(keys::kProxyConfigRulePort, 1234);
    247   ASSERT_TRUE(
    248         GetProxyServer(&proxy_server_dict, net::ProxyServer::SCHEME_HTTP,
    249                        &created, &error));
    250   EXPECT_EQ("SOCKS proxy_server:1234", created.ToPacString());
    251 }
    252 
    253 TEST(ExtensionProxyApiHelpers, JoinUrlList) {
    254   ListValue list;
    255   list.Append(Value::CreateStringValue("s1"));
    256   list.Append(Value::CreateStringValue("s2"));
    257   list.Append(Value::CreateStringValue("s3"));
    258 
    259   std::string out;
    260   std::string error;
    261   ASSERT_TRUE(JoinUrlList(&list, ";", &out, &error));
    262   EXPECT_EQ("s1;s2;s3", out);
    263 }
    264 
    265 // This tests CreateProxyServerDict as well.
    266 TEST(ExtensionProxyApiHelpers, CreateProxyRulesDict) {
    267   scoped_ptr<DictionaryValue> browser_pref(
    268       ProxyConfigDictionary::CreateFixedServers(
    269           "http=proxy1:80;https=proxy2:80;ftp=proxy3:80;socks=proxy4:80",
    270           "localhost"));
    271   ProxyConfigDictionary config(browser_pref.get());
    272   scoped_ptr<DictionaryValue> extension_pref(CreateProxyRulesDict(config));
    273   ASSERT_TRUE(extension_pref.get());
    274 
    275   scoped_ptr<DictionaryValue> expected(new DictionaryValue);
    276   expected->Set("proxyForHttp",
    277                 CreateTestProxyServerDict("http", "proxy1", 80));
    278   expected->Set("proxyForHttps",
    279                 CreateTestProxyServerDict("http", "proxy2", 80));
    280   expected->Set("proxyForFtp",
    281                 CreateTestProxyServerDict("http", "proxy3", 80));
    282   expected->Set("fallbackProxy",
    283                 CreateTestProxyServerDict("socks4", "proxy4", 80));
    284   ListValue* bypass_list = new ListValue;
    285   bypass_list->Append(Value::CreateStringValue("localhost"));
    286   expected->Set(keys::kProxyConfigBypassList, bypass_list);
    287 
    288   EXPECT_TRUE(Value::Equals(expected.get(), extension_pref.get()));
    289 }
    290 
    291 // Test if a PAC script URL is specified.
    292 TEST(ExtensionProxyApiHelpers, CreatePacScriptDictWithUrl) {
    293   scoped_ptr<DictionaryValue> browser_pref(
    294       ProxyConfigDictionary::CreatePacScript(kSamplePacScriptUrl));
    295   ProxyConfigDictionary config(browser_pref.get());
    296   scoped_ptr<DictionaryValue> extension_pref(CreatePacScriptDict(config));
    297   ASSERT_TRUE(extension_pref.get());
    298 
    299   scoped_ptr<DictionaryValue> expected(new DictionaryValue);
    300   expected->SetString(keys::kProxyConfigPacScriptUrl, kSamplePacScriptUrl);
    301 
    302   EXPECT_TRUE(Value::Equals(expected.get(), extension_pref.get()));
    303 }
    304 
    305 // Test if a PAC script is encoded in a data URL.
    306 TEST(ExtensionProxyApiHelpers, CreatePacScriptDictWidthData) {
    307   scoped_ptr<DictionaryValue> browser_pref(
    308       ProxyConfigDictionary::CreatePacScript(kSamplePacScriptAsDataUrl));
    309   ProxyConfigDictionary config(browser_pref.get());
    310   scoped_ptr<DictionaryValue> extension_pref(CreatePacScriptDict(config));
    311   ASSERT_TRUE(extension_pref.get());
    312 
    313   scoped_ptr<DictionaryValue> expected(new DictionaryValue);
    314   expected->SetString(keys::kProxyConfigPacScriptData, kSamplePacScript);
    315 
    316   EXPECT_TRUE(Value::Equals(expected.get(), extension_pref.get()));
    317 }
    318 
    319 TEST(ExtensionProxyApiHelpers, TokenizeToStringList) {
    320   ListValue expected;
    321   expected.Append(Value::CreateStringValue("s1"));
    322   expected.Append(Value::CreateStringValue("s2"));
    323   expected.Append(Value::CreateStringValue("s3"));
    324 
    325   scoped_ptr<ListValue> out(TokenizeToStringList("s1;s2;s3", ";"));
    326   EXPECT_TRUE(Value::Equals(&expected, out.get()));
    327 }
    328 
    329 }  // namespace extension_proxy_api_helpers
    330