Bug 1200201 - Remove the code for redirecting to the FxOS client from Loop standalone. r=dmose

This commit is contained in:
Mark Banner 2015-09-05 11:01:44 +01:00
Родитель a73039099d
Коммит 19909b32e5
28 изменённых файлов: 45 добавлений и 1095 удалений

Просмотреть файл

@ -24,7 +24,6 @@ content/js/feedbackViews.js
content/shared/js/textChatView.js
content/shared/js/linkifiedTextView.js
content/shared/js/views.js
standalone/content/js/fxOSMarketplace.js
standalone/content/js/standaloneRoomViews.js
standalone/content/js/webapp.js
ui/ui-showcase.js

Просмотреть файл

@ -32,8 +32,6 @@
<script type="text/javascript" src="loop/shared/js/otSdkDriver.js"></script>
<script type="text/javascript" src="loop/shared/js/store.js"></script>
<script type="text/javascript" src="loop/shared/js/conversationStore.js"></script>
<script type="text/javascript" src="loop/shared/js/roomStates.js"></script>
<script type="text/javascript" src="loop/shared/js/fxOSActiveRoomStore.js"></script>
<script type="text/javascript" src="loop/shared/js/activeRoomStore.js"></script>
<script type="text/javascript" src="loop/shared/js/views.js"></script>
<script type="text/javascript" src="loop/js/feedbackViews.js"></script>

Просмотреть файл

@ -27,8 +27,6 @@
<script type="text/javascript" src="loop/shared/js/actions.js"></script>
<script type="text/javascript" src="loop/shared/js/dispatcher.js"></script>
<script type="text/javascript" src="loop/shared/js/store.js"></script>
<script type="text/javascript" src="loop/shared/js/roomStates.js"></script>
<script type="text/javascript" src="loop/shared/js/fxOSActiveRoomStore.js"></script>
<script type="text/javascript" src="loop/shared/js/activeRoomStore.js"></script>
<script type="text/javascript;version=1.8" src="loop/js/contacts.js"></script>
<script type="text/javascript" src="loop/js/roomStore.js"></script>

Просмотреть файл

