Bug 1081023 - Handle call url changes to the format for Loop's call links. r=nperriault

This commit is contained in:
Mark Banner 2014-10-23 09:42:21 +01:00
parent 7e0e31669a
commit f7c76f5450
11 changed files with 136 additions and 46 deletions

View File

@ -584,7 +584,7 @@ loop.conversation = (function(mozL10n) {
// Obtain the callId and pass it through
var helper = new loop.shared.utils.Helper();
var locationHash = helper.locationHash();
var locationHash = helper.locationData().hash;
var callId;
var outgoing;
var localRoomStore;

View File

@ -584,7 +584,7 @@ loop.conversation = (function(mozL10n) {
// Obtain the callId and pass it through
var helper = new loop.shared.utils.Helper();
var locationHash = helper.locationHash();
var locationHash = helper.locationData().hash;
var callId;
var outgoing;
var localRoomStore;

View File

@ -409,7 +409,7 @@ loop.store.ConversationStore = (function() {
// XXX: The internal callId is different from
// this.get("callId"), see bug 1084228 for more info.
var locationHash = new loop.shared.utils.Helper().locationHash();
var locationHash = new loop.shared.utils.Helper().locationData().hash;
var callId = locationHash.match(/\#outgoing\/(.*)/)[1];
navigator.mozLoop.releaseCallData(callId);
},

View File

@ -91,8 +91,15 @@ loop.shared.utils = (function(mozL10n) {
return this._iOSRegex.test(platform);
},
locationHash: function() {
return window.location.hash;
/**
* Helper to allow getting some of the location data in a way that's compatible
* with stubbing for unit tests.
*/
locationData: function() {
return {
hash: window.location.hash,
pathname: window.location.pathname
};
}
};

View File

@ -915,10 +915,23 @@ loop.webapp = (function($, _, OT, mozL10n) {
url: document.location.origin
});
// Obtain the loopToken and pass it to the conversation
var locationHash = helper.locationHash();
if (locationHash) {
conversation.set("loopToken", locationHash.match(/\#call\/(.*)/)[1]);
// Obtain the loopToken
var match;
// locationHash supports the old format urls.
var locationData = helper.locationData();
if (locationData.hash) {
match = locationData.hash.match(/\#call\/(.*)/);
} else if (locationData.pathname) {
// Otherwise, we're expecting a url such as /c/<token> for calls.
match = locationData.pathname.match(/\/c\/([\w\-]+)/);
}
// XXX Supporting '/\/([\w\-]+)/' is for rooms which are to be implemented
// in bug 1074701.
if (match && match[1]) {
conversation.set({loopToken: match[1]});
}
React.renderComponent(WebappRootView({

View File

@ -915,10 +915,23 @@ loop.webapp = (function($, _, OT, mozL10n) {
url: document.location.origin
});
// Obtain the loopToken and pass it to the conversation
var locationHash = helper.locationHash();
if (locationHash) {
conversation.set("loopToken", locationHash.match(/\#call\/(.*)/)[1]);
// Obtain the loopToken
var match;
// locationHash supports the old format urls.
var locationData = helper.locationData();
if (locationData.hash) {
match = locationData.hash.match(/\#call\/(.*)/);
} else if (locationData.pathname) {
// Otherwise, we're expecting a url such as /c/<token> for calls.
match = locationData.pathname.match(/\/c\/([\w\-]+)/);
}
// XXX Supporting '/\/([\w\-]+)/' is for rooms which are to be implemented
// in bug 1074701.
if (match && match[1]) {
conversation.set({loopToken: match[1]});
}
React.renderComponent(<WebappRootView

View File

@ -34,26 +34,43 @@ function getConfigFile(req, res) {
}
app.get('/content/config.js', getConfigFile);
app.get('/content/c/config.js', getConfigFile);
// This lets /test/ be mapped to the right place for running tests
app.use('/', express.static(__dirname + '/../'));
// Various mappings to let us end up with:
// /test - for the test files
// /ui - for the ui showcase
// /content - for the standalone files.
// Magic so that the legal content works both in the standalone server
// and as static content in the loop-client repo
app.use('/', express.static(__dirname + '/content/'));
app.use('/shared', express.static(__dirname + '/../content/shared/'));
app.get('/config.js', getConfigFile);
app.use('/test', express.static(__dirname + '/../test'));
app.use('/ui', express.static(__dirname + '/../ui'));
// This lets /content/ be mapped right for the static contents.
app.use('/', express.static(__dirname + '/'));
// This lets standalone components load images into the UI showcase
app.use('/standalone/content', express.static(__dirname + '/../content'));
// This exists exclusively for the unit tests. They are served the
// whole loop/ directory structure and expect some files in the standalone directory.
app.use('/standalone/content', express.static(__dirname + '/content'));
// We load /content this from both /content *and* /../content. The first one
// does what we need for running in the github loop-client context, the second one
// handles running in the hg repo under mozilla-central and is used so that the shared
// files are in the right location.
app.use('/content', express.static(__dirname + '/content'));
app.use('/content', express.static(__dirname + '/../content'));
// These two are based on the above, but handle call urls, that have a /c/ in them.
app.use('/content/c', express.static(__dirname + '/content'));
app.use('/content/c', express.static(__dirname + '/../content'));
// As we don't have hashes on the urls, the best way to serve the index files
// appears to be to be to closely filter the url and match appropriately.
function serveIndex(req, res) {
return res.sendfile(__dirname + '/content/index.html');
}
app.get(/^\/content\/[\w\-]+$/, serveIndex);
app.get(/^\/content\/c\/[\w\-]+$/, serveIndex);
var server = app.listen(port);
var baseUrl = "http://localhost:" + port + "/";
console.log("Serving repository root over HTTP at " + baseUrl);
console.log("Static contents are available at " + baseUrl + "content/");
console.log("Tests are viewable at " + baseUrl + "test/");
console.log("Use this for development only.");

View File

@ -79,7 +79,10 @@ describe("loop.conversation", function() {
sandbox.stub(loop.Dispatcher.prototype, "dispatch");
sandbox.stub(loop.shared.utils.Helper.prototype,
"locationHash").returns("#incoming/42");
"locationData").returns({
hash: "#incoming/42",
pathname: "/"
});
window.OT = {
overrideGuidStorage: sinon.stub()
@ -117,8 +120,11 @@ describe("loop.conversation", function() {
var fakeRoomID = "32";
beforeEach(function() {
loop.shared.utils.Helper.prototype.locationHash
.returns("#room/" + fakeRoomID);
loop.shared.utils.Helper.prototype.locationData
.returns({
hash: "#room/" + fakeRoomID,
pathname: ""
});
sandbox.stub(loop.store, "LocalRoomStore");
});
@ -159,7 +165,10 @@ describe("loop.conversation", function() {
it("should trigger an outgoing gatherCallData action for outgoing calls",
function() {
loop.shared.utils.Helper.prototype.locationHash.returns("#outgoing/24");
loop.shared.utils.Helper.prototype.locationData.returns({
hash: "#outgoing/24",
pathname: "/"
});
loop.conversation.init();

View File

@ -125,8 +125,11 @@ describe("loop.store.ConversationStore", function () {
describe("#connectionFailure", function() {
beforeEach(function() {
store._websocket = fakeWebsocket;
sandbox.stub(loop.shared.utils.Helper.prototype, "locationHash")
.returns("#outgoing/42");
sandbox.stub(loop.shared.utils.Helper.prototype, "locationData")
.returns({
hash: "#outgoing/42",
pathname: ""
});
});
it("should disconnect the session", function() {
@ -496,8 +499,11 @@ describe("loop.store.ConversationStore", function () {
close: wsCloseSpy
};
store.set({callState: CALL_STATES.ONGOING});
sandbox.stub(loop.shared.utils.Helper.prototype, "locationHash")
.returns("#outgoing/42");
sandbox.stub(loop.shared.utils.Helper.prototype, "locationData")
.returns({
hash: "#outgoing/42",
pathname: ""
});
});
it("should disconnect the session", function() {
@ -543,8 +549,11 @@ describe("loop.store.ConversationStore", function () {
close: wsCloseSpy
};
store.set({callState: CALL_STATES.ONGOING});
sandbox.stub(loop.shared.utils.Helper.prototype, "locationHash")
.returns("#outgoing/42");
sandbox.stub(loop.shared.utils.Helper.prototype, "locationData")
.returns({
hash: "#outgoing/42",
pathname: ""
});
});
it("should disconnect the session", function() {
@ -578,8 +587,11 @@ describe("loop.store.ConversationStore", function () {
store._websocket = fakeWebsocket;
store.set({callState: CALL_STATES.CONNECTING});
sandbox.stub(loop.shared.utils.Helper.prototype, "locationHash")
.returns("#outgoing/42");
sandbox.stub(loop.shared.utils.Helper.prototype, "locationData")
.returns({
hash: "#outgoing/42",
pathname: ""
});
});
it("should disconnect the session", function() {

View File

@ -34,8 +34,6 @@ describe("loop.webapp", function() {
beforeEach(function() {
sandbox.stub(React, "renderComponent");
sandbox.stub(sharedUtils.Helper.prototype,
"locationHash").returns("#call/fake-Token");
loop.config.feedbackApiUrl = "http://fake.invalid";
conversationSetStub =
sandbox.stub(sharedModels.ConversationModel.prototype, "set");
@ -52,12 +50,33 @@ describe("loop.webapp", function() {
}));
});
it("should set the loopToken on the conversation", function() {
loop.webapp.init();
it("should set the loopToken on the conversation for old-style call urls",
function() {
sandbox.stub(sharedUtils.Helper.prototype,
"locationData").returns({
hash: "#call/fake-Token",
pathname: "/"
});
sinon.assert.called(conversationSetStub);
sinon.assert.calledWithExactly(conversationSetStub, "loopToken", "fake-Token");
});
loop.webapp.init();
sinon.assert.called(conversationSetStub);
sinon.assert.calledWithExactly(conversationSetStub, {loopToken: "fake-Token"});
});
it("should set the loopToken on the conversation for new-style call urls",
function() {
sandbox.stub(sharedUtils.Helper.prototype,
"locationData").returns({
hash: "",
pathname: "/c/abc123-_Tes"
});
loop.webapp.init();
sinon.assert.called(conversationSetStub);
sinon.assert.calledWithExactly(conversationSetStub, {loopToken: "abc123-_Tes"});
});
});
describe("OutgoingConversationView", function() {

View File

@ -11,7 +11,7 @@
<link rel="stylesheet" type="text/css" href="../content/shared/css/conversation.css">
<link rel="stylesheet" type="text/css" href="../content/shared/css/panel.css">
<link rel="stylesheet" type="text/css" href="../content/shared/css/contacts.css">
<link rel="stylesheet" type="text/css" href="../standalone/content/css/webapp.css">
<link rel="stylesheet" type="text/css" href="../content/css/webapp.css">
<link rel="stylesheet" type="text/css" href="ui-showcase.css">
</head>
<body>
@ -45,7 +45,7 @@
<script src="../content/js/roomViews.js"></script>
<script src="../content/js/conversationViews.js"></script>
<script src="../content/js/client.js"></script>
<script src="../standalone/content/js/webapp.js"></script>
<script src="../content/js/webapp.js"></script>
<script type="text/javascript;version=1.8" src="../content/js/contacts.js"></script>
<script>
if (!loop.contacts) {