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 <gtest/gtest.h> 6 7 #include "base/command_line.h" 8 #include "base/memory/ref_counted.h" 9 #include "base/strings/string_util.h" 10 #include "base/values.h" 11 #include "chrome/browser/prefs/command_line_pref_store.h" 12 #include "chrome/browser/prefs/proxy_config_dictionary.h" 13 #include "chrome/common/chrome_switches.h" 14 #include "chrome/common/pref_names.h" 15 #include "ui/base/ui_base_switches.h" 16 17 namespace { 18 19 const char unknown_bool[] = "unknown_switch"; 20 const char unknown_string[] = "unknown_other_switch"; 21 22 } // namespace 23 24 class TestCommandLinePrefStore : public CommandLinePrefStore { 25 public: 26 explicit TestCommandLinePrefStore(CommandLine* cl) 27 : CommandLinePrefStore(cl) {} 28 29 bool ProxySwitchesAreValid() { 30 return ValidateProxySwitches(); 31 } 32 33 void VerifyProxyMode(ProxyPrefs::ProxyMode expected_mode) { 34 const base::Value* value = NULL; 35 ASSERT_TRUE(GetValue(prefs::kProxy, &value)); 36 ASSERT_EQ(base::Value::TYPE_DICTIONARY, value->GetType()); 37 ProxyConfigDictionary dict( 38 static_cast<const base::DictionaryValue*>(value)); 39 ProxyPrefs::ProxyMode actual_mode; 40 ASSERT_TRUE(dict.GetMode(&actual_mode)); 41 EXPECT_EQ(expected_mode, actual_mode); 42 } 43 44 void VerifySSLCipherSuites(const char* const* ciphers, 45 size_t cipher_count) { 46 const base::Value* value = NULL; 47 ASSERT_TRUE(GetValue(prefs::kCipherSuiteBlacklist, &value)); 48 ASSERT_EQ(base::Value::TYPE_LIST, value->GetType()); 49 const base::ListValue* list_value = 50 static_cast<const base::ListValue*>(value); 51 ASSERT_EQ(cipher_count, list_value->GetSize()); 52 53 std::string cipher_string; 54 for (base::ListValue::const_iterator it = list_value->begin(); 55 it != list_value->end(); ++it, ++ciphers) { 56 ASSERT_TRUE((*it)->GetAsString(&cipher_string)); 57 EXPECT_EQ(*ciphers, cipher_string); 58 } 59 } 60 61 private: 62 virtual ~TestCommandLinePrefStore() {} 63 }; 64 65 // Tests a simple string pref on the command line. 66 TEST(CommandLinePrefStoreTest, SimpleStringPref) { 67 CommandLine cl(CommandLine::NO_PROGRAM); 68 cl.AppendSwitchASCII(switches::kLang, "hi-MOM"); 69 scoped_refptr<CommandLinePrefStore> store = new CommandLinePrefStore(&cl); 70 71 const base::Value* actual = NULL; 72 EXPECT_TRUE(store->GetValue(prefs::kApplicationLocale, &actual)); 73 std::string result; 74 EXPECT_TRUE(actual->GetAsString(&result)); 75 EXPECT_EQ("hi-MOM", result); 76 } 77 78 // Tests a simple boolean pref on the command line. 79 TEST(CommandLinePrefStoreTest, SimpleBooleanPref) { 80 CommandLine cl(CommandLine::NO_PROGRAM); 81 cl.AppendSwitch(switches::kNoProxyServer); 82 scoped_refptr<TestCommandLinePrefStore> store = 83 new TestCommandLinePrefStore(&cl); 84 85 store->VerifyProxyMode(ProxyPrefs::MODE_DIRECT); 86 } 87 88 // Tests a command line with no recognized prefs. 89 TEST(CommandLinePrefStoreTest, NoPrefs) { 90 CommandLine cl(CommandLine::NO_PROGRAM); 91 cl.AppendSwitch(unknown_string); 92 cl.AppendSwitchASCII(unknown_bool, "a value"); 93 scoped_refptr<CommandLinePrefStore> store = new CommandLinePrefStore(&cl); 94 95 const base::Value* actual = NULL; 96 EXPECT_FALSE(store->GetValue(unknown_bool, &actual)); 97 EXPECT_FALSE(store->GetValue(unknown_string, &actual)); 98 } 99 100 // Tests a complex command line with multiple known and unknown switches. 101 TEST(CommandLinePrefStoreTest, MultipleSwitches) { 102 CommandLine cl(CommandLine::NO_PROGRAM); 103 cl.AppendSwitch(unknown_string); 104 cl.AppendSwitchASCII(switches::kProxyServer, "proxy"); 105 cl.AppendSwitchASCII(switches::kProxyBypassList, "list"); 106 cl.AppendSwitchASCII(unknown_bool, "a value"); 107 scoped_refptr<TestCommandLinePrefStore> store = 108 new TestCommandLinePrefStore(&cl); 109 110 const base::Value* actual = NULL; 111 EXPECT_FALSE(store->GetValue(unknown_bool, &actual)); 112 EXPECT_FALSE(store->GetValue(unknown_string, &actual)); 113 114 store->VerifyProxyMode(ProxyPrefs::MODE_FIXED_SERVERS); 115 116 const base::Value* value = NULL; 117 ASSERT_TRUE(store->GetValue(prefs::kProxy, &value)); 118 ASSERT_EQ(base::Value::TYPE_DICTIONARY, value->GetType()); 119 ProxyConfigDictionary dict(static_cast<const base::DictionaryValue*>(value)); 120 121 std::string string_result; 122 123 ASSERT_TRUE(dict.GetProxyServer(&string_result)); 124 EXPECT_EQ("proxy", string_result); 125 126 ASSERT_TRUE(dict.GetBypassList(&string_result)); 127 EXPECT_EQ("list", string_result); 128 } 129 130 // Tests proxy switch validation. 131 TEST(CommandLinePrefStoreTest, ProxySwitchValidation) { 132 CommandLine cl(CommandLine::NO_PROGRAM); 133 134 // No switches. 135 scoped_refptr<TestCommandLinePrefStore> store = 136 new TestCommandLinePrefStore(&cl); 137 EXPECT_TRUE(store->ProxySwitchesAreValid()); 138 139 // Only no-proxy. 140 cl.AppendSwitch(switches::kNoProxyServer); 141 scoped_refptr<TestCommandLinePrefStore> store2 = 142 new TestCommandLinePrefStore(&cl); 143 EXPECT_TRUE(store2->ProxySwitchesAreValid()); 144 145 // Another proxy switch too. 146 cl.AppendSwitch(switches::kProxyAutoDetect); 147 scoped_refptr<TestCommandLinePrefStore> store3 = 148 new TestCommandLinePrefStore(&cl); 149 EXPECT_FALSE(store3->ProxySwitchesAreValid()); 150 151 // All proxy switches except no-proxy. 152 CommandLine cl2(CommandLine::NO_PROGRAM); 153 cl2.AppendSwitch(switches::kProxyAutoDetect); 154 cl2.AppendSwitchASCII(switches::kProxyServer, "server"); 155 cl2.AppendSwitchASCII(switches::kProxyPacUrl, "url"); 156 cl2.AppendSwitchASCII(switches::kProxyBypassList, "list"); 157 scoped_refptr<TestCommandLinePrefStore> store4 = 158 new TestCommandLinePrefStore(&cl2); 159 EXPECT_TRUE(store4->ProxySwitchesAreValid()); 160 } 161 162 TEST(CommandLinePrefStoreTest, ManualProxyModeInference) { 163 CommandLine cl1(CommandLine::NO_PROGRAM); 164 cl1.AppendSwitch(unknown_string); 165 cl1.AppendSwitchASCII(switches::kProxyServer, "proxy"); 166 scoped_refptr<TestCommandLinePrefStore> store1 = 167 new TestCommandLinePrefStore(&cl1); 168 store1->VerifyProxyMode(ProxyPrefs::MODE_FIXED_SERVERS); 169 170 CommandLine cl2(CommandLine::NO_PROGRAM); 171 cl2.AppendSwitchASCII(switches::kProxyPacUrl, "proxy"); 172 scoped_refptr<TestCommandLinePrefStore> store2 = 173 new TestCommandLinePrefStore(&cl2); 174 store2->VerifyProxyMode(ProxyPrefs::MODE_PAC_SCRIPT); 175 176 CommandLine cl3(CommandLine::NO_PROGRAM); 177 cl3.AppendSwitchASCII(switches::kProxyServer, std::string()); 178 scoped_refptr<TestCommandLinePrefStore> store3 = 179 new TestCommandLinePrefStore(&cl3); 180 store3->VerifyProxyMode(ProxyPrefs::MODE_DIRECT); 181 } 182 183 TEST(CommandLinePrefStoreTest, DisableSSLCipherSuites) { 184 CommandLine cl1(CommandLine::NO_PROGRAM); 185 cl1.AppendSwitchASCII(switches::kCipherSuiteBlacklist, 186 "0x0004,0x0005"); 187 scoped_refptr<TestCommandLinePrefStore> store1 = 188 new TestCommandLinePrefStore(&cl1); 189 const char* const expected_ciphers1[] = { 190 "0x0004", 191 "0x0005", 192 }; 193 store1->VerifySSLCipherSuites(expected_ciphers1, 194 arraysize(expected_ciphers1)); 195 196 CommandLine cl2(CommandLine::NO_PROGRAM); 197 cl2.AppendSwitchASCII(switches::kCipherSuiteBlacklist, 198 "0x0004, WHITESPACE_IGNORED TEST , 0x0005"); 199 scoped_refptr<TestCommandLinePrefStore> store2 = 200 new TestCommandLinePrefStore(&cl2); 201 const char* const expected_ciphers2[] = { 202 "0x0004", 203 "WHITESPACE_IGNORED TEST", 204 "0x0005", 205 }; 206 store2->VerifySSLCipherSuites(expected_ciphers2, 207 arraysize(expected_ciphers2)); 208 209 CommandLine cl3(CommandLine::NO_PROGRAM); 210 cl3.AppendSwitchASCII(switches::kCipherSuiteBlacklist, 211 "0x0004;MOAR;0x0005"); 212 scoped_refptr<TestCommandLinePrefStore> store3 = 213 new TestCommandLinePrefStore(&cl3); 214 const char* const expected_ciphers3[] = { 215 "0x0004;MOAR;0x0005" 216 }; 217 store3->VerifySSLCipherSuites(expected_ciphers3, 218 arraysize(expected_ciphers3)); 219 } 220