DEV: Modernize controller unit tests (#17412)

Aligns controller tests with the Ember standard, by using `module` and `setupTest` instead of our custom `discourseModule`)
This commit is contained in:
Jarek Radosz 2022-10-14 13:15:58 +02:00 committed by GitHub
parent 2c5e8f1763
commit a5156d18ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 352 additions and 455 deletions

View File

@ -1,8 +1,10 @@
import { module, test } from "qunit";
import { setupTest } from "ember-qunit";
import Theme from "admin/models/theme"; import Theme from "admin/models/theme";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
discourseModule("Unit | Controller | admin-customize-themes-show", function () { module("Unit | Controller | admin-customize-themes-show", function (hooks) {
setupTest(hooks);
test("can display source url for remote themes", function (assert) { test("can display source url for remote themes", function (assert) {
const repoUrl = "https://github.com/discourse/discourse-brand-header.git"; const repoUrl = "https://github.com/discourse/discourse-brand-header.git";
const remoteTheme = Theme.create({ const remoteTheme = Theme.create({
@ -13,12 +15,14 @@ discourseModule("Unit | Controller | admin-customize-themes-show", function () {
remote_url: repoUrl, remote_url: repoUrl,
}, },
}); });
const controller = this.getController("admin-customize-themes-show", {
model: remoteTheme, const controller = this.owner.lookup(
}); "controller:admin-customize-themes-show"
);
controller.setProperties({ model: remoteTheme });
assert.deepEqual( assert.deepEqual(
controller.get("remoteThemeLink"), controller.remoteThemeLink,
repoUrl, repoUrl,
"returns theme's repo URL" "returns theme's repo URL"
); );
@ -34,12 +38,14 @@ discourseModule("Unit | Controller | admin-customize-themes-show", function () {
branch: "beta", branch: "beta",
}, },
}); });
const controller = this.getController("admin-customize-themes-show", {
model: remoteTheme, const controller = this.owner.lookup(
}); "controller:admin-customize-themes-show"
);
controller.setProperties({ model: remoteTheme });
assert.deepEqual( assert.deepEqual(
controller.get("remoteThemeLink"), controller.remoteThemeLink,
"https://github.com/discourse/discourse-brand-header/tree/beta", "https://github.com/discourse/discourse-brand-header/tree/beta",
"returns theme's repo URL to branch" "returns theme's repo URL to branch"
); );

View File

@ -1,8 +1,10 @@
import { module, test } from "qunit";
import { setupTest } from "ember-qunit";
import Theme from "admin/models/theme"; import Theme from "admin/models/theme";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
discourseModule("Unit | Controller | admin-customize-themes", function () { module("Unit | Controller | admin-customize-themes", function (hooks) {
setupTest(hooks);
test("can list themes correctly", function (assert) { test("can list themes correctly", function (assert) {
const defaultTheme = Theme.create({ const defaultTheme = Theme.create({
id: 2, id: 2,
@ -22,7 +24,8 @@ discourseModule("Unit | Controller | admin-customize-themes", function () {
component: true, component: true,
}); });
const controller = this.getController("admin-customize-themes", { const controller = this.owner.lookup("controller:admin-customize-themes");
controller.setProperties({
model: [ model: [
strayTheme2, strayTheme2,
strayTheme1, strayTheme1,
@ -33,16 +36,14 @@ discourseModule("Unit | Controller | admin-customize-themes", function () {
}); });
assert.deepEqual( assert.deepEqual(
controller.get("fullThemes").map((t) => t.get("name")), controller.fullThemes.map((t) => t.name),
[strayTheme2, strayTheme1, userTheme, defaultTheme].map((t) => [strayTheme2, strayTheme1, userTheme, defaultTheme].map((t) => t.name),
t.get("name")
),
"returns a list of themes without components" "returns a list of themes without components"
); );
assert.deepEqual( assert.deepEqual(
controller.get("childThemes").map((t) => t.get("name")), controller.childThemes.map((t) => t.name),
[componentTheme].map((t) => t.get("name")), [componentTheme].map((t) => t.name),
"separate components from themes" "separate components from themes"
); );
}); });

View File

@ -1,8 +1,10 @@
import { module, test } from "qunit";
import { setupTest } from "ember-qunit";
import Badge from "discourse/models/badge"; import Badge from "discourse/models/badge";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
discourseModule("Unit | Controller | admin-user-badges", function () { module("Unit | Controller | admin-user-badges", function (hooks) {
setupTest(hooks);
test("grantableBadges", function (assert) { test("grantableBadges", function (assert) {
const badgeFirst = Badge.create({ const badgeFirst = Badge.create({
id: 3, id: 3,
@ -35,7 +37,8 @@ discourseModule("Unit | Controller | admin-user-badges", function () {
manually_grantable: false, manually_grantable: false,
}); });
const controller = this.getController("admin-user-badges", { const controller = this.owner.lookup("controller:admin-user-badges");
controller.setProperties({
model: [], model: [],
badges: [ badges: [
badgeLast, badgeLast,
@ -47,9 +50,7 @@ discourseModule("Unit | Controller | admin-user-badges", function () {
}); });
const sortedNames = [badgeFirst.name, badgeMiddle.name, badgeLast.name]; const sortedNames = [badgeFirst.name, badgeMiddle.name, badgeLast.name];
const badgeNames = controller.get("grantableBadges").map(function (badge) { const badgeNames = controller.grantableBadges.map((badge) => badge.name);
return badge.name;
});
assert.notOk( assert.notOk(
badgeNames.includes(badgeDisabled), badgeNames.includes(badgeDisabled),

View File

@ -1,12 +1,9 @@
import { module, test } from "qunit";
import { setupTest } from "ember-qunit";
import EmberObject from "@ember/object"; import EmberObject from "@ember/object";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import { registerRouter } from "discourse/mapping-router";
import { test } from "qunit";
discourseModule("Unit | Controller | avatar-selector", function (hooks) { module("Unit | Controller | avatar-selector", function (hooks) {
hooks.beforeEach(function () { setupTest(hooks);
registerRouter(this.registry);
});
test("avatarTemplate", function (assert) { test("avatarTemplate", function (assert) {
const user = EmberObject.create({ const user = EmberObject.create({
@ -18,27 +15,26 @@ discourseModule("Unit | Controller | avatar-selector", function (hooks) {
gravatar_avatar_upload_id: 2, gravatar_avatar_upload_id: 2,
custom_avatar_upload_id: 3, custom_avatar_upload_id: 3,
}); });
const avatarSelectorController = this.getController("avatar-selector", { const controller = this.owner.lookup("controller:avatar-selector");
user, controller.setProperties({ user });
});
user.set("avatar_template", "system"); user.set("avatar_template", "system");
assert.strictEqual( assert.strictEqual(
avatarSelectorController.get("selectedUploadId"), controller.selectedUploadId,
1, 1,
"we are using system by default" "we are using system by default"
); );
user.set("avatar_template", "gravatar"); user.set("avatar_template", "gravatar");
assert.strictEqual( assert.strictEqual(
avatarSelectorController.get("selectedUploadId"), controller.selectedUploadId,
2, 2,
"we are using gravatar when set" "we are using gravatar when set"
); );
user.set("avatar_template", "avatar"); user.set("avatar_template", "avatar");
assert.strictEqual( assert.strictEqual(
avatarSelectorController.get("selectedUploadId"), controller.selectedUploadId,
3, 3,
"we are using custom when set" "we are using custom when set"
); );

View File

@ -1,12 +1,14 @@
import I18n from "I18n"; import { module, test } from "qunit";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers"; import { setupTest } from "ember-qunit";
import { test } from "qunit";
import { settled } from "@ember/test-helpers"; import { settled } from "@ember/test-helpers";
import I18n from "I18n";
module("Unit | Controller | create-account", function (hooks) {
setupTest(hooks);
discourseModule("Unit | Controller | create-account", function () {
test("basicUsernameValidation", function (assert) { test("basicUsernameValidation", function (assert) {
const testInvalidUsername = (username, expectedReason) => { const testInvalidUsername = (username, expectedReason) => {
const controller = this.getController("create-account"); const controller = this.owner.lookup("controller:create-account");
controller.set("accountUsername", username); controller.set("accountUsername", username);
let validation = controller.basicUsernameValidation(username); let validation = controller.basicUsernameValidation(username);
@ -25,7 +27,8 @@ discourseModule("Unit | Controller | create-account", function () {
I18n.t("user.username.too_long") I18n.t("user.username.too_long")
); );
const controller = this.getController("create-account", { const controller = this.owner.lookup("controller:create-account");
controller.setProperties({
accountUsername: "porkchops", accountUsername: "porkchops",
prefilledUsername: "porkchops", prefilledUsername: "porkchops",
}); });
@ -40,7 +43,7 @@ discourseModule("Unit | Controller | create-account", function () {
}); });
test("passwordValidation", async function (assert) { test("passwordValidation", async function (assert) {
const controller = this.getController("create-account"); const controller = this.owner.lookup("controller:create-account");
controller.set("authProvider", ""); controller.set("authProvider", "");
controller.set("accountEmail", "pork@chops.com"); controller.set("accountEmail", "pork@chops.com");
@ -65,12 +68,12 @@ discourseModule("Unit | Controller | create-account", function () {
assert.strictEqual( assert.strictEqual(
controller.passwordValidation.failed, controller.passwordValidation.failed,
true, true,
"password should be invalid: " + password `password should be invalid: ${password}`
); );
assert.strictEqual( assert.strictEqual(
controller.passwordValidation.reason, controller.passwordValidation.reason,
expectedReason, expectedReason,
"password validation reason: " + password + ", " + expectedReason `password validation reason: ${password}, ${expectedReason}`
); );
}; };
@ -87,7 +90,7 @@ discourseModule("Unit | Controller | create-account", function () {
}); });
test("authProviderDisplayName", function (assert) { test("authProviderDisplayName", function (assert) {
const controller = this.getController("create-account"); const controller = this.owner.lookup("controller:create-account");
assert.strictEqual( assert.strictEqual(
controller.authProviderDisplayName("facebook"), controller.authProviderDisplayName("facebook"),

View File

@ -1,40 +1,42 @@
import { discourseModule } from "discourse/tests/helpers/qunit-helpers"; import { module, test } from "qunit";
import { test } from "qunit"; import { setupTest } from "ember-qunit";
module("Unit | Controller | history", function (hooks) {
setupTest(hooks);
discourseModule("Unit | Controller | history", function () {
test("displayEdit", async function (assert) { test("displayEdit", async function (assert) {
const HistoryController = this.getController("history"); const controller = this.owner.lookup("controller:history");
HistoryController.setProperties({ controller.setProperties({
model: { last_revision: 3, current_revision: 3, can_edit: false }, model: { last_revision: 3, current_revision: 3, can_edit: false },
topicController: {}, topicController: {},
}); });
assert.strictEqual( assert.strictEqual(
HistoryController.get("displayEdit"), controller.displayEdit,
false, false,
"it should not display edit button when user cannot edit the post" "it should not display edit button when user cannot edit the post"
); );
HistoryController.set("model.can_edit", true); controller.set("model.can_edit", true);
assert.strictEqual( assert.strictEqual(
HistoryController.get("displayEdit"), controller.displayEdit,
true, true,
"it should display edit button when user can edit the post" "it should display edit button when user can edit the post"
); );
HistoryController.set("topicController", null); controller.set("topicController", null);
assert.strictEqual( assert.strictEqual(
HistoryController.get("displayEdit"), controller.displayEdit,
false, false,
"it should not display edit button when there is not topic controller" "it should not display edit button when there is not topic controller"
); );
HistoryController.set("topicController", {}); controller.set("topicController", {});
HistoryController.set("model.current_revision", 2); controller.set("model.current_revision", 2);
assert.strictEqual( assert.strictEqual(
HistoryController.get("displayEdit"), controller.displayEdit,
false, false,
"it should only display the edit button on the latest revision" "it should only display the edit button on the latest revision"
); );
@ -97,7 +99,7 @@ discourseModule("Unit | Controller | history", function () {
</tbody> </tbody>
</table>`; </table>`;
HistoryController.setProperties({ controller.setProperties({
viewMode: "side_by_side", viewMode: "side_by_side",
model: { model: {
body_changes: { body_changes: {
@ -106,9 +108,9 @@ discourseModule("Unit | Controller | history", function () {
}, },
}); });
await HistoryController.bodyDiffChanged(); await controller.bodyDiffChanged();
const output = HistoryController.get("bodyDiff"); const output = controller.bodyDiff;
assert.strictEqual( assert.strictEqual(
output, output,
expectedOutput, expectedOutput,

View File

@ -1,12 +1,18 @@
import { discourseModule } from "discourse/tests/helpers/qunit-helpers"; import { module, test } from "qunit";
import { test } from "qunit"; import { setupTest } from "ember-qunit";
module("Unit | Controller | preferences/account", function (hooks) {
setupTest(hooks);
discourseModule("Unit | Controller | preferences/account", function () {
test("updating of associated accounts", function (assert) { test("updating of associated accounts", function (assert) {
const controller = this.getController("preferences/account", { const siteSettings = this.owner.lookup("service:site-settings");
siteSettings: { siteSettings.enable_google_oauth2_logins = true;
enable_google_oauth2_logins: true,
}, const site = this.owner.lookup("service:site");
site.set("isMobileDevice", false);
const controller = this.owner.lookup("controller:preferences/account");
controller.setProperties({
model: { model: {
id: 70, id: 70,
second_factor_enabled: true, second_factor_enabled: true,
@ -15,20 +21,17 @@ discourseModule("Unit | Controller | preferences/account", function () {
currentUser: { currentUser: {
id: 1234, id: 1234,
}, },
site: {
isMobileDevice: false,
},
}); });
assert.strictEqual(controller.get("canUpdateAssociatedAccounts"), false); assert.strictEqual(controller.canUpdateAssociatedAccounts, false);
controller.set("model.second_factor_enabled", false); controller.set("model.second_factor_enabled", false);
assert.strictEqual(controller.get("canUpdateAssociatedAccounts"), false); assert.strictEqual(controller.canUpdateAssociatedAccounts, false);
controller.set("model.is_anonymous", false); controller.set("model.is_anonymous", false);
assert.strictEqual(controller.get("canUpdateAssociatedAccounts"), false); assert.strictEqual(controller.canUpdateAssociatedAccounts, false);
controller.set("model.id", 1234); controller.set("model.id", 1234);
assert.strictEqual(controller.get("canUpdateAssociatedAccounts"), true); assert.strictEqual(controller.canUpdateAssociatedAccounts, true);
}); });
}); });

View File

@ -1,11 +1,20 @@
import { discourseModule } from "discourse/tests/helpers/qunit-helpers"; import { module, test } from "qunit";
import { test } from "qunit"; import { setupTest } from "ember-qunit";
import User from "discourse/models/user"; import User from "discourse/models/user";
import Site from "discourse/models/site";
discourseModule("Unit | Controller | preferences/profile", function () { module("Unit | Controller | preferences/profile", function (hooks) {
setupTest(hooks);
test("prepare custom field data", function (assert) { test("prepare custom field data", function (assert) {
const controller = this.getController("preferences/profile", { const site = this.owner.lookup("service:site");
site.set("user_fields", [
{ position: 1, id: 1, editable: true },
{ position: 2, id: 2, editable: true },
{ position: 3, id: 3, editable: true },
]);
const controller = this.owner.lookup("controller:preferences/profile");
controller.setProperties({
model: User.create({ model: User.create({
id: 70, id: 70,
second_factor_enabled: true, second_factor_enabled: true,
@ -21,15 +30,6 @@ discourseModule("Unit | Controller | preferences/profile", function () {
}, },
}); });
Site.currentProp("user_fields", [
{ position: 1, id: 1, editable: true },
{ position: 2, id: 2, editable: true },
{ position: 3, id: 3, editable: true },
]);
// Since there are no injections in unit tests
controller.set("site", Site.current());
controller.send("_updateUserFields"); controller.send("_updateUserFields");
const fields = controller.model.user_fields; const fields = controller.model.user_fields;

View File

@ -1,13 +1,17 @@
import { discourseModule } from "discourse/tests/helpers/qunit-helpers"; import { module, test } from "qunit";
import { test } from "qunit"; import { setupTest } from "ember-qunit";
module("Unit | Controller | preferences/second-factor", function (hooks) {
setupTest(hooks);
discourseModule("Unit | Controller | preferences/second-factor", function () {
test("displayOAuthWarning when OAuth login methods are enabled", function (assert) { test("displayOAuthWarning when OAuth login methods are enabled", function (assert) {
const controller = this.getController("preferences/second-factor", { const siteSettings = this.owner.lookup("service:site-settings");
siteSettings: { siteSettings.enable_google_oauth2_logins = true;
enable_google_oauth2_logins: true,
}, const controller = this.owner.lookup(
}); "controller:preferences/second-factor"
assert.strictEqual(controller.get("displayOAuthWarning"), true); );
assert.strictEqual(controller.displayOAuthWarning, true);
}); });
}); });

View File

@ -1,27 +1,30 @@
import { module, test } from "qunit";
import { setupTest } from "ember-qunit";
import createStore from "discourse/tests/helpers/create-store"; import createStore from "discourse/tests/helpers/create-store";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import { test } from "qunit";
discourseModule("Unit | Controller | reorder-categories", function () { module("Unit | Controller | reorder-categories", function (hooks) {
setupTest(hooks);
test("reorder set unique position number", function (assert) { test("reorder set unique position number", function (assert) {
const controller = this.owner.lookup("controller:reorder-categories");
const store = createStore(); const store = createStore();
const categories = []; const site = this.owner.lookup("service:site");
for (let i = 0; i < 3; ++i) { site.set("categories", [
categories.push(store.createRecord("category", { id: i, position: 0 })); store.createRecord("category", { id: 1, position: 0 }),
} store.createRecord("category", { id: 2, position: 0 }),
store.createRecord("category", { id: 3, position: 0 }),
]);
const controller = this.getController("reorder-categories", {
site: { categories },
});
controller.reorder(); controller.reorder();
controller.get("categoriesOrdered").forEach((category, index) => { controller.categoriesOrdered.forEach((category, index) => {
assert.strictEqual(category.get("position"), index); assert.strictEqual(category.get("position"), index);
}); });
}); });
test("reorder places subcategories after their parent categories, while maintaining the relative order", function (assert) { test("reorder places subcategories after their parent categories, while maintaining the relative order", function (assert) {
const controller = this.owner.lookup("controller:reorder-categories");
const store = createStore(); const store = createStore();
const parent = store.createRecord("category", { const parent = store.createRecord("category", {
@ -48,18 +51,19 @@ discourseModule("Unit | Controller | reorder-categories", function () {
}); });
const expectedOrderSlugs = ["parent", "child2", "child1", "other"]; const expectedOrderSlugs = ["parent", "child2", "child1", "other"];
const controller = this.getController("reorder-categories", { const site = this.owner.lookup("service:site");
site: { categories: [child2, parent, other, child1] }, site.set("categories", [child2, parent, other, child1]);
});
controller.reorder(); controller.reorder();
assert.deepEqual( assert.deepEqual(
controller.get("categoriesOrdered").mapBy("slug"), controller.categoriesOrdered.mapBy("slug"),
expectedOrderSlugs expectedOrderSlugs
); );
}); });
test("changing the position number of a category should place it at given position", function (assert) { test("changing the position number of a category should place it at given position", function (assert) {
const controller = this.owner.lookup("controller:reorder-categories");
const store = createStore(); const store = createStore();
const elem1 = store.createRecord("category", { const elem1 = store.createRecord("category", {
@ -80,14 +84,13 @@ discourseModule("Unit | Controller | reorder-categories", function () {
slug: "test", slug: "test",
}); });
const controller = this.getController("reorder-categories", { const site = this.owner.lookup("service:site");
site: { categories: [elem1, elem2, elem3] }, site.set("categories", [elem1, elem2, elem3]);
});
// Move category 'foo' from position 0 to position 2 // Move category 'foo' from position 0 to position 2
controller.send("change", elem1, { target: { value: "2" } }); controller.send("change", elem1, { target: { value: "2" } });
assert.deepEqual(controller.get("categoriesOrdered").mapBy("slug"), [ assert.deepEqual(controller.categoriesOrdered.mapBy("slug"), [
"bar", "bar",
"test", "test",
"foo", "foo",
@ -95,6 +98,7 @@ discourseModule("Unit | Controller | reorder-categories", function () {
}); });
test("changing the position number of a category should place it at given position and respect children", function (assert) { test("changing the position number of a category should place it at given position and respect children", function (assert) {
const controller = this.owner.lookup("controller:reorder-categories");
const store = createStore(); const store = createStore();
const elem1 = store.createRecord("category", { const elem1 = store.createRecord("category", {
@ -106,7 +110,7 @@ discourseModule("Unit | Controller | reorder-categories", function () {
const child1 = store.createRecord("category", { const child1 = store.createRecord("category", {
id: 4, id: 4,
position: 1, position: 1,
slug: "foochild", slug: "foo-child",
parent_category_id: 1, parent_category_id: 1,
}); });
@ -122,34 +126,34 @@ discourseModule("Unit | Controller | reorder-categories", function () {
slug: "test", slug: "test",
}); });
const controller = this.getController("reorder-categories", { const site = this.owner.lookup("service:site");
site: { categories: [elem1, child1, elem2, elem3] }, site.set("categories", [elem1, child1, elem2, elem3]);
});
controller.send("change", elem1, { target: { value: 3 } }); controller.send("change", elem1, { target: { value: 3 } });
assert.deepEqual(controller.get("categoriesOrdered").mapBy("slug"), [ assert.deepEqual(controller.categoriesOrdered.mapBy("slug"), [
"bar", "bar",
"test", "test",
"foo", "foo",
"foochild", "foo-child",
]); ]);
}); });
test("changing the position through click on arrow of a category should place it at given position and respect children", function (assert) { test("changing the position through click on arrow of a category should place it at given position and respect children", function (assert) {
const controller = this.owner.lookup("controller:reorder-categories");
const store = createStore(); const store = createStore();
const child2 = store.createRecord("category", { const child2 = store.createRecord("category", {
id: 105, id: 105,
position: 2, position: 2,
slug: "foochildchild", slug: "foo-child-child",
parent_category_id: 104, parent_category_id: 104,
}); });
const child1 = store.createRecord("category", { const child1 = store.createRecord("category", {
id: 104, id: 104,
position: 1, position: 1,
slug: "foochild", slug: "foo-child",
parent_category_id: 101, parent_category_id: 101,
subcategories: [child2], subcategories: [child2],
}); });
@ -173,19 +177,18 @@ discourseModule("Unit | Controller | reorder-categories", function () {
slug: "test", slug: "test",
}); });
const controller = this.getController("reorder-categories", { const site = this.owner.lookup("service:site");
site: { categories: [elem1, child1, child2, elem2, elem3] }, site.set("categories", [elem1, child1, child2, elem2, elem3]);
});
controller.reorder(); controller.reorder();
controller.send("moveDown", elem1); controller.send("moveDown", elem1);
assert.deepEqual(controller.get("categoriesOrdered").mapBy("slug"), [ assert.deepEqual(controller.categoriesOrdered.mapBy("slug"), [
"bar", "bar",
"foo", "foo",
"foochild", "foo-child",
"foochildchild", "foo-child-child",
"test", "test",
]); ]);
}); });

View File

@ -1,66 +1,50 @@
import { module, test } from "qunit";
import { setupTest } from "ember-qunit";
import { settled } from "@ember/test-helpers";
import pretender, { response } from "discourse/tests/helpers/create-pretender";
import EmberObject from "@ember/object"; import EmberObject from "@ember/object";
import { Placeholder } from "discourse/lib/posts-with-placeholders"; import { Placeholder } from "discourse/lib/posts-with-placeholders";
import Topic from "discourse/models/topic"; import Topic from "discourse/models/topic";
import User from "discourse/models/user"; import User from "discourse/models/user";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import { next } from "@ember/runloop"; import { next } from "@ember/runloop";
import pretender, { response } from "discourse/tests/helpers/create-pretender";
import { settled } from "@ember/test-helpers";
import { test } from "qunit";
function topicWithStream(streamDetails) { function topicWithStream(streamDetails) {
let topic = Topic.create(); let topic = Topic.create();
topic.get("postStream").setProperties(streamDetails); topic.postStream.setProperties(streamDetails);
return topic; return topic;
} }
discourseModule("Unit | Controller | topic", function (hooks) { module("Unit | Controller | topic", function (hooks) {
hooks.beforeEach(function () { setupTest(hooks);
this.registry.injection("controller", "appEvents", "service:app-events");
});
hooks.afterEach(function () {
this.registry.unregister("service:current-user");
let topic = this.container.lookup("controller:topic");
topic.setProperties({
selectedPostIds: [],
selectedPostUsername: null,
});
});
test("editTopic", function (assert) { test("editTopic", function (assert) {
const controller = this.owner.lookup("controller:topic");
const model = Topic.create(); const model = Topic.create();
const controller = this.getController("topic", { model }); controller.setProperties({ model });
assert.notOk( assert.notOk(controller.editingTopic, "we are not editing by default");
controller.get("editingTopic"),
"we are not editing by default"
);
controller.set("model.details.can_edit", false); controller.set("model.details.can_edit", false);
controller.send("editTopic"); controller.editTopic();
assert.notOk( assert.notOk(
controller.get("editingTopic"), controller.editingTopic,
"calling editTopic doesn't enable editing unless the user can edit" "calling editTopic doesn't enable editing unless the user can edit"
); );
controller.set("model.details.can_edit", true); controller.set("model.details.can_edit", true);
controller.send("editTopic"); controller.editTopic();
assert.ok( assert.ok(
controller.get("editingTopic"), controller.editingTopic,
"calling editTopic enables editing if the user can edit" "calling editTopic enables editing if the user can edit"
); );
assert.strictEqual(controller.get("buffered.title"), model.get("title")); assert.strictEqual(controller.buffered.title, model.title);
assert.strictEqual( assert.strictEqual(controller.buffered.category_id, model.category_id);
controller.get("buffered.category_id"),
model.get("category_id")
);
controller.send("cancelEditingTopic"); controller.send("cancelEditingTopic");
assert.notOk( assert.notOk(
controller.get("editingTopic"), controller.editingTopic,
"cancelling edit mode reverts the property value" "cancelling edit mode reverts the property value"
); );
}); });
@ -69,17 +53,15 @@ discourseModule("Unit | Controller | topic", function (hooks) {
const model = Topic.create(); const model = Topic.create();
let destroyed = false; let destroyed = false;
let modalDisplayed = false; let modalDisplayed = false;
model.destroy = async () => { model.destroy = async () => (destroyed = true);
destroyed = true;
}; const siteSettings = this.owner.lookup("service:site-settings");
const controller = this.getController("topic", { siteSettings.min_topic_views_for_delete_confirm = 5;
const controller = this.owner.lookup("controller:topic");
controller.setProperties({
model, model,
siteSettings: { deleteTopicModal: () => (modalDisplayed = true),
min_topic_views_for_delete_confirm: 5,
},
deleteTopicModal: () => {
modalDisplayed = true;
},
}); });
model.set("views", 10000); model.set("views", 10000);
@ -94,82 +76,79 @@ discourseModule("Unit | Controller | topic", function (hooks) {
test("toggleMultiSelect", async function (assert) { test("toggleMultiSelect", async function (assert) {
const model = Topic.create(); const model = Topic.create();
const controller = this.getController("topic", { model }); const controller = this.owner.lookup("controller:topic");
controller.setProperties({ model });
assert.notOk( assert.notOk(
controller.get("multiSelect"), controller.multiSelect,
"multi selection mode is disabled by default" "multi selection mode is disabled by default"
); );
controller.get("selectedPostIds").pushObject(1); controller.selectedPostIds.pushObject(1);
assert.strictEqual(controller.get("selectedPostIds.length"), 1); assert.strictEqual(controller.selectedPostIds.length, 1);
controller.send("toggleMultiSelect"); controller.send("toggleMultiSelect");
await settled(); await settled();
assert.ok( assert.ok(
controller.get("multiSelect"), controller.multiSelect,
"calling 'toggleMultiSelect' once enables multi selection mode" "calling 'toggleMultiSelect' once enables multi selection mode"
); );
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostIds.length"), controller.selectedPostIds.length,
0, 0,
"toggling 'multiSelect' clears 'selectedPostIds'" "toggling 'multiSelect' clears 'selectedPostIds'"
); );
controller.get("selectedPostIds").pushObject(2); controller.selectedPostIds.pushObject(2);
assert.strictEqual(controller.get("selectedPostIds.length"), 1); assert.strictEqual(controller.selectedPostIds.length, 1);
controller.send("toggleMultiSelect"); controller.send("toggleMultiSelect");
await settled(); await settled();
assert.notOk( assert.notOk(
controller.get("multiSelect"), controller.multiSelect,
"calling 'toggleMultiSelect' twice disables multi selection mode" "calling 'toggleMultiSelect' twice disables multi selection mode"
); );
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostIds.length"), controller.selectedPostIds.length,
0, 0,
"toggling 'multiSelect' clears 'selectedPostIds'" "toggling 'multiSelect' clears 'selectedPostIds'"
); );
}); });
test("selectedPosts", function (assert) { test("selectedPosts", function (assert) {
let model = topicWithStream({ posts: [{ id: 1 }, { id: 2 }, { id: 3 }] }); const model = topicWithStream({ posts: [{ id: 1 }, { id: 2 }, { id: 3 }] });
const controller = this.getController("topic", { model }); const controller = this.owner.lookup("controller:topic");
controller.setProperties({ model });
controller.set("selectedPostIds", [1, 2, 42]); controller.set("selectedPostIds", [1, 2, 42]);
assert.strictEqual( assert.strictEqual(
controller.get("selectedPosts.length"), controller.selectedPosts.length,
2, 2,
"selectedPosts only contains already loaded posts" "selectedPosts only contains already loaded posts"
); );
assert.notOk( assert.notOk(
controller.get("selectedPosts").some((p) => p === undefined), controller.selectedPosts.some((p) => p === undefined),
"selectedPosts only contains valid post objects" "selectedPosts only contains valid post objects"
); );
}); });
test("selectedAllPosts", function (assert) { test("selectedAllPosts", function (assert) {
let model = topicWithStream({ stream: [1, 2, 3] }); const model = topicWithStream({ stream: [1, 2, 3] });
const controller = this.getController("topic", { model }); const controller = this.owner.lookup("controller:topic");
controller.setProperties({ model });
controller.set("selectedPostIds", [1, 2]); controller.set("selectedPostIds", [1, 2]);
assert.notOk(controller.selectedAllPosts, "not all posts are selected");
assert.notOk( controller.selectedPostIds.pushObject(3);
controller.get("selectedAllPosts"), assert.ok(controller.selectedAllPosts, "all posts are selected");
"not all posts are selected"
);
controller.get("selectedPostIds").pushObject(3);
assert.ok(controller.get("selectedAllPosts"), "all posts are selected");
controller.get("selectedPostIds").pushObject(42);
controller.selectedPostIds.pushObject(42);
assert.ok( assert.ok(
controller.get("selectedAllPosts"), controller.selectedAllPosts,
"all posts (including filtered posts) are selected" "all posts (including filtered posts) are selected"
); );
@ -177,15 +156,14 @@ discourseModule("Unit | Controller | topic", function (hooks) {
"postStream.isMegaTopic": true, "postStream.isMegaTopic": true,
posts_count: 1, posts_count: 1,
}); });
assert.ok( assert.ok(
controller.get("selectedAllPosts"), controller.selectedAllPosts,
"it uses the topic's post count for megatopics" "it uses the topic's post count for mega-topics"
); );
}); });
test("selectedPostsUsername", function (assert) { test("selectedPostsUsername", function (assert) {
let model = topicWithStream({ const model = topicWithStream({
posts: [ posts: [
{ id: 1, username: "gary" }, { id: 1, username: "gary" },
{ id: 2, username: "gary" }, { id: 2, username: "gary" },
@ -193,84 +171,69 @@ discourseModule("Unit | Controller | topic", function (hooks) {
], ],
stream: [1, 2, 3], stream: [1, 2, 3],
}); });
const controller = this.getController("topic", { model }); const controller = this.owner.lookup("controller:topic");
const selectedPostIds = controller.get("selectedPostIds"); controller.setProperties({ model });
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostsUsername"), controller.selectedPostsUsername,
undefined, undefined,
"no username when no selected posts" "no username when no selected posts"
); );
selectedPostIds.pushObject(1); controller.selectedPostIds.pushObject(1);
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostsUsername"), controller.selectedPostsUsername,
"gary", "gary",
"username of the selected posts" "username of the selected posts"
); );
selectedPostIds.pushObject(2); controller.selectedPostIds.pushObject(2);
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostsUsername"), controller.selectedPostsUsername,
"gary", "gary",
"username of all the selected posts when same user" "username of all the selected posts when same user"
); );
selectedPostIds.pushObject(3); controller.selectedPostIds.pushObject(3);
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostsUsername"), controller.selectedPostsUsername,
undefined, undefined,
"no username when more than 1 user" "no username when more than 1 user"
); );
selectedPostIds.replace(2, 1, [42]); controller.selectedPostIds.replace(2, 1, [42]);
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostsUsername"), controller.selectedPostsUsername,
undefined, undefined,
"no username when not already loaded posts are selected" "no username when not already loaded posts are selected"
); );
}); });
test("showSelectedPostsAtBottom", function (assert) { test("showSelectedPostsAtBottom", function (assert) {
const site = EmberObject.create({ mobileView: false });
const model = Topic.create({ posts_count: 3 }); const model = Topic.create({ posts_count: 3 });
const controller = this.getController("topic", { model, site }); const controller = this.owner.lookup("controller:topic");
controller.setProperties({ model });
assert.notOk( assert.notOk(controller.showSelectedPostsAtBottom, "false on desktop");
controller.get("showSelectedPostsAtBottom"),
"false on desktop"
);
const site = this.owner.lookup("service:site");
site.set("mobileView", true); site.set("mobileView", true);
assert.notOk( assert.notOk(
controller.get("showSelectedPostsAtBottom"), controller.showSelectedPostsAtBottom,
"requires at least 3 posts on mobile" "requires at least 3 posts on mobile"
); );
model.set("posts_count", 4); model.set("posts_count", 4);
assert.ok( assert.ok(
controller.get("showSelectedPostsAtBottom"), controller.showSelectedPostsAtBottom,
"true when mobile and more than 3 posts" "true when mobile and more than 3 posts"
); );
}); });
test("canDeleteSelected", function (assert) { test("canDeleteSelected", function (assert) {
const currentUser = User.create({ admin: false }); const currentUser = User.create({ admin: false });
this.registry.register("service:current-user", currentUser, { const model = topicWithStream({
instantiate: false,
});
this.registry.injection(
"controller",
"currentUser",
"service:current-user"
);
let model = topicWithStream({
posts: [ posts: [
{ id: 1, can_delete: false }, { id: 1, can_delete: false },
{ id: 2, can_delete: true }, { id: 2, can_delete: true },
@ -278,47 +241,45 @@ discourseModule("Unit | Controller | topic", function (hooks) {
], ],
stream: [1, 2, 3], stream: [1, 2, 3],
}); });
const controller = this.getController("topic", {
const controller = this.owner.lookup("controller:topic");
controller.setProperties({
model, model,
currentUser,
}); });
const selectedPostIds = controller.get("selectedPostIds");
assert.notOk( assert.notOk(
controller.get("canDeleteSelected"), controller.canDeleteSelected,
"false when no posts are selected" "false when no posts are selected"
); );
selectedPostIds.pushObject(1); controller.selectedPostIds.pushObject(1);
assert.notOk( assert.notOk(
controller.get("canDeleteSelected"), controller.canDeleteSelected,
"false when can't delete one of the selected posts" "false when can't delete one of the selected posts"
); );
selectedPostIds.replace(0, 1, [2, 3]); controller.selectedPostIds.replace(0, 1, [2, 3]);
assert.ok( assert.ok(
controller.get("canDeleteSelected"), controller.canDeleteSelected,
"true when all selected posts can be deleted" "true when all selected posts can be deleted"
); );
selectedPostIds.pushObject(1); controller.selectedPostIds.pushObject(1);
assert.notOk( assert.notOk(
controller.get("canDeleteSelected"), controller.canDeleteSelected,
"false when all posts are selected and user is staff" "false when all posts are selected and user is staff"
); );
currentUser.set("admin", true); currentUser.set("admin", true);
assert.ok( assert.ok(
controller.get("canDeleteSelected"), controller.canDeleteSelected,
"true when all posts are selected and user is staff" "true when all posts are selected and user is staff"
); );
}); });
test("Can split/merge topic", function (assert) { test("Can split/merge topic", function (assert) {
let model = topicWithStream({ const model = topicWithStream({
posts: [ posts: [
{ id: 1, post_number: 1, post_type: 1 }, { id: 1, post_number: 1, post_type: 1 },
{ id: 2, post_number: 2, post_type: 4 }, { id: 2, post_number: 2, post_type: 4 },
@ -327,140 +288,111 @@ discourseModule("Unit | Controller | topic", function (hooks) {
stream: [1, 2, 3], stream: [1, 2, 3],
}); });
model.set("details.can_move_posts", false); model.set("details.can_move_posts", false);
const controller = this.getController("topic", { model });
const selectedPostIds = controller.get("selectedPostIds"); const controller = this.owner.lookup("controller:topic");
controller.setProperties({ model });
assert.notOk( assert.notOk(
controller.get("canMergeTopic"), controller.canMergeTopic,
"can't merge topic when no posts are selected" "can't merge topic when no posts are selected"
); );
selectedPostIds.pushObject(1); controller.selectedPostIds.pushObject(1);
assert.notOk( assert.notOk(
controller.get("canMergeTopic"), controller.canMergeTopic,
"can't merge topic when can't move posts" "can't merge topic when can't move posts"
); );
model.set("details.can_move_posts", true); model.set("details.can_move_posts", true);
assert.ok(controller.get("canMergeTopic"), "can merge topic"); assert.ok(controller.canMergeTopic, "can merge topic");
selectedPostIds.removeObject(1); controller.selectedPostIds.removeObject(1);
selectedPostIds.pushObject(2); controller.selectedPostIds.pushObject(2);
assert.ok( assert.ok(
controller.get("canMergeTopic"), controller.canMergeTopic,
"can merge topic when 1st post is not a regular post" "can merge topic when 1st post is not a regular post"
); );
selectedPostIds.pushObject(3); controller.selectedPostIds.pushObject(3);
assert.ok( assert.ok(
controller.get("canMergeTopic"), controller.canMergeTopic,
"can merge topic when all posts are selected" "can merge topic when all posts are selected"
); );
}); });
test("canChangeOwner", function (assert) { test("canChangeOwner", function (assert) {
const currentUser = User.create({ admin: false }); const currentUser = User.create({ admin: false });
this.registry.register("service:current-user", currentUser, { const model = topicWithStream({
instantiate: false,
});
this.registry.injection(
"controller",
"currentUser",
"service:current-user"
);
let model = topicWithStream({
posts: [ posts: [
{ id: 1, username: "gary" }, { id: 1, username: "gary" },
{ id: 2, username: "lili" }, { id: 2, username: "lili" },
], ],
stream: [1, 2], stream: [1, 2],
}); });
const controller = this.getController("topic", { model.set("currentUser", currentUser);
model,
});
const selectedPostIds = controller.get("selectedPostIds");
assert.notOk( const controller = this.owner.lookup("controller:topic");
controller.get("canChangeOwner"), controller.setProperties({ model, currentUser });
"false when no posts are selected"
);
selectedPostIds.pushObject(1); assert.notOk(controller.canChangeOwner, "false when no posts are selected");
assert.notOk(controller.get("canChangeOwner"), "false when not admin"); controller.selectedPostIds.pushObject(1);
assert.notOk(controller.canChangeOwner, "false when not admin");
currentUser.set("admin", true); currentUser.set("admin", true);
assert.ok( assert.ok(
controller.get("canChangeOwner"), controller.canChangeOwner,
"true when admin and one post is selected" "true when admin and one post is selected"
); );
selectedPostIds.pushObject(2); controller.selectedPostIds.pushObject(2);
assert.notOk( assert.notOk(
controller.get("canChangeOwner"), controller.canChangeOwner,
"false when admin but more than 1 user" "false when admin but more than 1 user"
); );
}); });
test("modCanChangeOwner", function (assert) { test("modCanChangeOwner", function (assert) {
const currentUser = User.create({ moderator: false }); const currentUser = User.create({ moderator: false });
this.registry.register("service:current-user", currentUser, { const model = topicWithStream({
instantiate: false,
});
this.registry.injection(
"controller",
"currentUser",
"service:current-user"
);
let model = topicWithStream({
posts: [ posts: [
{ id: 1, username: "gary" }, { id: 1, username: "gary" },
{ id: 2, username: "lili" }, { id: 2, username: "lili" },
], ],
stream: [1, 2], stream: [1, 2],
}); });
const controller = this.getController("topic", { model.set("currentUser", currentUser);
model,
siteSettings: {
moderators_change_post_ownership: true,
},
});
const selectedPostIds = controller.get("selectedPostIds");
assert.notOk( const siteSettings = this.owner.lookup("service:site-settings");
controller.get("canChangeOwner"), siteSettings.moderators_change_post_ownership = true;
"false when no posts are selected"
);
selectedPostIds.pushObject(1); const controller = this.owner.lookup("controller:topic");
controller.setProperties({ model, currentUser });
assert.notOk(controller.get("canChangeOwner"), "false when not moderator"); assert.notOk(controller.canChangeOwner, "false when no posts are selected");
controller.selectedPostIds.pushObject(1);
assert.notOk(controller.canChangeOwner, "false when not moderator");
currentUser.set("moderator", true); currentUser.set("moderator", true);
assert.ok( assert.ok(
controller.get("canChangeOwner"), controller.canChangeOwner,
"true when moderator and one post is selected" "true when moderator and one post is selected"
); );
selectedPostIds.pushObject(2); controller.selectedPostIds.pushObject(2);
assert.notOk( assert.notOk(
controller.get("canChangeOwner"), controller.canChangeOwner,
"false when moderator but more than 1 user" "false when moderator but more than 1 user"
); );
}); });
test("canMergePosts", function (assert) { test("canMergePosts", function (assert) {
let model = topicWithStream({ const model = topicWithStream({
posts: [ posts: [
{ id: 1, username: "gary", can_delete: true }, { id: 1, username: "gary", can_delete: true },
{ id: 2, username: "lili", can_delete: true }, { id: 2, username: "lili", can_delete: true },
@ -469,104 +401,92 @@ discourseModule("Unit | Controller | topic", function (hooks) {
], ],
stream: [1, 2, 3], stream: [1, 2, 3],
}); });
const controller = this.getController("topic", {
model,
});
const selectedPostIds = controller.get("selectedPostIds");
const controller = this.owner.lookup("controller:topic");
controller.setProperties({ model });
assert.notOk(controller.canMergePosts, "false when no posts are selected");
controller.selectedPostIds.pushObject(1);
assert.notOk( assert.notOk(
controller.get("canMergePosts"), controller.canMergePosts,
"false when no posts are selected"
);
selectedPostIds.pushObject(1);
assert.notOk(
controller.get("canMergePosts"),
"false when only one post is selected" "false when only one post is selected"
); );
selectedPostIds.pushObject(2); controller.selectedPostIds.pushObject(2);
assert.notOk( assert.notOk(
controller.get("canMergePosts"), controller.canMergePosts,
"false when selected posts are from different users" "false when selected posts are from different users"
); );
selectedPostIds.replace(1, 1, [3]); controller.selectedPostIds.replace(1, 1, [3]);
assert.notOk( assert.notOk(
controller.get("canMergePosts"), controller.canMergePosts,
"false when selected posts can't be deleted" "false when selected posts can't be deleted"
); );
selectedPostIds.replace(1, 1, [4]); controller.selectedPostIds.replace(1, 1, [4]);
assert.ok( assert.ok(
controller.get("canMergePosts"), controller.canMergePosts,
"true when all selected posts are deletable and by the same user" "true when all selected posts are deletable and by the same user"
); );
}); });
test("Select/deselect all", function (assert) { test("Select/deselect all", function (assert) {
let model = topicWithStream({ stream: [1, 2, 3] }); const controller = this.owner.lookup("controller:topic");
const controller = this.getController("topic", { model }); const model = topicWithStream({ stream: [1, 2, 3] });
controller.setProperties({ model });
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostsCount"), controller.selectedPostsCount,
0, 0,
"no posts selected by default" "no posts selected by default"
); );
controller.send("selectAll"); controller.send("selectAll");
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostsCount"), controller.selectedPostsCount,
3, 3,
"calling 'selectAll' selects all posts" "calling 'selectAll' selects all posts"
); );
controller.send("deselectAll"); controller.send("deselectAll");
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostsCount"), controller.selectedPostsCount,
0, 0,
"calling 'deselectAll' deselects all posts" "calling 'deselectAll' deselects all posts"
); );
}); });
test("togglePostSelection", function (assert) { test("togglePostSelection", function (assert) {
const controller = this.getController("topic"); const controller = this.owner.lookup("controller:topic");
const selectedPostIds = controller.get("selectedPostIds");
assert.strictEqual( assert.strictEqual(
selectedPostIds[0], controller.selectedPostIds[0],
undefined, undefined,
"no posts selected by default" "no posts selected by default"
); );
controller.send("togglePostSelection", { id: 1 }); controller.send("togglePostSelection", { id: 1 });
assert.strictEqual( assert.strictEqual(
selectedPostIds[0], controller.selectedPostIds[0],
1, 1,
"adds the selected post id if not already selected" "adds the selected post id if not already selected"
); );
controller.send("togglePostSelection", { id: 1 }); controller.send("togglePostSelection", { id: 1 });
assert.strictEqual( assert.strictEqual(
selectedPostIds[0], controller.selectedPostIds[0],
undefined, undefined,
"removes the selected post id if already selected" "removes the selected post id if already selected"
); );
}); });
test("selectBelow", function (assert) { test("selectBelow", function (assert) {
const site = EmberObject.create({ const site = this.owner.lookup("service:site");
post_types: { small_action: 3, whisper: 4 }, site.set("post_types", { small_action: 3, whisper: 4 });
});
let model = topicWithStream({ const model = topicWithStream({
stream: [1, 2, 3, 4, 5, 6, 7, 8], stream: [1, 2, 3, 4, 5, 6, 7, 8],
posts: [ posts: [
{ id: 5, cooked: "whisper post", post_type: 4 }, { id: 5, cooked: "whisper post", post_type: 4 },
@ -574,33 +494,18 @@ discourseModule("Unit | Controller | topic", function (hooks) {
{ id: 7, cooked: "", post_type: 4 }, { id: 7, cooked: "", post_type: 4 },
], ],
}); });
const controller = this.getController("topic", { site, model });
let selectedPostIds = controller.get("selectedPostIds");
assert.strictEqual( const controller = this.owner.lookup("controller:topic");
selectedPostIds[0], controller.setProperties({ model });
undefined,
assert.deepEqual(
controller.selectedPostIds,
[],
"no posts selected by default" "no posts selected by default"
); );
controller.send("selectBelow", { id: 3 }); controller.send("selectBelow", { id: 3 });
assert.deepEqual(controller.selectedPostIds, [3, 4, 5, 8]);
assert.strictEqual(selectedPostIds[0], 3, "selected post #3");
assert.strictEqual(
selectedPostIds[1],
4,
"also selected 1st post below post #3"
);
assert.strictEqual(
selectedPostIds[2],
5,
"also selected 2nd post below post #3"
);
assert.strictEqual(
selectedPostIds[3],
8,
"also selected 3rd post below post #3"
);
}); });
test("selectReplies", async function (assert) { test("selectReplies", async function (assert) {
@ -608,29 +513,30 @@ discourseModule("Unit | Controller | topic", function (hooks) {
response([{ id: 2, level: 1 }]) response([{ id: 2, level: 1 }])
); );
let model = topicWithStream({ const model = topicWithStream({
posts: [{ id: 1 }, { id: 2 }], posts: [{ id: 1 }, { id: 2 }],
}); });
const controller = this.getController("topic", { model }); const controller = this.owner.lookup("controller:topic");
controller.setProperties({ model });
controller.send("selectReplies", { id: 1 }); controller.send("selectReplies", { id: 1 });
await settled(); await settled();
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostsCount"), controller.selectedPostsCount,
2, 2,
"It should select two, the post and its replies" "It should select two, the post and its replies"
); );
controller.send("togglePostSelection", { id: 1 }); controller.send("togglePostSelection", { id: 1 });
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostsCount"), controller.selectedPostsCount,
1, 1,
"It should be selecting one only " "It should be selecting one only "
); );
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostIds")[0], controller.selectedPostIds[0],
2, 2,
"It should be selecting the reply id " "It should be selecting the reply id "
); );
@ -639,17 +545,18 @@ discourseModule("Unit | Controller | topic", function (hooks) {
await settled(); await settled();
assert.strictEqual( assert.strictEqual(
controller.get("selectedPostsCount"), controller.selectedPostsCount,
2, 2,
"It should be selecting two, even if reply was already selected" "It should be selecting two, even if reply was already selected"
); );
}); });
test("topVisibleChanged", function (assert) { test("topVisibleChanged", function (assert) {
let model = topicWithStream({ const model = topicWithStream({
posts: [{ id: 1 }], posts: [{ id: 1 }],
}); });
const controller = this.getController("topic", { model }); const controller = this.owner.lookup("controller:topic");
controller.setProperties({ model });
const placeholder = new Placeholder("post-placeholder"); const placeholder = new Placeholder("post-placeholder");
assert.strictEqual( assert.strictEqual(
@ -670,26 +577,17 @@ discourseModule("Unit | Controller | topic", function (hooks) {
post_number: 2, post_number: 2,
can_delete: true, can_delete: true,
reply_count: 3, reply_count: 3,
destroy: async () => { destroy: async () => (destroyed = true),
destroyed = true;
},
}); });
const currentUser = EmberObject.create({ moderator: true }); const currentUser = EmberObject.create({ moderator: true });
this.registry.register("service:current-user", currentUser, { const model = topicWithStream({
instantiate: false,
});
this.registry.injection(
"controller",
"currentUser",
"service:current-user"
);
let model = topicWithStream({
stream: [2, 3, 4], stream: [2, 3, 4],
posts: [post, { id: 3 }, { id: 4 }], posts: [post, { id: 3 }, { id: 4 }],
}); });
const controller = this.getController("topic", { model });
const controller = this.owner.lookup("controller:topic");
controller.setProperties({ model, currentUser });
const done = assert.async(); const done = assert.async();
controller.send("deletePost", post); controller.send("deletePost", post);

View File

@ -1,24 +1,23 @@
import { discourseModule } from "discourse/tests/helpers/qunit-helpers"; import { module, test } from "qunit";
import { test } from "qunit"; import { setupTest } from "ember-qunit";
import * as showModal from "discourse/lib/show-modal";
import sinon from "sinon"; import sinon from "sinon";
import pretender, { response } from "discourse/tests/helpers/create-pretender";
import EmberObject from "@ember/object"; import EmberObject from "@ember/object";
import * as showModal from "discourse/lib/show-modal";
import User from "discourse/models/user"; import User from "discourse/models/user";
import pretender from "discourse/tests/helpers/create-pretender";
import I18n from "I18n"; import I18n from "I18n";
discourseModule("Unit | Controller | user-notifications", function () { module("Unit | Controller | user-notifications", function (hooks) {
setupTest(hooks);
test("Mark read marks all models read when response is 200", async function (assert) { test("Mark read marks all models read when response is 200", async function (assert) {
const model = [ const model = [
EmberObject.create({ read: false }), EmberObject.create({ read: false }),
EmberObject.create({ read: false }), EmberObject.create({ read: false }),
]; ];
const controller = this.getController("user-notifications", { const controller = this.owner.lookup("controller:user-notifications");
model, controller.setProperties({ model });
}); pretender.put("/notifications/mark-read", () => response({}));
pretender.put("/notifications/mark-read", () => {
return [200];
});
await controller.markRead(); await controller.markRead();
@ -33,10 +32,9 @@ discourseModule("Unit | Controller | user-notifications", function () {
EmberObject.create({ read: false }), EmberObject.create({ read: false }),
EmberObject.create({ read: true }), EmberObject.create({ read: true }),
]; ];
const controller = this.getController("user-notifications", { model }); const controller = this.owner.lookup("controller:user-notifications");
pretender.put("/notifications/mark-read", () => { controller.setProperties({ model });
return [500]; pretender.put("/notifications/mark-read", () => response(500));
});
assert.rejects(controller.markRead()); assert.rejects(controller.markRead());
assert.deepEqual( assert.deepEqual(
@ -49,13 +47,12 @@ discourseModule("Unit | Controller | user-notifications", function () {
test("Marks all notifications read when no high priority notifications", function (assert) { test("Marks all notifications read when no high priority notifications", function (assert) {
let markRead = false; let markRead = false;
const currentUser = User.create({ unread_high_priority_notifications: 0 }); const currentUser = User.create({ unread_high_priority_notifications: 0 });
const controller = this.getController("user-notifications", { const controller = this.owner.lookup("controller:user-notifications");
controller.setProperties({
model: [], model: [],
currentUser, currentUser,
}); });
sinon.stub(controller, "markRead").callsFake(() => { sinon.stub(controller, "markRead").callsFake(() => (markRead = true));
markRead = true;
});
controller.send("resetNew"); controller.send("resetNew");
@ -70,10 +67,10 @@ discourseModule("Unit | Controller | user-notifications", function () {
.returns({ .returns({
setProperties: (properties) => (capturedProperties = properties), setProperties: (properties) => (capturedProperties = properties),
}); });
const currentUser = User.create({ unread_high_priority_notifications: 1 }); const currentUser = User.create({ unread_high_priority_notifications: 1 });
const controller = this.getController("user-notifications", { const controller = this.owner.lookup("controller:user-notifications");
currentUser, controller.setProperties({ currentUser });
});
const markReadFake = sinon.fake(); const markReadFake = sinon.fake();
sinon.stub(controller, "markRead").callsFake(markReadFake); sinon.stub(controller, "markRead").callsFake(markReadFake);

View File

@ -1,20 +1,22 @@
import { discourseModule } from "discourse/tests/helpers/qunit-helpers"; import { module, test } from "qunit";
import { setupTest } from "ember-qunit";
import { import {
MULTIPLE_POLL_TYPE, MULTIPLE_POLL_TYPE,
NUMBER_POLL_TYPE, NUMBER_POLL_TYPE,
REGULAR_POLL_TYPE, REGULAR_POLL_TYPE,
} from "discourse/plugins/poll/controllers/poll-ui-builder"; } from "discourse/plugins/poll/controllers/poll-ui-builder";
import { test } from "qunit";
import { settled } from "@ember/test-helpers"; import { settled } from "@ember/test-helpers";
function setupController(ctx) { function setupController(ctx) {
let controller = ctx.getController("poll-ui-builder"); const controller = ctx.owner.lookup("controller:poll-ui-builder");
controller.set("toolbarEvent", { getText: () => "" }); controller.set("toolbarEvent", { getText: () => "" });
controller.onShow(); controller.onShow();
return controller; return controller;
} }
discourseModule("Unit | Controller | poll-ui-builder", function () { module("Unit | Controller | poll-ui-builder", function (hooks) {
setupTest(hooks);
test("isMultiple", function (assert) { test("isMultiple", function (assert) {
const controller = setupController(this); const controller = setupController(this);
@ -22,14 +24,12 @@ discourseModule("Unit | Controller | poll-ui-builder", function () {
pollType: MULTIPLE_POLL_TYPE, pollType: MULTIPLE_POLL_TYPE,
pollOptions: [{ value: "a" }], pollOptions: [{ value: "a" }],
}); });
assert.strictEqual(controller.isMultiple, true, "it should be true"); assert.strictEqual(controller.isMultiple, true, "it should be true");
controller.setProperties({ controller.setProperties({
pollType: "random", pollType: "random",
pollOptions: [{ value: "b" }], pollOptions: [{ value: "b" }],
}); });
assert.strictEqual(controller.isMultiple, false, "it should be false"); assert.strictEqual(controller.isMultiple, false, "it should be false");
}); });
@ -37,11 +37,9 @@ discourseModule("Unit | Controller | poll-ui-builder", function () {
const controller = setupController(this); const controller = setupController(this);
controller.set("pollType", REGULAR_POLL_TYPE); controller.set("pollType", REGULAR_POLL_TYPE);
assert.strictEqual(controller.isNumber, false, "it should be false"); assert.strictEqual(controller.isNumber, false, "it should be false");
controller.set("pollType", NUMBER_POLL_TYPE); controller.set("pollType", NUMBER_POLL_TYPE);
assert.strictEqual(controller.isNumber, true, "it should be true"); assert.strictEqual(controller.isNumber, true, "it should be true");
}); });
@ -49,68 +47,60 @@ discourseModule("Unit | Controller | poll-ui-builder", function () {
const controller = setupController(this); const controller = setupController(this);
controller.set("pollOptions", [{ value: "1" }, { value: "2" }]); controller.set("pollOptions", [{ value: "1" }, { value: "2" }]);
assert.strictEqual(controller.pollOptionsCount, 2, "it should equal 2"); assert.strictEqual(controller.pollOptionsCount, 2, "it should equal 2");
controller.set("pollOptions", []); controller.set("pollOptions", []);
assert.strictEqual(controller.pollOptionsCount, 0, "it should equal 0"); assert.strictEqual(controller.pollOptionsCount, 0, "it should equal 0");
}); });
test("disableInsert", function (assert) { test("disableInsert", function (assert) {
const controller = setupController(this); const controller = setupController(this);
controller.siteSettings.poll_maximum_options = 20;
controller.siteSettings.poll_maximum_options = 20;
assert.strictEqual(controller.disableInsert, true, "it should be true"); assert.strictEqual(controller.disableInsert, true, "it should be true");
controller.set("pollOptions", [{ value: "a" }, { value: "b" }]); controller.set("pollOptions", [{ value: "a" }, { value: "b" }]);
assert.strictEqual(controller.disableInsert, false, "it should be false"); assert.strictEqual(controller.disableInsert, false, "it should be false");
controller.set("pollType", NUMBER_POLL_TYPE); controller.set("pollType", NUMBER_POLL_TYPE);
assert.strictEqual(controller.disableInsert, false, "it should be false"); assert.strictEqual(controller.disableInsert, false, "it should be false");
controller.setProperties({ controller.setProperties({
pollType: REGULAR_POLL_TYPE, pollType: REGULAR_POLL_TYPE,
pollOptions: [{ value: "a" }, { value: "b" }, { value: "c" }], pollOptions: [{ value: "a" }, { value: "b" }, { value: "c" }],
}); });
assert.strictEqual(controller.disableInsert, false, "it should be false"); assert.strictEqual(controller.disableInsert, false, "it should be false");
controller.setProperties({ controller.setProperties({
pollType: REGULAR_POLL_TYPE, pollType: REGULAR_POLL_TYPE,
pollOptions: [], pollOptions: [],
}); });
assert.strictEqual(controller.disableInsert, true, "it should be true"); assert.strictEqual(controller.disableInsert, true, "it should be true");
controller.setProperties({ controller.setProperties({
pollType: REGULAR_POLL_TYPE, pollType: REGULAR_POLL_TYPE,
pollOptions: [{ value: "w" }], pollOptions: [{ value: "w" }],
}); });
assert.strictEqual(controller.disableInsert, false, "it should be false"); assert.strictEqual(controller.disableInsert, false, "it should be false");
}); });
test("number pollOutput", async function (assert) { test("number pollOutput", async function (assert) {
this.siteSettings.poll_maximum_options = 20;
const controller = setupController(this); const controller = setupController(this);
controller.siteSettings.poll_maximum_options = 20;
controller.setProperties({ controller.setProperties({
pollType: NUMBER_POLL_TYPE, pollType: NUMBER_POLL_TYPE,
pollMin: 1, pollMin: 1,
}); });
await settled(); await settled();
assert.strictEqual( assert.strictEqual(
controller.pollOutput, controller.pollOutput,
"[poll type=number results=always min=1 max=20 step=1]\n[/poll]\n", "[poll type=number results=always min=1 max=20 step=1]\n[/poll]\n",
"it should return the right output" "it should return the right output"
); );
controller.set("pollStep", 2); controller.set("pollStep", 2);
await settled(); await settled();
assert.strictEqual( assert.strictEqual(
controller.pollOutput, controller.pollOutput,
"[poll type=number results=always min=1 max=20 step=2]\n[/poll]\n", "[poll type=number results=always min=1 max=20 step=2]\n[/poll]\n",
@ -118,7 +108,6 @@ discourseModule("Unit | Controller | poll-ui-builder", function () {
); );
controller.set("publicPoll", true); controller.set("publicPoll", true);
assert.strictEqual( assert.strictEqual(
controller.pollOutput, controller.pollOutput,
"[poll type=number results=always min=1 max=20 step=2 public=true]\n[/poll]\n", "[poll type=number results=always min=1 max=20 step=2 public=true]\n[/poll]\n",
@ -126,7 +115,6 @@ discourseModule("Unit | Controller | poll-ui-builder", function () {
); );
controller.set("pollStep", 0); controller.set("pollStep", 0);
assert.strictEqual( assert.strictEqual(
controller.pollOutput, controller.pollOutput,
"[poll type=number results=always min=1 max=20 step=1 public=true]\n[/poll]\n", "[poll type=number results=always min=1 max=20 step=1 public=true]\n[/poll]\n",
@ -142,7 +130,6 @@ discourseModule("Unit | Controller | poll-ui-builder", function () {
pollOptions: [{ value: "1" }, { value: "2" }], pollOptions: [{ value: "1" }, { value: "2" }],
pollType: REGULAR_POLL_TYPE, pollType: REGULAR_POLL_TYPE,
}); });
assert.strictEqual( assert.strictEqual(
controller.pollOutput, controller.pollOutput,
"[poll type=regular results=always chartType=bar]\n* 1\n* 2\n[/poll]\n", "[poll type=regular results=always chartType=bar]\n* 1\n* 2\n[/poll]\n",
@ -150,7 +137,6 @@ discourseModule("Unit | Controller | poll-ui-builder", function () {
); );
controller.set("publicPoll", "true"); controller.set("publicPoll", "true");
assert.strictEqual( assert.strictEqual(
controller.pollOutput, controller.pollOutput,
"[poll type=regular results=always public=true chartType=bar]\n* 1\n* 2\n[/poll]\n", "[poll type=regular results=always public=true chartType=bar]\n* 1\n* 2\n[/poll]\n",
@ -158,7 +144,6 @@ discourseModule("Unit | Controller | poll-ui-builder", function () {
); );
controller.set("pollGroups", "test"); controller.set("pollGroups", "test");
assert.strictEqual( assert.strictEqual(
controller.get("pollOutput"), controller.get("pollOutput"),
"[poll type=regular results=always public=true chartType=bar groups=test]\n* 1\n* 2\n[/poll]\n", "[poll type=regular results=always public=true chartType=bar groups=test]\n* 1\n* 2\n[/poll]\n",
@ -175,7 +160,6 @@ discourseModule("Unit | Controller | poll-ui-builder", function () {
pollMin: 1, pollMin: 1,
pollOptions: [{ value: "1" }, { value: "2" }], pollOptions: [{ value: "1" }, { value: "2" }],
}); });
assert.strictEqual( assert.strictEqual(
controller.pollOutput, controller.pollOutput,
"[poll type=multiple results=always min=1 max=2 chartType=bar]\n* 1\n* 2\n[/poll]\n", "[poll type=multiple results=always min=1 max=2 chartType=bar]\n* 1\n* 2\n[/poll]\n",
@ -183,7 +167,6 @@ discourseModule("Unit | Controller | poll-ui-builder", function () {
); );
controller.set("publicPoll", "true"); controller.set("publicPoll", "true");
assert.strictEqual( assert.strictEqual(
controller.pollOutput, controller.pollOutput,
"[poll type=multiple results=always min=1 max=2 public=true chartType=bar]\n* 1\n* 2\n[/poll]\n", "[poll type=multiple results=always min=1 max=2 public=true chartType=bar]\n* 1\n* 2\n[/poll]\n",