REFACTOR: New format for acceptance tests

This gets us closer to how newer Ember versions want to do things, but
with a bit of Discourse flair.

`acceptance` now takes a function as a parameter, and tests need to be
declared in that new function context.

A new helper, `needs`, is passed as a parameter. You can use it to set
up the test the way you want.
This commit is contained in:
Robin Ward 2020-10-15 15:46:23 -04:00
parent b5933e2b49
commit b3b9cf7c5d
22 changed files with 1187 additions and 1195 deletions

View File

@ -2,13 +2,13 @@ import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("About");
acceptance("About", function () {
test("viewing", async (assert) => {
await visit("/about");
test("viewing", async (assert) => {
await visit("/about");
assert.ok($("body.about-page").length, "has body class");
assert.ok(exists(".about.admins .user-info"), "has admins");
assert.ok(exists(".about.moderators .user-info"), "has moderators");
assert.ok(exists(".about.stats tr td"), "has stats");
assert.ok($("body.about-page").length, "has body class");
assert.ok(exists(".about.admins .user-info"), "has admins");
assert.ok(exists(".about.moderators .user-info"), "has moderators");
assert.ok(exists(".about.stats tr td"), "has stats");
});
});

View File

@ -3,88 +3,88 @@ import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import PreloadStore from "discourse/lib/preload-store";
acceptance("Account Created");
acceptance("Account Created", function () {
test("account created - message", async (assert) => {
PreloadStore.store("accountCreated", {
message: "Hello World",
});
await visit("/u/account-created");
test("account created - message", async (assert) => {
PreloadStore.store("accountCreated", {
message: "Hello World",
});
await visit("/u/account-created");
assert.ok(exists(".account-created"));
assert.equal(
find(".account-created .ac-message").text().trim(),
"Hello World",
"it displays the message"
);
assert.notOk(exists(".activation-controls"));
});
test("account created - resend email", async (assert) => {
PreloadStore.store("accountCreated", {
message: "Hello World",
username: "eviltrout",
email: "eviltrout@example.com",
show_controls: true,
assert.ok(exists(".account-created"));
assert.equal(
find(".account-created .ac-message").text().trim(),
"Hello World",
"it displays the message"
);
assert.notOk(exists(".activation-controls"));
});
await visit("/u/account-created");
test("account created - resend email", async (assert) => {
PreloadStore.store("accountCreated", {
message: "Hello World",
username: "eviltrout",
email: "eviltrout@example.com",
show_controls: true,
});
assert.ok(exists(".account-created"));
assert.equal(
find(".account-created .ac-message").text().trim(),
"Hello World",
"it displays the message"
);
await visit("/u/account-created");
await click(".activation-controls .resend");
assert.ok(exists(".account-created"));
assert.equal(
find(".account-created .ac-message").text().trim(),
"Hello World",
"it displays the message"
);
assert.equal(currentPath(), "account-created.resent");
const email = find(".account-created .ac-message b").text();
assert.equal(email, "eviltrout@example.com");
});
await click(".activation-controls .resend");
test("account created - update email - cancel", async (assert) => {
PreloadStore.store("accountCreated", {
message: "Hello World",
username: "eviltrout",
email: "eviltrout@example.com",
show_controls: true,
assert.equal(currentPath(), "account-created.resent");
const email = find(".account-created .ac-message b").text();
assert.equal(email, "eviltrout@example.com");
});
await visit("/u/account-created");
test("account created - update email - cancel", async (assert) => {
PreloadStore.store("accountCreated", {
message: "Hello World",
username: "eviltrout",
email: "eviltrout@example.com",
show_controls: true,
});
await click(".activation-controls .edit-email");
await visit("/u/account-created");
assert.equal(currentPath(), "account-created.edit-email");
assert.ok(find(".activation-controls .btn-primary:disabled").length);
await click(".activation-controls .edit-email");
await click(".activation-controls .edit-cancel");
assert.equal(currentPath(), "account-created.edit-email");
assert.ok(find(".activation-controls .btn-primary:disabled").length);
assert.equal(currentPath(), "account-created.index");
});
await click(".activation-controls .edit-cancel");
test("account created - update email - submit", async (assert) => {
PreloadStore.store("accountCreated", {
message: "Hello World",
username: "eviltrout",
email: "eviltrout@example.com",
show_controls: true,
assert.equal(currentPath(), "account-created.index");
});
await visit("/u/account-created");
test("account created - update email - submit", async (assert) => {
PreloadStore.store("accountCreated", {
message: "Hello World",
username: "eviltrout",
email: "eviltrout@example.com",
show_controls: true,
});
await click(".activation-controls .edit-email");
await visit("/u/account-created");
assert.ok(find(".activation-controls .btn-primary:disabled").length);
await click(".activation-controls .edit-email");
await fillIn(".activate-new-email", "newemail@example.com");
assert.ok(find(".activation-controls .btn-primary:disabled").length);
assert.notOk(find(".activation-controls .btn-primary:disabled").length);
await fillIn(".activate-new-email", "newemail@example.com");
await click(".activation-controls .btn-primary");
assert.notOk(find(".activation-controls .btn-primary:disabled").length);
assert.equal(currentPath(), "account-created.resent");
const email = find(".account-created .ac-message b").text();
assert.equal(email, "newemail@example.com");
await click(".activation-controls .btn-primary");
assert.equal(currentPath(), "account-created.resent");
const email = find(".account-created .ac-message b").text();
assert.equal(email, "newemail@example.com");
});
});

View File

@ -1,11 +1,8 @@
import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import pretender from "discourse/tests/helpers/create-pretender";
acceptance("Admin - Emails", { loggedIn: true });
const email = `
const EMAIL = `
From: "somebody" <somebody@example.com>
To: someone@example.com
Date: Mon, 3 Dec 2018 00:00:00 -0000
@ -16,28 +13,29 @@ Hello, this is a test!
---
This part should be elided.`.trim();
This part should be elided.`;
test("shows selected and elided text", async (assert) => {
pretender.post("/admin/email/advanced-test", () => {
return [
200,
{ "Content-Type": "application/json" },
{
acceptance("Admin - Emails", function (needs) {
needs.user();
needs.pretender((server, helper) => {
server.post("/admin/email/advanced-test", () => {
return helper.response({
format: 1,
text: "Hello, this is a test!",
elided: "---\n\nThis part should be elided.",
},
];
});
});
});
await visit("/admin/email/advanced-test");
await fillIn("textarea.email-body", email);
await click(".email-advanced-test button");
test("shows selected and elided text", async (assert) => {
await visit("/admin/email/advanced-test");
await fillIn("textarea.email-body", EMAIL.trim());
await click(".email-advanced-test button");
assert.equal(find(".text pre").text(), "Hello, this is a test!");
assert.equal(
find(".elided pre").text(),
"---\n\nThis part should be elided."
);
assert.equal(find(".text pre").text(), "Hello, this is a test!");
assert.equal(
find(".elided pre").text(),
"---\n\nThis part should be elided."
);
});
});

View File

@ -1,12 +1,15 @@
import { visit } from "@ember/test-helpers";
import { skip } from "qunit";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Admin - Search Log Term", { loggedIn: true });
skip("show search log term details", async (assert) => {
await visit("/admin/logs/search_logs/term?term=ruby");
acceptance("Admin - Search Log Term", function (needs) {
needs.user();
assert.ok($("div.search-logs-filter").length, "has the search type filter");
assert.ok(exists("canvas.chartjs-render-monitor"), "has graph canvas");
assert.ok(exists("div.header-search-results"), "has header search results");
test("show search log term details", async (assert) => {
await visit("/admin/logs/search_logs/term?term=ruby");
assert.ok($("div.search-logs-filter").length, "has the search type filter");
assert.ok(exists("canvas.chartjs-render-monitor"), "has graph canvas");
assert.ok(exists("div.header-search-results"), "has header search results");
});
});

View File

@ -1,22 +1,25 @@
import { visit } from "@ember/test-helpers";
import { skip } from "qunit";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Admin - Search Logs", { loggedIn: true });
skip("show search logs", async (assert) => {
await visit("/admin/logs/search_logs");
acceptance("Admin - Search Logs", function (needs) {
needs.user();
assert.ok($("table.search-logs-list.grid").length, "has the div class");
test("show search logs", async (assert) => {
await visit("/admin/logs/search_logs");
assert.ok(
exists(".search-logs-list .admin-list-item .col"),
"has a list of search logs"
);
assert.ok($("table.search-logs-list.grid").length, "has the div class");
await click(".term a");
assert.ok(
exists(".search-logs-list .admin-list-item .col"),
"has a list of search logs"
);
assert.ok(
$("div.search-logs-filter").length,
"it should show the search log term page"
);
await click(".term a");
assert.ok(
$("div.search-logs-filter").length,
"it should show the search log term page"
);
});
});

View File

@ -3,134 +3,139 @@ import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import siteSettingFixture from "discourse/tests/fixtures/site-settings";
var titleOverride = undefined;
acceptance("Admin - Site Settings", function (needs) {
let updatedTitle;
acceptance("Admin - Site Settings", {
loggedIn: true,
beforeEach() {
titleOverride = undefined;
},
pretend(server, helper) {
needs.user();
needs.pretender((server, helper) => {
server.put("/admin/site_settings/title", (body) => {
titleOverride = body.requestBody.split("=")[1];
updatedTitle = body.requestBody.split("=")[1];
return helper.response({ success: "OK" });
});
server.get("/admin/site_settings", () => {
const fixtures = siteSettingFixture["/admin/site_settings"].site_settings;
const titleSetting = Object.assign({}, fixtures[0]);
if (titleOverride) {
titleSetting.value = titleOverride;
if (updatedTitle) {
titleSetting.value = updatedTitle;
}
const response = {
site_settings: [titleSetting, ...fixtures.slice(1)],
};
return helper.response(response);
});
},
});
test("upload site setting", async (assert) => {
await visit("/admin/site_settings");
assert.ok(
exists(".row.setting.upload .image-uploader"),
"image uploader is present"
);
assert.ok(exists(".row.setting.upload .undo"), "undo button is present");
});
test("changing value updates dirty state", async (assert) => {
await visit("/admin/site_settings");
await fillIn("#setting-filter", " title ");
assert.equal(count(".row.setting"), 1, "filter returns 1 site setting");
assert.ok(!exists(".row.setting.overridden"), "setting isn't overriden");
await fillIn(".input-setting-string", "Test");
await click("button.cancel");
assert.ok(
!exists(".row.setting.overridden"),
"canceling doesn't mark setting as overriden"
);
await fillIn(".input-setting-string", "Test");
await click("button.ok");
assert.ok(
exists(".row.setting.overridden"),
"saving marks setting as overriden"
);
await click("button.undo");
assert.ok(
!exists(".row.setting.overridden"),
"setting isn't marked as overriden after undo"
);
await click("button.cancel");
assert.ok(
exists(".row.setting.overridden"),
"setting is marked as overriden after cancel"
);
await click("button.undo");
await click("button.ok");
assert.ok(
!exists(".row.setting.overridden"),
"setting isn't marked as overriden after undo"
);
await fillIn(".input-setting-string", "Test");
await keyEvent(".input-setting-string", "keydown", 13); // enter
assert.ok(
exists(".row.setting.overridden"),
"saving via Enter key marks setting as overriden"
);
});
test("always shows filtered site settings if a filter is set", async (assert) => {
await visit("/admin/site_settings");
await fillIn("#setting-filter", "title");
assert.equal(count(".row.setting"), 1);
// navigate away to the "Dashboard" page
await click(".nav.nav-pills li:nth-child(1) a");
assert.equal(count(".row.setting"), 0);
// navigate back to the "Settings" page
await click(".nav.nav-pills li:nth-child(2) a");
assert.equal(count(".row.setting"), 1);
});
test("filter settings by plugin name", async (assert) => {
await visit("/admin/site_settings");
await fillIn("#setting-filter", "plugin:discourse-logo");
assert.equal(count(".row.setting"), 1);
// inexistent plugin
await fillIn("#setting-filter", "plugin:discourse-plugin");
assert.equal(count(".row.setting"), 0);
});
test("category name is preserved", async (assert) => {
await visit("admin/site_settings/category/basic?filter=menu");
assert.equal(currentURL(), "admin/site_settings/category/basic?filter=menu");
});
test("shows all_results if current category has none", async (assert) => {
await visit("admin/site_settings");
await click(".admin-nav .basic a");
assert.equal(currentURL(), "/admin/site_settings/category/basic");
await fillIn("#setting-filter", "menu");
assert.equal(currentURL(), "/admin/site_settings/category/basic?filter=menu");
await fillIn("#setting-filter", "contact");
assert.equal(
currentURL(),
"/admin/site_settings/category/all_results?filter=contact"
);
});
needs.hooks.beforeEach(() => {
updatedTitle = null;
});
test("upload site setting", async (assert) => {
await visit("/admin/site_settings");
assert.ok(
exists(".row.setting.upload .image-uploader"),
"image uploader is present"
);
assert.ok(exists(".row.setting.upload .undo"), "undo button is present");
});
test("changing value updates dirty state", async (assert) => {
await visit("/admin/site_settings");
await fillIn("#setting-filter", " title ");
assert.equal(count(".row.setting"), 1, "filter returns 1 site setting");
assert.ok(!exists(".row.setting.overridden"), "setting isn't overriden");
await fillIn(".input-setting-string", "Test");
await click("button.cancel");
assert.ok(
!exists(".row.setting.overridden"),
"canceling doesn't mark setting as overriden"
);
await fillIn(".input-setting-string", "Test");
await click("button.ok");
assert.ok(
exists(".row.setting.overridden"),
"saving marks setting as overriden"
);
await click("button.undo");
assert.ok(
!exists(".row.setting.overridden"),
"setting isn't marked as overriden after undo"
);
await click("button.cancel");
assert.ok(
exists(".row.setting.overridden"),
"setting is marked as overriden after cancel"
);
await click("button.undo");
await click("button.ok");
assert.ok(
!exists(".row.setting.overridden"),
"setting isn't marked as overriden after undo"
);
await fillIn(".input-setting-string", "Test");
await keyEvent(".input-setting-string", "keydown", 13); // enter
assert.ok(
exists(".row.setting.overridden"),
"saving via Enter key marks setting as overriden"
);
});
test("always shows filtered site settings if a filter is set", async (assert) => {
await visit("/admin/site_settings");
await fillIn("#setting-filter", "title");
assert.equal(count(".row.setting"), 1);
// navigate away to the "Dashboard" page
await click(".nav.nav-pills li:nth-child(1) a");
assert.equal(count(".row.setting"), 0);
// navigate back to the "Settings" page
await click(".nav.nav-pills li:nth-child(2) a");
assert.equal(count(".row.setting"), 1);
});
test("filter settings by plugin name", async (assert) => {
await visit("/admin/site_settings");
await fillIn("#setting-filter", "plugin:discourse-logo");
assert.equal(count(".row.setting"), 1);
// inexistent plugin
await fillIn("#setting-filter", "plugin:discourse-plugin");
assert.equal(count(".row.setting"), 0);
});
test("category name is preserved", async (assert) => {
await visit("admin/site_settings/category/basic?filter=menu");
assert.equal(
currentURL(),
"admin/site_settings/category/basic?filter=menu"
);
});
test("shows all_results if current category has none", async (assert) => {
await visit("admin/site_settings");
await click(".admin-nav .basic a");
assert.equal(currentURL(), "/admin/site_settings/category/basic");
await fillIn("#setting-filter", "menu");
assert.equal(
currentURL(),
"/admin/site_settings/category/basic?filter=menu"
);
await fillIn("#setting-filter", "contact");
assert.equal(
currentURL(),
"/admin/site_settings/category/all_results?filter=contact"
);
});
});

View File

@ -2,50 +2,52 @@ import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Admin - Site Texts", { loggedIn: true });
acceptance("Admin - Site Texts", function (needs) {
needs.user();
test("search for a key", async (assert) => {
await visit("/admin/customize/site_texts");
test("search for a key", async (assert) => {
await visit("/admin/customize/site_texts");
await fillIn(".site-text-search", "Test");
await fillIn(".site-text-search", "Test");
assert.equal(currentURL(), "/admin/customize/site_texts?q=Test");
assert.ok(exists(".site-text"));
assert.ok(exists(".site-text:not(.overridden)"));
assert.ok(exists(".site-text.overridden"));
assert.equal(currentURL(), "/admin/customize/site_texts?q=Test");
assert.ok(exists(".site-text"));
assert.ok(exists(".site-text:not(.overridden)"));
assert.ok(exists(".site-text.overridden"));
// Only show overridden
await click(".search-area .filter-options input");
assert.equal(
currentURL(),
"/admin/customize/site_texts?overridden=true&q=Test"
);
// Only show overridden
await click(".search-area .filter-options input");
assert.equal(
currentURL(),
"/admin/customize/site_texts?overridden=true&q=Test"
);
assert.ok(!exists(".site-text:not(.overridden)"));
assert.ok(exists(".site-text.overridden"));
});
test("edit and revert a site text by key", async (assert) => {
await visit("/admin/customize/site_texts/site.test");
assert.equal(find(".title h3").text(), "site.test");
assert.ok(!exists(".saved"));
assert.ok(!exists(".revert-site-text"));
// Change the value
await fillIn(".site-text-value", "New Test Value");
await click(".save-changes");
assert.ok(exists(".saved"));
assert.ok(exists(".revert-site-text"));
// Revert the changes
await click(".revert-site-text");
assert.ok(exists(".bootbox.modal"));
await click(".bootbox.modal .btn-primary");
assert.ok(!exists(".saved"));
assert.ok(!exists(".revert-site-text"));
assert.ok(!exists(".site-text:not(.overridden)"));
assert.ok(exists(".site-text.overridden"));
});
test("edit and revert a site text by key", async (assert) => {
await visit("/admin/customize/site_texts/site.test");
assert.equal(find(".title h3").text(), "site.test");
assert.ok(!exists(".saved"));
assert.ok(!exists(".revert-site-text"));
// Change the value
await fillIn(".site-text-value", "New Test Value");
await click(".save-changes");
assert.ok(exists(".saved"));
assert.ok(exists(".revert-site-text"));
// Revert the changes
await click(".revert-site-text");
assert.ok(exists(".bootbox.modal"));
await click(".bootbox.modal .btn-primary");
assert.ok(!exists(".saved"));
assert.ok(!exists(".revert-site-text"));
});
});

View File

@ -3,10 +3,9 @@ import { test } from "qunit";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Admin - Suspend User", {
loggedIn: true,
pretend(server, helper) {
acceptance("Admin - Suspend User", function (needs) {
needs.user();
needs.pretender((server, helper) => {
server.put("/admin/users/:user_id/suspend", () =>
helper.response(200, {
suspension: {
@ -22,82 +21,82 @@ acceptance("Admin - Suspend User", {
},
})
);
},
});
test("suspend a user - cancel", async (assert) => {
await visit("/admin/users/1234/regular");
await click(".suspend-user");
assert.equal(find(".suspend-user-modal:visible").length, 1);
await click(".d-modal-cancel");
assert.equal(find(".suspend-user-modal:visible").length, 0);
});
test("suspend a user - cancel with input", async (assert) => {
await visit("/admin/users/1234/regular");
await click(".suspend-user");
assert.equal(find(".suspend-user-modal:visible").length, 1);
await fillIn(".suspend-reason", "for breaking the rules");
await fillIn(".suspend-message", "this is an email reason why");
await click(".d-modal-cancel");
assert.equal(find(".bootbox.modal:visible").length, 1);
await click(".modal-footer .btn-default");
assert.equal(find(".suspend-user-modal:visible").length, 1);
assert.equal(
find(".suspend-message")[0].value,
"this is an email reason why"
);
await click(".d-modal-cancel");
assert.equal(find(".bootbox.modal:visible").length, 1);
assert.equal(find(".suspend-user-modal:visible").length, 0);
await click(".modal-footer .btn-primary");
assert.equal(find(".bootbox.modal:visible").length, 0);
});
test("suspend, then unsuspend a user", async (assert) => {
const suspendUntilCombobox = selectKit(".suspend-until .combobox");
await visit("/admin/flags/active");
await visit("/admin/users/1234/regular");
assert.ok(!exists(".suspension-info"));
await click(".suspend-user");
assert.equal(
find(".perform-suspend[disabled]").length,
1,
"disabled by default"
);
await suspendUntilCombobox.expand();
await suspendUntilCombobox.selectRowByValue("tomorrow");
await fillIn(".suspend-reason", "for breaking the rules");
await fillIn(".suspend-message", "this is an email reason why");
assert.equal(
find(".perform-suspend[disabled]").length,
0,
"no longer disabled"
);
await click(".perform-suspend");
assert.equal(find(".suspend-user-modal:visible").length, 0);
assert.ok(exists(".suspension-info"));
await click(".unsuspend-user");
assert.ok(!exists(".suspension-info"));
});
test("suspend a user - cancel", async (assert) => {
await visit("/admin/users/1234/regular");
await click(".suspend-user");
assert.equal(find(".suspend-user-modal:visible").length, 1);
await click(".d-modal-cancel");
assert.equal(find(".suspend-user-modal:visible").length, 0);
});
test("suspend a user - cancel with input", async (assert) => {
await visit("/admin/users/1234/regular");
await click(".suspend-user");
assert.equal(find(".suspend-user-modal:visible").length, 1);
await fillIn(".suspend-reason", "for breaking the rules");
await fillIn(".suspend-message", "this is an email reason why");
await click(".d-modal-cancel");
assert.equal(find(".bootbox.modal:visible").length, 1);
await click(".modal-footer .btn-default");
assert.equal(find(".suspend-user-modal:visible").length, 1);
assert.equal(
find(".suspend-message")[0].value,
"this is an email reason why"
);
await click(".d-modal-cancel");
assert.equal(find(".bootbox.modal:visible").length, 1);
assert.equal(find(".suspend-user-modal:visible").length, 0);
await click(".modal-footer .btn-primary");
assert.equal(find(".bootbox.modal:visible").length, 0);
});
test("suspend, then unsuspend a user", async (assert) => {
const suspendUntilCombobox = selectKit(".suspend-until .combobox");
await visit("/admin/flags/active");
await visit("/admin/users/1234/regular");
assert.ok(!exists(".suspension-info"));
await click(".suspend-user");
assert.equal(
find(".perform-suspend[disabled]").length,
1,
"disabled by default"
);
await suspendUntilCombobox.expand();
await suspendUntilCombobox.selectRowByValue("tomorrow");
await fillIn(".suspend-reason", "for breaking the rules");
await fillIn(".suspend-message", "this is an email reason why");
assert.equal(
find(".perform-suspend[disabled]").length,
0,
"no longer disabled"
);
await click(".perform-suspend");
assert.equal(find(".suspend-user-modal:visible").length, 0);
assert.ok(exists(".suspension-info"));
await click(".unsuspend-user");
assert.ok(!exists(".suspension-info"));
});
});

View File

@ -2,10 +2,12 @@ import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Admin - Users Badges", { loggedIn: true });
acceptance("Admin - Users Badges", function (needs) {
needs.user();
test("lists badges", async (assert) => {
await visit("/admin/users/1/eviltrout/badges");
test("lists badges", async (assert) => {
await visit("/admin/users/1/eviltrout/badges");
assert.ok(exists(`span[data-badge-name="Badge 8"]`));
assert.ok(exists(`span[data-badge-name="Badge 8"]`));
});
});

View File

@ -3,9 +3,7 @@ import { test } from "qunit";
import I18n from "I18n";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Admin - User Emails", { loggedIn: true });
const assertNoSecondary = (assert) => {
function assertNoSecondary(assert) {
assert.equal(
find(".display-row.email .value a").text(),
"eviltrout@example.com",
@ -17,9 +15,9 @@ const assertNoSecondary = (assert) => {
I18n.t("user.email.no_secondary"),
"it should not display secondary emails"
);
};
}
const assertMultipleSecondary = (assert, firstEmail, secondEmail) => {
function assertMultipleSecondary(assert, firstEmail, secondEmail) {
assert.equal(
find(".display-row.secondary-emails .value li:first-of-type a").text(),
firstEmail,
@ -31,44 +29,48 @@ const assertMultipleSecondary = (assert, firstEmail, secondEmail) => {
secondEmail,
"it should display the second secondary email"
);
};
}
test("viewing self without secondary emails", async (assert) => {
await visit("/admin/users/1/eviltrout");
acceptance("Admin - User Emails", function (needs) {
needs.user();
assertNoSecondary(assert);
});
test("viewing self with multiple secondary emails", async (assert) => {
await visit("/admin/users/3/markvanlan");
assert.equal(
find(".display-row.email .value a").text(),
"markvanlan@example.com",
"it should display the user's primary email"
);
assertMultipleSecondary(
assert,
"markvanlan1@example.com",
"markvanlan2@example.com"
);
});
test("viewing another user with no secondary email", async (assert) => {
await visit("/admin/users/1234/regular");
await click(`.display-row.secondary-emails button`);
assertNoSecondary(assert);
});
test("viewing another account with secondary emails", async (assert) => {
await visit("/admin/users/1235/regular1");
await click(`.display-row.secondary-emails button`);
assertMultipleSecondary(
assert,
"regular2alt1@example.com",
"regular2alt2@example.com"
);
test("viewing self without secondary emails", async (assert) => {
await visit("/admin/users/1/eviltrout");
assertNoSecondary(assert);
});
test("viewing self with multiple secondary emails", async (assert) => {
await visit("/admin/users/3/markvanlan");
assert.equal(
find(".display-row.email .value a").text(),
"markvanlan@example.com",
"it should display the user's primary email"
);
assertMultipleSecondary(
assert,
"markvanlan1@example.com",
"markvanlan2@example.com"
);
});
test("viewing another user with no secondary email", async (assert) => {
await visit("/admin/users/1234/regular");
await click(`.display-row.secondary-emails button`);
assertNoSecondary(assert);
});
test("viewing another account with secondary emails", async (assert) => {
await visit("/admin/users/1235/regular1");
await click(`.display-row.secondary-emails button`);
assertMultipleSecondary(
assert,
"regular2alt1@example.com",
"regular2alt2@example.com"
);
});
});

View File

@ -2,12 +2,11 @@ import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import pretender from "discourse/tests/helpers/create-pretender";
acceptance("Admin - User Index", {
loggedIn: true,
pretend(pretenderServer, helper) {
pretenderServer.get("/groups/search.json", () => {
acceptance("Admin - User Index", function (needs) {
needs.user();
needs.pretender((server, helper) => {
server.get("/groups/search.json", () => {
return helper.response([
{
id: 42,
@ -33,60 +32,56 @@ acceptance("Admin - User Index", {
},
]);
});
},
});
test("can edit username", async (assert) => {
pretender.put("/users/sam/preferences/username", () => [
200,
{
"Content-Type": "application/json",
},
{ id: 2, username: "new-sam" },
]);
await visit("/admin/users/2/sam");
assert.equal(find(".display-row.username .value").text().trim(), "sam");
// Trying cancel.
await click(".display-row.username button");
await fillIn(".display-row.username .value input", "new-sam");
await click(".display-row.username a");
assert.equal(find(".display-row.username .value").text().trim(), "sam");
// Doing edit.
await click(".display-row.username button");
await fillIn(".display-row.username .value input", "new-sam");
await click(".display-row.username button");
assert.equal(find(".display-row.username .value").text().trim(), "new-sam");
});
test("will clear unsaved groups when switching user", async (assert) => {
await visit("/admin/users/2/sam");
assert.equal(
find(".display-row.username .value").text().trim(),
"sam",
"the name should be correct"
);
const groupChooser = selectKit(".group-chooser");
await groupChooser.expand();
await groupChooser.selectRowByValue(42);
assert.equal(groupChooser.header().value(), 42, "group should be set");
await visit("/admin/users/1/eviltrout");
assert.equal(
find(".display-row.username .value").text().trim(),
"eviltrout",
"the name should be correct"
);
assert.equal(
find('.group-chooser span[title="Macdonald"]').length,
0,
"group should not be set"
);
server.put("/users/sam/preferences/username", () => {
return helper.response({ id: 2, username: "new-sam" });
});
});
test("can edit username", async (assert) => {
await visit("/admin/users/2/sam");
assert.equal(find(".display-row.username .value").text().trim(), "sam");
// Trying cancel.
await click(".display-row.username button");
await fillIn(".display-row.username .value input", "new-sam");
await click(".display-row.username a");
assert.equal(find(".display-row.username .value").text().trim(), "sam");
// Doing edit.
await click(".display-row.username button");
await fillIn(".display-row.username .value input", "new-sam");
await click(".display-row.username button");
assert.equal(find(".display-row.username .value").text().trim(), "new-sam");
});
test("will clear unsaved groups when switching user", async (assert) => {
await visit("/admin/users/2/sam");
assert.equal(
find(".display-row.username .value").text().trim(),
"sam",
"the name should be correct"
);
const groupChooser = selectKit(".group-chooser");
await groupChooser.expand();
await groupChooser.selectRowByValue(42);
assert.equal(groupChooser.header().value(), 42, "group should be set");
await visit("/admin/users/1/eviltrout");
assert.equal(
find(".display-row.username .value").text().trim(),
"eviltrout",
"the name should be correct"
);
assert.equal(
find('.group-chooser span[title="Macdonald"]').length,
0,
"group should not be set"
);
});
});

View File

@ -3,96 +3,102 @@ import { test } from "qunit";
import I18n from "I18n";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Admin - Users List", { loggedIn: true });
acceptance("Admin - Users List", function (needs) {
needs.user();
test("lists users", async (assert) => {
await visit("/admin/users/list/active");
test("lists users", async (assert) => {
await visit("/admin/users/list/active");
assert.ok(exists(".users-list .user"));
assert.ok(!exists(".user:eq(0) .email small"), "escapes email");
});
test("sorts users", async (assert) => {
await visit("/admin/users/list/active");
assert.ok(exists(".users-list .user"));
await click(".users-list .sortable:nth-child(1)");
assert.ok(
find(".users-list .user:nth-child(1) .username")
.text()
.includes("eviltrout"),
"list should be sorted by username"
);
await click(".users-list .sortable:nth-child(1)");
assert.ok(
find(".users-list .user:nth-child(1) .username")
.text()
.includes("discobot"),
"list should be sorted ascending by username"
);
});
test("toggles email visibility", async (assert) => {
await visit("/admin/users/list/active");
assert.ok(exists(".users-list .user"));
await click(".show-emails");
assert.equal(
find(".users-list .user:nth-child(1) .email").text(),
"<small>eviltrout@example.com</small>",
"shows the emails"
);
await click(".hide-emails");
assert.equal(
find(".users-list .user:nth-child(1) .email").text(),
"",
"hides the emails"
);
});
test("switching tabs", async (assert) => {
const activeUser = "eviltrout";
const suspectUser = "sam";
const activeTitle = I18n.t("admin.users.titles.active");
const suspectTitle = I18n.t("admin.users.titles.new");
await visit("/admin/users/list/active");
assert.equal(find(".admin-title h2").text(), activeTitle);
assert.ok(
find(".users-list .user:nth-child(1) .username").text().includes(activeUser)
);
await click('a[href="/admin/users/list/new"]');
assert.equal(find(".admin-title h2").text(), suspectTitle);
assert.ok(
find(".users-list .user:nth-child(1) .username")
.text()
.includes(suspectUser)
);
await click(".users-list .sortable:nth-child(4)");
assert.equal(find(".admin-title h2").text(), suspectTitle);
assert.ok(
find(".users-list .user:nth-child(1) .username")
.text()
.includes(suspectUser)
);
await click('a[href="/admin/users/list/active"]');
assert.equal(find(".admin-title h2").text(), activeTitle);
assert.ok(
find(".users-list .user:nth-child(1) .username").text().includes(activeUser)
);
assert.ok(exists(".users-list .user"));
assert.ok(!exists(".user:eq(0) .email small"), "escapes email");
});
test("sorts users", async (assert) => {
await visit("/admin/users/list/active");
assert.ok(exists(".users-list .user"));
await click(".users-list .sortable:nth-child(1)");
assert.ok(
find(".users-list .user:nth-child(1) .username")
.text()
.includes("eviltrout"),
"list should be sorted by username"
);
await click(".users-list .sortable:nth-child(1)");
assert.ok(
find(".users-list .user:nth-child(1) .username")
.text()
.includes("discobot"),
"list should be sorted ascending by username"
);
});
test("toggles email visibility", async (assert) => {
await visit("/admin/users/list/active");
assert.ok(exists(".users-list .user"));
await click(".show-emails");
assert.equal(
find(".users-list .user:nth-child(1) .email").text(),
"<small>eviltrout@example.com</small>",
"shows the emails"
);
await click(".hide-emails");
assert.equal(
find(".users-list .user:nth-child(1) .email").text(),
"",
"hides the emails"
);
});
test("switching tabs", async (assert) => {
const activeUser = "eviltrout";
const suspectUser = "sam";
const activeTitle = I18n.t("admin.users.titles.active");
const suspectTitle = I18n.t("admin.users.titles.new");
await visit("/admin/users/list/active");
assert.equal(find(".admin-title h2").text(), activeTitle);
assert.ok(
find(".users-list .user:nth-child(1) .username")
.text()
.includes(activeUser)
);
await click('a[href="/admin/users/list/new"]');
assert.equal(find(".admin-title h2").text(), suspectTitle);
assert.ok(
find(".users-list .user:nth-child(1) .username")
.text()
.includes(suspectUser)
);
await click(".users-list .sortable:nth-child(4)");
assert.equal(find(".admin-title h2").text(), suspectTitle);
assert.ok(
find(".users-list .user:nth-child(1) .username")
.text()
.includes(suspectUser)
);
await click('a[href="/admin/users/list/active"]');
assert.equal(find(".admin-title h2").text(), activeTitle);
assert.ok(
find(".users-list .user:nth-child(1) .username")
.text()
.includes(activeUser)
);
});
});

View File

@ -1,75 +1,78 @@
import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Admin - Watched Words", { loggedIn: true });
test("list words in groups", async (assert) => {
await visit("/admin/logs/watched_words/action/block");
acceptance("Admin - Watched Words", function (needs) {
needs.user();
assert.ok(exists(".watched-words-list"));
assert.ok(
!exists(".watched-words-list .watched-word"),
"Don't show bad words by default."
);
test("list words in groups", async (assert) => {
await visit("/admin/logs/watched_words/action/block");
await fillIn(".admin-controls .controls input[type=text]", "li");
assert.ok(exists(".watched-words-list"));
assert.ok(
!exists(".watched-words-list .watched-word"),
"Don't show bad words by default."
);
assert.equal(
find(".watched-words-list .watched-word").length,
1,
"When filtering, show words even if checkbox is unchecked."
);
await fillIn(".admin-controls .controls input[type=text]", "li");
await fillIn(".admin-controls .controls input[type=text]", "");
assert.equal(
find(".watched-words-list .watched-word").length,
1,
"When filtering, show words even if checkbox is unchecked."
);
assert.ok(
!exists(".watched-words-list .watched-word"),
"Clearing the filter hides words again."
);
await fillIn(".admin-controls .controls input[type=text]", "");
await click(".show-words-checkbox");
assert.ok(
!exists(".watched-words-list .watched-word"),
"Clearing the filter hides words again."
);
assert.ok(
exists(".watched-words-list .watched-word"),
"Always show the words when checkbox is checked."
);
await click(".show-words-checkbox");
await click(".nav-stacked .censor a");
assert.ok(
exists(".watched-words-list .watched-word"),
"Always show the words when checkbox is checked."
);
assert.ok(exists(".watched-words-list"));
assert.ok(!exists(".watched-words-list .watched-word"), "Empty word list.");
});
await click(".nav-stacked .censor a");
test("add words", async (assert) => {
await visit("/admin/logs/watched_words/action/block");
click(".show-words-checkbox");
fillIn(".watched-word-form input", "poutine");
await click(".watched-word-form button");
let found = [];
$.each(find(".watched-words-list .watched-word"), (index, elem) => {
if ($(elem).text().trim() === "poutine") {
found.push(true);
}
});
assert.equal(found.length, 1);
});
test("remove words", async (assert) => {
await visit("/admin/logs/watched_words/action/block");
await click(".show-words-checkbox");
let word = null;
$.each(find(".watched-words-list .watched-word"), (index, elem) => {
if ($(elem).text().trim() === "anise") {
word = elem;
}
assert.ok(exists(".watched-words-list"));
assert.ok(!exists(".watched-words-list .watched-word"), "Empty word list.");
});
await click("#" + $(word).attr("id"));
test("add words", async (assert) => {
await visit("/admin/logs/watched_words/action/block");
assert.equal(find(".watched-words-list .watched-word").length, 2);
click(".show-words-checkbox");
fillIn(".watched-word-form input", "poutine");
await click(".watched-word-form button");
let found = [];
$.each(find(".watched-words-list .watched-word"), (index, elem) => {
if ($(elem).text().trim() === "poutine") {
found.push(true);
}
});
assert.equal(found.length, 1);
});
test("remove words", async (assert) => {
await visit("/admin/logs/watched_words/action/block");
await click(".show-words-checkbox");
let word = null;
$.each(find(".watched-words-list .watched-word"), (index, elem) => {
if ($(elem).text().trim() === "anise") {
word = elem;
}
});
await click("#" + $(word).attr("id"));
assert.equal(find(".watched-words-list .watched-word").length, 2);
});
});

View File

@ -1,8 +1,9 @@
import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Auth Complete", {
beforeEach() {
acceptance("Auth Complete", function (needs) {
needs.hooks.beforeEach(() => {
const node = document.createElement("meta");
node.dataset.authenticationData = JSON.stringify({
auth_provider: "test",
@ -10,33 +11,34 @@ acceptance("Auth Complete", {
});
node.id = "data-authentication";
document.querySelector("head").appendChild(node);
},
afterEach() {
});
needs.hooks.afterEach(() => {
document
.querySelector("head")
.removeChild(document.getElementById("data-authentication"));
},
});
test("when login not required", async (assert) => {
await visit("/");
assert.equal(currentPath(), "discovery.latest", "it stays on the homepage");
assert.ok(
exists("#discourse-modal div.create-account"),
"it shows the registration modal"
);
});
test("when login required", async function (assert) {
this.siteSettings.login_required = true;
await visit("/");
assert.equal(currentPath(), "login", "it redirects to the login page");
assert.ok(
exists("#discourse-modal div.create-account"),
"it shows the registration modal"
);
});
test("when login not required", async (assert) => {
await visit("/");
assert.equal(currentPath(), "discovery.latest", "it stays on the homepage");
assert.ok(
exists("#discourse-modal div.create-account"),
"it shows the registration modal"
);
});
test("when login required", async function (assert) {
this.siteSettings.login_required = true;
await visit("/");
assert.equal(currentPath(), "login", "it redirects to the login page");
assert.ok(
exists("#discourse-modal div.create-account"),
"it shows the registration modal"
);
});
});

View File

@ -3,24 +3,26 @@ import { test } from "qunit";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Badges", { loggedIn: true });
acceptance("Badges", function (needs) {
needs.user();
test("Visit Badge Pages", async (assert) => {
await visit("/badges");
test("Visit Badge Pages", async (assert) => {
await visit("/badges");
assert.ok($("body.badges-page").length, "has body class");
assert.ok(exists(".badge-groups .badge-card"), "has a list of badges");
assert.ok($("body.badges-page").length, "has body class");
assert.ok(exists(".badge-groups .badge-card"), "has a list of badges");
await visit("/badges/9/autobiographer");
await visit("/badges/9/autobiographer");
assert.ok(exists(".badge-card"), "has the badge in the listing");
assert.ok(exists(".user-info"), "has the list of users with that badge");
assert.ok(!exists(".badge-card:eq(0) script"));
});
test("shows correct badge titles to choose from", async (assert) => {
const availableBadgeTitles = selectKit(".select-kit");
await visit("/badges/50/custombadge");
await availableBadgeTitles.expand();
assert.ok(availableBadgeTitles.rowByIndex(1).name() === "CustomBadge");
assert.ok(exists(".badge-card"), "has the badge in the listing");
assert.ok(exists(".user-info"), "has the list of users with that badge");
assert.ok(!exists(".badge-card:eq(0) script"));
});
test("shows correct badge titles to choose from", async (assert) => {
const availableBadgeTitles = selectKit(".select-kit");
await visit("/badges/50/custombadge");
await availableBadgeTitles.expand();
assert.ok(availableBadgeTitles.rowByIndex(1).name() === "CustomBadge");
});
});

View File

@ -1,50 +1,16 @@
import { visit } from "@ember/test-helpers";
import { skip } from "qunit";
import { test } from "qunit";
import I18n from "I18n";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import {
acceptance,
loggedInUser,
acceptanceUseFakeClock,
} from "discourse/tests/helpers/qunit-helpers";
import pretender, {
parsePostData,
} from "discourse/tests/helpers/create-pretender";
acceptance("Bookmarking", {
loggedIn: true,
afterEach() {
sandbox.restore();
},
});
function handleRequest(assert, request) {
const data = parsePostData(request.requestBody);
assert.step(data.reminder_type || "none");
return [
200,
{
"Content-Type": "application/json",
},
{
id: 999,
success: "OK",
},
];
}
function mockSuccessfulBookmarkPost(assert) {
pretender.post("/bookmarks", (request) => handleRequest(assert, request));
pretender.put("/bookmarks/999", (request) => handleRequest(assert, request));
}
async function openBookmarkModal() {
if (exists(".topic-post:first-child button.show-more-actions")) {
await click(".topic-post:first-child button.show-more-actions");
}
await click(".topic-post:first-child button.bookmark");
}
@ -52,209 +18,189 @@ async function openEditBookmarkModal() {
await click(".topic-post:first-child button.bookmarked");
}
test("Bookmarks modal opening", async (assert) => {
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
assert.ok(exists("#bookmark-reminder-modal"), "it shows the bookmark modal");
});
acceptance("Bookmarking", function (needs) {
needs.user();
let steps = [];
test("Bookmarks modal selecting reminder type", async (assert) => {
mockSuccessfulBookmarkPost(assert);
needs.hooks.beforeEach(() => (steps = []));
await visit("/t/internationalization-localization/280");
needs.pretender((server, helper) => {
function handleRequest(request) {
const data = helper.parsePostData(request.requestBody);
steps.push(data.reminder_type || "none");
return helper.response({ id: 999, success: "OK" });
}
server.post("/bookmarks", handleRequest);
server.put("/bookmarks/999", handleRequest);
server.delete("/bookmarks/999", () =>
helper.response({ success: "OK", topic_bookmarked: false })
);
});
await openBookmarkModal();
await click("#tap_tile_tomorrow");
await openBookmarkModal();
await click("#tap_tile_start_of_next_business_week");
await openBookmarkModal();
await click("#tap_tile_next_week");
await openBookmarkModal();
await click("#tap_tile_next_month");
await openBookmarkModal();
await click("#tap_tile_custom");
assert.ok(exists("#tap_tile_custom.active"), "it selects custom");
assert.ok(exists(".tap-tile-date-input"), "it shows the custom date input");
assert.ok(exists(".tap-tile-time-input"), "it shows the custom time input");
await click("#save-bookmark");
assert.verifySteps([
"tomorrow",
"start_of_next_business_week",
"next_week",
"next_month",
"custom",
]);
});
test("Saving a bookmark with a reminder", async (assert) => {
mockSuccessfulBookmarkPost(assert);
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await fillIn("input#bookmark-name", "Check this out later");
await click("#tap_tile_tomorrow");
assert.ok(
exists(".topic-post:first-child button.bookmark.bookmarked"),
"it shows the bookmarked icon on the post"
);
assert.ok(
exists(
".topic-post:first-child button.bookmark.bookmarked > .d-icon-discourse-bookmark-clock"
),
"it shows the bookmark clock icon because of the reminder"
);
assert.verifySteps(["tomorrow"]);
});
test("Opening the options panel and remembering the option", async (assert) => {
mockSuccessfulBookmarkPost(assert);
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await click(".bookmark-options-button");
assert.ok(
exists(".bookmark-options-panel"),
"it should open the options panel"
);
await selectKit(".bookmark-option-selector").expand();
await selectKit(".bookmark-option-selector").selectRowByValue(1);
await click("#save-bookmark");
await openEditBookmarkModal();
assert.ok(
exists(".bookmark-options-panel"),
"it should reopen the options panel"
);
assert.equal(selectKit(".bookmark-option-selector").header().value(), 1);
assert.verifySteps(["none"]);
});
test("Saving a bookmark with no reminder or name", async (assert) => {
mockSuccessfulBookmarkPost(assert);
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await click("#save-bookmark");
assert.ok(
exists(".topic-post:first-child button.bookmark.bookmarked"),
"it shows the bookmarked icon on the post"
);
assert.not(
exists(
".topic-post:first-child button.bookmark.bookmarked > .d-icon-discourse-bookmark-clock"
),
"it shows the regular bookmark active icon"
);
assert.verifySteps(["none"]);
});
test("Deleting a bookmark with a reminder", async (assert) => {
pretender.delete("/bookmarks/999", () => [
200,
{
"Content-Type": "application/json",
},
{
success: "OK",
topic_bookmarked: false,
},
]);
mockSuccessfulBookmarkPost(assert);
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await click("#tap_tile_tomorrow");
assert.verifySteps(["tomorrow"]);
await openEditBookmarkModal();
assert.ok(exists("#bookmark-reminder-modal"), "it shows the bookmark modal");
await click("#delete-bookmark");
assert.ok(exists(".bootbox.modal"), "it asks for delete confirmation");
assert.ok(
find(".bootbox.modal").text().includes(I18n.t("bookmarks.confirm_delete")),
"it shows delete confirmation message"
);
await click(".bootbox.modal .btn-primary");
assert.not(
exists(".topic-post:first-child button.bookmark.bookmarked"),
"it no longer shows the bookmarked icon on the post after bookmark is deleted"
);
});
test("Cancelling saving a bookmark", async (assert) => {
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await click(".d-modal-cancel");
assert.not(
exists(".topic-post:first-child button.bookmark.bookmarked"),
"it does not show the bookmarked icon on the post because it is not saved"
);
});
test("Editing a bookmark", async (assert) => {
mockSuccessfulBookmarkPost(assert);
await visit("/t/internationalization-localization/280");
let now = moment.tz(loggedInUser().resolvedTimezone(loggedInUser()));
let tomorrow = now.add(1, "day").format("YYYY-MM-DD");
await openBookmarkModal();
await fillIn("input#bookmark-name", "Test name");
await click("#tap_tile_tomorrow");
await openEditBookmarkModal();
assert.equal(
find("#bookmark-name").val(),
"Test name",
"it should prefill the bookmark name"
);
assert.equal(
find("#bookmark-custom-date > input").val(),
tomorrow,
"it should prefill the bookmark date"
);
assert.equal(
find("#bookmark-custom-time").val(),
"08:00",
"it should prefill the bookmark time"
);
assert.verifySteps(["tomorrow"]);
});
acceptance("Bookmarking - Mobile", {
loggedIn: true,
mobileView: true,
afterEach() {
sandbox.restore();
},
});
skip("Editing a bookmark that has a Later Today reminder, and it is before 6pm today", async (assert) => {
await acceptanceUseFakeClock("2020-05-04T13:00:00", async () => {
mockSuccessfulBookmarkPost(assert);
test("Bookmarks modal opening", async (assert) => {
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await fillIn("input#bookmark-name", "Test name");
await click("#tap_tile_later_today");
await openEditBookmarkModal();
assert.not(
exists("#bookmark-custom-date > input"),
"it does not show the custom date input"
assert.ok(
exists("#bookmark-reminder-modal"),
"it shows the bookmark modal"
);
});
test("Bookmarks modal selecting reminder type", async (assert) => {
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await click("#tap_tile_tomorrow");
await openBookmarkModal();
await click("#tap_tile_start_of_next_business_week");
await openBookmarkModal();
await click("#tap_tile_next_week");
await openBookmarkModal();
await click("#tap_tile_next_month");
await openBookmarkModal();
await click("#tap_tile_custom");
assert.ok(exists("#tap_tile_custom.active"), "it selects custom");
assert.ok(exists(".tap-tile-date-input"), "it shows the custom date input");
assert.ok(exists(".tap-tile-time-input"), "it shows the custom time input");
await click("#save-bookmark");
assert.deepEqual(steps, [
"tomorrow",
"start_of_next_business_week",
"next_week",
"next_month",
"custom",
]);
});
test("Saving a bookmark with a reminder", async (assert) => {
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await fillIn("input#bookmark-name", "Check this out later");
await click("#tap_tile_tomorrow");
assert.ok(
exists(".topic-post:first-child button.bookmark.bookmarked"),
"it shows the bookmarked icon on the post"
);
assert.ok(
exists("#tap_tile_later_today.active"),
"it preselects Later Today"
exists(
".topic-post:first-child button.bookmark.bookmarked > .d-icon-discourse-bookmark-clock"
),
"it shows the bookmark clock icon because of the reminder"
);
assert.verifySteps(["later_today"]);
assert.deepEqual(steps, ["tomorrow"]);
});
test("Opening the options panel and remembering the option", async (assert) => {
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await click(".bookmark-options-button");
assert.ok(
exists(".bookmark-options-panel"),
"it should open the options panel"
);
await selectKit(".bookmark-option-selector").expand();
await selectKit(".bookmark-option-selector").selectRowByValue(1);
await click("#save-bookmark");
await openEditBookmarkModal();
assert.ok(
exists(".bookmark-options-panel"),
"it should reopen the options panel"
);
assert.equal(selectKit(".bookmark-option-selector").header().value(), 1);
assert.deepEqual(steps, ["none"]);
});
test("Saving a bookmark with no reminder or name", async (assert) => {
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await click("#save-bookmark");
assert.ok(
exists(".topic-post:first-child button.bookmark.bookmarked"),
"it shows the bookmarked icon on the post"
);
assert.not(
exists(
".topic-post:first-child button.bookmark.bookmarked > .d-icon-discourse-bookmark-clock"
),
"it shows the regular bookmark active icon"
);
assert.deepEqual(steps, ["none"]);
});
test("Deleting a bookmark with a reminder", async (assert) => {
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await click("#tap_tile_tomorrow");
assert.deepEqual(steps, ["tomorrow"]);
await openEditBookmarkModal();
assert.ok(
exists("#bookmark-reminder-modal"),
"it shows the bookmark modal"
);
await click("#delete-bookmark");
assert.ok(exists(".bootbox.modal"), "it asks for delete confirmation");
assert.ok(
find(".bootbox.modal")
.text()
.includes(I18n.t("bookmarks.confirm_delete")),
"it shows delete confirmation message"
);
await click(".bootbox.modal .btn-primary");
assert.not(
exists(".topic-post:first-child button.bookmark.bookmarked"),
"it no longer shows the bookmarked icon on the post after bookmark is deleted"
);
});
test("Cancelling saving a bookmark", async (assert) => {
await visit("/t/internationalization-localization/280");
await openBookmarkModal();
await click(".d-modal-cancel");
assert.not(
exists(".topic-post:first-child button.bookmark.bookmarked"),
"it does not show the bookmarked icon on the post because it is not saved"
);
});
test("Editing a bookmark", async (assert) => {
await visit("/t/internationalization-localization/280");
let now = moment.tz(loggedInUser().resolvedTimezone(loggedInUser()));
let tomorrow = now.add(1, "day").format("YYYY-MM-DD");
await openBookmarkModal();
await fillIn("input#bookmark-name", "Test name");
await click("#tap_tile_tomorrow");
await openEditBookmarkModal();
assert.equal(
find("#bookmark-name").val(),
"Test name",
"it should prefill the bookmark name"
);
assert.equal(
find("#bookmark-custom-date > input").val(),
tomorrow,
"it should prefill the bookmark date"
);
assert.equal(
find("#bookmark-custom-time").val(),
"08:00",
"it should prefill the bookmark time"
);
assert.deepEqual(steps, ["tomorrow"]);
});
});

View File

@ -3,8 +3,9 @@ import { test } from "qunit";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import DiscoveryFixtures from "discourse/tests/fixtures/discovery-fixtures";
acceptance("Category Banners", {
pretend(server, helper) {
acceptance("Category Banners", function (needs) {
needs.user();
needs.pretender((server, helper) => {
server.get("/c/test-read-only-without-banner/5/l/latest.json", () => {
return helper.response(
DiscoveryFixtures["/latest_can_create_topic.json"]
@ -15,9 +16,8 @@ acceptance("Category Banners", {
DiscoveryFixtures["/latest_can_create_topic.json"]
);
});
},
loggedIn: true,
site: {
});
needs.site({
categories: [
{
id: 5,
@ -34,45 +34,44 @@ acceptance("Category Banners", {
"You need to video yourself <div class='inner'>doing</div> the secret handshake to post here",
},
],
},
});
test("Does not display category banners when not set", async (assert) => {
await visit("/c/test-read-only-without-banner");
await click("#create-topic");
assert.ok(!visible(".bootbox.modal"), "it does not pop up a modal");
assert.ok(
!visible(".category-read-only-banner"),
"it does not show a banner"
);
});
test("Displays category banners when set", async (assert) => {
await visit("/c/test-read-only-with-banner");
await click("#create-topic");
assert.ok(visible(".bootbox.modal"), "it pops up a modal");
await click(".modal-footer>.btn-primary");
assert.ok(!visible(".bootbox.modal"), "it closes the modal");
assert.ok(visible(".category-read-only-banner"), "it shows a banner");
assert.ok(
find(".category-read-only-banner .inner").length === 1,
"it allows staff to embed html in the message"
);
});
});
test("Does not display category banners when not set", async (assert) => {
await visit("/c/test-read-only-without-banner");
await click("#create-topic");
assert.ok(!visible(".bootbox.modal"), "it does not pop up a modal");
assert.ok(
!visible(".category-read-only-banner"),
"it does not show a banner"
);
});
test("Displays category banners when set", async (assert) => {
await visit("/c/test-read-only-with-banner");
await click("#create-topic");
assert.ok(visible(".bootbox.modal"), "it pops up a modal");
await click(".modal-footer>.btn-primary");
assert.ok(!visible(".bootbox.modal"), "it closes the modal");
assert.ok(visible(".category-read-only-banner"), "it shows a banner");
assert.ok(
find(".category-read-only-banner .inner").length === 1,
"it allows staff to embed html in the message"
);
});
acceptance("Anonymous Category Banners", {
pretend(server, helper) {
acceptance("Anonymous Category Banners", function (needs) {
needs.pretender((server, helper) => {
server.get("/c/test-read-only-with-banner/6/l/latest.json", () => {
return helper.response(
DiscoveryFixtures["/latest_can_create_topic.json"]
);
});
},
loggedIn: false,
site: {
});
needs.site({
categories: [
{
id: 6,
@ -83,13 +82,13 @@ acceptance("Anonymous Category Banners", {
"You need to video yourself doing the secret handshake to post here",
},
],
},
});
});
test("Does not display category banners when set", async (assert) => {
await visit("/c/test-read-only-with-banner");
assert.ok(
!visible(".category-read-only-banner"),
"it does not show a banner"
);
test("Does not display category banners when set", async (assert) => {
await visit("/c/test-read-only-with-banner");
assert.ok(
!visible(".category-read-only-banner"),
"it does not show a banner"
);
});
});

View File

@ -3,26 +3,25 @@ import { test } from "qunit";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("CategoryChooser", {
loggedIn: true,
settings: {
acceptance("CategoryChooser", function (needs) {
needs.user();
needs.settings({
allow_uncategorized_topics: false,
},
});
test("does not display uncategorized if not allowed", async (assert) => {
const categoryChooser = selectKit(".category-chooser");
await visit("/");
await click("#create-topic");
await categoryChooser.expand();
assert.ok(categoryChooser.rowByIndex(0).name() !== "uncategorized");
});
test("prefill category when category_id is set", async (assert) => {
await visit("/new-topic?category_id=1");
assert.equal(selectKit(".category-chooser").header().value(), 1);
});
test("does not display uncategorized if not allowed", async (assert) => {
const categoryChooser = selectKit(".category-chooser");
await visit("/");
await click("#create-topic");
await categoryChooser.expand();
assert.ok(categoryChooser.rowByIndex(0).name() !== "uncategorized");
});
test("prefill category when category_id is set", async (assert) => {
await visit("/new-topic?category_id=1");
assert.equal(selectKit(".category-chooser").header().value(), 1);
});
});

View File

@ -3,110 +3,110 @@ import { test } from "qunit";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Category Edit - security", {
loggedIn: true,
});
test("default", async (assert) => {
await visit("/c/bug");
await click(".edit-category");
await click("li.edit-category-security a");
const $permissionListItems = find(".permission-list li");
const badgeName = $permissionListItems.eq(0).find(".badge-group").text();
assert.equal(badgeName, "everyone");
const permission = $permissionListItems.eq(0).find(".permission").text();
assert.equal(permission, "Create / Reply / See");
});
test("removing a permission", async (assert) => {
const availableGroups = selectKit(".available-groups");
await visit("/c/bug");
await click(".edit-category");
await click("li.edit-category-security a");
await click(".edit-category-tab-security .edit-permission");
await availableGroups.expand();
assert.notOk(
availableGroups.rowByValue("everyone").exists(),
"everyone is already used and is not in the available groups"
);
await click(
".edit-category-tab-security .permission-list li:first-of-type .remove-permission"
);
await availableGroups.expand();
assert.ok(
availableGroups.rowByValue("everyone").exists(),
"everyone has been removed and appears in the available groups"
);
});
test("adding a permission", async (assert) => {
const availableGroups = selectKit(".available-groups");
const permissionSelector = selectKit(".permission-selector");
await visit("/c/bug");
await click(".edit-category");
await click("li.edit-category-security a");
await click(".edit-category-tab-security .edit-permission");
await availableGroups.expand();
await availableGroups.selectRowByValue("staff");
await permissionSelector.expand();
await permissionSelector.selectRowByValue("2");
await click(".edit-category-tab-security .add-permission");
const $addedPermissionItem = find(
".edit-category-tab-security .permission-list li:nth-child(2)"
);
const badgeName = $addedPermissionItem.find(".badge-group").text();
assert.equal(badgeName, "staff");
const permission = $addedPermissionItem.find(".permission").text();
assert.equal(permission, "Reply / See");
});
test("adding a previously removed permission", async (assert) => {
const availableGroups = selectKit(".available-groups");
await visit("/c/bug");
await click(".edit-category");
await click("li.edit-category-security a");
await click(".edit-category-tab-security .edit-permission");
await click(
".edit-category-tab-security .permission-list li:first-of-type .remove-permission"
);
assert.equal(
find(".edit-category-tab-security .permission-list li").length,
0,
"it removes the permission from the list"
);
await availableGroups.expand();
await availableGroups.selectRowByValue("everyone");
await click(".edit-category-tab-security .add-permission");
assert.equal(
find(".edit-category-tab-security .permission-list li").length,
1,
"it adds the permission to the list"
);
const $permissionListItems = find(".permission-list li");
const badgeName = $permissionListItems.eq(0).find(".badge-group").text();
assert.equal(badgeName, "everyone");
const permission = $permissionListItems.eq(0).find(".permission").text();
assert.equal(permission, "Create / Reply / See");
acceptance("Category Edit - security", function (needs) {
needs.user();
test("default", async (assert) => {
await visit("/c/bug");
await click(".edit-category");
await click("li.edit-category-security a");
const $permissionListItems = find(".permission-list li");
const badgeName = $permissionListItems.eq(0).find(".badge-group").text();
assert.equal(badgeName, "everyone");
const permission = $permissionListItems.eq(0).find(".permission").text();
assert.equal(permission, "Create / Reply / See");
});
test("removing a permission", async (assert) => {
const availableGroups = selectKit(".available-groups");
await visit("/c/bug");
await click(".edit-category");
await click("li.edit-category-security a");
await click(".edit-category-tab-security .edit-permission");
await availableGroups.expand();
assert.notOk(
availableGroups.rowByValue("everyone").exists(),
"everyone is already used and is not in the available groups"
);
await click(
".edit-category-tab-security .permission-list li:first-of-type .remove-permission"
);
await availableGroups.expand();
assert.ok(
availableGroups.rowByValue("everyone").exists(),
"everyone has been removed and appears in the available groups"
);
});
test("adding a permission", async (assert) => {
const availableGroups = selectKit(".available-groups");
const permissionSelector = selectKit(".permission-selector");
await visit("/c/bug");
await click(".edit-category");
await click("li.edit-category-security a");
await click(".edit-category-tab-security .edit-permission");
await availableGroups.expand();
await availableGroups.selectRowByValue("staff");
await permissionSelector.expand();
await permissionSelector.selectRowByValue("2");
await click(".edit-category-tab-security .add-permission");
const $addedPermissionItem = find(
".edit-category-tab-security .permission-list li:nth-child(2)"
);
const badgeName = $addedPermissionItem.find(".badge-group").text();
assert.equal(badgeName, "staff");
const permission = $addedPermissionItem.find(".permission").text();
assert.equal(permission, "Reply / See");
});
test("adding a previously removed permission", async (assert) => {
const availableGroups = selectKit(".available-groups");
await visit("/c/bug");
await click(".edit-category");
await click("li.edit-category-security a");
await click(".edit-category-tab-security .edit-permission");
await click(
".edit-category-tab-security .permission-list li:first-of-type .remove-permission"
);
assert.equal(
find(".edit-category-tab-security .permission-list li").length,
0,
"it removes the permission from the list"
);
await availableGroups.expand();
await availableGroups.selectRowByValue("everyone");
await click(".edit-category-tab-security .add-permission");
assert.equal(
find(".edit-category-tab-security .permission-list li").length,
1,
"it adds the permission to the list"
);
const $permissionListItems = find(".permission-list li");
const badgeName = $permissionListItems.eq(0).find(".badge-group").text();
assert.equal(badgeName, "everyone");
const permission = $permissionListItems.eq(0).find(".permission").text();
assert.equal(permission, "Create / Reply / See");
});
});

View File

@ -1,113 +1,97 @@
import { visit } from "@ember/test-helpers";
import { skip } from "qunit";
import { test } from "qunit";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import DiscourseURL from "discourse/lib/url";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Category Edit", {
loggedIn: true,
settings: { email_in: true },
});
test("Can open the category modal", async (assert) => {
await visit("/c/bug");
await click(".edit-category");
assert.ok(visible(".d-modal"), "it pops up a modal");
await click("button.modal-close");
assert.ok(!visible(".d-modal"), "it closes the modal");
});
test("Editing the category", async (assert) => {
await visit("/c/bug");
await click(".edit-category");
assert.equal(find(".d-modal .badge-category").text(), "bug");
await fillIn("input.category-name", "testing");
assert.equal(find(".d-modal .badge-category").text(), "testing");
await fillIn("#edit-text-color", "#ff0000");
await click(".edit-category-topic-template");
await fillIn(".d-editor-input", "this is the new topic template");
await click(".edit-category-settings");
const searchPriorityChooser = selectKit("#category-search-priority");
await searchPriorityChooser.expand();
await searchPriorityChooser.selectRowByValue(1);
await click("#save-category");
assert.ok(!visible(".d-modal"), "it closes the modal");
assert.equal(
DiscourseURL.redirectedTo,
"/c/bug/1",
"it does one of the rare full page redirects"
);
});
skip("Edit the description without loosing progress", async (assert) => {
let win = { focus: function () {} };
let windowOpen = sandbox.stub(window, "open").returns(win);
sandbox.stub(win, "focus");
await visit("/c/bug");
await click(".edit-category");
await click(".edit-category-description");
assert.ok(
windowOpen.calledWith("/t/category-definition-for-bug/2", "_blank"),
"opens the category topic in a new tab"
);
});
test("Error Saving", async (assert) => {
await visit("/c/bug");
await click(".edit-category");
await click(".edit-category-settings");
await fillIn(".email-in", "duplicate@example.com");
await click("#save-category");
assert.ok(visible("#modal-alert"));
assert.equal(find("#modal-alert").html(), "duplicate email");
});
test("Subcategory list settings", async (assert) => {
const categoryChooser = selectKit(
".edit-category-tab-general .category-chooser"
);
await visit("/c/bug");
await click(".edit-category");
await click(".edit-category-settings a");
assert.ok(
!visible(".subcategory-list-style-field"),
"subcategory list style isn't visible by default"
);
await click(".show-subcategory-list-field input[type=checkbox]");
assert.ok(
visible(".subcategory-list-style-field"),
"subcategory list style is shown if show subcategory list is checked"
);
await click(".edit-category-general");
await categoryChooser.expand();
await categoryChooser.selectRowByValue(3);
await click(".edit-category-settings a");
assert.ok(
!visible(".show-subcategory-list-field"),
"show subcategory list isn't visible for child categories"
);
assert.ok(
!visible(".subcategory-list-style-field"),
"subcategory list style isn't visible for child categories"
);
acceptance("Category Edit", function (needs) {
needs.user();
needs.settings({ email_in: true });
test("Can open the category modal", async (assert) => {
await visit("/c/bug");
await click(".edit-category");
assert.ok(visible(".d-modal"), "it pops up a modal");
await click("button.modal-close");
assert.ok(!visible(".d-modal"), "it closes the modal");
});
test("Editing the category", async (assert) => {
await visit("/c/bug");
await click(".edit-category");
assert.equal(find(".d-modal .badge-category").text(), "bug");
await fillIn("input.category-name", "testing");
assert.equal(find(".d-modal .badge-category").text(), "testing");
await fillIn("#edit-text-color", "#ff0000");
await click(".edit-category-topic-template");
await fillIn(".d-editor-input", "this is the new topic template");
await click(".edit-category-settings");
const searchPriorityChooser = selectKit("#category-search-priority");
await searchPriorityChooser.expand();
await searchPriorityChooser.selectRowByValue(1);
await click("#save-category");
assert.ok(!visible(".d-modal"), "it closes the modal");
assert.equal(
DiscourseURL.redirectedTo,
"/c/bug/1",
"it does one of the rare full page redirects"
);
});
test("Error Saving", async (assert) => {
await visit("/c/bug");
await click(".edit-category");
await click(".edit-category-settings");
await fillIn(".email-in", "duplicate@example.com");
await click("#save-category");
assert.ok(visible("#modal-alert"));
assert.equal(find("#modal-alert").html(), "duplicate email");
});
test("Subcategory list settings", async (assert) => {
const categoryChooser = selectKit(
".edit-category-tab-general .category-chooser"
);
await visit("/c/bug");
await click(".edit-category");
await click(".edit-category-settings a");
assert.ok(
!visible(".subcategory-list-style-field"),
"subcategory list style isn't visible by default"
);
await click(".show-subcategory-list-field input[type=checkbox]");
assert.ok(
visible(".subcategory-list-style-field"),
"subcategory list style is shown if show subcategory list is checked"
);
await click(".edit-category-general");
await categoryChooser.expand();
await categoryChooser.selectRowByValue(3);
await click(".edit-category-settings a");
assert.ok(
!visible(".show-subcategory-list-field"),
"show subcategory list isn't visible for child categories"
);
assert.ok(
!visible(".subcategory-list-style-field"),
"subcategory list style isn't visible for child categories"
);
});
});

View File

@ -1,17 +1,23 @@
import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import pretender from "discourse/tests/helpers/create-pretender";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Click Track", {});
acceptance("Click Track", function (needs) {
let tracked = false;
needs.pretender((server, helper) => {
server.post("/clicks/track", () => {
tracked = true;
return helper.response({ success: "OK" });
});
});
test("Do not track mentions", async (assert) => {
pretender.post("/clicks/track", () => assert.ok(false));
test("Do not track mentions", async (assert) => {
await visit("/t/internationalization-localization/280");
assert.ok(find(".user-card.show").length === 0, "card should not appear");
await visit("/t/internationalization-localization/280");
assert.ok(find(".user-card.show").length === 0, "card should not appear");
await click("article[data-post-id=3651] a.mention");
assert.ok(find(".user-card.show").length === 1, "card appear");
assert.equal(currentURL(), "/t/internationalization-localization/280");
await click("article[data-post-id=3651] a.mention");
assert.ok(find(".user-card.show").length === 1, "card appear");
assert.equal(currentURL(), "/t/internationalization-localization/280");
assert.ok(!tracked);
});
});

View File

@ -39,6 +39,7 @@ import siteFixtures from "discourse/tests/fixtures/site-fixtures";
import Site from "discourse/models/site";
import createStore from "discourse/tests/helpers/create-store";
import { getApplication } from "@ember/test-helpers";
import deprecated from "discourse-common/lib/deprecated";
export function currentUser() {
return User.create(sessionFixtures["/session/current.json"].current_user);
@ -66,24 +67,6 @@ export function fakeTime(timeString, timezone = null, advanceTime = false) {
});
}
export async function acceptanceUseFakeClock(
timeString,
callback,
timezone = null
) {
if (!timezone) {
let user = loggedInUser();
if (user) {
timezone = user.resolvedTimezone(user);
} else {
timezone = "America/Denver";
}
}
let clock = fakeTime(timeString, timezone, true);
await callback();
clock.reset();
}
const Plugin = $.fn.modal;
const Modal = Plugin.Constructor;
@ -167,13 +150,28 @@ export function addPretenderCallback(name, fn) {
}
}
export function acceptance(name, options) {
export function acceptance(name, optionsOrCallback) {
name = `Acceptance: ${name}`;
options = options || {};
let callback;
let options = {};
if (typeof optionsOrCallback === "function") {
callback = optionsOrCallback;
} else if (typeof optionsOrCallback === "object") {
deprecated(
"The second parameter to `acceptance` should be a function that encloses your tests.",
{ since: "2.6.0" }
);
options = optionsOrCallback;
}
addPretenderCallback(name, options.pretend);
module(name, {
let loggedIn = false;
let siteChanges;
let settingChanges;
const setup = {
beforeEach() {
resetMobile();
@ -185,12 +183,12 @@ export function acceptance(name, options) {
forceMobile();
}
if (options.loggedIn) {
if (loggedIn) {
logIn();
}
if (options.settings) {
mergeSettings(options.settings);
if (settingChanges) {
mergeSettings(settingChanges);
}
this.siteSettings = currentSettings();
@ -198,8 +196,8 @@ export function acceptance(name, options) {
clearHTMLCache();
resetPluginApi();
if (options.site) {
resetSite(currentSettings(), options.site);
if (siteChanges) {
resetSite(currentSettings(), siteChanges);
}
getApplication().reset();
@ -248,7 +246,45 @@ export function acceptance(name, options) {
// We do this after reset so that the willClearRender will have already fired
resetWidgetCleanCallbacks();
},
});
};
const needs = {
user() {
loggedIn = true;
},
pretender(fn) {
addPretenderCallback(name, fn);
},
site(changes) {
siteChanges = changes;
},
settings(changes) {
settingChanges = changes;
},
};
if (options.loggedIn) {
needs.user();
}
if (options.site) {
needs.site(options.site);
}
if (options.settings) {
needs.settings(options.settings);
}
if (callback) {
// New, preferred way
module(name, function (hooks) {
hooks.beforeEach(setup.beforeEach);
hooks.afterEach(setup.afterEach);
needs.hooks = hooks;
callback(needs);
});
} else {
// Old way
module(name, setup);
}
}
export function controllerFor(controller, model) {