- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / docs / examples / extensions / proxy_configuration / test / proxy_form_controller_test.js
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 // Stub out the `chrome.proxy`, `chrome.i18n`, and `chrome.extension` APIs
6 chrome = chrome || {
7   proxy: {
8     settings: {
9       get: function() {},
10       clear: function() {},
11       set: function() {}
12     }
13   },
14   i18n: {
15     getMessage: function(x) { return x; }
16   },
17   extension: {
18     sendRequest: function() {},
19     isAllowedIncognitoAccess: function(funk) {
20       funk(true);
21     }
22   }
23 };
24
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];
31
32 var mockFunctionFactory = function(returnValue, logging) {
33   var called = [];
34   returnValue = returnValue || null;
35
36   var funky = function() {
37     called.push(arguments);
38     if (arguments[1] && typeof(arguments[1]) === 'function') {
39       var funk = arguments[1];
40       funk(returnValue);
41     }
42     return returnValue;
43   };
44   funky.getCallList = function() { return called; };
45   funky.getValue = function() { return returnValue; };
46   return funky;
47 };
48
49 var proxyform = new Test.Unit.Runner({
50   setup: function() {
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.
57     chrome.proxy = {
58       settings: {
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' })
68       }
69     };
70   },
71
72   teardown: function() {
73     fixture.removeChild(fixture.childNodes[0]);
74     delete(this.controller_);
75   },
76
77   // Clicking on various bits of the interface should set correct classes,
78   // and select correct radio buttons.
79   testActivationClicks: function() {
80     var self = this;
81     var i;
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'));
89       }
90     });
91   },
92
93   // Elements inside an active group should not be disabled, and vice versa
94   testDisabledElements: function() {
95     var self = this;
96     var i, j;
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');
106         }
107         all[i].dispatchEvent(self.clickEvent_);
108         for (j = 0; j < inputs.length; j++) {
109           self.assert(!inputs[j].hasAttribute('disabled'));
110         }
111       }
112     });
113   },
114
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');
125
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'));
131   },
132
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'
140     });
141
142     fixture.innerHTML = baselineHTML;
143     this.controller_ = new ProxyFormController('proxyForm');
144     // Wait for async calls to fire
145     this.wait(100, function() {
146       this.assertEqual(
147           6,
148           chrome.proxy.settings.get.getCallList().length);
149       this.assert(
150           document.getElementById(ProxyFormController.ProxyTypes.SYSTEM)
151               .classList.contains('active'));
152     });
153   },
154
155   testSetupFormDirect: function() {
156     chrome.proxy.settings.get =
157         mockFunctionFactory({value: {mode: 'direct'},
158              levelOfControl: 'controllable_by_this_extension'}, true);
159
160     fixture.innerHTML = baselineHTML;
161     this.controller_ = new ProxyFormController('proxyForm');
162     // Wait for async calls to fire
163     this.wait(100, function() {
164       this.assertEqual(
165           2,
166           chrome.proxy.settings.get.getCallList().length);
167       this.assert(
168           document.getElementById(ProxyFormController.ProxyTypes.DIRECT)
169               .classList.contains('active'));
170     });
171   },
172
173   testSetupFormPac: function() {
174     chrome.proxy.settings.get =
175         mockFunctionFactory({value: {mode: 'pac_script' },
176              levelOfControl: 'controllable_by_this_extension'});
177
178     fixture.innerHTML = baselineHTML;
179     this.controller_ = new ProxyFormController('proxyForm');
180     // Wait for async calls to fire
181     this.wait(100, function() {
182       this.assertEqual(
183           2,
184           chrome.proxy.settings.get.getCallList().length);
185       this.assert(
186           document.getElementById(ProxyFormController.ProxyTypes.PAC)
187               .classList.contains('active'));
188     });
189   },
190
191   testSetupFormFixed: function() {
192     chrome.proxy.settings.get =
193         mockFunctionFactory({value: {mode: 'fixed_servers' },
194              levelOfControl: 'controllable_by_this_extension'});
195
196     fixture.innerHTML = baselineHTML;
197     this.controller_ = new ProxyFormController('proxyForm');
198     // Wait for async calls to fire
199     this.wait(100, function() {
200       this.assertEqual(
201           2,
202           chrome.proxy.settings.get.getCallList().length);
203       this.assert(
204           document.getElementById(ProxyFormController.ProxyTypes.FIXED)
205               .classList.contains('active'));
206     });
207   },
208
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,
215       rules: {},
216       pacScript: ''
217     });
218     this.assert(
219         document.getElementById(ProxyFormController.ProxyTypes.PAC)
220             .classList.contains('active'));
221
222     // DIRECT
223     this.controller_.recalcFormValues_({
224       mode: ProxyFormController.ProxyTypes.DIRECT,
225       rules: {},
226       pacScript: ''
227     });
228     this.assert(
229         document.getElementById(ProxyFormController.ProxyTypes.DIRECT)
230             .classList.contains('active'));
231
232     // FIXED
233     this.controller_.recalcFormValues_({
234       mode: ProxyFormController.ProxyTypes.FIXED,
235       rules: {},
236       pacScript: ''
237     });
238     this.assert(
239         document.getElementById(ProxyFormController.ProxyTypes.FIXED)
240             .classList.contains('active'));
241
242     // PAC
243     this.controller_.recalcFormValues_({
244       mode: ProxyFormController.ProxyTypes.PAC,
245       rules: {},
246       pacScript: ''
247     });
248     this.assert(
249         document.getElementById(ProxyFormController.ProxyTypes.PAC)
250           .classList.contains('active'));
251
252     // SYSTEM
253     this.controller_.recalcFormValues_({
254       mode: ProxyFormController.ProxyTypes.SYSTEM,
255       rules: {},
256       pacScript: ''
257     });
258     this.assert(
259         document.getElementById(ProxyFormController.ProxyTypes.SYSTEM)
260           .classList.contains('active'));
261   },
262
263   testRecalcFormValuesFixedSingle: function() {
264     this.controller_.recalcFormValues_({
265       mode: ProxyFormController.ProxyTypes.FIXED,
266       rules: {
267          singleProxy: {
268            scheme: 'socks5',
269            host: 'singleproxy.example.com',
270            port: '1234'
271         }
272       }
273     });
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);
278   },
279
280   testRecalcFormValuesPacScript: function() {
281     this.controller_.recalcFormValues_({
282       mode: ProxyFormController.ProxyTypes.PAC,
283       rules: {},
284       pacScript: {url: 'http://example.com/this/is/a/pac.script'}
285     });
286     this.assertEqual(
287         'http://example.com/this/is/a/pac.script',
288         document.getElementById('autoconfigURL').value);
289   },
290
291   testRecalcFormValuesSingle: function() {
292     this.controller_.recalcFormValues_({
293        mode: ProxyFormController.ProxyTypes.FIXED,
294        rules: {
295          singleProxy: {
296            scheme: 'https',
297            host: 'example.com',
298            port: 80
299         }
300       }
301     });
302     // Single!
303     this.assert(
304       document.querySelector('#' + ProxyFormController.ProxyTypes.FIXED +
305           ' > section').classList.contains('single'));
306
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);
311   },
312
313   testRecalcFormValuesMultiple: function() {
314     this.controller_.recalcFormValues_({
315        mode: ProxyFormController.ProxyTypes.FIXED,
316        rules: {
317          proxyForHttp: {
318            scheme: 'http',
319            host: 'http.example.com',
320            port: 1
321         },
322          proxyForHttps: {
323            scheme: 'https',
324            host: 'https.example.com',
325            port: 2
326         },
327          proxyForFtp: {
328            scheme: 'socks4',
329            host: 'socks4.example.com',
330            port: 3
331         },
332          fallbackProxy: {
333            scheme: 'socks5',
334            host: 'socks5.example.com',
335            port: 4
336         }
337       }
338     });
339     // Not Single!
340     this.assert(
341       !document.querySelector('#' + ProxyFormController.ProxyTypes.FIXED
342           + ' > section').classList.contains('single'));
343     var server = this.controller_.singleProxy;
344     this.assertNull(server);
345
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);
350
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);
355
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);
360
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);
365   },
366
367   testBypassList: function() {
368     this.controller_.bypassList = ['1.example.com',
369                                    '2.example.com',
370                                    '3.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']);
377   },
378
379   // Test that "system" rules are correctly generated
380   testProxyRulesGenerationSystem: function() {
381     this.controller_.changeActive_(
382         document.getElementById(ProxyFormController.ProxyTypes.SYSTEM));
383
384     this.assertHashEqual(
385         {mode: 'system'},
386         this.controller_.generateProxyConfig_());
387   },
388
389   // Test that "direct" rules are correctly generated
390   testProxyRulesGenerationDirect: function() {
391     this.controller_.changeActive_(
392         document.getElementById(ProxyFormController.ProxyTypes.DIRECT));
393
394     this.assertHashEqual(
395         {mode: 'direct'},
396         this.controller_.generateProxyConfig_());
397   },
398
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));
404
405     this.assertHashEqual(
406         {mode: 'auto_detect'},
407         this.controller_.generateProxyConfig_());
408   },
409
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);
419   },
420
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);
430   },
431
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);
442   },
443
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));
449
450     this.controller_.singleProxy = {
451       scheme: 'http',
452       host: 'example.com',
453       port: '80'
454     };
455
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);
465   },
466
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));
472
473     this.controller_.singleProxy = false;
474     this.controller_.httpProxy = {
475       scheme: 'http',
476       host: 'http.example.com',
477       port: 80
478     };
479     this.controller_.httpsProxy = {
480       scheme: 'https',
481       host: 'https.example.com',
482       port: 443
483     };
484     this.controller_.ftpProxy = {
485       scheme: 'socks4',
486       host: 'ftp.example.com',
487       port: 80
488     };
489     this.controller_.fallbackProxy = {
490       scheme: 'socks5',
491       host: 'fallback.example.com',
492       port: 80
493     };
494
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);
510   }
511 }, { testLog: 'proxyformcontrollerlog' });
512
513 var c = new ProxyFormController('proxyForm');