@ -5,6 +5,33 @@
var loop = loop || {};
loop.store = loop.store || {};
loop.store.ROOM_STATES = {
// The initial state of the room
INIT: "room-init",
// The store is gathering the room data
GATHER: "room-gather",
// The store has got the room data
READY: "room-ready",
// Obtaining media from the user
MEDIA_WAIT: "room-media-wait",
// Joining the room is taking place
JOINING: "room-joining",
// The room is known to be joined on the loop-server
JOINED: "room-joined",
// The room is connected to the sdk server.
SESSION_CONNECTED: "room-session-connected",
// There are participants in the room.
HAS_PARTICIPANTS: "room-has-participants",
// There was an issue with the room
FAILED: "room-failed",
// The room is full
FULL: "room-full",
// The room conversation has ended, displays the feedback view.
ENDED: "room-ended",
// The window is closing
CLOSING: "room-closing"
};
loop.store.ActiveRoomStore = (function() {
"use strict";

Просмотреть файл

@ -1,164 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
var loop = loop || {};
loop.store = loop.store || {};
loop.store.FxOSActiveRoomStore = (function() {
"use strict";
var sharedActions = loop.shared.actions;
var ROOM_STATES = loop.store.ROOM_STATES;
var FxOSActiveRoomStore = loop.store.createStore({
actions: [
"fetchServerData"
],
initialize: function(options) {
if (!options.mozLoop) {
throw new Error("Missing option mozLoop");
}
this._mozLoop = options.mozLoop;
},
/**
* Returns initial state data for this active room.
*/
getInitialStoreState: function() {
return {
roomState: ROOM_STATES.INIT,
audioMuted: false,
videoMuted: false,
failureReason: undefined,
localVideoDimensions: {},
remoteVideoDimensions: {}
};
},
/**
* Registers the actions with the dispatcher that this store is interested
* in after the initial setup has been performed.
*/
_registerPostSetupActions: function() {
this.dispatcher.register(this, [
"joinRoom"
]);
},
/**
* Execute fetchServerData event action from the dispatcher. Although
* this is to fetch the server data - for rooms on the standalone client,
* we don't actually need to get any data. Therefore we just save the
* data that is given to us for when the user chooses to join the room.
*
* @param {sharedActions.FetchServerData} actionData
*/
fetchServerData: function(actionData) {
if (actionData.windowType !== "room") {
// Nothing for us to do here, leave it to other stores.
return;
}
this._registerPostSetupActions();
this.setStoreState({
roomToken: actionData.token,
roomState: ROOM_STATES.READY
});
},
/**
* Handles the action to join to a room.
*/
joinRoom: function() {
// Reset the failure reason if necessary.
if (this.getStoreState().failureReason) {
this.setStoreState({failureReason: undefined});
}
this._setupOutgoingRoom(true);
},
/**
* Sets up an outgoing room. It will try launching the activity to let the
* FirefoxOS loop app handle the call. If the activity fails:
* - if installApp is true, then it'll try to install the FirefoxOS loop
* app.
* - if installApp is false, then it'll just log and error and fail.
*
* @param {boolean} installApp
*/
_setupOutgoingRoom: function(installApp) {
var request = new MozActivity({
name: "room-call",
data: {
type: "loop/rToken",
token: this.getStoreState("roomToken")
}
});
request.onsuccess = function() {};
request.onerror = (function(event) {
if (!installApp) {
// This really should not happen ever.
console.error(
"Unexpected activity launch error after the app has been installed");
return;
}
if (event.target.error.name !== "NO_PROVIDER") {
console.error("Unexpected " + event.target.error.name);
return;
}
// We need to install the FxOS app.
this.setStoreState({
marketplaceSrc: loop.config.marketplaceUrl,
onMarketplaceMessage: this._onMarketplaceMessage.bind(this)
});
}).bind(this);
},
/**
* This method will handle events generated on the marketplace frame. It
* will launch the FirefoxOS loop app installation, and receive the result
* of the installation.
*
* @param {DOMEvent} event
*/
_onMarketplaceMessage: function(event) {
var message = event.data;
switch (message.name) {
case "loaded":
var marketplace = window.document.getElementById("marketplace");
// Once we have it loaded, we request the installation of the FxOS
// Loop client app. We will be receiving the result of this action
// via postMessage from the child iframe.
marketplace.contentWindow.postMessage({
"name": "install-package",
"data": {
"product": {
"name": loop.config.fxosApp.name,
"manifest_url": loop.config.fxosApp.manifestUrl,
"is_packaged": true
}
}
}, "*");
break;
case "install-package":
window.removeEventListener("message", this.onMarketplaceMessage);
if (message.error) {
console.error(message.error.error);
return;
}
// We installed the FxOS app, so we can continue with the call
// process.
this._setupOutgoingRoom(false);
break;
}
}
});
return FxOSActiveRoomStore;
})();

Просмотреть файл

@ -1,33 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
var loop = loop || {};
loop.store = loop.store || {};
loop.store.ROOM_STATES = {
// The initial state of the room
INIT: "room-init",
// The store is gathering the room data
GATHER: "room-gather",
// The store has got the room data
READY: "room-ready",
// Obtaining media from the user
MEDIA_WAIT: "room-media-wait",
// Joining the room is taking place
JOINING: "room-joining",
// The room is known to be joined on the loop-server
JOINED: "room-joined",
// The room is connected to the sdk server.
SESSION_CONNECTED: "room-session-connected",
// There are participants in the room.
HAS_PARTICIPANTS: "room-has-participants",
// There was an issue with the room
FAILED: "room-failed",
// The room is full
FULL: "room-full",
// The room conversation has ended, displays the feedback view.
ENDED: "room-ended",
// The window is closing
CLOSING: "room-closing"
};

Просмотреть файл

@ -145,15 +145,6 @@ var inChrome = typeof Components != "undefined" && "utils" in Components;
return platform.toLowerCase().indexOf("firefox") !== -1;
}
function isFirefoxOS(platform) {
// So far WebActivities are exposed only in FxOS, but they may be
// exposed in Firefox Desktop soon, so we check for its existence
// and also check if the UA belongs to a mobile platform.
// XXX WebActivities are also exposed in WebRT on Firefox for Android,
// so we need a better check. Bug 1065403.
return !!window.MozActivity && /mobi/i.test(platform);
}
function isOpera(platform) {
return platform.toLowerCase().indexOf("opera") > -1 ||
platform.toLowerCase().indexOf("opr") > -1;
@ -798,7 +789,6 @@ var inChrome = typeof Components != "undefined" && "utils" in Components;
getPlatform: getPlatform,
isChrome: isChrome,
isFirefox: isFirefox,
isFirefoxOS: isFirefoxOS,
isOpera: isOpera,
getUnsupportedPlatform: getUnsupportedPlatform,
hasAudioOrVideoDevices: hasAudioOrVideoDevices,

Просмотреть файл

@ -101,8 +101,6 @@ browser.jar:
content/browser/loop/shared/js/actions.js (content/shared/js/actions.js)
content/browser/loop/shared/js/conversationStore.js (content/shared/js/conversationStore.js)
content/browser/loop/shared/js/store.js (content/shared/js/store.js)
content/browser/loop/shared/js/roomStates.js (content/shared/js/roomStates.js)
content/browser/loop/shared/js/fxOSActiveRoomStore.js (content/shared/js/fxOSActiveRoomStore.js)
content/browser/loop/shared/js/activeRoomStore.js (content/shared/js/activeRoomStore.js)
content/browser/loop/shared/js/dispatcher.js (content/shared/js/dispatcher.js)
content/browser/loop/shared/js/models.js (content/shared/js/models.js)

Просмотреть файл

@ -68,10 +68,6 @@ config:
@echo "loop.config.privacyWebsiteUrl = '`echo $(LOOP_PRIVACY_WEBSITE_URL)`';" >> content/config.js
@echo "loop.config.legalWebsiteUrl = '`echo $(LOOP_LEGAL_WEBSITE_URL)`';" >> content/config.js
@echo "loop.config.learnMoreUrl = '`echo $(LOOP_PRODUCT_HOMEPAGE_URL)`';" >> content/config.js
@echo "loop.config.fxosApp = loop.config.fxosApp || {};" >> content/config.js
@echo "loop.config.fxosApp.name = 'Loop';" >> content/config.js
@echo "loop.config.fxosApp.rooms = true;" >> content/config.js
@echo "loop.config.fxosApp.manifestUrl = 'http://fake-market.herokuapp.com/apps/packagedApp/manifest.webapp';" >> content/config.js
@echo "loop.config.roomsSupportUrl = 'https://support.mozilla.org/kb/group-conversations-firefox-hello-webrtc';" >> content/config.js
@echo "loop.config.guestSupportUrl = 'https://support.mozilla.org/kb/respond-firefox-hello-invitation-guest-mode';" >> content/config.js
@echo "loop.config.generalSupportUrl = 'https://support.mozilla.org/kb/respond-firefox-hello-invitation-guest-mode';" >> content/config.js

Просмотреть файл

@ -147,8 +147,6 @@
<script type="text/javascript" src="shared/js/websocket.js"></script>
<script type="text/javascript" src="shared/js/otSdkDriver.js"></script>
<script type="text/javascript" src="shared/js/store.js"></script>
<script type="text/javascript" src="shared/js/roomStates.js"></script>
<script type="text/javascript" src="shared/js/fxOSActiveRoomStore.js"></script>
<script type="text/javascript" src="shared/js/activeRoomStore.js"></script>
<script type="text/javascript" src="shared/js/views.js"></script>
<script type="text/javascript" src="shared/js/textChatStore.js"></script>
@ -158,7 +156,6 @@
<script type="text/javascript" src="js/standaloneAppStore.js"></script>
<script type="text/javascript" src="js/standaloneClient.js"></script>
<script type="text/javascript" src="js/standaloneMozLoop.js"></script>
<script type="text/javascript" src="js/fxOSMarketplace.js"></script>
<script type="text/javascript" src="js/standaloneRoomViews.js"></script>
<script type="text/javascript" src="js/standaloneMetricsStore.js"></script>
<script type="text/javascript" src="js/webapp.js"></script>

Просмотреть файл

@ -1,44 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
var loop = loop || {};
loop.fxOSMarketplaceViews = (function() {
"use strict";
/**
* The Firefox Marketplace exposes a web page that contains a postMesssage
* based API that wraps a small set of functionality from the WebApps API
* that allow us to request the installation of apps given their manifest
* URL. We will be embedding the content of this web page within an hidden
* iframe in case that we need to request the installation of the FxOS Loop
* client.
*/
var FxOSHiddenMarketplaceView = React.createClass({displayName: "FxOSHiddenMarketplaceView",
propTypes: {
marketplaceSrc: React.PropTypes.string,
onMarketplaceMessage: React.PropTypes.func
},
render: function() {
return React.createElement("iframe", {hidden: true, id: "marketplace", src: this.props.marketplaceSrc});
},
componentDidUpdate: function() {
// This happens only once when we change the 'src' property of the iframe.
if (this.props.onMarketplaceMessage) {
// The reason for listening on the global window instead of on the
// iframe content window is because the Marketplace is doing a
// window.top.postMessage.
// XXX Bug 1097703: This should be changed to an action when the old
// style URLs go away.
window.addEventListener("message", this.props.onMarketplaceMessage);
}
}
});
return {
FxOSHiddenMarketplaceView: FxOSHiddenMarketplaceView
};
})();

Просмотреть файл

@ -1,44 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
var loop = loop || {};
loop.fxOSMarketplaceViews = (function() {
"use strict";
/**
* The Firefox Marketplace exposes a web page that contains a postMesssage
* based API that wraps a small set of functionality from the WebApps API
* that allow us to request the installation of apps given their manifest
* URL. We will be embedding the content of this web page within an hidden
* iframe in case that we need to request the installation of the FxOS Loop
* client.
*/
var FxOSHiddenMarketplaceView = React.createClass({
propTypes: {
marketplaceSrc: React.PropTypes.string,
onMarketplaceMessage: React.PropTypes.func
},
render: function() {
return <iframe hidden id="marketplace" src={this.props.marketplaceSrc} />;
},
componentDidUpdate: function() {
// This happens only once when we change the 'src' property of the iframe.
if (this.props.onMarketplaceMessage) {
// The reason for listening on the global window instead of on the
// iframe content window is because the Marketplace is doing a
// window.top.postMessage.
// XXX Bug 1097703: This should be changed to an action when the old
// style URLs go away.
window.addEventListener("message", this.props.onMarketplaceMessage);
}
}
});
return {
FxOSHiddenMarketplaceView: FxOSHiddenMarketplaceView
};
})();

Просмотреть файл

@ -82,10 +82,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
},
propTypes: {
activeRoomStore: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
]).isRequired,
activeRoomStore: React.PropTypes.instanceOf(loop.store.ActiveRoomStore).isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
failureReason: React.PropTypes.string,
isFirefox: React.PropTypes.bool.isRequired,
@ -355,10 +352,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
propTypes: {
// We pass conversationStore here rather than use the mixin, to allow
// easy configurability for the ui-showcase.
activeRoomStore: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
]).isRequired,
activeRoomStore: React.PropTypes.instanceOf(loop.store.ActiveRoomStore).isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
isFirefox: React.PropTypes.bool.isRequired,
// The poster URLs are for UI-showcase testing and development
@ -590,9 +584,6 @@ loop.standaloneRoomViews = (function(mozL10n) {
video: {enabled: !this.state.videoMuted,
visible: this._roomIsActive()}})
),
React.createElement(loop.fxOSMarketplaceViews.FxOSHiddenMarketplaceView, {
marketplaceSrc: this.state.marketplaceSrc,
onMarketplaceMessage: this.state.onMarketplaceMessage}),
React.createElement(StandaloneRoomFooter, {dispatcher: this.props.dispatcher})
)
);

