103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file.
403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Tests launched by extensions/renderer/api/serial/data_receiver_unittest.cc
603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)var test = require('test').binding;
803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)var unittestBindings = require('test_environment_specific_bindings');
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivar BUFFER_SIZE = 10;
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivar FATAL_ERROR = 2;
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Returns a promise to a newly created DataReceiver.
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)function createReceiver() {
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return Promise.all([
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    requireAsync('content/public/renderer/service_provider'),
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    requireAsync('data_receiver'),
1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    requireAsync('device/serial/data_stream.mojom'),
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ]).then(function(modules) {
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    var serviceProvider = modules[0];
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    var dataReceiver = modules[1];
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    var dataStream = modules[2];
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return new dataReceiver.DataReceiver(
2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        serviceProvider.connectToService(dataStream.DataSourceProxy.NAME_),
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        BUFFER_SIZE,
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        FATAL_ERROR);
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  });
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Returns a promise that will resolve to |receiver| when it has received an
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// error from its DataSource.
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifunction waitForReceiveError(receiver) {
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return new Promise(function(resolve, reject) {
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    var onError = receiver.onError;
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    receiver.onError = function() {
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      $Function.apply(onError, receiver, arguments);
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      resolve(receiver);
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    };
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  });
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Returns a function that receives data from a provided DataReceiver
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// |receiver|, checks that it matches the expected data and returns a promise
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// that will resolve to |receiver|.
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifunction receiveAndCheckData(expectedData) {
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return function(receiver) {
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return receiver.receive().then(function(data) {
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      test.assertEq(expectedData.length, data.byteLength);
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      for (var i = 0; i < expectedData.length; i++)
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        test.assertEq(expectedData.charCodeAt(i), new Int8Array(data)[i]);
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return receiver;
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    });
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    test.assertThrows(
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        receiver.receive, receiver, [], 'Receive already in progress.');
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Returns a function that attempts to receive data from a provided DataReceiver
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// |receiver|, checks that the correct error is reported and returns a promise
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// that will resolve to |receiver|.
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifunction receiveAndCheckError(expectedError) {
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return function(receiver) {
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return receiver.receive().catch(function(error) {
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      test.assertEq(expectedError, error.error);
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return receiver;
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    });
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    test.assertThrows(
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        receiver.receive, receiver, [], 'Receive already in progress.');
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Serializes and deserializes the provided DataReceiver |receiver|, returning
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// a promise that will resolve to the newly deserialized DataReceiver.
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifunction serializeRoundTrip(receiver) {
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return Promise.all([
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    receiver.serialize(),
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    requireAsync('data_receiver'),
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ]).then(function(promises) {
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    var serialized = promises[0];
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    var dataReceiverModule = promises[1];
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return dataReceiverModule.DataReceiver.deserialize(serialized);
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  });
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Closes and returns the provided DataReceiver |receiver|.
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccifunction closeReceiver(receiver) {
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  receiver.close();
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return receiver;
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)unittestBindings.exportTests([
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  function testReceive() {
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    createReceiver()
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckData('a'))
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(closeReceiver)
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(test.succeed, test.fail);
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  },
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  function testReceiveError() {
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    createReceiver()
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckError(1))
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(closeReceiver)
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(test.succeed, test.fail);
10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  },
10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  function testReceiveDataAndError() {
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    createReceiver()
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckData('a'))
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckError(1))
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckData('b'))
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(closeReceiver)
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(test.succeed, test.fail);
11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  },
11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  function testReceiveErrorThenData() {
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    createReceiver()
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckError(1))
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckData('a'))
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(closeReceiver)
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(test.succeed, test.fail);
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  },
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  function testReceiveBeforeAndAfterSerialization() {
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    createReceiver()
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckData('a'))
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(serializeRoundTrip)
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckData('b'))
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(closeReceiver)
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(test.succeed, test.fail);
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  },
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  function testReceiveErrorSerialization() {
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    createReceiver()
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(waitForReceiveError)
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(serializeRoundTrip)
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckError(1))
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckError(3))
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(closeReceiver)
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(test.succeed, test.fail);
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  },
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  function testReceiveDataAndErrorSerialization() {
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    createReceiver()
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(waitForReceiveError)
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckData('a'))
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(serializeRoundTrip)
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckError(1))
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckData('b'))
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckError(3))
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(closeReceiver)
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(test.succeed, test.fail);
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  },
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  function testSerializeDuringReceive() {
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    var receiver = createReceiver();
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Promise.all([
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        receiver.then(receiveAndCheckError(FATAL_ERROR)),
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        receiver
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            .then(serializeRoundTrip)
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            .then(receiveAndCheckData('a'))
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            .then(closeReceiver)
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ]).then(test.succeed, test.fail);
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  },
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  function testSerializeAfterClose() {
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    function receiveAfterClose(receiver) {
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      test.assertThrows(
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          receiver.receive, receiver, [], 'DataReceiver has been closed');
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    createReceiver()
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(closeReceiver)
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(serializeRoundTrip)
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAfterClose)
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(test.succeed, test.fail);
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  },
17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  function testSourceShutdown() {
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    createReceiver()
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(receiveAndCheckError(FATAL_ERROR))
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(closeReceiver)
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        .then(test.succeed, test.fail);
18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  },
18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)], test.runTests, exports);
186