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