/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ /* jshint esnext:true, globalstrict:true, moz:true, undef:true, unused:true */ /* globals Components,Assert,run_next_test,add_test,do_execute_soon */ "use strict"; /* globals ControllerStateMachine */ const {ControllerStateMachine} = ChromeUtils.import("resource://gre/modules/presentation/ControllerStateMachine.jsm"); /* globals ReceiverStateMachine */ const {ReceiverStateMachine} = ChromeUtils.import("resource://gre/modules/presentation/ReceiverStateMachine.jsm"); /* globals State */ const {State} = ChromeUtils.import("resource://gre/modules/presentation/StateMachineHelper.jsm"); const testControllerId = "test-controller-id"; const testPresentationId = "test-presentation-id"; const testUrl = "http://example.org"; let mockControllerChannel = {}; let mockReceiverChannel = {}; let controllerState = new ControllerStateMachine(mockControllerChannel, testControllerId); let receiverState = new ReceiverStateMachine(mockReceiverChannel); mockControllerChannel.sendCommand = function(command) { executeSoon(function() { receiverState.onCommand(command); }); }; mockReceiverChannel.sendCommand = function(command) { executeSoon(function() { controllerState.onCommand(command); }); }; function connect() { Assert.equal(controllerState.state, State.INIT, "controller in init state"); Assert.equal(receiverState.state, State.INIT, "receiver in init state"); // step 1: underlying connection is ready controllerState.onChannelReady(); Assert.equal(controllerState.state, State.CONNECTING, "controller in connecting state"); receiverState.onChannelReady(); Assert.equal(receiverState.state, State.CONNECTING, "receiver in connecting state"); // step 2: receiver reply to connect command mockReceiverChannel.notifyDeviceConnected = function(deviceId) { Assert.equal(deviceId, testControllerId, "receiver connect to mock controller"); Assert.equal(receiverState.state, State.CONNECTED, "receiver in connected state"); // step 3: controller receive connect-ack command mockControllerChannel.notifyDeviceConnected = function() { Assert.equal(controllerState.state, State.CONNECTED, "controller in connected state"); run_next_test(); }; }; } function launch() { Assert.equal(controllerState.state, State.CONNECTED, "controller in connected state"); Assert.equal(receiverState.state, State.CONNECTED, "receiver in connected state"); controllerState.launch(testPresentationId, testUrl); mockReceiverChannel.notifyLaunch = function(presentationId, url) { Assert.equal(receiverState.state, State.CONNECTED, "receiver in connected state"); Assert.equal(presentationId, testPresentationId, "expected presentationId received"); Assert.equal(url, testUrl, "expected url received"); mockControllerChannel.notifyLaunch = function(presId) { Assert.equal(controllerState.state, State.CONNECTED, "controller in connected state"); Assert.equal(presId, testPresentationId, "expected presentationId received from ack"); run_next_test(); }; }; } function terminateByController() { Assert.equal(controllerState.state, State.CONNECTED, "controller in connected state"); Assert.equal(receiverState.state, State.CONNECTED, "receiver in connected state"); controllerState.terminate(testPresentationId); mockReceiverChannel.notifyTerminate = function(presentationId) { Assert.equal(receiverState.state, State.CONNECTED, "receiver in connected state"); Assert.equal(presentationId, testPresentationId, "expected presentationId received"); mockControllerChannel.notifyTerminate = function(presId) { Assert.equal(controllerState.state, State.CONNECTED, "controller in connected state"); Assert.equal(presId, testPresentationId, "expected presentationId received from ack"); run_next_test(); }; receiverState.terminateAck(presentationId); }; } function terminateByReceiver() { Assert.equal(controllerState.state, State.CONNECTED, "controller in connected state"); Assert.equal(receiverState.state, State.CONNECTED, "receiver in connected state"); receiverState.terminate(testPresentationId); mockControllerChannel.notifyTerminate = function(presentationId) { Assert.equal(controllerState.state, State.CONNECTED, "controller in connected state"); Assert.equal(presentationId, testPresentationId, "expected presentationId received"); mockReceiverChannel.notifyTerminate = function(presId) { Assert.equal(receiverState.state, State.CONNECTED, "receiver in connected state"); Assert.equal(presId, testPresentationId, "expected presentationId received from ack"); run_next_test(); }; controllerState.terminateAck(presentationId); }; } function exchangeSDP() { Assert.equal(controllerState.state, State.CONNECTED, "controller in connected state"); Assert.equal(receiverState.state, State.CONNECTED, "receiver in connected state"); const testOffer = "test-offer"; const testAnswer = "test-answer"; const testIceCandidate = "test-ice-candidate"; controllerState.sendOffer(testOffer); mockReceiverChannel.notifyOffer = function(offer) { Assert.equal(offer, testOffer, "expected offer received"); receiverState.sendAnswer(testAnswer); mockControllerChannel.notifyAnswer = function(answer) { Assert.equal(answer, testAnswer, "expected answer received"); controllerState.updateIceCandidate(testIceCandidate); mockReceiverChannel.notifyIceCandidate = function(candidate) { Assert.equal(candidate, testIceCandidate, "expected ice candidate received in receiver"); receiverState.updateIceCandidate(testIceCandidate); mockControllerChannel.notifyIceCandidate = function(controllerCandidate) { Assert.equal(controllerCandidate, testIceCandidate, "expected ice candidate received in controller"); run_next_test(); }; }; }; }; } function disconnect() { // step 1: controller send disconnect command controllerState.onChannelClosed(Cr.NS_OK, false); Assert.equal(controllerState.state, State.CLOSING, "controller in closing state"); mockReceiverChannel.notifyDisconnected = function(reason) { Assert.equal(reason, Cr.NS_OK, "receive close reason"); Assert.equal(receiverState.state, State.CLOSED, "receiver in closed state"); receiverState.onChannelClosed(Cr.NS_OK, true); Assert.equal(receiverState.state, State.CLOSED, "receiver in closed state"); mockControllerChannel.notifyDisconnected = function(disconnectReason) { Assert.equal(disconnectReason, Cr.NS_OK, "receive close reason"); Assert.equal(controllerState.state, State.CLOSED, "controller in closed state"); run_next_test(); }; controllerState.onChannelClosed(Cr.NS_OK, true); }; } function receiverDisconnect() { // initial state: controller and receiver are connected controllerState.state = State.CONNECTED; receiverState.state = State.CONNECTED; // step 1: controller send disconnect command receiverState.onChannelClosed(Cr.NS_OK, false); Assert.equal(receiverState.state, State.CLOSING, "receiver in closing state"); mockControllerChannel.notifyDisconnected = function(reason) { Assert.equal(reason, Cr.NS_OK, "receive close reason"); Assert.equal(controllerState.state, State.CLOSED, "controller in closed state"); controllerState.onChannelClosed(Cr.NS_OK, true); Assert.equal(controllerState.state, State.CLOSED, "controller in closed state"); mockReceiverChannel.notifyDisconnected = function(disconnectReason) { Assert.equal(disconnectReason, Cr.NS_OK, "receive close reason"); Assert.equal(receiverState.state, State.CLOSED, "receiver in closed state"); run_next_test(); }; receiverState.onChannelClosed(Cr.NS_OK, true); }; } function abnormalDisconnect() { // initial state: controller and receiver are connected controllerState.state = State.CONNECTED; receiverState.state = State.CONNECTED; const testErrorReason = Cr.NS_ERROR_FAILURE; // step 1: controller send disconnect command controllerState.onChannelClosed(testErrorReason, false); Assert.equal(controllerState.state, State.CLOSING, "controller in closing state"); mockReceiverChannel.notifyDisconnected = function(reason) { Assert.equal(reason, testErrorReason, "receive abnormal close reason"); Assert.equal(receiverState.state, State.CLOSED, "receiver in closed state"); receiverState.onChannelClosed(Cr.NS_OK, true); Assert.equal(receiverState.state, State.CLOSED, "receiver in closed state"); mockControllerChannel.notifyDisconnected = function(disconnectReason) { Assert.equal(disconnectReason, testErrorReason, "receive abnormal close reason"); Assert.equal(controllerState.state, State.CLOSED, "controller in closed state"); run_next_test(); }; controllerState.onChannelClosed(Cr.NS_OK, true); }; } add_test(connect); add_test(launch); add_test(terminateByController); add_test(terminateByReceiver); add_test(exchangeSDP); add_test(disconnect); add_test(receiverDisconnect); add_test(abnormalDisconnect);