Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / options / chromeos / bluetooth_options_browsertest.js
1 // Copyright (c) 2013 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 GEN('#if defined(OS_CHROMEOS)');
6
7 function BluetoothWebUITest() {}
8
9 BluetoothWebUITest.prototype = {
10   __proto__: testing.Test.prototype,
11
12   /**
13    * Start tests from the main-settings page.
14    */
15   browsePreload: 'chrome://settings-frame/settings',
16
17   /**
18    * @override
19    */
20   preLoad: function() {
21     this.makeAndRegisterMockHandler([
22       'bluetoothEnableChange',
23       'updateBluetoothDevice',
24       'findBluetoothDevices',
25       'stopBluetoothDeviceDiscovery',
26     ]);
27   },
28
29   /**
30    * Retrieves the list item associated with a Bluetooth device.
31    * @param {!Element} listElement Element containing a list of devices.
32    * @param {string} deviceName The name of the device.
33    * @return {Element|undefined} List item matching the device name.
34    */
35   getElementForDevice: function(listElement, deviceName) {
36     var items = listElement.querySelectorAll('.bluetooth-device');
37     for (var i = 0; i < items.length; i++) {
38       var candidate = items[i];
39       var name = candidate.data.name;
40       if (name == deviceName)
41         return candidate;
42     }
43   },
44
45   /**
46    * Selects a bluetooth device from the list with the matching address.
47    * @param {!Element} listElement A list of Bluetooth devices.
48    * @param {{address: string,
49    *          connectable: boolean,
50    *          connected: boolean,
51    *          name: string,
52    *          paired: boolean}} device Description of the device.
53    */
54   selectDevice: function(listElement, device) {
55     listElement.selectedItem = device;
56     cr.dispatchSimpleEvent(listElement, 'change');
57   },
58
59   /**
60    * Fake input of a pincode or passkey.
61    * @param {!Element} element Text input field.
62    * @param {string} text New value for the input field.
63    */
64   fakeInput: function(element, text) {
65     element.value = text;
66     cr.dispatchSimpleEvent(element, 'input');
67   },
68
69 };
70
71 TEST_F('BluetoothWebUITest', 'testEnableBluetooth', function() {
72   assertEquals(this.browsePreload, document.location.href);
73   expectFalse($('enable-bluetooth').checked);
74   expectTrue($('bluetooth-paired-devices-list').parentNode.hidden);
75
76   this.mockHandler.expects(once()).bluetoothEnableChange([true]).will(
77       callFunction(function() {
78         options.BrowserOptions.setBluetoothState(true);
79       }));
80   $('enable-bluetooth').click();
81
82   expectFalse($('bluetooth-paired-devices-list').parentNode.hidden);
83 });
84
85 TEST_F('BluetoothWebUITest', 'testAddDevices', function() {
86   assertEquals(this.browsePreload, document.location.href);
87
88   var pairedDeviceList = $('bluetooth-paired-devices-list');
89   var unpairedDeviceList = $('bluetooth-unpaired-devices-list');
90
91   var fakePairedDevice = {
92     address: '00:11:22:33:44:55',
93     connectable: true,
94     connected: false,
95     name: 'Fake device',
96     paired: true
97   };
98
99   var fakeUnpairedDevice = {
100     address: '28:CF:DA:00:00:00',
101     connectable: true,
102     connected: false,
103     name: 'Apple Magic Mouse',
104     paired: false
105   };
106
107   var fakeUnpairedDevice2 = {
108     address: '28:37:37:00:00:00',
109     connectable: true,
110     connected: false,
111     name: 'Apple Wireless Keyboard',
112     paired: false
113   };
114
115   // Ensure data models for the paired and unpaired device lists are properly
116   // updated.
117   var index = pairedDeviceList.find(fakePairedDevice.address);
118   expectEquals(undefined, index);
119   options.BrowserOptions.addBluetoothDevice(fakePairedDevice);
120   index = pairedDeviceList.find(fakePairedDevice.address);
121   expectEquals(0, index);
122
123   // Ensure the DOM contents of the list are properly updated. The default
124   // layout of a list creates DOM elements only for visible elements in the
125   // list, which is problematic if the list is hidden at the time of layout.
126   // The Bluetooth device lists overcomes this problem by using fixed sized
127   // elements in an auto-expanding list. This test ensures the problem stays
128   // fixed.
129   expectTrue(!!this.getElementForDevice(pairedDeviceList,
130                                         fakePairedDevice.name));
131   expectFalse(!!this.getElementForDevice(unpairedDeviceList,
132                                          fakePairedDevice.name));
133
134   options.BrowserOptions.addBluetoothDevice(fakeUnpairedDevice);
135   index = unpairedDeviceList.find(fakeUnpairedDevice.address);
136   expectEquals(0, index);
137   expectFalse(!!this.getElementForDevice(pairedDeviceList,
138                                          fakeUnpairedDevice.name));
139   expectTrue(!!this.getElementForDevice(unpairedDeviceList,
140                                         fakeUnpairedDevice.name));
141
142   // Test adding a second device to a list.
143   options.BrowserOptions.addBluetoothDevice(fakeUnpairedDevice2);
144   index = unpairedDeviceList.find(fakeUnpairedDevice2.address);
145   expectEquals(1, index);
146   expectTrue(!!this.getElementForDevice(unpairedDeviceList,
147                                         fakeUnpairedDevice2.name));
148
149   // Test clicking on the 'Add a device' button.
150   this.mockHandler.expects(once()).findBluetoothDevices();
151   $('bluetooth-add-device').click();
152   expectFalse($('bluetooth-options').hidden);
153   expectTrue($('bluetooth-add-device-apply-button').disabled);
154   expectFalse($('bluetooth-add-device-cancel-button').disabled);
155
156   Mock4JS.verifyAllMocks();
157   Mock4JS.clearMocksToVerify();
158
159   // Test selecting an element and clicking on the connect button.
160   this.mockHandler.expects(once()).stopBluetoothDeviceDiscovery();
161   this.mockHandler.expects(once()).updateBluetoothDevice(
162       [fakeUnpairedDevice2.address, 'connect']);
163   this.selectDevice(unpairedDeviceList, fakeUnpairedDevice2);
164   var connectButton = $('bluetooth-add-device-apply-button');
165   expectFalse(connectButton.disabled);
166   connectButton.click();
167 });
168
169 TEST_F('BluetoothWebUITest', 'testDevicePairing', function() {
170   assertEquals(this.browsePreload, document.location.href);
171
172   var pairedDeviceList = $('bluetooth-paired-devices-list');
173   var unpairedDeviceList = $('bluetooth-unpaired-devices-list');
174
175   var fakeDevice = {
176     address: '00:24:BE:00:00:00',
177     connectable: true,
178     connected: false,
179     name: 'Sony BT-00',
180     paired: false
181   };
182
183   options.BrowserOptions.addBluetoothDevice(fakeDevice);
184   var index = unpairedDeviceList.find(fakeDevice.address);
185   expectEquals(0, index);
186   expectTrue(!!this.getElementForDevice(unpairedDeviceList,
187                                         fakeDevice.name));
188
189   // Simulate process of pairing a device.
190   fakeDevice.pairing = 'bluetoothEnterPinCode';
191   options.BrowserOptions.addBluetoothDevice(fakeDevice);
192
193   // Verify that the pairing dialog is displayed with the proper options.
194   expectFalse($('bluetooth-pairing').hidden);
195   expectTrue($('bluetooth-pairing-passkey-display').hidden);
196   expectTrue($('bluetooth-pairing-passkey-entry').hidden);
197   expectFalse($('bluetooth-pairing-pincode-entry').hidden);
198
199   // Connect button should be visible but disabled until a pincode is entered.
200   expectFalse($('bluetooth-pair-device-connect-button').hidden);
201   expectFalse($('bluetooth-pair-device-cancel-button').hidden);
202   expectTrue($('bluetooth-pair-device-connect-button').disabled);
203   expectFalse($('bluetooth-pair-device-cancel-button').disabled);
204
205   // Simulate process of entering a pincode.
206   var pincode = '123456';
207
208   this.mockHandler.expects(once()).updateBluetoothDevice(
209       [fakeDevice.address, 'connect', pincode]).will(
210       callFunction(function() {
211         delete fakeDevice.pairing;
212         fakeDevice.paired = true;
213         options.BrowserOptions.addBluetoothDevice(fakeDevice);
214       }));
215
216   this.fakeInput($('bluetooth-pincode'), pincode);
217   $('bluetooth-pair-device-connect-button').click();
218
219   // Verify that the device is removed from the unparied list and added to the
220   // paired device list.
221   expectTrue(!!this.getElementForDevice(pairedDeviceList,
222                                         fakeDevice.name));
223   expectFalse(!!this.getElementForDevice(unpairedDeviceList,
224                                          fakeDevice.name));
225 });
226
227 TEST_F('BluetoothWebUITest', 'testConnectionState', function() {
228   assertEquals(this.browsePreload, document.location.href);
229
230   var pairedDeviceList = $('bluetooth-paired-devices-list');
231   var connectButton = $('bluetooth-reconnect-device');
232
233   var fakeDevice = {
234     address: '00:24:BE:00:00:00',
235     connectable: true,
236     connected: false,
237     name: 'Sony BT-00',
238     paired: true
239   };
240
241   options.BrowserOptions.addBluetoothDevice(fakeDevice);
242   var element = this.getElementForDevice(pairedDeviceList,
243                                          fakeDevice.name);
244   assertTrue(!!element);
245   expectFalse(!!element.getAttribute('connected'));
246   expectTrue(connectButton.disabled);
247
248   // Simulate connecting to a previously paired device.
249   this.selectDevice(pairedDeviceList, fakeDevice);
250   expectFalse(connectButton.disabled);
251   this.mockHandler.expects(once()).updateBluetoothDevice(
252       [fakeDevice.address, 'connect']).will(
253       callFunction(function() {
254         fakeDevice.connected = true;
255         options.BrowserOptions.addBluetoothDevice(fakeDevice);
256       }));
257   connectButton.click();
258   element = this.getElementForDevice(pairedDeviceList,
259                                      fakeDevice.name);
260   assertTrue(!!element);
261   expectTrue(!!element.getAttribute('connected'));
262   var button = element.querySelector('.row-delete-button');
263   expectTrue(!!button);
264
265   Mock4JS.verifyAllMocks();
266   Mock4JS.clearMocksToVerify();
267
268   // Test disconnecting.
269   this.mockHandler.expects(once()).updateBluetoothDevice(
270       [fakeDevice.address, 'disconnect']).will(
271       callFunction(function() {
272         fakeDevice.connected = false;
273         options.BrowserOptions.addBluetoothDevice(fakeDevice);
274       }));
275   button.click();
276   element = this.getElementForDevice(pairedDeviceList,
277                                      fakeDevice.name);
278   assertTrue(!!element);
279   expectFalse(!!element.getAttribute('connected'));
280   button = element.querySelector('.row-delete-button');
281   expectTrue(!!button);
282
283   Mock4JS.verifyAllMocks();
284   Mock4JS.clearMocksToVerify();
285
286   // Test forgetting  a disconnected device.
287   this.mockHandler.expects(once()).updateBluetoothDevice(
288       [fakeDevice.address, 'forget']).will(
289       callFunction(function() {
290         options.BrowserOptions.removeBluetoothDevice(fakeDevice.address);
291       }));
292   button.click();
293   expectFalse(!!this.getElementForDevice(pairedDeviceList,
294                                          fakeDevice.name));
295 });
296
297
298 TEST_F('BluetoothWebUITest', 'testMaliciousInput', function() {
299   assertEquals(this.browsePreload, document.location.href);
300
301   var unpairedDeviceList = $('bluetooth-unpaired-devices-list');
302   var pairDeviceDialog = $('bluetooth-pairing');
303
304   var maliciousStrings = [
305       '<SCRIPT>alert(1)</SCRIPT>',
306       '>\'>\\"><SCRIPT>alert(1)</SCRIPT>',
307       '<IMG SRC=\\"javascript:alert(1)\\">',
308       '<A HREF=\\"data:text/html;base64,' +
309           'PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pgo=\\">...</A>',
310       '<div>',
311       '<textarea>',
312       '<style>',
313       '[0xC0][0xBC]SCRIPT[0xC0][0xBE]alert(1)[0xC0][0xBC]/SCRIPT[0xC0][0xBE]',
314       '+ADw-SCRIPT+AD4-alert(1)+ADw-/SCRIPT+AD4-',
315       '&#<script>alert(1)</script>;',
316       '<!-- Hello -- world > <SCRIPT>alert(1)</SCRIPT> -->',
317       '<!<!-- Hello world > <SCRIPT>alert(1)</SCRIPT> -->',
318       '\x3CSCRIPT\x3Ealert(1)\x3C/SCRIPT\x3E',
319       '<IMG SRC=\\"j[0x00]avascript:alert(1)\\">',
320       '<BASE HREF=\\"javascript:1;/**/\\"><IMG SRC=\\"alert(1)\\">',
321       'javascript:alert(1);',
322       ' xss_injection=\\"\\" ',
323       '\\" xss_injection=\\"',
324       '\' xss_injection=\'',
325       '<!--',
326       '\'',
327       '\\"'
328   ];
329
330   var fakeDevice = {
331     address: '11:22:33:44:55:66',
332     connectable: true,
333     connected: false,
334     name: 'fake',
335     paired: false,
336     pairing: 'bluetoothStartConnecting'
337   };
338
339   options.BrowserOptions.addBluetoothDevice(fakeDevice);
340
341   var nodeCount = function(node) {
342     if (node.getAttribute)
343       assertFalse(!!node.getAttribute('xss_injection'));
344     var length = node.childNodes.length;
345     var tally = length;
346     for (var i = 0; i < length; i++) {
347       tally += nodeCount(node.childNodes[i]);
348     }
349     return tally;
350   };
351
352   // Determine the expected sizes.
353   var unpairedDeviceListSize = nodeCount(unpairedDeviceList);
354   var pairDeviceDialogSize = nodeCount(pairDeviceDialog);
355
356   // Ensure that updating the device with a malicious name does not corrupt the
357   // structure of the document.  Tests the unpaired device list and bluetooth
358   // pairing dialog.
359   for (var i = 0; i < maliciousStrings.length; i++) {
360     fakeDevice.name = maliciousStrings[i];
361     options.BrowserOptions.addBluetoothDevice(fakeDevice);
362     assertEquals(unpairedDeviceListSize, nodeCount(unpairedDeviceList));
363     var element = this.getElementForDevice(unpairedDeviceList,
364                                            fakeDevice.name);
365     assertTrue(!!element);
366     var label = element.querySelector('.bluetooth-device-label');
367     assertTrue(!!label);
368     assertEquals(maliciousStrings[i], label.textContent);
369     assertEquals(pairDeviceDialogSize, nodeCount(pairDeviceDialog));
370   }
371
372 });
373
374 GEN('#endif');