Lots of work on tests

This commit is contained in:
Robin Ward 2014-07-30 18:56:01 -04:00
parent b6684e7168
commit 6f36d5996d
43 changed files with 248 additions and 311 deletions

View File

@ -12,7 +12,10 @@
"bootbox", "bootbox",
"module", "module",
"moduleFor", "moduleFor",
"moduleForComponent",
"sandbox",
"integration", "integration",
"controllerFor",
"test", "test",
"ok", "ok",
"not", "not",
@ -39,10 +42,6 @@
"start", "start",
"_", "_",
"alert", "alert",
"controllerFor",
"viewClassFor",
"componentClassFor",
"testController",
"containsInstance", "containsInstance",
"parseHTML", "parseHTML",
"deepEqual", "deepEqual",

View File

@ -32,7 +32,7 @@ test("save", function() {
controller = this.subject({ model: [badge, otherBadge] }); controller = this.subject({ model: [badge, otherBadge] });
controller.send('selectBadge', badge); controller.send('selectBadge', badge);
sinon.stub(badge, "save").returns(Ember.RSVP.resolve({})); sandbox.stub(badge, "save").returns(Ember.RSVP.resolve({}));
controller.send("save"); controller.send("save");
ok(badge.save.calledOnce, "called save on the badge"); ok(badge.save.calledOnce, "called save on the badge");
}); });
@ -42,7 +42,7 @@ test("destroy", function() {
otherBadge = Discourse.Badge.create({id: 102, name: "Other Badge"}), otherBadge = Discourse.Badge.create({id: 102, name: "Other Badge"}),
controller = this.subject({model: [badge, otherBadge]}); controller = this.subject({model: [badge, otherBadge]});
sinon.stub(badge, 'destroy').returns(Ember.RSVP.resolve({})); sandbox.stub(badge, 'destroy').returns(Ember.RSVP.resolve({}));
bootbox.confirm = function(text, yes, no, func) { bootbox.confirm = function(text, yes, no, func) {
func(false); func(false);

View File

@ -2,7 +2,7 @@ module("Discourse.AdminUser");
asyncTestDiscourse('generate key', function() { asyncTestDiscourse('generate key', function() {
this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {id: 1234, key: 'asdfasdf'}})); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {id: 1234, key: 'asdfasdf'}}));
var adminUser = Discourse.AdminUser.create({id: 333}); var adminUser = Discourse.AdminUser.create({id: 333});
@ -19,7 +19,7 @@ asyncTestDiscourse('revoke key', function() {
var apiKey = Discourse.ApiKey.create({id: 1234, key: 'asdfasdf'}), var apiKey = Discourse.ApiKey.create({id: 1234, key: 'asdfasdf'}),
adminUser = Discourse.AdminUser.create({id: 333, api_key: apiKey}); adminUser = Discourse.AdminUser.create({id: 333, api_key: apiKey});
this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve()); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve());
equal(adminUser.get('api_key'), apiKey, 'it has the api key in the beginning'); equal(adminUser.get('api_key'), apiKey, 'it has the api key in the beginning');
adminUser.revokeApiKey().then(function() { adminUser.revokeApiKey().then(function() {
@ -27,4 +27,4 @@ asyncTestDiscourse('revoke key', function() {
ok(Discourse.ajax.calledWith("/admin/users/333/revoke_api_key", { type: 'DELETE' }), "it DELETEd to the url"); ok(Discourse.ajax.calledWith("/admin/users/333/revoke_api_key", { type: 'DELETE' }), "it DELETEd to the url");
blank(adminUser.get('api_key'), 'it cleared the api_key'); blank(adminUser.get('api_key'), 'it cleared the api_key');
}); });
}); });

View File

