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.
5 // Stub out the `chrome.proxy`, `chrome.i18n`, and `chrome.extension` APIs
15 getMessage: function(x) { return x; }
18 sendRequest: function() {},
19 isAllowedIncognitoAccess: function(funk) {
25 var fixture = document.getElementById('fixture');
26 var baselineHTML = fixture.innerHTML;
27 var groupIDs = [ProxyFormController.ProxyTypes.DIRECT,
28 ProxyFormController.ProxyTypes.SYSTEM,
29 ProxyFormController.ProxyTypes.PAC,
30 ProxyFormController.ProxyTypes.FIXED];
32 var mockFunctionFactory = function(returnValue, logging) {
34 returnValue = returnValue || null;
36 var funky = function() {
37 called.push(arguments);
38 if (arguments[1] && typeof(arguments[1]) === 'function') {
39 var funk = arguments[1];
44 funky.getCallList = function() { return called; };
45 funky.getValue = function() { return returnValue; };
49 var proxyform = new Test.Unit.Runner({
51 fixture.innerHTML = baselineHTML;
52 this.controller_ = new ProxyFormController('proxyForm');
53 this.clickEvent_ = document.createEvent('MouseEvents');
54 this.clickEvent_.initMouseEvent('click', true, true, window,
55 0, 0, 0, 0, 0, false, false, false, false, 0, null);
56 // Reset mock functions.
59 get: mockFunctionFactory({
60 value: {mode: 'system' },
61 levelOfControl: 'controllable_by_this_extension' }),
62 clear: mockFunctionFactory({
63 value: {mode: 'system' },
64 levelOfControl: 'controllable_by_this_extension' }),
65 set: mockFunctionFactory({
66 value: {mode: 'system' },
67 levelOfControl: 'controllable_by_this_extension' })
72 teardown: function() {
73 fixture.removeChild(fixture.childNodes[0]);
74 delete(this.controller_);
77 // Clicking on various bits of the interface should set correct classes,
78 // and select correct radio buttons.
79 testActivationClicks: function() {
82 groupIDs.forEach(function(id) {
83 var group = document.getElementById(id);
84 var all = group.querySelectorAll('*');
85 for (i = 0; i < all.length; i++) {
86 group.classList.remove('active');
87 all[i].dispatchEvent(self.clickEvent_);
88 self.assert(group.classList.contains('active'));
93 // Elements inside an active group should not be disabled, and vice versa
94 testDisabledElements: function() {
97 groupIDs.forEach(function(id) {
98 var group = document.getElementById(id);
99 var all = group.querySelectorAll('*');
100 // First, check that activating a group enables its form elements
101 for (i = 0; i < all.length; i++) {
102 group.classList.remove('active');
103 var inputs = group.querySelectorAll('input:not([type="radio"]),select');
104 for (j = 0; j < inputs.length; j++) {
105 inputs[j].setAttribute('disabled', 'disabled');
107 all[i].dispatchEvent(self.clickEvent_);
108 for (j = 0; j < inputs.length; j++) {
109 self.assert(!inputs[j].hasAttribute('disabled'));
115 // Clicking the "Use single proxy" checkbox should set the correct
116 // classes on the form.
117 testSingleProxyToggle: function() {
118 var group = document.getElementById(
119 ProxyFormController.ProxyTypes.FIXED);
120 var checkbox = document.getElementById('singleProxyForEverything');
121 var section = checkbox.parentNode.parentNode;
122 // Checkbox only works in active group, `testActivationClicks` tests
123 // the inactive click behavior.
124 group.classList.add('active');
126 checkbox.checked = false;
127 checkbox.dispatchEvent(this.clickEvent_);
128 this.assert(section.classList.contains('single'));
129 checkbox.dispatchEvent(this.clickEvent_);
130 this.assert(!section.classList.contains('single'));
133 // On instantiation, ProxyFormController should read the current state
134 // from `chrome.proxy.settings.get`, and react accordingly.
135 // Let's see if that happens with the next four sets of assertions.
136 testSetupFormSystem: function() {
137 chrome.proxy.settings.get = mockFunctionFactory({
138 value: {mode: 'system'},
139 levelOfControl: 'controllable_by_this_extension'
142 fixture.innerHTML = baselineHTML;
143 this.controller_ = new ProxyFormController('proxyForm');
144 // Wait for async calls to fire
145 this.wait(100, function() {
148 chrome.proxy.settings.get.getCallList().length);
150 document.getElementById(ProxyFormController.ProxyTypes.SYSTEM)
151 .classList.contains('active'));
155 testSetupFormDirect: function() {
156 chrome.proxy.settings.get =
157 mockFunctionFactory({value: {mode: 'direct'},
158 levelOfControl: 'controllable_by_this_extension'}, true);
160 fixture.innerHTML = baselineHTML;
161 this.controller_ = new ProxyFormController('proxyForm');
162 // Wait for async calls to fire
163 this.wait(100, function() {
166 chrome.proxy.settings.get.getCallList().length);
168 document.getElementById(ProxyFormController.ProxyTypes.DIRECT)
169 .classList.contains('active'));
173 testSetupFormPac: function() {
174 chrome.proxy.settings.get =
175 mockFunctionFactory({value: {mode: 'pac_script' },
176 levelOfControl: 'controllable_by_this_extension'});
178 fixture.innerHTML = baselineHTML;
179 this.controller_ = new ProxyFormController('proxyForm');
180 // Wait for async calls to fire
181 this.wait(100, function() {
184 chrome.proxy.settings.get.getCallList().length);
186 document.getElementById(ProxyFormController.ProxyTypes.PAC)
187 .classList.contains('active'));
191 testSetupFormFixed: function() {
192 chrome.proxy.settings.get =
193 mockFunctionFactory({value: {mode: 'fixed_servers' },
194 levelOfControl: 'controllable_by_this_extension'});
196 fixture.innerHTML = baselineHTML;
197 this.controller_ = new ProxyFormController('proxyForm');
198 // Wait for async calls to fire
199 this.wait(100, function() {
202 chrome.proxy.settings.get.getCallList().length);
204 document.getElementById(ProxyFormController.ProxyTypes.FIXED)
205 .classList.contains('active'));
209 // Test that `recalcFormValues_` correctly sets DOM field values when
210 // given a `ProxyConfig` structure
211 testRecalcFormValuesGroups: function() {
212 // Test `AUTO` normalization to `PAC`
213 this.controller_.recalcFormValues_({
214 mode: ProxyFormController.ProxyTypes.AUTO,
219 document.getElementById(ProxyFormController.ProxyTypes.PAC)
220 .classList.contains('active'));
223 this.controller_.recalcFormValues_({
224 mode: ProxyFormController.ProxyTypes.DIRECT,
229 document.getElementById(ProxyFormController.ProxyTypes.DIRECT)
230 .classList.contains('active'));
233 this.controller_.recalcFormValues_({
234 mode: ProxyFormController.ProxyTypes.FIXED,
239 document.getElementById(ProxyFormController.ProxyTypes.FIXED)
240 .classList.contains('active'));
243 this.controller_.recalcFormValues_({
244 mode: ProxyFormController.ProxyTypes.PAC,
249 document.getElementById(ProxyFormController.ProxyTypes.PAC)
250 .classList.contains('active'));
253 this.controller_.recalcFormValues_({
254 mode: ProxyFormController.ProxyTypes.SYSTEM,
259 document.getElementById(ProxyFormController.ProxyTypes.SYSTEM)
260 .classList.contains('active'));
263 testRecalcFormValuesFixedSingle: function() {
264 this.controller_.recalcFormValues_({
265 mode: ProxyFormController.ProxyTypes.FIXED,
269 host: 'singleproxy.example.com',
274 var single = this.controller_.singleProxy;
275 this.assertEqual('socks5', single.scheme);
276 this.assertEqual('singleproxy.example.com', single.host);
277 this.assertEqual(1234, single.port);
280 testRecalcFormValuesPacScript: function() {
281 this.controller_.recalcFormValues_({
282 mode: ProxyFormController.ProxyTypes.PAC,
284 pacScript: {url: 'http://example.com/this/is/a/pac.script'}
287 'http://example.com/this/is/a/pac.script',
288 document.getElementById('autoconfigURL').value);
291 testRecalcFormValuesSingle: function() {
292 this.controller_.recalcFormValues_({
293 mode: ProxyFormController.ProxyTypes.FIXED,
304 document.querySelector('#' + ProxyFormController.ProxyTypes.FIXED +
305 ' > section').classList.contains('single'));
307 var single = this.controller_.singleProxy;
308 this.assertEqual('https', single.scheme);
309 this.assertEqual('example.com', single.host);
310 this.assertEqual(80, single.port);
313 testRecalcFormValuesMultiple: function() {
314 this.controller_.recalcFormValues_({
315 mode: ProxyFormController.ProxyTypes.FIXED,
319 host: 'http.example.com',
324 host: 'https.example.com',
329 host: 'socks4.example.com',
334 host: 'socks5.example.com',
341 !document.querySelector('#' + ProxyFormController.ProxyTypes.FIXED
342 + ' > section').classList.contains('single'));
343 var server = this.controller_.singleProxy;
344 this.assertNull(server);
346 server = this.controller_.httpProxy;
347 this.assertEqual('http', server.scheme);
348 this.assertEqual('http.example.com', server.host);
349 this.assertEqual(1, server.port);
351 server = this.controller_.httpsProxy;
352 this.assertEqual('https', server.scheme);
353 this.assertEqual('https.example.com', server.host);
354 this.assertEqual(2, server.port);
356 server = this.controller_.ftpProxy;
357 this.assertEqual('socks4', server.scheme);
358 this.assertEqual('socks4.example.com', server.host);
359 this.assertEqual(3, server.port);
361 server = this.controller_.fallbackProxy;
362 this.assertEqual('socks5', server.scheme);
363 this.assertEqual('socks5.example.com', server.host);
364 this.assertEqual(4, server.port);
367 testBypassList: function() {
368 this.controller_.bypassList = ['1.example.com',
371 this.assertEnumEqual(
372 document.getElementById('bypassList').value,
373 '1.example.com, 2.example.com, 3.example.com');
374 this.assertEnumEqual(
375 this.controller_.bypassList,
376 ['1.example.com', '2.example.com', '3.example.com']);
379 // Test that "system" rules are correctly generated
380 testProxyRulesGenerationSystem: function() {
381 this.controller_.changeActive_(
382 document.getElementById(ProxyFormController.ProxyTypes.SYSTEM));
384 this.assertHashEqual(
386 this.controller_.generateProxyConfig_());
389 // Test that "direct" rules are correctly generated
390 testProxyRulesGenerationDirect: function() {
391 this.controller_.changeActive_(
392 document.getElementById(ProxyFormController.ProxyTypes.DIRECT));
394 this.assertHashEqual(
396 this.controller_.generateProxyConfig_());
399 // Test that auto detection rules are correctly generated when "automatic"
400 // is selected, and no PAC file URL is given
401 testProxyRulesGenerationAuto: function() {
402 this.controller_.changeActive_(
403 document.getElementById(ProxyFormController.ProxyTypes.PAC));
405 this.assertHashEqual(
406 {mode: 'auto_detect'},
407 this.controller_.generateProxyConfig_());
410 // Test that PAC URL rules are correctly generated when "automatic"
411 // is selected, and a PAC file URL is given
412 testProxyRulesGenerationPacURL: function() {
413 this.controller_.changeActive_(
414 document.getElementById(ProxyFormController.ProxyTypes.PAC));
415 this.controller_.pacURL = 'http://example.com/pac.pac';
416 var result = this.controller_.generateProxyConfig_();
417 this.assertEqual('pac_script', result.mode);
418 this.assertEqual('http://example.com/pac.pac', result.pacScript.url);
421 // Manual PAC definitions
422 testProxyRulesGenerationPacData: function() {
423 var pacData = 'function FindProxyForURL(url,host) { return "DIRECT"; }';
424 this.controller_.changeActive_(
425 document.getElementById(ProxyFormController.ProxyTypes.PAC));
426 this.controller_.manualPac = pacData;
427 var result = this.controller_.generateProxyConfig_();
428 this.assertEqual('pac_script', result.mode);
429 this.assertEqual(pacData, result.pacScript.data);
432 // PAC URLs override manual PAC definitions
433 testProxyRulesGenerationPacURLOverridesData: function() {
434 this.controller_.changeActive_(
435 document.getElementById(ProxyFormController.ProxyTypes.PAC));
436 this.controller_.pacURL = 'http://example.com/pac.pac';
437 this.controller_.manualPac =
438 'function FindProxyForURL(url,host) { return "DIRECT"; }';
439 var result = this.controller_.generateProxyConfig_();
440 this.assertEqual('pac_script', result.mode);
441 this.assertEqual('http://example.com/pac.pac', result.pacScript.url);
444 // Test that fixed, manual servers are correctly transformed into a
445 // `ProxyRules` structure.
446 testProxyRulesGenerationSingle: function() {
447 this.controller_.changeActive_(
448 document.getElementById(ProxyFormController.ProxyTypes.FIXED));
450 this.controller_.singleProxy = {
456 var result = this.controller_.generateProxyConfig_();
457 this.assertEqual('fixed_servers', result.mode);
458 this.assertEqual('http', result.rules.singleProxy.scheme);
459 this.assertEqual('example.com', result.rules.singleProxy.host);
460 this.assertEqual(80, result.rules.singleProxy.port);
461 this.assertEqual(undefined, result.rules.proxyForHttp);
462 this.assertEqual(undefined, result.rules.proxyForHttps);
463 this.assertEqual(undefined, result.rules.proxyForFtp);
464 this.assertEqual(undefined, result.rules.fallbackProxy);
467 // Test that proxy configuration rules are correctly generated
468 // for separate manually entered servers.
469 testProxyRulesGenerationSeparate: function() {
470 this.controller_.changeActive_(
471 document.getElementById(ProxyFormController.ProxyTypes.FIXED));
473 this.controller_.singleProxy = false;
474 this.controller_.httpProxy = {
476 host: 'http.example.com',
479 this.controller_.httpsProxy = {
481 host: 'https.example.com',
484 this.controller_.ftpProxy = {
486 host: 'ftp.example.com',
489 this.controller_.fallbackProxy = {
491 host: 'fallback.example.com',
495 var result = this.controller_.generateProxyConfig_();
496 this.assertEqual('fixed_servers', result.mode);
497 this.assertEqual(undefined, result.rules.singleProxy);
498 this.assertEqual('http', result.rules.proxyForHttp.scheme);
499 this.assertEqual('http.example.com', result.rules.proxyForHttp.host);
500 this.assertEqual('80', result.rules.proxyForHttp.port);
501 this.assertEqual('https', result.rules.proxyForHttps.scheme);
502 this.assertEqual('https.example.com', result.rules.proxyForHttps.host);
503 this.assertEqual('443', result.rules.proxyForHttps.port);
504 this.assertEqual('socks4', result.rules.proxyForFtp.scheme);
505 this.assertEqual('ftp.example.com', result.rules.proxyForFtp.host);
506 this.assertEqual('80', result.rules.proxyForFtp.port);
507 this.assertEqual('socks5', result.rules.fallbackProxy.scheme);
508 this.assertEqual('fallback.example.com', result.rules.fallbackProxy.host);
509 this.assertEqual('80', result.rules.fallbackProxy.port);
511 }, { testLog: 'proxyformcontrollerlog' });
513 var c = new ProxyFormController('proxyForm');