| <!DOCTYPE html> |
| <script src="../resources/testharness.js"></script> |
| <script src="../resources/testharnessreport.js"></script> |
| <script src="resources/bluetooth-helpers.js"></script> |
| <script> |
| 'use strict' |
| |
| test(t => { assert_true(window.testRunner instanceof Object); t.done(); }, |
| 'window.testRunner is required for the following tests.'); |
| |
| promise_test(() => { |
| testRunner.setBluetoothMockDataSet('HeartRateAdapter'); |
| return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]}) |
| .then(device => device.connectGATT()) |
| .then(gattServer => { |
| testRunner.setBluetoothMockDataSet('EmptyAdapter'); |
| return assert_promise_rejects_with_message( |
| gattServer.getPrimaryService('generic_access'), |
| new DOMException('Bluetooth Device is no longer in range.', |
| 'NetworkError'), |
| 'Device went out of range.'); |
| }); |
| }, 'Device goes out of range. Reject with NetworkError.'); |
| |
| promise_test(() => { |
| testRunner.setBluetoothMockDataSet('HeartRateAdapter'); |
| let expected = new DOMException('Service not found in device.', |
| 'NotFoundError'); |
| return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]}) |
| .then(device => device.connectGATT()) |
| .then(gattServer => Promise.all( |
| [assert_promise_rejects_with_message( |
| gattServer.getPrimaryService(glucose.alias), expected), |
| assert_promise_rejects_with_message( |
| gattServer.getPrimaryService(glucose.name), expected), |
| assert_promise_rejects_with_message( |
| gattServer.getPrimaryService(glucose.uuid), expected)])); |
| }, 'Request for wrong service. Reject with NotFoundError.'); |
| |
| promise_test(() => { |
| // Because state doesn't get cleaned after each test in a file, we need to |
| // clean it ourselves. In this case, the services for a HeartRateDevice had |
| // been discovered in the previous test, since the state doesn't get cleaned |
| // it appears as if the services had been discovered for the device in this |
| // test. |
| // TODO(ortuno): split tests into different files. |
| // http://crbug.com/554240 |
| testRunner.setBluetoothMockDataSet(''); |
| testRunner.setBluetoothMockDataSet('DelayedServicesDiscoveryAdapter'); |
| return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]}) |
| .then(device => device.connectGATT()) |
| .then(gattServer => gattServer.getPrimaryService('heart_rate')) |
| .then(service => { |
| assert_equals(service.uuid, heart_rate.uuid); |
| }); |
| }, 'Request for service. Must return even when the services are not immediately discovered'); |
| |
| promise_test(() => { |
| // Because state doesn't get cleaned after each test in a file, we need to |
| // clean it ourselves. In this case, the services for a HeartRateDevice had |
| // been discovered in the previous test, since the state doesn't get cleaned |
| // it appears as if the services had been discovered for the device in this |
| // test. |
| // TODO(ortuno): split tests into different files. |
| // http://crbug.com/554240 |
| testRunner.setBluetoothMockDataSet(''); |
| testRunner.setBluetoothMockDataSet('DelayedServicesDiscoveryAdapter'); |
| return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]}) |
| .then(device => device.connectGATT()) |
| .then(gattServer => { |
| return assert_promise_rejects_with_message( |
| gattServer.getPrimaryService('battery_service'), |
| new DOMException('Service not found in device.', 'NotFoundError')); |
| }); |
| }, 'Request for wrong service. Must reject with NotFoundError even when the services' + |
| ' are not immediately discovered'); |
| |
| promise_test(function() { |
| testRunner.setBluetoothMockDataSet('HeartRateAdapter'); |
| return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]}) |
| .then(device => device.connectGATT()) |
| .then(gattServer => Promise.all( |
| [gattServer.getPrimaryService(generic_access.alias), |
| gattServer.getPrimaryService(generic_access.name), |
| gattServer.getPrimaryService(generic_access.uuid)])) |
| .then(services => { |
| services.forEach(service => { |
| assert_equals(service.uuid, generic_access.uuid, |
| 'Service UUID should be the same as requested UUID.'); |
| assert_true(service.isPrimary, |
| 'getPrimaryService should return a primary service.'); |
| }); |
| }); |
| }, 'Request for service. Should return right service'); |
| |
| promise_test(() => { |
| testRunner.setBluetoothMockDataSet('HeartRateAdapter'); |
| return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]}) |
| .then(device => device.connectGATT()) |
| .then(gattServer => Promise.all( |
| [gattServer.getPrimaryService(generic_access.alias), |
| gattServer.getPrimaryService(generic_access.alias), |
| gattServer.getPrimaryService(generic_access.name), |
| gattServer.getPrimaryService(generic_access.name), |
| gattServer.getPrimaryService(generic_access.uuid), |
| gattServer.getPrimaryService(generic_access.uuid)])) |
| .then(services => { |
| // getPrimaryService should return the same object if it was created |
| // earlier. https://crbug.com/495270 |
| // TODO(ortuno): Change to assert_equals. |
| for (let i = 1; i < services.length; i++) { |
| assert_not_equals(services[0], services[i], |
| 'Should return the same service as the first call.'); |
| } |
| }); |
| }, 'Calls to get the same service should return the same object.'); |
| |
| promise_test(() => { |
| testRunner.setBluetoothMockDataSet('HeartRateAdapter'); |
| return requestDeviceWithKeyDown({filters: [{services: ['heart_rate']}]}) |
| .then(device => device.connectGATT()) |
| .then(gattServer => { |
| return assert_promise_rejects_with_message( |
| gattServer.getPrimaryService('wrong_name'), new DOMException( |
| 'Failed to execute \'getPrimaryService\' on ' + |
| '\'BluetoothGATTRemoteServer\': Invalid Service name: ' + |
| '\'wrong_name\'. ' + |
| 'It must be a valid UUID alias (e.g. 0x1234), ' + |
| 'UUID (lowercase hex characters e.g. ' + |
| '\'00001234-0000-1000-8000-00805f9b34fb\'), ' + |
| 'or recognized standard name from ' + |
| 'https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx' + |
| ' e.g. \'alert_notification\'.', |
| 'SyntaxError'), |
| 'Wrong Service name passed.'); |
| }); |
| }, 'Wrong Service name. Reject with SyntaxError.'); |
| </script> |