Просмотреть файл

@ -82,10 +82,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
},
propTypes: {
activeRoomStore: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
]).isRequired,
activeRoomStore: React.PropTypes.instanceOf(loop.store.ActiveRoomStore).isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
failureReason: React.PropTypes.string,
isFirefox: React.PropTypes.bool.isRequired,
@ -355,10 +352,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
propTypes: {
// We pass conversationStore here rather than use the mixin, to allow
// easy configurability for the ui-showcase.
activeRoomStore: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
]).isRequired,
activeRoomStore: React.PropTypes.instanceOf(loop.store.ActiveRoomStore).isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
isFirefox: React.PropTypes.bool.isRequired,
// The poster URLs are for UI-showcase testing and development
@ -590,9 +584,6 @@ loop.standaloneRoomViews = (function(mozL10n) {
video={{enabled: !this.state.videoMuted,
visible: this._roomIsActive()}} />
</sharedViews.MediaLayoutView>
<loop.fxOSMarketplaceViews.FxOSHiddenMarketplaceView
marketplaceSrc={this.state.marketplaceSrc}
onMarketplaceMessage={this.state.onMarketplaceMessage} />
<StandaloneRoomFooter dispatcher={this.props.dispatcher} />
</div>
);

Просмотреть файл

@ -143,74 +143,6 @@ loop.webapp = (function(_, OT, mozL10n) {
}
});
var FxOSConversationModel = Backbone.Model.extend({
setupOutgoingCall: function(selectedCallType) {
if (selectedCallType) {
this.set("selectedCallType", selectedCallType);
}
// The FxOS Loop client exposes a "loop-call" activity. If we get the
// activity onerror callback it means that there is no "loop-call"
// activity handler available and so no FxOS Loop client installed.
var request = new MozActivity({
name: "loop-call",
data: {
type: "loop/token",
token: this.get("loopToken"),
callerId: this.get("callerId"),
video: this.get("selectedCallType") === "audio-video"
}
});
request.onsuccess = function() {};
request.onerror = (function(event) {
if (event.target.error.name !== "NO_PROVIDER") {
console.error("Unexpected " + event.target.error.name);
this.trigger("session:error", "fxos_app_needed", {
fxosAppName: loop.config.fxosApp.name
});
return;
}
this.trigger("fxos:app-needed");
}).bind(this);
},
onMarketplaceMessage: function(event) {
var message = event.data;
switch (message.name) {
case "loaded":
var marketplace = window.document.getElementById("marketplace");
// Once we have it loaded, we request the installation of the FxOS
// Loop client app. We will be receiving the result of this action
// via postMessage from the child iframe.
marketplace.contentWindow.postMessage({
"name": "install-package",
"data": {
"product": {
"name": loop.config.fxosApp.name,
"manifest_url": loop.config.fxosApp.manifestUrl,
"is_packaged": true
}
}
}, "*");
break;
case "install-package":
window.removeEventListener("message", this.onMarketplaceMessage);
if (message.error) {
console.error(message.error.error);
this.trigger("session:error", "fxos_app_needed", {
fxosAppName: loop.config.fxosApp.name
});
return;
}
// We installed the FxOS app \o/, so we can continue with the call
// process.
this.setupOutgoingCall();
break;
}
}
});
var ConversationHeader = React.createClass({displayName: "ConversationHeader",
propTypes: {
urlCreationDateString: React.PropTypes.string.isRequired
@ -447,10 +379,7 @@ loop.webapp = (function(_, OT, mozL10n) {
propTypes: {
callButtonLabel: React.PropTypes.string.isRequired,
client: React.PropTypes.object.isRequired,
conversation: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(sharedModels.ConversationModel),
React.PropTypes.instanceOf(FxOSConversationModel)
]).isRequired,
conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel).isRequired,
// XXX Check more tightly here when we start injecting window.loop.*
notifications: React.PropTypes.object.isRequired,
title: React.PropTypes.string.isRequired
@ -466,8 +395,6 @@ loop.webapp = (function(_, OT, mozL10n) {
componentDidMount: function() {
this.listenTo(this.props.conversation,
"session:error", this._onSessionError);
this.listenTo(this.props.conversation,
"fxos:app-needed", this._onFxOSAppNeeded);
this.props.client.requestCallUrlInfo(
this.props.conversation.get("loopToken"),
this._setConversationTimestamp);
@ -484,15 +411,6 @@ loop.webapp = (function(_, OT, mozL10n) {
console.error(errorL10n);
},
_onFxOSAppNeeded: function() {
this.setState({
marketplaceSrc: loop.config.marketplaceUrl,
onMarketplaceMessage: this.props.conversation.onMarketplaceMessage.bind(
this.props.conversation
)
});
},
/**
* Initiates the call.
* Takes in a call type parameter "audio" or "audio-video" and returns
@ -563,10 +481,6 @@ loop.webapp = (function(_, OT, mozL10n) {
dangerouslySetInnerHTML: {__html: tosHTML}})
),
React.createElement(loop.fxOSMarketplaceViews.FxOSHiddenMarketplaceView, {
marketplaceSrc: this.state.marketplaceSrc,
onMarketplaceMessage: this.state.onMarketplaceMessage}),
React.createElement(ConversationFooter, null)
)
);
@ -644,10 +558,7 @@ loop.webapp = (function(_, OT, mozL10n) {
var OutgoingConversationView = React.createClass({displayName: "OutgoingConversationView",
propTypes: {
client: React.PropTypes.instanceOf(loop.StandaloneClient).isRequired,
conversation: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(sharedModels.ConversationModel),
React.PropTypes.instanceOf(FxOSConversationModel)
]).isRequired,
conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel).isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
isFirefox: React.PropTypes.bool.isRequired,
notifications: React.PropTypes.instanceOf(sharedModels.NotificationCollection).isRequired,
@ -937,15 +848,9 @@ loop.webapp = (function(_, OT, mozL10n) {
Backbone.Events],
propTypes: {
activeRoomStore: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
]).isRequired,
activeRoomStore: React.PropTypes.instanceOf(loop.store.ActiveRoomStore).isRequired,
client: React.PropTypes.instanceOf(loop.StandaloneClient).isRequired,
conversation: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(sharedModels.ConversationModel),
React.PropTypes.instanceOf(FxOSConversationModel)
]).isRequired,
conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel).isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
notifications: React.PropTypes.instanceOf(sharedModels.NotificationCollection)
.isRequired,
@ -1035,25 +940,11 @@ loop.webapp = (function(_, OT, mozL10n) {
dispatcher: dispatcher,
sdk: OT
});
var conversation;
var activeRoomStore;
if (sharedUtils.isFirefoxOS(navigator.userAgent)) {
if (loop.config.fxosApp) {
conversation = new FxOSConversationModel();
if (loop.config.fxosApp.rooms) {
activeRoomStore = new loop.store.FxOSActiveRoomStore(dispatcher, {
mozLoop: standaloneMozLoop
});
}
}
}
conversation = conversation ||
new sharedModels.ConversationModel({}, {
var conversation = new sharedModels.ConversationModel({}, {
sdk: OT
});
activeRoomStore = activeRoomStore ||
new loop.store.ActiveRoomStore(dispatcher, {
var activeRoomStore = new loop.store.ActiveRoomStore(dispatcher, {
mozLoop: standaloneMozLoop,
sdkDriver: sdkDriver
});
@ -1119,7 +1010,6 @@ loop.webapp = (function(_, OT, mozL10n) {
UnsupportedDeviceView: UnsupportedDeviceView,
init: init,
PromoteFirefoxView: PromoteFirefoxView,
WebappRootView: WebappRootView,
FxOSConversationModel: FxOSConversationModel
WebappRootView: WebappRootView
};
})(_, window.OT, navigator.mozL10n);

Просмотреть файл

@ -143,74 +143,6 @@ loop.webapp = (function(_, OT, mozL10n) {
}
});
var FxOSConversationModel = Backbone.Model.extend({
setupOutgoingCall: function(selectedCallType) {
if (selectedCallType) {
this.set("selectedCallType", selectedCallType);
}
// The FxOS Loop client exposes a "loop-call" activity. If we get the
// activity onerror callback it means that there is no "loop-call"
// activity handler available and so no FxOS Loop client installed.
var request = new MozActivity({
name: "loop-call",
data: {
type: "loop/token",
token: this.get("loopToken"),
callerId: this.get("callerId"),
video: this.get("selectedCallType") === "audio-video"
}
});
request.onsuccess = function() {};
request.onerror = (function(event) {
if (event.target.error.name !== "NO_PROVIDER") {
console.error("Unexpected " + event.target.error.name);
this.trigger("session:error", "fxos_app_needed", {
fxosAppName: loop.config.fxosApp.name
});
return;
}
this.trigger("fxos:app-needed");
}).bind(this);
},
onMarketplaceMessage: function(event) {
var message = event.data;
switch (message.name) {
case "loaded":
var marketplace = window.document.getElementById("marketplace");
// Once we have it loaded, we request the installation of the FxOS
// Loop client app. We will be receiving the result of this action
// via postMessage from the child iframe.
marketplace.contentWindow.postMessage({
"name": "install-package",
"data": {
"product": {
"name": loop.config.fxosApp.name,
"manifest_url": loop.config.fxosApp.manifestUrl,
"is_packaged": true
}
}
}, "*");
break;
case "install-package":
window.removeEventListener("message", this.onMarketplaceMessage);
if (message.error) {
console.error(message.error.error);
this.trigger("session:error", "fxos_app_needed", {
fxosAppName: loop.config.fxosApp.name
});
return;
}
// We installed the FxOS app \o/, so we can continue with the call
// process.
this.setupOutgoingCall();
break;
}
}
});
var ConversationHeader = React.createClass({
propTypes: {
urlCreationDateString: React.PropTypes.string.isRequired
@ -447,10 +379,7 @@ loop.webapp = (function(_, OT, mozL10n) {
propTypes: {
callButtonLabel: React.PropTypes.string.isRequired,
client: React.PropTypes.object.isRequired,
conversation: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(sharedModels.ConversationModel),
React.PropTypes.instanceOf(FxOSConversationModel)
]).isRequired,
conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel).isRequired,
// XXX Check more tightly here when we start injecting window.loop.*
notifications: React.PropTypes.object.isRequired,
title: React.PropTypes.string.isRequired
@ -466,8 +395,6 @@ loop.webapp = (function(_, OT, mozL10n) {
componentDidMount: function() {
this.listenTo(this.props.conversation,
"session:error", this._onSessionError);
this.listenTo(this.props.conversation,
"fxos:app-needed", this._onFxOSAppNeeded);
this.props.client.requestCallUrlInfo(
this.props.conversation.get("loopToken"),
this._setConversationTimestamp);
@ -484,15 +411,6 @@ loop.webapp = (function(_, OT, mozL10n) {
console.error(errorL10n);
},
_onFxOSAppNeeded: function() {
this.setState({
marketplaceSrc: loop.config.marketplaceUrl,
onMarketplaceMessage: this.props.conversation.onMarketplaceMessage.bind(
this.props.conversation
)
});
},
/**
* Initiates the call.
* Takes in a call type parameter "audio" or "audio-video" and returns
@ -563,10 +481,6 @@ loop.webapp = (function(_, OT, mozL10n) {
dangerouslySetInnerHTML={{__html: tosHTML}}></p>
</div>
<loop.fxOSMarketplaceViews.FxOSHiddenMarketplaceView
marketplaceSrc={this.state.marketplaceSrc}
onMarketplaceMessage= {this.state.onMarketplaceMessage} />
<ConversationFooter />
</div>
);
@ -644,10 +558,7 @@ loop.webapp = (function(_, OT, mozL10n) {
var OutgoingConversationView = React.createClass({
propTypes: {
client: React.PropTypes.instanceOf(loop.StandaloneClient).isRequired,
conversation: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(sharedModels.ConversationModel),
React.PropTypes.instanceOf(FxOSConversationModel)
]).isRequired,
conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel).isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
isFirefox: React.PropTypes.bool.isRequired,
notifications: React.PropTypes.instanceOf(sharedModels.NotificationCollection).isRequired,
@ -937,15 +848,9 @@ loop.webapp = (function(_, OT, mozL10n) {
Backbone.Events],
propTypes: {
activeRoomStore: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(loop.store.ActiveRoomStore),
React.PropTypes.instanceOf(loop.store.FxOSActiveRoomStore)
]).isRequired,
activeRoomStore: React.PropTypes.instanceOf(loop.store.ActiveRoomStore).isRequired,
client: React.PropTypes.instanceOf(loop.StandaloneClient).isRequired,
conversation: React.PropTypes.oneOfType([
React.PropTypes.instanceOf(sharedModels.ConversationModel),
React.PropTypes.instanceOf(FxOSConversationModel)
]).isRequired,
conversation: React.PropTypes.instanceOf(sharedModels.ConversationModel).isRequired,
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
notifications: React.PropTypes.instanceOf(sharedModels.NotificationCollection)
.isRequired,
@ -1035,25 +940,11 @@ loop.webapp = (function(_, OT, mozL10n) {
dispatcher: dispatcher,
sdk: OT
});
var conversation;
var activeRoomStore;
if (sharedUtils.isFirefoxOS(navigator.userAgent)) {
if (loop.config.fxosApp) {
conversation = new FxOSConversationModel();
if (loop.config.fxosApp.rooms) {
activeRoomStore = new loop.store.FxOSActiveRoomStore(dispatcher, {
mozLoop: standaloneMozLoop
});
}
}
}
conversation = conversation ||
new sharedModels.ConversationModel({}, {
var conversation = new sharedModels.ConversationModel({}, {
sdk: OT
});
activeRoomStore = activeRoomStore ||
new loop.store.ActiveRoomStore(dispatcher, {
var activeRoomStore = new loop.store.ActiveRoomStore(dispatcher, {
mozLoop: standaloneMozLoop,
sdkDriver: sdkDriver
});
@ -1119,7 +1010,6 @@ loop.webapp = (function(_, OT, mozL10n) {
UnsupportedDeviceView: UnsupportedDeviceView,
init: init,
PromoteFirefoxView: PromoteFirefoxView,
WebappRootView: WebappRootView,
FxOSConversationModel: FxOSConversationModel
WebappRootView: WebappRootView
};
})(_, window.OT, navigator.mozL10n);

Просмотреть файл

@ -71,7 +71,6 @@ call_progress_getting_media_description={{clientShortname}} requires access to y
call_progress_getting_media_title=Waiting for media…
call_progress_connecting_description=Connecting…
call_progress_ringing_description=Ringing…
fxos_app_needed=Please install the {{fxosAppName}} app from the Firefox Marketplace.
## LOCALIZATION_NOTE (feedback_rejoin_button): Displayed on the feedback form after
## a signed-in to signed-in user call.

Просмотреть файл

@ -36,17 +36,10 @@ function getConfigFile(req, res) {
"loop.config.serverUrl = '" + loopServerUrl + "/v0';",
"loop.config.feedbackApiUrl = '" + feedbackApiUrl + "';",
"loop.config.feedbackProductName = '" + feedbackProductName + "';",
// XXX Update with the real marketplace url once the FxOS Loop app is
// uploaded to the marketplace bug 1053424
"loop.config.marketplaceUrl = 'http://fake-market.herokuapp.com/iframe-install.html'",
"loop.config.downloadFirefoxUrl = 'https://www.mozilla.org/firefox/new/?scene=2&utm_source=hello.firefox.com&utm_medium=referral&utm_campaign=non-webrtc-browser#download-fx';",
"loop.config.privacyWebsiteUrl = 'https://www.mozilla.org/privacy/firefox-hello/';",
"loop.config.learnMoreUrl = 'https://www.mozilla.org/hello/';",
"loop.config.legalWebsiteUrl = 'https://www.mozilla.org/about/legal/terms/firefox-hello/';",
"loop.config.fxosApp = loop.config.fxosApp || {};",
"loop.config.fxosApp.name = 'Loop';",
"loop.config.fxosApp.rooms = true;",
"loop.config.fxosApp.manifestUrl = 'http://fake-market.herokuapp.com/apps/packagedApp/manifest.webapp';",
"loop.config.roomsSupportUrl = 'https://support.mozilla.org/kb/group-conversations-firefox-hello-webrtc';",
"loop.config.tilesIframeUrl = 'https://tiles.cdn.mozilla.net/iframe.html';",
"loop.config.tilesSupportUrl = 'https://support.mozilla.org/tiles-firefox-hello';",

Просмотреть файл

@ -55,8 +55,6 @@
<script src="../../content/shared/js/otSdkDriver.js"></script>
<script src="../../content/shared/js/store.js"></script>
<script src="../../content/shared/js/conversationStore.js"></script>
<script src="../../content/shared/js/roomStates.js"></script>
<script src="../../content/shared/js/fxOSActiveRoomStore.js"></script>
<script src="../../content/shared/js/activeRoomStore.js"></script>
<script src="../../content/shared/js/views.js"></script>
<script src="../../content/shared/js/textChatStore.js"></script>

Просмотреть файл

@ -26,8 +26,6 @@ module.exports = function(config) {
"content/shared/js/dispatcher.js",
"content/shared/js/store.js",
"content/shared/js/conversationStore.js",
"content/shared/js/roomStates.js",
"content/shared/js/fxOSActiveRoomStore.js",
"content/shared/js/activeRoomStore.js",
"content/shared/js/views.js",
"content/shared/js/textChatStore.js",

Просмотреть файл

@ -27,8 +27,6 @@ module.exports = function(config) {
"content/shared/js/actions.js",
"content/shared/js/dispatcher.js",
"content/shared/js/otSdkDriver.js",
"content/shared/js/roomStates.js",
"content/shared/js/fxOSActiveRoomStore.js",
"content/shared/js/activeRoomStore.js",
"content/shared/js/conversationStore.js",
"content/shared/js/views.js",
@ -40,7 +38,6 @@ module.exports = function(config) {
"standalone/content/js/standaloneAppStore.js",
"standalone/content/js/standaloneClient.js",
"standalone/content/js/standaloneMozLoop.js",
"standalone/content/js/fxOSMarketplace.js",
"standalone/content/js/standaloneRoomViews.js",
"standalone/content/js/standaloneMetricsStore.js",
"standalone/content/js/webapp.js",

Просмотреть файл

@ -1,211 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
describe("loop.store.FxOSActiveRoomStore", function () {
"use strict";
var ROOM_STATES = loop.store.ROOM_STATES;
var expect = chai.expect;
var sharedActions = loop.shared.actions;
var sandbox;
var dispatcher;
var fakeMozLoop;
var store;
beforeEach(function() {
sandbox = sinon.sandbox.create();
sandbox.useFakeTimers();
dispatcher = new loop.Dispatcher();
sandbox.stub(dispatcher, "dispatch");
fakeMozLoop = {
setLoopPref: sandbox.stub(),
rooms: {
join: sinon.stub()
}
};
store = new loop.store.FxOSActiveRoomStore(dispatcher, {
mozLoop: fakeMozLoop
});
});
afterEach(function() {
sandbox.restore();
});
describe("#FxOSActiveRoomStore - constructor", function() {
it("should throw an error if mozLoop is missing", function() {
expect(function() {
new loop.store.FxOSActiveRoomStore(dispatcher);
}).to.Throw(/mozLoop/);
});
});
describe("#FxOSActiveRoomStore - fetchServerData", function() {
it("should save the token", function() {
store.fetchServerData(new sharedActions.FetchServerData({
windowType: "room",
token: "fakeToken"
}));
expect(store.getStoreState().roomToken).eql("fakeToken");
});
it("should set the state to `READY`", function() {
store.fetchServerData(new sharedActions.FetchServerData({
windowType: "room",
token: "fakeToken"
}));
expect(store.getStoreState().roomState).eql(ROOM_STATES.READY);
});
});
describe("#FxOSActiveRoomStore - setupOutgoingRoom", function() {
var realMozActivity;
var _activityDetail;
var _onerror;
function fireError(errorName) {
_onerror({
target: {
error: {
name: errorName
}
}
});
}
before(function() {
realMozActivity = window.MozActivity;
window.MozActivity = function(activityDetail) {
_activityDetail = activityDetail;
return {
set onerror(cbk) {
_onerror = cbk;
}
};
};
});
after(function() {
window.MozActivity = realMozActivity;
});
beforeEach(function() {
sandbox.stub(console, "error");
_activityDetail = undefined;
_onerror = undefined;
});
afterEach(function() {
sandbox.restore();
});
it("should reset failureReason", function() {
store.setStoreState({failureReason: "Test"});
store.joinRoom();
expect(store.getStoreState().failureReason).eql(undefined);
});
it("should create an activity", function() {
store.setStoreState({
roomToken: "fakeToken",
token: "fakeToken"
});
expect(_activityDetail).to.not.exist;
store.joinRoom();
expect(_activityDetail).to.exist;
expect(_activityDetail).eql({
name: "room-call",
data: {
type: "loop/rToken",
token: "fakeToken"
}
});
});
it("should change the store state when the activity fail with a " +
"NO_PROVIDER error", function() {
loop.config = {
marketplaceUrl: "http://market/"
};
store._setupOutgoingRoom(true);
fireError("NO_PROVIDER");
expect(store.getStoreState().marketplaceSrc).eql(
loop.config.marketplaceUrl
);
});
it("should log an error when the activity fail with a error different " +
"from NO_PROVIDER", function() {
loop.config = {
marketplaceUrl: "http://market/"
};
store._setupOutgoingRoom(true);
fireError("whatever");
sinon.assert.calledOnce(console.error);
sinon.assert.calledWith(console.error, "Unexpected whatever");
});
it("should log an error and exist if an activity error is received when " +
"the parameter is false ", function() {
loop.config = {
marketplaceUrl: "http://market/"
};
store._setupOutgoingRoom(false);
fireError("whatever");
sinon.assert.calledOnce(console.error);
sinon.assert.calledWith(console.error,
"Unexpected activity launch error after the app has been installed");
});
});
describe("#FxOSActiveRoomStore - _onMarketplaceMessage", function() {
var setupOutgoingRoom;
beforeEach(function() {
sandbox.stub(console, "error");
setupOutgoingRoom = sandbox.stub(store, "_setupOutgoingRoom");
});
afterEach(function() {
setupOutgoingRoom.restore();
});
it("We should call trigger a FxOS outgoing call if we get " +
"install-package message without error", function() {
sinon.assert.notCalled(setupOutgoingRoom);
store._onMarketplaceMessage({
data: {
name: "install-package"
}
});
sinon.assert.calledOnce(setupOutgoingRoom);
});
it("We should log an error if we get install-package message with an " +
"error", function() {
sinon.assert.notCalled(setupOutgoingRoom);
store._onMarketplaceMessage({
data: {
name: "install-package",
error: { error: "whatever error" }
}
});
sinon.assert.notCalled(setupOutgoingRoom);
sinon.assert.calledOnce(console.error);
sinon.assert.calledWith(console.error, "whatever error");
});
});
});

Просмотреть файл

@ -57,7 +57,6 @@
<script src="../../content/shared/js/otSdkDriver.js"></script>
<script src="../../content/shared/js/store.js"></script>
<script src="../../content/shared/js/roomStates.js"></script>
<script src="../../content/shared/js/fxOSActiveRoomStore.js"></script>
<script src="../../content/shared/js/activeRoomStore.js"></script>
<script src="../../content/shared/js/conversationStore.js"></script>
<script src="../../content/shared/js/views.js"></script>
@ -76,7 +75,6 @@
<script src="validate_test.js"></script>
<script src="dispatcher_test.js"></script>
<script src="activeRoomStore_test.js"></script>
<script src="fxOSActiveRoomStore_test.js"></script>
<script src="conversationStore_test.js"></script>
<script src="otSdkDriver_test.js"></script>
<script src="store_test.js"></script>

Просмотреть файл

@ -54,39 +54,6 @@ describe("loop.shared.utils", function() {
});
});
describe("#isFirefoxOS", function() {
describe("without mozActivities", function() {
it("shouldn't detect FirefoxOS on mobile platform", function() {
expect(sharedUtils.isFirefoxOS("mobi")).eql(false);
});
it("shouldn't detect FirefoxOS on non mobile platform", function() {
expect(sharedUtils.isFirefoxOS("whatever")).eql(false);
});
});
describe("with mozActivities", function() {
var realMozActivity;
before(function() {
realMozActivity = window.MozActivity;
window.MozActivity = {};
});
after(function() {
window.MozActivity = realMozActivity;
});
it("should detect FirefoxOS on mobile platform", function() {
expect(sharedUtils.isFirefoxOS("mobi")).eql(true);
});
it("shouldn't detect FirefoxOS on non mobile platform", function() {
expect(sharedUtils.isFirefoxOS("whatever")).eql(false);
});
});
});
describe("#formatDate", function() {
beforeEach(function() {
sandbox.stub(Date.prototype, "toLocaleDateString").returns("fake result");

Просмотреть файл

@ -53,7 +53,6 @@
<script src="../../content/shared/js/dispatcher.js"></script>
<script src="../../content/shared/js/store.js"></script>
<script src="../../content/shared/js/roomStates.js"></script>
<script src="../../content/shared/js/fxOSActiveRoomStore.js"></script>
<script src="../../content/shared/js/activeRoomStore.js"></script>
<script src="../../content/shared/js/views.js"></script>
<script src="../../content/shared/js/textChatStore.js"></script>
@ -63,7 +62,6 @@
<script src="../../standalone/content/js/standaloneAppStore.js"></script>
<script src="../../standalone/content/js/standaloneClient.js"></script>
<script src="../../standalone/content/js/standaloneMozLoop.js"></script>
<script src="../../standalone/content/js/fxOSMarketplace.js"></script>
<script src="../../standalone/content/js/standaloneRoomViews.js"></script>
<script src="../../standalone/content/js/standaloneMetricsStore.js"></script>
<script src="../../standalone/content/js/webapp.js"></script>

Просмотреть файл

@ -742,26 +742,6 @@ describe("loop.standaloneRoomViews", function() {
null);
});
});
describe("Marketplace hidden iframe", function() {
it("should set src when the store state change",
function(done) {
var marketplace = view.getDOMNode().querySelector("#marketplace");
expect(marketplace.src).to.be.equal("");
activeRoomStore.setStoreState({
marketplaceSrc: "http://market/",
onMarketplaceMessage: function () {}
});
view.forceUpdate(function() {
expect(marketplace.src).to.be.equal("http://market/");
done();
});
});
});
});
});
});

Просмотреть файл

@ -939,7 +939,6 @@ describe("loop.webapp", function() {
sdk: {}
});
conversation.onMarketplaceMessage = function() {};
sandbox.stub(notifications, "errorL10n");
requestCallUrlInfo = sandbox.stub();
@ -950,8 +949,6 @@ describe("loop.webapp", function() {
notifications: notifications,
client: {requestCallUrlInfo: requestCallUrlInfo}
}));
loop.config.marketplaceUrl = "http://market/";
});
it("should call requestCallUrlInfo", function() {
@ -988,20 +985,6 @@ describe("loop.webapp", function() {
sinon.assert.calledWithExactly(notifications.errorL10n,
"tech_error", { param: "value" });
});
it("should set marketplace hidden iframe src when fxos:app-needed is " +
"triggered", function(done) {
var marketplace = view.getDOMNode().querySelector("#marketplace");
expect(marketplace.src).to.be.equal("");
conversation.trigger("fxos:app-needed");
view.forceUpdate(function() {
expect(marketplace.src).to.be.equal(loop.config.marketplaceUrl);
done();
});
});
});
describe("#render", function() {
@ -1111,231 +1094,4 @@ describe("loop.webapp", function() {
});
});
});
describe("Firefox OS", function() {
var conversation, client;
before(function() {
client = new loop.StandaloneClient({
baseServerUrl: "http://fake.example.com"
});
sandbox.stub(client, "requestCallInfo");
conversation = new sharedModels.ConversationModel({}, {
sdk: {},
pendingCallTimeout: 1000
});
});
describe("Setup call", function() {
var fakeConversation, setupOutgoingCall, view, requestCallUrlInfo;
beforeEach(function() {
fakeConversation = new loop.webapp.FxOSConversationModel({
loopToken: "fakeToken"
});
setupOutgoingCall = sandbox.stub(fakeConversation, "setupOutgoingCall");
var standaloneClientStub = {
requestCallUrlInfo: function(token, cb) {
cb(null, {urlCreationDate: 0});
},
settings: {baseServerUrl: loop.webapp.baseServerUrl}
};
view = React.addons.TestUtils.renderIntoDocument(
React.createElement(
loop.webapp.StartConversationView, {
conversation: fakeConversation,
notifications: notifications,
client: standaloneClientStub
}));
// default to succeeding with a null local media object
stubGetPermsAndCacheMedia.callsArgWith(1, {});
});
it("should start the conversation establishment process", function() {
var button = view.getDOMNode().querySelector("button");
React.addons.TestUtils.Simulate.click(button);
sinon.assert.calledOnce(setupOutgoingCall);
});
});
describe("FxOSConversationModel", function() {
var model, realMozActivity;
before(function() {
model = new loop.webapp.FxOSConversationModel({
loopToken: "fakeToken",
callerId: "callerId"
});
realMozActivity = window.MozActivity;
loop.config.fxosApp = {
name: "Firefox Hello"
};
});
after(function() {
window.MozActivity = realMozActivity;
});
describe("setupOutgoingCall", function() {
var _activityProps, _onerror, trigger;
function fireError(errorName) {
_onerror({
target: {
error: {
name: errorName
}
}
});
}
before(function() {
window.MozActivity = function(activityProps) {
_activityProps = activityProps;
return {
set onerror(callback) {
_onerror = callback;
}
};
};
});
after(function() {
window.MozActivity = realMozActivity;
});
beforeEach(function() {
trigger = sandbox.stub(model, "trigger");
_activityProps = undefined;
});
afterEach(function() {
trigger.restore();
});
it("Activity properties with video call", function() {
expect(_activityProps).to.not.exist;
model.setupOutgoingCall("audio-video");
expect(_activityProps).to.exist;
expect(_activityProps).eql({
name: "loop-call",
data: {
type: "loop/token",
token: "fakeToken",
callerId: "callerId",
video: true
}
});
});
it("Activity properties with audio call", function() {
expect(_activityProps).to.not.exist;
model.setupOutgoingCall("audio");
expect(_activityProps).to.exist;
expect(_activityProps).eql({
name: "loop-call",
data: {
type: "loop/token",
token: "fakeToken",
callerId: "callerId",
video: false
}
});
});
it("Activity properties by default", function() {
expect(_activityProps).to.not.exist;
model.setupOutgoingCall();
expect(_activityProps).to.exist;
expect(_activityProps).eql({
name: "loop-call",
data: {
type: "loop/token",
token: "fakeToken",
callerId: "callerId",
video: false
}
});
});
it("NO_PROVIDER activity error should trigger fxos:app-needed",
function() {
sinon.assert.notCalled(trigger);
model.setupOutgoingCall();
fireError("NO_PROVIDER");
sinon.assert.calledOnce(trigger);
sinon.assert.calledWithExactly(trigger, "fxos:app-needed");
}
);
it("Other activity error should trigger session:error",
function() {
sinon.assert.notCalled(trigger);
model.setupOutgoingCall();
fireError("whatever");
sinon.assert.calledOnce(trigger);
sinon.assert.calledWithExactly(trigger, "session:error",
"fxos_app_needed", { fxosAppName: loop.config.fxosApp.name });
}
);
});
describe("onMarketplaceMessage", function() {
var view, setupOutgoingCall, trigger;
before(function() {
view = React.addons.TestUtils.renderIntoDocument(
React.createElement(
loop.webapp.StartConversationView, {
conversation: model,
notifications: notifications,
client: {requestCallUrlInfo: sandbox.stub()}
}));
});
beforeEach(function() {
setupOutgoingCall = sandbox.stub(model, "setupOutgoingCall");
trigger = sandbox.stub(model, "trigger");
});
afterEach(function() {
setupOutgoingCall.restore();
trigger.restore();
});
it("We should call trigger a FxOS outgoing call if we get " +
"install-package message without error", function() {
sinon.assert.notCalled(setupOutgoingCall);
model.onMarketplaceMessage({
data: {
name: "install-package"
}
});
sinon.assert.calledOnce(setupOutgoingCall);
});
it("We should trigger a session:error event if we get " +
"install-package message with an error", function() {
sinon.assert.notCalled(trigger);
sinon.assert.notCalled(setupOutgoingCall);
model.onMarketplaceMessage({
data: {
name: "install-package",
error: "error"
}
});
sinon.assert.notCalled(setupOutgoingCall);
sinon.assert.calledOnce(trigger);
sinon.assert.calledWithExactly(trigger, "session:error",
"fxos_app_needed", { fxosAppName: loop.config.fxosApp.name });
});
});
});
});
});

Просмотреть файл

@ -42,8 +42,6 @@
<script src="../content/shared/js/dispatcher.js"></script>
<script src="../content/shared/js/store.js"></script>
<script src="../content/shared/js/conversationStore.js"></script>
<script src="../content/shared/js/roomStates.js"></script>
<script src="../content/shared/js/fxOSActiveRoomStore.js"></script>
<script src="../content/shared/js/activeRoomStore.js"></script>
<script src="../content/shared/js/views.js"></script>
<script src="../content/shared/js/textChatStore.js"></script>
@ -58,7 +56,6 @@
<script src="../standalone/content/js/multiplexGum.js"></script>
<script src="../standalone/content/js/webapp.js"></script>
<script src="../standalone/content/js/standaloneRoomViews.js"></script>
<script src="../standalone/content/js/fxOSMarketplace.js"></script>
<script type="text/javascript;version=1.8" src="../content/js/contacts.js"></script>
<script>
if (!loop.contacts) {