@ -9,7 +9,7 @@ test('create', function() {
asyncTestDiscourse('find', function() { asyncTestDiscourse('find', function() {
this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve([])); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve([]));
Discourse.ApiKey.find().then(function() { Discourse.ApiKey.find().then(function() {
start(); start();
ok(Discourse.ajax.calledWith("/admin/api"), "it GETs the keys"); ok(Discourse.ajax.calledWith("/admin/api"), "it GETs the keys");
@ -17,7 +17,7 @@ asyncTestDiscourse('find', function() {
}); });
asyncTestDiscourse('generateMasterKey', function() { asyncTestDiscourse('generateMasterKey', function() {
this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {}})); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {}}));
Discourse.ApiKey.generateMasterKey().then(function() { Discourse.ApiKey.generateMasterKey().then(function() {
start(); start();
ok(Discourse.ajax.calledWith("/admin/api/key", {type: 'POST'}), "it POSTs to create a master key"); ok(Discourse.ajax.calledWith("/admin/api/key", {type: 'POST'}), "it POSTs to create a master key");
@ -27,7 +27,7 @@ asyncTestDiscourse('generateMasterKey', function() {
asyncTestDiscourse('regenerate', function() { asyncTestDiscourse('regenerate', function() {
var apiKey = Discourse.ApiKey.create({id: 3456}); var apiKey = Discourse.ApiKey.create({id: 3456});
this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {id: 3456}})); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({api_key: {id: 3456}}));
apiKey.regenerate().then(function() { apiKey.regenerate().then(function() {
start(); start();
ok(Discourse.ajax.calledWith("/admin/api/key", {type: 'PUT', data: {id: 3456}}), "it PUTs the key"); ok(Discourse.ajax.calledWith("/admin/api/key", {type: 'PUT', data: {id: 3456}}), "it PUTs the key");
@ -37,9 +37,9 @@ asyncTestDiscourse('regenerate', function() {
asyncTestDiscourse('revoke', function() { asyncTestDiscourse('revoke', function() {
var apiKey = Discourse.ApiKey.create({id: 3456}); var apiKey = Discourse.ApiKey.create({id: 3456});
this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve([])); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve([]));
apiKey.revoke().then(function() { apiKey.revoke().then(function() {
start(); start();
ok(Discourse.ajax.calledWith("/admin/api/key", {type: 'DELETE', data: {id: 3456}}), "it DELETES the key"); ok(Discourse.ajax.calledWith("/admin/api/key", {type: 'DELETE', data: {id: 3456}}), "it DELETES the key");
}); });
}); });

View File

@ -1,7 +1,7 @@
module("Discourse.FlaggedPost"); module("Discourse.FlaggedPost");
test('delete first post', function() { test('delete first post', function() {
this.stub(Discourse, 'ajax'); sandbox.stub(Discourse, 'ajax');
Discourse.FlaggedPost.create({ id: 1, topic_id: 2, post_number: 1 }) Discourse.FlaggedPost.create({ id: 1, topic_id: 2, post_number: 1 })
.deletePost(); .deletePost();
@ -10,7 +10,7 @@ test('delete first post', function() {
}); });
test('delete second post', function() { test('delete second post', function() {
this.stub(Discourse, 'ajax'); sandbox.stub(Discourse, 'ajax');
Discourse.FlaggedPost.create({ id: 1, topic_id: 2, post_number: 2 }) Discourse.FlaggedPost.create({ id: 1, topic_id: 2, post_number: 2 })
.deletePost(); .deletePost();

View File

@ -48,6 +48,7 @@ module("Discourse.HomeLogoComponent", {
teardown: function() { teardown: function() {
Discourse.Mobile.mobileView = oldMobileView; Discourse.Mobile.mobileView = oldMobileView;
Discourse.reset();
} }
}); });

View File

@ -1,11 +1,13 @@
var testMouseTrap;
module("Discourse.KeyboardShortcuts", { module("Discourse.KeyboardShortcuts", {
setup: function() { setup: function() {
this.testMouseTrap = { var _bindings = {};
bindings: {},
testMouseTrap = {
bind: function(bindings, callback) { bind: function(bindings, callback) {
var registerBinding = _.bind(function(binding) { var registerBinding = _.bind(function(binding) {
this.bindings[binding] = callback; _bindings[binding] = callback;
}, this); }, this);
if (_.isArray(bindings)) { if (_.isArray(bindings)) {
@ -17,11 +19,11 @@ module("Discourse.KeyboardShortcuts", {
}, },
trigger: function(binding) { trigger: function(binding) {
this.bindings[binding].call(); _bindings[binding].call();
} }
}; };
sinon.stub(Discourse.URL, "routeTo"); sandbox.stub(Discourse.URL, "routeTo");
$("#qunit-fixture").html([ $("#qunit-fixture").html([
"<article class='topic-post selected'>", "<article class='topic-post selected'>",
@ -54,8 +56,6 @@ module("Discourse.KeyboardShortcuts", {
teardown: function() { teardown: function() {
$("#qunit-scratch").html(""); $("#qunit-scratch").html("");
Discourse.URL.routeTo.restore();
} }
}); });
@ -65,8 +65,8 @@ _.each(pathBindings, function(path, binding) {
var testName = binding + " goes to " + path; var testName = binding + " goes to " + path;
test(testName, function() { test(testName, function() {
Discourse.KeyboardShortcuts.bindEvents(this.testMouseTrap); Discourse.KeyboardShortcuts.bindEvents(testMouseTrap);
this.testMouseTrap.trigger(binding); testMouseTrap.trigger(binding);
ok(Discourse.URL.routeTo.calledWith(path)); ok(Discourse.URL.routeTo.calledWith(path));
}); });
@ -79,14 +79,14 @@ _.each(clickBindings, function(selector, binding) {
var testName = binding + " clicks on " + selector; var testName = binding + " clicks on " + selector;
test(testName, bindings.length, function() { test(testName, function() {
Discourse.KeyboardShortcuts.bindEvents(this.testMouseTrap); Discourse.KeyboardShortcuts.bindEvents(testMouseTrap);
$(selector).on("click", function() { $(selector).on("click", function() {
ok(true, selector + " was clicked"); ok(true, selector + " was clicked");
}); });
_.each(bindings, function(binding) { _.each(bindings, function(binding) {
this.testMouseTrap.trigger(binding); testMouseTrap.trigger(binding);
}, this); }, this);
}); });
}); });
@ -97,55 +97,49 @@ _.each(functionBindings, function(func, binding) {
var testName = binding + " calls " + func; var testName = binding + " calls " + func;
test(testName, function() { test(testName, function() {
var stub = sinon.stub(Discourse.KeyboardShortcuts, func, function() { sandbox.stub(Discourse.KeyboardShortcuts, func, function() {
ok(true, func + " is called when " + binding + " is triggered"); ok(true, func + " is called when " + binding + " is triggered");
}); });
Discourse.KeyboardShortcuts.bindEvents(this.testMouseTrap); Discourse.KeyboardShortcuts.bindEvents(testMouseTrap);
this.testMouseTrap.trigger(binding); testMouseTrap.trigger(binding);
stub.restore();
}); });
}); });
test("selectDown calls _moveSelection with 1", function() { test("selectDown calls _moveSelection with 1", function() {
var spy = sinon.spy(Discourse.KeyboardShortcuts, '_moveSelection'); var spy = sandbox.spy(Discourse.KeyboardShortcuts, '_moveSelection');
Discourse.KeyboardShortcuts.selectDown(); Discourse.KeyboardShortcuts.selectDown();
ok(spy.calledWith(1), "_moveSelection is called with 1"); ok(spy.calledWith(1), "_moveSelection is called with 1");
spy.restore();
}); });
test("selectUp calls _moveSelection with -1", function() { test("selectUp calls _moveSelection with -1", function() {
var spy = sinon.spy(Discourse.KeyboardShortcuts, '_moveSelection'); var spy = sandbox.spy(Discourse.KeyboardShortcuts, '_moveSelection');
Discourse.KeyboardShortcuts.selectUp(); Discourse.KeyboardShortcuts.selectUp();
ok(spy.calledWith(-1), "_moveSelection is called with -1"); ok(spy.calledWith(-1), "_moveSelection is called with -1");
spy.restore();
}); });
test("goBack calls history.back", function() { test("goBack calls history.back", function() {
var called = false, var called = false;
stub = sinon.stub(history, 'back', function() { sandbox.stub(history, 'back', function() {
called = true; called = true;
}); });
Discourse.KeyboardShortcuts.goBack(); Discourse.KeyboardShortcuts.goBack();
ok(called, "history.back is called"); ok(called, "history.back is called");
stub.restore();
}); });
test("nextSection calls _changeSection with 1", function() { test("nextSection calls _changeSection with 1", function() {
var spy = sinon.spy(Discourse.KeyboardShortcuts, '_changeSection'); var spy = sandbox.spy(Discourse.KeyboardShortcuts, '_changeSection');
Discourse.KeyboardShortcuts.nextSection(); Discourse.KeyboardShortcuts.nextSection();
ok(spy.calledWith(1), "_changeSection is called with 1"); ok(spy.calledWith(1), "_changeSection is called with 1");
spy.restore();
}); });
test("prevSection calls _changeSection with -1", function() { test("prevSection calls _changeSection with -1", function() {
var spy = sinon.spy(Discourse.KeyboardShortcuts, '_changeSection'); var spy = sandbox.spy(Discourse.KeyboardShortcuts, '_changeSection');
Discourse.KeyboardShortcuts.prevSection(); Discourse.KeyboardShortcuts.prevSection();
ok(spy.calledWith(-1), "_changeSection is called with -1"); ok(spy.calledWith(-1), "_changeSection is called with -1");
spy.restore();
}); });

View File

@ -13,43 +13,44 @@ var buildAdminUser = function(args) {
}, args || {})); }, args || {}));
}; };
moduleFor("controller:flag"); moduleFor("controller:flag", "controller:flag", {
needs: ['controller:modal']
});
test("canDeleteSpammer not staff", function(){ test("canDeleteSpammer not staff", function(){
var flagController = controllerFor('flag', buildPost()); var flagController = this.subject({ model: buildPost() });
this.stub(Discourse.User, 'currentProp').withArgs('staff').returns(false); sandbox.stub(Discourse.User, 'currentProp').withArgs('staff').returns(false);
flagController.set('selected', Discourse.PostActionType.create({name_key: 'spam'})); flagController.set('selected', Discourse.PostActionType.create({name_key: 'spam'}));
equal(flagController.get('canDeleteSpammer'), false, 'false if current user is not staff'); equal(flagController.get('canDeleteSpammer'), false, 'false if current user is not staff');
}); });
var canDeleteSpammer = function(test, postActionType, expected, testName) { var canDeleteSpammer = function(flagController, postActionType, expected, testName) {
test.flagController.set('selected', Discourse.PostActionType.create({name_key: postActionType})); flagController.set('selected', Discourse.PostActionType.create({name_key: postActionType}));
equal(test.flagController.get('canDeleteSpammer'), expected, testName); equal(flagController.get('canDeleteSpammer'), expected, testName);
}; };
test("canDeleteSpammer spam not selected", function(){ test("canDeleteSpammer spam not selected", function(){
this.stub(Discourse.User, 'currentProp').withArgs('staff').returns(true); sandbox.stub(Discourse.User, 'currentProp').withArgs('staff').returns(true);
this.flagController = controllerFor('flag', buildPost()); var flagController = this.subject({ model: buildPost() });
this.flagController.set('userDetails', buildAdminUser({can_delete_all_posts: true, can_be_deleted: true})); flagController.set('userDetails', buildAdminUser({can_delete_all_posts: true, can_be_deleted: true}));
canDeleteSpammer(this, 'off_topic', false, 'false if current user is staff, but selected is off_topic'); canDeleteSpammer(flagController, 'off_topic', false, 'false if current user is staff, but selected is off_topic');
canDeleteSpammer(this, 'inappropriate', false, 'false if current user is staff, but selected is inappropriate'); canDeleteSpammer(flagController, 'inappropriate', false, 'false if current user is staff, but selected is inappropriate');
canDeleteSpammer(this, 'notify_user', false, 'false if current user is staff, but selected is notify_user'); canDeleteSpammer(flagController, 'notify_user', false, 'false if current user is staff, but selected is notify_user');
canDeleteSpammer(this, 'notify_moderators', false, 'false if current user is staff, but selected is notify_moderators'); canDeleteSpammer(flagController, 'notify_moderators', false, 'false if current user is staff, but selected is notify_moderators');
}); });
test("canDeleteSpammer spam selected", function(){ test("canDeleteSpammer spam selected", function(){
this.stub(Discourse.User, 'currentProp').withArgs('staff').returns(true); sandbox.stub(Discourse.User, 'currentProp').withArgs('staff').returns(true);
this.flagController = controllerFor('flag', buildPost()); var flagController = this.subject({ model: buildPost() });
flagController.set('userDetails', buildAdminUser({can_delete_all_posts: true, can_be_deleted: true}));
canDeleteSpammer(flagController, 'spam', true, 'true if current user is staff, selected is spam, posts and user can be deleted');
this.flagController.set('userDetails', buildAdminUser({can_delete_all_posts: true, can_be_deleted: true})); flagController.set('userDetails', buildAdminUser({can_delete_all_posts: false, can_be_deleted: true}));
canDeleteSpammer(this, 'spam', true, 'true if current user is staff, selected is spam, posts and user can be deleted'); canDeleteSpammer(flagController, 'spam', false, 'false if current user is staff, selected is spam, posts cannot be deleted');
this.flagController.set('userDetails', buildAdminUser({can_delete_all_posts: false, can_be_deleted: true})); flagController.set('userDetails', buildAdminUser({can_delete_all_posts: true, can_be_deleted: false}));
canDeleteSpammer(this, 'spam', false, 'false if current user is staff, selected is spam, posts cannot be deleted'); canDeleteSpammer(flagController, 'spam', false, 'false if current user is staff, selected is spam, user cannot be deleted');
this.flagController.set('userDetails', buildAdminUser({can_delete_all_posts: true, can_be_deleted: false})); flagController.set('userDetails', buildAdminUser({can_delete_all_posts: false, can_be_deleted: false}));
canDeleteSpammer(this, 'spam', false, 'false if current user is staff, selected is spam, user cannot be deleted'); canDeleteSpammer(flagController, 'spam', false, 'false if current user is staff, selected is spam, user cannot be deleted');
this.flagController.set('userDetails', buildAdminUser({can_delete_all_posts: false, can_be_deleted: false}));
canDeleteSpammer(this, 'spam', false, 'false if current user is staff, selected is spam, user cannot be deleted');
}); });

View File

@ -1,4 +1,4 @@
module("controller:header", "Header Controller"); moduleFor("controller:header", "controller:header");
test("showNotifications action", function() { test("showNotifications action", function() {
var resolveRequestWith; var resolveRequestWith;
@ -6,17 +6,15 @@ test("showNotifications action", function() {
resolveRequestWith = resolve; resolveRequestWith = resolve;
}); });
var controller = this.subject();
var controller = controllerFor('header');
var viewSpy = { var viewSpy = {
showDropdownBySelector: sinon.spy() showDropdownBySelector: sinon.spy()
}; };
this.stub(Discourse, "ajax").withArgs("/notifications").returns(request); sandbox.stub(Discourse, "ajax").withArgs("/notifications").returns(request);
this.stub(Discourse.User, "current").returns(Discourse.User.create({ sandbox.stub(Discourse.User, "current").returns(Discourse.User.create({
unread_notifications: 1 unread_notifications: 1
})); }));
Ember.run(function() { Ember.run(function() {
controller.send("showNotifications", viewSpy); controller.send("showNotifications", viewSpy);
}); });
@ -25,7 +23,6 @@ test("showNotifications action", function() {
equal(Discourse.User.current().get("unread_notifications"), 1, "current user's unread notifications count is not zeroed before data has finished loading"); equal(Discourse.User.current().get("unread_notifications"), 1, "current user's unread notifications count is not zeroed before data has finished loading");
ok(viewSpy.showDropdownBySelector.calledWith("#user-notifications"), "dropdown with loading glyph is shown before data has finished loading"); ok(viewSpy.showDropdownBySelector.calledWith("#user-notifications"), "dropdown with loading glyph is shown before data has finished loading");
Ember.run(function() { Ember.run(function() {
resolveRequestWith(["notification"]); resolveRequestWith(["notification"]);
}); });

View File

@ -1,25 +1,16 @@
var controller, searcherStub; var searcherStub;
module("controller:search", { moduleFor("controller:search", "controller:search", {
setup: function() { setup: function() {
Discourse.SiteSettings.min_search_term_length = 2; Discourse.SiteSettings.min_search_term_length = 2;
// cancels debouncing behavior (calls the debounced function immediately)
sinon.stub(Ember.run, "debounce").callsArg(1);
searcherStub = Ember.Deferred.create(); searcherStub = Ember.Deferred.create();
sinon.stub(Discourse.Search, "forTerm").returns(searcherStub); sandbox.stub(Discourse.Search, "forTerm").returns(searcherStub);
controller = testController('search', []);
},
teardown: function() {
Ember.run.debounce.restore();
Discourse.Search.forTerm.restore();
} }
}); });
test("when no search term is typed yet", function() { test("when no search term is typed yet", function() {
var controller = this.subject();
ok(!controller.get("loading"), "loading flag is false"); ok(!controller.get("loading"), "loading flag is false");
ok(!controller.get("noResults"), "noResults flag is false"); ok(!controller.get("noResults"), "noResults flag is false");
deepEqual(controller.get("content"), [], "content is empty"); deepEqual(controller.get("content"), [], "content is empty");
@ -28,9 +19,8 @@ test("when no search term is typed yet", function() {
}); });
test("when user started typing a search term but did not reach the minimum character count threshold yet", function() { test("when user started typing a search term but did not reach the minimum character count threshold yet", function() {
Ember.run(function() { var controller = this.subject();
controller.set("term", "a"); controller.set("term", "a");
});
ok(!controller.get("loading"), "loading flag is false"); ok(!controller.get("loading"), "loading flag is false");
ok(!controller.get("noResults"), "noResults flag is false"); ok(!controller.get("noResults"), "noResults flag is false");
@ -40,10 +30,8 @@ test("when user started typing a search term but did not reach the minimum chara
}); });
test("when user typed a search term that is equal to or exceeds the minimum character count threshold, but results have not yet finished loading", function() { test("when user typed a search term that is equal to or exceeds the minimum character count threshold, but results have not yet finished loading", function() {
Ember.run(function() { var controller = this.subject();
controller.set("term", "ab"); controller.set("term", "ab");
});
ok(controller.get("loading"), "loading flag is true"); ok(controller.get("loading"), "loading flag is true");
ok(!controller.get("noResults"), "noResults flag is false"); ok(!controller.get("noResults"), "noResults flag is false");
deepEqual(controller.get("content"), [], "content is empty"); deepEqual(controller.get("content"), [], "content is empty");
@ -52,9 +40,10 @@ test("when user typed a search term that is equal to or exceeds the minimum char
}); });
test("when user typed a search term that is equal to or exceeds the minimum character count threshold and results have finished loading, but there are no results found", function() { test("when user typed a search term that is equal to or exceeds the minimum character count threshold and results have finished loading, but there are no results found", function() {
Ember.run(function() { var controller = this.subject();
controller.set("term", "ab"); Em.run(function() {
searcherStub.resolve([]); searcherStub.resolve([]);
controller.set("term", "ab");
}); });
ok(!controller.get("loading"), "loading flag is false"); ok(!controller.get("loading"), "loading flag is false");
@ -65,7 +54,8 @@ test("when user typed a search term that is equal to or exceeds the minimum char
}); });
test("when user typed a search term that is equal to or exceeds the minimum character count threshold and results have finished loading, and there are results found", function() { test("when user typed a search term that is equal to or exceeds the minimum character count threshold and results have finished loading, and there are results found", function() {
Ember.run(function() { var controller = this.subject();
Em.run(function() {
controller.set("term", "ab"); controller.set("term", "ab");
searcherStub.resolve([{ searcherStub.resolve([{
type: "user", type: "user",
@ -84,7 +74,8 @@ test("when user typed a search term that is equal to or exceeds the minimum char
}); });
test("starting to type a new term resets the previous search results", function() { test("starting to type a new term resets the previous search results", function() {
Ember.run(function() { var controller = this.subject();
Em.run.next(function() {
controller.set("term", "ab"); controller.set("term", "ab");
searcherStub.resolve([ searcherStub.resolve([
{ {
@ -106,7 +97,8 @@ test("starting to type a new term resets the previous search results", function(
}); });
test("search results from the server are correctly reformatted (sections are sorted, section fields are preserved, item sorting is preserved, item fields are preserved, items are globally indexed across all sections)", function() { test("search results from the server are correctly reformatted (sections are sorted, section fields are preserved, item sorting is preserved, item fields are preserved, items are globally indexed across all sections)", function() {
Ember.run(function() { var controller = this.subject();
Em.run(function() {
controller.set("term", "ab"); controller.set("term", "ab");
searcherStub.resolve([ searcherStub.resolve([
{ {
@ -165,7 +157,8 @@ test("search results from the server are correctly reformatted (sections are sor
}); });
test("keyboard navigation", function() { test("keyboard navigation", function() {
Ember.run(function() { var controller = this.subject();
Em.run(function() {
controller.set("term", "ab"); controller.set("term", "ab");
searcherStub.resolve([ searcherStub.resolve([
{ {
@ -197,8 +190,9 @@ test("keyboard navigation", function() {
}); });
test("selecting a highlighted item", function() { test("selecting a highlighted item", function() {
this.stub(Discourse.URL, "routeTo"); sandbox.stub(Discourse.URL, "routeTo");
var controller = this.subject();
Ember.run(function() { Ember.run(function() {
controller.set("term", "ab"); controller.set("term", "ab");
searcherStub.resolve([ searcherStub.resolve([
@ -233,6 +227,7 @@ test("selecting a highlighted item", function() {
}); });
test("search query / the flow of the search", function() { test("search query / the flow of the search", function() {
var controller = this.subject();
Ember.run(function() { Ember.run(function() {
controller.set("searchContext", "context"); controller.set("searchContext", "context");
controller.set("searchContextEnabled", true); controller.set("searchContextEnabled", true);
@ -279,6 +274,7 @@ test("search query / the flow of the search", function() {
}); });
test("typing new term when the results are filtered by type cancels type filter", function() { test("typing new term when the results are filtered by type cancels type filter", function() {
var controller = this.subject();
Ember.run(function() { Ember.run(function() {
controller.set("term", "ab"); controller.set("term", "ab");
controller.send("moreOfType", "topic"); controller.send("moreOfType", "topic");

View File

@ -1,13 +1,8 @@
var controller; moduleFor("controller:site-map-category");
module("controller:site-map-category", {
setup: function() {
controller = testController('site-map-category');
}
});
test("showBadges", function() { test("showBadges", function() {
this.stub(Discourse.User, "current"); sandbox.stub(Discourse.User, "current");
var controller = this.subject();
Discourse.User.current.returns(null); Discourse.User.current.returns(null);
ok(!controller.get("showBadges"), "returns false when no user is logged in"); ok(!controller.get("showBadges"), "returns false when no user is logged in");

View File

@ -1,10 +1,8 @@
var controller, oldMobileView; var oldMobileView;
module("controller:site-map", { moduleFor("controller:site-map", "controller:site-map", {
setup: function() { setup: function() {
oldMobileView = Discourse.Mobile.mobileView; oldMobileView = Discourse.Mobile.mobileView;
controller = testController('site-map');
}, },
teardown: function() { teardown: function() {
@ -13,14 +11,15 @@ module("controller:site-map", {
}); });
test("itemController", function() { test("itemController", function() {
equal(controller.get("itemController"), "site-map-category", "defaults to site-map-category"); equal(this.subject().get("itemController"), "site-map-category", "defaults to site-map-category");
}); });
test("showAdminLinks", function() { test("showAdminLinks", function() {
var currentUserStub = Ember.Object.create(); var currentUserStub = Ember.Object.create();
this.stub(Discourse.User, "current").returns(currentUserStub); sandbox.stub(Discourse.User, "current").returns(currentUserStub);
currentUserStub.set("staff", true); currentUserStub.set("staff", true);
var controller = this.subject();
equal(controller.get("showAdminLinks"), true, "is true when current user is a staff member"); equal(controller.get("showAdminLinks"), true, "is true when current user is a staff member");
currentUserStub.set("staff", false); currentUserStub.set("staff", false);
@ -29,9 +28,10 @@ test("showAdminLinks", function() {
test("flaggedPostsCount", function() { test("flaggedPostsCount", function() {
var currentUserStub = Ember.Object.create(); var currentUserStub = Ember.Object.create();
this.stub(Discourse.User, "current").returns(currentUserStub); sandbox.stub(Discourse.User, "current").returns(currentUserStub);
currentUserStub.set("site_flagged_posts_count", 5); currentUserStub.set("site_flagged_posts_count", 5);
var controller = this.subject();
equal(controller.get("flaggedPostsCount"), 5, "returns current user's flagged posts count"); equal(controller.get("flaggedPostsCount"), 5, "returns current user's flagged posts count");
currentUserStub.set("site_flagged_posts_count", 0); currentUserStub.set("site_flagged_posts_count", 0);
@ -40,46 +40,54 @@ test("flaggedPostsCount", function() {
test("faqUrl returns faq url configured in site settings if it is set", function() { test("faqUrl returns faq url configured in site settings if it is set", function() {
Discourse.SiteSettings.faq_url = "faq-url"; Discourse.SiteSettings.faq_url = "faq-url";
var controller = this.subject();
equal(controller.get("faqUrl"), "faq-url"); equal(controller.get("faqUrl"), "faq-url");
}); });
test("faqUrl returns default '/faq' url when there is no corresponding site setting set", function() { test("faqUrl returns default '/faq' url when there is no corresponding site setting set", function() {
Discourse.SiteSettings.faq_url = null; Discourse.SiteSettings.faq_url = null;
var controller = this.subject();
equal(controller.get("faqUrl"), "/faq"); equal(controller.get("faqUrl"), "/faq");
}); });
test("showMoblieToggle returns true when mobile theme is enabled in site settings", function() { test("showMoblieToggle returns true when mobile theme is enabled in site settings", function() {
Discourse.SiteSettings.enable_mobile_theme = true; Discourse.SiteSettings.enable_mobile_theme = true;
Discourse.Mobile.isMobileDevice = true; Discourse.Mobile.isMobileDevice = true;
var controller = this.subject();
equal(controller.get("showMobileToggle"), true); equal(controller.get("showMobileToggle"), true);
}); });
test("showMoblieToggle returns false when mobile theme is disabled in site settings", function() { test("showMoblieToggle returns false when mobile theme is disabled in site settings", function() {
Discourse.SiteSettings.enable_mobile_theme = false; Discourse.SiteSettings.enable_mobile_theme = false;
Discourse.Mobile.isMobileDevice = true; Discourse.Mobile.isMobileDevice = true;
var controller = this.subject();
equal(controller.get("showMobileToggle"), false); equal(controller.get("showMobileToggle"), false);
}); });
test("mobileViewLinkTextKey returns translation key for a desktop view if the current view is mobile view", function() { test("mobileViewLinkTextKey returns translation key for a desktop view if the current view is mobile view", function() {
Discourse.Mobile.mobileView = true; Discourse.Mobile.mobileView = true;
var controller = this.subject();
equal(controller.get("mobileViewLinkTextKey"), "desktop_view"); equal(controller.get("mobileViewLinkTextKey"), "desktop_view");
}); });
test("mobileViewLinkTextKey returns translation key for a mobile view if the current view is desktop view", function() { test("mobileViewLinkTextKey returns translation key for a mobile view if the current view is desktop view", function() {
Discourse.Mobile.mobileView = false; Discourse.Mobile.mobileView = false;
var controller = this.subject();
equal(controller.get("mobileViewLinkTextKey"), "mobile_view"); equal(controller.get("mobileViewLinkTextKey"), "mobile_view");
}); });
test("categories", function() { test("categories", function() {
var categoryListStub = ["category1", "category2"]; var categoryListStub = ["category1", "category2"];
this.stub(Discourse.Category, "list").returns(categoryListStub); sandbox.stub(Discourse.Category, "list").returns(categoryListStub);
var controller = this.subject();
deepEqual(controller.get("categories"), categoryListStub, "returns the list of categories"); deepEqual(controller.get("categories"), categoryListStub, "returns the list of categories");
}); });
test("toggleMobleView", function() { test("toggleMobleView", function() {
this.stub(Discourse.Mobile, "toggleMobileView"); sandbox.stub(Discourse.Mobile, "toggleMobileView");
var controller = this.subject();
controller.send("toggleMobileView"); controller.send("toggleMobileView");
ok(Discourse.Mobile.toggleMobileView.calledOnce, "switches between desktop and mobile views"); ok(Discourse.Mobile.toggleMobileView.calledOnce, "switches between desktop and mobile views");
}); });

View File

@ -1,16 +1,10 @@
var controller; moduleFor("controller:user-dropdown");
module("controller:user-dropdown", {
setup: function() {
controller = testController('user-dropdown');
}
});
test("logout action logs out the current user", function () { test("logout action logs out the current user", function () {
var logout_mock = sinon.mock(Discourse, "logout"); var logout_mock = sinon.mock(Discourse, "logout");
logout_mock.expects("logout").once(); logout_mock.expects("logout").once();
var controller = controllerFor('user-dropdown'); var controller = this.subject();
controller.send("logout"); controller.send("logout");
logout_mock.verify(); logout_mock.verify();
@ -18,9 +12,10 @@ test("logout action logs out the current user", function () {
test("showAdminLinks", function() { test("showAdminLinks", function() {
var currentUserStub = Ember.Object.create(); var currentUserStub = Ember.Object.create();
this.stub(Discourse.User, "current").returns(currentUserStub); sandbox.stub(Discourse.User, "current").returns(currentUserStub);
currentUserStub.set("staff", true); currentUserStub.set("staff", true);
var controller = this.subject();
equal(controller.get("showAdminLinks"), true, "is true when current user is a staff member"); equal(controller.get("showAdminLinks"), true, "is true when current user is a staff member");
currentUserStub.set("staff", false); currentUserStub.set("staff", false);

File diff suppressed because one or more lines are too long

View File

@ -6,4 +6,4 @@ function parseHTML(rawHtml) {
parser.parseComplete(rawHtml); parser.parseComplete(rawHtml);
return builder.dom; return builder.dom;
} }

View File

@ -1,17 +1,13 @@
/* global asyncTest, requirejs, require */ /* global asyncTest */
/* exported integration, testController, controllerFor, asyncTestDiscourse, fixture */ /* exported integration, testController, controllerFor, asyncTestDiscourse, fixture */
function integration(name, lifecycle) { function integration(name, lifecycle) {
module("Integration: " + name, { module("Integration: " + name, {
setup: function() { setup: function() {
sinon.stub(Discourse.ScrollingDOMMethods, "bindOnScroll");
sinon.stub(Discourse.ScrollingDOMMethods, "unbindOnScroll");
Ember.run(Discourse, Discourse.advanceReadiness); Ember.run(Discourse, Discourse.advanceReadiness);
if (lifecycle && lifecycle.setup) { if (lifecycle && lifecycle.setup) {
lifecycle.setup.call(this); lifecycle.setup.call(this);
} }
Discourse.reset();
}, },
teardown: function() { teardown: function() {
@ -20,8 +16,6 @@ function integration(name, lifecycle) {
} }
Discourse.reset(); Discourse.reset();
Discourse.ScrollingDOMMethods.bindOnScroll.restore();
Discourse.ScrollingDOMMethods.unbindOnScroll.restore();
} }
}); });
} }
@ -32,14 +26,6 @@ function controllerFor(controller, model) {
return controller; return controller;
} }
function viewClassFor(name) {
return Discourse.__container__.lookupFactory('view:' + name);
}
function componentClassFor(name) {
return Discourse.__container__.lookupFactory('component:' + name);
}
function asyncTestDiscourse(text, func) { function asyncTestDiscourse(text, func) {
asyncTest(text, function () { asyncTest(text, function () {
var self = this; var self = this;

View File

@ -1,7 +1,7 @@
integration("Header", { integration("Header", {
setup: function() { setup: function() {
var originalUser = Discourse.User.current(); var originalUser = Discourse.User.current();
sinon.stub(Discourse.User, "current").returns(originalUser); sandbox.stub(Discourse.User, "current").returns(originalUser);
Discourse.User.current.returns(Ember.Object.create({ Discourse.User.current.returns(Ember.Object.create({
username: 'test', username: 'test',
staff: true, staff: true,
@ -29,7 +29,7 @@ test("header", function() {
// Logo changing // Logo changing
andThen(function() { andThen(function() {
controllerFor("header").set("showExtraInfo", true); controllerFor('header').set("showExtraInfo", true);
}); });
andThen(function() { andThen(function() {

View File

@ -1,12 +1,16 @@
var windowOpen,
win,
redirectTo;
module("Discourse.ClickTrack", { module("Discourse.ClickTrack", {
setup: function() { setup: function() {
// Prevent any of these tests from navigating away // Prevent any of these tests from navigating away
this.win = {focus: function() { } }; win = {focus: function() { } };
this.redirectTo = sinon.stub(Discourse.URL, "redirectTo"); redirectTo = sandbox.stub(Discourse.URL, "redirectTo");
sinon.stub(Discourse, "ajax"); sandbox.stub(Discourse, "ajax");
this.windowOpen = sinon.stub(window, "open").returns(this.win); windowOpen = sandbox.stub(window, "open").returns(win);
sinon.stub(this.win, "focus"); sandbox.stub(win, "focus");
fixture().html([ fixture().html([
'<div id="topic" id="1337">', '<div id="topic" id="1337">',
@ -23,13 +27,6 @@ module("Discourse.ClickTrack", {
' <a class="attachment" href="http://discuss.domain.com/uploads/default/1234/1532357280.txt">log.txt</a>', ' <a class="attachment" href="http://discuss.domain.com/uploads/default/1234/1532357280.txt">log.txt</a>',
' </article>', ' </article>',
'</div>'].join("\n")); '</div>'].join("\n"));
},
teardown: function() {
Discourse.URL.redirectTo.restore();
Discourse.ajax.restore();
window.open.restore();
this.win.focus.restore();
} }
}); });
@ -42,14 +39,14 @@ var generateClickEventOn = function(selector) {
test("does not track clicks on lightboxes", function() { test("does not track clicks on lightboxes", function() {
var clickEvent = generateClickEventOn('.lightbox'); var clickEvent = generateClickEventOn('.lightbox');
this.stub(clickEvent, "preventDefault"); sandbox.stub(clickEvent, "preventDefault");
ok(track(clickEvent)); ok(track(clickEvent));
ok(!clickEvent.preventDefault.calledOnce); ok(!clickEvent.preventDefault.calledOnce);
}); });
test("it calls preventDefault when clicking on an a", function() { test("it calls preventDefault when clicking on an a", function() {
var clickEvent = generateClickEventOn('a'); var clickEvent = generateClickEventOn('a');
this.stub(clickEvent, "preventDefault"); sandbox.stub(clickEvent, "preventDefault");
track(clickEvent); track(clickEvent);
ok(clickEvent.preventDefault.calledOnce); ok(clickEvent.preventDefault.calledOnce);
ok(Discourse.URL.redirectTo.calledOnce); ok(Discourse.URL.redirectTo.calledOnce);
@ -82,12 +79,12 @@ var badgeClickCount = function(id, expected) {
}; };
test("does not update badge clicks on my own link", function() { test("does not update badge clicks on my own link", function() {
this.stub(Discourse.User, 'currentProp').withArgs('id').returns(314); sandbox.stub(Discourse.User, 'currentProp').withArgs('id').returns(314);
badgeClickCount('with-badge', 1); badgeClickCount('with-badge', 1);
}); });
test("does not update badge clicks in my own post", function() { test("does not update badge clicks in my own post", function() {
this.stub(Discourse.User, 'currentProp').withArgs('id').returns(3141); sandbox.stub(Discourse.User, 'currentProp').withArgs('id').returns(3141);
badgeClickCount('with-badge-but-not-mine', 1); badgeClickCount('with-badge-but-not-mine', 1);
}); });
@ -117,7 +114,7 @@ test("right clicks are tracked", function() {
test("preventDefault is not called for right clicks", function() { test("preventDefault is not called for right clicks", function() {
var clickEvent = generateClickEventOn('a'); var clickEvent = generateClickEventOn('a');
clickEvent.which = 3; clickEvent.which = 3;
this.stub(clickEvent, "preventDefault"); sandbox.stub(clickEvent, "preventDefault");
ok(track(clickEvent)); ok(track(clickEvent));
ok(!clickEvent.preventDefault.calledOnce); ok(!clickEvent.preventDefault.calledOnce);
}); });
@ -126,7 +123,7 @@ var testOpenInANewTab = function(description, clickEventModifier) {
test(description, function() { test(description, function() {
var clickEvent = generateClickEventOn('a'); var clickEvent = generateClickEventOn('a');
clickEventModifier(clickEvent); clickEventModifier(clickEvent);
this.stub(clickEvent, "preventDefault"); sandbox.stub(clickEvent, "preventDefault");
ok(track(clickEvent)); ok(track(clickEvent));
ok(Discourse.ajax.calledOnce); ok(Discourse.ajax.calledOnce);
ok(!clickEvent.preventDefault.calledOnce); ok(!clickEvent.preventDefault.calledOnce);
@ -150,8 +147,8 @@ testOpenInANewTab("it opens in a new tab on middle click", function(clickEvent)
}); });
test("tracks via AJAX if we're on the same site", function() { test("tracks via AJAX if we're on the same site", function() {
this.stub(Discourse.URL, "routeTo"); sandbox.stub(Discourse.URL, "routeTo");
this.stub(Discourse.URL, "origin").returns("http://discuss.domain.com"); sandbox.stub(Discourse.URL, "origin").returns("http://discuss.domain.com");
ok(!track(generateClickEventOn('#same-site'))); ok(!track(generateClickEventOn('#same-site')));
ok(Discourse.ajax.calledOnce); ok(Discourse.ajax.calledOnce);
@ -159,8 +156,8 @@ test("tracks via AJAX if we're on the same site", function() {
}); });
test("does not track via AJAX for attachments", function() { test("does not track via AJAX for attachments", function() {
this.stub(Discourse.URL, "routeTo"); sandbox.stub(Discourse.URL, "routeTo");
this.stub(Discourse.URL, "origin").returns("http://discuss.domain.com"); sandbox.stub(Discourse.URL, "origin").returns("http://discuss.domain.com");
ok(!track(generateClickEventOn('.attachment'))); ok(!track(generateClickEventOn('.attachment')));
ok(Discourse.URL.redirectTo.calledOnce); ok(Discourse.URL.redirectTo.calledOnce);
@ -168,13 +165,13 @@ test("does not track via AJAX for attachments", function() {
test("tracks custom urls when opening in another window", function() { test("tracks custom urls when opening in another window", function() {
var clickEvent = generateClickEventOn('a'); var clickEvent = generateClickEventOn('a');
this.stub(Discourse.User, "currentProp").withArgs('external_links_in_new_tab').returns(true); sandbox.stub(Discourse.User, "currentProp").withArgs('external_links_in_new_tab').returns(true);
ok(!track(clickEvent)); ok(!track(clickEvent));
ok(this.windowOpen.calledWith('/clicks/track?url=http%3A%2F%2Fwww.google.com&post_id=42', '_blank')); ok(windowOpen.calledWith('/clicks/track?url=http%3A%2F%2Fwww.google.com&post_id=42', '_blank'));
}); });
test("tracks custom urls when opening in another window", function() { test("tracks custom urls when opening in another window", function() {
var clickEvent = generateClickEventOn('a'); var clickEvent = generateClickEventOn('a');
ok(!track(clickEvent)); ok(!track(clickEvent));
ok(this.redirectTo.calledWith('/clicks/track?url=http%3A%2F%2Fwww.google.com&post_id=42')); ok(redirectTo.calledWith('/clicks/track?url=http%3A%2F%2Fwww.google.com&post_id=42'));
}); });

View File

@ -1,6 +1,6 @@
module("Discourse.Computed", { module("Discourse.Computed", {
setup: function() { setup: function() {
sinon.stub(I18n, "t", function(scope) { sandbox.stub(I18n, "t", function(scope) {
return "%@ translated: " + scope; return "%@ translated: " + scope;
}); });
}, },

View File

@ -35,7 +35,7 @@ test("undefined color", function() {
test("allowUncategorized", function() { test("allowUncategorized", function() {
var uncategorized = Discourse.Category.create({name: 'uncategorized', id: 345}); var uncategorized = Discourse.Category.create({name: 'uncategorized', id: 345});
this.stub(Discourse.Site, 'currentProp').withArgs('uncategorized_category_id').returns(345); sandbox.stub(Discourse.Site, 'currentProp').withArgs('uncategorized_category_id').returns(345);
blank(html.categoryBadge(uncategorized), "it doesn't return HTML for uncategorized by default"); blank(html.categoryBadge(uncategorized), "it doesn't return HTML for uncategorized by default");
present(html.categoryBadge(uncategorized, {allowUncategorized: true}), "it returns HTML"); present(html.categoryBadge(uncategorized, {allowUncategorized: true}), "it returns HTML");

View File

@ -5,7 +5,7 @@ module("Discourse.Onebox", {
}); });
asyncTestDiscourse("Stops rapid calls with cache true", function() { asyncTestDiscourse("Stops rapid calls with cache true", function() {
this.stub(Discourse, "ajax").returns(Ember.RSVP.resolve()); sandbox.stub(Discourse, "ajax").returns(Ember.RSVP.resolve());
Discourse.Onebox.load(this.anchor, true); Discourse.Onebox.load(this.anchor, true);
Discourse.Onebox.load(this.anchor, true); Discourse.Onebox.load(this.anchor, true);
@ -14,7 +14,7 @@ asyncTestDiscourse("Stops rapid calls with cache true", function() {
}); });
asyncTestDiscourse("Stops rapid calls with cache true", function() { asyncTestDiscourse("Stops rapid calls with cache true", function() {
this.stub(Discourse, "ajax").returns(Ember.RSVP.resolve()); sandbox.stub(Discourse, "ajax").returns(Ember.RSVP.resolve());
Discourse.Onebox.load(this.anchor, false); Discourse.Onebox.load(this.anchor, false);
Discourse.Onebox.load(this.anchor, false); Discourse.Onebox.load(this.anchor, false);

View File

@ -1,7 +1,7 @@
module("Discourse.URL"); module("Discourse.URL");
test("isInternal with a HTTP url", function() { test("isInternal with a HTTP url", function() {
this.stub(Discourse.URL, "origin").returns("http://eviltrout.com"); sandbox.stub(Discourse.URL, "origin").returns("http://eviltrout.com");
not(Discourse.URL.isInternal(null), "a blank URL is not internal"); not(Discourse.URL.isInternal(null), "a blank URL is not internal");
ok(Discourse.URL.isInternal("/test"), "relative URLs are internal"); ok(Discourse.URL.isInternal("/test"), "relative URLs are internal");
@ -11,7 +11,7 @@ test("isInternal with a HTTP url", function() {
}); });
test("isInternal with a HTTPS url", function() { test("isInternal with a HTTPS url", function() {
this.stub(Discourse.URL, "origin").returns("https://eviltrout.com"); sandbox.stub(Discourse.URL, "origin").returns("https://eviltrout.com");
ok(Discourse.URL.isInternal("http://eviltrout.com/monocle"), "HTTPS urls match HTTP urls"); ok(Discourse.URL.isInternal("http://eviltrout.com/monocle"), "HTTPS urls match HTTP urls");
}); });
@ -20,7 +20,7 @@ test("isInternal with a HTTPS url", function() {
// -------------------------------------------- // --------------------------------------------
// test("routeTo", function() { // test("routeTo", function() {
// this.stub(Discourse.URL, "handleURL", function (path) { return path === "/t/topic-title/42"; }); // sandbox.stub(Discourse.URL, "handleURL", function (path) { return path === "/t/topic-title/42"; });
// ok(Discourse.URL.routeTo("https://discourse.org/t/topic-title/42"), "can route HTTPS"); // ok(Discourse.URL.routeTo("https://discourse.org/t/topic-title/42"), "can route HTTPS");
// ok(Discourse.URL.routeTo("http://discourse.org/t/topic-title/42"), "can route HTTP"); // ok(Discourse.URL.routeTo("http://discourse.org/t/topic-title/42"), "can route HTTP");
@ -33,7 +33,7 @@ test("isInternal with a HTTPS url", function() {
// test("navigatedToHome", function() { // test("navigatedToHome", function() {
// var fakeDiscoveryController = { send: function() { return true; } }; // var fakeDiscoveryController = { send: function() { return true; } };
// var mock = sinon.mock(fakeDiscoveryController); // var mock = sinon.mock(fakeDiscoveryController);
// this.stub(Discourse.URL, "controllerFor").returns(fakeDiscoveryController); // sandbox.stub(Discourse.URL, "controllerFor").returns(fakeDiscoveryController);
// //
// mock.expects("send").withArgs('refresh').twice(); // mock.expects("send").withArgs('refresh').twice();
// ok(Discourse.URL.navigatedToHome("/", "/")); // ok(Discourse.URL.navigatedToHome("/", "/"));

View File

@ -16,7 +16,7 @@ test("validateUploadedFiles", function() {
}); });
test("uploading one file", function() { test("uploading one file", function() {
this.stub(bootbox, "alert"); sandbox.stub(bootbox, "alert");
not(validUpload([1, 2])); not(validUpload([1, 2]));
ok(bootbox.alert.calledWith(I18n.t('post.errors.too_many_uploads'))); ok(bootbox.alert.calledWith(I18n.t('post.errors.too_many_uploads')));
@ -24,7 +24,7 @@ test("uploading one file", function() {
test("new user cannot upload images", function() { test("new user cannot upload images", function() {
Discourse.SiteSettings.newuser_max_images = 0; Discourse.SiteSettings.newuser_max_images = 0;
this.stub(bootbox, "alert"); sandbox.stub(bootbox, "alert");
not(validUpload([{name: "image.png"}]), 'the upload is not valid'); not(validUpload([{name: "image.png"}]), 'the upload is not valid');
ok(bootbox.alert.calledWith(I18n.t('post.errors.image_upload_not_allowed_for_new_user')), 'the alert is called'); ok(bootbox.alert.calledWith(I18n.t('post.errors.image_upload_not_allowed_for_new_user')), 'the alert is called');
@ -32,7 +32,7 @@ test("new user cannot upload images", function() {
test("new user cannot upload attachments", function() { test("new user cannot upload attachments", function() {
Discourse.SiteSettings.newuser_max_attachments = 0; Discourse.SiteSettings.newuser_max_attachments = 0;
this.stub(bootbox, "alert"); sandbox.stub(bootbox, "alert");
not(validUpload([{name: "roman.txt"}])); not(validUpload([{name: "roman.txt"}]));
ok(bootbox.alert.calledWith(I18n.t('post.errors.attachment_upload_not_allowed_for_new_user'))); ok(bootbox.alert.calledWith(I18n.t('post.errors.attachment_upload_not_allowed_for_new_user')));
@ -41,7 +41,7 @@ test("new user cannot upload attachments", function() {
test("ensures an authorized upload", function() { test("ensures an authorized upload", function() {
var html = { name: "unauthorized.html" }; var html = { name: "unauthorized.html" };
var extensions = Discourse.SiteSettings.authorized_extensions.replace(/\|/g, ", "); var extensions = Discourse.SiteSettings.authorized_extensions.replace(/\|/g, ", ");
this.stub(bootbox, "alert"); sandbox.stub(bootbox, "alert");
not(validUpload([html])); not(validUpload([html]));
ok(bootbox.alert.calledWith(I18n.t('post.errors.upload_not_authorized', { authorized_extensions: extensions }))); ok(bootbox.alert.calledWith(I18n.t('post.errors.upload_not_authorized', { authorized_extensions: extensions })));
@ -51,7 +51,7 @@ test("prevents files that are too big from being uploaded", function() {
var image = { name: "image.png", size: 10 * 1024 }; var image = { name: "image.png", size: 10 * 1024 };
Discourse.SiteSettings.max_image_size_kb = 5; Discourse.SiteSettings.max_image_size_kb = 5;
Discourse.User.currentProp("trust_level", 1); Discourse.User.currentProp("trust_level", 1);
this.stub(bootbox, "alert"); sandbox.stub(bootbox, "alert");
not(validUpload([image])); not(validUpload([image]));
ok(bootbox.alert.calledWith(I18n.t('post.errors.image_too_large', { max_size_kb: 5 }))); ok(bootbox.alert.calledWith(I18n.t('post.errors.image_too_large', { max_size_kb: 5 })));
@ -71,7 +71,7 @@ var dummyBlob = function() {
test("allows valid uploads to go through", function() { test("allows valid uploads to go through", function() {
Discourse.User.currentProp("trust_level", 1); Discourse.User.currentProp("trust_level", 1);
Discourse.SiteSettings.max_image_size_kb = 15; Discourse.SiteSettings.max_image_size_kb = 15;
this.stub(bootbox, "alert"); sandbox.stub(bootbox, "alert");
// image // image
var image = { name: "image.png", size: 10 * 1024 }; var image = { name: "image.png", size: 10 * 1024 };

View File

@ -1,7 +1,7 @@
module("Discourse.HasCurrentUser"); module("Discourse.HasCurrentUser");
test("adds `currentUser` property to an object and ensures it is not cached", function() { test("adds `currentUser` property to an object and ensures it is not cached", function() {
this.stub(Discourse.User, "current"); sandbox.stub(Discourse.User, "current");
var testObj = Ember.Object.createWithMixins(Discourse.HasCurrentUser, {}); var testObj = Ember.Object.createWithMixins(Discourse.HasCurrentUser, {});
Discourse.User.current.returns("first user"); Discourse.User.current.returns("first user");

View File

@ -22,4 +22,4 @@ test("blank", function() {
ok(testObj.blank('emptyArray'), "Empty arrays are blank"); ok(testObj.blank('emptyArray'), "Empty arrays are blank");
ok(!testObj.blank('nonEmptyArray'), "Non empty arrays are not blank"); ok(!testObj.blank('nonEmptyArray'), "Non empty arrays are not blank");
ok(testObj.blank('missing'), "Missing properties are blank"); ok(testObj.blank('missing'), "Missing properties are blank");
}); });

View File

@ -58,4 +58,4 @@ test("createCurrent that returns null", function() {
blank(Missing.current(), "it doesn't return an instance"); blank(Missing.current(), "it doesn't return an instance");
blank(Missing.currentProp('madeup'), "it won't raise an error asking for a property. Will just return null."); blank(Missing.currentProp('madeup'), "it won't raise an error asking for a property. Will just return null.");
}); });

View File

@ -11,7 +11,7 @@ test('displayName', function() {
var badge1 = Discourse.Badge.create({id: 1, name: "Test Badge 1"}); var badge1 = Discourse.Badge.create({id: 1, name: "Test Badge 1"});
equal(badge1.get('displayName'), "Test Badge 1", "falls back to the original name in the absence of a translation"); equal(badge1.get('displayName'), "Test Badge 1", "falls back to the original name in the absence of a translation");
this.stub(I18n, "t").returnsArg(0); sandbox.stub(I18n, "t").returnsArg(0);
var badge2 = Discourse.Badge.create({id: 2, name: "Test Badge 2"}); var badge2 = Discourse.Badge.create({id: 2, name: "Test Badge 2"});
equal(badge2.get('displayName'), "badges.badge.test_badge_2.name", "uses translation when available"); equal(badge2.get('displayName'), "badges.badge.test_badge_2.name", "uses translation when available");
}); });
@ -21,7 +21,7 @@ test('translatedDescription', function() {
equal(badge1.get('translatedDescription'), null, "returns null when no translation exists"); equal(badge1.get('translatedDescription'), null, "returns null when no translation exists");
var badge2 = Discourse.Badge.create({id: 2, name: "Test Badge 2 **"}); var badge2 = Discourse.Badge.create({id: 2, name: "Test Badge 2 **"});
this.stub(I18n, "t").returns("description translation"); sandbox.stub(I18n, "t").returns("description translation");
equal(badge2.get('translatedDescription'), "description translation", "users translated description"); equal(badge2.get('translatedDescription'), "description translation", "users translated description");
}); });
@ -30,7 +30,7 @@ test('displayDescription', function() {
equal(badge1.get('displayDescription'), "TEST", "returns original description when no translation exists"); equal(badge1.get('displayDescription'), "TEST", "returns original description when no translation exists");
var badge2 = Discourse.Badge.create({id: 2, name: "Test Badge 2 **"}); var badge2 = Discourse.Badge.create({id: 2, name: "Test Badge 2 **"});
this.stub(I18n, "t").returns("description translation"); sandbox.stub(I18n, "t").returns("description translation");
equal(badge2.get('displayDescription'), "description translation", "users translated description"); equal(badge2.get('displayDescription'), "description translation", "users translated description");
}); });
@ -61,7 +61,7 @@ test('updateFromJson', function() {
}); });
test('save', function() { test('save', function() {
this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({})); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve({}));
var badge = Discourse.Badge.create({name: "New Badge", description: "This is a new badge.", badge_type_id: 1}); var badge = Discourse.Badge.create({name: "New Badge", description: "This is a new badge.", badge_type_id: 1});
// TODO: clean API // TODO: clean API
badge.save(["name", "description", "badge_type_id"]); badge.save(["name", "description", "badge_type_id"]);
@ -69,7 +69,7 @@ test('save', function() {
}); });
test('destroy', function() { test('destroy', function() {
this.stub(Discourse, 'ajax'); sandbox.stub(Discourse, 'ajax');
var badge = Discourse.Badge.create({name: "New Badge", description: "This is a new badge.", badge_type_id: 1}); var badge = Discourse.Badge.create({name: "New Badge", description: "This is a new badge.", badge_type_id: 1});
badge.destroy(); badge.destroy();
ok(!Discourse.ajax.calledOnce, "no AJAX call for a new badge"); ok(!Discourse.ajax.calledOnce, "no AJAX call for a new badge");

View File

@ -31,7 +31,7 @@ test('findBySlug', function() {
luke = Discourse.Category.create({id: 2, slug: 'luke', parentCategory: darth}), luke = Discourse.Category.create({id: 2, slug: 'luke', parentCategory: darth}),
categoryList = [darth, luke]; categoryList = [darth, luke];
this.stub(Discourse.Category, 'list').returns(categoryList); sandbox.stub(Discourse.Category, 'list').returns(categoryList);
equal(Discourse.Category.findBySlug('darth'), darth, 'we can find a parent category'); equal(Discourse.Category.findBySlug('darth'), darth, 'we can find a parent category');
equal(Discourse.Category.findBySlug('luke', 'darth'), luke, 'we can find a child with parent'); equal(Discourse.Category.findBySlug('luke', 'darth'), luke, 'we can find a child with parent');
@ -45,7 +45,7 @@ test('findByIds', function() {
2: Discourse.Category.create({id: 2}) 2: Discourse.Category.create({id: 2})
}; };
this.stub(Discourse.Category, 'idMap').returns(categories); sandbox.stub(Discourse.Category, 'idMap').returns(categories);
deepEqual(Discourse.Category.findByIds([1,2,3]), _.values(categories)); deepEqual(Discourse.Category.findByIds([1,2,3]), _.values(categories));
}); });

View File

@ -1,6 +1,6 @@
module("Discourse.Composer", { module("Discourse.Composer", {
setup: function() { setup: function() {
sinon.stub(Discourse.User, 'currentProp').withArgs('admin').returns(false); sandbox.stub(Discourse.User, 'currentProp').withArgs('admin').returns(false);
}, },
teardown: function() { teardown: function() {
@ -130,7 +130,7 @@ test("Title length for private messages", function() {
}); });
test('importQuote with no data', function() { test('importQuote with no data', function() {
this.stub(Discourse.Post, 'load'); sandbox.stub(Discourse.Post, 'load');
var composer = Discourse.Composer.create(); var composer = Discourse.Composer.create();
composer.importQuote(); composer.importQuote();
blank(composer.get('reply'), 'importing with no topic adds nothing'); blank(composer.get('reply'), 'importing with no topic adds nothing');
@ -158,7 +158,7 @@ test('editingFirstPost', function() {
asyncTestDiscourse('importQuote with a post', function() { asyncTestDiscourse('importQuote with a post', function() {
expect(1); expect(1);
this.stub(Discourse.Post, 'load').withArgs(123).returns(Em.Deferred.promise(function (p) { sandbox.stub(Discourse.Post, 'load').withArgs(123).returns(Em.Deferred.promise(function (p) {
p.resolve(Discourse.Post.create({raw: "let's quote"})); p.resolve(Discourse.Post.create({raw: "let's quote"}));
})); }));
@ -172,7 +172,7 @@ asyncTestDiscourse('importQuote with a post', function() {
asyncTestDiscourse('importQuote with no post', function() { asyncTestDiscourse('importQuote with no post', function() {
expect(1); expect(1);
this.stub(Discourse.Post, 'load').withArgs(4).returns(Em.Deferred.promise(function (p) { sandbox.stub(Discourse.Post, 'load').withArgs(4).returns(Em.Deferred.promise(function (p) {
p.resolve(Discourse.Post.create({raw: 'quote me'})); p.resolve(Discourse.Post.create({raw: 'quote me'}));
})); }));
@ -243,7 +243,7 @@ test('open with a quote', function() {
module("Discourse.Composer as admin", { module("Discourse.Composer as admin", {
setup: function() { setup: function() {
sinon.stub(Discourse.User, 'currentProp').withArgs('admin').returns(true); sandbox.stub(Discourse.User, 'currentProp').withArgs('admin').returns(true);
}, },
teardown: function() { teardown: function() {
@ -267,4 +267,4 @@ test("Title length for regular topics as admin", function() {
composer.set('title', ''); composer.set('title', '');
ok(!composer.get('titleLengthValid'), "admins must set title to at least 1 character"); ok(!composer.get('titleLengthValid'), "admins must set title to at least 1 character");
}); });

View File

@ -2,4 +2,4 @@ module("Discourse.EmailLog");
test("create", function() { test("create", function() {
ok(Discourse.EmailLog.create(), "it can be created without arguments"); ok(Discourse.EmailLog.create(), "it can be created without arguments");
}); });

View File

@ -2,4 +2,4 @@ module("Discourse.Invite");
test("create", function() { test("create", function() {
ok(Discourse.Invite.create(), "it can be created without arguments"); ok(Discourse.Invite.create(), "it can be created without arguments");
}); });

View File

@ -111,7 +111,7 @@ test("removePosts", function() {
test("cancelFilter", function() { test("cancelFilter", function() {
var postStream = buildStream(1235); var postStream = buildStream(1235);
this.stub(postStream, "refresh"); sandbox.stub(postStream, "refresh");
postStream.set('summary', true); postStream.set('summary', true);
postStream.cancelFilter(); postStream.cancelFilter();
@ -124,7 +124,7 @@ test("cancelFilter", function() {
test("toggleParticipant", function() { test("toggleParticipant", function() {
var postStream = buildStream(1236); var postStream = buildStream(1236);
this.stub(postStream, "refresh"); sandbox.stub(postStream, "refresh");
equal(postStream.get('userFilters.length'), 0, "by default no participants are toggled"); equal(postStream.get('userFilters.length'), 0, "by default no participants are toggled");
@ -137,7 +137,7 @@ test("toggleParticipant", function() {
test("streamFilters", function() { test("streamFilters", function() {
var postStream = buildStream(1237); var postStream = buildStream(1237);
this.stub(postStream, "refresh"); sandbox.stub(postStream, "refresh");
deepEqual(postStream.get('streamFilters'), {}, "there are no postFilters by default"); deepEqual(postStream.get('streamFilters'), {}, "there are no postFilters by default");
ok(postStream.get('hasNoFilters'), "there are no filters by default"); ok(postStream.get('hasNoFilters'), "there are no filters by default");
@ -254,7 +254,7 @@ asyncTestDiscourse("loadIntoIdentityMap with no data", function() {
var postStream = buildStream(1234); var postStream = buildStream(1234);
expect(1); expect(1);
this.stub(Discourse, "ajax"); sandbox.stub(Discourse, "ajax");
postStream.loadIntoIdentityMap([]).then(function() { postStream.loadIntoIdentityMap([]).then(function() {
ok(!Discourse.ajax.calledOnce, "an empty array returned a promise yet performed no ajax request"); ok(!Discourse.ajax.calledOnce, "an empty array returned a promise yet performed no ajax request");
start(); start();
@ -265,7 +265,7 @@ asyncTestDiscourse("loadIntoIdentityMap with post ids", function() {
var postStream = buildStream(1234); var postStream = buildStream(1234);
expect(1); expect(1);
this.stub(Discourse, "ajax").returns(Ember.RSVP.resolve({ sandbox.stub(Discourse, "ajax").returns(Ember.RSVP.resolve({
post_stream: { post_stream: {
posts: [{id: 10, post_number: 10}] posts: [{id: 10, post_number: 10}]
} }
@ -285,7 +285,7 @@ asyncTestDiscourse("loading a post's history", function() {
var secondPost = Discourse.Post.create({id: 2222}); var secondPost = Discourse.Post.create({id: 2222});
this.stub(Discourse, "ajax").returns(Ember.RSVP.resolve([secondPost])); sandbox.stub(Discourse, "ajax").returns(Ember.RSVP.resolve([secondPost]));
postStream.findReplyHistory(post).then(function() { postStream.findReplyHistory(post).then(function() {
ok(Discourse.ajax.calledOnce, "it made the ajax request"); ok(Discourse.ajax.calledOnce, "it made the ajax request");
present(postStream.findLoadedPost(2222), "it stores the returned post in the identity map"); present(postStream.findLoadedPost(2222), "it stores the returned post in the identity map");
@ -367,8 +367,8 @@ test("staging and committing a post", function() {
test('triggerNewPostInStream', function() { test('triggerNewPostInStream', function() {
var postStream = buildStream(225566); var postStream = buildStream(225566);
this.stub(postStream, 'appendMore'); sandbox.stub(postStream, 'appendMore');
this.stub(postStream, 'refresh'); sandbox.stub(postStream, 'refresh');
postStream.triggerNewPostInStream(null); postStream.triggerNewPostInStream(null);
ok(!postStream.appendMore.calledOnce, "asking for a null id does nothing"); ok(!postStream.appendMore.calledOnce, "asking for a null id does nothing");
@ -418,7 +418,7 @@ test("comitting and triggerNewPostInStream race condition", function() {
equal(postStream.get('filteredPostsCount'), 0, "it has no filteredPostsCount yet"); equal(postStream.get('filteredPostsCount'), 0, "it has no filteredPostsCount yet");
stagedPost.set('id', 123); stagedPost.set('id', 123);
this.stub(postStream, 'appendMore'); sandbox.stub(postStream, 'appendMore');
postStream.triggerNewPostInStream(123); postStream.triggerNewPostInStream(123);
equal(postStream.get('filteredPostsCount'), 1, "it added the post"); equal(postStream.get('filteredPostsCount'), 1, "it added the post");

View File

@ -59,7 +59,7 @@ test('destroy by staff', function() {
var user = Discourse.User.create({username: 'staff', staff: true}); var user = Discourse.User.create({username: 'staff', staff: true});
var post = buildPost({user: user}); var post = buildPost({user: user});
this.stub(Discourse, 'ajax').returns(new Em.Deferred()); sandbox.stub(Discourse, 'ajax').returns(new Em.Deferred());
post.destroy(user); post.destroy(user);
present(post.get('deleted_at'), "it has a `deleted_at` field."); present(post.get('deleted_at'), "it has a `deleted_at` field.");
@ -77,7 +77,7 @@ test('destroy by non-staff', function() {
var user = Discourse.User.create({username: 'evil trout'}); var user = Discourse.User.create({username: 'evil trout'});
var post = buildPost({user: user, cooked: originalCooked}); var post = buildPost({user: user, cooked: originalCooked});
this.stub(Discourse, 'ajax'); sandbox.stub(Discourse, 'ajax');
post.destroy(user); post.destroy(user);
ok(!post.get('can_delete'), "the post can't be deleted again in this session"); ok(!post.get('can_delete'), "the post can't be deleted again in this session");

View File

@ -3,4 +3,4 @@ module("Discourse.Session");
test('highestSeenByTopic', function() { test('highestSeenByTopic', function() {
var session = Discourse.Session.current(); var session = Discourse.Session.current();
deepEqual(session.get('highestSeenByTopic'), {}, "by default it returns an empty object"); deepEqual(session.get('highestSeenByTopic'), {}, "by default it returns an empty object");
}); });

View File

@ -36,4 +36,4 @@ test('create categories', function() {
present(subcategory, "it loaded the subcategory"); present(subcategory, "it loaded the subcategory");
equal(subcategory.get('parentCategory'), parent, "it has associated the child with the parent"); equal(subcategory.get('parentCategory'), parent, "it has associated the child with the parent");
}); });

View File

@ -2,4 +2,4 @@ module("Discourse.StaffActionLog");
test("create", function() { test("create", function() {
ok(Discourse.StaffActionLog.create(), "it can be created without arguments"); ok(Discourse.StaffActionLog.create(), "it can be created without arguments");
}); });

View File

@ -48,7 +48,7 @@ test("destroy", function() {
var user = Discourse.User.create({username: 'eviltrout'}); var user = Discourse.User.create({username: 'eviltrout'});
var topic = Discourse.Topic.create({id: 1234}); var topic = Discourse.Topic.create({id: 1234});
this.stub(Discourse, 'ajax'); sandbox.stub(Discourse, 'ajax');
topic.destroy(user); topic.destroy(user);
present(topic.get('deleted_at'), 'deleted at is set'); present(topic.get('deleted_at'), 'deleted at is set');
@ -60,10 +60,10 @@ test("recover", function() {
var user = Discourse.User.create({username: 'eviltrout'}); var user = Discourse.User.create({username: 'eviltrout'});
var topic = Discourse.Topic.create({id: 1234, deleted_at: new Date(), deleted_by: user}); var topic = Discourse.Topic.create({id: 1234, deleted_at: new Date(), deleted_by: user});
this.stub(Discourse, 'ajax'); sandbox.stub(Discourse, 'ajax');
topic.recover(); topic.recover();
blank(topic.get('deleted_at'), "it clears deleted_at"); blank(topic.get('deleted_at'), "it clears deleted_at");
blank(topic.get('deleted_by'), "it clears deleted_by"); blank(topic.get('deleted_by'), "it clears deleted_by");
//ok(Discourse.ajax.calledOnce, "it called recover over the wire"); //ok(Discourse.ajax.calledOnce, "it called recover over the wire");
}); });

View File

@ -19,7 +19,7 @@ test('createFromJson array', function() {
asyncTestDiscourse('findByUsername', function() { asyncTestDiscourse('findByUsername', function() {
expect(2); expect(2);
this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve(multipleBadgesJson)); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve(multipleBadgesJson));
Discourse.UserBadge.findByUsername("anne3").then(function(badges) { Discourse.UserBadge.findByUsername("anne3").then(function(badges) {
ok(Array.isArray(badges), "returns an array"); ok(Array.isArray(badges), "returns an array");
start(); start();
@ -29,7 +29,7 @@ asyncTestDiscourse('findByUsername', function() {
asyncTestDiscourse('findByBadgeId', function() { asyncTestDiscourse('findByBadgeId', function() {
expect(2); expect(2);
this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve(multipleBadgesJson)); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve(multipleBadgesJson));
Discourse.UserBadge.findByBadgeId(880).then(function(badges) { Discourse.UserBadge.findByBadgeId(880).then(function(badges) {
ok(Array.isArray(badges), "returns an array"); ok(Array.isArray(badges), "returns an array");
start(); start();
@ -39,7 +39,7 @@ asyncTestDiscourse('findByBadgeId', function() {
asyncTestDiscourse('grant', function() { asyncTestDiscourse('grant', function() {
expect(2); expect(2);
this.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve(singleBadgeJson)); sandbox.stub(Discourse, 'ajax').returns(Ember.RSVP.resolve(singleBadgeJson));
Discourse.UserBadge.grant(1, "username").then(function(userBadge) { Discourse.UserBadge.grant(1, "username").then(function(userBadge) {
ok(!Array.isArray(userBadge), "does not return an array"); ok(!Array.isArray(userBadge), "does not return an array");
start(); start();
@ -48,7 +48,7 @@ asyncTestDiscourse('grant', function() {
}); });
test('revoke', function() { test('revoke', function() {
this.stub(Discourse, 'ajax'); sandbox.stub(Discourse, 'ajax');
var userBadge = Discourse.UserBadge.create({id: 1}); var userBadge = Discourse.UserBadge.create({id: 1});
userBadge.revoke(); userBadge.revoke();
ok(Discourse.ajax.calledOnce, "makes an AJAX call"); ok(Discourse.ajax.calledOnce, "makes an AJAX call");

View File

@ -22,7 +22,7 @@ var categoryLinksSelector = ".category-links";
module("Template: site_map", { module("Template: site_map", {
setup: function() { setup: function() {
sinon.stub(I18n, "t", function(scope, options) { sandbox.stub(I18n, "t", function(scope, options) {
if (options) { if (options) {
if (options.count) { if (options.count) {
return [scope, options.count].join(" "); return [scope, options.count].join(" ");
@ -39,6 +39,7 @@ module("Template: site_map", {
}, },
teardown: function() { teardown: function() {
Discourse.reset();
I18n.t.restore(); I18n.t.restore();
} }
}); });
@ -91,7 +92,7 @@ test("location links part is rendered correctly", function() {
}); });
test("binds mobile theme toggle link to the correct controller action", function() { test("binds mobile theme toggle link to the correct controller action", function() {
this.stub(Ember.Handlebars.helpers, "action", function(actionName) { sandbox.stub(Ember.Handlebars.helpers, "action", function(actionName) {
return new Handlebars.SafeString('data-test-stub-action-name="' + actionName + '"'); return new Handlebars.SafeString('data-test-stub-action-name="' + actionName + '"');
}); });

View File

@ -92,16 +92,25 @@ if (window.Logster) {
window.Logster = { enabled: false }; window.Logster = { enabled: false };
} }
QUnit.testStart(function() { var origDebounce = Ember.run.debounce;
QUnit.testStart(function(ctx) {
// Allow our tests to change site settings and have them reset before the next test // Allow our tests to change site settings and have them reset before the next test
Discourse.SiteSettings = jQuery.extend(true, {}, Discourse.SiteSettingsOriginal); Discourse.SiteSettings = jQuery.extend(true, {}, Discourse.SiteSettingsOriginal);
Discourse.BaseUri = "/"; Discourse.BaseUri = "/";
Discourse.BaseUrl = ""; Discourse.BaseUrl = "";
// Never debounce in test, just makes testing harder window.sandbox = sinon.sandbox.create();
sinon.stub(Ember.run, "debounce").callsArg(1)
window.sandbox.stub(Discourse.ScrollingDOMMethods, "bindOnScroll");
window.sandbox.stub(Discourse.ScrollingDOMMethods, "unbindOnScroll");
// Don't debounce in test unless we're testing debouncing
if (ctx.module.indexOf('debounce') === -1) {
Ember.run.debounce = Ember.run;
}
}); });
QUnit.testDone(function() { QUnit.testDone(function() {
Ember.run.debounce.restore(); Ember.run.debounce = origDebounce;
window.sandbox.restore();
}); });

View File

@ -1,85 +1,88 @@
var SomeViewClass = Ember.View.extend(), var SomeViewClass = Ember.View.extend();
containerView;
function containerHasOnlyOneChild(klass) { function containerHasOnlyOneChild(containerView, klass) {
equal(containerView.get('childViews').length, 1, "container has no other children than the one created by method"); equal(containerView.get('childViews').length, 1, "container has no other children than the one created by method");
ok(containerView.objectAt(0) instanceof klass, "container's child created by method is an instance of a correct class"); ok(containerView.objectAt(0) instanceof klass, "container's child created by method is an instance of a correct class");
} }
function containerHasTwoChildren(klass1, klass2) { function containerHasTwoChildren(containerView, klass1, klass2) {
equal(containerView.get('childViews').length, 2, "container has both already existing and newly created children"); equal(containerView.get('childViews').length, 2, "container has both already existing and newly created children");
ok(containerView.objectAt(0) instanceof klass1, "already existing child's class is correct"); ok(containerView.objectAt(0) instanceof klass1, "already existing child's class is correct");
ok(containerView.objectAt(1) instanceof klass2, "newly created child's class is correct"); ok(containerView.objectAt(1) instanceof klass2, "newly created child's class is correct");
} }
var childHasProperty = function(name) { function childHasProperty(containerView, name) {
equal(containerView.objectAt(0).get(name), name, "method passes properties to the container's child it creates"); equal(containerView.objectAt(0).get(name), name, "method passes properties to the container's child it creates");
}; }
module("view:container", { moduleFor("view:container");
setup: function() {
containerView = Discourse.__container__.lookup('view:container');
}
});
test("mixes in Discourse.Presence", function() { test("mixes in Discourse.Presence", function() {
var containerView = this.subject();
ok(Discourse.Presence.detect(containerView)); ok(Discourse.Presence.detect(containerView));
}); });
test("attachViewWithArgs: creates a view of a given class with given properties and appends it to the container", function() { test("attachViewWithArgs: creates a view of a given class with given properties and appends it to the container", function() {
var containerView = this.subject();
containerView.attachViewWithArgs({foo: "foo"}, SomeViewClass); containerView.attachViewWithArgs({foo: "foo"}, SomeViewClass);
containerHasOnlyOneChild(containerView, SomeViewClass);
containerHasOnlyOneChild(SomeViewClass); childHasProperty(containerView, "foo");
childHasProperty("foo");
}); });
test("attachViewWithArgs: creates a view of a given class without any properties and appends it to the container", function() { test("attachViewWithArgs: creates a view of a given class without any properties and appends it to the container", function() {
containerView.attachViewWithArgs(null, SomeViewClass);
containerHasOnlyOneChild(SomeViewClass); var containerView = this.subject();
containerView.attachViewWithArgs(null, SomeViewClass);
containerHasOnlyOneChild(containerView, SomeViewClass);
}); });
test("attachViewWithArgs: creates a view without class specified (Ember.View is used by default) with given properties and appends it to the container", function() { test("attachViewWithArgs: creates a view without class specified (Ember.View is used by default) with given properties and appends it to the container", function() {
var containerView = this.subject();
containerView.attachViewWithArgs({foo: "foo"}); containerView.attachViewWithArgs({foo: "foo"});
containerHasOnlyOneChild(Ember.View); containerHasOnlyOneChild(containerView, Ember.View);
childHasProperty("foo"); childHasProperty(containerView, "foo");
}); });
test("attachViewWithArgs: creates a view without class specified (Ember.View is used by default) without any properties and appends it to the container", function() { test("attachViewWithArgs: creates a view without class specified (Ember.View is used by default) without any properties and appends it to the container", function() {
var containerView = this.subject();
containerView.attachViewWithArgs(); containerView.attachViewWithArgs();
containerHasOnlyOneChild(Ember.View); containerHasOnlyOneChild(containerView, Ember.View);
}); });
test("attachViewWithArgs: appends a view to a container already containing other views", function() { test("attachViewWithArgs: appends a view to a container already containing other views", function() {
var AlreadyContainedViewClass = Ember.View.extend(); var AlreadyContainedViewClass = Ember.View.extend();
var alreadyContainedView = AlreadyContainedViewClass.create(); var alreadyContainedView = AlreadyContainedViewClass.create();
var containerView = this.subject();
containerView.pushObject(alreadyContainedView); containerView.pushObject(alreadyContainedView);
containerView.attachViewWithArgs(null, SomeViewClass); containerView.attachViewWithArgs(null, SomeViewClass);
containerHasTwoChildren(AlreadyContainedViewClass, SomeViewClass); containerHasTwoChildren(containerView, AlreadyContainedViewClass, SomeViewClass);
}); });
test("attachViewClass: creates a view of a given class without any properties and appends it to the container", function() { test("attachViewClass: creates a view of a given class without any properties and appends it to the container", function() {
var containerView = this.subject();
containerView.attachViewClass(SomeViewClass); containerView.attachViewClass(SomeViewClass);
containerHasOnlyOneChild(SomeViewClass); containerHasOnlyOneChild(containerView, SomeViewClass);
}); });
test("attachViewClass: creates a view without class specified (Ember.View is used by default) without any properties and appends it to the container", function() { test("attachViewClass: creates a view without class specified (Ember.View is used by default) without any properties and appends it to the container", function() {
var containerView = this.subject();
containerView.attachViewClass(); containerView.attachViewClass();
containerHasOnlyOneChild(Ember.View); containerHasOnlyOneChild(containerView, Ember.View);
}); });
test("attachViewClass: appends a view to a container already containing other views", function() { test("attachViewClass: appends a view to a container already containing other views", function() {
var AlreadyContainedViewClass = Ember.View.extend(); var AlreadyContainedViewClass = Ember.View.extend();
var alreadyContainedView = AlreadyContainedViewClass.create(); var alreadyContainedView = AlreadyContainedViewClass.create();
var containerView = this.subject();
containerView.pushObject(alreadyContainedView); containerView.pushObject(alreadyContainedView);
containerView.attachViewClass(SomeViewClass); containerView.attachViewClass(SomeViewClass);
containerHasTwoChildren(AlreadyContainedViewClass, SomeViewClass); containerHasTwoChildren(containerView, AlreadyContainedViewClass, SomeViewClass);
}); });

View File

@ -1,13 +1,10 @@
module("Discourse.HeaderView"); moduleFor("view:header");
test("showNotifications", function() { test("showNotifications", function() {
var controllerSpy = { var controllerSpy = {
send: sinon.spy() send: sinon.spy()
}; };
var view = viewClassFor('header').create({ var view = this.subject({controller: controllerSpy});
controller: controllerSpy
});
view.showNotifications(); view.showNotifications();
ok(controllerSpy.send.calledWith("showNotifications", view), "sends showNotifications message to the controller, passing header view as a param"); ok(controllerSpy.send.calledWith("showNotifications", view), "sends showNotifications message to the controller, passing header view as a param");

View File

@ -1,59 +1,17 @@
var appendTextFieldWithProperties = function(properties) { moduleForComponent("text-field");
var view = componentClassFor('text-field').create(properties);
Ember.run(function() {
view.appendTo(fixture());
});
};
var hasAttr = function($element, attrName, attrValue) {
equal($element.attr(attrName), attrValue, "'" + attrName + "' attribute is correctly rendered");
};
var hasNoAttr = function($element, attrName) {
equal($element.attr(attrName), undefined, "'" + attrName + "' attribute is not rendered");
};
module("view:text-field");
test("renders correctly with no properties set", function() { test("renders correctly with no properties set", function() {
appendTextFieldWithProperties({}); var component = this.subject();
equal(component.get('type'), "text");
var $input = fixture("input");
hasAttr($input, "type", "text");
hasAttr($input, "placeholder", "");
hasNoAttr($input, "autocorrect");
hasNoAttr($input, "autocapitalize");
hasNoAttr($input, "autofocus");
}); });
test("renders correctly with all allowed properties set", function() { test("support a placeholder", function() {
this.stub(I18n, "t").returnsArg(0); sandbox.stub(I18n, "t").returnsArg(0);
appendTextFieldWithProperties({ var component = this.subject({
autocorrect: "on",
autocapitalize: "off",
autofocus: "autofocus",
placeholderKey: "placeholder.i18n.key" placeholderKey: "placeholder.i18n.key"
}); });
var $input = fixture("input"); equal(component.get('type'), "text");
hasAttr($input, "type", "text"); equal(component.get('placeholder'), "placeholder.i18n.key");
hasAttr($input, "placeholder", "placeholder.i18n.key");
hasAttr($input, "autocorrect", "on");
hasAttr($input, "autocapitalize", "off");
hasAttr($input, "autofocus", "autofocus");
}); });
// NEIL commented out this test. It fails now that TextField is in the components dir.
// test("is registered as helper", function() {
// var view = Ember.View.create({
// template: Ember.Handlebars.compile("{{text-field}}")
// });
// Ember.run(function() {
// view.appendTo(fixture());
// });
// ok(exists(fixture("input")));
// });