Bug 1090209 - Part 2 Use MozLoopService to manage window ids centrally, and store the data for the window opening. r=mikedeboer
Use LoopCalls directly to handle busy statuses.
This commit is contained in:
@@ -47,7 +47,7 @@ CallProgressSocket.prototype = {
|
||||
connect: function(onSuccess, onError) {
|
||||
this._onSuccess = onSuccess;
|
||||
this._onError = onError ||
|
||||
(reason => {MozLoopService.logwarn("LoopCalls::callProgessSocket - ", reason);});
|
||||
(reason => {MozLoopService.log.warn("LoopCalls::callProgessSocket - ", reason);});
|
||||
|
||||
if (!onSuccess) {
|
||||
this._onError("missing onSuccess argument");
|
||||
@@ -126,9 +126,8 @@ CallProgressSocket.prototype = {
|
||||
let msg = {};
|
||||
try {
|
||||
msg = JSON.parse(aMsg);
|
||||
}
|
||||
catch (error) {
|
||||
MozLoopService.logerror("LoopCalls: error parsing progress message - ", error);
|
||||
} catch (error) {
|
||||
MozLoopService.log.error("LoopCalls: error parsing progress message - ", error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -146,7 +145,7 @@ CallProgressSocket.prototype = {
|
||||
*/
|
||||
_send: function(aMsg) {
|
||||
if (!this._handshakeComplete) {
|
||||
MozLoopService.logwarn("LoopCalls::_send error - handshake not complete");
|
||||
MozLoopService.log.warn("LoopCalls::_send error - handshake not complete");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -179,14 +178,12 @@ CallProgressSocket.prototype = {
|
||||
* and register with the Loop server.
|
||||
*/
|
||||
let LoopCallsInternal = {
|
||||
callsData: {
|
||||
inUse: false,
|
||||
},
|
||||
|
||||
mocks: {
|
||||
webSocket: undefined,
|
||||
},
|
||||
|
||||
conversationInProgress: {},
|
||||
|
||||
/**
|
||||
* Callback from MozLoopPushHandler - A push notification has been received from
|
||||
* the server.
|
||||
@@ -248,21 +245,19 @@ let LoopCallsInternal = {
|
||||
let respData = JSON.parse(response.body);
|
||||
if (respData.calls && Array.isArray(respData.calls)) {
|
||||
respData.calls.forEach((callData) => {
|
||||
if (!this.callsData.inUse) {
|
||||
if ("id" in this.conversationInProgress) {
|
||||
this._returnBusy(callData);
|
||||
} else {
|
||||
callData.sessionType = sessionType;
|
||||
// XXX Bug 1090209 will transiton into a better window id.
|
||||
callData.windowId = callData.callId;
|
||||
callData.type = "incoming";
|
||||
this._startCall(callData);
|
||||
} else {
|
||||
this._returnBusy(callData);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
MozLoopService.logwarn("Error: missing calls[] in response");
|
||||
MozLoopService.log.warn("Error: missing calls[] in response");
|
||||
}
|
||||
} catch (err) {
|
||||
MozLoopService.logwarn("Error parsing calls info", err);
|
||||
MozLoopService.log.warn("Error parsing calls info", err);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -274,13 +269,7 @@ let LoopCallsInternal = {
|
||||
* "outgoing".
|
||||
*/
|
||||
_startCall: function(callData) {
|
||||
this.callsData.inUse = true;
|
||||
this.callsData.data = callData;
|
||||
MozLoopService.openChatWindow(
|
||||
null,
|
||||
// No title, let the page set that, to avoid flickering.
|
||||
"",
|
||||
"about:loopconversation#" + callData.windowId);
|
||||
this.conversationInProgress.id = MozLoopService.openChatWindow(callData);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -291,15 +280,13 @@ let LoopCallsInternal = {
|
||||
* @return true if the call is opened, false if it is not opened (i.e. busy)
|
||||
*/
|
||||
startDirectCall: function(contact, callType) {
|
||||
if (this.callsData.inUse)
|
||||
if ("id" in this.conversationInProgress)
|
||||
return false;
|
||||
|
||||
var callData = {
|
||||
contact: contact,
|
||||
callType: callType,
|
||||
type: "outgoing",
|
||||
// XXX Really we shouldn't be using random numbers, bug 1090209 will fix this.
|
||||
windowId: Math.floor((Math.random() * 100000000))
|
||||
type: "outgoing"
|
||||
};
|
||||
|
||||
this._startCall(callData);
|
||||
@@ -343,21 +330,18 @@ this.LoopCalls = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the callData for a specific conversation window id.
|
||||
* Used to signify that a call is in progress.
|
||||
*
|
||||
* The data was retrieved from the LoopServer via a GET/calls/<version> request
|
||||
* triggered by an incoming message from the LoopPushServer.
|
||||
*
|
||||
* @param {Number} conversationWindowId
|
||||
* @return {callData} The callData or undefined if error.
|
||||
* @param {String} The window id for the call in progress.
|
||||
*/
|
||||
getCallData: function(conversationWindowId) {
|
||||
if (LoopCallsInternal.callsData.data &&
|
||||
LoopCallsInternal.callsData.data.windowId == conversationWindowId) {
|
||||
return LoopCallsInternal.callsData.data;
|
||||
} else {
|
||||
return undefined;
|
||||
setCallInProgress: function(conversationWindowId) {
|
||||
if ("id" in LoopCallsInternal.conversationInProgress &&
|
||||
LoopCallsInternal.conversationInProgress.id != conversationWindowId) {
|
||||
MozLoopService.log.error("Starting a new conversation when one is already in progress?");
|
||||
return;
|
||||
}
|
||||
|
||||
LoopCallsInternal.conversationInProgress.id = conversationWindowId;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -367,11 +351,10 @@ this.LoopCalls = {
|
||||
*
|
||||
* @param {Number} conversationWindowId
|
||||
*/
|
||||
releaseCallData: function(conversationWindowId) {
|
||||
if (LoopCallsInternal.callsData.data &&
|
||||
LoopCallsInternal.callsData.data.windowId == conversationWindowId) {
|
||||
LoopCallsInternal.callsData.data = undefined;
|
||||
LoopCallsInternal.callsData.inUse = false;
|
||||
clearCallInProgress: function(conversationWindowId) {
|
||||
if ("id" in LoopCallsInternal.conversationInProgress &&
|
||||
LoopCallsInternal.conversationInProgress.id == conversationWindowId) {
|
||||
delete LoopCallsInternal.conversationInProgress.id;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -104,10 +104,21 @@ const injectObjectAPI = function(api, targetWindow) {
|
||||
// through the priv => unpriv barrier with `Cu.cloneInto()`.
|
||||
Object.keys(api).forEach(func => {
|
||||
injectedAPI[func] = function(...params) {
|
||||
let callback = params.pop();
|
||||
api[func](...params, function(...results) {
|
||||
callback(...[cloneValueInto(r, targetWindow) for (r of results)]);
|
||||
});
|
||||
let lastParam = params.pop();
|
||||
|
||||
// If the last parameter is a function, assume its a callback
|
||||
// and wrap it differently.
|
||||
if (lastParam && typeof lastParam === "function") {
|
||||
api[func](...params, function(...results) {
|
||||
lastParam(...[cloneValueInto(r, targetWindow) for (r of results)]);
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
return cloneValueInto(api[func](...params, lastParam), targetWindow);
|
||||
} catch (ex) {
|
||||
return cloneValueInto(ex, targetWindow);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -135,6 +146,7 @@ function injectLoopAPI(targetWindow) {
|
||||
let appVersionInfo;
|
||||
let contactsAPI;
|
||||
let roomsAPI;
|
||||
let callsAPI;
|
||||
|
||||
let api = {
|
||||
/**
|
||||
@@ -206,34 +218,20 @@ function injectLoopAPI(targetWindow) {
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the callData for a specific conversation window id.
|
||||
* Returns the window data for a specific conversation window id.
|
||||
*
|
||||
* The data was retrieved from the LoopServer via a GET/calls/<version> request
|
||||
* triggered by an incoming message from the LoopPushServer.
|
||||
* This data will be relevant to the type of window, e.g. rooms or calls.
|
||||
* See LoopRooms or LoopCalls for more information.
|
||||
*
|
||||
* @param {Number} conversationWindowId
|
||||
* @returns {callData} The callData or undefined if error.
|
||||
* @param {String} conversationWindowId
|
||||
* @returns {Object} The window data or null if error.
|
||||
*/
|
||||
getCallData: {
|
||||
getConversationWindowData: {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function(conversationWindowId) {
|
||||
return Cu.cloneInto(LoopCalls.getCallData(conversationWindowId), targetWindow);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Releases the callData for a specific conversation window id.
|
||||
*
|
||||
* The result of this call will be a free call session slot.
|
||||
*
|
||||
* @param {Number} conversationWindowId
|
||||
*/
|
||||
releaseCallData: {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function(conversationWindowId) {
|
||||
LoopCalls.releaseCallData(conversationWindowId);
|
||||
return Cu.cloneInto(MozLoopService.getConversationWindowData(conversationWindowId),
|
||||
targetWindow);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -273,6 +271,22 @@ function injectLoopAPI(targetWindow) {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the calls API.
|
||||
*
|
||||
* @returns {Object} The rooms API object
|
||||
*/
|
||||
calls: {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
if (callsAPI) {
|
||||
return callsAPI;
|
||||
}
|
||||
|
||||
return callsAPI = injectObjectAPI(LoopCalls, targetWindow);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Import a list of (new) contacts from an external data source.
|
||||
*
|
||||
@@ -670,21 +684,6 @@ function injectLoopAPI(targetWindow) {
|
||||
return MozLoopService.generateUUID();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts a direct call to the contact addresses.
|
||||
*
|
||||
* @param {Object} contact The contact to call
|
||||
* @param {String} callType The type of call, e.g. "audio-video" or "audio-only"
|
||||
* @return true if the call is opened, false if it is not opened (i.e. busy)
|
||||
*/
|
||||
startDirectCall: {
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: function(contact, callType) {
|
||||
LoopCalls.startDirectCall(contact, callType);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function onStatusChanged(aSubject, aTopic, aData) {
|
||||
|
||||
@@ -116,6 +116,8 @@ let gFxAEnabled = true;
|
||||
let gFxAOAuthClientPromise = null;
|
||||
let gFxAOAuthClient = null;
|
||||
let gErrors = new Map();
|
||||
let gLastWindowId = 0;
|
||||
let gConversationWindowData = new Map();
|
||||
|
||||
/**
|
||||
* Internal helper methods and state
|
||||
@@ -693,15 +695,20 @@ let MozLoopServiceInternal = {
|
||||
/**
|
||||
* Opens the chat window
|
||||
*
|
||||
* @param {Object} contentWindow The window to open the chat window in, may
|
||||
* be null.
|
||||
* @param {String} title The title of the chat window.
|
||||
* @param {String} url The page to load in the chat window.
|
||||
* @param {Object} conversationWindowData The data to be obtained by the
|
||||
* window when it opens.
|
||||
* @returns {Number} The id of the window.
|
||||
*/
|
||||
openChatWindow: function(contentWindow, title, url) {
|
||||
openChatWindow: function(conversationWindowData) {
|
||||
// So I guess the origin is the loop server!?
|
||||
let origin = this.loopServerUri;
|
||||
url = url.spec || url;
|
||||
let windowId = gLastWindowId++;
|
||||
// Store the id as a string, as that's what we use elsewhere.
|
||||
windowId = windowId.toString();
|
||||
|
||||
gConversationWindowData.set(windowId, conversationWindowData);
|
||||
|
||||
let url = "about:loopconversation#" + windowId;
|
||||
|
||||
let callback = chatbox => {
|
||||
// We need to use DOMContentLoaded as otherwise the injection will happen
|
||||
@@ -749,7 +756,8 @@ let MozLoopServiceInternal = {
|
||||
}.bind(this), true);
|
||||
};
|
||||
|
||||
Chat.open(contentWindow, origin, title, url, undefined, undefined, callback);
|
||||
Chat.open(null, origin, "", url, undefined, undefined, callback);
|
||||
return windowId;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -996,13 +1004,12 @@ this.MozLoopService = {
|
||||
/**
|
||||
* Opens the chat window
|
||||
*
|
||||
* @param {Object} contentWindow The window to open the chat window in, may
|
||||
* be null.
|
||||
* @param {String} title The title of the chat window.
|
||||
* @param {String} url The page to load in the chat window.
|
||||
* @param {Object} conversationWindowData The data to be obtained by the
|
||||
* window when it opens.
|
||||
* @returns {Number} The id of the window.
|
||||
*/
|
||||
openChatWindow: function(contentWindow, title, url) {
|
||||
MozLoopServiceInternal.openChatWindow(contentWindow, title, url);
|
||||
openChatWindow: function(conversationWindowData) {
|
||||
return MozLoopServiceInternal.openChatWindow(conversationWindowData);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1416,4 +1423,24 @@ this.MozLoopService = {
|
||||
return MozLoopServiceInternal.hawkRequest(sessionType, path, method, payloadObj).catch(
|
||||
error => {MozLoopServiceInternal._hawkRequestError(error);});
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the window data for a specific conversation window id.
|
||||
*
|
||||
* This data will be relevant to the type of window, e.g. rooms or calls.
|
||||
* See LoopRooms or LoopCalls for more information.
|
||||
*
|
||||
* @param {String} conversationWindowId
|
||||
* @returns {Object} The window data or null if error.
|
||||
*/
|
||||
getConversationWindowData: function(conversationWindowId) {
|
||||
if (gConversationWindowData.has(conversationWindowId)) {
|
||||
var conversationData = gConversationWindowData.get(conversationWindowId);
|
||||
gConversationWindowData.delete(conversationWindowId);
|
||||
return conversationData;
|
||||
}
|
||||
|
||||
log.error("Window data was already fetched before. Possible race condition!");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -392,12 +392,12 @@ loop.contacts = (function(_, mozL10n) {
|
||||
break;
|
||||
case "video-call":
|
||||
if (!contact.blocked) {
|
||||
navigator.mozLoop.startDirectCall(contact, CALL_TYPES.AUDIO_VIDEO);
|
||||
navigator.mozLoop.calls.startDirectCall(contact, CALL_TYPES.AUDIO_VIDEO);
|
||||
}
|
||||
break;
|
||||
case "audio-call":
|
||||
if (!contact.blocked) {
|
||||
navigator.mozLoop.startDirectCall(contact, CALL_TYPES.AUDIO_ONLY);
|
||||
navigator.mozLoop.calls.startDirectCall(contact, CALL_TYPES.AUDIO_ONLY);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -392,12 +392,12 @@ loop.contacts = (function(_, mozL10n) {
|
||||
break;
|
||||
case "video-call":
|
||||
if (!contact.blocked) {
|
||||
navigator.mozLoop.startDirectCall(contact, CALL_TYPES.AUDIO_VIDEO);
|
||||
navigator.mozLoop.calls.startDirectCall(contact, CALL_TYPES.AUDIO_VIDEO);
|
||||
}
|
||||
break;
|
||||
case "audio-call":
|
||||
if (!contact.blocked) {
|
||||
navigator.mozLoop.startDirectCall(contact, CALL_TYPES.AUDIO_ONLY);
|
||||
navigator.mozLoop.calls.startDirectCall(contact, CALL_TYPES.AUDIO_ONLY);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -218,7 +218,9 @@ loop.conversation = (function(mozL10n) {
|
||||
client: React.PropTypes.instanceOf(loop.Client).isRequired,
|
||||
conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel)
|
||||
.isRequired,
|
||||
sdk: React.PropTypes.object.isRequired
|
||||
sdk: React.PropTypes.object.isRequired,
|
||||
conversationAppStore: React.PropTypes.instanceOf(
|
||||
loop.store.ConversationAppStore).isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
@@ -352,13 +354,9 @@ loop.conversation = (function(mozL10n) {
|
||||
setupIncomingCall: function() {
|
||||
navigator.mozLoop.startAlerting();
|
||||
|
||||
var callData = navigator.mozLoop.getCallData(this.props.conversation.get("windowId"));
|
||||
if (!callData) {
|
||||
// XXX Not the ideal response, but bug 1047410 will be replacing
|
||||
// this by better "call failed" UI.
|
||||
console.error("Failed to get the call data");
|
||||
return;
|
||||
}
|
||||
// XXX This is a hack until we rework for the flux model in bug 1088672.
|
||||
var callData = this.props.conversationAppStore.getStoreState().windowData;
|
||||
|
||||
this.props.conversation.setIncomingSessionData(callData);
|
||||
this._setupWebSocket();
|
||||
},
|
||||
@@ -374,7 +372,8 @@ loop.conversation = (function(mozL10n) {
|
||||
* Moves the call to the end state
|
||||
*/
|
||||
endCall: function() {
|
||||
navigator.mozLoop.releaseCallData(this.props.conversation.get("windowId"));
|
||||
navigator.mozLoop.calls.clearCallInProgress(
|
||||
this.props.conversation.get("windowId"));
|
||||
this.setState({callStatus: "end"});
|
||||
},
|
||||
|
||||
@@ -475,7 +474,8 @@ loop.conversation = (function(mozL10n) {
|
||||
*/
|
||||
_declineCall: function() {
|
||||
this._websocket.decline();
|
||||
navigator.mozLoop.releaseCallData(this.props.conversation.get("windowId"));
|
||||
navigator.mozLoop.calls.clearCallInProgress(
|
||||
this.props.conversation.get("windowId"));
|
||||
this._websocket.close();
|
||||
// Having a timeout here lets the logging for the websocket complete and be
|
||||
// displayed on the console if both are on.
|
||||
@@ -565,7 +565,8 @@ loop.conversation = (function(mozL10n) {
|
||||
return (IncomingConversationView({
|
||||
client: this.props.client,
|
||||
conversation: this.props.conversation,
|
||||
sdk: this.props.sdk}
|
||||
sdk: this.props.sdk,
|
||||
conversationAppStore: this.props.conversationAppStore}
|
||||
));
|
||||
}
|
||||
case "outgoing": {
|
||||
@@ -582,7 +583,7 @@ loop.conversation = (function(mozL10n) {
|
||||
}
|
||||
case "failed": {
|
||||
return (GenericFailureView({
|
||||
cancelCall: this.closeWindow.bind(this)}
|
||||
cancelCall: this.closeWindow}
|
||||
));
|
||||
}
|
||||
default: {
|
||||
@@ -657,7 +658,7 @@ loop.conversation = (function(mozL10n) {
|
||||
|
||||
window.addEventListener("unload", function(event) {
|
||||
// Handle direct close of dialog box via [x] control.
|
||||
navigator.mozLoop.releaseCallData(windowId);
|
||||
navigator.mozLoop.calls.clearCallInProgress(windowId);
|
||||
});
|
||||
|
||||
React.renderComponent(AppControllerView({
|
||||
|
||||
@@ -218,7 +218,9 @@ loop.conversation = (function(mozL10n) {
|
||||
client: React.PropTypes.instanceOf(loop.Client).isRequired,
|
||||
conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel)
|
||||
.isRequired,
|
||||
sdk: React.PropTypes.object.isRequired
|
||||
sdk: React.PropTypes.object.isRequired,
|
||||
conversationAppStore: React.PropTypes.instanceOf(
|
||||
loop.store.ConversationAppStore).isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
@@ -352,13 +354,9 @@ loop.conversation = (function(mozL10n) {
|
||||
setupIncomingCall: function() {
|
||||
navigator.mozLoop.startAlerting();
|
||||
|
||||
var callData = navigator.mozLoop.getCallData(this.props.conversation.get("windowId"));
|
||||
if (!callData) {
|
||||
// XXX Not the ideal response, but bug 1047410 will be replacing
|
||||
// this by better "call failed" UI.
|
||||
console.error("Failed to get the call data");
|
||||
return;
|
||||
}
|
||||
// XXX This is a hack until we rework for the flux model in bug 1088672.
|
||||
var callData = this.props.conversationAppStore.getStoreState().windowData;
|
||||
|
||||
this.props.conversation.setIncomingSessionData(callData);
|
||||
this._setupWebSocket();
|
||||
},
|
||||
@@ -374,7 +372,8 @@ loop.conversation = (function(mozL10n) {
|
||||
* Moves the call to the end state
|
||||
*/
|
||||
endCall: function() {
|
||||
navigator.mozLoop.releaseCallData(this.props.conversation.get("windowId"));
|
||||
navigator.mozLoop.calls.clearCallInProgress(
|
||||
this.props.conversation.get("windowId"));
|
||||
this.setState({callStatus: "end"});
|
||||
},
|
||||
|
||||
@@ -475,7 +474,8 @@ loop.conversation = (function(mozL10n) {
|
||||
*/
|
||||
_declineCall: function() {
|
||||
this._websocket.decline();
|
||||
navigator.mozLoop.releaseCallData(this.props.conversation.get("windowId"));
|
||||
navigator.mozLoop.calls.clearCallInProgress(
|
||||
this.props.conversation.get("windowId"));
|
||||
this._websocket.close();
|
||||
// Having a timeout here lets the logging for the websocket complete and be
|
||||
// displayed on the console if both are on.
|
||||
@@ -566,6 +566,7 @@ loop.conversation = (function(mozL10n) {
|
||||
client={this.props.client}
|
||||
conversation={this.props.conversation}
|
||||
sdk={this.props.sdk}
|
||||
conversationAppStore={this.props.conversationAppStore}
|
||||
/>);
|
||||
}
|
||||
case "outgoing": {
|
||||
@@ -582,7 +583,7 @@ loop.conversation = (function(mozL10n) {
|
||||
}
|
||||
case "failed": {
|
||||
return (<GenericFailureView
|
||||
cancelCall={this.closeWindow.bind(this)}
|
||||
cancelCall={this.closeWindow}
|
||||
/>);
|
||||
}
|
||||
default: {
|
||||
@@ -657,7 +658,7 @@ loop.conversation = (function(mozL10n) {
|
||||
|
||||
window.addEventListener("unload", function(event) {
|
||||
// Handle direct close of dialog box via [x] control.
|
||||
navigator.mozLoop.releaseCallData(windowId);
|
||||
navigator.mozLoop.calls.clearCallInProgress(windowId);
|
||||
});
|
||||
|
||||
React.renderComponent(<AppControllerView
|
||||
|
||||
@@ -66,7 +66,7 @@ loop.store.ConversationAppStore = (function() {
|
||||
if (this._mozLoop.getLoopBoolPref("test.alwaysUseRooms")) {
|
||||
windowData = {type: "room", localRoomId: "42"};
|
||||
} else {
|
||||
windowData = this._mozLoop.getCallData(actionData.windowId);
|
||||
windowData = this._mozLoop.getConversationWindowData(actionData.windowId);
|
||||
}
|
||||
|
||||
if (!windowData) {
|
||||
@@ -75,11 +75,15 @@ loop.store.ConversationAppStore = (function() {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setStoreState({windowType: windowData.type});
|
||||
|
||||
this._dispatcher.dispatch(new loop.shared.actions.SetupWindowData({
|
||||
// XXX windowData is a hack for the IncomingConversationView until
|
||||
// we rework it for the flux model in bug 1088672.
|
||||
this.setStoreState({
|
||||
windowType: windowData.type,
|
||||
windowData: windowData
|
||||
}));
|
||||
});
|
||||
|
||||
this._dispatcher.dispatch(new loop.shared.actions.SetupWindowData(_.extend({
|
||||
windowId: actionData.windowId}, windowData)));
|
||||
}
|
||||
}, Backbone.Events);
|
||||
|
||||
|
||||
@@ -42,7 +42,13 @@ loop.shared.actions = (function() {
|
||||
* record the appropriate data.
|
||||
*/
|
||||
SetupWindowData: Action.define("setupWindowData", {
|
||||
windowData: Object
|
||||
windowId: String,
|
||||
type: String
|
||||
|
||||
// Optional Items. There are other optional items typically sent
|
||||
// around with this action. They are for the setup of calls and rooms and
|
||||
// depend on the type. See LoopCalls and LoopRooms for the details of this
|
||||
// data.
|
||||
}),
|
||||
|
||||
/**
|
||||
|
||||
@@ -189,8 +189,7 @@ loop.store.ConversationStore = (function() {
|
||||
},
|
||||
|
||||
setupWindowData: function(actionData) {
|
||||
var windowData = actionData.windowData;
|
||||
var windowType = windowData.type;
|
||||
var windowType = actionData.type;
|
||||
if (windowType !== "outgoing" &&
|
||||
windowType !== "incoming") {
|
||||
// Not for this store, don't do anything.
|
||||
@@ -198,12 +197,12 @@ loop.store.ConversationStore = (function() {
|
||||
}
|
||||
|
||||
this.set({
|
||||
contact: windowData.contact,
|
||||
contact: actionData.contact,
|
||||
outgoing: windowType === "outgoing",
|
||||
windowId: windowData.windowId,
|
||||
callType: windowData.callType,
|
||||
windowId: actionData.windowId,
|
||||
callType: actionData.callType,
|
||||
callState: CALL_STATES.GATHER,
|
||||
videoMuted: windowData.callType === CALL_TYPES.AUDIO_ONLY
|
||||
videoMuted: actionData.callType === CALL_TYPES.AUDIO_ONLY
|
||||
});
|
||||
|
||||
if (this.get("outgoing")) {
|
||||
@@ -317,6 +316,8 @@ loop.store.ConversationStore = (function() {
|
||||
var contactAddresses = [];
|
||||
var contact = this.get("contact");
|
||||
|
||||
navigator.mozLoop.calls.setCallInProgress(this.get("windowId"));
|
||||
|
||||
function appendContactValues(property, strip) {
|
||||
if (contact.hasOwnProperty(property)) {
|
||||
contact[property].forEach(function(item) {
|
||||
@@ -396,7 +397,7 @@ loop.store.ConversationStore = (function() {
|
||||
delete this._websocket;
|
||||
}
|
||||
|
||||
navigator.mozLoop.releaseCallData(this.get("windowId"));
|
||||
navigator.mozLoop.calls.clearCallInProgress(this.get("windowId"));
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -100,16 +100,16 @@ loop.store.LocalRoomStore = (function() {
|
||||
* @param {sharedActions.SetupWindowData} actionData
|
||||
*/
|
||||
setupWindowData: function(actionData) {
|
||||
if (actionData.windowData.type !== "room") {
|
||||
if (actionData.type !== "room") {
|
||||
// Nothing for us to do here, leave it to other stores.
|
||||
return;
|
||||
}
|
||||
|
||||
this._fetchRoomData(actionData.windowData.localRoomId,
|
||||
this._fetchRoomData(actionData.localRoomId,
|
||||
function(error, roomData) {
|
||||
this.setStoreState({
|
||||
error: error,
|
||||
localRoomId: actionData.windowData.localRoomId,
|
||||
localRoomId: actionData.localRoomId,
|
||||
serverData: roomData
|
||||
});
|
||||
}.bind(this));
|
||||
|
||||
@@ -32,10 +32,10 @@ describe("loop.store.ConversationAppStore", function () {
|
||||
});
|
||||
|
||||
describe("#getWindowData", function() {
|
||||
var fakeCallData, fakeGetWindowData, fakeMozLoop, store;
|
||||
var fakeWindowData, fakeGetWindowData, fakeMozLoop, store;
|
||||
|
||||
beforeEach(function() {
|
||||
fakeCallData = {
|
||||
fakeWindowData = {
|
||||
type: "incoming",
|
||||
callId: "123456"
|
||||
};
|
||||
@@ -47,9 +47,9 @@ describe("loop.store.ConversationAppStore", function () {
|
||||
fakeMozLoop = {
|
||||
// XXX Remove me in bug 1074678
|
||||
getLoopBoolPref: function() { return false; },
|
||||
getCallData: function(windowId) {
|
||||
getConversationWindowData: function(windowId) {
|
||||
if (windowId === "42") {
|
||||
return fakeCallData;
|
||||
return fakeWindowData;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -64,7 +64,10 @@ describe("loop.store.ConversationAppStore", function () {
|
||||
it("should fetch the window type from the mozLoop API", function() {
|
||||
dispatcher.dispatch(new sharedActions.GetWindowData(fakeGetWindowData));
|
||||
|
||||
expect(store.getStoreState()).eql({windowType: "incoming"});
|
||||
expect(store.getStoreState()).eql({
|
||||
windowType: "incoming",
|
||||
windowData: fakeWindowData
|
||||
});
|
||||
});
|
||||
|
||||
it("should dispatch a SetupWindowData action with the data from the mozLoop API",
|
||||
@@ -75,9 +78,9 @@ describe("loop.store.ConversationAppStore", function () {
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||
new sharedActions.SetupWindowData({
|
||||
windowData: fakeCallData
|
||||
}));
|
||||
new sharedActions.SetupWindowData(_.extend({
|
||||
windowId: fakeGetWindowData.windowId
|
||||
}, fakeWindowData)));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -41,8 +41,9 @@ describe("loop.conversation", function() {
|
||||
setLoopCharPref: sinon.stub(),
|
||||
getLoopCharPref: sinon.stub().returns("http://fakeurl"),
|
||||
getLoopBoolPref: sinon.stub(),
|
||||
getCallData: sinon.stub(),
|
||||
releaseCallData: sinon.stub(),
|
||||
calls: {
|
||||
clearCallInProgress: sinon.stub()
|
||||
},
|
||||
startAlerting: sinon.stub(),
|
||||
stopAlerting: sinon.stub(),
|
||||
ensureRegistered: sinon.stub(),
|
||||
@@ -185,6 +186,13 @@ describe("loop.conversation", function() {
|
||||
});
|
||||
|
||||
it("should display the IncomingConversationView for incoming calls", function() {
|
||||
sandbox.stub(conversation, "setIncomingSessionData");
|
||||
sandbox.stub(loop, "CallConnectionWebSocket").returns({
|
||||
promiseConnect: function() {
|
||||
return new Promise(function() {});
|
||||
},
|
||||
on: sandbox.spy()
|
||||
});
|
||||
conversationAppStore.setStoreState({windowType: "incoming"});
|
||||
|
||||
ccView = mountTestComponent();
|
||||
@@ -213,14 +221,15 @@ describe("loop.conversation", function() {
|
||||
});
|
||||
|
||||
describe("IncomingConversationView", function() {
|
||||
var conversation, client, icView, oldTitle;
|
||||
var conversationAppStore, conversation, client, icView, oldTitle;
|
||||
|
||||
function mountTestComponent() {
|
||||
return TestUtils.renderIntoDocument(
|
||||
loop.conversation.IncomingConversationView({
|
||||
client: client,
|
||||
conversation: conversation,
|
||||
sdk: {}
|
||||
sdk: {},
|
||||
conversationAppStore: conversationAppStore
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -231,6 +240,11 @@ describe("loop.conversation", function() {
|
||||
sdk: {}
|
||||
});
|
||||
conversation.set({windowId: 42});
|
||||
var dispatcher = new loop.Dispatcher();
|
||||
conversationAppStore = new loop.store.ConversationAppStore({
|
||||
dispatcher: dispatcher,
|
||||
mozLoop: navigator.mozLoop
|
||||
});
|
||||
sandbox.stub(conversation, "setOutgoingSessionData");
|
||||
});
|
||||
|
||||
@@ -241,13 +255,13 @@ describe("loop.conversation", function() {
|
||||
|
||||
describe("start", function() {
|
||||
it("should set the title to incoming_call_title2", function() {
|
||||
navigator.mozLoop.getCallData = function() {
|
||||
return {
|
||||
conversationAppStore.setStoreState({
|
||||
windowData: {
|
||||
progressURL: "fake",
|
||||
websocketToken: "fake",
|
||||
callId: 42
|
||||
};
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
icView = mountTestComponent();
|
||||
|
||||
@@ -256,7 +270,8 @@ describe("loop.conversation", function() {
|
||||
});
|
||||
|
||||
describe("componentDidMount", function() {
|
||||
var fakeSessionData;
|
||||
var fakeSessionData, promise, resolveWebSocketConnect;
|
||||
var rejectWebSocketConnect;
|
||||
|
||||
beforeEach(function() {
|
||||
fakeSessionData = {
|
||||
@@ -269,7 +284,10 @@ describe("loop.conversation", function() {
|
||||
websocketToken: "7b"
|
||||
};
|
||||
|
||||
navigator.mozLoop.getCallData.returns(fakeSessionData);
|
||||
conversationAppStore.setStoreState({
|
||||
windowData: fakeSessionData
|
||||
});
|
||||
|
||||
stubComponent(loop.conversation, "IncomingCallView");
|
||||
stubComponent(sharedView, "ConversationView");
|
||||
});
|
||||
@@ -280,179 +298,167 @@ describe("loop.conversation", function() {
|
||||
sinon.assert.calledOnce(navigator.mozLoop.startAlerting);
|
||||
});
|
||||
|
||||
it("should call getCallData on navigator.mozLoop", function() {
|
||||
icView = mountTestComponent();
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.getCallData);
|
||||
sinon.assert.calledWith(navigator.mozLoop.getCallData, 42);
|
||||
});
|
||||
|
||||
describe("getCallData successful", function() {
|
||||
var promise, resolveWebSocketConnect,
|
||||
rejectWebSocketConnect;
|
||||
|
||||
describe("Session Data setup", function() {
|
||||
beforeEach(function() {
|
||||
sandbox.stub(loop, "CallConnectionWebSocket").returns({
|
||||
promiseConnect: function () {
|
||||
promise = new Promise(function(resolve, reject) {
|
||||
resolveWebSocketConnect = resolve;
|
||||
rejectWebSocketConnect = reject;
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
on: sinon.stub()
|
||||
});
|
||||
});
|
||||
|
||||
it("should store the session data", function() {
|
||||
sandbox.stub(conversation, "setIncomingSessionData");
|
||||
|
||||
icView = mountTestComponent();
|
||||
|
||||
sinon.assert.calledOnce(conversation.setIncomingSessionData);
|
||||
sinon.assert.calledWithExactly(conversation.setIncomingSessionData,
|
||||
fakeSessionData);
|
||||
});
|
||||
|
||||
it("should setup the websocket connection", function() {
|
||||
icView = mountTestComponent();
|
||||
|
||||
sinon.assert.calledOnce(loop.CallConnectionWebSocket);
|
||||
sinon.assert.calledWithExactly(loop.CallConnectionWebSocket, {
|
||||
callId: "Hello",
|
||||
url: "http://progress.example.com",
|
||||
websocketToken: "7b"
|
||||
});
|
||||
describe("Session Data setup", function() {
|
||||
beforeEach(function() {
|
||||
sandbox.stub(loop, "CallConnectionWebSocket").returns({
|
||||
promiseConnect: function () {
|
||||
promise = new Promise(function(resolve, reject) {
|
||||
resolveWebSocketConnect = resolve;
|
||||
rejectWebSocketConnect = reject;
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
on: sinon.stub()
|
||||
});
|
||||
});
|
||||
|
||||
describe("WebSocket Handling", function() {
|
||||
beforeEach(function() {
|
||||
promise = new Promise(function(resolve, reject) {
|
||||
resolveWebSocketConnect = resolve;
|
||||
rejectWebSocketConnect = reject;
|
||||
});
|
||||
it("should store the session data", function() {
|
||||
sandbox.stub(conversation, "setIncomingSessionData");
|
||||
|
||||
sandbox.stub(loop.CallConnectionWebSocket.prototype, "promiseConnect").returns(promise);
|
||||
icView = mountTestComponent();
|
||||
|
||||
sinon.assert.calledOnce(conversation.setIncomingSessionData);
|
||||
sinon.assert.calledWithExactly(conversation.setIncomingSessionData,
|
||||
fakeSessionData);
|
||||
});
|
||||
|
||||
it("should setup the websocket connection", function() {
|
||||
icView = mountTestComponent();
|
||||
|
||||
sinon.assert.calledOnce(loop.CallConnectionWebSocket);
|
||||
sinon.assert.calledWithExactly(loop.CallConnectionWebSocket, {
|
||||
callId: "Hello",
|
||||
url: "http://progress.example.com",
|
||||
websocketToken: "7b"
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("WebSocket Handling", function() {
|
||||
beforeEach(function() {
|
||||
promise = new Promise(function(resolve, reject) {
|
||||
resolveWebSocketConnect = resolve;
|
||||
rejectWebSocketConnect = reject;
|
||||
});
|
||||
|
||||
it("should set the state to incoming on success", function(done) {
|
||||
sandbox.stub(loop.CallConnectionWebSocket.prototype, "promiseConnect").returns(promise);
|
||||
});
|
||||
|
||||
it("should set the state to incoming on success", function(done) {
|
||||
icView = mountTestComponent();
|
||||
resolveWebSocketConnect("incoming");
|
||||
|
||||
promise.then(function () {
|
||||
expect(icView.state.callStatus).eql("incoming");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should set the state to close on success if the progress " +
|
||||
"state is terminated", function(done) {
|
||||
icView = mountTestComponent();
|
||||
resolveWebSocketConnect("incoming");
|
||||
resolveWebSocketConnect("terminated");
|
||||
|
||||
promise.then(function () {
|
||||
expect(icView.state.callStatus).eql("incoming");
|
||||
expect(icView.state.callStatus).eql("close");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should set the state to close on success if the progress " +
|
||||
"state is terminated", function(done) {
|
||||
icView = mountTestComponent();
|
||||
resolveWebSocketConnect("terminated");
|
||||
// XXX implement me as part of bug 1047410
|
||||
// see https://hg.mozilla.org/integration/fx-team/rev/5d2c69ebb321#l18.259
|
||||
it.skip("should should switch view state to failed", function(done) {
|
||||
icView = mountTestComponent();
|
||||
rejectWebSocketConnect();
|
||||
|
||||
promise.then(function () {
|
||||
expect(icView.state.callStatus).eql("close");
|
||||
promise.then(function() {}, function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("WebSocket Events", function() {
|
||||
describe("Call cancelled or timed out before acceptance", function() {
|
||||
beforeEach(function() {
|
||||
// Mounting the test component automatically calls the required
|
||||
// setup functions
|
||||
icView = mountTestComponent();
|
||||
promise = new Promise(function(resolve, reject) {
|
||||
resolve();
|
||||
});
|
||||
|
||||
sandbox.stub(loop.CallConnectionWebSocket.prototype, "promiseConnect").returns(promise);
|
||||
sandbox.stub(loop.CallConnectionWebSocket.prototype, "close");
|
||||
sandbox.stub(window, "close");
|
||||
});
|
||||
|
||||
describe("progress - terminated (previousState = alerting)", function() {
|
||||
it("should stop alerting", function(done) {
|
||||
promise.then(function() {
|
||||
icView._websocket.trigger("progress", {
|
||||
state: "terminated",
|
||||
reason: "timeout"
|
||||
}, "alerting");
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.stopAlerting);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
// XXX implement me as part of bug 1047410
|
||||
// see https://hg.mozilla.org/integration/fx-team/rev/5d2c69ebb321#l18.259
|
||||
it.skip("should should switch view state to failed", function(done) {
|
||||
icView = mountTestComponent();
|
||||
rejectWebSocketConnect();
|
||||
it("should close the websocket", function(done) {
|
||||
promise.then(function() {
|
||||
icView._websocket.trigger("progress", {
|
||||
state: "terminated",
|
||||
reason: "closed"
|
||||
}, "alerting");
|
||||
|
||||
promise.then(function() {}, function() {
|
||||
done();
|
||||
sinon.assert.calledOnce(icView._websocket.close);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should close the window", function(done) {
|
||||
promise.then(function() {
|
||||
icView._websocket.trigger("progress", {
|
||||
state: "terminated",
|
||||
reason: "answered-elsewhere"
|
||||
}, "alerting");
|
||||
|
||||
sandbox.clock.tick(1);
|
||||
|
||||
sinon.assert.calledOnce(window.close);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("WebSocket Events", function() {
|
||||
describe("Call cancelled or timed out before acceptance", function() {
|
||||
beforeEach(function() {
|
||||
// Mounting the test component automatically calls the required
|
||||
// setup functions
|
||||
icView = mountTestComponent();
|
||||
promise = new Promise(function(resolve, reject) {
|
||||
resolve();
|
||||
describe("progress - terminated (previousState not init" +
|
||||
" nor alerting)",
|
||||
function() {
|
||||
it("should set the state to end", function(done) {
|
||||
promise.then(function() {
|
||||
icView._websocket.trigger("progress", {
|
||||
state: "terminated",
|
||||
reason: "media-fail"
|
||||
}, "connecting");
|
||||
|
||||
expect(icView.state.callStatus).eql("end");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
sandbox.stub(loop.CallConnectionWebSocket.prototype, "promiseConnect").returns(promise);
|
||||
sandbox.stub(loop.CallConnectionWebSocket.prototype, "close");
|
||||
sandbox.stub(window, "close");
|
||||
});
|
||||
|
||||
describe("progress - terminated (previousState = alerting)", function() {
|
||||
it("should stop alerting", function(done) {
|
||||
promise.then(function() {
|
||||
icView._websocket.trigger("progress", {
|
||||
state: "terminated",
|
||||
reason: "timeout"
|
||||
}, "alerting");
|
||||
reason: "media-fail"
|
||||
}, "connecting");
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.stopAlerting);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should close the websocket", function(done) {
|
||||
promise.then(function() {
|
||||
icView._websocket.trigger("progress", {
|
||||
state: "terminated",
|
||||
reason: "closed"
|
||||
}, "alerting");
|
||||
|
||||
sinon.assert.calledOnce(icView._websocket.close);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should close the window", function(done) {
|
||||
promise.then(function() {
|
||||
icView._websocket.trigger("progress", {
|
||||
state: "terminated",
|
||||
reason: "answered-elsewhere"
|
||||
}, "alerting");
|
||||
|
||||
sandbox.clock.tick(1);
|
||||
|
||||
sinon.assert.calledOnce(window.close);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("progress - terminated (previousState not init" +
|
||||
" nor alerting)",
|
||||
function() {
|
||||
it("should set the state to end", function(done) {
|
||||
promise.then(function() {
|
||||
icView._websocket.trigger("progress", {
|
||||
state: "terminated",
|
||||
reason: "media-fail"
|
||||
}, "connecting");
|
||||
|
||||
expect(icView.state.callStatus).eql("end");
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should stop alerting", function(done) {
|
||||
promise.then(function() {
|
||||
icView._websocket.trigger("progress", {
|
||||
state: "terminated",
|
||||
reason: "media-fail"
|
||||
}, "connecting");
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.stopAlerting);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -526,8 +532,9 @@ describe("loop.conversation", function() {
|
||||
it("should release callData", function() {
|
||||
icView.decline();
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.releaseCallData);
|
||||
sinon.assert.calledWithExactly(navigator.mozLoop.releaseCallData, "8699");
|
||||
sinon.assert.calledOnce(navigator.mozLoop.calls.clearCallInProgress);
|
||||
sinon.assert.calledWithExactly(
|
||||
navigator.mozLoop.calls.clearCallInProgress, "8699");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -598,13 +605,27 @@ describe("loop.conversation", function() {
|
||||
var fakeSessionData;
|
||||
|
||||
beforeEach(function() {
|
||||
icView = mountTestComponent();
|
||||
|
||||
fakeSessionData = {
|
||||
sessionId: "sessionId",
|
||||
sessionToken: "sessionToken",
|
||||
apiKey: "apiKey"
|
||||
};
|
||||
|
||||
conversationAppStore.setStoreState({
|
||||
windowData: fakeSessionData
|
||||
});
|
||||
|
||||
sandbox.stub(conversation, "setIncomingSessionData");
|
||||
sandbox.stub(loop, "CallConnectionWebSocket").returns({
|
||||
promiseConnect: function() {
|
||||
return new Promise(function() {});
|
||||
},
|
||||
on: sandbox.spy()
|
||||
});
|
||||
|
||||
icView = mountTestComponent();
|
||||
|
||||
conversation.set("loopToken", "fakeToken");
|
||||
navigator.mozLoop.getLoopCharPref.returns("http://fake");
|
||||
stubComponent(sharedView, "ConversationView");
|
||||
|
||||
@@ -38,7 +38,10 @@ describe("loop.store.ConversationStore", function () {
|
||||
|
||||
navigator.mozLoop = {
|
||||
getLoopBoolPref: sandbox.stub(),
|
||||
releaseCallData: sandbox.stub()
|
||||
calls: {
|
||||
setCallInProgress: sandbox.stub(),
|
||||
clearCallInProgress: sandbox.stub()
|
||||
}
|
||||
};
|
||||
|
||||
dispatcher = new loop.Dispatcher();
|
||||
@@ -156,8 +159,9 @@ describe("loop.store.ConversationStore", function () {
|
||||
dispatcher.dispatch(
|
||||
new sharedActions.ConnectionFailure({reason: "fake"}));
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.releaseCallData);
|
||||
sinon.assert.calledWithExactly(navigator.mozLoop.releaseCallData, "42");
|
||||
sinon.assert.calledOnce(navigator.mozLoop.calls.clearCallInProgress);
|
||||
sinon.assert.calledWithExactly(
|
||||
navigator.mozLoop.calls.clearCallInProgress, "42");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -227,12 +231,10 @@ describe("loop.store.ConversationStore", function () {
|
||||
beforeEach(function() {
|
||||
store.set({callState: CALL_STATES.INIT});
|
||||
fakeSetupWindowData = {
|
||||
windowData: {
|
||||
type: "outgoing",
|
||||
contact: contact,
|
||||
windowId: "123456",
|
||||
callType: sharedUtils.CALL_TYPES.AUDIO_VIDEO
|
||||
}
|
||||
windowId: "123456",
|
||||
type: "outgoing",
|
||||
contact: contact,
|
||||
callType: sharedUtils.CALL_TYPES.AUDIO_VIDEO
|
||||
};
|
||||
});
|
||||
|
||||
@@ -270,7 +272,7 @@ describe("loop.store.ConversationStore", function () {
|
||||
});
|
||||
|
||||
it("should include all email addresses in the call data", function() {
|
||||
fakeSetupWindowData.windowData.contact = {
|
||||
fakeSetupWindowData.contact = {
|
||||
name: [ "Mr Smith" ],
|
||||
email: [{
|
||||
type: "home",
|
||||
@@ -293,7 +295,7 @@ describe("loop.store.ConversationStore", function () {
|
||||
});
|
||||
|
||||
it("should include trim phone numbers for the call data", function() {
|
||||
fakeSetupWindowData.windowData.contact = {
|
||||
fakeSetupWindowData.contact = {
|
||||
name: [ "Mr Smith" ],
|
||||
tel: [{
|
||||
type: "home",
|
||||
@@ -311,7 +313,7 @@ describe("loop.store.ConversationStore", function () {
|
||||
});
|
||||
|
||||
it("should include all email and telephone values in the call data", function() {
|
||||
fakeSetupWindowData.windowData.contact = {
|
||||
fakeSetupWindowData.contact = {
|
||||
name: [ "Mr Smith" ],
|
||||
email: [{
|
||||
type: "home",
|
||||
@@ -504,8 +506,9 @@ describe("loop.store.ConversationStore", function () {
|
||||
it("should release mozLoop callsData", function() {
|
||||
dispatcher.dispatch(new sharedActions.HangupCall());
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.releaseCallData);
|
||||
sinon.assert.calledWithExactly(navigator.mozLoop.releaseCallData, "42");
|
||||
sinon.assert.calledOnce(navigator.mozLoop.calls.clearCallInProgress);
|
||||
sinon.assert.calledWithExactly(
|
||||
navigator.mozLoop.calls.clearCallInProgress, "42");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -544,8 +547,9 @@ describe("loop.store.ConversationStore", function () {
|
||||
it("should release mozLoop callsData", function() {
|
||||
dispatcher.dispatch(new sharedActions.PeerHungupCall());
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.releaseCallData);
|
||||
sinon.assert.calledWithExactly(navigator.mozLoop.releaseCallData, "42");
|
||||
sinon.assert.calledOnce(navigator.mozLoop.calls.clearCallInProgress);
|
||||
sinon.assert.calledWithExactly(
|
||||
navigator.mozLoop.calls.clearCallInProgress, "42");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -592,8 +596,9 @@ describe("loop.store.ConversationStore", function () {
|
||||
it("should release mozLoop callsData", function() {
|
||||
dispatcher.dispatch(new sharedActions.CancelCall());
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.releaseCallData);
|
||||
sinon.assert.calledWithExactly(navigator.mozLoop.releaseCallData, "42");
|
||||
sinon.assert.calledOnce(navigator.mozLoop.calls.clearCallInProgress);
|
||||
sinon.assert.calledWithExactly(
|
||||
navigator.mozLoop.calls.clearCallInProgress, "42");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -59,10 +59,9 @@ describe("loop.store.LocalRoomStore", function () {
|
||||
});
|
||||
|
||||
dispatcher.dispatch(new sharedActions.SetupWindowData({
|
||||
windowData: {
|
||||
type: "room",
|
||||
localRoomId: fakeRoomId
|
||||
}
|
||||
windowId: "42",
|
||||
type: "room",
|
||||
localRoomId: fakeRoomId
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -76,10 +75,9 @@ describe("loop.store.LocalRoomStore", function () {
|
||||
});
|
||||
|
||||
dispatcher.dispatch(new sharedActions.SetupWindowData({
|
||||
windowData: {
|
||||
type: "room",
|
||||
localRoomId: fakeRoomId
|
||||
}
|
||||
windowId: "42",
|
||||
type: "room",
|
||||
localRoomId: fakeRoomId
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -93,10 +91,9 @@ describe("loop.store.LocalRoomStore", function () {
|
||||
});
|
||||
|
||||
dispatcher.dispatch(new sharedActions.SetupWindowData({
|
||||
windowData: {
|
||||
type: "room",
|
||||
localRoomId: fakeRoomId
|
||||
}
|
||||
windowId: "42",
|
||||
type: "room",
|
||||
localRoomId: fakeRoomId
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -116,10 +113,9 @@ describe("loop.store.LocalRoomStore", function () {
|
||||
});
|
||||
|
||||
dispatcher.dispatch(new sharedActions.SetupWindowData({
|
||||
windowData: {
|
||||
type: "room",
|
||||
localRoomId: fakeRoomId
|
||||
}
|
||||
windowId: "42",
|
||||
type: "room",
|
||||
localRoomId: fakeRoomId
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
@@ -26,8 +26,10 @@ add_test(function test_busy_2guest_calls() {
|
||||
|
||||
MozLoopService.promiseRegisteredWithServers().then(() => {
|
||||
let opened = 0;
|
||||
Chat.open = function() {
|
||||
let windowId;
|
||||
Chat.open = function(contentWindow, origin, title, url) {
|
||||
opened++;
|
||||
windowId = url.match(/about:loopconversation\#(\d+)$/)[1];
|
||||
};
|
||||
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsGuest);
|
||||
@@ -35,7 +37,7 @@ add_test(function test_busy_2guest_calls() {
|
||||
waitForCondition(() => {return actionReceived && opened > 0}).then(() => {
|
||||
do_check_true(opened === 1, "should open only one chat window");
|
||||
do_check_true(actionReceived, "should respond with busy/reject to second call");
|
||||
LoopCalls.releaseCallData(firstCallId);
|
||||
LoopCalls.clearCallInProgress(windowId);
|
||||
run_next_test();
|
||||
}, () => {
|
||||
do_throw("should have opened a chat window for first call and rejected second call");
|
||||
@@ -49,8 +51,10 @@ add_test(function test_busy_1fxa_1guest_calls() {
|
||||
|
||||
MozLoopService.promiseRegisteredWithServers().then(() => {
|
||||
let opened = 0;
|
||||
Chat.open = function() {
|
||||
let windowId;
|
||||
Chat.open = function(contentWindow, origin, title, url) {
|
||||
opened++;
|
||||
windowId = url.match(/about:loopconversation\#(\d+)$/)[1];
|
||||
};
|
||||
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsFxA);
|
||||
@@ -59,7 +63,7 @@ add_test(function test_busy_1fxa_1guest_calls() {
|
||||
waitForCondition(() => {return actionReceived && opened > 0}).then(() => {
|
||||
do_check_true(opened === 1, "should open only one chat window");
|
||||
do_check_true(actionReceived, "should respond with busy/reject to second call");
|
||||
LoopCalls.releaseCallData(firstCallId);
|
||||
LoopCalls.clearCallInProgress(windowId);
|
||||
run_next_test();
|
||||
}, () => {
|
||||
do_throw("should have opened a chat window for first call and rejected second call");
|
||||
@@ -73,8 +77,10 @@ add_test(function test_busy_2fxa_calls() {
|
||||
|
||||
MozLoopService.promiseRegisteredWithServers().then(() => {
|
||||
let opened = 0;
|
||||
Chat.open = function() {
|
||||
let windowId;
|
||||
Chat.open = function(contentWindow, origin, title, url) {
|
||||
opened++;
|
||||
windowId = url.match(/about:loopconversation\#(\d+)$/)[1];
|
||||
};
|
||||
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsFxA);
|
||||
@@ -82,7 +88,7 @@ add_test(function test_busy_2fxa_calls() {
|
||||
waitForCondition(() => {return actionReceived && opened > 0}).then(() => {
|
||||
do_check_true(opened === 1, "should open only one chat window");
|
||||
do_check_true(actionReceived, "should respond with busy/reject to second call");
|
||||
LoopCalls.releaseCallData(firstCallId);
|
||||
LoopCalls.clearCallInProgress(windowId);
|
||||
run_next_test();
|
||||
}, () => {
|
||||
do_throw("should have opened a chat window for first call and rejected second call");
|
||||
@@ -96,8 +102,10 @@ add_test(function test_busy_1guest_1fxa_calls() {
|
||||
|
||||
MozLoopService.promiseRegisteredWithServers().then(() => {
|
||||
let opened = 0;
|
||||
Chat.open = function() {
|
||||
let windowId;
|
||||
Chat.open = function(contentWindow, origin, title, url) {
|
||||
opened++;
|
||||
windowId = url.match(/about:loopconversation\#(\d+)$/)[1];
|
||||
};
|
||||
|
||||
mockPushHandler.notify(1, MozLoopService.channelIDs.callsGuest);
|
||||
@@ -106,7 +114,7 @@ add_test(function test_busy_1guest_1fxa_calls() {
|
||||
waitForCondition(() => {return actionReceived && opened > 0}).then(() => {
|
||||
do_check_true(opened === 1, "should open only one chat window");
|
||||
do_check_true(actionReceived, "should respond with busy/reject to second call");
|
||||
LoopCalls.releaseCallData(firstCallId);
|
||||
LoopCalls.clearCallInProgress(windowId);
|
||||
run_next_test();
|
||||
}, () => {
|
||||
do_throw("should have opened a chat window for first call and rejected second call");
|
||||
|
||||
@@ -26,11 +26,11 @@ add_task(function test_startDirectCall_opens_window() {
|
||||
do_check_true(!!openedUrl, "should open a chat window");
|
||||
|
||||
// Stop the busy kicking in for following tests.
|
||||
let callId = openedUrl.match(/about:loopconversation\#(\d+)$/)[1];
|
||||
LoopCalls.releaseCallData(callId);
|
||||
let windowId = openedUrl.match(/about:loopconversation\#(\d+)$/)[1];
|
||||
LoopCalls.clearCallInProgress(windowId);
|
||||
});
|
||||
|
||||
add_task(function test_startDirectCall_getCallData() {
|
||||
add_task(function test_startDirectCall_getConversationWindowData() {
|
||||
let openedUrl;
|
||||
Chat.open = function(contentWindow, origin, title, url) {
|
||||
openedUrl = url;
|
||||
@@ -38,15 +38,15 @@ add_task(function test_startDirectCall_getCallData() {
|
||||
|
||||
LoopCalls.startDirectCall(contact, "audio-video");
|
||||
|
||||
let callId = openedUrl.match(/about:loopconversation\#(\d+)$/)[1];
|
||||
let windowId = openedUrl.match(/about:loopconversation\#(\d+)$/)[1];
|
||||
|
||||
let callData = LoopCalls.getCallData(callId);
|
||||
let callData = MozLoopService.getConversationWindowData(windowId);
|
||||
|
||||
do_check_eq(callData.callType, "audio-video", "should have the correct call type");
|
||||
do_check_eq(callData.contact, contact, "should have the contact details");
|
||||
|
||||
// Stop the busy kicking in for following tests.
|
||||
LoopCalls.releaseCallData(callId);
|
||||
LoopCalls.clearCallInProgress(windowId);
|
||||
});
|
||||
|
||||
function run_test() {
|
||||
|
||||
Reference in New Issue
Block a user