mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 00:05:36 +00:00
Bug 985596 - Refactored shared assets & tests. r=dmose
--HG-- rename : static/shared/README.md => browser/components/loop/content/shared/README.md rename : static/shared/css/common.css => browser/components/loop/content/shared/css/common.css rename : static/shared/css/conversation.css => browser/components/loop/content/shared/css/conversation.css rename : static/shared/css/panel.css => browser/components/loop/content/shared/css/panel.css rename : static/shared/css/readme.html => browser/components/loop/content/shared/css/readme.html rename : static/shared/img/icon_32.png => browser/components/loop/content/shared/img/icon_32.png rename : static/shared/img/icon_64.png => browser/components/loop/content/shared/img/icon_64.png rename : static/shared/js/models.js => browser/components/loop/content/shared/js/models.js rename : static/shared/js/views.js => browser/components/loop/content/shared/js/views.js rename : static/shared/libs/backbone-1.1.2.js => browser/components/loop/content/shared/libs/backbone-1.1.2.js rename : static/shared/libs/jquery-2.1.0.js => browser/components/loop/content/shared/libs/jquery-2.1.0.js rename : static/shared/libs/lodash-2.4.1.js => browser/components/loop/content/shared/libs/lodash-2.4.1.js rename : static/shared/libs/sdk.js => browser/components/loop/content/shared/libs/sdk.js rename : static/shared/libs/webl10n-20130617.js => browser/components/loop/content/shared/libs/webl10n-20130617.js rename : static/css/webapp.css => browser/components/loop/standalone/content/css/webapp.css rename : static/index.html => browser/components/loop/standalone/content/index.html rename : static/js/webapp.js => browser/components/loop/standalone/content/js/webapp.js rename : static/l10n/data.ini => browser/components/loop/standalone/content/l10n/data.ini rename : test/webapp_test.js => browser/components/loop/test/standalone/webapp_test.js extra : transplant_source : %DA%D9%3A%E9%C6%E0d%13%84%C1%BEps%C8b%F09o%D7m
This commit is contained in:
parent
49c12d9a48
commit
4ac3aa169a
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
@ -14,6 +14,7 @@ loop.shared.models = (function() {
|
||||
*/
|
||||
var ConversationModel = Backbone.Model.extend({
|
||||
defaults: {
|
||||
callerId: undefined, // Loop caller id
|
||||
loopToken: undefined, // Loop conversation token
|
||||
sessionId: undefined, // TB session id
|
||||
sessionToken: undefined, // TB session token
|
||||
@ -31,12 +32,11 @@ loop.shared.models = (function() {
|
||||
* retrieved from the server;
|
||||
* - `session:error` when the request failed.
|
||||
*
|
||||
* @param {Object} baseServerUrl The server URL
|
||||
* @throws {Error} If no baseServerUrl is given
|
||||
* @throws {Error} If no conversation token is set
|
||||
* @param {String} baseServerUrl The server URL
|
||||
* @throws {Error} If no baseServerUrl is given
|
||||
* @throws {Error} If no conversation token is set
|
||||
*/
|
||||
initiate: function(baseServerUrl) {
|
||||
|
||||
if (!baseServerUrl) {
|
||||
throw new Error("baseServerUrl arg must be passed to initiate()");
|
||||
}
|
||||
@ -95,7 +95,26 @@ loop.shared.models = (function() {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Notification model.
|
||||
*/
|
||||
var NotificationModel = Backbone.Model.extend({
|
||||
defaults: {
|
||||
level: "info",
|
||||
message: ""
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Notification collection
|
||||
*/
|
||||
var NotificationCollection = Backbone.Collection.extend({
|
||||
model: NotificationModel
|
||||
});
|
||||
|
||||
return {
|
||||
ConversationModel: ConversationModel
|
||||
ConversationModel: ConversationModel,
|
||||
NotificationCollection: NotificationCollection,
|
||||
NotificationModel: NotificationModel
|
||||
};
|
||||
})();
|
37
browser/components/loop/content/shared/js/router.js
Normal file
37
browser/components/loop/content/shared/js/router.js
Normal file
@ -0,0 +1,37 @@
|
||||
/* 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/. */
|
||||
|
||||
/* global loop:true */
|
||||
|
||||
var loop = loop || {};
|
||||
loop.shared = loop.shared || {};
|
||||
loop.shared.router = (function() {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Base Router. Allows defining a main active view and ease toggling it when
|
||||
* the active route changes.
|
||||
*
|
||||
* @link http://mikeygee.com/blog/backbone.html
|
||||
*/
|
||||
var BaseRouter = Backbone.Router.extend({
|
||||
activeView: undefined,
|
||||
|
||||
/**
|
||||
* Loads and render current active view.
|
||||
*
|
||||
* @param {loop.shared.views.BaseView} view View.
|
||||
*/
|
||||
loadView : function(view) {
|
||||
if (this.activeView) {
|
||||
this.activeView.hide();
|
||||
}
|
||||
this.activeView = view.render().show();
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
BaseRouter: BaseRouter
|
||||
};
|
||||
})();
|
@ -4,8 +4,6 @@
|
||||
|
||||
/* global loop:true */
|
||||
|
||||
// XXX This file needs unit tests.
|
||||
|
||||
var loop = loop || {};
|
||||
loop.shared = loop.shared || {};
|
||||
loop.shared.views = (function(TB) {
|
||||
@ -42,15 +40,23 @@ loop.shared.views = (function(TB) {
|
||||
var ConversationView = BaseView.extend({
|
||||
el: "#conversation",
|
||||
|
||||
initialize: function() {
|
||||
this.videoStyles = { width: "100%", height: "100%" };
|
||||
videoStyles: { width: "100%", height: "100%" },
|
||||
|
||||
// XXX this feels like to be moved to the ConversationModel, but as it's
|
||||
/**
|
||||
* Establishes webrtc communication using TB sdk.
|
||||
*/
|
||||
initialize: function(options) {
|
||||
options = options || {};
|
||||
if (!options.sdk) {
|
||||
throw new Error("missing required sdk");
|
||||
}
|
||||
this.sdk = options.sdk;
|
||||
// XXX: this feels like to be moved to the ConversationModel, but as it's
|
||||
// tighly coupled with the DOM (element ids to receive streams), we'd need
|
||||
// an abstraction we probably don't want yet.
|
||||
this.session = TB.initSession(this.model.get("sessionId"));
|
||||
this.publisher = TB.initPublisher(this.model.get("apiKey"), "outgoing",
|
||||
this.videoStyles);
|
||||
this.session = this.sdk.initSession(this.model.get("sessionId"));
|
||||
this.publisher = this.sdk.initPublisher(this.model.get("apiKey"),
|
||||
"outgoing", this.videoStyles);
|
||||
|
||||
this.session.connect(this.model.get("apiKey"),
|
||||
this.model.get("sessionToken"));
|
||||
@ -85,8 +91,59 @@ loop.shared.views = (function(TB) {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Notification view.
|
||||
*/
|
||||
var NotificationView = Backbone.View.extend({
|
||||
template: _.template([
|
||||
'<div class="alert alert-<%- level %>">',
|
||||
' <button class="close"></button>',
|
||||
' <p class="message"><%- message %></p>',
|
||||
'</div>'
|
||||
].join("")),
|
||||
|
||||
events: {
|
||||
"click .close": "dismiss"
|
||||
},
|
||||
|
||||
dismiss: function(event) {
|
||||
event.preventDefault();
|
||||
this.$el.addClass("fade-out");
|
||||
setTimeout(function() {
|
||||
this.collection.remove(this.model);
|
||||
this.remove();
|
||||
}.bind(this), 500); // XXX make timeout value configurable
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Notification list view.
|
||||
*/
|
||||
var NotificationListView = Backbone.View.extend({
|
||||
initialize: function() {
|
||||
this.listenTo(this.collection, "reset add remove", this.render);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(this.collection.map(function(notification) {
|
||||
return new NotificationView({
|
||||
model: notification,
|
||||
collection: this.collection
|
||||
}).render().$el;
|
||||
}.bind(this)));
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
BaseView: BaseView,
|
||||
ConversationView: ConversationView
|
||||
ConversationView: ConversationView,
|
||||
NotificationListView: NotificationListView,
|
||||
NotificationView: NotificationView
|
||||
};
|
||||
})(window.TB);
|
@ -1,4 +1,4 @@
|
||||
node_modules
|
||||
static/shared/libs
|
||||
content/shared/libs
|
||||
test/shared/vendor
|
||||
|
||||
|
@ -11,7 +11,7 @@ test:
|
||||
@echo "Not implemented yet."
|
||||
|
||||
lint:
|
||||
@$(NODE_LOCAL_BIN)/jshint *.js static test
|
||||
@$(NODE_LOCAL_BIN)/jshint *.js content test
|
||||
|
||||
runserver:
|
||||
@node server.js
|
||||
|
@ -20,11 +20,11 @@ For development, run a local static file server:
|
||||
|
||||
Then point your browser at:
|
||||
|
||||
- `http://localhost:3000/static/` for public web contents,
|
||||
- `http://localhost:3000/content/` for all public webapp contents,
|
||||
- `http://localhost:3000/test/` for tests.
|
||||
|
||||
**Note:** the provided static file server is **not** intended for production
|
||||
use.
|
||||
**Note:** the provided static file server for web contents is **not** intended
|
||||
for production use.
|
||||
|
||||
Code linting
|
||||
------------
|
||||
|
@ -56,6 +56,7 @@
|
||||
<!-- app scripts -->
|
||||
<script type="text/javascript" src="shared/js/models.js"></script>
|
||||
<script type="text/javascript" src="shared/js/views.js"></script>
|
||||
<script type="text/javascript" src="shared/js/router.js"></script>
|
||||
<script type="text/javascript" src="js/webapp.js"></script>
|
||||
|
||||
<script>
|
@ -15,11 +15,15 @@ loop.webapp = (function($, TB) {
|
||||
*
|
||||
* @type {String}
|
||||
*/
|
||||
var baseApiUrl = "http://localhost:5000";
|
||||
var sharedModels = loop.shared.models,
|
||||
sharedViews = loop.shared.views,
|
||||
// XXX this one should be configurable
|
||||
// see https://bugzilla.mozilla.org/show_bug.cgi?id=987086
|
||||
baseServerUrl = "http://localhost:5000";
|
||||
|
||||
/**
|
||||
* App router.
|
||||
* @type {loop.webapp.Router}
|
||||
* @type {loop.webapp.WebappRouter}
|
||||
*/
|
||||
var router;
|
||||
|
||||
@ -32,7 +36,7 @@ loop.webapp = (function($, TB) {
|
||||
/**
|
||||
* Homepage view.
|
||||
*/
|
||||
var HomeView = loop.shared.views.BaseView.extend({
|
||||
var HomeView = sharedViews.BaseView.extend({
|
||||
el: "#home"
|
||||
});
|
||||
|
||||
@ -40,7 +44,7 @@ loop.webapp = (function($, TB) {
|
||||
* Conversation launcher view. A ConversationModel is associated and attached
|
||||
* as a `model` property.
|
||||
*/
|
||||
var ConversationFormView = loop.shared.views.BaseView.extend({
|
||||
var ConversationFormView = sharedViews.BaseView.extend({
|
||||
el: "#conversation-form",
|
||||
|
||||
events: {
|
||||
@ -57,18 +61,18 @@ loop.webapp = (function($, TB) {
|
||||
|
||||
initiate: function(event) {
|
||||
event.preventDefault();
|
||||
this.model.initiate(baseApiUrl);
|
||||
this.model.initiate(baseServerUrl);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* App Router. Allows defining a main active view and ease toggling it when
|
||||
* the active route changes.
|
||||
* Webapp Router. Allows defining a main active view and easily toggling it
|
||||
* when the active route changes.
|
||||
*
|
||||
* @link http://mikeygee.com/blog/backbone.html
|
||||
*/
|
||||
var Router = Backbone.Router.extend({
|
||||
var WebappRouter = loop.shared.router.BaseRouter.extend({
|
||||
_conversation: undefined,
|
||||
activeView: undefined,
|
||||
|
||||
routes: {
|
||||
"": "home",
|
||||
@ -104,18 +108,6 @@ loop.webapp = (function($, TB) {
|
||||
this.navigate("call/" + this._conversation.get("token"), {trigger: true});
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads and render current active view.
|
||||
*
|
||||
* @param {loop.shared.BaseView} view View.
|
||||
*/
|
||||
loadView : function(view) {
|
||||
if (this.activeView) {
|
||||
this.activeView.hide();
|
||||
}
|
||||
this.activeView = view.render().show();
|
||||
},
|
||||
|
||||
/**
|
||||
* Default entry point.
|
||||
*/
|
||||
@ -149,7 +141,10 @@ loop.webapp = (function($, TB) {
|
||||
}
|
||||
}
|
||||
this.loadView(
|
||||
new loop.shared.views.ConversationView({model: this._conversation}));
|
||||
new sharedViews.ConversationView({
|
||||
sdk: TB,
|
||||
model: this._conversation
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
@ -157,8 +152,8 @@ loop.webapp = (function($, TB) {
|
||||
* App initialization.
|
||||
*/
|
||||
function init() {
|
||||
conversation = new loop.shared.models.ConversationModel();
|
||||
router = new Router({conversation: conversation});
|
||||
conversation = new sharedModels.ConversationModel();
|
||||
router = new WebappRouter({conversation: conversation});
|
||||
Backbone.history.start();
|
||||
}
|
||||
|
||||
@ -166,6 +161,6 @@ loop.webapp = (function($, TB) {
|
||||
ConversationFormView: ConversationFormView,
|
||||
HomeView: HomeView,
|
||||
init: init,
|
||||
Router: Router
|
||||
WebappRouter: WebappRouter
|
||||
};
|
||||
})(jQuery, window.TB);
|
@ -9,6 +9,6 @@ app.use(express.static(__dirname + '/'));
|
||||
|
||||
app.listen(3000);
|
||||
console.log("Serving repository root over HTTP at http://localhost:3000/");
|
||||
console.log("Static contents are available at http://localhost:3000/static/");
|
||||
console.log("Static contents are available at http://localhost:3000/content/");
|
||||
console.log("Tests are viewable at http://localhost:3000/test/");
|
||||
console.log("Use this for development only.");
|
||||
|
@ -3,16 +3,13 @@
|
||||
- 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/. -->
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Loop mocha tests</title>
|
||||
<link rel="stylesheet" media="all" href="vendor/mocha-1.17.1.css">
|
||||
<link rel="prefetch" type="application/l10n" href="../../static/l10n/data.ini">
|
||||
<link rel="prefetch" type="application/l10n" href="../../content/l10n/data.ini">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="mocha">
|
||||
<p><a href=".">Index</a></p>
|
||||
</div>
|
||||
@ -20,10 +17,10 @@
|
||||
<div id="fixtures"></div>
|
||||
|
||||
<!-- libs -->
|
||||
<script src="../../static/shared/libs/webl10n-20130617.js"></script>
|
||||
<script src="../../static/shared/libs/jquery-2.1.0.js"></script>
|
||||
<script src="../../static/shared/libs/lodash-2.4.1.js"></script>
|
||||
<script src="../../static/shared/libs/backbone-1.1.2.js"></script>
|
||||
<script src="../../content/shared/libs/webl10n-20130617.js"></script>
|
||||
<script src="../../content/shared/libs/jquery-2.1.0.js"></script>
|
||||
<script src="../../content/shared/libs/lodash-2.4.1.js"></script>
|
||||
<script src="../../content/shared/libs/backbone-1.1.2.js"></script>
|
||||
|
||||
<!-- test dependencies -->
|
||||
<script src="vendor/mocha-1.17.1.js"></script>
|
||||
@ -35,17 +32,17 @@
|
||||
</script>
|
||||
|
||||
<!-- App scripts -->
|
||||
<script src="../../static/shared/js/models.js"></script>
|
||||
<script src="../../static/shared/js/views.js"></script>
|
||||
|
||||
<script src="../../content/shared/js/models.js"></script>
|
||||
<script src="../../content/shared/js/views.js"></script>
|
||||
<script src="../../content/shared/js/router.js"></script>
|
||||
<!-- Test scripts -->
|
||||
<script src="models_test.js"></script>
|
||||
<script src="views_test.js"></script>
|
||||
<script src="router_test.js"></script>
|
||||
<script>
|
||||
mocha.run(function () {
|
||||
$("#mocha").append("<p>Complete.</p>");
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -9,7 +9,8 @@ var expect = chai.expect;
|
||||
describe("loop.shared.models", function() {
|
||||
"use strict";
|
||||
|
||||
var sandbox, fakeXHR, requests = [];
|
||||
var sharedModels = loop.shared.models,
|
||||
sandbox, fakeXHR, requests = [];
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
@ -29,7 +30,7 @@ describe("loop.shared.models", function() {
|
||||
var conversation, fakeSessionData, fakeBaseServerUrl;
|
||||
|
||||
beforeEach(function() {
|
||||
conversation = new loop.shared.models.ConversationModel();
|
||||
conversation = new sharedModels.ConversationModel();
|
||||
fakeSessionData = {
|
||||
sessionId: "sessionId",
|
||||
sessionToken: "sessionToken",
|
||||
@ -39,7 +40,6 @@ describe("loop.shared.models", function() {
|
||||
});
|
||||
|
||||
describe("#initiate", function() {
|
||||
|
||||
it("should throw an Error if no baseServerUrl argument is passed",
|
||||
function () {
|
||||
expect(function() {
|
||||
@ -69,8 +69,8 @@ describe("loop.shared.models", function() {
|
||||
it("should update conversation session information from server data",
|
||||
function() {
|
||||
conversation.set("loopToken", "fakeToken");
|
||||
|
||||
conversation.initiate(fakeBaseServerUrl);
|
||||
|
||||
requests[0].respond(200, {"Content-Type": "application/json"},
|
||||
JSON.stringify(fakeSessionData));
|
||||
|
||||
@ -122,4 +122,3 @@ describe("loop.shared.models", function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
40
browser/components/loop/test/shared/router_test.js
Normal file
40
browser/components/loop/test/shared/router_test.js
Normal file
@ -0,0 +1,40 @@
|
||||
/* 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/. */
|
||||
|
||||
/* global loop, sinon */
|
||||
|
||||
var expect = chai.expect;
|
||||
|
||||
describe("loop.shared.router", function() {
|
||||
"use strict";
|
||||
|
||||
var sandbox;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
describe("BaseRouter", function() {
|
||||
var router;
|
||||
|
||||
beforeEach(function() {
|
||||
router = new loop.shared.router.BaseRouter();
|
||||
});
|
||||
|
||||
describe("#loadView", function() {
|
||||
it("should set the active view", function() {
|
||||
var TestView = loop.shared.views.BaseView.extend({});
|
||||
var view = new TestView();
|
||||
|
||||
router.loadView(view);
|
||||
|
||||
expect(router.activeView).eql(view);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -2,23 +2,149 @@
|
||||
* 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/. */
|
||||
|
||||
/* global sinon */
|
||||
/* global loop, sinon */
|
||||
|
||||
var expect = chai.expect;
|
||||
|
||||
describe("loop.shared.views", function() {
|
||||
"use strict";
|
||||
|
||||
var sandbox;
|
||||
var sharedModels = loop.shared.models,
|
||||
sharedViews = loop.shared.views,
|
||||
sandbox;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
sandbox.useFakeTimers(); // exposes sandbox.clock as a fake timer
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
$("#fixtures").empty();
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
describe("ConversationView", function() {
|
||||
it("should be tested");
|
||||
var fakeSDK, fakeSession;
|
||||
|
||||
beforeEach(function() {
|
||||
fakeSession = _.extend({
|
||||
connect: sandbox.spy()
|
||||
}, Backbone.Events);
|
||||
fakeSDK = {
|
||||
initPublisher: sandbox.spy(),
|
||||
initSession: sandbox.stub().returns(fakeSession)
|
||||
};
|
||||
});
|
||||
|
||||
describe("initialize", function() {
|
||||
it("should require an sdk object", function() {
|
||||
expect(function() {
|
||||
new sharedViews.ConversationView();
|
||||
}).to.Throw(Error, /sdk/);
|
||||
});
|
||||
|
||||
it("should initiate a session", function() {
|
||||
new sharedViews.ConversationView({
|
||||
sdk: fakeSDK,
|
||||
model: new sharedModels.ConversationModel()
|
||||
});
|
||||
|
||||
sinon.assert.calledOnce(fakeSession.connect);
|
||||
});
|
||||
|
||||
it("should trigger a session:ended model event when connectionDestroyed" +
|
||||
" event is received/", function(done) {
|
||||
// XXX remove when we implement proper notifications
|
||||
sandbox.stub(window, "alert");
|
||||
var model = new sharedModels.ConversationModel();
|
||||
new sharedViews.ConversationView({
|
||||
sdk: fakeSDK,
|
||||
model: model
|
||||
});
|
||||
|
||||
model.once("session:ended", function() {
|
||||
done();
|
||||
});
|
||||
|
||||
fakeSession.trigger("connectionDestroyed", {reason: "ko"});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("NotificationView", function() {
|
||||
var collection, model, view;
|
||||
|
||||
beforeEach(function() {
|
||||
$("#fixtures").append('<div id="test-notif"></div>');
|
||||
model = new sharedModels.NotificationModel({
|
||||
level: "error",
|
||||
message: "plop"
|
||||
});
|
||||
collection = new sharedModels.NotificationCollection([model]);
|
||||
view = new sharedViews.NotificationView({
|
||||
el: $("#test-notif"),
|
||||
collection: collection,
|
||||
model: model
|
||||
});
|
||||
});
|
||||
|
||||
describe("#dismiss", function() {
|
||||
it("should automatically dismiss notification after 500ms", function() {
|
||||
view.render().dismiss({preventDefault: sandbox.spy()});
|
||||
|
||||
expect(view.$(".message").text()).eql("plop");
|
||||
|
||||
sandbox.clock.tick(500);
|
||||
|
||||
expect(collection).to.have.length.of(0);
|
||||
expect($("#test-notif").html()).eql(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#render", function() {
|
||||
it("should render template with model attribute values", function() {
|
||||
view.render();
|
||||
|
||||
expect(view.$(".message").text()).eql("plop");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("NotificationListView", function() {
|
||||
describe("Collection events", function() {
|
||||
var coll, testNotif, view;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox.stub(sharedViews.NotificationListView.prototype, "render");
|
||||
testNotif = new sharedModels.NotificationModel({
|
||||
level: "error",
|
||||
message: "plop"
|
||||
});
|
||||
coll = new sharedModels.NotificationCollection();
|
||||
view = new sharedViews.NotificationListView({collection: coll});
|
||||
});
|
||||
|
||||
it("should render on notification added to the collection", function() {
|
||||
coll.add(testNotif);
|
||||
|
||||
sinon.assert.calledOnce(view.render);
|
||||
});
|
||||
|
||||
it("should render on notification removed from the collection",
|
||||
function() {
|
||||
coll.add(testNotif);
|
||||
coll.remove(testNotif);
|
||||
|
||||
sinon.assert.calledTwice(view.render);
|
||||
});
|
||||
|
||||
it("should render on collection reset",
|
||||
function() {
|
||||
coll.reset();
|
||||
|
||||
sinon.assert.calledOnce(view.render);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
45
browser/components/loop/test/standalone/index.html
Normal file
45
browser/components/loop/test/standalone/index.html
Normal file
@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<!-- 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/. -->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Loop mocha tests</title>
|
||||
<link rel="stylesheet" media="all" href="../shared/vendor/mocha-1.17.1.css">
|
||||
<link rel="prefetch" type="application/l10n" href="../../content/l10n/data.ini">
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha">
|
||||
<p><a href=".">Index</a></p>
|
||||
<p><a href="../shared/">Shared Tests</a></p>
|
||||
</div>
|
||||
<div id="messages"></div>
|
||||
<div id="fixtures"></div>
|
||||
<!-- libs -->
|
||||
<script src="../../content/shared/libs/webl10n-20130617.js"></script>
|
||||
<script src="../../content/shared/libs/jquery-2.1.0.js"></script>
|
||||
<script src="../../content/shared/libs/lodash-2.4.1.js"></script>
|
||||
<script src="../../content/shared/libs/backbone-1.1.2.js"></script>
|
||||
<!-- test dependencies -->
|
||||
<script src="../shared/vendor/mocha-1.17.1.js"></script>
|
||||
<script src="../shared/vendor/chai-1.9.0.js"></script>
|
||||
<script src="../shared/vendor/sinon-1.9.0.js"></script>
|
||||
<script>
|
||||
chai.Assertion.includeStack = true;
|
||||
mocha.setup('bdd');
|
||||
</script>
|
||||
<!-- App scripts -->
|
||||
<script src="../../content/shared/js/models.js"></script>
|
||||
<script src="../../content/shared/js/views.js"></script>
|
||||
<script src="../../content/shared/js/router.js"></script>
|
||||
<script src="../../content/js/webapp.js"></script>
|
||||
<!-- Test scripts -->
|
||||
<script src="webapp_test.js"></script>
|
||||
<script>
|
||||
mocha.run(function () {
|
||||
$("#mocha").append("<p>Complete.</p>");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -9,7 +9,8 @@ var expect = chai.expect;
|
||||
describe("loop.webapp", function() {
|
||||
"use strict";
|
||||
|
||||
var sandbox;
|
||||
var sharedModels = loop.shared.models,
|
||||
sandbox;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
@ -19,11 +20,11 @@ describe("loop.webapp", function() {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
describe("Router", function() {
|
||||
describe("WebappRouter", function() {
|
||||
var conversation, fakeSessionData;
|
||||
|
||||
beforeEach(function() {
|
||||
conversation = new loop.shared.models.ConversationModel();
|
||||
conversation = new sharedModels.ConversationModel();
|
||||
fakeSessionData = {
|
||||
sessionId: "sessionId",
|
||||
sessionToken: "sessionToken",
|
||||
@ -34,14 +35,14 @@ describe("loop.webapp", function() {
|
||||
describe("#constructor", function() {
|
||||
it("should require a ConversationModel instance", function() {
|
||||
expect(function() {
|
||||
new loop.webapp.Router();
|
||||
new loop.webapp.WebappRouter();
|
||||
}).to.Throw(Error, /missing required conversation/);
|
||||
});
|
||||
|
||||
it("should load the HomeView", function() {
|
||||
sandbox.stub(loop.webapp.Router.prototype, "loadView");
|
||||
sandbox.stub(loop.webapp.WebappRouter.prototype, "loadView");
|
||||
|
||||
var router = new loop.webapp.Router({conversation: conversation});
|
||||
var router = new loop.webapp.WebappRouter({conversation: conversation});
|
||||
|
||||
sinon.assert.calledOnce(router.loadView);
|
||||
sinon.assert.calledWithMatch(router.loadView,
|
||||
@ -53,7 +54,7 @@ describe("loop.webapp", function() {
|
||||
var router;
|
||||
|
||||
beforeEach(function() {
|
||||
router = new loop.webapp.Router({conversation: conversation});
|
||||
router = new loop.webapp.WebappRouter({conversation: conversation});
|
||||
});
|
||||
|
||||
describe("#loadView", function() {
|
||||
@ -66,7 +67,7 @@ describe("loop.webapp", function() {
|
||||
var router;
|
||||
|
||||
beforeEach(function() {
|
||||
router = new loop.webapp.Router({conversation: conversation});
|
||||
router = new loop.webapp.WebappRouter({conversation: conversation});
|
||||
sandbox.stub(router, "loadView");
|
||||
});
|
||||
|
||||
@ -132,8 +133,10 @@ describe("loop.webapp", function() {
|
||||
describe("Events", function() {
|
||||
it("should navigate to call/ongoing once the call session is ready",
|
||||
function() {
|
||||
sandbox.stub(loop.webapp.Router.prototype, "navigate");
|
||||
var router = new loop.webapp.Router({conversation: conversation});
|
||||
sandbox.stub(loop.webapp.WebappRouter.prototype, "navigate");
|
||||
var router = new loop.webapp.WebappRouter({
|
||||
conversation: conversation
|
||||
});
|
||||
|
||||
conversation.setReady(fakeSessionData);
|
||||
|
||||
@ -143,40 +146,12 @@ describe("loop.webapp", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Router", function() {
|
||||
var router, conversation;
|
||||
|
||||
beforeEach(function() {
|
||||
conversation = new loop.shared.models.ConversationModel({
|
||||
loopToken: "fake"
|
||||
});
|
||||
router = new loop.webapp.Router({conversation: conversation});
|
||||
});
|
||||
|
||||
describe("#constructor", function() {
|
||||
it("should define a default active view", function() {
|
||||
expect(router.activeView).to.be.an.instanceOf(loop.webapp.HomeView);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#loadView", function() {
|
||||
it("should set the active view", function() {
|
||||
router.loadView(new loop.webapp.ConversationFormView({
|
||||
model: conversation
|
||||
}));
|
||||
|
||||
expect(router.activeView).to.be.an.instanceOf(
|
||||
loop.webapp.ConversationFormView);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("ConversationFormView", function() {
|
||||
describe("#initiate", function() {
|
||||
var conversation, initiate, view, fakeSubmitEvent;
|
||||
|
||||
beforeEach(function() {
|
||||
conversation = new loop.shared.models.ConversationModel();
|
||||
conversation = new sharedModels.ConversationModel();
|
||||
view = new loop.webapp.ConversationFormView({model: conversation});
|
||||
fakeSubmitEvent = {preventDefault: sinon.spy()};
|
||||
});
|
Loading…
Reference in New Issue
Block a user