DEV: Modernize component tests (#17368)

* Use QUnit `module` instead of `discourseModule`
* Use QUnit `test` instead of `componentTest`
* Use angle-bracket syntax
* Remove jQuery usage
* Improve assertions (and actually fix some of them)
This commit is contained in:
Jarek Radosz
2022-07-11 12:29:44 +02:00
committed by GitHub
parent 5b70b67e78
commit 189bebb2e4
122 changed files with 8203 additions and 9999 deletions

View File

@ -159,6 +159,10 @@ export default Mixin.create(UppyS3Multipart, ExtendableUploader, {
}); });
this._uppyInstance.on("upload", (data) => { this._uppyInstance.on("upload", (data) => {
if (this.isDestroying || this.isDestroyed) {
return;
}
this._addNeedProcessing(data.fileIDs.length); this._addNeedProcessing(data.fileIDs.length);
const files = data.fileIDs.map((fileId) => const files = data.fileIDs.map((fileId) =>
this._uppyInstance.getFile(fileId) this._uppyInstance.getFile(fileId)
@ -257,6 +261,10 @@ export default Mixin.create(UppyS3Multipart, ExtendableUploader, {
this._uppyInstance.on("complete", () => { this._uppyInstance.on("complete", () => {
run(() => { run(() => {
if (this.isDestroying || this.isDestroyed) {
return;
}
this.appEvents.trigger(`upload-mixin:${this.id}:all-uploads-complete`); this.appEvents.trigger(`upload-mixin:${this.id}:all-uploads-complete`);
this._reset(); this._reset();
}); });

View File

@ -5,16 +5,28 @@ import TopicTrackingState from "discourse/models/topic-tracking-state";
import User from "discourse/models/user"; import User from "discourse/models/user";
import { autoLoadModules } from "discourse/initializers/auto-load-modules"; import { autoLoadModules } from "discourse/initializers/auto-load-modules";
import QUnit, { test } from "qunit"; import QUnit, { test } from "qunit";
import { setupRenderingTest as emberSetupRenderingTest } from "ember-qunit"; import { setupRenderingTest as emberSetupRenderingTest } from "ember-qunit";
import { currentSettings } from "discourse/tests/helpers/site-settings";
import { clearResolverOptions } from "discourse-common/resolver";
import { testCleanup } from "discourse/tests/helpers/qunit-helpers";
export function setupRenderingTest(hooks) { export function setupRenderingTest(hooks) {
emberSetupRenderingTest(hooks); emberSetupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
if (!hooks.usingDiscourseModule) {
this.siteSettings = currentSettings();
if (!this.registry) {
this.registry = this.owner.__registry__;
}
this.container = this.owner;
clearResolverOptions();
}
this.site = Site.current(); this.site = Site.current();
this.session = Session.current(); this.session = Session.current();
this.container = this.owner;
const currentUser = User.create({ const currentUser = User.create({
username: "eviltrout", username: "eviltrout",
@ -41,9 +53,16 @@ export function setupRenderingTest(hooks) {
); );
autoLoadModules(this.owner, this.registry); autoLoadModules(this.owner, this.registry);
this.owner.lookup("service:store");
$.fn.autocomplete = function () {}; $.fn.autocomplete = function () {};
}); });
if (!hooks.usingDiscourseModule) {
hooks.afterEach(function () {
testCleanup(this.container);
});
}
} }
export default function (name, hooks, opts) { export default function (name, hooks, opts) {

View File

@ -138,7 +138,7 @@ export function applyPretender(name, server, helper) {
} }
// Add clean up code here to run after every test // Add clean up code here to run after every test
function testCleanup(container, app) { export function testCleanup(container, app) {
if (_initialized.has(QUnit.config.current.testId)) { if (_initialized.has(QUnit.config.current.testId)) {
if (!app) { if (!app) {
app = getApplication(); app = getApplication();
@ -223,6 +223,7 @@ export function discourseModule(name, options) {
this.moduleName = name; this.moduleName = name;
hooks.usingDiscourseModule = true;
options.call(this, hooks); options.call(this, hooks);
}); });

View File

@ -1,48 +1,37 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { import { count, exists } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
exists,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | ace-editor", function (hooks) { module("Integration | Component | ace-editor", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("css editor", { test("css editor", async function (assert) {
template: hbs`{{ace-editor mode="css"}}`, await render(hbs`<AceEditor @mode="css" />`);
test(assert) {
assert.ok(exists(".ace_editor"), "it renders the ace editor"); assert.ok(exists(".ace_editor"), "it renders the ace editor");
},
}); });
componentTest("html editor", { test("html editor", async function (assert) {
template: hbs`{{ace-editor mode="html" content="<b>wat</b>"}}`, await render(hbs`<AceEditor @mode="html" @content="<b>wat</b>" />`);
test(assert) {
assert.ok(exists(".ace_editor"), "it renders the ace editor"); assert.ok(exists(".ace_editor"), "it renders the ace editor");
},
}); });
componentTest("sql editor", { test("sql editor", async function (assert) {
template: hbs`{{ace-editor mode="sql" content="SELECT * FROM users"}}`, await render(hbs`<AceEditor @mode="sql" @content="SELECT * FROM users" />`);
test(assert) {
assert.ok(exists(".ace_editor"), "it renders the ace editor"); assert.ok(exists(".ace_editor"), "it renders the ace editor");
},
}); });
componentTest("disabled editor", { test("disabled editor", async function (assert) {
template: hbs` await render(hbs`
{{ace-editor mode="sql" content="SELECT * FROM users" disabled=true}} <AceEditor @mode="sql" @content="SELECT * FROM users" @disabled=true />
`, `);
test(assert) {
assert.ok(exists(".ace_editor"), "it renders the ace editor"); assert.ok(exists(".ace_editor"), "it renders the ace editor");
assert.equal( assert.strictEqual(
queryAll(".ace-wrapper[data-disabled]").length, count(".ace-wrapper[data-disabled]"),
1, 1,
"it has a data-disabled attr" "it has a data-disabled attr"
); );
},
}); });
}); });

View File

@ -1,24 +1,18 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule, exists } from "discourse/tests/helpers/qunit-helpers"; import { exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule( module("Integration | Component | activation-controls", function (hooks) {
"Integration | Component | activation-controls",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("hides change email button", { test("hides change email button", async function (assert) {
template: hbs`{{activation-controls}}`,
beforeEach() {
this.siteSettings.enable_local_logins = false; this.siteSettings.enable_local_logins = false;
this.siteSettings.email_editable = false; this.siteSettings.email_editable = false;
},
test(assert) { await render(hbs`<ActivationControls />`);
assert.ok(!exists("button.edit-email")); assert.ok(!exists("button.edit-email"));
},
}); });
} });
);

View File

@ -1,67 +1,60 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render } from "@ember/test-helpers";
import { import { count, exists, query } from "discourse/tests/helpers/qunit-helpers";
count,
discourseModule,
exists,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import { click } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import pretender from "discourse/tests/helpers/create-pretender"; import pretender from "discourse/tests/helpers/create-pretender";
discourseModule("Integration | Component | admin-report", function (hooks) { module("Integration | Component | admin-report", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("default", { test("default", async function (assert) {
template: hbs`{{admin-report dataSourceName='signups'}}`, await render(hbs`<AdminReport @dataSourceName="signups" />`);
async test(assert) {
assert.ok(exists(".admin-report.signups")); assert.ok(exists(".admin-report.signups"));
assert.ok(exists(".admin-report.signups", "it defaults to table mode")); assert.ok(exists(".admin-report.signups", "it defaults to table mode"));
assert.strictEqual( assert.strictEqual(
queryAll(".header .item.report").text().trim(), query(".header .item.report").innerText.trim(),
"Signups", "Signups",
"it has a title" "it has a title"
); );
assert.strictEqual( assert.strictEqual(
queryAll(".header .info").attr("data-tooltip"), query(".header .info").getAttribute("data-tooltip"),
"New account registrations for this period", "New account registrations for this period",
"it has a description" "it has a description"
); );
assert.strictEqual( assert.strictEqual(
queryAll(".admin-report-table thead tr th:first-child .title") query(
.text() ".admin-report-table thead tr th:first-child .title"
.trim(), ).innerText.trim(),
"Day", "Day",
"it has col headers" "it has col headers"
); );
assert.strictEqual( assert.strictEqual(
queryAll(".admin-report-table thead tr th:nth-child(2) .title") query(
.text() ".admin-report-table thead tr th:nth-child(2) .title"
.trim(), ).innerText.trim(),
"Count", "Count",
"it has col headers" "it has col headers"
); );
assert.strictEqual( assert.strictEqual(
queryAll(".admin-report-table tbody tr:nth-child(1) td:nth-child(1)") query(
.text() ".admin-report-table tbody tr:nth-child(1) td:nth-child(1)"
.trim(), ).innerText.trim(),
"June 16, 2018", "June 16, 2018",
"it has rows" "it has rows"
); );
assert.strictEqual( assert.strictEqual(
queryAll(".admin-report-table tbody tr:nth-child(1) td:nth-child(2)") query(
.text() ".admin-report-table tbody tr:nth-child(1) td:nth-child(2)"
.trim(), ).innerText.trim(),
"12", "12",
"it has rows" "it has rows"
); );
@ -71,28 +64,26 @@ discourseModule("Integration | Component | admin-report", function (hooks) {
await click(".admin-report-table-header.y .sort-btn"); await click(".admin-report-table-header.y .sort-btn");
assert.strictEqual( assert.strictEqual(
queryAll(".admin-report-table tbody tr:nth-child(1) td:nth-child(2)") query(
.text() ".admin-report-table tbody tr:nth-child(1) td:nth-child(2)"
.trim(), ).innerText.trim(),
"7", "7",
"it can sort rows" "it can sort rows"
); );
},
}); });
componentTest("options", { test("options", async function (assert) {
template: hbs`{{admin-report dataSourceName='signups' reportOptions=options}}`,
beforeEach() {
this.set("options", { this.set("options", {
table: { table: {
perPage: 4, perPage: 4,
total: false, total: false,
}, },
}); });
},
test(assert) { await render(
hbs`<AdminReport @dataSourceName="signups" @reportOptions={{this.options}} />`
);
assert.ok(exists(".pagination"), "it paginates the results"); assert.ok(exists(".pagination"), "it paginates the results");
assert.strictEqual( assert.strictEqual(
count(".pagination button"), count(".pagination button"),
@ -101,46 +92,38 @@ discourseModule("Integration | Component | admin-report", function (hooks) {
); );
assert.notOk(exists(".totals-sample-table"), "it hides totals"); assert.notOk(exists(".totals-sample-table"), "it hides totals");
},
}); });
componentTest("switch modes", { test("switch modes", async function (assert) {
template: hbs`{{admin-report dataSourceName='signups' showFilteringUI=true}}`, await render(
hbs`<AdminReport @dataSourceName="signups" @showFilteringUI={{true}} />`
);
async test(assert) {
await click(".mode-btn.chart"); await click(".mode-btn.chart");
assert.notOk(exists(".admin-report-table"), "it removes the table"); assert.notOk(exists(".admin-report-table"), "it removes the table");
assert.ok(exists(".admin-report-chart"), "it shows the chart"); assert.ok(exists(".admin-report-chart"), "it shows the chart");
},
}); });
componentTest("timeout", { test("timeout", async function (assert) {
template: hbs`{{admin-report dataSourceName='signups_timeout'}}`, await render(hbs`<AdminReport @dataSourceName="signups_timeout" />`);
test(assert) {
assert.ok(exists(".alert-error.timeout"), "it displays a timeout error"); assert.ok(exists(".alert-error.timeout"), "it displays a timeout error");
},
}); });
componentTest("no data", { test("no data", async function (assert) {
template: hbs`{{admin-report dataSourceName='posts'}}`, await render(hbs`<AdminReport @dataSourceName="posts" />`);
test(assert) {
assert.ok(exists(".no-data"), "it displays a no data alert"); assert.ok(exists(".no-data"), "it displays a no data alert");
},
}); });
componentTest("exception", { test("exception", async function (assert) {
template: hbs`{{admin-report dataSourceName='signups_exception'}}`, await render(hbs`<AdminReport @dataSourceName="signups_exception" />`);
test(assert) {
assert.ok(exists(".alert-error.exception"), "it displays an error"); assert.ok(exists(".alert-error.exception"), "it displays an error");
},
}); });
componentTest("rate limited", { test("rate limited", async function (assert) {
beforeEach() {
pretender.get("/admin/reports/bulk", () => { pretender.get("/admin/reports/bulk", () => {
return [ return [
429, 429,
@ -154,37 +137,30 @@ discourseModule("Integration | Component | admin-report", function (hooks) {
}, },
]; ];
}); });
},
template: hbs`{{admin-report dataSourceName='signups_rate_limited'}}`, await render(hbs`<AdminReport @dataSourceName="signups_rate_limited" />`);
test(assert) {
assert.ok( assert.ok(
exists(".alert-error.rate-limited"), exists(".alert-error.rate-limited"),
"it displays a rate limited error" "it displays a rate limited error"
); );
},
}); });
componentTest("post edits", { test("post edits", async function (assert) {
template: hbs`{{admin-report dataSourceName='post_edits'}}`, await render(hbs`<AdminReport @dataSourceName="post_edits" />`);
test(assert) {
assert.ok( assert.ok(
exists(".admin-report.post-edits"), exists(".admin-report.post-edits"),
"it displays the post edits report" "it displays the post edits report"
); );
},
}); });
componentTest("not found", { test("not found", async function (assert) {
template: hbs`{{admin-report dataSourceName='not_found'}}`, await render(hbs`<AdminReport @dataSourceName="not_found" />`);
test(assert) {
assert.ok( assert.ok(
exists(".alert-error.not-found"), exists(".alert-error.not-found"),
"it displays a not found error" "it displays a not found error"
); );
},
}); });
}); });

View File

@ -1,78 +1,60 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render } from "@ember/test-helpers";
import { import { exists, query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import I18n from "I18n"; import I18n from "I18n";
import { click } from "@ember/test-helpers";
discourseModule( module("Integration | Component | admin-user-field-item", function (hooks) {
"Integration | Component | admin-user-field-item",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("user field without an id", { test("user field without an id", async function (assert) {
template: hbs`{{admin-user-field-item userField=userField}}`, await render(hbs`<AdminUserFieldItem @userField={{this.userField}} />`);
async test(assert) {
assert.ok(exists(".save"), "displays editing mode"); assert.ok(exists(".save"), "displays editing mode");
},
}); });
componentTest("cancel action", { test("cancel action", async function (assert) {
template: hbs`{{admin-user-field-item isEditing=isEditing destroyAction=destroyAction userField=userField}}`,
beforeEach() {
this.set("userField", { id: 1, field_type: "text" }); this.set("userField", { id: 1, field_type: "text" });
this.set("isEditing", true); this.set("isEditing", true);
},
async test(assert) { await render(
hbs`<AdminUserFieldItem @isEditing={{this.isEditing}} @destroyAction={{this.destroyAction}} @userField={{this.userField}} />`
);
await click(".cancel"); await click(".cancel");
assert.ok(exists(".edit")); assert.ok(exists(".edit"));
},
}); });
componentTest("edit action", { test("edit action", async function (assert) {
template: hbs`{{admin-user-field-item destroyAction=destroyAction userField=userField}}`,
beforeEach() {
this.set("userField", { id: 1, field_type: "text" }); this.set("userField", { id: 1, field_type: "text" });
},
async test(assert) { await render(
hbs`<AdminUserFieldItem @destroyAction={{this.destroyAction}} @userField={{this.userField}} />`
);
await click(".edit"); await click(".edit");
assert.ok(exists(".save")); assert.ok(exists(".save"));
},
}); });
componentTest("user field with an id", { test("user field with an id", async function (assert) {
template: hbs`{{admin-user-field-item userField=userField}}`,
beforeEach() {
this.set("userField", { this.set("userField", {
id: 1, id: 1,
field_type: "text", field_type: "text",
name: "foo", name: "foo",
description: "what is foo", description: "what is foo",
}); });
},
async test(assert) { await render(hbs`<AdminUserFieldItem @userField={{this.userField}} />`);
assert.equal(query(".name").innerText, this.userField.name);
assert.equal( assert.strictEqual(query(".name").innerText, this.userField.name);
assert.strictEqual(
query(".description").innerText, query(".description").innerText,
this.userField.description this.userField.description
); );
assert.equal( assert.strictEqual(
query(".field-type").innerText, query(".field-type").innerText,
I18n.t("admin.user_fields.field_types.text") I18n.t("admin.user_fields.field_types.text")
); );
},
}); });
} });
);

View File

@ -1,14 +1,11 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import pretender from "discourse/tests/helpers/create-pretender"; import { createFile } from "discourse/tests/helpers/qunit-helpers";
import {
createFile,
discourseModule,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import pretender from "discourse/tests/helpers/create-pretender";
discourseModule("Integration | Component | avatar-uploader", function (hooks) { module("Integration | Component | avatar-uploader", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
@ -17,25 +14,24 @@ discourseModule("Integration | Component | avatar-uploader", function (hooks) {
}); });
}); });
componentTest("default", { test("default", async function (assert) {
template: hbs`{{avatar-uploader
id="avatar-uploader"
done=done
}}`,
async test(assert) {
const done = assert.async(); const done = assert.async();
this.set("done", () => { this.set("done", () => {
assert.ok(true, "action is called after avatar is uploaded"); assert.ok(true, "action is called after avatar is uploaded");
done(); done();
}); });
await render(hbs`
<AvatarUploader
@id="avatar-uploader"
@done={{this.done}}
/>
`);
await this.container await this.container
.lookup("service:app-events") .lookup("service:app-events")
.trigger("upload-mixin:avatar-uploader:add-files", [ .trigger("upload-mixin:avatar-uploader:add-files", [
createFile("avatar.png"), createFile("avatar.png"),
]); ]);
},
}); });
}); });

View File

@ -1,105 +1,81 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { import { exists, query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | badge-button", function (hooks) { module("Integration | Component | badge-button", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("disabled badge", { test("disabled badge", async function (assert) {
template: hbs`{{badge-button badge=badge}}`,
beforeEach() {
this.set("badge", { enabled: false }); this.set("badge", { enabled: false });
},
async test(assert) { await render(hbs`<BadgeButton @badge={{this.badge}} />`);
assert.ok(exists(".user-badge.disabled")); assert.ok(exists(".user-badge.disabled"));
},
}); });
componentTest("enabled badge", { test("enabled badge", async function (assert) {
template: hbs`{{badge-button badge=badge}}`,
beforeEach() {
this.set("badge", { enabled: true }); this.set("badge", { enabled: true });
},
async test(assert) { await render(hbs`<BadgeButton @badge={{this.badge}} />`);
assert.notOk(exists(".user-badge.disabled")); assert.notOk(exists(".user-badge.disabled"));
},
}); });
componentTest("data-badge-name", { test("data-badge-name", async function (assert) {
template: hbs`{{badge-button badge=badge}}`,
beforeEach() {
this.set("badge", { name: "foo" }); this.set("badge", { name: "foo" });
},
async test(assert) { await render(hbs`<BadgeButton @badge={{this.badge}} />`);
assert.ok(exists('.user-badge[data-badge-name="foo"]')); assert.ok(exists('.user-badge[data-badge-name="foo"]'));
},
}); });
componentTest("title", { test("title", async function (assert) {
template: hbs`{{badge-button badge=badge}}`,
beforeEach() {
this.set("badge", { description: "a <a href>good</a> run" }); this.set("badge", { description: "a <a href>good</a> run" });
},
async test(assert) { await render(hbs`<BadgeButton @badge={{this.badge}} />`);
assert.equal(query(".user-badge").title, "a good run", "it strips html");
assert.strictEqual(
query(".user-badge").title,
"a good run",
"it strips html"
);
this.set("badge", { description: "a bad run" }); this.set("badge", { description: "a bad run" });
assert.equal( assert.strictEqual(
query(".user-badge").title, query(".user-badge").title,
"a bad run", "a bad run",
"it updates title when changing description" "it updates title when changing description"
); );
},
}); });
componentTest("icon", { test("icon", async function (assert) {
template: hbs`{{badge-button badge=badge}}`,
beforeEach() {
this.set("badge", { icon: "times" }); this.set("badge", { icon: "times" });
},
async test(assert) { await render(hbs`<BadgeButton @badge={{this.badge}} />`);
assert.ok(exists(".d-icon.d-icon-times")); assert.ok(exists(".d-icon.d-icon-times"));
},
}); });
componentTest("accepts block", { test("accepts block", async function (assert) {
template: hbs`{{#badge-button badge=badge}}<span class="test"></span>{{/badge-button}}`,
beforeEach() {
this.set("badge", {}); this.set("badge", {});
},
async test(assert) { await render(hbs`
<BadgeButton @badge={{this.badge}}>
<span class="test"></span>
</BadgeButton>
`);
assert.ok(exists(".test")); assert.ok(exists(".test"));
},
}); });
componentTest("badgeTypeClassName", { test("badgeTypeClassName", async function (assert) {
template: hbs`{{badge-button badge=badge}}`,
beforeEach() {
this.set("badge", { badgeTypeClassName: "foo" }); this.set("badge", { badgeTypeClassName: "foo" });
},
async test(assert) { await render(hbs`<BadgeButton @badge={{this.badge}} />`);
assert.ok(exists(".user-badge.foo")); assert.ok(exists(".user-badge.foo"));
},
}); });
}); });

View File

@ -1,22 +1,15 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render } from "@ember/test-helpers";
import EmberObject from "@ember/object";
import { click } from "@ember/test-helpers";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import pretender from "discourse/tests/helpers/create-pretender"; import pretender from "discourse/tests/helpers/create-pretender";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import EmberObject from "@ember/object";
discourseModule("Integration | Component | badge-title", function (hooks) { module("Integration | Component | badge-title", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("badge title", { test("badge title", async function (assert) {
template: hbs`
{{badge-title selectableUserBadges=selectableUserBadges}}
`,
beforeEach() {
this.set("subject", selectKit()); this.set("subject", selectKit());
this.set("selectableUserBadges", [ this.set("selectableUserBadges", [
EmberObject.create({ EmberObject.create({
@ -29,18 +22,21 @@ discourseModule("Integration | Component | badge-title", function (hooks) {
badge: { name: "Test" }, badge: { name: "Test" },
}), }),
]); ]);
},
async test(assert) {
pretender.put("/u/eviltrout/preferences/badge_title", () => [ pretender.put("/u/eviltrout/preferences/badge_title", () => [
200, 200,
{ "Content-Type": "application/json" }, { "Content-Type": "application/json" },
{}, {},
]); ]);
await render(hbs`
<BadgeTitle @selectableUserBadges={{this.selectableUserBadges}} />
`);
await this.subject.expand(); await this.subject.expand();
await this.subject.selectRowByValue(42); await this.subject.selectRowByValue(42);
await click(".btn"); await click(".btn");
assert.strictEqual(this.currentUser.title, "Test"); assert.strictEqual(this.currentUser.title, "Test");
},
}); });
}); });

View File

@ -1,38 +1,31 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import Bookmark from "discourse/models/bookmark"; import Bookmark from "discourse/models/bookmark";
import I18n from "I18n"; import I18n from "I18n";
import { formattedReminderTime } from "discourse/lib/bookmark"; import { formattedReminderTime } from "discourse/lib/bookmark";
import { tomorrow } from "discourse/lib/time-utils"; import { tomorrow } from "discourse/lib/time-utils";
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import hbs from "htmlbars-inline-precompile";
import {
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
discourseModule("Integration | Component | bookmark-icon", function (hooks) { module("Integration | Component | bookmark-icon", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("with reminder", { test("with reminder", async function (assert) {
template: hbs`{{bookmark-icon bookmark=bookmark}}`,
beforeEach() {
this.setProperties({ this.setProperties({
bookmark: Bookmark.create({ bookmark: Bookmark.create({
reminder_at: tomorrow(this.currentUser.timezone), reminder_at: tomorrow(this.currentUser.timezone),
name: "some name", name: "some name",
}), }),
}); });
},
async test(assert) { await render(hbs`<BookmarkIcon @bookmark={{this.bookmark}} />`);
assert.ok( assert.ok(
exists(".d-icon-discourse-bookmark-clock.bookmark-icon__bookmarked") exists(".d-icon-discourse-bookmark-clock.bookmark-icon__bookmarked")
); );
assert.strictEqual( assert.strictEqual(
query(".svg-icon-title")["title"], query(".svg-icon-title").title,
I18n.t("bookmarks.created_with_reminder_generic", { I18n.t("bookmarks.created_with_reminder_generic", {
date: formattedReminderTime( date: formattedReminderTime(
this.bookmark.reminder_at, this.bookmark.reminder_at,
@ -41,47 +34,38 @@ discourseModule("Integration | Component | bookmark-icon", function (hooks) {
name: "some name", name: "some name",
}) })
); );
},
}); });
componentTest("no reminder", { test("no reminder", async function (assert) {
template: hbs`{{bookmark-icon bookmark=bookmark}}`,
beforeEach() {
this.set( this.set(
"bookmark", "bookmark",
Bookmark.create({ Bookmark.create({
name: "some name", name: "some name",
}) })
); );
},
async test(assert) { await render(hbs`<BookmarkIcon @bookmark={{this.bookmark}} />`);
assert.ok(exists(".d-icon-bookmark.bookmark-icon__bookmarked")); assert.ok(exists(".d-icon-bookmark.bookmark-icon__bookmarked"));
assert.strictEqual( assert.strictEqual(
query(".svg-icon-title")["title"], query(".svg-icon-title").title,
I18n.t("bookmarks.created_generic", { I18n.t("bookmarks.created_generic", {
name: "some name", name: "some name",
}) })
); );
},
}); });
componentTest("null bookmark", { test("null bookmark", async function (assert) {
template: hbs`{{bookmark-icon bookmark=bookmark}}`,
beforeEach() {
this.setProperties({ this.setProperties({
bookmark: null, bookmark: null,
}); });
},
async test(assert) { await render(hbs`<BookmarkIcon @bookmark={{this.bookmark}} />`);
assert.ok(exists(".d-icon-bookmark.bookmark-icon")); assert.ok(exists(".d-icon-bookmark.bookmark-icon"));
assert.strictEqual( assert.strictEqual(
query(".svg-icon-title")["title"], query(".svg-icon-title").title,
I18n.t("bookmarks.create") I18n.t("bookmarks.create")
); );
},
}); });
}); });

View File

@ -1,20 +1,12 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers"; import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | bookmark", function (hooks) { module("Integration | Component | bookmark", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
const template = hbs`{{bookmark
model=model
afterSave=afterSave
afterDelete=afterDelete
onCloseWithoutSaving=onCloseWithoutSaving
registerOnCloseHandler=registerOnCloseHandler
closeModal=closeModal}}`;
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.setProperties({ this.setProperties({
model: {}, model: {},
@ -26,22 +18,27 @@ discourseModule("Integration | Component | bookmark", function (hooks) {
}); });
}); });
componentTest("prefills the custom reminder type date and time", { test("prefills the custom reminder type date and time", async function (assert) {
template,
beforeEach() {
let name = "test"; let name = "test";
let reminderAt = "2020-05-15T09:45:00"; let reminderAt = "2020-05-15T09:45:00";
this.model = { id: 1, name, reminderAt }; this.model = { id: 1, name, reminderAt };
},
test(assert) { await render(hbs`
<Bookmark
@model={{this.model}}
@afterSave={{this.afterSave}}
@afterDelete={{this.afterDelete}}
@onCloseWithoutSaving={{this.onCloseWithoutSaving}}
@registerOnCloseHandler={{this.registerOnCloseHandler}}
@closeModal={{this.closeModal}}
/>
`);
assert.strictEqual(query("#bookmark-name").value, "test"); assert.strictEqual(query("#bookmark-name").value, "test");
assert.strictEqual( assert.strictEqual(
query("#custom-date > .date-picker").value, query("#custom-date > .date-picker").value,
"2020-05-15" "2020-05-15"
); );
assert.strictEqual(query("#custom-time").value, "09:45"); assert.strictEqual(query("#custom-time").value, "09:45");
},
}); });
}); });

View File

@ -0,0 +1,33 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import Category from "discourse/models/category";
module("Integration | Component | category-badge helper", function (hooks) {
setupRenderingTest(hooks);
test("displays category", async function (assert) {
this.set("category", Category.findById(1));
await render(hbs`{{category-badge category}}`);
assert.strictEqual(
query(".category-name").innerText.trim(),
this.category.name
);
});
test("options.link", async function (assert) {
this.set("category", Category.findById(1));
await render(hbs`{{category-badge category link=true}}`);
assert.ok(
exists(
`a.badge-wrapper[href="/c/${this.category.slug}/${this.category.id}"]`
)
);
});
});

View File

@ -1,45 +0,0 @@
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import {
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import Category from "discourse/models/category";
discourseModule("Integration | Component | category-badge", function (hooks) {
setupRenderingTest(hooks);
componentTest("displays category", {
template: hbs`{{category-badge category}}`,
beforeEach() {
this.set("category", Category.findById(1));
},
async test(assert) {
assert.equal(
query(".category-name").innerText.trim(),
this.category.name
);
},
});
componentTest("options.link", {
template: hbs`{{category-badge category link=true}}`,
beforeEach() {
this.set("category", Category.findById(1));
},
async test(assert) {
assert.ok(
exists(
`a.badge-wrapper[href="/c/${this.category.slug}/${this.category.id}"]`
)
);
},
});
});

View File

@ -1,27 +1,26 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers"; import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import pretender from "discourse/tests/helpers/create-pretender"; import pretender from "discourse/tests/helpers/create-pretender";
import { resetCache } from "pretty-text/upload-short-url"; import { resetCache } from "pretty-text/upload-short-url";
discourseModule("Integration | Component | cook-text", function (hooks) { module("Integration | Component | cook-text", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("renders markdown", { hooks.afterEach(function () {
template: hbs`<CookText @rawText="_foo_" @class="post-body" />`, resetCache();
test(assert) {
const html = query(".post-body").innerHTML.trim();
assert.strictEqual(html, "<p><em>foo</em></p>");
},
}); });
componentTest("resolves short URLs", { test("renders markdown", async function (assert) {
template: hbs`<CookText @rawText="![an image](upload://a.png)" @class="post-body" />`, await render(hbs`<CookText @rawText="_foo_" @class="post-body" />`);
beforeEach() { const html = query(".post-body").innerHTML.trim();
assert.strictEqual(html, "<p><em>foo</em></p>");
});
test("resolves short URLs", async function (assert) {
pretender.post("/uploads/lookup-urls", () => { pretender.post("/uploads/lookup-urls", () => {
return [ return [
200, 200,
@ -35,18 +34,15 @@ discourseModule("Integration | Component | cook-text", function (hooks) {
], ],
]; ];
}); });
},
afterEach() { await render(
resetCache(); hbs`<CookText @rawText="![an image](upload://a.png)" @class="post-body" />`
}, );
test(assert) {
const html = query(".post-body").innerHTML.trim(); const html = query(".post-body").innerHTML.trim();
assert.strictEqual( assert.strictEqual(
html, html,
'<p><img src="/images/avatar.png" alt="an image"></p>' '<p><img src="/images/avatar.png" alt="an image"></p>'
); );
},
}); });
}); });

View File

@ -1,82 +1,57 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render, triggerKeyEvent } from "@ember/test-helpers";
import { import { exists, query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
exists,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import { triggerKeyEvent } from "@ember/test-helpers";
import I18n from "I18n"; import I18n from "I18n";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | d-button", function (hooks) { module("Integration | Component | d-button", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("icon only button", { test("icon only button", async function (assert) {
template: hbs`{{d-button icon="plus" tabindex="3"}}`, await render(hbs`<DButton @icon="plus" tabindex="3" />`);
test(assert) { assert.ok(exists("button.btn.btn-icon.no-text"), "it has all the classes");
assert.ok(
exists("button.btn.btn-icon.no-text"),
"it has all the classes"
);
assert.ok(exists("button .d-icon.d-icon-plus"), "it has the icon"); assert.ok(exists("button .d-icon.d-icon-plus"), "it has the icon");
assert.strictEqual( assert.strictEqual(
queryAll("button").attr("tabindex"), query("button").getAttribute("tabindex"),
"3", "3",
"it has the tabindex" "it has the tabindex"
); );
},
}); });
componentTest("icon and text button", { test("icon and text button", async function (assert) {
template: hbs`{{d-button icon="plus" label="topic.create"}}`, await render(hbs`<DButton @icon="plus" @label="topic.create" />`);
test(assert) {
assert.ok(exists("button.btn.btn-icon-text"), "it has all the classes"); assert.ok(exists("button.btn.btn-icon-text"), "it has all the classes");
assert.ok(exists("button .d-icon.d-icon-plus"), "it has the icon"); assert.ok(exists("button .d-icon.d-icon-plus"), "it has the icon");
assert.ok(exists("button span.d-button-label"), "it has the label"); assert.ok(exists("button span.d-button-label"), "it has the label");
},
}); });
componentTest("text only button", { test("text only button", async function (assert) {
template: hbs`{{d-button label="topic.create"}}`, await render(hbs`<DButton @label="topic.create" />`);
test(assert) {
assert.ok(exists("button.btn.btn-text"), "it has all the classes"); assert.ok(exists("button.btn.btn-text"), "it has all the classes");
assert.ok(exists("button span.d-button-label"), "it has the label"); assert.ok(exists("button span.d-button-label"), "it has the label");
},
}); });
componentTest("form attribute", { test("form attribute", async function (assert) {
template: hbs`{{d-button form="login-form"}}`, await render(hbs`<DButton @form="login-form" />`);
test(assert) {
assert.ok(exists("button[form=login-form]"), "it has the form attribute"); assert.ok(exists("button[form=login-form]"), "it has the form attribute");
},
}); });
componentTest("link-styled button", { test("link-styled button", async function (assert) {
template: hbs`{{d-button display="link"}}`, await render(hbs`<DButton @display="link" />`);
test(assert) { assert.ok(exists("button.btn-link:not(.btn)"), "it has the right classes");
assert.ok(
exists("button.btn-link:not(.btn)"),
"it has the right classes"
);
},
}); });
componentTest("isLoading button", { test("isLoading button", async function (assert) {
template: hbs`{{d-button isLoading=isLoading}}`,
beforeEach() {
this.set("isLoading", true); this.set("isLoading", true);
},
test(assert) { await render(hbs`<DButton @isLoading={{this.isLoading}} />`);
assert.ok( assert.ok(
exists("button.is-loading .loading-icon"), exists("button.is-loading .loading-icon"),
"it has a spinner showing" "it has a spinner showing"
@ -96,13 +71,11 @@ discourseModule("Integration | Component | d-button", function (hooks) {
exists("button:not([disabled])"), exists("button:not([disabled])"),
"while not loading the button is enabled" "while not loading the button is enabled"
); );
},
}); });
componentTest("button without isLoading attribute", { test("button without isLoading attribute", async function (assert) {
template: hbs`{{d-button}}`, await render(hbs`<DButton />`);
test(assert) {
assert.notOk( assert.notOk(
exists("button.is-loading"), exists("button.is-loading"),
"it doesn't have class is-loading" "it doesn't have class is-loading"
@ -112,17 +85,13 @@ discourseModule("Integration | Component | d-button", function (hooks) {
"it doesn't have a spinner showing" "it doesn't have a spinner showing"
); );
assert.notOk(exists("button[disabled]"), "it isn't disabled"); assert.notOk(exists("button[disabled]"), "it isn't disabled");
},
}); });
componentTest("isLoading button explicitly set to undefined state", { test("isLoading button explicitly set to undefined state", async function (assert) {
template: hbs`{{d-button isLoading=isLoading}}`,
beforeEach() {
this.set("isLoading"); this.set("isLoading");
},
test(assert) { await render(hbs`<DButton @isLoading={{this.isLoading}} />`);
assert.notOk( assert.notOk(
exists("button.is-loading"), exists("button.is-loading"),
"it doesn't have class is-loading" "it doesn't have class is-loading"
@ -132,33 +101,26 @@ discourseModule("Integration | Component | d-button", function (hooks) {
"it doesn't have a spinner showing" "it doesn't have a spinner showing"
); );
assert.notOk(exists("button[disabled]"), "it isn't disabled"); assert.notOk(exists("button[disabled]"), "it isn't disabled");
},
}); });
componentTest("disabled button", { test("disabled button", async function (assert) {
template: hbs`{{d-button disabled=disabled}}`,
beforeEach() {
this.set("disabled", true); this.set("disabled", true);
},
test(assert) { await render(hbs`<DButton @disabled={{this.disabled}} />`);
assert.ok(exists("button[disabled]"), "the button is disabled"); assert.ok(exists("button[disabled]"), "the button is disabled");
this.set("disabled", false); this.set("disabled", false);
assert.ok(exists("button:not([disabled])"), "the button is enabled"); assert.ok(exists("button:not([disabled])"), "the button is enabled");
},
}); });
componentTest("aria-label", { test("aria-label", async function (assert) {
template: hbs`{{d-button ariaLabel=ariaLabel translatedAriaLabel=translatedAriaLabel}}`,
beforeEach() {
I18n.translations[I18n.locale].js.test = { fooAriaLabel: "foo" }; I18n.translations[I18n.locale].js.test = { fooAriaLabel: "foo" };
},
test(assert) { await render(
hbs`<DButton @ariaLabel={{this.ariaLabel}} @translatedAriaLabel={{this.translatedAriaLabel}} />`
);
this.set("ariaLabel", "test.fooAriaLabel"); this.set("ariaLabel", "test.fooAriaLabel");
assert.strictEqual( assert.strictEqual(
@ -172,17 +134,15 @@ discourseModule("Integration | Component | d-button", function (hooks) {
}); });
assert.strictEqual(query("button").getAttribute("aria-label"), "bar"); assert.strictEqual(query("button").getAttribute("aria-label"), "bar");
},
}); });
componentTest("title", { test("title", async function (assert) {
template: hbs`{{d-button title=title translatedTitle=translatedTitle}}`,
beforeEach() {
I18n.translations[I18n.locale].js.test = { fooTitle: "foo" }; I18n.translations[I18n.locale].js.test = { fooTitle: "foo" };
},
test(assert) { await render(
hbs`<DButton @title={{this.title}} @translatedTitle={{this.translatedTitle}} />`
);
this.set("title", "test.fooTitle"); this.set("title", "test.fooTitle");
assert.strictEqual( assert.strictEqual(
query("button").getAttribute("title"), query("button").getAttribute("title"),
@ -195,21 +155,19 @@ discourseModule("Integration | Component | d-button", function (hooks) {
}); });
assert.strictEqual(query("button").getAttribute("title"), "bar"); assert.strictEqual(query("button").getAttribute("title"), "bar");
},
}); });
componentTest("label", { test("label", async function (assert) {
template: hbs`{{d-button label=label translatedLabel=translatedLabel}}`,
beforeEach() {
I18n.translations[I18n.locale].js.test = { fooLabel: "foo" }; I18n.translations[I18n.locale].js.test = { fooLabel: "foo" };
},
test(assert) { await render(
hbs`<DButton @label={{this.label}} @translatedLabel={{this.translatedLabel}} />`
);
this.set("label", "test.fooLabel"); this.set("label", "test.fooLabel");
assert.strictEqual( assert.strictEqual(
queryAll("button .d-button-label").text(), query("button .d-button-label").innerText,
I18n.t("test.fooLabel") I18n.t("test.fooLabel")
); );
@ -218,49 +176,38 @@ discourseModule("Integration | Component | d-button", function (hooks) {
translatedLabel: "bar", translatedLabel: "bar",
}); });
assert.strictEqual(queryAll("button .d-button-label").text(), "bar"); assert.strictEqual(query("button .d-button-label").innerText, "bar");
},
}); });
componentTest("aria-expanded", { test("aria-expanded", async function (assert) {
template: hbs`{{d-button ariaExpanded=ariaExpanded}}`, await render(hbs`<DButton @ariaExpanded={{this.ariaExpanded}} />`);
test(assert) {
assert.strictEqual(query("button").getAttribute("aria-expanded"), null); assert.strictEqual(query("button").getAttribute("aria-expanded"), null);
this.set("ariaExpanded", true); this.set("ariaExpanded", true);
assert.strictEqual(query("button").getAttribute("aria-expanded"), "true"); assert.strictEqual(query("button").getAttribute("aria-expanded"), "true");
this.set("ariaExpanded", false); this.set("ariaExpanded", false);
assert.strictEqual( assert.strictEqual(query("button").getAttribute("aria-expanded"), "false");
query("button").getAttribute("aria-expanded"),
"false"
);
this.set("ariaExpanded", "false"); this.set("ariaExpanded", "false");
assert.strictEqual(query("button").getAttribute("aria-expanded"), null); assert.strictEqual(query("button").getAttribute("aria-expanded"), null);
this.set("ariaExpanded", "true"); this.set("ariaExpanded", "true");
assert.strictEqual(query("button").getAttribute("aria-expanded"), null); assert.strictEqual(query("button").getAttribute("aria-expanded"), null);
},
}); });
componentTest("aria-controls", { test("aria-controls", async function (assert) {
template: hbs`{{d-button ariaControls=ariaControls}}`, await render(hbs`<DButton @ariaControls={{this.ariaControls}} />`);
test(assert) {
this.set("ariaControls", "foo-bar"); this.set("ariaControls", "foo-bar");
assert.strictEqual( assert.strictEqual(
query("button").getAttribute("aria-controls"), query("button").getAttribute("aria-controls"),
"foo-bar" "foo-bar"
); );
},
}); });
componentTest("onKeyDown callback", { test("onKeyDown callback", async function (assert) {
template: hbs`{{d-button action=action onKeyDown=onKeyDown}}`,
beforeEach() {
this.set("foo", null); this.set("foo", null);
this.set("onKeyDown", () => { this.set("onKeyDown", () => {
this.set("foo", "bar"); this.set("foo", "bar");
@ -268,37 +215,30 @@ discourseModule("Integration | Component | d-button", function (hooks) {
this.set("action", () => { this.set("action", () => {
this.set("foo", "baz"); this.set("foo", "baz");
}); });
},
async test(assert) { await render(
hbs`<DButton @action={{this.action}} @onKeyDown={{this.onKeyDown}} />`
);
await triggerKeyEvent(".btn", "keydown", 32); await triggerKeyEvent(".btn", "keydown", 32);
assert.strictEqual(this.foo, "bar"); assert.strictEqual(this.foo, "bar");
await triggerKeyEvent(".btn", "keydown", 13); await triggerKeyEvent(".btn", "keydown", 13);
assert.strictEqual(this.foo, "bar"); assert.strictEqual(this.foo, "bar");
},
}); });
componentTest("press Enter", { test("press Enter", async function (assert) {
template: hbs`{{d-button action=action}}`,
beforeEach() {
this.set("foo", null); this.set("foo", null);
this.set("action", () => { this.set("action", () => {
this.set("foo", "bar"); this.set("foo", "bar");
}); });
},
async test(assert) { await render(hbs`<DButton @action={{this.action}} />`);
await triggerKeyEvent(".btn", "keydown", 32); await triggerKeyEvent(".btn", "keydown", 32);
assert.strictEqual(this.foo, null); assert.strictEqual(this.foo, null);
await triggerKeyEvent(".btn", "keydown", 13); await triggerKeyEvent(".btn", "keydown", 13);
assert.strictEqual(this.foo, "bar"); assert.strictEqual(this.foo, "bar");
},
}); });
}); });

View File

@ -1,78 +1,71 @@
import { click, fillIn, settled } from "@ember/test-helpers"; import { module, test } from "qunit";
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest, import { click, fillIn, render, settled } from "@ember/test-helpers";
} from "discourse/tests/helpers/component-test";
import { import {
discourseModule, chromeTest,
exists, exists,
paste, paste,
query, query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import { import {
getTextareaSelection, getTextareaSelection,
setTextareaSelection, setTextareaSelection,
} from "discourse/tests/helpers/textarea-selection-helper"; } from "discourse/tests/helpers/textarea-selection-helper";
import hbs from "htmlbars-inline-precompile";
import I18n from "I18n"; import I18n from "I18n";
import { clearToolbarCallbacks } from "discourse/components/d-editor"; import { clearToolbarCallbacks } from "discourse/components/d-editor";
import formatTextWithSelection from "discourse/tests/helpers/d-editor-helper"; import formatTextWithSelection from "discourse/tests/helpers/d-editor-helper";
import hbs from "htmlbars-inline-precompile";
import { next } from "@ember/runloop"; import { next } from "@ember/runloop";
import { withPluginApi } from "discourse/lib/plugin-api"; import { withPluginApi } from "discourse/lib/plugin-api";
discourseModule("Integration | Component | d-editor", function (hooks) { module("Integration | Component | d-editor", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("preview updates with markdown", { hooks.afterEach(function () {
template: hbs`{{d-editor value=value}}`, clearToolbarCallbacks();
});
test("preview updates with markdown", async function (assert) {
await render(hbs`<DEditor @value={{this.value}} />`);
async test(assert) {
assert.ok(exists(".d-editor-button-bar")); assert.ok(exists(".d-editor-button-bar"));
await fillIn(".d-editor-input", "hello **world**"); await fillIn(".d-editor-input", "hello **world**");
assert.strictEqual(this.value, "hello **world**"); assert.strictEqual(this.value, "hello **world**");
assert.strictEqual( assert.strictEqual(
queryAll(".d-editor-preview").html().trim(), query(".d-editor-preview").innerHTML.trim(),
"<p>hello <strong>world</strong></p>" "<p>hello <strong>world</strong></p>"
); );
},
}); });
componentTest("links in preview are not tabbable", { test("links in preview are not tabbable", async function (assert) {
template: hbs`{{d-editor value=value}}`, await render(hbs`<DEditor @value={{this.value}} />`);
async test(assert) {
await fillIn(".d-editor-input", "[discourse](https://www.discourse.org)"); await fillIn(".d-editor-input", "[discourse](https://www.discourse.org)");
assert.strictEqual( assert.strictEqual(
queryAll(".d-editor-preview").html().trim(), query(".d-editor-preview").innerHTML.trim(),
'<p><a href="https://www.discourse.org" tabindex="-1">discourse</a></p>' '<p><a href="https://www.discourse.org" tabindex="-1">discourse</a></p>'
); );
},
}); });
componentTest("preview sanitizes HTML", { test("preview sanitizes HTML", async function (assert) {
template: hbs`{{d-editor value=value}}`, await render(hbs`<DEditor @value={{this.value}} />`);
async test(assert) {
await fillIn(".d-editor-input", `"><svg onload="prompt(/xss/)"></svg>`); await fillIn(".d-editor-input", `"><svg onload="prompt(/xss/)"></svg>`);
assert.strictEqual( assert.strictEqual(
queryAll(".d-editor-preview").html().trim(), query(".d-editor-preview").innerHTML.trim(),
'<p>"&gt;</p>' '<p>"&gt;</p>'
); );
},
}); });
componentTest("updating the value refreshes the preview", { test("updating the value refreshes the preview", async function (assert) {
template: hbs`{{d-editor value=value}}`,
beforeEach() {
this.set("value", "evil trout"); this.set("value", "evil trout");
},
async test(assert) { await render(hbs`<DEditor @value={{this.value}} />`);
assert.strictEqual( assert.strictEqual(
queryAll(".d-editor-preview").html().trim(), query(".d-editor-preview").innerHTML.trim(),
"<p>evil trout</p>" "<p>evil trout</p>"
); );
@ -80,10 +73,9 @@ discourseModule("Integration | Component | d-editor", function (hooks) {
await settled(); await settled();
assert.strictEqual( assert.strictEqual(
queryAll(".d-editor-preview").html().trim(), query(".d-editor-preview").innerHTML.trim(),
"<p>zogstrip</p>" "<p>zogstrip</p>"
); );
},
}); });
function jumpEnd(textarea) { function jumpEnd(textarea) {
@ -93,30 +85,26 @@ discourseModule("Integration | Component | d-editor", function (hooks) {
} }
function testCase(title, testFunc) { function testCase(title, testFunc) {
componentTest(title, { chromeTest(title, async function (assert) {
template: hbs`{{d-editor value=value}}`,
beforeEach() {
this.set("value", "hello world."); this.set("value", "hello world.");
},
async test(assert) { await render(hbs`<DEditor @value={{this.value}} />`);
const textarea = jumpEnd(query("textarea.d-editor-input")); const textarea = jumpEnd(query("textarea.d-editor-input"));
await testFunc.call(this, assert, textarea); await testFunc.call(this, assert, textarea);
},
skip: !navigator.userAgent.includes("Chrome"),
}); });
} }
function composerTestCase(title, testFunc) { function composerTestCase(title, testFunc) {
componentTest(title, { test(title, async function (assert) {
template: hbs`{{d-editor value=value composerEvents=true}}`,
beforeEach() {
this.set("value", "hello world."); this.set("value", "hello world.");
},
async test(assert) { await render(
hbs`<DEditor @value={{this.value}} @composerEvents={{true}} />`
);
const textarea = jumpEnd(query("textarea.d-editor-input")); const textarea = jumpEnd(query("textarea.d-editor-input"));
await testFunc.call(this, assert, textarea); await testFunc.call(this, assert, textarea);
},
}); });
} }
@ -255,23 +243,21 @@ discourseModule("Integration | Component | d-editor", function (hooks) {
} }
); );
componentTest("advanced code", { test("advanced code", async function (assert) {
template: hbs`{{d-editor value=value}}`,
beforeEach() {
this.siteSettings.code_formatting_style = "4-spaces-indent"; this.siteSettings.code_formatting_style = "4-spaces-indent";
this.set( this.set(
"value", "value",
` `
function xyz(x, y, z) { function xyz(x, y, z) {
if (y === z) { if (y === z) {
return true; return true;
} }
} }
` `
); );
},
async test(assert) { await render(hbs`<DEditor @value={{this.value}} />`);
const textarea = query("textarea.d-editor-input"); const textarea = query("textarea.d-editor-input");
textarea.selectionStart = 0; textarea.selectionStart = 0;
textarea.selectionEnd = textarea.value.length; textarea.selectionEnd = textarea.value.length;
@ -285,18 +271,15 @@ discourseModule("Integration | Component | d-editor", function (hooks) {
return true; return true;
} }
} }
` `
); );
},
}); });
componentTest("code button", { test("code button", async function (assert) {
template: hbs`{{d-editor value=value}}`,
beforeEach() {
this.siteSettings.code_formatting_style = "4-spaces-indent"; this.siteSettings.code_formatting_style = "4-spaces-indent";
},
async test(assert) { await render(hbs`<DEditor @value={{this.value}} />`);
const textarea = jumpEnd(query("textarea.d-editor-input")); const textarea = jumpEnd(query("textarea.d-editor-input"));
await click("button.code"); await click("button.code");
@ -348,10 +331,7 @@ third line`
textarea.selectionEnd = 10; textarea.selectionEnd = 10;
await click("button.code"); await click("button.code");
assert.strictEqual( assert.strictEqual(this.value, "first `line`\n\nsecond line\n\nthird line");
this.value,
"first `line`\n\nsecond line\n\nthird line"
);
assert.strictEqual(textarea.selectionStart, 7); assert.strictEqual(textarea.selectionStart, 7);
assert.strictEqual(textarea.selectionEnd, 11); assert.strictEqual(textarea.selectionEnd, 11);
@ -375,16 +355,13 @@ third line`
assert.strictEqual(this.value, "first line\n\nsecond line\n\nthird line"); assert.strictEqual(this.value, "first line\n\nsecond line\n\nthird line");
assert.strictEqual(textarea.selectionStart, 0); assert.strictEqual(textarea.selectionStart, 0);
assert.strictEqual(textarea.selectionEnd, 23); assert.strictEqual(textarea.selectionEnd, 23);
},
}); });
componentTest("code fences", { test("code fences", async function (assert) {
template: hbs`{{d-editor value=value}}`,
beforeEach() {
this.set("value", ""); this.set("value", "");
},
async test(assert) { await render(hbs`<DEditor @value={{this.value}} />`);
const textarea = jumpEnd(query("textarea.d-editor-input")); const textarea = jumpEnd(query("textarea.d-editor-input"));
await click("button.code"); await click("button.code");
@ -491,15 +468,15 @@ third line`
document.execCommand("undo"); document.execCommand("undo");
assert.strictEqual(this.value, "first line\nsecond line\nthird line"); assert.strictEqual(this.value, "first line\nsecond line\nthird line");
},
}); });
componentTest("quote button - empty lines", { test("quote button - empty lines", async function (assert) {
template: hbs`{{d-editor value=value composerEvents=true}}`,
beforeEach() {
this.set("value", "one\n\ntwo\n\nthree"); this.set("value", "one\n\ntwo\n\nthree");
},
async test(assert) { await render(
hbs`<DEditor @value={{this.value}} @composerEvents={{true}} />`
);
const textarea = jumpEnd(query("textarea.d-editor-input")); const textarea = jumpEnd(query("textarea.d-editor-input"));
textarea.selectionStart = 0; textarea.selectionStart = 0;
@ -512,15 +489,15 @@ third line`
await click("button.blockquote"); await click("button.blockquote");
assert.strictEqual(this.value, "one\n\ntwo\n\nthree"); assert.strictEqual(this.value, "one\n\ntwo\n\nthree");
},
}); });
componentTest("quote button - selecting empty lines", { test("quote button - selecting empty lines", async function (assert) {
template: hbs`{{d-editor value=value composerEvents=true}}`,
beforeEach() {
this.set("value", "one\n\n\n\ntwo"); this.set("value", "one\n\n\n\ntwo");
},
async test(assert) { await render(
hbs`<DEditor @value={{this.value}} @composerEvents={{true}} />`
);
const textarea = jumpEnd(query("textarea.d-editor-input")); const textarea = jumpEnd(query("textarea.d-editor-input"));
textarea.selectionStart = 6; textarea.selectionStart = 6;
@ -531,7 +508,6 @@ third line`
document.execCommand("undo"); document.execCommand("undo");
assert.strictEqual(this.value, "one\n\n\n\ntwo"); assert.strictEqual(this.value, "one\n\n\n\ntwo");
},
}); });
testCase("quote button", async function (assert, textarea) { testCase("quote button", async function (assert, textarea) {
@ -652,33 +628,29 @@ third line`
assert.strictEqual(textarea.selectionEnd, 18); assert.strictEqual(textarea.selectionEnd, 18);
}); });
componentTest("clicking the toggle-direction changes dir from ltr to rtl", { test("clicking the toggle-direction changes dir from ltr to rtl", async function (assert) {
template: hbs`{{d-editor value=value}}`,
beforeEach() {
this.siteSettings.support_mixed_text_direction = true; this.siteSettings.support_mixed_text_direction = true;
this.siteSettings.default_locale = "en"; this.siteSettings.default_locale = "en";
},
async test(assert) { await render(hbs`<DEditor @value={{this.value}} />`);
const textarea = queryAll("textarea.d-editor-input");
await click("button.toggle-direction"); await click("button.toggle-direction");
assert.strictEqual(textarea.attr("dir"), "rtl"); assert.strictEqual(
}, query("textarea.d-editor-input").getAttribute("dir"),
"rtl"
);
}); });
componentTest("clicking the toggle-direction changes dir from ltr to rtl", { test("clicking the toggle-direction changes dir from ltr to rtl", async function (assert) {
template: hbs`{{d-editor value=value}}`,
beforeEach() {
this.siteSettings.support_mixed_text_direction = true; this.siteSettings.support_mixed_text_direction = true;
this.siteSettings.default_locale = "en"; this.siteSettings.default_locale = "en";
},
async test(assert) { await render(hbs`<DEditor @value={{this.value}} />`);
const textarea = queryAll("textarea.d-editor-input");
textarea.attr("dir", "ltr"); const textarea = query("textarea.d-editor-input");
textarea.setAttribute("dir", "ltr");
await click("button.toggle-direction"); await click("button.toggle-direction");
assert.strictEqual(textarea.attr("dir"), "rtl"); assert.strictEqual(textarea.getAttribute("dir"), "rtl");
},
}); });
testCase( testCase(
@ -699,9 +671,7 @@ third line`
} }
); );
componentTest("emoji", { test("emoji", async function (assert) {
template: hbs`{{d-editor value=value}}`,
beforeEach() {
// Test adding a custom button // Test adding a custom button
withPluginApi("0.1", (api) => { withPluginApi("0.1", (api) => {
api.onToolbarCreate((toolbar) => { api.onToolbarCreate((toolbar) => {
@ -714,13 +684,9 @@ third line`
}); });
}); });
this.set("value", "hello world."); this.set("value", "hello world.");
},
afterEach() { await render(hbs`<DEditor @value={{this.value}} />`);
clearToolbarCallbacks();
},
async test(assert) {
jumpEnd(query("textarea.d-editor-input")); jumpEnd(query("textarea.d-editor-input"));
await click("button.emoji"); await click("button.emoji");
@ -746,7 +712,6 @@ third line`
"starting to type an emoji like :grinning:", "starting to type an emoji like :grinning:",
"it works when there is a partial emoji" "it works when there is a partial emoji"
); );
},
}); });
testCase("replace-text event by default", async function (assert) { testCase("replace-text event by default", async function (assert) {
@ -863,35 +828,33 @@ third line`
} }
); );
componentTest("paste table", { test("paste table", async function (assert) {
template: hbs`{{d-editor value=value composerEvents=true}}`,
beforeEach() {
this.set("value", ""); this.set("value", "");
this.siteSettings.enable_rich_text_paste = true; this.siteSettings.enable_rich_text_paste = true;
},
async test(assert) { await render(
hbs`<DEditor @value={{this.value}} @composerEvents={{true}} />`
);
let element = query(".d-editor"); let element = query(".d-editor");
await paste(element, "\ta\tb\n1\t2\t3"); await paste(element, "\ta\tb\n1\t2\t3");
assert.strictEqual(this.value, "||a|b|\n|---|---|---|\n|1|2|3|\n"); assert.strictEqual(this.value, "||a|b|\n|---|---|---|\n|1|2|3|\n");
document.execCommand("undo"); document.execCommand("undo");
assert.strictEqual(this.value, ""); assert.strictEqual(this.value, "");
},
}); });
componentTest("paste a different table", { test("paste a different table", async function (assert) {
template: hbs`{{d-editor value=value composerEvents=true}}`,
beforeEach() {
this.set("value", ""); this.set("value", "");
this.siteSettings.enable_rich_text_paste = true; this.siteSettings.enable_rich_text_paste = true;
},
async test(assert) { await render(
hbs`<DEditor @value={{this.value}} @composerEvents={{true}} />`
);
let element = query(".d-editor"); let element = query(".d-editor");
await paste(element, '\ta\tb\n1\t"2\n2.5"\t3'); await paste(element, '\ta\tb\n1\t"2\n2.5"\t3');
assert.strictEqual(this.value, "||a|b|\n|---|---|---|\n|1|2<br>2.5|3|\n"); assert.strictEqual(this.value, "||a|b|\n|---|---|---|\n|1|2<br>2.5|3|\n");
},
}); });
testCase( testCase(
@ -1066,7 +1029,7 @@ third line`
await focus(textarea); await focus(textarea);
assert.ok(textarea.value === BEFORE); assert.strictEqual(textarea.value, BEFORE);
const [start, len] = CASE.before; const [start, len] = CASE.before;
setTextareaSelection(textarea, start, start + len); setTextareaSelection(textarea, start, start + len);

View File

@ -0,0 +1,29 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
module("Integration | Component | d-icon helper", function (hooks) {
setupRenderingTest(hooks);
test("default", async function (assert) {
await render(hbs`<div class="test">{{d-icon "bars"}}</div>`);
const html = query(".test").innerHTML.trim();
assert.strictEqual(
html,
'<svg class="fa d-icon d-icon-bars svg-icon svg-string" xmlns="http://www.w3.org/2000/svg"><use href="#bars"></use></svg>'
);
});
test("with replacement", async function (assert) {
await render(hbs`<div class="test">{{d-icon "d-watching"}}</div>`);
const html = query(".test").innerHTML.trim();
assert.strictEqual(
html,
'<svg class="fa d-icon d-icon-d-watching svg-icon svg-string" xmlns="http://www.w3.org/2000/svg"><use href="#discourse-bell-exclamation"></use></svg>'
);
});
});

View File

@ -1,36 +0,0 @@
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import {
discourseModule,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | d-icon", function (hooks) {
setupRenderingTest(hooks);
componentTest("default", {
template: hbs`<div class="test">{{d-icon "bars"}}</div>`,
test(assert) {
const html = queryAll(".test").html().trim();
assert.strictEqual(
html,
'<svg class="fa d-icon d-icon-bars svg-icon svg-string" xmlns="http://www.w3.org/2000/svg"><use href="#bars"></use></svg>'
);
},
});
componentTest("with replacement", {
template: hbs`<div class="test">{{d-icon "d-watching"}}</div>`,
test(assert) {
const html = queryAll(".test").html().trim();
assert.strictEqual(
html,
'<svg class="fa d-icon d-icon-d-watching svg-icon svg-string" xmlns="http://www.w3.org/2000/svg"><use href="#discourse-bell-exclamation"></use></svg>'
);
},
});
});

View File

@ -1,11 +1,10 @@
import { click } from "@ember/test-helpers"; import { module, test } from "qunit";
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest, import { click, render } from "@ember/test-helpers";
} from "discourse/tests/helpers/component-test"; import { count, query } from "discourse/tests/helpers/qunit-helpers";
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | d-navigation", function (hooks) { module("Integration | Component | d-navigation", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
@ -13,24 +12,19 @@ discourseModule("Integration | Component | d-navigation", function (hooks) {
.filter((category) => !category.parent_category_id) .filter((category) => !category.parent_category_id)
.slice(0, 4); .slice(0, 4);
this.site.setProperties({ categories }); this.site.setProperties({ categories });
this.currentUser.set( this.currentUser.set(
"indirectly_muted_category_ids", "indirectly_muted_category_ids",
categories.slice(0, 3).map((category) => category.id) categories.slice(0, 3).map((category) => category.id)
); );
}); });
componentTest("filters indirectly muted categories", { test("filters indirectly muted categories", async function (assert) {
template: hbs` await render(hbs`<DNavigation @filterType="categories" />`);
{{d-navigation
filterType="categories"
}}
`,
async test(assert) {
await click(".category-drop .select-kit-header-wrapper"); await click(".category-drop .select-kit-header-wrapper");
assert.strictEqual( assert.strictEqual(
document.querySelectorAll(".category-row").length, count(".category-row"),
1, 1,
"displays only categories that are not muted" "displays only categories that are not muted"
); );
@ -38,6 +32,5 @@ discourseModule("Integration | Component | d-navigation", function (hooks) {
query(".category-row .badge-category span").textContent.trim(), query(".category-row .badge-category span").textContent.trim(),
"dev" "dev"
); );
},
}); });
}); });

View File

@ -1,102 +1,102 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render, triggerKeyEvent } from "@ember/test-helpers";
import { import { exists, query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { showPopover } from "discourse/lib/d-popover"; import { showPopover } from "discourse/lib/d-popover";
import { click, triggerKeyEvent } from "@ember/test-helpers";
discourseModule("Integration | Component | d-popover", function (hooks) { module("Integration | Component | d-popover", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("show/hide popover from lib", { test("show/hide popover from lib", async function (assert) {
template: hbs`{{d-button translatedLabel="test" action=onButtonClick forwardEvent=true}}`,
beforeEach() {
this.set("onButtonClick", (_, event) => { this.set("onButtonClick", (_, event) => {
showPopover(event, { content: "test", trigger: "click", duration: 0 }); showPopover(event, { content: "test", trigger: "click", duration: 0 });
}); });
},
async test(assert) { await render(hbs`
<DButton
@translatedLabel="test"
@action={{this.onButtonClick}}
@forwardEvent={{true}}
/>
`);
assert.notOk(document.querySelector("div[data-tippy-root]")); assert.notOk(document.querySelector("div[data-tippy-root]"));
await click(".btn"); await click(".btn");
assert.strictEqual(
assert.equal(
document.querySelector("div[data-tippy-root]").innerText.trim(), document.querySelector("div[data-tippy-root]").innerText.trim(),
"test" "test"
); );
await click(".btn"); await click(".btn");
assert.notOk(document.querySelector("div[data-tippy-root]")); assert.notOk(document.querySelector("div[data-tippy-root]"));
},
}); });
componentTest("show/hide popover from component", { test("show/hide popover from component", async function (assert) {
template: hbs`{{#d-popover}}{{d-button class="trigger" icon="chevron-down"}}<ul><li class="test">foo</li><li>{{d-button icon="times" class="closer"}}</li></ul>{{/d-popover}}`, await render(hbs`
<DPopover>
<DButton class="trigger" @icon="chevron-down" />
<ul>
<li class="test">foo</li>
<li><DButton class="closer" @icon="times" /></li>
</ul>
</DPopover>
`);
async test(assert) {
assert.notOk(exists(".d-popover.is-expanded")); assert.notOk(exists(".d-popover.is-expanded"));
assert.notOk(exists(".test")); assert.notOk(exists(".test"));
await click(".trigger"); await click(".trigger");
assert.ok(exists(".d-popover.is-expanded")); assert.ok(exists(".d-popover.is-expanded"));
assert.equal(query(".test").innerText.trim(), "foo"); assert.strictEqual(query(".test").innerText.trim(), "foo");
await click(".closer"); await click(".closer");
assert.notOk(exists(".d-popover.is-expanded")); assert.notOk(exists(".d-popover.is-expanded"));
},
}); });
componentTest("using options with component", { test("using options with component", async function (assert) {
template: hbs`{{#d-popover options=(hash content="bar")}}{{d-button icon="chevron-down"}}{{/d-popover}}`, await render(hbs`
<DPopover @options={{hash content="bar"}}>
<DButton @icon="chevron-down" />
</DPopover>
`);
async test(assert) {
await click(".btn"); await click(".btn");
assert.strictEqual(query(".tippy-content").innerText.trim(), "bar");
assert.equal(query(".tippy-content").innerText.trim(), "bar");
},
}); });
componentTest("d-popover component accepts a block", { test("d-popover component accepts a block", async function (assert) {
template: hbs`{{#d-popover as |state|}}{{d-button icon=(if state.isExpanded "chevron-up" "chevron-down")}}{{/d-popover}}`, await render(hbs`
<DPopover as |state|>
<DButton @icon={{if state.isExpanded "chevron-up" "chevron-down"}} />
</DPopover>
`);
async test(assert) {
assert.ok(exists(".d-icon-chevron-down")); assert.ok(exists(".d-icon-chevron-down"));
await click(".btn"); await click(".btn");
assert.ok(exists(".d-icon-chevron-up")); assert.ok(exists(".d-icon-chevron-up"));
},
}); });
componentTest("d-popover component accepts a class property", { test("d-popover component accepts a class property", async function (assert) {
template: hbs`{{#d-popover class="foo"}}{{/d-popover}}`, await render(hbs`<DPopover @class="foo"></DPopover>`);
async test(assert) {
assert.ok(exists(".d-popover.foo")); assert.ok(exists(".d-popover.foo"));
},
}); });
componentTest("d-popover component closes on escape key", { test("d-popover component closes on escape key", async function (assert) {
template: hbs`{{#d-popover as |state|}}{{d-button icon=(if state.isExpanded "chevron-up" "chevron-down")}}{{/d-popover}}`, await render(hbs`
<DPopover as |state|>
<DButton @icon={{if state.isExpanded "chevron-up" "chevron-down"}} />
</DPopover>
`);
async test(assert) {
await click(".btn"); await click(".btn");
assert.ok(exists(".d-popover.is-expanded")); assert.ok(exists(".d-popover.is-expanded"));
await triggerKeyEvent(document, "keydown", 27); await triggerKeyEvent(document, "keydown", 27);
assert.notOk(exists(".d-popover.is-expanded")); assert.notOk(exists(".d-popover.is-expanded"));
},
}); });
}); });

View File

@ -1,7 +1,7 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers"; import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
function dateInput() { function dateInput() {
@ -16,50 +16,42 @@ function noop() {}
const DEFAULT_DATE = moment("2019-01-29"); const DEFAULT_DATE = moment("2019-01-29");
discourseModule("Integration | Component | date-input", function (hooks) { module("Integration | Component | date-input", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("default", { test("default", async function (assert) {
template: hbs`{{date-input date=date}}`,
beforeEach() {
this.setProperties({ date: DEFAULT_DATE }); this.setProperties({ date: DEFAULT_DATE });
},
test(assert) { await render(hbs`<DateInput @date={{this.date}} />`);
assert.strictEqual(dateInput().value, "2019-01-29"); assert.strictEqual(dateInput().value, "2019-01-29");
},
}); });
componentTest("prevents mutations", { test("prevents mutations", async function (assert) {
template: hbs`{{date-input date=date onChange=onChange}}`,
beforeEach() {
this.setProperties({ date: DEFAULT_DATE }); this.setProperties({ date: DEFAULT_DATE });
this.set("onChange", noop); this.set("onChange", noop);
},
async test(assert) { await render(
hbs`<DateInput @date={{this.date}} @onChange={{this.onChange}} />`
);
dateInput().value = "2019-01-02"; dateInput().value = "2019-01-02";
dateInput().dispatchEvent(new Event("change")); dateInput().dispatchEvent(new Event("change"));
assert.ok(this.date.isSame(DEFAULT_DATE)); assert.ok(this.date.isSame(DEFAULT_DATE));
},
}); });
componentTest("allows mutations through actions", { test("allows mutations through actions", async function (assert) {
template: hbs`{{date-input date=date onChange=onChange}}`,
beforeEach() {
this.setProperties({ date: DEFAULT_DATE }); this.setProperties({ date: DEFAULT_DATE });
this.set("onChange", setDate); this.set("onChange", setDate);
},
async test(assert) { await render(
hbs`<DateInput @date={{this.date}} @onChange={{this.onChange}} />`
);
dateInput().value = "2019-02-02"; dateInput().value = "2019-02-02";
dateInput().dispatchEvent(new Event("change")); dateInput().dispatchEvent(new Event("change"));
assert.ok(this.date.isSame(moment("2019-02-02"))); assert.ok(this.date.isSame(moment("2019-02-02")));
},
}); });
}); });

View File

@ -1,7 +1,7 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers"; import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
function fromDateInput() { function fromDateInput() {
@ -22,24 +22,19 @@ function toTimeInput() {
const DEFAULT_DATE_TIME = moment("2019-01-29 14:45"); const DEFAULT_DATE_TIME = moment("2019-01-29 14:45");
discourseModule( module("Integration | Component | date-time-input-range", function (hooks) {
"Integration | Component | date-time-input-range",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("default", { test("default", async function (assert) {
template: hbs`{{date-time-input-range from=from to=to}}`,
beforeEach() {
this.setProperties({ from: DEFAULT_DATE_TIME, to: null }); this.setProperties({ from: DEFAULT_DATE_TIME, to: null });
},
test(assert) { await render(
hbs`<DateTimeInputRange @from={{this.from}} @to={{this.to}} />`
);
assert.strictEqual(fromDateInput().value, "2019-01-29"); assert.strictEqual(fromDateInput().value, "2019-01-29");
assert.strictEqual(fromTimeInput().dataset.name, "14:45"); assert.strictEqual(fromTimeInput().dataset.name, "14:45");
assert.strictEqual(toDateInput().value, ""); assert.strictEqual(toDateInput().value, "");
assert.strictEqual(toTimeInput().dataset.name, "--:--"); assert.strictEqual(toTimeInput().dataset.name, "--:--");
},
}); });
} });
);

View File

@ -1,11 +1,7 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { import { exists, query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
function dateInput() { function dateInput() {
@ -22,61 +18,49 @@ function setDate(date) {
const DEFAULT_DATE_TIME = moment("2019-01-29 14:45"); const DEFAULT_DATE_TIME = moment("2019-01-29 14:45");
discourseModule("Integration | Component | date-time-input", function (hooks) { module("Integration | Component | date-time-input", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("default", { test("default", async function (assert) {
template: hbs`{{date-time-input date=date}}`,
beforeEach() {
this.setProperties({ date: DEFAULT_DATE_TIME }); this.setProperties({ date: DEFAULT_DATE_TIME });
},
test(assert) { await render(hbs`<DateTimeInput @date={{this.date}} />`);
assert.strictEqual(dateInput().value, "2019-01-29"); assert.strictEqual(dateInput().value, "2019-01-29");
assert.strictEqual(timeInput().dataset.name, "14:45"); assert.strictEqual(timeInput().dataset.name, "14:45");
},
}); });
componentTest("prevents mutations", { test("prevents mutations", async function (assert) {
template: hbs`{{date-time-input date=date}}`,
beforeEach() {
this.setProperties({ date: DEFAULT_DATE_TIME }); this.setProperties({ date: DEFAULT_DATE_TIME });
},
async test(assert) { await render(hbs`<DateTimeInput @date={{this.date}} />`);
dateInput().value = "2019-01-02"; dateInput().value = "2019-01-02";
assert.ok(this.date.isSame(DEFAULT_DATE_TIME)); assert.ok(this.date.isSame(DEFAULT_DATE_TIME));
},
}); });
componentTest("allows mutations through actions", { test("allows mutations through actions", async function (assert) {
template: hbs`{{date-time-input date=date onChange=onChange}}`,
beforeEach() {
this.setProperties({ date: DEFAULT_DATE_TIME }); this.setProperties({ date: DEFAULT_DATE_TIME });
this.set("onChange", setDate); this.set("onChange", setDate);
},
async test(assert) { await render(
hbs`<DateTimeInput @date={{this.date}} @onChange={{this.onChange}} />`
);
dateInput().value = "2019-01-02"; dateInput().value = "2019-01-02";
dateInput().dispatchEvent(new Event("change")); dateInput().dispatchEvent(new Event("change"));
assert.ok(this.date.isSame(moment("2019-01-02 14:45"))); assert.ok(this.date.isSame(moment("2019-01-02 14:45")));
},
}); });
componentTest("can hide time", { test("can hide time", async function (assert) {
template: hbs`{{date-time-input date=date showTime=false}}`,
beforeEach() {
this.setProperties({ date: DEFAULT_DATE_TIME }); this.setProperties({ date: DEFAULT_DATE_TIME });
},
async test(assert) { await render(
hbs`<DateTimeInput @date={{this.date}} @showTime={{false}} />`
);
assert.notOk(exists(timeInput())); assert.notOk(exists(timeInput()));
},
}); });
}); });

View File

@ -1,52 +1,43 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render } from "@ember/test-helpers";
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers"; import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { click } from "@ember/test-helpers";
discourseModule("Integration | Component | emoji-picker", function (hooks) { module("Integration | Component | emoji-picker", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("when placement == bottom, places the picker on the bottom", { test("when placement == bottom, places the picker on the bottom", async function (assert) {
template: hbs`
{{d-button class="emoji-picker-anchor" action=showEmojiPicker}}
{{emoji-picker isActive=pickerIsActive placement="bottom"}}
`,
beforeEach() {
this.set("showEmojiPicker", () => { this.set("showEmojiPicker", () => {
this.set("pickerIsActive", true); this.set("pickerIsActive", true);
}); });
},
async test(assert) { await render(hbs`
<DButton class="emoji-picker-anchor" @action={{this.showEmojiPicker}} />
<EmojiPicker @isActive={{this.pickerIsActive}} @placement="bottom" />
`);
await click(".emoji-picker-anchor"); await click(".emoji-picker-anchor");
assert.equal( assert.strictEqual(
query(".emoji-picker.opened").getAttribute("data-popper-placement"), query(".emoji-picker.opened").getAttribute("data-popper-placement"),
"bottom" "bottom"
); );
},
}); });
componentTest("when placement == right, places the picker on the right", { test("when placement == right, places the picker on the right", async function (assert) {
template: hbs`
{{d-button class="emoji-picker-anchor" action=showEmojiPicker}}
{{emoji-picker isActive=pickerIsActive placement="right"}}
`,
beforeEach() {
this.set("showEmojiPicker", () => { this.set("showEmojiPicker", () => {
this.set("pickerIsActive", true); this.set("pickerIsActive", true);
}); });
},
async test(assert) { await render(hbs`
<DButton class="emoji-picker-anchor" @action={{this.showEmojiPicker}} />
<EmojiPicker @isActive={{this.pickerIsActive}} @placement="right" />
`);
await click(".emoji-picker-anchor"); await click(".emoji-picker-anchor");
assert.equal( assert.strictEqual(
query(".emoji-picker.opened").getAttribute("data-popper-placement"), query(".emoji-picker.opened").getAttribute("data-popper-placement"),
"right" "right"
); );
},
}); });
}); });

View File

@ -1,26 +1,16 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { fillIn, render } from "@ember/test-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import { createFile } from "discourse/tests/helpers/qunit-helpers";
import {
createFile,
discourseModule,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import pretender, { response } from "discourse/tests/helpers/create-pretender"; import pretender, { response } from "discourse/tests/helpers/create-pretender";
import { fillIn } from "@ember/test-helpers"; import selectKit from "discourse/tests/helpers/select-kit-helper";
let requestNumber; let requestNumber;
discourseModule("Integration | Component | emoji-uploader", function (hooks) { module("Integration | Component | emoji-uploader", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
const template = hbs` {{emoji-uploader
emojiGroups=emojiGroups
done=doneUpload
id="emoji-uploader"
}}`;
hooks.beforeEach(function () { hooks.beforeEach(function () {
requestNumber = 0; requestNumber = 0;
this.setProperties({ this.setProperties({
@ -46,10 +36,15 @@ discourseModule("Integration | Component | emoji-uploader", function (hooks) {
}); });
}); });
componentTest("uses the selected group for the upload", { test("uses the selected group for the upload", async function (assert) {
template, await render(hbs`
<EmojiUploader
@id="emoji-uploader"
@emojiGroups={{this.emojiGroups}}
@done={{this.doneUpload}}
/>
`);
async test(assert) {
const done = assert.async(); const done = assert.async();
await selectKit("#emoji-group-selector").expand(); await selectKit("#emoji-group-selector").expand();
await selectKit("#emoji-group-selector").selectRowByValue("cool-emojis"); await selectKit("#emoji-group-selector").selectRowByValue("cool-emojis");
@ -59,16 +54,21 @@ discourseModule("Integration | Component | emoji-uploader", function (hooks) {
done(); done();
}); });
const image = createFile("avatar.png"); const image = createFile("avatar.png");
await this.container await this.container
.lookup("service:app-events") .lookup("service:app-events")
.trigger("upload-mixin:emoji-uploader:add-files", image); .trigger("upload-mixin:emoji-uploader:add-files", image);
},
}); });
componentTest("does not clear the selected group between multiple uploads", { test("does not clear the selected group between multiple uploads", async function (assert) {
template, await render(hbs`
<EmojiUploader
@id="emoji-uploader"
@emojiGroups={{this.emojiGroups}}
@done={{this.doneUpload}}
/>
`);
async test(assert) {
const done = assert.async(); const done = assert.async();
await selectKit("#emoji-group-selector").expand(); await selectKit("#emoji-group-selector").expand();
await selectKit("#emoji-group-selector").selectRowByValue("cool-emojis"); await selectKit("#emoji-group-selector").selectRowByValue("cool-emojis");
@ -85,23 +85,24 @@ discourseModule("Integration | Component | emoji-uploader", function (hooks) {
const image = createFile("avatar.png"); const image = createFile("avatar.png");
const image2 = createFile("avatar2.png"); const image2 = createFile("avatar2.png");
await this.container await this.container
.lookup("service:app-events") .lookup("service:app-events")
.trigger("upload-mixin:emoji-uploader:add-files", [image, image2]); .trigger("upload-mixin:emoji-uploader:add-files", [image, image2]);
},
}); });
componentTest( test("clears the name after the first upload to avoid duplicate names", async function (assert) {
"clears the name after the first upload to avoid duplicate names", await render(hbs`
{ <EmojiUploader
template, @id="emoji-uploader"
@emojiGroups={{this.emojiGroups}}
@done={{this.doneUpload}}
/>
`);
async test(assert) {
const done = assert.async(); const done = assert.async();
await selectKit("#emoji-group-selector").expand(); await selectKit("#emoji-group-selector").expand();
await selectKit("#emoji-group-selector").selectRowByValue( await selectKit("#emoji-group-selector").selectRowByValue("cool-emojis");
"cool-emojis"
);
await fillIn("#emoji-name", "okay"); await fillIn("#emoji-name", "okay");
let uploadDoneCount = 0; let uploadDoneCount = 0;
@ -123,7 +124,5 @@ discourseModule("Integration | Component | emoji-uploader", function (hooks) {
await this.container await this.container
.lookup("service:app-events") .lookup("service:app-events")
.trigger("upload-mixin:emoji-uploader:add-files", [image, image2]); .trigger("upload-mixin:emoji-uploader:add-files", [image, image2]);
}, });
}
);
}); });

View File

@ -1,18 +1,16 @@
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers"; import { module, test } from "qunit";
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest, import { render } from "@ember/test-helpers";
} from "discourse/tests/helpers/component-test"; import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | empty-state", function (hooks) { module("Integration | Component | empty-state", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("it renders", { test("it renders", async function (assert) {
template: hbs`<EmptyState @title="title" @body="body" />`, await render(hbs`<EmptyState @title="title" @body="body" />`);
test(assert) {
assert.strictEqual(query("[data-test-title]").textContent, "title"); assert.strictEqual(query("[data-test-title]").textContent, "title");
assert.strictEqual(query("[data-test-body]").textContent, "body"); assert.strictEqual(query("[data-test-body]").textContent, "body");
},
}); });
}); });

View File

@ -1,47 +1,35 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render, triggerKeyEvent } from "@ember/test-helpers";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import { click, triggerKeyEvent } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | flat-button", function (hooks) { module("Integration | Component | flat-button", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("press Enter", { test("press Enter", async function (assert) {
template: hbs`{{flat-button action=action}}`,
beforeEach() {
this.set("foo", null); this.set("foo", null);
this.set("action", () => { this.set("action", () => {
this.set("foo", "bar"); this.set("foo", "bar");
}); });
},
async test(assert) { await render(hbs`<FlatButton @action={{this.action}} />`);
await triggerKeyEvent(".btn-flat", "keydown", 32); await triggerKeyEvent(".btn-flat", "keydown", 32);
assert.strictEqual(this.foo, null); assert.strictEqual(this.foo, null);
await triggerKeyEvent(".btn-flat", "keydown", 13); await triggerKeyEvent(".btn-flat", "keydown", 13);
assert.strictEqual(this.foo, "bar"); assert.strictEqual(this.foo, "bar");
},
}); });
componentTest("click", {
template: hbs`{{flat-button action=action}}`,
beforeEach() { test("click", async function (assert) {
this.set("foo", null); this.set("foo", null);
this.set("action", () => { this.set("action", () => {
this.set("foo", "bar"); this.set("foo", "bar");
}); });
},
async test(assert) { await render(hbs`<FlatButton @action={{this.action}} />`);
await click(".btn-flat"); await click(".btn-flat");
assert.strictEqual(this.foo, "bar"); assert.strictEqual(this.foo, "bar");
},
}); });
}); });

View File

@ -1,21 +1,14 @@
import EmberObject from "@ember/object"; import { module, test } from "qunit";
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest, import { render } from "@ember/test-helpers";
} from "discourse/tests/helpers/component-test";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import EmberObject from "@ember/object";
discourseModule( module("Integration | Component | group-list site-setting", function (hooks) {
"Integration | Component | group-list site-setting",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("default", { test("default", async function (assert) {
template: hbs`{{site-setting setting=setting}}`,
beforeEach() {
this.site.groups = [ this.site.groups = [
{ {
id: 1, id: 1,
@ -44,9 +37,9 @@ discourseModule(
value: "1", value: "1",
}) })
); );
},
async test(assert) { await render(hbs`<SiteSetting @setting={{this.setting}} />`);
const subject = selectKit(".list-setting"); const subject = selectKit(".list-setting");
assert.strictEqual( assert.strictEqual(
@ -63,7 +56,5 @@ discourseModule(
"1,2", "1,2",
"it allows to select a setting from the list of choices" "it allows to select a setting from the list of choices"
); );
},
}); });
} });
);

View File

@ -1,26 +1,17 @@
import { import { module, test } from "qunit";
count, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
discourseModule, import { render } from "@ember/test-helpers";
exists, import { count, exists } from "discourse/tests/helpers/qunit-helpers";
} from "discourse/tests/helpers/qunit-helpers";
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule( module("Integration | Component | group-membership-button", function (hooks) {
"Integration | Component | group-membership-button",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("canJoinGroup", { test("canJoinGroup", async function (assert) {
template: hbs`{{group-membership-button model=model}}`,
beforeEach() {
this.set("model", { public_admission: false, is_group_user: true }); this.set("model", { public_admission: false, is_group_user: true });
},
async test(assert) { await render(hbs`<GroupMembershipButton @model={{this.model}} />`);
assert.ok( assert.ok(
!exists(".group-index-join"), !exists(".group-index-join"),
"can't join group if public_admission is false" "can't join group if public_admission is false"
@ -34,15 +25,13 @@ discourseModule(
this.set("model.is_group_user", false); this.set("model.is_group_user", false);
assert.ok(exists(".group-index-join"), "allowed to join group"); assert.ok(exists(".group-index-join"), "allowed to join group");
},
}); });
componentTest("canLeaveGroup", { test("canLeaveGroup", async function (assert) {
template: hbs`{{group-membership-button model=model}}`,
beforeEach() {
this.set("model", { public_exit: false, is_group_user: false }); this.set("model", { public_exit: false, is_group_user: false });
},
async test(assert) { await render(hbs`<GroupMembershipButton @model={{this.model}} />`);
assert.ok( assert.ok(
!exists(".group-index-leave"), !exists(".group-index-leave"),
"can't leave group if public_exit is false" "can't leave group if public_exit is false"
@ -60,19 +49,16 @@ discourseModule(
1, 1,
"allowed to leave group" "allowed to leave group"
); );
},
}); });
componentTest("canRequestMembership", { test("canRequestMembership", async function (assert) {
template: hbs`{{group-membership-button model=model}}`,
beforeEach() {
this.set("model", { this.set("model", {
allow_membership_requests: true, allow_membership_requests: true,
is_group_user: true, is_group_user: true,
}); });
},
async test(assert) { await render(hbs`<GroupMembershipButton @model={{this.model}} />`);
assert.ok( assert.ok(
!exists(".group-index-request"), !exists(".group-index-request"),
"can't request for membership if user is already in the group" "can't request for membership if user is already in the group"
@ -82,7 +68,5 @@ discourseModule(
exists(".group-index-request"), exists(".group-index-request"),
"allowed to request for group membership" "allowed to request for group membership"
); );
},
}); });
} });
);

View File

@ -1,36 +1,29 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render } from "@ember/test-helpers";
import { import { exists, query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import I18n from "I18n"; import I18n from "I18n";
import { click } from "@ember/test-helpers";
discourseModule("Integration | Component | hidden-details", function (hooks) { module("Integration | Component | hidden-details", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("Shows a link and turns link into details on click", { test("Shows a link and turns link into details on click", async function (assert) {
template: hbs`{{hidden-details label=label details=details}}`,
beforeEach() {
this.set("label", "label"); this.set("label", "label");
this.set("details", "details"); this.set("details", "details");
},
async test(assert) { await render(
hbs`<HiddenDetails @label={{this.label}} @details={{this.details}} />`
);
assert.ok(exists(".btn-link")); assert.ok(exists(".btn-link"));
assert.ok(query(".btn-link span").innerText === I18n.t("label")); assert.strictEqual(query(".btn-link span").innerText, I18n.t("label"));
assert.notOk(exists(".description")); assert.notOk(exists(".description"));
await click(".btn-link"); await click(".btn-link");
assert.notOk(exists(".btn-link")); assert.notOk(exists(".btn-link"));
assert.ok(exists(".description")); assert.ok(exists(".description"));
assert.ok(query(".description").innerText === "details"); assert.strictEqual(query(".description").innerText, "details");
},
}); });
}); });

View File

@ -1,48 +1,34 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { import { query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
const LONG_CODE_BLOCK = "puts a\n".repeat(15000); const LONG_CODE_BLOCK = "puts a\n".repeat(15000);
discourseModule("Integration | Component | highlighted-code", function (hooks) { module("Integration | Component | highlighted-code", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("highlighting code", { test("highlighting code", async function (assert) {
template: hbs`{{highlighted-code lang='ruby' code=code}}`,
beforeEach() {
this.session.highlightJsPath = this.session.highlightJsPath =
"/assets/highlightjs/highlight-test-bundle.min.js"; "/assets/highlightjs/highlight-test-bundle.min.js";
this.set("code", "def test; end"); this.set("code", "def test; end");
},
test(assert) { await render(hbs`<HighlightedCode @lang="ruby" @code={{this.code}} />`);
assert.strictEqual( assert.strictEqual(
queryAll("code.ruby.hljs .hljs-function .hljs-keyword").text().trim(), query("code.ruby.hljs .hljs-function .hljs-keyword").innerText.trim(),
"def" "def"
); );
},
}); });
componentTest("large code blocks are not highlighted", { test("large code blocks are not highlighted", async function (assert) {
template: hbs`{{highlighted-code lang='ruby' code=code}}`,
beforeEach() {
this.session.highlightJsPath = this.session.highlightJsPath =
"/assets/highlightjs/highlight-test-bundle.min.js"; "/assets/highlightjs/highlight-test-bundle.min.js";
this.set("code", LONG_CODE_BLOCK); this.set("code", LONG_CODE_BLOCK);
},
test(assert) { await render(hbs`<HighlightedCode @lang="ruby" @code={{this.code}} />`);
assert.strictEqual(
queryAll("code").text().trim(), assert.strictEqual(query("code").innerText.trim(), LONG_CODE_BLOCK.trim());
LONG_CODE_BLOCK.trim()
);
},
}); });
}); });

View File

@ -1,21 +1,17 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule, exists } from "discourse/tests/helpers/qunit-helpers"; import { exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | html-safe-helper", function (hooks) { module("Integration | Component | html-safe-helper", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("default", { test("default", async function (assert) {
template: hbs`{{html-safe string}}`,
beforeEach() {
this.set("string", "<p class='cookies'>biscuits</p>"); this.set("string", "<p class='cookies'>biscuits</p>");
},
async test(assert) { await render(hbs`{{html-safe string}}`);
assert.ok(exists("p.cookies"), "it displays the string as html"); assert.ok(exists("p.cookies"), "it displays the string as html");
},
}); });
}); });

View File

@ -1,19 +1,17 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { import { queryAll } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | iframed-html", function (hooks) { module("Integration | Component | iframed-html", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("appends the html into the iframe", { test("appends the html into the iframe", async function (assert) {
template: hbs`{{iframed-html html="<h1 id='find-me'>hello</h1>" className='this-is-an-iframe'}}`, await render(
hbs`<IframedHtml @html="<h1 id='find-me'>hello</h1>" @className="this-is-an-iframe" />`
);
async test(assert) {
const iframe = queryAll("iframe.this-is-an-iframe"); const iframe = queryAll("iframe.this-is-an-iframe");
assert.strictEqual(iframe.length, 1, "inserts an iframe"); assert.strictEqual(iframe.length, 1, "inserts an iframe");
@ -23,11 +21,9 @@ discourseModule("Integration | Component | iframed-html", function (hooks) {
); );
assert.strictEqual( assert.strictEqual(
iframe[0].contentWindow.document.body.querySelectorAll("#find-me") iframe[0].contentWindow.document.body.querySelectorAll("#find-me").length,
.length,
1, 1,
"inserts the passed in html into the iframe" "inserts the passed in html into the iframe"
); );
},
}); });
}); });

View File

@ -1,19 +1,22 @@
import componentTest, { import { module } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { chromeTest, query } from "discourse/tests/helpers/qunit-helpers";
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule( module(
"Integration | Component | consistent input/dropdown/button sizes", "Integration | Component | consistent input/dropdown/button sizes",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("icon only button, icon and text button, text only button", { // these tests fail on Firefox 78 in CI, skipping for now
template: hbs`{{d-button icon="plus"}} {{d-button icon="plus" label="topic.create"}} {{d-button label="topic.create"}}`, chromeTest(
"icon only button, icon and text button, text only button",
async function (assert) {
await render(
hbs`<DButton @icon="plus" /> <DButton @icon="plus" @label="topic.create" /> <DButton @label="topic.create" />`
);
test(assert) {
assert.strictEqual( assert.strictEqual(
query(".btn:nth-child(1)").offsetHeight, query(".btn:nth-child(1)").offsetHeight,
query(".btn:nth-child(2)").offsetHeight, query(".btn:nth-child(2)").offsetHeight,
@ -24,37 +27,31 @@ discourseModule(
query(".btn:nth-child(3)").offsetHeight, query(".btn:nth-child(3)").offsetHeight,
"have equal height" "have equal height"
); );
}, }
// these tests fail on Firefox 78 in CI, skipping for now );
skip: !navigator.userAgent.includes("Chrome"),
});
componentTest("button + text input", { chromeTest("button + text input", async function (assert) {
template: hbs`{{text-field}} {{d-button icon="plus" label="topic.create"}}`, await render(
hbs`<TextField /> <DButton @icon="plus" @label="topic.create" />`
);
test(assert) {
assert.strictEqual( assert.strictEqual(
query("input").offsetHeight, query("input").offsetHeight,
query(".btn").offsetHeight, query(".btn").offsetHeight,
"have equal height" "have equal height"
); );
},
skip: !navigator.userAgent.includes("Chrome"),
}); });
componentTest("combo box + input", { chromeTest("combo box + input", async function (assert) {
template: hbs`{{combo-box options=(hash none="category.none")}} {{text-field}}`, await render(
hbs`<ComboBox @options={{hash none="category.none"}} /> <TextField />`
);
test(assert) {
assert.strictEqual( assert.strictEqual(
query("input").offsetHeight, query("input").offsetHeight,
query(".combo-box").offsetHeight, query(".combo-box").offsetHeight,
"have equal height" "have equal height"
); );
},
skip: !navigator.userAgent.includes("Chrome"),
}); });
} }
); );

View File

@ -1,25 +1,16 @@
import { set } from "@ember/object"; import { module, test } from "qunit";
import { click } from "@ember/test-helpers"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import User from "discourse/models/user"; import { click, render } from "@ember/test-helpers";
import componentTest, { import { exists, query } from "discourse/tests/helpers/qunit-helpers";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import pretender from "discourse/tests/helpers/create-pretender";
import {
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import pretender from "discourse/tests/helpers/create-pretender";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import User from "discourse/models/user";
discourseModule("Integration | Component | invite-panel", function (hooks) { module("Integration | Component | invite-panel", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("shows the invite link after it is generated", { test("shows the invite link after it is generated", async function (assert) {
template: hbs`{{invite-panel panel=panel}}`,
beforeEach() {
pretender.get("/u/search/users", () => { pretender.get("/u/search/users", () => {
return [200, { "Content-Type": "application/json" }, { users: [] }]; return [200, { "Content-Type": "application/json" }, { users: [] }];
}); });
@ -34,24 +25,24 @@ discourseModule("Integration | Component | invite-panel", function (hooks) {
]; ];
}); });
set(this.currentUser, "details", { can_invite_via_email: true }); this.currentUser.set("details", { can_invite_via_email: true });
this.set("panel", { this.set("panel", {
id: "invite", id: "invite",
model: { inviteModel: User.create(this.currentUser) }, model: { inviteModel: User.create(this.currentUser) },
}); });
},
async test(assert) { await render(hbs`<InvitePanel @panel={{this.panel}} />`);
const input = selectKit(".invite-user-input"); const input = selectKit(".invite-user-input");
await input.expand(); await input.expand();
await input.fillInFilter("eviltrout@example.com"); await input.fillInFilter("eviltrout@example.com");
await input.selectRowByValue("eviltrout@example.com"); await input.selectRowByValue("eviltrout@example.com");
assert.ok(!exists(".send-invite:disabled")); assert.ok(!exists(".send-invite:disabled"));
await click(".generate-invite-link"); await click(".generate-invite-link");
assert.strictEqual( assert.strictEqual(
query(".invite-link-input").value, query(".invite-link-input").value,
"http://example.com/invites/92c297e886a0ca03089a109ccd6be155" "http://example.com/invites/92c297e886a0ca03089a109ccd6be155"
); );
},
}); });
}); });

View File

@ -1,34 +1,32 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { configureEyeline } from "discourse/lib/eyeline"; import { configureEyeline } from "discourse/lib/eyeline";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | load-more", function (hooks) { module("Integration | Component | load-more", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("updates once after initialization", { hooks.beforeEach(function () {
template: hbs`
{{#load-more selector=".numbers tr" action=loadMore}}
<table class="numbers"><tr></tr></table>
{{/load-more}}
`,
beforeEach() {
this.set("loadMore", () => this.set("loadedMore", true));
configureEyeline({ configureEyeline({
skipUpdate: false, skipUpdate: false,
rootElement: "#ember-testing", rootElement: "#ember-testing",
}); });
}, });
afterEach() { hooks.afterEach(function () {
configureEyeline(); configureEyeline();
}, });
test("updates once after initialization", async function (assert) {
this.set("loadMore", () => this.set("loadedMore", true));
await render(hbs`
<LoadMore @selector=".numbers tr" @action={{this.loadMore}}>
<table class="numbers"><tr></tr></table>
</LoadMore>
`);
test(assert) {
assert.ok(this.loadedMore); assert.ok(this.loadedMore);
},
}); });
}); });

View File

@ -1,17 +1,14 @@
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers"; import { module, test } from "qunit";
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest, import { render } from "@ember/test-helpers";
} from "discourse/tests/helpers/component-test"; import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import createStore from "discourse/tests/helpers/create-store"; import createStore from "discourse/tests/helpers/create-store";
discourseModule("Integration | Component | pending-post", function (hooks) { module("Integration | Component | pending-post", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("it renders", { test("it renders", async function (assert) {
template: hbs`<PendingPost @post={{this.post}}/>`,
beforeEach() {
const store = createStore(); const store = createStore();
store.createRecord("category", { id: 2 }); store.createRecord("category", { id: 2 });
const post = store.createRecord("pending-post", { const post = store.createRecord("pending-post", {
@ -22,14 +19,13 @@ discourseModule("Integration | Component | pending-post", function (hooks) {
raw_text: "**bold text**", raw_text: "**bold text**",
}); });
this.set("post", post); this.set("post", post);
},
test(assert) { await render(hbs`<PendingPost @post={{this.post}}/>`);
assert.strictEqual( assert.strictEqual(
query("p.excerpt").textContent.trim(), query("p.excerpt").textContent.trim(),
"bold text", "bold text",
"renders the cooked text" "renders the cooked text"
); );
},
}); });
}); });

View File

@ -1,120 +1,94 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers"; import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
discourseModule( module("Integration | Component | relative-time-picker", function (hooks) {
"Integration | Component | relative-time-picker",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("prefills and preselects minutes", { test("prefills and preselects minutes", async function (assert) {
template: hbs`{{relative-time-picker durationMinutes="5"}}`, await render(hbs`<RelativeTimePicker @durationMinutes="5" />`);
test(assert) {
const prefilledDuration = query(".relative-time-duration").value; const prefilledDuration = query(".relative-time-duration").value;
assert.strictEqual(this.subject.header().value(), "mins"); assert.strictEqual(this.subject.header().value(), "mins");
assert.strictEqual(prefilledDuration, "5"); assert.strictEqual(prefilledDuration, "5");
},
}); });
componentTest("prefills and preselects hours based on translated minutes", { test("prefills and preselects hours based on translated minutes", async function (assert) {
template: hbs`{{relative-time-picker durationMinutes="90"}}`, await render(hbs`<RelativeTimePicker @durationMinutes="90" />`);
test(assert) {
const prefilledDuration = query(".relative-time-duration").value; const prefilledDuration = query(".relative-time-duration").value;
assert.strictEqual(this.subject.header().value(), "hours"); assert.strictEqual(this.subject.header().value(), "hours");
assert.strictEqual(prefilledDuration, "1.5"); assert.strictEqual(prefilledDuration, "1.5");
},
}); });
componentTest("prefills and preselects days based on translated minutes", { test("prefills and preselects days based on translated minutes", async function (assert) {
template: hbs`{{relative-time-picker durationMinutes="2880"}}`, await render(hbs`<RelativeTimePicker @durationMinutes="2880" />`);
test(assert) {
const prefilledDuration = query(".relative-time-duration").value; const prefilledDuration = query(".relative-time-duration").value;
assert.strictEqual(this.subject.header().value(), "days"); assert.strictEqual(this.subject.header().value(), "days");
assert.strictEqual(prefilledDuration, "2"); assert.strictEqual(prefilledDuration, "2");
},
}); });
componentTest( test("prefills and preselects months based on translated minutes", async function (assert) {
"prefills and preselects months based on translated minutes", await render(hbs`<RelativeTimePicker @durationMinutes="129600" />`);
{
template: hbs`{{relative-time-picker durationMinutes="129600"}}`,
test(assert) {
const prefilledDuration = query(".relative-time-duration").value; const prefilledDuration = query(".relative-time-duration").value;
assert.strictEqual(this.subject.header().value(), "months"); assert.strictEqual(this.subject.header().value(), "months");
assert.strictEqual(prefilledDuration, "3"); assert.strictEqual(prefilledDuration, "3");
}, });
}
);
componentTest("prefills and preselects years based on translated minutes", { test("prefills and preselects years based on translated minutes", async function (assert) {
template: hbs`{{relative-time-picker durationMinutes="525600"}}`, await render(hbs`<RelativeTimePicker @durationMinutes="525600" />`);
test(assert) {
const prefilledDuration = query(".relative-time-duration").value; const prefilledDuration = query(".relative-time-duration").value;
assert.strictEqual(this.subject.header().value(), "years"); assert.strictEqual(this.subject.header().value(), "years");
assert.strictEqual(prefilledDuration, "1"); assert.strictEqual(prefilledDuration, "1");
},
}); });
componentTest("prefills and preselects hours", { test("prefills and preselects hours", async function (assert) {
template: hbs`{{relative-time-picker durationHours="5"}}`, await render(hbs`<RelativeTimePicker @durationHours="5" />`);
test(assert) {
const prefilledDuration = query(".relative-time-duration").value; const prefilledDuration = query(".relative-time-duration").value;
assert.strictEqual(this.subject.header().value(), "hours"); assert.strictEqual(this.subject.header().value(), "hours");
assert.strictEqual(prefilledDuration, "5"); assert.strictEqual(prefilledDuration, "5");
},
}); });
componentTest("prefills and preselects minutes based on translated hours", { test("prefills and preselects minutes based on translated hours", async function (assert) {
template: hbs`{{relative-time-picker durationHours="0.5"}}`, await render(hbs`<RelativeTimePicker @durationHours="0.5" />`);
test(assert) {
const prefilledDuration = query(".relative-time-duration").value; const prefilledDuration = query(".relative-time-duration").value;
assert.strictEqual(this.subject.header().value(), "mins"); assert.strictEqual(this.subject.header().value(), "mins");
assert.strictEqual(prefilledDuration, "30"); assert.strictEqual(prefilledDuration, "30");
},
}); });
componentTest("prefills and preselects days based on translated hours", { test("prefills and preselects days based on translated hours", async function (assert) {
template: hbs`{{relative-time-picker durationHours="48"}}`, await render(hbs`<RelativeTimePicker @durationHours="48" />`);
test(assert) {
const prefilledDuration = query(".relative-time-duration").value; const prefilledDuration = query(".relative-time-duration").value;
assert.strictEqual(this.subject.header().value(), "days"); assert.strictEqual(this.subject.header().value(), "days");
assert.strictEqual(prefilledDuration, "2"); assert.strictEqual(prefilledDuration, "2");
},
}); });
componentTest("prefills and preselects months based on translated hours", { test("prefills and preselects months based on translated hours", async function (assert) {
template: hbs`{{relative-time-picker durationHours="2160"}}`, await render(hbs`<RelativeTimePicker @durationHours="2160" />`);
test(assert) {
const prefilledDuration = query(".relative-time-duration").value; const prefilledDuration = query(".relative-time-duration").value;
assert.strictEqual(this.subject.header().value(), "months"); assert.strictEqual(this.subject.header().value(), "months");
assert.strictEqual(prefilledDuration, "3"); assert.strictEqual(prefilledDuration, "3");
},
}); });
componentTest("prefills and preselects years based on translated hours", { test("prefills and preselects years based on translated hours", async function (assert) {
template: hbs`{{relative-time-picker durationHours="17520"}}`, await render(hbs`<RelativeTimePicker @durationHours="17520" />`);
test(assert) {
const prefilledDuration = query(".relative-time-duration").value; const prefilledDuration = query(".relative-time-duration").value;
assert.strictEqual(this.subject.header().value(), "years"); assert.strictEqual(this.subject.header().value(), "years");
assert.strictEqual(prefilledDuration, "2"); assert.strictEqual(prefilledDuration, "2");
},
}); });
} });
);

View File

@ -1,26 +1,16 @@
import { blur, click, fillIn } from "@ember/test-helpers"; import { module, test } from "qunit";
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest, import { blur, click, fillIn, render } from "@ember/test-helpers";
} from "discourse/tests/helpers/component-test"; import { count, exists, query } from "discourse/tests/helpers/qunit-helpers";
import {
count,
discourseModule,
exists,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import I18n from "I18n"; import I18n from "I18n";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule( module("Integration | Component | secret-value-list", function (hooks) {
"Integration | Component | secret-value-list",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("adding a value", { test("adding a value", async function (assert) {
template: hbs`{{secret-value-list values=values}}`, await render(hbs`<SecretValueList @values={{this.values}} />`);
async test(assert) {
this.set("values", "firstKey|FirstValue\nsecondKey|secondValue"); this.set("values", "firstKey|FirstValue\nsecondKey|secondValue");
await fillIn(".new-value-input.key", "thirdKey"); await fillIn(".new-value-input.key", "thirdKey");
@ -57,13 +47,11 @@ discourseModule(
"firstKey|FirstValue\nsecondKey|secondValue\nthirdKey|thirdValue", "firstKey|FirstValue\nsecondKey|secondValue\nthirdKey|thirdValue",
"it adds the value to the list of values" "it adds the value to the list of values"
); );
},
}); });
componentTest("adding an invalid value", { test("adding an invalid value", async function (assert) {
template: hbs`{{secret-value-list values=values}}`, await render(hbs`<SecretValueList @values={{this.values}} />`);
async test(assert) {
await fillIn(".new-value-input.key", "someString"); await fillIn(".new-value-input.key", "someString");
await fillIn(".new-value-input.secret", "keyWithAPipe|Hidden"); await fillIn(".new-value-input.secret", "keyWithAPipe|Hidden");
await click(".add-value-btn"); await click(".add-value-btn");
@ -80,19 +68,16 @@ discourseModule(
); );
assert.ok( assert.ok(
queryAll(".validation-error") query(".validation-error").innerText.includes(
.html() I18n.t("admin.site_settings.secret_list.invalid_input")
.indexOf(I18n.t("admin.site_settings.secret_list.invalid_input")) > ),
-1,
"it shows validation error" "it shows validation error"
); );
},
}); });
componentTest("changing a value", { test("changing a value", async function (assert) {
template: hbs`{{secret-value-list values=values}}`, await render(hbs`<SecretValueList @values={{this.values}} />`);
async test(assert) {
this.set("values", "firstKey|FirstValue\nsecondKey|secondValue"); this.set("values", "firstKey|FirstValue\nsecondKey|secondValue");
await fillIn( await fillIn(
@ -102,8 +87,7 @@ discourseModule(
await blur(".values .value[data-index='1'] .value-input:first-of-type"); await blur(".values .value[data-index='1'] .value-input:first-of-type");
assert.strictEqual( assert.strictEqual(
query(".values .value[data-index='1'] .value-input:first-of-type") query(".values .value[data-index='1'] .value-input:first-of-type").value,
.value,
"changedKey" "changedKey"
); );
@ -114,8 +98,7 @@ discourseModule(
await blur(".values .value[data-index='1'] .value-input:last-of-type"); await blur(".values .value[data-index='1'] .value-input:last-of-type");
assert.strictEqual( assert.strictEqual(
query(".values .value[data-index='1'] .value-input:last-of-type") query(".values .value[data-index='1'] .value-input:last-of-type").value,
.value,
"changedValue" "changedValue"
); );
assert.deepEqual( assert.deepEqual(
@ -123,13 +106,11 @@ discourseModule(
"firstKey|FirstValue\nchangedKey|changedValue", "firstKey|FirstValue\nchangedKey|changedValue",
"updates the value list" "updates the value list"
); );
},
}); });
componentTest("removing a value", { test("removing a value", async function (assert) {
template: hbs`{{secret-value-list values=values}}`, await render(hbs`<SecretValueList @values={{this.values}} />`);
async test(assert) {
this.set("values", "firstKey|FirstValue\nsecondKey|secondValue"); this.set("values", "firstKey|FirstValue\nsecondKey|secondValue");
await click(".values .value[data-index='0'] .remove-value-btn"); await click(".values .value[data-index='0'] .remove-value-btn");
@ -145,7 +126,5 @@ discourseModule(
"secondKey|secondValue", "secondKey|secondValue",
"it removes the expected value" "it removes the expected value"
); );
},
}); });
} });
);

View File

@ -1,10 +1,7 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { import { query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import selectKit, { import selectKit, {
DEFAULT_CONTENT, DEFAULT_CONTENT,
setDefaultState, setDefaultState,
@ -13,12 +10,11 @@ import { clearCallbacks } from "select-kit/mixins/plugin-api";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { withPluginApi } from "discourse/lib/plugin-api"; import { withPluginApi } from "discourse/lib/plugin-api";
discourseModule("Integration | Component | select-kit:api", function (hooks) { module("Integration | Component | select-kit/api", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.setProperties({ this.setProperties({
// subject: selectKit();
comboBox: selectKit(".combo-box"), comboBox: selectKit(".combo-box"),
singleSelect: selectKit(".single-select:not(.combo-box)"), singleSelect: selectKit(".single-select:not(.combo-box)"),
}); });
@ -28,13 +24,7 @@ discourseModule("Integration | Component | select-kit:api", function (hooks) {
clearCallbacks(); clearCallbacks();
}); });
componentTest("modifySelectKit(identifier).appendContent", { test("modifySelectKit(identifier).appendContent", async function (assert) {
template: hbs`
{{combo-box value=value content=content onChange=onChange}}
{{single-select value=value content=content onChange=onChange}}
`,
beforeEach() {
setDefaultState(this, null, { content: DEFAULT_CONTENT }); setDefaultState(this, null, { content: DEFAULT_CONTENT });
withPluginApi("0.8.43", (api) => { withPluginApi("0.8.43", (api) => {
@ -46,9 +36,11 @@ discourseModule("Integration | Component | select-kit:api", function (hooks) {
}); });
api.modifySelectKit("combo-box").appendContent(() => {}); api.modifySelectKit("combo-box").appendContent(() => {});
}); });
},
async test(assert) { await render(hbs`
<ComboBox @value={{this.value}} @content={{this.content}} @onChange={{this.onChange}} />
<SingleSelect @value={{this.value}} @content={{this.content}} @onChange={{this.onChange}} />
`);
await this.comboBox.expand(); await this.comboBox.expand();
assert.strictEqual(this.comboBox.rows().length, 4); assert.strictEqual(this.comboBox.rows().length, 4);
@ -60,16 +52,9 @@ discourseModule("Integration | Component | select-kit:api", function (hooks) {
await this.comboBox.collapse(); await this.comboBox.collapse();
assert.notOk(this.singleSelect.rowByValue("alpaca").exists()); assert.notOk(this.singleSelect.rowByValue("alpaca").exists());
},
}); });
componentTest("modifySelectKit(identifier).prependContent", { test("modifySelectKit(identifier).prependContent", async function (assert) {
template: hbs`
{{combo-box value=value content=content onChange=onChange}}
{{single-select value=value content=content onChange=onChange}}
`,
beforeEach() {
setDefaultState(this, null, { content: DEFAULT_CONTENT }); setDefaultState(this, null, { content: DEFAULT_CONTENT });
withPluginApi("0.8.43", (api) => { withPluginApi("0.8.43", (api) => {
@ -81,9 +66,11 @@ discourseModule("Integration | Component | select-kit:api", function (hooks) {
}); });
api.modifySelectKit("combo-box").prependContent(() => {}); api.modifySelectKit("combo-box").prependContent(() => {});
}); });
},
async test(assert) { await render(hbs`
<ComboBox @value={{this.value}} @content={{this.content}} @onChange={{this.onChange}} />
<SingleSelect @value={{this.value}} @content={{this.content}} @onChange={{this.onChange}} />
`);
await this.comboBox.expand(); await this.comboBox.expand();
assert.strictEqual(this.comboBox.rows().length, 4); assert.strictEqual(this.comboBox.rows().length, 4);
@ -95,30 +82,24 @@ discourseModule("Integration | Component | select-kit:api", function (hooks) {
await this.comboBox.collapse(); await this.comboBox.collapse();
assert.notOk(this.singleSelect.rowByValue("alpaca").exists()); assert.notOk(this.singleSelect.rowByValue("alpaca").exists());
},
}); });
componentTest("modifySelectKit(identifier).onChange", { test("modifySelectKit(identifier).onChange", async function (assert) {
template: hbs`
<div id="test"></div>
{{combo-box value=value content=content onChange=onChange}}
`,
beforeEach() {
setDefaultState(this, null, { content: DEFAULT_CONTENT }); setDefaultState(this, null, { content: DEFAULT_CONTENT });
withPluginApi("0.8.43", (api) => { withPluginApi("0.8.43", (api) => {
api.modifySelectKit("combo-box").onChange((component, value, item) => { api.modifySelectKit("combo-box").onChange((component, value, item) => {
queryAll("#test").text(item.name); query("#test").innerText = item.name;
}); });
}); });
},
async test(assert) { await render(hbs`
<div id="test"></div>
<ComboBox @value={{this.value}} @content={{this.content}} @onChange={{this.onChange}} />
`);
await this.comboBox.expand(); await this.comboBox.expand();
await this.comboBox.selectRowByIndex(0); await this.comboBox.selectRowByIndex(0);
assert.strictEqual(queryAll("#test").text(), "foo"); assert.strictEqual(query("#test").innerText, "foo");
},
}); });
}); });

View File

@ -1,13 +1,12 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import I18n from "I18n"; import I18n from "I18n";
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 hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
discourseModule( module(
"Integration | Component | select-kit/category-chooser", "Integration | Component | select-kit/category-chooser",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
@ -16,51 +15,44 @@ discourseModule(
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("with value", { test("with value", async function (assert) {
template: hbs`
{{category-chooser
value=value
}}
`,
beforeEach() {
this.set("value", 2); this.set("value", 2);
},
async test(assert) { await render(hbs`
<CategoryChooser
@value={{this.value}}
/>
`);
assert.strictEqual(this.subject.header().value(), "2"); assert.strictEqual(this.subject.header().value(), "2");
assert.strictEqual(this.subject.header().label(), "feature"); assert.strictEqual(this.subject.header().label(), "feature");
},
}); });
componentTest("with excludeCategoryId", { test("with excludeCategoryId", async function (assert) {
template: hbs` await render(hbs`
{{category-chooser <CategoryChooser
value=value @value={{this.value}}
options=(hash @options={{hash
excludeCategoryId=2 excludeCategoryId=2
)
}} }}
`, />
`);
async test(assert) {
await this.subject.expand(); await this.subject.expand();
assert.notOk(this.subject.rowByValue(2).exists()); assert.notOk(this.subject.rowByValue(2).exists());
},
}); });
componentTest("with scopedCategoryId", { test("with scopedCategoryId", async function (assert) {
template: hbs` await render(hbs`
{{category-chooser <CategoryChooser
value=value @value={{this.value}}
options=(hash @options={{hash
scopedCategoryId=2 scopedCategoryId=2
)
}} }}
`, />
`);
async test(assert) {
await this.subject.expand(); await this.subject.expand();
assert.strictEqual(this.subject.rowByIndex(0).title(), "feature"); assert.strictEqual(this.subject.rowByIndex(0).title(), "feature");
@ -80,20 +72,18 @@ discourseModule(
"bug", "bug",
"search finds outside of scope" "search finds outside of scope"
); );
},
}); });
componentTest("with prioritizedCategoryId", { test("with prioritizedCategoryId", async function (assert) {
template: hbs` await render(hbs`
{{category-chooser <CategoryChooser
value=value @value={{this.value}}
options=(hash @options={{hash
prioritizedCategoryId=5 prioritizedCategoryId=5
)
}} }}
`, />
`);
async test(assert) {
await this.subject.expand(); await this.subject.expand();
// The prioritized category // The prioritized category
@ -118,143 +108,117 @@ discourseModule(
"bug", "bug",
"search still finds categories" "search still finds categories"
); );
},
}); });
componentTest("with allowUncategorized=null", { test("with allowUncategorized=null", async function (assert) {
template: hbs`
{{category-chooser
value=value
options=(hash
allowUncategorized=null
)
}}
`,
beforeEach() {
this.siteSettings.allow_uncategorized_topics = false; this.siteSettings.allow_uncategorized_topics = false;
},
test(assert) { await render(hbs`
<CategoryChooser
@value={{this.value}}
@options={{hash
allowUncategorized=null
}}
/>
`);
assert.strictEqual(this.subject.header().value(), null); assert.strictEqual(this.subject.header().value(), null);
assert.strictEqual(this.subject.header().label(), "category…"); assert.strictEqual(this.subject.header().label(), "category…");
},
}); });
componentTest("with allowUncategorized=null none=true", { test("with allowUncategorized=null none=true", async function (assert) {
template: hbs` this.siteSettings.allow_uncategorized_topics = false;
{{category-chooser
value=value await render(hbs`
options=(hash <CategoryChooser
@value={{this.value}}
@options={{hash
allowUncategorized=null allowUncategorized=null
none=true none=true
)
}} }}
`, />
`);
beforeEach() {
this.siteSettings.allow_uncategorized_topics = false;
},
test(assert) {
assert.strictEqual(this.subject.header().value(), null); assert.strictEqual(this.subject.header().value(), null);
assert.strictEqual(this.subject.header().label(), "(no category)"); assert.strictEqual(this.subject.header().label(), "(no category)");
},
}); });
componentTest("with disallowed uncategorized, none", { test("with disallowed uncategorized, none", async function (assert) {
template: hbs`
{{category-chooser
value=value
options=(hash
allowUncategorized=null
none="test.root"
)
}}
`,
beforeEach() {
I18n.translations[I18n.locale].js.test = { root: "root none label" }; I18n.translations[I18n.locale].js.test = { root: "root none label" };
this.siteSettings.allow_uncategorized_topics = false; this.siteSettings.allow_uncategorized_topics = false;
},
test(assert) { await render(hbs`
<CategoryChooser
@value={{this.value}}
@options={{hash
allowUncategorized=null
none="test.root"
}}
/>
`);
assert.strictEqual(this.subject.header().value(), null); assert.strictEqual(this.subject.header().value(), null);
assert.strictEqual(this.subject.header().label(), "root none label"); assert.strictEqual(this.subject.header().label(), "root none label");
},
}); });
componentTest("with allowed uncategorized", { test("with allowed uncategorized", async function (assert) {
template: hbs`
{{category-chooser
value=value
options=(hash
allowUncategorized=true
)
}}
`,
beforeEach() {
this.siteSettings.allow_uncategorized_topics = true; this.siteSettings.allow_uncategorized_topics = true;
},
test(assert) { await render(hbs`
<CategoryChooser
@value={{this.value}}
@options={{hash
allowUncategorized=true
}}
/>
`);
assert.strictEqual(this.subject.header().value(), null); assert.strictEqual(this.subject.header().value(), null);
assert.strictEqual(this.subject.header().label(), "uncategorized"); assert.strictEqual(this.subject.header().label(), "uncategorized");
},
}); });
componentTest("with allowed uncategorized and none=true", { test("with allowed uncategorized and none=true", async function (assert) {
template: hbs` this.siteSettings.allow_uncategorized_topics = true;
{{category-chooser
value=value await render(hbs`
options=(hash <CategoryChooser
@value={{this.value}}
@options={{hash
allowUncategorized=true allowUncategorized=true
none=true none=true
)
}} }}
`, />
`);
beforeEach() {
this.siteSettings.allow_uncategorized_topics = true;
},
test(assert) {
assert.strictEqual(this.subject.header().value(), null); assert.strictEqual(this.subject.header().value(), null);
assert.strictEqual(this.subject.header().label(), "(no category)"); assert.strictEqual(this.subject.header().label(), "(no category)");
},
}); });
componentTest("with allowed uncategorized and none", { test("with allowed uncategorized and none", async function (assert) {
template: hbs`
{{category-chooser
value=value
options=(hash
allowUncategorized=true
none="test.root"
)
}}
`,
beforeEach() {
I18n.translations[I18n.locale].js.test = { root: "root none label" }; I18n.translations[I18n.locale].js.test = { root: "root none label" };
this.siteSettings.allow_uncategorized_topics = true; this.siteSettings.allow_uncategorized_topics = true;
},
test(assert) { await render(hbs`
<CategoryChooser
@value={{this.value}}
@options={{hash
allowUncategorized=true
none="test.root"
}}
/>
`);
assert.strictEqual(this.subject.header().value(), null); assert.strictEqual(this.subject.header().value(), null);
assert.strictEqual(this.subject.header().label(), "root none label"); assert.strictEqual(this.subject.header().label(), "root none label");
},
}); });
componentTest("filter is case insensitive", { test("filter is case insensitive", async function (assert) {
template: hbs` await render(hbs`
{{category-chooser <CategoryChooser
value=value @value={{this.value}}
}} />
`, `);
async test(assert) {
await this.subject.expand(); await this.subject.expand();
await this.subject.fillInFilter("bug"); await this.subject.fillInFilter("bug");
@ -266,51 +230,43 @@ discourseModule(
assert.strictEqual(this.subject.rows().length, 1); assert.strictEqual(this.subject.rows().length, 1);
assert.strictEqual(this.subject.rowByIndex(0).name(), "bug"); assert.strictEqual(this.subject.rowByIndex(0).name(), "bug");
},
}); });
componentTest("filter works with non english characters", { test("filter works with non english characters", async function (assert) {
template: hbs`
{{category-chooser
value=value
}}
`,
beforeEach() {
const store = createStore(); const store = createStore();
store.createRecord("category", { store.createRecord("category", {
id: 1, id: 1,
name: "chữ Quốc ngữ", name: "chữ Quốc ngữ",
}); });
},
async test(assert) { await render(hbs`
<CategoryChooser
@value={{this.value}}
/>
`);
await this.subject.expand(); await this.subject.expand();
await this.subject.fillInFilter("gữ"); await this.subject.fillInFilter("gữ");
assert.strictEqual(this.subject.rows().length, 1); assert.strictEqual(this.subject.rows().length, 1);
assert.strictEqual(this.subject.rowByIndex(0).name(), "chữ Quốc ngữ"); assert.strictEqual(this.subject.rowByIndex(0).name(), "chữ Quốc ngữ");
},
}); });
componentTest("decodes entities in row title", { test("decodes entities in row title", async function (assert) {
template: hbs`
{{category-chooser
value=value
options=(hash scopedCategoryId=1)
}}
`,
beforeEach() {
const store = createStore(); const store = createStore();
store.createRecord("category", { store.createRecord("category", {
id: 1, id: 1,
name: "cat-with-entities", name: "cat-with-entities",
description_text: "baz &quot;bar ‘foo’", description_text: "baz &quot;bar ‘foo’",
}); });
},
async test(assert) { await render(hbs`
<CategoryChooser
@value={{this.value}}
@options={{hash scopedCategoryId=1}}
/>
`);
await this.subject.expand(); await this.subject.expand();
assert.strictEqual( assert.strictEqual(
@ -318,7 +274,6 @@ discourseModule(
.innerText, .innerText,
'baz "bar ‘foo’' 'baz "bar ‘foo’'
); );
},
}); });
} }
); );

View File

@ -1,11 +1,10 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { import {
ALL_CATEGORIES_ID, ALL_CATEGORIES_ID,
NO_CATEGORIES_ID, NO_CATEGORIES_ID,
} from "select-kit/components/category-drop"; } from "select-kit/components/category-drop";
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import Category from "discourse/models/category"; import Category from "discourse/models/category";
import DiscourseURL from "discourse/lib/url"; import DiscourseURL from "discourse/lib/url";
import I18n from "I18n"; import I18n from "I18n";
@ -35,68 +34,59 @@ function initCategoriesWithParentCategory(context) {
}); });
} }
discourseModule( module("Integration | Component | select-kit/category-drop", function (hooks) {
"Integration | Component | select-kit/category-drop",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("caretUpIcon", { test("caretUpIcon", async function (assert) {
template: hbs` await render(hbs`
{{category-drop <CategoryDrop
category=value @category={{this.value}}
categories=content @categories={{this.content}}
}} />
`, `);
async test(assert) {
const header = this.subject.header().el(); const header = this.subject.header().el();
assert.ok( assert.ok(
header.querySelector(`.d-icon-caret-right`), header.querySelector(`.d-icon-caret-right`),
"it uses the correct default icon" "it uses the correct default icon"
); );
},
}); });
componentTest("none", { test("none", async function (assert) {
template: hbs` await render(hbs`
{{category-drop <CategoryDrop
category=value @category={{this.value}}
categories=content @categories={{this.content}}
}} />
`, `);
async test(assert) {
const text = this.subject.header().label(); const text = this.subject.header().label();
assert.strictEqual( assert.strictEqual(
text, text,
I18n.t("category.all").toLowerCase(), I18n.t("category.all").toLowerCase(),
"it uses the noneLabel" "it uses the noneLabel"
); );
},
}); });
componentTest("[not staff - TL0] displayCategoryDescription", { test("[not staff - TL0] displayCategoryDescription", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
}}
`,
beforeEach() {
set(this.currentUser, "staff", false); set(this.currentUser, "staff", false);
set(this.currentUser, "trust_level", 0); set(this.currentUser, "trust_level", 0);
initCategories(this); initCategories(this);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const row = this.subject.rowByValue(this.category.id); const row = this.subject.rowByValue(this.category.id);
@ -104,26 +94,22 @@ discourseModule(
row.el().querySelector(".category-desc"), row.el().querySelector(".category-desc"),
"it shows category description for newcomers" "it shows category description for newcomers"
); );
},
}); });
componentTest("[not staff - TL1] displayCategoryDescription", { test("[not staff - TL1] displayCategoryDescription", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
}}
`,
beforeEach() {
set(this.currentUser, "moderator", false); set(this.currentUser, "moderator", false);
set(this.currentUser, "admin", false); set(this.currentUser, "admin", false);
set(this.currentUser, "trust_level", 1); set(this.currentUser, "trust_level", 1);
initCategories(this); initCategories(this);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const row = this.subject.rowByValue(this.category.id); const row = this.subject.rowByValue(this.category.id);
@ -131,26 +117,22 @@ discourseModule(
row.el().querySelector(".category-desc"), row.el().querySelector(".category-desc"),
"it doesn't shows category description for TL0+" "it doesn't shows category description for TL0+"
); );
},
}); });
componentTest("[staff - TL0] displayCategoryDescription", { test("[staff - TL0] displayCategoryDescription", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
}}
`,
beforeEach() {
set(this.currentUser, "moderator", true); set(this.currentUser, "moderator", true);
set(this.currentUser, "trust_level", 0); set(this.currentUser, "trust_level", 0);
initCategories(this); initCategories(this);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const row = this.subject.rowByValue(this.category.id); const row = this.subject.rowByValue(this.category.id);
@ -158,48 +140,40 @@ discourseModule(
row.el().querySelector(".category-desc"), row.el().querySelector(".category-desc"),
"it doesn't show category description for staff" "it doesn't show category description for staff"
); );
},
}); });
componentTest("hideParentCategory (default: false)", { test("hideParentCategory (default: false)", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
}}
`,
beforeEach() {
initCategories(this); initCategories(this);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const row = this.subject.rowByValue(this.category.id); const row = this.subject.rowByValue(this.category.id);
assert.strictEqual(row.value(), this.category.id.toString()); assert.strictEqual(row.value(), this.category.id.toString());
assert.strictEqual(this.category.parent_category_id, undefined); assert.strictEqual(this.category.parent_category_id, undefined);
},
}); });
componentTest("hideParentCategory (true)", { test("hideParentCategory (true)", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
options=(hash
hideParentCategory=true
)
}}
`,
beforeEach() {
initCategoriesWithParentCategory(this); initCategoriesWithParentCategory(this);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
@options={{hash
hideParentCategory=true
}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const parentRow = this.subject.rowByValue(this.parentCategory.id); const parentRow = this.subject.rowByValue(this.parentCategory.id);
@ -212,135 +186,109 @@ discourseModule(
const categoryStatus = childRow.el().querySelector(".category-status"); const categoryStatus = childRow.el().querySelector(".category-status");
assert.ok(categoryStatus.innerText.trim().match(/^spec/)); assert.ok(categoryStatus.innerText.trim().match(/^spec/));
},
}); });
componentTest("allow_uncategorized_topics (true)", { test("allow_uncategorized_topics (true)", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
}}
`,
beforeEach() {
this.siteSettings.allow_uncategorized_topics = true; this.siteSettings.allow_uncategorized_topics = true;
initCategories(this); initCategories(this);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const uncategorizedCategoryId = this.site.uncategorized_category_id; const uncategorizedCategoryId = this.site.uncategorized_category_id;
const row = this.subject.rowByValue(uncategorizedCategoryId); const row = this.subject.rowByValue(uncategorizedCategoryId);
assert.ok(row.exists(), "the uncategorized row is showing"); assert.ok(row.exists(), "the uncategorized row is showing");
},
}); });
componentTest("allow_uncategorized_topics (false)", { test("allow_uncategorized_topics (false)", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
}}
`,
beforeEach() {
this.siteSettings.allow_uncategorized_topics = false; this.siteSettings.allow_uncategorized_topics = false;
initCategories(this); initCategories(this);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const uncategorizedCategoryId = this.site.uncategorized_category_id; const uncategorizedCategoryId = this.site.uncategorized_category_id;
const row = this.subject.rowByValue(uncategorizedCategoryId); const row = this.subject.rowByValue(uncategorizedCategoryId);
assert.notOk(row.exists(), "the uncategorized row is not showing"); assert.notOk(row.exists(), "the uncategorized row is not showing");
},
}); });
componentTest("countSubcategories (default: false)", { test("countSubcategories (default: false)", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
}}
`,
beforeEach() {
initCategories(this); initCategories(this);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const category = Category.findById(7); const category = Category.findById(7);
const row = this.subject.rowByValue(category.id); const row = this.subject.rowByValue(category.id);
const topicCount = row const topicCount = row.el().querySelector(".topic-count").innerText.trim();
.el()
.querySelector(".topic-count")
.innerText.trim();
assert.strictEqual( assert.strictEqual(
topicCount, topicCount,
"× 481", "× 481",
"it doesn't include the topic count of subcategories" "it doesn't include the topic count of subcategories"
); );
},
}); });
componentTest("countSubcategories (true)", { test("countSubcategories (true)", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
options=(hash
countSubcategories=true
)
}}
`,
beforeEach() {
initCategories(this); initCategories(this);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
@options={{hash
countSubcategories=true
}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const category = Category.findById(7); const category = Category.findById(7);
const row = this.subject.rowByValue(category.id); const row = this.subject.rowByValue(category.id);
const topicCount = row const topicCount = row.el().querySelector(".topic-count").innerText.trim();
.el()
.querySelector(".topic-count")
.innerText.trim();
assert.strictEqual( assert.strictEqual(
topicCount, topicCount,
"× 584", "× 584",
"it includes the topic count of subcategories" "it includes the topic count of subcategories"
); );
},
}); });
componentTest("shortcuts:default", { test("shortcuts:default", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
}}
`,
beforeEach() {
initCategories(this); initCategories(this);
this.set("category", null); this.set("category", null);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
/>
`);
await this.subject.expand(); await this.subject.expand();
assert.strictEqual( assert.strictEqual(
@ -348,107 +296,76 @@ discourseModule(
this.categories.firstObject.id.toString(), this.categories.firstObject.id.toString(),
"Shortcuts are not prepended when no category is selected" "Shortcuts are not prepended when no category is selected"
); );
},
}); });
componentTest("shortcuts:category is set", { test("shortcuts:category is set", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
}}
`,
beforeEach() {
initCategories(this); initCategories(this);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
/>
`);
await this.subject.expand(); await this.subject.expand();
assert.strictEqual( assert.strictEqual(this.subject.rowByIndex(0).value(), ALL_CATEGORIES_ID);
this.subject.rowByIndex(0).value(),
ALL_CATEGORIES_ID
);
},
}); });
componentTest("shortcuts with parentCategory/subCategory=true:default", { test("shortcuts with parentCategory/subCategory=true:default", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
options=(hash
subCategory=true
)
}}
`,
beforeEach() {
initCategoriesWithParentCategory(this); initCategoriesWithParentCategory(this);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
@options={{hash
subCategory=true
}}
/>
`);
await this.subject.expand(); await this.subject.expand();
assert.strictEqual( assert.strictEqual(this.subject.rowByIndex(0).value(), NO_CATEGORIES_ID);
this.subject.rowByIndex(0).value(),
NO_CATEGORIES_ID
);
},
}); });
componentTest( test("shortcuts with parentCategory/subCategory=true:category is selected", async function (assert) {
"shortcuts with parentCategory/subCategory=true:category is selected",
{
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
options=(hash
subCategory=true
)
}}
`,
beforeEach() {
initCategoriesWithParentCategory(this); initCategoriesWithParentCategory(this);
this.set("category", this.categories.firstObject); this.set("category", this.categories.firstObject);
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
@options={{hash
subCategory=true
}}
/>
`);
await this.subject.expand(); await this.subject.expand();
assert.strictEqual( assert.strictEqual(this.subject.rowByIndex(0).value(), ALL_CATEGORIES_ID);
this.subject.rowByIndex(0).value(), assert.strictEqual(this.subject.rowByIndex(1).value(), NO_CATEGORIES_ID);
ALL_CATEGORIES_ID });
);
assert.strictEqual(
this.subject.rowByIndex(1).value(),
NO_CATEGORIES_ID
);
},
}
);
componentTest("category url", { test("category url", async function (assert) {
template: hbs`
{{category-drop
category=category
categories=categories
parentCategory=parentCategory
}}
`,
beforeEach() {
initCategoriesWithParentCategory(this); initCategoriesWithParentCategory(this);
sinon.stub(DiscourseURL, "routeTo"); sinon.stub(DiscourseURL, "routeTo");
},
async test(assert) { await render(hbs`
<CategoryDrop
@category={{this.category}}
@categories={{this.categories}}
@parentCategory={{this.parentCategory}}
/>
`);
await this.subject.expand(); await this.subject.expand();
await this.subject.selectRowByValue(26); await this.subject.selectRowByValue(26);
@ -456,7 +373,5 @@ discourseModule(
DiscourseURL.routeTo.calledWith("/c/feature/spec/26"), DiscourseURL.routeTo.calledWith("/c/feature/spec/26"),
"it builds a correct URL" "it builds a correct URL"
); );
},
}); });
} });
);

View File

@ -1,8 +1,6 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render } from "@ember/test-helpers";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import { click } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -14,46 +12,41 @@ const DEFAULT_CONTENT = [
const DEFAULT_VALUE = 1; const DEFAULT_VALUE = 1;
const setDefaultState = (ctx, options) => { const setDefaultState = (ctx, options = {}) => {
const properties = Object.assign( const properties = Object.assign(
{ {
content: DEFAULT_CONTENT, content: DEFAULT_CONTENT,
value: DEFAULT_VALUE, value: DEFAULT_VALUE,
}, },
options || {} options
); );
ctx.setProperties(properties); ctx.setProperties(properties);
}; };
discourseModule( module("Integration | Component | select-kit/combo-box", function (hooks) {
"Integration | Component | select-kit/combo-box",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("options.clearable", { test("options.clearable", async function (assert) {
template: hbs`
{{combo-box
value=value
content=content
onChange=onChange
options=(hash clearable=clearable)
}}
`,
beforeEach() {
setDefaultState(this, { setDefaultState(this, {
clearable: true, clearable: true,
onChange: (value) => { onChange: (value) => {
this.set("value", value); this.set("value", value);
}, },
}); });
},
async test(assert) { await render(hbs`
<ComboBox
@value={{this.value}}
@content={{this.content}}
@onChange={{this.onChange}}
@options={{hash clearable=this.clearable}}
/>
`);
const header = this.subject.header(); const header = this.subject.header();
assert.ok( assert.ok(
@ -69,29 +62,25 @@ discourseModule(
"it hides the clear button" "it hides the clear button"
); );
assert.strictEqual(header.value(), null); assert.strictEqual(header.value(), null);
},
}); });
componentTest("options.{caretUpIcon,caretDownIcon}", { test("options.{caretUpIcon,caretDownIcon}", async function (assert) {
template: hbs`
{{combo-box
value=value
content=content
options=(hash
caretUpIcon=caretUpIcon
caretDownIcon=caretDownIcon
)
}}
`,
beforeEach() {
setDefaultState(this, { setDefaultState(this, {
caretUpIcon: "pencil-alt", caretUpIcon: "pencil-alt",
caretDownIcon: "trash-alt", caretDownIcon: "trash-alt",
}); });
},
async test(assert) { await render(hbs`
<ComboBox
@value={{this.value}}
@content={{this.content}}
@options={{hash
caretUpIcon=caretUpIcon
caretDownIcon=caretDownIcon
}}
/>
`);
const header = this.subject.header().el(); const header = this.subject.header().el();
assert.ok( assert.ok(
@ -105,7 +94,5 @@ discourseModule(
header.querySelector(`.d-icon-${this.caretUpIcon}`), header.querySelector(`.d-icon-${this.caretUpIcon}`),
"it uses the icon provided" "it uses the icon provided"
); );
},
}); });
} });
);

View File

@ -1,7 +1,6 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -27,7 +26,7 @@ const setDefaultState = (ctx, options) => {
ctx.setProperties(properties); ctx.setProperties(properties);
}; };
discourseModule( module(
"Integration | Component | select-kit/dropdown-select-box", "Integration | Component | select-kit/dropdown-select-box",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
@ -36,19 +35,16 @@ discourseModule(
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("selection behavior", { test("selection behavior", async function (assert) {
template: hbs`
{{dropdown-select-box
value=value
content=content
}}
`,
beforeEach() {
setDefaultState(this); setDefaultState(this);
},
async test(assert) { await render(hbs`
<DropdownSelectBox
@value={{this.value}}
@content={{this.content}}
/>
`);
await this.subject.expand(); await this.subject.expand();
assert.ok(this.subject.isExpanded()); assert.ok(this.subject.isExpanded());
@ -57,31 +53,27 @@ discourseModule(
this.subject.isExpanded(), this.subject.isExpanded(),
"it collapses the dropdown on select" "it collapses the dropdown on select"
); );
},
}); });
componentTest("options.showFullTitle=false", { test("options.showFullTitle=false", async function (assert) {
template: hbs`
{{dropdown-select-box
value=value
content=content
options=(hash
icon="times"
showFullTitle=showFullTitle
none=none
)
}}
`,
beforeEach() {
setDefaultState(this, { setDefaultState(this, {
value: null, value: null,
showFullTitle: false, showFullTitle: false,
none: "test_none", none: "test_none",
}); });
},
async test(assert) { await render(hbs`
<DropdownSelectBox
@value={{this.value}}
@content={{this.content}}
@options={{hash
icon="times"
showFullTitle=this.showFullTitle
none=this.none
}}
/>
`);
assert.notOk( assert.notOk(
this.subject.header().el().querySelector(".selected-name"), this.subject.header().el().querySelector(".selected-name"),
"it hides the text of the selected item" "it hides the text of the selected item"
@ -92,30 +84,25 @@ discourseModule(
"[en.test_none]", "[en.test_none]",
"it adds a title attribute to the button" "it adds a title attribute to the button"
); );
},
}); });
componentTest("options.showFullTitle=true", { test("options.showFullTitle=true", async function (assert) {
template: hbs`
{{dropdown-select-box
value=value
content=content
options=(hash
showFullTitle=showFullTitle
)
}}
`,
beforeEach() {
setDefaultState(this, { showFullTitle: true }); setDefaultState(this, { showFullTitle: true });
},
async test(assert) { await render(hbs`
<DropdownSelectBox
@value={{this.value}}
@content={{this.content}}
@options={{hash
showFullTitle=this.showFullTitle
}}
/>
`);
assert.ok( assert.ok(
this.subject.header().el().querySelector(".selected-name"), this.subject.header().el().querySelector(".selected-name"),
"it shows the text of the selected item" "it shows the text of the selected item"
); );
},
}); });
} }
); );

View File

@ -1,18 +1,26 @@
import selectKit from "discourse/tests/helpers/select-kit-helper"; import { module, test } from "qunit";
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest, import { fillIn, render } from "@ember/test-helpers";
} from "discourse/tests/helpers/component-test";
import { import {
discourseModule,
exists, exists,
fakeTime, fakeTime,
queryAll, queryAll,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import I18n from "I18n"; import I18n from "I18n";
import { fillIn } from "@ember/test-helpers";
discourseModule("Unit | Lib | select-kit/future-date-input", function (hooks) { function getOptions() {
return Array.from(
queryAll(`.select-kit-collection .select-kit-row`).map(
(_, span) => span.dataset.name
)
);
}
module(
"Integration | Component | select-kit/future-date-input",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
@ -20,25 +28,22 @@ discourseModule("Unit | Lib | select-kit/future-date-input", function (hooks) {
}); });
hooks.afterEach(function () { hooks.afterEach(function () {
if (this.clock) { this.clock?.restore();
this.clock.restore();
}
}); });
componentTest("rendering and expanding", { test("rendering and expanding", async function (assert) {
template: hbs` await render(hbs`
{{future-date-input <FutureDateInput
options=(hash @options={{hash
none="time_shortcut.select_timeframe" none="time_shortcut.select_timeframe"
)
}} }}
`, />
`);
async test(assert) {
assert.ok(exists(".future-date-input-selector"), "Selector is rendered"); assert.ok(exists(".future-date-input-selector"), "Selector is rendered");
assert.ok( assert.strictEqual(
this.subject.header().label() === this.subject.header().label(),
I18n.t("time_shortcut.select_timeframe"), I18n.t("time_shortcut.select_timeframe"),
"Default text is rendered" "Default text is rendered"
); );
@ -49,18 +54,14 @@ discourseModule("Unit | Lib | select-kit/future-date-input", function (hooks) {
exists(".select-kit-collection"), exists(".select-kit-collection"),
"List of options is rendered" "List of options is rendered"
); );
},
}); });
componentTest("renders default options", { test("renders default options", async function (assert) {
template: hbs`{{future-date-input}}`,
beforeEach() {
const monday = "2100-12-13T08:00:00"; const monday = "2100-12-13T08:00:00";
this.clock = fakeTime(monday, this.currentUser.timezone, true); this.clock = fakeTime(monday, this.currentUser.timezone, true);
},
async test(assert) { await render(hbs`<FutureDateInput />`);
await this.subject.expand(); await this.subject.expand();
const options = getOptions(); const options = getOptions();
const expected = [ const expected = [
@ -80,61 +81,53 @@ discourseModule("Unit | Lib | select-kit/future-date-input", function (hooks) {
]; ];
assert.deepEqual(options, expected); assert.deepEqual(options, expected);
},
}); });
componentTest("shows 'Custom date and time' by default", { test("shows 'Custom date and time' by default", async function (assert) {
template: hbs`{{future-date-input}}`, await render(hbs`<FutureDateInput />`);
async test(assert) {
await this.subject.expand(); await this.subject.expand();
const options = getOptions(); const options = getOptions();
const customDateAndTime = I18n.t("time_shortcut.custom"); const customDateAndTime = I18n.t("time_shortcut.custom");
assert.ok(options.includes(customDateAndTime)); assert.ok(options.includes(customDateAndTime));
},
}); });
componentTest("doesn't show 'Custom date and time' if disabled", { test("doesn't show 'Custom date and time' if disabled", async function (assert) {
template: hbs` await render(hbs`
{{future-date-input <FutureDateInput
includeDateTime=false @includeDateTime={{false}}
}} />
`, `);
async test(assert) {
await this.subject.expand(); await this.subject.expand();
const options = getOptions(); const options = getOptions();
const customDateAndTime = I18n.t("time_shortcut.custom"); const customDateAndTime = I18n.t("time_shortcut.custom");
assert.notOk(options.includes(customDateAndTime)); assert.notOk(options.includes(customDateAndTime));
},
}); });
componentTest("shows the now option if enabled", { test("shows the now option if enabled", async function (assert) {
template: hbs` await render(hbs`
{{future-date-input <FutureDateInput
includeNow=true @includeNow={{true}}
}} />
`, `);
async test(assert) {
await this.subject.expand(); await this.subject.expand();
const options = getOptions(); const options = getOptions();
const now = I18n.t("time_shortcut.now"); const now = I18n.t("time_shortcut.now");
assert.ok(options.includes(now)); assert.ok(options.includes(now));
},
}); });
componentTest("changing date/time updates the input correctly", { test("changing date/time updates the input correctly", async function (assert) {
template: hbs`{{future-date-input input=input onChangeInput=(action (mut input))}}`,
beforeEach() {
this.set("input", moment("2032-01-01 11:10")); this.set("input", moment("2032-01-01 11:10"));
},
async test(assert) { await render(
hbs`<FutureDateInput @input={{this.input}} @onChangeInput={{action (mut input)}} />`
);
await fillIn(".time-input", "11:15"); await fillIn(".time-input", "11:15");
assert.ok(this.input.includes("2032-01-01")); assert.ok(this.input.includes("2032-01-01"));
@ -144,14 +137,6 @@ discourseModule("Unit | Lib | select-kit/future-date-input", function (hooks) {
assert.ok(this.input.includes("2033-01-01")); assert.ok(this.input.includes("2033-01-01"));
assert.ok(this.input.includes("11:15")); assert.ok(this.input.includes("11:15"));
},
}); });
function getOptions() {
return Array.from(
queryAll(`.select-kit-collection .select-kit-row`).map(
(_, span) => span.dataset.name
)
);
} }
}); );

View File

@ -1,31 +0,0 @@
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
discourseModule(
"Integration | Component | site-setting | host-list",
function (hooks) {
setupRenderingTest(hooks);
componentTest("displays setting value", {
template: hbs`{{site-setting setting=setting}}`,
beforeEach() {
this.set("setting", {
setting: "blocked_onebox_domains",
value: "a.com|b.com",
type: "host_list",
});
},
async test(assert) {
assert.strictEqual(
query(".formatted-selection").innerText,
"a.com, b.com"
);
},
});
}
);

View File

@ -1,33 +1,27 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
discourseModule( module("Integration | Component | select-kit/list-setting", function (hooks) {
"Integration | Component | select-kit/list-setting",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("default", { test("default", async function (assert) {
template: hbs`
{{list-setting
value=value
choices=choices
}}
`,
beforeEach() {
this.set("value", ["bold", "italic"]); this.set("value", ["bold", "italic"]);
this.set("choices", ["bold", "italic", "underline"]); this.set("choices", ["bold", "italic", "underline"]);
},
async test(assert) { await render(hbs`
<ListSetting
@value={{this.value}}
@choices={{this.choices}}
/>
`);
assert.strictEqual(this.subject.header().name(), "bold,italic"); assert.strictEqual(this.subject.header().name(), "bold,italic");
assert.strictEqual(this.subject.header().value(), "bold,italic"); assert.strictEqual(this.subject.header().value(), "bold,italic");
@ -35,7 +29,5 @@ discourseModule(
assert.strictEqual(this.subject.rows().length, 1); assert.strictEqual(this.subject.rows().length, 1);
assert.strictEqual(this.subject.rowByIndex(0).value(), "underline"); assert.strictEqual(this.subject.rowByIndex(0).value(), "underline");
},
}); });
} });
);

View File

@ -1,16 +1,12 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { import { query, queryAll } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import I18n from "I18n"; import I18n from "I18n";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
discourseModule( module(
"Integration | Component | select-kit/mini-tag-chooser", "Integration | Component | select-kit/mini-tag-chooser",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
@ -19,78 +15,65 @@ discourseModule(
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("displays tags", { test("displays tags", async function (assert) {
template: hbs`{{mini-tag-chooser value=value}}`,
beforeEach() {
this.set("value", ["foo", "bar"]); this.set("value", ["foo", "bar"]);
},
async test(assert) { await render(hbs`<MiniTagChooser @value={{this.value}} />`);
assert.strictEqual(this.subject.header().value(), "foo,bar"); assert.strictEqual(this.subject.header().value(), "foo,bar");
},
}); });
componentTest("create a tag", { test("create a tag", async function (assert) {
template: hbs`{{mini-tag-chooser value=value}}`,
beforeEach() {
this.set("value", ["foo", "bar"]); this.set("value", ["foo", "bar"]);
},
async test(assert) { await render(hbs`<MiniTagChooser @value={{this.value}} />`);
assert.strictEqual(this.subject.header().value(), "foo,bar"); assert.strictEqual(this.subject.header().value(), "foo,bar");
await this.subject.expand(); await this.subject.expand();
await this.subject.fillInFilter("mon"); await this.subject.fillInFilter("mon");
assert.strictEqual( assert.deepEqual(
queryAll(".select-kit-row").text().trim(), [...queryAll(".select-kit-row")].map((el) => el.textContent.trim()),
"monkey x1\ngazelle x2" ["monkey x1", "gazelle x2"]
); );
await this.subject.fillInFilter("key"); await this.subject.fillInFilter("key");
assert.strictEqual( assert.deepEqual(
queryAll(".select-kit-row").text().trim(), [...queryAll(".select-kit-row")].map((el) => el.textContent.trim()),
"monkey x1\ngazelle x2" ["monkey x1", "gazelle x2"]
); );
await this.subject.selectRowByValue("monkey"); await this.subject.selectRowByValue("monkey");
assert.strictEqual(this.subject.header().value(), "foo,bar,monkey"); assert.strictEqual(this.subject.header().value(), "foo,bar,monkey");
},
}); });
componentTest("max_tags_per_topic", { test("max_tags_per_topic", async function (assert) {
template: hbs`{{mini-tag-chooser value=value}}`,
beforeEach() {
this.set("value", ["foo", "bar"]); this.set("value", ["foo", "bar"]);
this.siteSettings.max_tags_per_topic = 2; this.siteSettings.max_tags_per_topic = 2;
},
async test(assert) { await render(hbs`<MiniTagChooser @value={{this.value}} />`);
assert.strictEqual(this.subject.header().value(), "foo,bar"); assert.strictEqual(this.subject.header().value(), "foo,bar");
await this.subject.expand(); await this.subject.expand();
await this.subject.fillInFilter("baz"); await this.subject.fillInFilter("baz");
await this.subject.selectRowByValue("monkey"); await this.subject.selectRowByValue("monkey");
const error = queryAll(".select-kit-error").text(); const error = query(".select-kit-error").innerText;
assert.strictEqual( assert.strictEqual(
error, error,
I18n.t("select_kit.max_content_reached", { I18n.t("select_kit.max_content_reached", {
count: this.siteSettings.max_tags_per_topic, count: this.siteSettings.max_tags_per_topic,
}) })
); );
},
}); });
componentTest("required_tag_group", { test("required_tag_group", async function (assert) {
template: hbs`{{mini-tag-chooser value=value options=(hash categoryId=1)}}`,
beforeEach() {
this.set("value", ["foo", "bar"]); this.set("value", ["foo", "bar"]);
},
async test(assert) { await render(
hbs`<MiniTagChooser @value={{this.value}} @options={{hash categoryId=1}} />`
);
assert.strictEqual(this.subject.header().value(), "foo,bar"); assert.strictEqual(this.subject.header().value(), "foo,bar");
await this.subject.expand(); await this.subject.expand();
@ -109,7 +92,6 @@ discourseModule(
query("input[name=filter-input-search]").placeholder, query("input[name=filter-input-search]").placeholder,
I18n.t("select_kit.filter_placeholder") I18n.t("select_kit.filter_placeholder")
); );
},
}); });
} }
); );

View File

@ -1,7 +1,6 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -22,28 +21,23 @@ const setDefaultState = (ctx, options) => {
ctx.setProperties(properties); ctx.setProperties(properties);
}; };
discourseModule( module("Integration | Component | select-kit/multi-select", function (hooks) {
"Integration | Component | select-kit/multi-select",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("content", { test("content", async function (assert) {
template: hbs`
{{multi-select
value=value
content=content
}}
`,
beforeEach() {
setDefaultState(this); setDefaultState(this);
},
async test(assert) { await render(hbs`
<MultiSelect
@value={{this.value}}
@content={{this.content}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const content = this.subject.displayedContent(); const content = this.subject.displayedContent();
@ -63,34 +57,19 @@ discourseModule(
null, null,
"it doesn't set a value from the content" "it doesn't set a value from the content"
); );
},
});
}
);
discourseModule(
"Integration | Component | select-kit/multi-select | maximum=1",
function (hooks) {
setupRenderingTest(hooks);
hooks.beforeEach(function () {
this.set("subject", selectKit());
}); });
componentTest("content", { test("maximum=1", async function (assert) {
template: hbs`
{{multi-select
value=value
content=content
options=(hash maximum=1)
}}
`,
beforeEach() {
setDefaultState(this); setDefaultState(this);
},
async test(assert) { await render(hbs`
<MultiSelect
@value={{this.value}}
@content={{this.content}}
@options={{hash maximum=1}}
/>
`);
await this.subject.expand(); await this.subject.expand();
await this.subject.selectRowByValue(1); await this.subject.selectRowByValue(1);
@ -103,39 +82,22 @@ discourseModule(
this.subject.isExpanded(), this.subject.isExpanded(),
"it doesn’t close the dropdown when no selection has been made" "it doesn’t close the dropdown when no selection has been made"
); );
},
});
}
);
discourseModule(
"Integration | Component | select-kit/multi-select | maximum=2",
function (hooks) {
setupRenderingTest(hooks);
hooks.beforeEach(function () {
this.set("subject", selectKit());
}); });
componentTest("content", { test("maximum=2", async function (assert) {
template: hbs`
{{multi-select
value=value
content=content
options=(hash maximum=2)
}}
`,
beforeEach() {
setDefaultState(this); setDefaultState(this);
},
async test(assert) { await render(hbs`
<MultiSelect
@value={{this.value}}
@content={{this.content}}
@options={{hash maximum=2}}
/>
`);
await this.subject.expand(); await this.subject.expand();
await this.subject.selectRowByValue(1); await this.subject.selectRowByValue(1);
assert.ok(this.subject.isExpanded(), "it doesn’t close the dropdown"); assert.ok(this.subject.isExpanded(), "it doesn’t close the dropdown");
},
}); });
} });
);

View File

@ -1,13 +1,12 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import selectKit, { import selectKit, {
setDefaultState, setDefaultState,
} from "discourse/tests/helpers/select-kit-helper"; } from "discourse/tests/helpers/select-kit-helper";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule( module(
"Integration | Component | select-kit/notifications-button", "Integration | Component | select-kit/notifications-button",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
@ -16,24 +15,20 @@ discourseModule(
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("default", { test("default", async function (assert) {
template: hbs`
{{notifications-button
value=value
options=(hash
i18nPrefix=i18nPrefix
i18nPostfix=i18nPostfix
)
}}
`,
beforeEach() {
this.set("value", 1); this.set("value", 1);
setDefaultState(this, 1, { i18nPrefix: "pre", i18nPostfix: "post" }); setDefaultState(this, 1, { i18nPrefix: "pre", i18nPostfix: "post" });
},
async test(assert) { await render(hbs`
<NotificationsButton
@value={{this.value}}
@options={{hash
i18nPrefix=this.i18nPrefix
i18nPostfix=this.i18nPostfix
}}
/>
`);
assert.ok(this.subject.header().value()); assert.ok(this.subject.header().value());
assert.ok( assert.ok(
@ -49,7 +44,6 @@ discourseModule(
icon.classList.contains("d-icon-d-regular"), icon.classList.contains("d-icon-d-regular"),
"it shows the correct icon" "it shows the correct icon"
); );
},
}); });
} }
); );

View File

@ -1,8 +1,7 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import Topic from "discourse/models/topic"; import Topic from "discourse/models/topic";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -15,49 +14,42 @@ const buildTopic = function (pinned = true) {
}); });
}; };
discourseModule( module("Integration | Component | select-kit/pinned-options", function (hooks) {
"Integration | Component | select-kit/pinned-options",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("unpinning", { test("unpinning", async function (assert) {
template: hbs`{{pinned-options value=topic.pinned topic=topic}}`,
beforeEach() {
this.siteSettings.automatically_unpin_topics = false; this.siteSettings.automatically_unpin_topics = false;
this.set("topic", buildTopic()); this.set("topic", buildTopic());
},
async test(assert) { await render(
hbs`<PinnedOptions @value={{this.topic.pinned}} @topic={{this.topic}} />`
);
assert.strictEqual(this.subject.header().name(), "pinned"); assert.strictEqual(this.subject.header().name(), "pinned");
await this.subject.expand(); await this.subject.expand();
await this.subject.selectRowByValue("unpinned"); await this.subject.selectRowByValue("unpinned");
assert.strictEqual(this.subject.header().name(), "unpinned"); assert.strictEqual(this.subject.header().name(), "unpinned");
},
}); });
componentTest("pinning", { test("pinning", async function (assert) {
template: hbs`{{pinned-options value=topic.pinned topic=topic}}`,
beforeEach() {
this.siteSettings.automatically_unpin_topics = false; this.siteSettings.automatically_unpin_topics = false;
this.set("topic", buildTopic(false)); this.set("topic", buildTopic(false));
},
async test(assert) { await render(
hbs`<PinnedOptions @value={{this.topic.pinned}} @topic={{this.topic}} />`
);
assert.strictEqual(this.subject.header().name(), "unpinned"); assert.strictEqual(this.subject.header().name(), "unpinned");
await this.subject.expand(); await this.subject.expand();
await this.subject.selectRowByValue("pinned"); await this.subject.selectRowByValue("pinned");
assert.strictEqual(this.subject.header().name(), "pinned"); assert.strictEqual(this.subject.header().name(), "pinned");
},
}); });
} });
);

View File

@ -1,8 +1,7 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import I18n from "I18n"; import I18n from "I18n";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -30,23 +29,18 @@ const setDefaultState = (ctx, options) => {
ctx.setProperties(properties); ctx.setProperties(properties);
}; };
discourseModule( module("Integration | Component | select-kit/single-select", function (hooks) {
"Integration | Component | select-kit/single-select",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("content", { test("content", async function (assert) {
template: hbs`{{single-select content=content}}`,
beforeEach() {
setDefaultState(this); setDefaultState(this);
},
async test(assert) { await render(hbs`<SingleSelect @content={{this.content}} />`);
await this.subject.expand(); await this.subject.expand();
const content = this.subject.displayedContent(); const content = this.subject.displayedContent();
@ -66,52 +60,44 @@ discourseModule(
null, null,
"it doesn't set a value from the content" "it doesn't set a value from the content"
); );
},
}); });
componentTest("value", { test("value", async function (assert) {
template: hbs`
{{single-select
value=value
content=content
nameProperty=nameProperty
valueProperty=valueProperty
onChange=onChange
}}
`,
beforeEach() {
setDefaultState(this); setDefaultState(this);
},
test(assert) { await render(hbs`
<SingleSelect
@value={{this.value}}
@content={{this.content}}
@nameProperty={{this.nameProperty}}
@valueProperty={{this.valueProperty}}
@onChange={{this.onChange}}
/>
`);
assert.strictEqual( assert.strictEqual(
this.subject.header().value(this.content), this.subject.header().value(this.content),
"1", "1",
"it selects the correct content to display" "it selects the correct content to display"
); );
},
}); });
componentTest("options.filterable", { test("options.filterable", async function (assert) {
template: hbs`
{{single-select
value=value
content=content
nameProperty=nameProperty
valueProperty=valueProperty
onChange=onChange
options=(hash
filterable=filterable
)
}}
`,
beforeEach() {
setDefaultState(this, { filterable: true }); setDefaultState(this, { filterable: true });
},
async test(assert) { await render(hbs`
<SingleSelect
@value={{this.value}}
@content={{this.content}}
@nameProperty={{this.nameProperty}}
@valueProperty={{this.valueProperty}}
@onChange={{this.onChange}}
@options={{hash
filterable=this.filterable
}}
/>
`);
await this.subject.expand(); await this.subject.expand();
assert.ok(this.subject.filter().exists(), "it shows the filter"); assert.ok(this.subject.filter().exists(), "it shows the filter");
@ -122,29 +108,25 @@ discourseModule(
filter, filter,
"it filters the list" "it filters the list"
); );
},
}); });
componentTest("options.limitMatches", { test("options.limitMatches", async function (assert) {
template: hbs`
{{single-select
value=value
content=content
nameProperty=nameProperty
valueProperty=valueProperty
onChange=onChange
options=(hash
limitMatches=limitMatches
filterable=filterable
)
}}
`,
beforeEach() {
setDefaultState(this, { limitMatches: 1, filterable: true }); setDefaultState(this, { limitMatches: 1, filterable: true });
},
async test(assert) { await render(hbs`
<SingleSelect
@value={{this.value}}
@content={{this.content}}
@nameProperty={{this.nameProperty}}
@valueProperty={{this.valueProperty}}
@onChange={{this.onChange}}
@options={{hash
limitMatches=this.limitMatches
filterable=this.filterable
}}
/>
`);
await this.subject.expand(); await this.subject.expand();
await this.subject.fillInFilter("ba"); await this.subject.fillInFilter("ba");
@ -153,19 +135,9 @@ discourseModule(
1, 1,
"it returns only 1 result" "it returns only 1 result"
); );
},
}); });
componentTest("valueAttribute (deprecated)", { test("valueAttribute (deprecated)", async function (assert) {
template: hbs`
{{single-select
value=value
content=content
valueAttribute="value"
}}
`,
beforeEach() {
this.set("value", "normal"); this.set("value", "normal");
const content = [ const content = [
@ -176,85 +148,68 @@ discourseModule(
{ name: "Largest", value: "largest" }, { name: "Largest", value: "largest" },
]; ];
this.set("content", content); this.set("content", content);
},
async test(assert) { await render(hbs`
<SingleSelect
@value={{this.value}}
@content={{this.content}}
@valueAttribute="value"
/>
`);
await this.subject.expand(); await this.subject.expand();
assert.strictEqual(this.subject.selectedRow().value(), this.value); assert.strictEqual(this.subject.selectedRow().value(), this.value);
},
}); });
componentTest("none:string", { test("none:string", async function (assert) {
template: hbs`
{{single-select
value=value
content=content
nameProperty=nameProperty
valueProperty=valueProperty
onChange=onChange
options=(hash
none="test.none"
)
}}
`,
beforeEach() {
I18n.translations[I18n.locale].js.test = { none: "(default)" }; I18n.translations[I18n.locale].js.test = { none: "(default)" };
setDefaultState(this, { value: 1 }); setDefaultState(this, { value: 1 });
},
async test(assert) { await render(hbs`
<SingleSelect
@value={{this.value}}
@content={{this.content}}
@nameProperty={{this.nameProperty}}
@valueProperty={{this.valueProperty}}
@onChange={{this.onChange}}
@options={{hash
none="test.none"
}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const noneRow = this.subject.rowByIndex(0); const noneRow = this.subject.rowByIndex(0);
assert.strictEqual(noneRow.value(), null); assert.strictEqual(noneRow.value(), null);
assert.strictEqual(noneRow.name(), I18n.t("test.none")); assert.strictEqual(noneRow.name(), I18n.t("test.none"));
},
}); });
componentTest("none:object", { test("none:object", async function (assert) {
template: hbs`
{{single-select
value=value
content=content
nameProperty=nameProperty
valueProperty=valueProperty
onChange=onChange
options=(hash
none=none
)
}}
`,
beforeEach() {
setDefaultState(this, { none: { value: null, name: "(default)" } }); setDefaultState(this, { none: { value: null, name: "(default)" } });
},
async test(assert) { await render(hbs`
<SingleSelect
@value={{this.value}}
@content={{this.content}}
@nameProperty={{this.nameProperty}}
@valueProperty={{this.valueProperty}}
@onChange={{this.onChange}}
@options={{hash
none=this.none
}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const noneRow = this.subject.rowByIndex(0); const noneRow = this.subject.rowByIndex(0);
assert.strictEqual(noneRow.value(), null); assert.strictEqual(noneRow.value(), null);
assert.strictEqual(noneRow.name(), "(default)"); assert.strictEqual(noneRow.name(), "(default)");
},
}); });
componentTest("content is a basic array", { test("content is a basic array", async function (assert) {
template: hbs`
{{single-select
value=value
content=content
nameProperty=nameProperty
valueProperty=valueProperty
onChange=onChange
options=(hash
none="test.none"
)
}}
`,
beforeEach() {
I18n.translations[I18n.locale].js.test = { none: "(default)" }; I18n.translations[I18n.locale].js.test = { none: "(default)" };
setDefaultState(this, { setDefaultState(this, {
nameProperty: null, nameProperty: null,
@ -262,9 +217,20 @@ discourseModule(
value: "foo", value: "foo",
content: ["foo", "bar", "baz"], content: ["foo", "bar", "baz"],
}); });
},
async test(assert) { await render(hbs`
<SingleSelect
@value={{this.value}}
@content={{this.content}}
@nameProperty={{this.nameProperty}}
@valueProperty={{this.valueProperty}}
@onChange={{this.onChange}}
@options={{hash
none="test.none"
}}
/>
`);
await this.subject.expand(); await this.subject.expand();
const noneRow = this.subject.rowByIndex(0); const noneRow = this.subject.rowByIndex(0);
@ -275,21 +241,9 @@ discourseModule(
await this.subject.selectRowByIndex(0); await this.subject.selectRowByIndex(0);
assert.strictEqual(this.value, null); assert.strictEqual(this.value, null);
},
}); });
componentTest("selected value can be 0", { test("selected value can be 0", async function (assert) {
template: hbs`
{{single-select
value=value
content=content
nameProperty=nameProperty
valueProperty=valueProperty
onChange=onChange
}}
`,
beforeEach() {
setDefaultState(this, { setDefaultState(this, {
value: 1, value: 1,
content: [ content: [
@ -297,61 +251,61 @@ discourseModule(
{ id: 1, name: "bar" }, { id: 1, name: "bar" },
], ],
}); });
},
async test(assert) { await render(hbs`
<SingleSelect
@value={{this.value}}
@content={{this.content}}
@nameProperty={{this.nameProperty}}
@valueProperty={{this.valueProperty}}
@onChange={{this.onChange}}
/>
`);
assert.strictEqual(this.subject.header().value(), "1"); assert.strictEqual(this.subject.header().value(), "1");
await this.subject.expand(); await this.subject.expand();
await this.subject.selectRowByValue(0); await this.subject.selectRowByValue(0);
assert.strictEqual(this.subject.header().value(), "0"); assert.strictEqual(this.subject.header().value(), "0");
},
}); });
componentTest("prevents propagating click event on header", { test("prevents propagating click event on header", async function (assert) {
template: hbs`
{{#d-button icon='times' action=onClick}}
{{single-select
options=(hash preventsClickPropagation=true)
value=value
content=content
}}
{{/d-button}}
`,
beforeEach() {
this.setProperties({ this.setProperties({
onClick: () => this.set("value", "foo"), onClick: () => this.set("value", "foo"),
content: DEFAULT_CONTENT, content: DEFAULT_CONTENT,
value: DEFAULT_VALUE, value: DEFAULT_VALUE,
}); });
},
async test(assert) { await render(hbs`
<DButton @icon="times" @action={{this.onClick}}>
<SingleSelect
@value={{this.value}}
@content={{this.content}}
@options={{hash preventsClickPropagation=true}}
/>
</DButton>
`);
assert.strictEqual(this.value, DEFAULT_VALUE); assert.strictEqual(this.value, DEFAULT_VALUE);
await this.subject.expand(); await this.subject.expand();
assert.strictEqual(this.value, DEFAULT_VALUE); assert.strictEqual(this.value, DEFAULT_VALUE);
},
}); });
componentTest("labelProperty", { test("labelProperty", async function (assert) {
template: hbs`
{{single-select
labelProperty="foo"
value=value
content=content
}}
`,
beforeEach() {
this.setProperties({ this.setProperties({
content: [{ id: 1, name: "john", foo: "JACKSON" }], content: [{ id: 1, name: "john", foo: "JACKSON" }],
value: 1, value: 1,
}); });
},
async test(assert) { await render(hbs`
<SingleSelect
@labelProperty="foo"
@value={{this.value}}
@content={{this.content}}
/>
`);
assert.strictEqual(this.subject.header().label(), "JACKSON"); assert.strictEqual(this.subject.header().label(), "JACKSON");
await this.subject.expand(); await this.subject.expand();
@ -359,26 +313,22 @@ discourseModule(
const row = this.subject.rowByValue(1); const row = this.subject.rowByValue(1);
assert.strictEqual(row.label(), "JACKSON"); assert.strictEqual(row.label(), "JACKSON");
},
}); });
componentTest("titleProperty", { test("titleProperty", async function (assert) {
template: hbs`
{{single-select
titleProperty="foo"
value=value
content=content
}}
`,
beforeEach() {
this.setProperties({ this.setProperties({
content: [{ id: 1, name: "john", foo: "JACKSON" }], content: [{ id: 1, name: "john", foo: "JACKSON" }],
value: 1, value: 1,
}); });
},
async test(assert) { await render(hbs`
<SingleSelect
@titleProperty="foo"
@value={{this.value}}
@content={{this.content}}
/>
`);
assert.strictEqual(this.subject.header().title(), "JACKSON"); assert.strictEqual(this.subject.header().title(), "JACKSON");
await this.subject.expand(); await this.subject.expand();
@ -386,20 +336,18 @@ discourseModule(
const row = this.subject.rowByValue(1); const row = this.subject.rowByValue(1);
assert.strictEqual(row.title(), "JACKSON"); assert.strictEqual(row.title(), "JACKSON");
},
}); });
componentTest("langProperty", { test("langProperty", async function (assert) {
template: hbs`{{single-select langProperty="foo" value=value content=content}}`,
beforeEach() {
this.setProperties({ this.setProperties({
content: [{ id: 1, name: "john", foo: "be" }], content: [{ id: 1, name: "john", foo: "be" }],
value: null, value: null,
}); });
},
async test(assert) { await render(
hbs`<SingleSelect @langProperty="foo" @value={{this.value}} @content={{this.content}} />`
);
assert.strictEqual( assert.strictEqual(
this.subject.header().el().querySelector(".selected-name").lang, this.subject.header().el().querySelector(".selected-name").lang,
"" ""
@ -416,20 +364,18 @@ discourseModule(
this.subject.header().el().querySelector(".selected-name").lang, this.subject.header().el().querySelector(".selected-name").lang,
"be" "be"
); );
},
}); });
componentTest("name", { test("name", async function (assert) {
template: hbs`{{single-select value=value content=content}}`,
beforeEach() {
this.setProperties({ this.setProperties({
content: [{ id: 1, name: "john" }], content: [{ id: 1, name: "john" }],
value: null, value: null,
}); });
},
async test(assert) { await render(
hbs`<SingleSelect @value={{this.value}} @content={{this.content}} />`
);
assert.strictEqual( assert.strictEqual(
this.subject.header().el().getAttribute("name"), this.subject.header().el().getAttribute("name"),
I18n.t("select_kit.select_to_filter") I18n.t("select_kit.select_to_filter")
@ -444,7 +390,5 @@ discourseModule(
name: this.content.firstObject.name, name: this.content.firstObject.name,
}) })
); );
},
}); });
} });
);

View File

@ -1,13 +1,10 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import I18n from "I18n"; import I18n from "I18n";
import Site from "discourse/models/site";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import pretender from "discourse/tests/helpers/create-pretender"; import pretender, { response } from "discourse/tests/helpers/create-pretender";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
import { set } from "@ember/object";
function initTags(context) { function initTags(context) {
const categories = context.site.categoriesList; const categories = context.site.categoriesList;
@ -20,20 +17,13 @@ function initTags(context) {
}); });
} }
discourseModule( module("Integration | Component | select-kit/tag-drop", function (hooks) {
"Integration | Component | select-kit/tag-drop",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.set("subject", selectKit()); this.set("subject", selectKit());
const site = Site.current(); this.site.set("top_tags", ["jeff", "neil", "arpit", "régis"]);
set(site, "top_tags", ["jeff", "neil", "arpit", "régis"]);
const response = (object) => {
return [200, { "Content-Type": "application/json" }, object];
};
pretender.get("/tags/filter/search", (params) => { pretender.get("/tags/filter/search", (params) => {
if (params.queryParams.q === "dav") { if (params.queryParams.q === "dav") {
@ -44,31 +34,21 @@ discourseModule(
}); });
}); });
componentTest("default", { test("default", async function (assert) {
template: hbs`
{{tag-drop
currentCategory=currentCategory
tagId=tagId
options=(hash
tagId=tagId
)
}}
`,
beforeEach() {
initTags(this); initTags(this);
},
async test(assert) { await render(hbs`
<TagDrop
@currentCategory={{this.currentCategory}}
@tagId={{this.tagId}}
@options={{hash
tagId=this.tagId
}}
/>
`);
await this.subject.expand(); await this.subject.expand();
assert.ok(true);
// const row = this.subject.rowByValue(this.category.id);
// assert.ok(
// exists(row.el().find(".category-desc")),
// "it shows category description for newcomers"
// );
const content = this.subject.displayedContent(); const content = this.subject.displayedContent();
assert.strictEqual( assert.strictEqual(
@ -89,17 +69,12 @@ discourseModule(
"David", "David",
"it has no tag count when filtering in a category context" "it has no tag count when filtering in a category context"
); );
},
}); });
componentTest("default global (no category)", { test("default global (no category)", async function (assert) {
template: hbs`{{tag-drop}}`, await render(hbs`<TagDrop />`);
async test(assert) {
await this.subject.expand(); await this.subject.expand();
assert.ok(true);
await this.subject.fillInFilter("dav"); await this.subject.fillInFilter("dav");
assert.strictEqual( assert.strictEqual(
@ -107,7 +82,5 @@ discourseModule(
"David x2", "David x2",
"it has the tag count" "it has the tag count"
); );
},
}); });
} });
);

View File

@ -1,12 +1,9 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import I18n from "I18n"; import I18n from "I18n";
import Topic from "discourse/models/topic"; import Topic from "discourse/models/topic";
import { import { query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -28,7 +25,7 @@ const buildTopic = function (opts) {
const originalTranslation = const originalTranslation =
I18n.translations.en.js.topic.notifications.tracking_pm.title; I18n.translations.en.js.topic.notifications.tracking_pm.title;
discourseModule( module(
"Integration | Component | select-kit/topic-notifications-button", "Integration | Component | select-kit/topic-notifications-button",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
@ -38,247 +35,192 @@ discourseModule(
originalTranslation; originalTranslation;
}); });
componentTest("the header has a localized title", { test("the header has a localized title", async function (assert) {
template: hbs`
{{topic-notifications-button
notificationLevel=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
this.set("topic", buildTopic({ level: 1 })); this.set("topic", buildTopic({ level: 1 }));
},
async test(assert) { await render(hbs`
<TopicNotificationsButton
@notificationLevel={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
assert.strictEqual( assert.strictEqual(
selectKit().header().label(), selectKit().header().label(),
"Normal", "Normal",
"it has the correct label" "it has the correct label"
); );
await this.set("topic", buildTopic({ level: 2 })); this.set("topic", buildTopic({ level: 2 }));
assert.strictEqual( assert.strictEqual(
selectKit().header().label(), selectKit().header().label(),
"Tracking", "Tracking",
"it correctly changes the label" "it correctly changes the label"
); );
},
}); });
componentTest("the header has a localized title", { test("the header has a localized title", async function (assert) {
template: hbs`
{{topic-notifications-button
notificationLevel=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
I18n.translations.en.js.topic.notifications.tracking_pm.title = `${originalTranslation} PM`; I18n.translations.en.js.topic.notifications.tracking_pm.title = `${originalTranslation} PM`;
this.set( this.set("topic", buildTopic({ level: 2, archetype: "private_message" }));
"topic",
buildTopic({ level: 2, archetype: "private_message" }) await render(hbs`
); <TopicNotificationsButton
}, @notificationLevel={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
test(assert) {
assert.strictEqual( assert.strictEqual(
selectKit().header().label(), selectKit().header().label(),
`${originalTranslation} PM`, `${originalTranslation} PM`,
"it has the correct label for PMs" "it has the correct label for PMs"
); );
},
}); });
componentTest("notification reason text - user mailing list mode", { test("notification reason text - user mailing list mode", async function (assert) {
template: hbs`
{{topic-notifications-button
notificationLevel=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
this.currentUser.set("mailing_list_mode", true); this.currentUser.set("mailing_list_mode", true);
this.set("topic", buildTopic({ level: 2 })); this.set("topic", buildTopic({ level: 2 }));
},
test(assert) { await render(hbs`
<TopicNotificationsButton
@notificationLevel={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
assert.strictEqual( assert.strictEqual(
queryAll(".topic-notifications-button .text").text(), query(".topic-notifications-button .text").innerText,
I18n.t("topic.notifications.reasons.mailing_list_mode"), I18n.t("topic.notifications.reasons.mailing_list_mode"),
"mailing_list_mode enabled for the user shows unique text" "mailing_list_mode enabled for the user shows unique text"
); );
},
}); });
componentTest("notification reason text - bad notification reason", { test("notification reason text - bad notification reason", async function (assert) {
template: hbs`
{{topic-notifications-button
notificationLevel=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
this.set("topic", buildTopic({ level: 2 })); this.set("topic", buildTopic({ level: 2 }));
},
test(assert) { await render(hbs`
<TopicNotificationsButton
@notificationLevel={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
this.set("topic", buildTopic({ level: 3, reason: 999 })); this.set("topic", buildTopic({ level: 3, reason: 999 }));
assert.strictEqual( assert.strictEqual(
queryAll(".topic-notifications-button .text").text(), query(".topic-notifications-button .text").innerText,
I18n.t("topic.notifications.reasons.3"), I18n.t("topic.notifications.reasons.3"),
"fallback to regular level translation if reason does not exist" "fallback to regular level translation if reason does not exist"
); );
},
}); });
componentTest("notification reason text - user tracking category", { test("notification reason text - user tracking category", async function (assert) {
template: hbs`
{{topic-notifications-button
notificationLevel=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
this.currentUser.set("tracked_category_ids", [88]); this.currentUser.set("tracked_category_ids", [88]);
this.set("topic", buildTopic({ level: 2, reason: 8, category_id: 88 })); this.set("topic", buildTopic({ level: 2, reason: 8, category_id: 88 }));
},
test(assert) { await render(hbs`
<TopicNotificationsButton
@notificationLevel={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
assert.strictEqual( assert.strictEqual(
queryAll(".topic-notifications-button .text").text(), query(".topic-notifications-button .text").innerText,
I18n.t("topic.notifications.reasons.2_8"), I18n.t("topic.notifications.reasons.2_8"),
"use 2_8 notification if user is still tracking category" "use 2_8 notification if user is still tracking category"
); );
},
}); });
componentTest( test("notification reason text - user no longer tracking category", async function (assert) {
"notification reason text - user no longer tracking category",
{
template: hbs`
{{topic-notifications-button
notificationLevel=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
this.currentUser.set("tracked_category_ids", []); this.currentUser.set("tracked_category_ids", []);
this.set( this.set("topic", buildTopic({ level: 2, reason: 8, category_id: 88 }));
"topic",
buildTopic({ level: 2, reason: 8, category_id: 88 }) await render(hbs`
); <TopicNotificationsButton
}, @notificationLevel={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
test(assert) {
assert.strictEqual( assert.strictEqual(
queryAll(".topic-notifications-button .text").text(), query(".topic-notifications-button .text").innerText,
I18n.t("topic.notifications.reasons.2_8_stale"), I18n.t("topic.notifications.reasons.2_8_stale"),
"use _stale notification if user is no longer tracking category" "use _stale notification if user is no longer tracking category"
); );
}, });
}
);
componentTest("notification reason text - user watching category", { test("notification reason text - user watching category", async function (assert) {
template: hbs`
{{topic-notifications-button
notificationLevel=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
this.currentUser.set("watched_category_ids", [88]); this.currentUser.set("watched_category_ids", [88]);
this.set("topic", buildTopic({ level: 3, reason: 6, category_id: 88 })); this.set("topic", buildTopic({ level: 3, reason: 6, category_id: 88 }));
},
test(assert) { await render(hbs`
<TopicNotificationsButton
@notificationLevel={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
assert.strictEqual( assert.strictEqual(
queryAll(".topic-notifications-button .text").text(), query(".topic-notifications-button .text").innerText,
I18n.t("topic.notifications.reasons.3_6"), I18n.t("topic.notifications.reasons.3_6"),
"use 3_6 notification if user is still watching category" "use 3_6 notification if user is still watching category"
); );
},
}); });
componentTest( test("notification reason text - user no longer watching category", async function (assert) {
"notification reason text - user no longer watching category",
{
template: hbs`
{{topic-notifications-button
notificationLevel=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
this.currentUser.set("watched_category_ids", []); this.currentUser.set("watched_category_ids", []);
this.set( this.set("topic", buildTopic({ level: 3, reason: 6, category_id: 88 }));
"topic",
buildTopic({ level: 3, reason: 6, category_id: 88 }) await render(hbs`
); <TopicNotificationsButton
}, @notificationLevel={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
test(assert) {
assert.strictEqual( assert.strictEqual(
queryAll(".topic-notifications-button .text").text(), query(".topic-notifications-button .text").innerText,
I18n.t("topic.notifications.reasons.3_6_stale"), I18n.t("topic.notifications.reasons.3_6_stale"),
"use _stale notification if user is no longer watching category" "use _stale notification if user is no longer watching category"
); );
}, });
}
);
componentTest("notification reason text - user watching tag", { test("notification reason text - user watching tag", async function (assert) {
template: hbs`
{{topic-notifications-button
notificationLevel=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
this.currentUser.set("watched_tags", ["test"]); this.currentUser.set("watched_tags", ["test"]);
this.set("topic", buildTopic({ level: 3, reason: 10, tags: ["test"] })); this.set("topic", buildTopic({ level: 3, reason: 10, tags: ["test"] }));
},
test(assert) { await render(hbs`
<TopicNotificationsButton
@notificationLevel={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
assert.strictEqual( assert.strictEqual(
queryAll(".topic-notifications-button .text").text(), query(".topic-notifications-button .text").innerText,
I18n.t("topic.notifications.reasons.3_10"), I18n.t("topic.notifications.reasons.3_10"),
"use 3_10 notification if user is still watching tag" "use 3_10 notification if user is still watching tag"
); );
},
}); });
componentTest("notification reason text - user no longer watching tag", { test("notification reason text - user no longer watching tag", async function (assert) {
template: hbs`
{{topic-notifications-button
notificationLevel=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
this.currentUser.set("watched_tags", []); this.currentUser.set("watched_tags", []);
this.set("topic", buildTopic({ level: 3, reason: 10, tags: ["test"] })); this.set("topic", buildTopic({ level: 3, reason: 10, tags: ["test"] }));
},
test(assert) { await render(hbs`
<TopicNotificationsButton
@notificationLevel={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
assert.strictEqual( assert.strictEqual(
queryAll(".topic-notifications-button .text").text(), query(".topic-notifications-button .text").innerText,
I18n.t("topic.notifications.reasons.3_10_stale"), I18n.t("topic.notifications.reasons.3_10_stale"),
"use _stale notification if user is no longer watching tag" "use _stale notification if user is no longer watching tag"
); );
},
}); });
} }
); );

View File

@ -1,9 +1,8 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import I18n from "I18n"; import I18n from "I18n";
import Topic from "discourse/models/topic"; import Topic from "discourse/models/topic";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -29,24 +28,21 @@ function getTranslations(type = "") {
}); });
} }
discourseModule( module(
"Integration | Component | select-kit/topic-notifications-options", "Integration | Component | select-kit/topic-notifications-options",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("regular topic notification level descriptions", { test("regular topic notification level descriptions", async function (assert) {
template: hbs`
{{topic-notifications-options
value=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
this.set("topic", buildTopic("regular")); this.set("topic", buildTopic("regular"));
},
async test(assert) { await render(hbs`
<TopicNotificationsOptions
@value={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
await selectKit().expand(); await selectKit().expand();
const uiTexts = extractDescriptions(selectKit().rows()); const uiTexts = extractDescriptions(selectKit().rows());
@ -57,6 +53,7 @@ discourseModule(
descriptions.length, descriptions.length,
"it has the correct copy" "it has the correct copy"
); );
uiTexts.forEach((text, index) => { uiTexts.forEach((text, index) => {
assert.strictEqual( assert.strictEqual(
text.trim(), text.trim(),
@ -64,22 +61,18 @@ discourseModule(
"it has the correct copy" "it has the correct copy"
); );
}); });
},
}); });
componentTest("PM topic notification level descriptions", { test("PM topic notification level descriptions", async function (assert) {
template: hbs`
{{topic-notifications-options
value=topic.details.notification_level
topic=topic
}}
`,
beforeEach() {
this.set("topic", buildTopic("private_message")); this.set("topic", buildTopic("private_message"));
},
async test(assert) { await render(hbs`
<TopicNotificationsOptions
@value={{this.topic.details.notification_level}}
@topic={{this.topic}}
/>
`);
await selectKit().expand(); await selectKit().expand();
const uiTexts = extractDescriptions(selectKit().rows()); const uiTexts = extractDescriptions(selectKit().rows());
@ -98,7 +91,6 @@ discourseModule(
"it has the correct copy" "it has the correct copy"
); );
}); });
},
}); });
} }
); );

View File

@ -1,43 +1,31 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
discourseModule( module("Integration | Component | select-kit/user-chooser", function (hooks) {
"Integration | Component | select-kit/user-chooser",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("displays usernames", { test("displays usernames", async function (assert) {
template: hbs`{{user-chooser value=value}}`,
beforeEach() {
this.set("value", ["bob", "martin"]); this.set("value", ["bob", "martin"]);
},
async test(assert) { await render(hbs`<UserChooser @value={{this.value}} />`);
assert.strictEqual(this.subject.header().name(), "bob,martin"); assert.strictEqual(this.subject.header().name(), "bob,martin");
},
}); });
componentTest("can remove a username", { test("can remove a username", async function (assert) {
template: hbs`{{user-chooser value=value}}`,
beforeEach() {
this.set("value", ["bob", "martin"]); this.set("value", ["bob", "martin"]);
},
async test(assert) { await render(hbs`<UserChooser @value={{this.value}} />`);
await this.subject.expand(); await this.subject.expand();
await this.subject.deselectItemByValue("bob"); await this.subject.deselectItemByValue("bob");
assert.strictEqual(this.subject.header().name(), "martin"); assert.strictEqual(this.subject.header().name(), "martin");
},
}); });
} });
);

View File

@ -1,3 +1,5 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { import {
blur, blur,
click, click,
@ -5,29 +7,17 @@ import {
render, render,
triggerKeyEvent, triggerKeyEvent,
} from "@ember/test-helpers"; } from "@ember/test-helpers";
import componentTest, { import { count, exists, query } from "discourse/tests/helpers/qunit-helpers";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import {
count,
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { test } from "qunit";
discourseModule("Integration | Component | simple-list", function (hooks) { module("Integration | Component | simple-list", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("adding a value", { test("adding a value", async function (assert) {
template: hbs`{{simple-list values=values}}`,
beforeEach() {
this.set("values", "vinkas\nosama"); this.set("values", "vinkas\nosama");
},
async test(assert) { await render(hbs`<SimpleList @values={{this.values}} />`);
assert.ok( assert.ok(
exists(".add-value-btn[disabled]"), exists(".add-value-btn[disabled]"),
"while loading the + button is disabled" "while loading the + button is disabled"
@ -42,8 +32,9 @@ discourseModule("Integration | Component | simple-list", function (hooks) {
"it adds the value to the list of values" "it adds the value to the list of values"
); );
assert.ok( assert.strictEqual(
query(".values .value[data-index='2'] .value-input").value === "penar", query(".values .value[data-index='2'] .value-input").value,
"penar",
"it sets the correct value for added item" "it sets the correct value for added item"
); );
@ -55,7 +46,6 @@ discourseModule("Integration | Component | simple-list", function (hooks) {
4, 4,
"it adds the value when keying Enter" "it adds the value when keying Enter"
); );
},
}); });
test("changing a value", async function (assert) { test("changing a value", async function (assert) {
@ -67,7 +57,9 @@ discourseModule("Integration | Component | simple-list", function (hooks) {
done(); done();
}); });
await render(hbs`{{simple-list values=values onChange=onChange}}`); await render(
hbs`<SimpleList @values={{this.values}} @onChange={{this.onChange}} />`
);
await fillIn(".values .value[data-index='1'] .value-input", "jarek"); await fillIn(".values .value[data-index='1'] .value-input", "jarek");
await blur(".values .value[data-index='1'] .value-input"); await blur(".values .value[data-index='1'] .value-input");
@ -78,14 +70,11 @@ discourseModule("Integration | Component | simple-list", function (hooks) {
); );
}); });
componentTest("removing a value", { test("removing a value", async function (assert) {
template: hbs`{{simple-list values=values}}`,
beforeEach() {
this.set("values", "vinkas\nosama"); this.set("values", "vinkas\nosama");
},
async test(assert) { await render(hbs`<SimpleList @values={{this.values}} />`);
await click(".values .value[data-index='0'] .remove-value-btn"); await click(".values .value[data-index='0'] .remove-value-btn");
assert.strictEqual( assert.strictEqual(
@ -94,21 +83,20 @@ discourseModule("Integration | Component | simple-list", function (hooks) {
"it removes the value from the list of values" "it removes the value from the list of values"
); );
assert.ok( assert.strictEqual(
query(".values .value[data-index='0'] .value-input").value === "osama", query(".values .value[data-index='0'] .value-input").value,
"osama",
"it removes the correct value" "it removes the correct value"
); );
},
}); });
componentTest("delimiter support", { test("delimiter support", async function (assert) {
template: hbs`{{simple-list values=values inputDelimiter='|'}}`,
beforeEach() {
this.set("values", "vinkas|osama"); this.set("values", "vinkas|osama");
},
async test(assert) { await render(
hbs`<SimpleList @values={{this.values}} @inputDelimiter="|" />`
);
await fillIn(".add-value-input", "eviltrout"); await fillIn(".add-value-input", "eviltrout");
await click(".add-value-btn"); await click(".add-value-btn");
@ -118,11 +106,10 @@ discourseModule("Integration | Component | simple-list", function (hooks) {
"it adds the value to the list of values" "it adds the value to the list of values"
); );
assert.ok( assert.strictEqual(
query(".values .value[data-index='2'] .value-input").value === query(".values .value[data-index='2'] .value-input").value,
"eviltrout", "eviltrout",
"it adds the correct value" "it adds the correct value"
); );
},
}); });
}); });

View File

@ -1,16 +1,11 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render } from "@ember/test-helpers";
import { import { count, exists } from "discourse/tests/helpers/qunit-helpers";
count,
discourseModule,
exists,
} from "discourse/tests/helpers/qunit-helpers";
import pretender from "discourse/tests/helpers/create-pretender"; import pretender from "discourse/tests/helpers/create-pretender";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { click } from "@ember/test-helpers";
discourseModule("Integration | Component | site-header", function (hooks) { module("Integration | Component | site-header", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
@ -18,10 +13,9 @@ discourseModule("Integration | Component | site-header", function (hooks) {
this.currentUser.set("read_first_notification", false); this.currentUser.set("read_first_notification", false);
}); });
componentTest("first notification mask", { test("first notification mask", async function (assert) {
template: hbs`{{site-header}}`, await render(hbs`<SiteHeader />`);
async test(assert) {
assert.strictEqual( assert.strictEqual(
count(".ring-backdrop"), count(".ring-backdrop"),
1, 1,
@ -35,14 +29,13 @@ discourseModule("Integration | Component | site-header", function (hooks) {
!exists(".ring-backdrop"), !exists(".ring-backdrop"),
"it hides the first notification mask" "it hides the first notification mask"
); );
},
}); });
componentTest("do not call authenticated endpoints as anonymous", { test("do not call authenticated endpoints as anonymous", async function (assert) {
template: hbs`{{site-header}}`, this.owner.unregister("current-user:main");
anonymous: true,
await render(hbs`<SiteHeader />`);
async test(assert) {
assert.ok( assert.ok(
!exists(".ring-backdrop"), !exists(".ring-backdrop"),
"there is no first notification mask for anonymous users" "there is no first notification mask for anonymous users"
@ -55,6 +48,5 @@ discourseModule("Integration | Component | site-header", function (hooks) {
// Click anywhere // Click anywhere
await click("header.d-header"); await click("header.d-header");
},
}); });
}); });

View File

@ -0,0 +1,21 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
module("Integration | Component | site-setting", function (hooks) {
setupRenderingTest(hooks);
test("displays host-list setting value", async function (assert) {
this.set("setting", {
setting: "blocked_onebox_domains",
value: "a.com|b.com",
type: "host_list",
});
await render(hbs`<SiteSetting @setting={{this.setting}} />`);
assert.strictEqual(query(".formatted-selection").innerText, "a.com, b.com");
});
});

View File

@ -1,82 +1,62 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { import { count, exists } from "discourse/tests/helpers/qunit-helpers";
count,
discourseModule,
exists,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | slow-mode-info", function (hooks) { module("Integration | Component | slow-mode-info", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("doesn't render if the topic is closed", { test("doesn't render if the topic is closed", async function (assert) {
template: hbs`{{slow-mode-info topic=topic}}`,
beforeEach() {
this.set("topic", { slow_mode_seconds: 3600, closed: true }); this.set("topic", { slow_mode_seconds: 3600, closed: true });
},
test(assert) { await render(hbs`<SlowModeInfo @topic={{this.topic}} />`);
assert.ok(!exists(".slow-mode-heading"), "it doesn't render the notice"); assert.ok(!exists(".slow-mode-heading"), "it doesn't render the notice");
},
}); });
componentTest("doesn't render if the slow mode is disabled", { test("doesn't render if the slow mode is disabled", async function (assert) {
template: hbs`{{slow-mode-info topic=topic}}`,
beforeEach() {
this.set("topic", { slow_mode_seconds: 0, closed: false }); this.set("topic", { slow_mode_seconds: 0, closed: false });
},
test(assert) { await render(hbs`<SlowModeInfo @topic={{this.topic}} />`);
assert.ok(!exists(".slow-mode-heading"), "it doesn't render the notice"); assert.ok(!exists(".slow-mode-heading"), "it doesn't render the notice");
},
}); });
componentTest("renders if slow mode is enabled", { test("renders if slow mode is enabled", async function (assert) {
template: hbs`{{slow-mode-info topic=topic}}`,
beforeEach() {
this.set("topic", { slow_mode_seconds: 3600, closed: false }); this.set("topic", { slow_mode_seconds: 3600, closed: false });
},
test(assert) { await render(hbs`<SlowModeInfo @topic={{this.topic}} />`);
assert.strictEqual(count(".slow-mode-heading"), 1); assert.strictEqual(count(".slow-mode-heading"), 1);
},
}); });
componentTest("staff and TL4 users can disable slow mode", { test("staff and TL4 users can disable slow mode", async function (assert) {
template: hbs`{{slow-mode-info topic=topic user=user}}`,
beforeEach() {
this.setProperties({ this.setProperties({
topic: { slow_mode_seconds: 3600, closed: false }, topic: { slow_mode_seconds: 3600, closed: false },
user: { canManageTopic: true }, user: { canManageTopic: true },
}); });
},
test(assert) { await render(
hbs`<SlowModeInfo @topic={{this.topic}} @user={{this.user}} />`
);
assert.strictEqual(count(".slow-mode-remove"), 1); assert.strictEqual(count(".slow-mode-remove"), 1);
},
}); });
componentTest("regular users can't disable slow mode", { test("regular users can't disable slow mode", async function (assert) {
template: hbs`{{slow-mode-info topic=topic user=user}}`,
beforeEach() {
this.setProperties({ this.setProperties({
topic: { slow_mode_seconds: 3600, closed: false }, topic: { slow_mode_seconds: 3600, closed: false },
user: { canManageTopic: false }, user: { canManageTopic: false },
}); });
},
test(assert) { await render(
hbs`<SlowModeInfo @topic={{this.topic}} @user={{this.user}} />`
);
assert.ok( assert.ok(
!exists(".slow-mode-remove"), !exists(".slow-mode-remove"),
"it doesn't let you disable slow mode" "it doesn't let you disable slow mode"
); );
},
}); });
}); });

View File

@ -0,0 +1,35 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import {
count,
exists,
publishToMessageBus,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import { later } from "@ember/runloop";
module("Integration | Component | software-update-prompt", function (hooks) {
setupRenderingTest(hooks);
test("software-update-prompt gets correct CSS class after messageBus message", async function (assert) {
await render(hbs`{{software-update-prompt}}`);
assert.ok(
!exists("div.software-update-prompt"),
"it does not have the class to show the prompt"
);
publishToMessageBus("/global/asset-version", "somenewversion");
const done = assert.async();
later(() => {
assert.strictEqual(
count("div.software-update-prompt.require-software-refresh"),
1,
"it does have the class to show the prompt"
);
done();
}, 10);
});
});

View File

@ -1,68 +1,46 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { fillIn, render } from "@ember/test-helpers";
import { import { exists, query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
exists,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import I18n from "I18n";
import { fillIn } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import sinon from "sinon"; import sinon from "sinon";
import I18n from "I18n";
discourseModule("Integration | Component | text-field", function (hooks) { module("Integration | Component | text-field", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("renders correctly with no properties set", { test("renders correctly with no properties set", async function (assert) {
template: hbs`{{text-field}}`, await render(hbs`<TextField />`);
test(assert) {
assert.ok(exists("input[type=text]")); assert.ok(exists("input[type=text]"));
},
}); });
componentTest("support a placeholder", { test("support a placeholder", async function (assert) {
template: hbs`{{text-field placeholderKey="placeholder.i18n.key"}}`,
beforeEach() {
sinon.stub(I18n, "t").returnsArg(0); sinon.stub(I18n, "t").returnsArg(0);
},
test(assert) { await render(hbs`<TextField @placeholderKey="placeholder.i18n.key" />`);
assert.ok(exists("input[type=text]")); assert.ok(exists("input[type=text]"));
assert.strictEqual( assert.strictEqual(query("input").placeholder, "placeholder.i18n.key");
queryAll("input").prop("placeholder"),
"placeholder.i18n.key"
);
},
}); });
componentTest("sets the dir attribute to ltr for Hebrew text", { test("sets the dir attribute to ltr for Hebrew text", async function (assert) {
template: hbs`{{text-field value='זהו שם עברי עם מקום עברי'}}`,
beforeEach() {
this.siteSettings.support_mixed_text_direction = true; this.siteSettings.support_mixed_text_direction = true;
},
test(assert) { await render(hbs`<TextField @value="זהו שם עברי עם מקום עברי" />`);
assert.strictEqual(queryAll("input").attr("dir"), "rtl");
}, assert.strictEqual(query("input").getAttribute("dir"), "rtl");
}); });
componentTest("sets the dir attribute to ltr for English text", { test("sets the dir attribute to ltr for English text", async function (assert) {
template: hbs`{{text-field value='This is a ltr title'}}`,
beforeEach() {
this.siteSettings.support_mixed_text_direction = true; this.siteSettings.support_mixed_text_direction = true;
},
test(assert) { await render(hbs`<TextField @value="This is a ltr title" />`);
assert.strictEqual(queryAll("input").attr("dir"), "ltr");
}, assert.strictEqual(query("input").getAttribute("dir"), "ltr");
}); });
componentTest("supports onChange", { test("supports onChange", async function (assert) {
template: hbs`{{text-field class="tf-test" value=value onChange=changed}}`,
beforeEach() {
this.called = false; this.called = false;
this.newValue = null; this.newValue = null;
this.set("value", "hello"); this.set("value", "hello");
@ -70,19 +48,20 @@ discourseModule("Integration | Component | text-field", function (hooks) {
this.newValue = v; this.newValue = v;
this.called = true; this.called = true;
}); });
},
async test(assert) { await render(
hbs`<TextField class="tf-test" @value={{this.value}} @onChange={{this.changed}} />`
);
await fillIn(".tf-test", "hello"); await fillIn(".tf-test", "hello");
assert.ok(!this.called); assert.ok(!this.called);
await fillIn(".tf-test", "new text"); await fillIn(".tf-test", "new text");
assert.ok(this.called); assert.ok(this.called);
assert.strictEqual(this.newValue, "new text"); assert.strictEqual(this.newValue, "new text");
},
}); });
componentTest("supports onChangeImmediate", { test("supports onChangeImmediate", async function (assert) {
template: hbs`{{text-field class="tf-test" value=value onChangeImmediate=changed}}`,
beforeEach() {
this.called = false; this.called = false;
this.newValue = null; this.newValue = null;
this.set("value", "old"); this.set("value", "old");
@ -90,13 +69,16 @@ discourseModule("Integration | Component | text-field", function (hooks) {
this.newValue = v; this.newValue = v;
this.called = true; this.called = true;
}); });
},
async test(assert) { await render(
hbs`<TextField class="tf-test" @value={{this.value}} @onChangeImmediate={{this.changed}} />`
);
await fillIn(".tf-test", "old"); await fillIn(".tf-test", "old");
assert.ok(!this.called); assert.ok(!this.called);
await fillIn(".tf-test", "no longer old"); await fillIn(".tf-test", "no longer old");
assert.ok(this.called); assert.ok(this.called);
assert.strictEqual(this.newValue, "no longer old"); assert.strictEqual(this.newValue, "no longer old");
},
}); });
}); });

View File

@ -1,47 +1,36 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { count, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import I18n from "I18n"; import I18n from "I18n";
import Theme from "admin/models/theme"; import Theme from "admin/models/theme";
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import {
count,
discourseModule,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | themes-list-item", function (hooks) { module("Integration | Component | themes-list-item", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("default theme", {
template: hbs`{{themes-list-item theme=theme}}`,
beforeEach() {
this.set("theme", Theme.create({ name: "Test", default: true }));
},
test(assert) { test("default theme", async function (assert) {
this.set("theme", Theme.create({ name: "Test", default: true }));
await render(hbs`<ThemesListItem @theme={{this.theme}} />`);
assert.expect(1); assert.expect(1);
assert.strictEqual(count(".d-icon-check"), 1, "shows default theme icon"); assert.strictEqual(count(".d-icon-check"), 1, "shows default theme icon");
},
}); });
componentTest("pending updates", { test("pending updates", async function (assert) {
template: hbs`{{themes-list-item theme=theme}}`,
beforeEach() {
this.set( this.set(
"theme", "theme",
Theme.create({ name: "Test", remote_theme: { commits_behind: 6 } }) Theme.create({ name: "Test", remote_theme: { commits_behind: 6 } })
); );
},
test(assert) { await render(hbs`<ThemesListItem @theme={{this.theme}} />`);
assert.expect(1); assert.expect(1);
assert.strictEqual(count(".d-icon-sync"), 1, "shows pending update icon"); assert.strictEqual(count(".d-icon-sync"), 1, "shows pending update icon");
},
}); });
componentTest("broken theme", { test("broken theme", async function (assert) {
template: hbs`{{themes-list-item theme=theme}}`,
beforeEach() {
this.set( this.set(
"theme", "theme",
Theme.create({ Theme.create({
@ -49,22 +38,18 @@ discourseModule("Integration | Component | themes-list-item", function (hooks) {
theme_fields: [{ name: "scss", type_id: 1, error: "something" }], theme_fields: [{ name: "scss", type_id: 1, error: "something" }],
}) })
); );
},
test(assert) { await render(hbs`<ThemesListItem @theme={{this.theme}} />`);
assert.expect(1); assert.expect(1);
assert.strictEqual( assert.strictEqual(
count(".d-icon-exclamation-circle"), count(".d-icon-exclamation-circle"),
1, 1,
"shows broken theme icon" "shows broken theme icon"
); );
},
}); });
componentTest("with children", { test("with children", async function (assert) {
template: hbs`{{themes-list-item theme=theme}}`,
beforeEach() {
this.childrenList = [1, 2, 3, 4, 5].map((num) => this.childrenList = [1, 2, 3, 4, 5].map((num) =>
Theme.create({ name: `Child ${num}`, component: true }) Theme.create({ name: `Child ${num}`, component: true })
); );
@ -77,14 +62,13 @@ discourseModule("Integration | Component | themes-list-item", function (hooks) {
default: true, default: true,
}) })
); );
},
test(assert) { await render(hbs`<ThemesListItem @theme={{this.theme}} />`);
assert.expect(2); assert.expect(2);
assert.deepEqual( assert.deepEqual(
queryAll(".components") query(".components")
.text() .innerText.trim()
.trim()
.split(",") .split(",")
.map((n) => n.trim()) .map((n) => n.trim())
.join(","), .join(","),
@ -95,10 +79,9 @@ discourseModule("Integration | Component | themes-list-item", function (hooks) {
"lists the first 4 children" "lists the first 4 children"
); );
assert.deepEqual( assert.deepEqual(
queryAll(".others-count").text().trim(), query(".others-count").innerText.trim(),
I18n.t("admin.customize.theme.and_x_more", { count: 1 }), I18n.t("admin.customize.theme.and_x_more", { count: 1 }),
"shows count of remaining children" "shows count of remaining children"
); );
},
}); });
}); });

View File

@ -1,17 +1,15 @@
import Theme, { COMPONENTS, THEMES } from "admin/models/theme"; import { module, test } from "qunit";
import I18n from "I18n"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import componentTest, { import { click, fillIn, render } from "@ember/test-helpers";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { import {
count, count,
discourseModule,
exists, exists,
query, query,
queryAll, queryAll,
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { click, fillIn } from "@ember/test-helpers"; import Theme, { COMPONENTS, THEMES } from "admin/models/theme";
import I18n from "I18n";
function createThemes(itemsCount, customAttributesCallback) { function createThemes(itemsCount, customAttributesCallback) {
return [...Array(itemsCount)].map((_, i) => { return [...Array(itemsCount)].map((_, i) => {
@ -23,11 +21,10 @@ function createThemes(itemsCount, customAttributesCallback) {
}); });
} }
discourseModule("Integration | Component | themes-list", function (hooks) { module("Integration | Component | themes-list", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("current tab is themes", {
template: hbs`{{themes-list themes=themes components=components currentTab=currentTab}}`, test("current tab is themes", async function (assert) {
beforeEach() {
this.themes = createThemes(5); this.themes = createThemes(5);
this.components = createThemes(5, (n) => { this.components = createThemes(5, (n) => {
return { return {
@ -42,23 +39,24 @@ discourseModule("Integration | Component | themes-list", function (hooks) {
components: this.components, components: this.components,
currentTab: THEMES, currentTab: THEMES,
}); });
},
test(assert) { await render(
hbs`<ThemesList @themes={{this.themes}} @components={{this.components}} @currentTab={{this.currentTab}} />`
);
assert.strictEqual( assert.strictEqual(
queryAll(".themes-tab").hasClass("active"), query(".themes-tab").classList.contains("active"),
true, true,
"themes tab is active" "themes tab is active"
); );
assert.strictEqual( assert.strictEqual(
queryAll(".components-tab").hasClass("active"), query(".components-tab").classList.contains("active"),
false, false,
"components tab is not active" "components tab is not active"
); );
assert.strictEqual( assert.notOk(
queryAll(".inactive-indicator").index(), exists(".inactive-indicator"),
-1,
"there is no inactive themes separator when all themes are inactive" "there is no inactive themes separator when all themes are inactive"
); );
assert.strictEqual(count(".themes-list-item"), 5, "displays all themes"); assert.strictEqual(count(".themes-list-item"), 5, "displays all themes");
@ -82,9 +80,8 @@ discourseModule("Integration | Component | themes-list", function (hooks) {
this.themes.forEach((theme) => theme.set("user_selectable", true)); this.themes.forEach((theme) => theme.set("user_selectable", true));
this.set("themes", this.themes); this.set("themes", this.themes);
assert.strictEqual( assert.notOk(
queryAll(".inactive-indicator").index(), exists(".inactive-indicator"),
-1,
"there is no inactive themes separator when all themes are user-selectable" "there is no inactive themes separator when all themes are user-selectable"
); );
@ -95,16 +92,13 @@ discourseModule("Integration | Component | themes-list", function (hooks) {
"shows one entry with a message when there is nothing to display" "shows one entry with a message when there is nothing to display"
); );
assert.strictEqual( assert.strictEqual(
queryAll(".themes-list-item span.empty").text().trim(), query(".themes-list-item span.empty").innerText.trim(),
I18n.t("admin.customize.theme.empty"), I18n.t("admin.customize.theme.empty"),
"displays the right message" "displays the right message"
); );
},
}); });
componentTest("current tab is components", { test("current tab is components", async function (assert) {
template: hbs`{{themes-list themes=themes components=components currentTab=currentTab}}`,
beforeEach() {
this.themes = createThemes(5); this.themes = createThemes(5);
this.components = createThemes(5, (n) => { this.components = createThemes(5, (n) => {
return { return {
@ -119,25 +113,23 @@ discourseModule("Integration | Component | themes-list", function (hooks) {
components: this.components, components: this.components,
currentTab: COMPONENTS, currentTab: COMPONENTS,
}); });
},
test(assert) { await render(
hbs`<ThemesList @themes={{this.themes}} @components={{this.components}} @currentTab={{this.currentTab}} />`
);
assert.strictEqual( assert.strictEqual(
queryAll(".components-tab").hasClass("active"), query(".components-tab").classList.contains("active"),
true, true,
"components tab is active" "components tab is active"
); );
assert.strictEqual( assert.strictEqual(
queryAll(".themes-tab").hasClass("active"), query(".themes-tab").classList.contains("active"),
false, false,
"themes tab is not active" "themes tab is not active"
); );
assert.strictEqual( assert.notOk(exists(".inactive-indicator"), "there is no separator");
queryAll(".inactive-indicator").index(),
-1,
"there is no separator"
);
assert.strictEqual( assert.strictEqual(
count(".themes-list-item"), count(".themes-list-item"),
5, 5,
@ -151,40 +143,30 @@ discourseModule("Integration | Component | themes-list", function (hooks) {
"shows one entry with a message when there is nothing to display" "shows one entry with a message when there is nothing to display"
); );
assert.strictEqual( assert.strictEqual(
queryAll(".themes-list-item span.empty").text().trim(), query(".themes-list-item span.empty").innerText.trim(),
I18n.t("admin.customize.theme.empty"), I18n.t("admin.customize.theme.empty"),
"displays the right message" "displays the right message"
); );
},
}); });
componentTest( test("themes filter is not visible when there are less than 10 themes", async function (assert) {
"themes filter is not visible when there are less than 10 themes",
{
template: hbs`{{themes-list themes=themes components=[] currentTab=currentTab}}`,
beforeEach() {
const themes = createThemes(9); const themes = createThemes(9);
this.setProperties({ this.setProperties({
themes, themes,
currentTab: THEMES, currentTab: THEMES,
}); });
},
async test(assert) { await render(
hbs`<ThemesList @themes={{this.themes}} components=[] @currentTab={{this.currentTab}} />`
);
assert.ok( assert.ok(
!exists(".themes-list-filter"), !exists(".themes-list-filter"),
"filter input not shown when we have fewer than 10 themes" "filter input not shown when we have fewer than 10 themes"
); );
}, });
}
);
componentTest( test("themes filter keeps themes whose names include the filter term", async function (assert) {
"themes filter keeps themes whose names include the filter term",
{
template: hbs`{{themes-list themes=themes components=[] currentTab=currentTab}}`,
beforeEach() {
const themes = ["osama", "OsAmaa", "osAMA 1234"] const themes = ["osama", "OsAmaa", "osAMA 1234"]
.map((name) => Theme.create({ name: `Theme ${name}` })) .map((name) => Theme.create({ name: `Theme ${name}` }))
.concat(createThemes(7)); .concat(createThemes(7));
@ -192,8 +174,11 @@ discourseModule("Integration | Component | themes-list", function (hooks) {
themes, themes,
currentTab: THEMES, currentTab: THEMES,
}); });
},
async test(assert) { await render(
hbs`<ThemesList @themes={{this.themes}} components=[] @currentTab={{this.currentTab}} />`
);
assert.ok(exists(".themes-list-filter")); assert.ok(exists(".themes-list-filter"));
await fillIn(".themes-list-filter .filter-input", " oSAma "); await fillIn(".themes-list-filter .filter-input", " oSAma ");
assert.deepEqual( assert.deepEqual(
@ -203,16 +188,9 @@ discourseModule("Integration | Component | themes-list", function (hooks) {
["Theme osama", "Theme OsAmaa", "Theme osAMA 1234"], ["Theme osama", "Theme OsAmaa", "Theme osAMA 1234"],
"only themes whose names include the filter term are shown" "only themes whose names include the filter term are shown"
); );
}, });
}
);
componentTest( test("switching between themes and components tabs keeps the filter visible only if both tabs have at least 10 items", async function (assert) {
"switching between themes and components tabs keeps the filter visible only if both tabs have at least 10 items",
{
template: hbs`{{themes-list themes=themes components=components currentTab=currentTab}}`,
beforeEach() {
const themes = createThemes(10, (n) => { const themes = createThemes(10, (n) => {
return { name: `Theme ${n}${n}` }; return { name: `Theme ${n}${n}` };
}); });
@ -229,8 +207,11 @@ discourseModule("Integration | Component | themes-list", function (hooks) {
components, components,
currentTab: THEMES, currentTab: THEMES,
}); });
},
async test(assert) { await render(
hbs`<ThemesList @themes={{this.themes}} @components={{this.components}} @currentTab={{this.currentTab}} />`
);
await fillIn(".themes-list-filter .filter-input", "11"); await fillIn(".themes-list-filter .filter-input", "11");
assert.strictEqual( assert.strictEqual(
query(".themes-list-container").textContent.trim(), query(".themes-list-container").textContent.trim(),
@ -289,7 +270,5 @@ discourseModule("Integration | Component | themes-list", function (hooks) {
"Theme 66", "Theme 66",
"filter term persisted between tabs because both have more than 10 items" "filter term persisted between tabs because both have more than 10 items"
); );
}, });
}
);
}); });

View File

@ -1,7 +1,6 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -9,51 +8,45 @@ function setTime(time) {
this.setProperties(time); this.setProperties(time);
} }
discourseModule("Integration | Component | time-input", function (hooks) { module("Integration | Component | time-input", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
this.set("subject", selectKit()); this.set("subject", selectKit());
}); });
componentTest("default", { test("default", async function (assert) {
template: hbs`{{time-input hours=hours minutes=minutes}}`,
beforeEach() {
this.setProperties({ hours: "14", minutes: "58" }); this.setProperties({ hours: "14", minutes: "58" });
},
test(assert) { await render(
hbs`<TimeInput @hours={{this.hours}} @minutes={{this.minutes}} />`
);
assert.strictEqual(this.subject.header().name(), "14:58"); assert.strictEqual(this.subject.header().name(), "14:58");
},
}); });
componentTest("prevents mutations", { test("prevents mutations", async function (assert) {
template: hbs`{{time-input hours=hours minutes=minutes}}`,
beforeEach() {
this.setProperties({ hours: "14", minutes: "58" }); this.setProperties({ hours: "14", minutes: "58" });
},
async test(assert) { await render(
hbs`<TimeInput @hours={{this.hours}} @minutes={{this.minutes}} />`
);
await this.subject.expand(); await this.subject.expand();
await this.subject.selectRowByIndex(3); await this.subject.selectRowByIndex(3);
assert.strictEqual(this.subject.header().name(), "14:58"); assert.strictEqual(this.subject.header().name(), "14:58");
},
}); });
componentTest("allows mutations through actions", { test("allows mutations through actions", async function (assert) {
template: hbs`{{time-input hours=hours minutes=minutes onChange=onChange}}`,
beforeEach() {
this.setProperties({ hours: "14", minutes: "58" }); this.setProperties({ hours: "14", minutes: "58" });
this.set("onChange", setTime); this.set("onChange", setTime);
},
async test(assert) { await render(
hbs`<TimeInput @hours={{this.hours}} @minutes={{this.minutes}} @onChange={{this.onChange}} />`
);
await this.subject.expand(); await this.subject.expand();
await this.subject.selectRowByIndex(3); await this.subject.selectRowByIndex(3);
assert.strictEqual(this.subject.header().name(), "00:45"); assert.strictEqual(this.subject.header().name(), "00:45");
},
}); });
}); });

View File

@ -1,8 +1,7 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render } from "@ember/test-helpers";
import { import {
discourseModule,
exists, exists,
fakeTime, fakeTime,
query, query,
@ -10,15 +9,10 @@ import {
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import I18n from "I18n"; import I18n from "I18n";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { click } from "@ember/test-helpers";
discourseModule( module("Integration | Component | time-shortcut-picker", function (hooks) {
"Integration | Component | time-shortcut-picker",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
const template = hbs`{{time-shortcut-picker _itsatrap=itsatrap}}`;
hooks.beforeEach(function () { hooks.beforeEach(function () {
const itsatrapStub = { const itsatrapStub = {
bind: () => {}, bind: () => {},
@ -29,21 +23,16 @@ discourseModule(
}); });
hooks.afterEach(function () { hooks.afterEach(function () {
if (this.clock) { this.clock?.restore();
this.clock.restore();
}
}); });
componentTest("shows default options", { test("shows default options", async function (assert) {
template,
beforeEach() {
this.siteSettings.suggest_weekends_in_date_pickers = true; this.siteSettings.suggest_weekends_in_date_pickers = true;
const tuesday = "2100-06-08T08:00:00"; const tuesday = "2100-06-08T08:00:00";
this.clock = fakeTime(tuesday, this.currentUser.timezone, true); this.clock = fakeTime(tuesday, this.currentUser.timezone, true);
},
async test(assert) { await render(hbs`<TimeShortcutPicker @_itsatrap={{this.itsatrap}} />`);
const expected = [ const expected = [
I18n.t("time_shortcut.later_today"), I18n.t("time_shortcut.later_today"),
I18n.t("time_shortcut.tomorrow"), I18n.t("time_shortcut.tomorrow"),
@ -62,170 +51,126 @@ discourseModule(
); );
assert.deepEqual(options, expected); assert.deepEqual(options, expected);
},
}); });
componentTest("show 'Later This Week' if today is < Thursday", { test("show 'Later This Week' if today is < Thursday", async function (assert) {
template,
beforeEach() {
const monday = "2100-06-07T08:00:00"; const monday = "2100-06-07T08:00:00";
this.clock = fakeTime(monday, this.currentUser.timezone, true); this.clock = fakeTime(monday, this.currentUser.timezone, true);
},
test(assert) { await render(hbs`<TimeShortcutPicker @_itsatrap={{this.itsatrap}} />`);
assert.ok(
exists("#tap_tile_later_this_week"), assert.ok(exists("#tap_tile_later_this_week"), "it has later this week");
"it has later this week"
);
},
}); });
componentTest("does not show 'Later This Week' if today is >= Thursday", { test("does not show 'Later This Week' if today is >= Thursday", async function (assert) {
template,
beforeEach() {
const thursday = "2100-06-10T08:00:00"; const thursday = "2100-06-10T08:00:00";
this.clock = fakeTime(thursday, this.currentUser.timezone, true); this.clock = fakeTime(thursday, this.currentUser.timezone, true);
},
test(assert) { await render(hbs`<TimeShortcutPicker @_itsatrap={{this.itsatrap}} />`);
assert.notOk( assert.notOk(
exists("#tap_tile_later_this_week"), exists("#tap_tile_later_this_week"),
"it does not have later this week" "it does not have later this week"
); );
},
}); });
componentTest("does not show 'Later Today' if 'Later Today' is tomorrow", { test("does not show 'Later Today' if 'Later Today' is tomorrow", async function (assert) {
template,
beforeEach() {
this.clock = fakeTime( this.clock = fakeTime(
"2100-12-11T22:00:00", // + 3 hours is tomorrow "2100-12-11T22:00:00", // + 3 hours is tomorrow
this.currentUser.timezone, this.currentUser.timezone,
true true
); );
},
test(assert) { await render(hbs`<TimeShortcutPicker @_itsatrap={{this.itsatrap}} />`);
assert.notOk( assert.notOk(
exists("#tap_tile_later_today"), exists("#tap_tile_later_today"),
"it does not have later today" "it does not have later today"
); );
},
}); });
componentTest("shows 'Later Today' if it is before 5pm", { test("shows 'Later Today' if it is before 5pm", async function (assert) {
template,
beforeEach() {
this.clock = fakeTime( this.clock = fakeTime(
"2100-12-11T16:50:00", "2100-12-11T16:50:00",
this.currentUser.timezone, this.currentUser.timezone,
true true
); );
},
test(assert) { await render(hbs`<TimeShortcutPicker @_itsatrap={{this.itsatrap}} />`);
assert.ok(exists("#tap_tile_later_today"), "it does have later today"); assert.ok(exists("#tap_tile_later_today"), "it does have later today");
},
}); });
componentTest("does not show 'Later Today' if it is after 5pm", { test("does not show 'Later Today' if it is after 5pm", async function (assert) {
template,
beforeEach() {
this.clock = fakeTime( this.clock = fakeTime(
"2100-12-11T17:00:00", "2100-12-11T17:00:00",
this.currentUser.timezone, this.currentUser.timezone,
true true
); );
},
test(assert) { await render(hbs`<TimeShortcutPicker @_itsatrap={{this.itsatrap}} />`);
assert.notOk( assert.notOk(
exists("#tap_tile_later_today"), exists("#tap_tile_later_today"),
"it does not have later today" "it does not have later today"
); );
},
}); });
componentTest("defaults to 08:00 for custom time", { test("defaults to 08:00 for custom time", async function (assert) {
template, await render(hbs`<TimeShortcutPicker @_itsatrap={{this.itsatrap}} />`);
async test(assert) {
await click("#tap_tile_custom"); await click("#tap_tile_custom");
assert.strictEqual(query("#custom-time").value, "08:00"); assert.strictEqual(query("#custom-time").value, "08:00");
},
}); });
componentTest("shows 'Next Monday' instead of 'Monday' on Sundays", { test("shows 'Next Monday' instead of 'Monday' on Sundays", async function (assert) {
template,
beforeEach() {
const sunday = "2100-01-24T08:00:00"; const sunday = "2100-01-24T08:00:00";
this.clock = fakeTime(sunday, this.currentUser.timezone, true); this.clock = fakeTime(sunday, this.currentUser.timezone, true);
},
async test(assert) { await render(hbs`<TimeShortcutPicker @_itsatrap={{this.itsatrap}} />`);
assert.equal(
query("#tap_tile_start_of_next_business_week .tap-tile-title") assert.strictEqual(
.innerText, query("#tap_tile_start_of_next_business_week .tap-tile-title").innerText,
"Next Monday" "Next Monday"
); );
assert.equal( assert.strictEqual(
query("div#tap_tile_start_of_next_business_week div.tap-tile-date") query("div#tap_tile_start_of_next_business_week div.tap-tile-date")
.innerText, .innerText,
"Feb 1, 8:00 am" "Feb 1, 8:00 am"
); );
},
}); });
componentTest("shows 'Next Monday' instead of 'Monday' on Mondays", { test("shows 'Next Monday' instead of 'Monday' on Mondays", async function (assert) {
template,
beforeEach() {
const monday = "2100-01-25T08:00:00"; const monday = "2100-01-25T08:00:00";
this.clock = fakeTime(monday, this.currentUser.timezone, true); this.clock = fakeTime(monday, this.currentUser.timezone, true);
},
async test(assert) { await render(hbs`<TimeShortcutPicker @_itsatrap={{this.itsatrap}} />`);
assert.equal(
query("#tap_tile_start_of_next_business_week .tap-tile-title") assert.strictEqual(
.innerText, query("#tap_tile_start_of_next_business_week .tap-tile-title").innerText,
"Next Monday" "Next Monday"
); );
assert.equal( assert.strictEqual(
query("div#tap_tile_start_of_next_business_week div.tap-tile-date") query("div#tap_tile_start_of_next_business_week div.tap-tile-date")
.innerText, .innerText,
"Feb 1, 8:00 am" "Feb 1, 8:00 am"
); );
},
}); });
componentTest( test("the 'Next Month' option points to the first day of the next month", async function (assert) {
"the 'Next Month' option points to the first day of the next month",
{
template,
beforeEach() {
this.clock = fakeTime( this.clock = fakeTime(
"2100-01-01T08:00:00", "2100-01-01T08:00:00",
this.currentUser.timezone, this.currentUser.timezone,
true true
); );
},
async test(assert) { await render(hbs`<TimeShortcutPicker @_itsatrap={{this.itsatrap}} />`);
assert.strictEqual( assert.strictEqual(
query("div#tap_tile_next_month div.tap-tile-date").innerText, query("div#tap_tile_next_month div.tap-tile-date").innerText,
"Feb 1, 8:00 am" "Feb 1, 8:00 am"
); );
}, });
} });
);
}
);

View File

@ -1,29 +1,14 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { import { queryAll } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import Topic from "discourse/models/topic"; import Topic from "discourse/models/topic";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | topic-list-item", function (hooks) { module("Integration | Component | topic-list-item", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("checkbox is rendered checked if topic is in selected array", { test("checkbox is rendered checked if topic is in selected array", async function (assert) {
template: hbs`{{topic-list-item
topic=topic
bulkSelectEnabled=true
selected=selected
}}
{{topic-list-item
topic=topic2
bulkSelectEnabled=true
selected=selected
}}`,
beforeEach() {
const topic = Topic.create({ id: 24234 }); const topic = Topic.create({ id: 24234 });
const topic2 = Topic.create({ id: 24235 }); const topic2 = Topic.create({ id: 24235 });
this.setProperties({ this.setProperties({
@ -31,12 +16,22 @@ discourseModule("Integration | Component | topic-list-item", function (hooks) {
topic2, topic2,
selected: [topic], selected: [topic],
}); });
},
async test(assert) { await render(hbs`
<TopicListItem
@topic={{this.topic}}
@bulkSelectEnabled={{true}}
@selected={{this.selected}}
/>
<TopicListItem
@topic={{this.topic2}}
@bulkSelectEnabled={{true}}
@selected={{this.selected}}
/>
`);
const checkboxes = queryAll("input.bulk-select"); const checkboxes = queryAll("input.bulk-select");
assert.ok(checkboxes[0].checked); assert.ok(checkboxes[0].checked);
assert.ok(!checkboxes[1].checked); assert.ok(!checkboxes[1].checked);
},
}); });
}); });

View File

@ -1,30 +1,15 @@
import { click } from "@ember/test-helpers"; import { module, test } from "qunit";
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest, import { click, render } from "@ember/test-helpers";
} from "discourse/tests/helpers/component-test";
import { discourseModule } from "discourse/tests/helpers/qunit-helpers";
import Topic from "discourse/models/topic"; import Topic from "discourse/models/topic";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | topic-list", function (hooks) { module("Integration | Component | topic-list", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("bulk select", { test("bulk select", async function (assert) {
template: hbs`{{topic-list
canBulkSelect=true
toggleBulkSelect=toggleBulkSelect
bulkSelectEnabled=bulkSelectEnabled
autoAddTopicsToBulkSelect=autoAddTopicsToBulkSelect
updateAutoAddTopicsToBulkSelect=updateAutoAddTopicsToBulkSelect
topics=topics
selected=selected
}}`,
beforeEach() {
const topic = Topic.create({ id: 24234 });
const topic2 = Topic.create({ id: 24235 });
this.setProperties({ this.setProperties({
topics: [topic, topic2], topics: [Topic.create({ id: 24234 }), Topic.create({ id: 24235 })],
selected: [], selected: [],
bulkSelectEnabled: false, bulkSelectEnabled: false,
autoAddTopicsToBulkSelect: false, autoAddTopicsToBulkSelect: false,
@ -37,9 +22,19 @@ discourseModule("Integration | Component | topic-list", function (hooks) {
this.set("autoAddTopicsToBulkSelect", newVal); this.set("autoAddTopicsToBulkSelect", newVal);
}, },
}); });
},
async test(assert) { await render(hbs`
<TopicList
@canBulkSelect={{true}}
@toggleBulkSelect={{this.toggleBulkSelect}}
@bulkSelectEnabled={{this.bulkSelectEnabled}}
@autoAddTopicsToBulkSelect={{this.autoAddTopicsToBulkSelect}}
@updateAutoAddTopicsToBulkSelect={{this.updateAutoAddTopicsToBulkSelect}}
@topics={{this.topics}}
@selected={{this.selected}}
/>
`);
assert.strictEqual(this.selected.length, 0, "defaults to 0"); assert.strictEqual(this.selected.length, 0, "defaults to 0");
await click("button.bulk-select"); await click("button.bulk-select");
assert.ok(this.bulkSelectEnabled, "bulk select is enabled"); assert.ok(this.bulkSelectEnabled, "bulk select is enabled");
@ -65,6 +60,5 @@ discourseModule("Integration | Component | topic-list", function (hooks) {
!this.autoAddTopicsToBulkSelect, !this.autoAddTopicsToBulkSelect,
"clicking Clear All turns off the autoAddTopicsToBulkSelect flag" "clicking Clear All turns off the autoAddTopicsToBulkSelect flag"
); );
},
}); });
}); });

View File

@ -1,25 +1,17 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render } from "@ember/test-helpers";
import { import { count, exists } from "discourse/tests/helpers/qunit-helpers";
count,
discourseModule,
exists,
} from "discourse/tests/helpers/qunit-helpers";
import { click } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule( module("Integration | Component | uppy-image-uploader", function (hooks) {
"Integration | Component | uppy-image-uploader",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("with image", { test("with image", async function (assert) {
template: hbs` await render(hbs`
{{uppy-image-uploader id="test-uppy-image-uploader" imageUrl='/images/avatar.png' placeholderUrl='/not/used.png'}} <UppyImageUploader @id="test-uppy-image-uploader" @imageUrl="/images/avatar.png" @placeholderUrl="/not/used.png" />
`, `);
async test(assert) {
assert.strictEqual( assert.strictEqual(
count(".d-icon-far-image"), count(".d-icon-far-image"),
1, 1,
@ -44,13 +36,11 @@ discourseModule(
1, 1,
"it displays the image lightbox" "it displays the image lightbox"
); );
},
}); });
componentTest("without image", { test("without image", async function (assert) {
template: hbs`{{uppy-image-uploader id="test-uppy-image-uploader"}}`, await render(hbs`<UppyImageUploader @id="test-uppy-image-uploader" />`);
test(assert) {
assert.strictEqual( assert.strictEqual(
count(".d-icon-far-image"), count(".d-icon-far-image"),
1, 1,
@ -66,13 +56,13 @@ discourseModule(
!exists(".image-uploader-lightbox-btn"), !exists(".image-uploader-lightbox-btn"),
"it does not display the button to open image lightbox" "it does not display the button to open image lightbox"
); );
},
}); });
componentTest("with placeholder", { test("with placeholder", async function (assert) {
template: hbs`{{uppy-image-uploader id="test-uppy-image-uploader" placeholderUrl='/images/avatar.png'}}`, await render(
hbs`<UppyImageUploader @id="test-uppy-image-uploader" @placeholderUrl="/images/avatar.png" />`
);
test(assert) {
assert.strictEqual( assert.strictEqual(
count(".d-icon-far-image"), count(".d-icon-far-image"),
1, 1,
@ -94,7 +84,5 @@ discourseModule(
1, 1,
"it displays the placeholder image" "it displays the placeholder image"
); );
},
}); });
} });
);

View File

@ -1,11 +1,7 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { import { exists, query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
exists,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { resetFlair } from "discourse/lib/avatar-flair"; import { resetFlair } from "discourse/lib/avatar-flair";
@ -42,115 +38,94 @@ function setupSiteGroups(that) {
]; ];
} }
discourseModule( module("Integration | Component | user-avatar-flair", function (hooks) {
"Integration | Component | user-avatar-flair",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("avatar flair for admin user", { hooks.beforeEach(function () {
template: hbs`{{user-avatar-flair user=args}}`,
beforeEach() {
resetFlair(); resetFlair();
});
hooks.afterEach(function () {
resetFlair();
});
test("avatar flair for admin user", async function (assert) {
this.set("args", { this.set("args", {
admin: true, admin: true,
moderator: false, moderator: false,
trust_level: 2, trust_level: 2,
}); });
setupSiteGroups(this); setupSiteGroups(this);
},
afterEach() { await render(hbs`<UserAvatarFlair @user={{this.args}} />`);
resetFlair();
},
test(assert) {
assert.ok(exists(".avatar-flair"), "it has the tag"); assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-bars"), "it has the svg icon"); assert.ok(exists("svg.d-icon-bars"), "it has the svg icon");
assert.strictEqual( assert.strictEqual(
queryAll(".avatar-flair").attr("style"), query(".avatar-flair").getAttribute("style"),
"background-color: #CC000A; color: #FFFFFA; ", "background-color: #CC000A; color: #FFFFFA; ",
"it has styles" "it has styles"
); );
},
}); });
componentTest("avatar flair for moderator user with fallback to staff", { test("avatar flair for moderator user with fallback to staff", async function (assert) {
template: hbs`{{user-avatar-flair user=args}}`,
beforeEach() {
resetFlair();
this.set("args", { this.set("args", {
admin: false, admin: false,
moderator: true, moderator: true,
trust_level: 2, trust_level: 2,
}); });
setupSiteGroups(this); setupSiteGroups(this);
},
afterEach() { await render(hbs`<UserAvatarFlair @user={{this.args}} />`);
resetFlair();
},
test(assert) {
assert.ok(exists(".avatar-flair"), "it has the tag"); assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-bars"), "it has the svg icon"); assert.ok(exists("svg.d-icon-bars"), "it has the svg icon");
assert.strictEqual( assert.strictEqual(
queryAll(".avatar-flair").attr("style"), query(".avatar-flair").getAttribute("style"),
"background-color: #CC0005; color: #FFFFF5; ", "background-color: #CC0005; color: #FFFFF5; ",
"it has styles" "it has styles"
); );
},
}); });
componentTest("avatar flair for trust level", { test("avatar flair for trust level", async function (assert) {
template: hbs`{{user-avatar-flair user=args}}`,
beforeEach() {
resetFlair();
this.set("args", { this.set("args", {
admin: false, admin: false,
moderator: false, moderator: false,
trust_level: 2, trust_level: 2,
}); });
setupSiteGroups(this); setupSiteGroups(this);
},
afterEach() { await render(hbs`<UserAvatarFlair @user={{this.args}} />`);
resetFlair();
},
test(assert) {
assert.ok(exists(".avatar-flair"), "it has the tag"); assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-dice-two"), "it has the svg icon"); assert.ok(exists("svg.d-icon-dice-two"), "it has the svg icon");
assert.strictEqual( assert.strictEqual(
queryAll(".avatar-flair").attr("style"), query(".avatar-flair").getAttribute("style"),
"background-color: #CC0002; color: #FFFFF2; ", "background-color: #CC0002; color: #FFFFF2; ",
"it has styles" "it has styles"
); );
},
}); });
componentTest("avatar flair for trust level with fallback", { test("avatar flair for trust level with fallback", async function (assert) {
template: hbs`{{user-avatar-flair user=args}}`,
beforeEach() {
resetFlair();
this.set("args", { this.set("args", {
admin: false, admin: false,
moderator: false, moderator: false,
trust_level: 3, trust_level: 3,
}); });
setupSiteGroups(this); setupSiteGroups(this);
},
afterEach() { await render(hbs`<UserAvatarFlair @user={{this.args}} />`);
resetFlair();
},
test(assert) {
assert.ok(exists(".avatar-flair"), "it has the tag"); assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-dice-two"), "it has the svg icon"); assert.ok(exists("svg.d-icon-dice-two"), "it has the svg icon");
assert.strictEqual( assert.strictEqual(
queryAll(".avatar-flair").attr("style"), query(".avatar-flair").getAttribute("style"),
"background-color: #CC0002; color: #FFFFF2; ", "background-color: #CC0002; color: #FFFFF2; ",
"it has styles" "it has styles"
); );
},
}); });
componentTest("avatar flair for login-required site, before login", { test("avatar flair for login-required site, before login", async function (assert) {
template: hbs`{{user-avatar-flair user=args}}`,
beforeEach() {
resetFlair();
this.set("args", { this.set("args", {
admin: false, admin: false,
moderator: false, moderator: false,
@ -158,19 +133,13 @@ discourseModule(
}); });
// Groups not serialized for anon on login_required // Groups not serialized for anon on login_required
this.site.groups = undefined; this.site.groups = undefined;
},
afterEach() { await render(hbs`<UserAvatarFlair @user={{this.args}} />`);
resetFlair();
},
test(assert) {
assert.ok(!exists(".avatar-flair"), "it does not render a flair"); assert.ok(!exists(".avatar-flair"), "it does not render a flair");
},
}); });
componentTest("avatar flair for primary group flair", { test("avatar flair for primary group flair", async function (assert) {
template: hbs`{{user-avatar-flair user=args}}`,
beforeEach() {
resetFlair();
this.set("args", { this.set("args", {
admin: false, admin: false,
moderator: false, moderator: false,
@ -182,37 +151,27 @@ discourseModule(
primary_group_name: "Band Geeks", primary_group_name: "Band Geeks",
}); });
setupSiteGroups(this); setupSiteGroups(this);
},
afterEach() { await render(hbs`<UserAvatarFlair @user={{this.args}} />`);
resetFlair();
},
test(assert) {
assert.ok(exists(".avatar-flair"), "it has the tag"); assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-times"), "it has the svg icon"); assert.ok(exists("svg.d-icon-times"), "it has the svg icon");
assert.strictEqual( assert.strictEqual(
queryAll(".avatar-flair").attr("style"), query(".avatar-flair").getAttribute("style"),
"background-color: #123456; color: #B0B0B0; ", "background-color: #123456; color: #B0B0B0; ",
"it has styles" "it has styles"
); );
},
}); });
componentTest("user-avatar-flair for user with no flairs", { test("user-avatar-flair for user with no flairs", async function (assert) {
template: hbs`{{user-avatar-flair user=args}}`,
beforeEach() {
resetFlair();
this.set("args", { this.set("args", {
admin: false, admin: false,
moderator: false, moderator: false,
trust_level: 1, trust_level: 1,
}); });
},
afterEach() { await render(hbs`<UserAvatarFlair @user={{this.args}} />`);
resetFlair();
},
test(assert) {
assert.ok(!exists(".avatar-flair"), "it does not render a flair"); assert.ok(!exists(".avatar-flair"), "it does not render a flair");
},
}); });
} });
);

View File

@ -1,71 +1,53 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { import { exists, query } from "discourse/tests/helpers/qunit-helpers";
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
discourseModule("Integration | Component | user-info", function (hooks) { module("Integration | Component | user-info", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("prioritized name", { test("prioritized name", async function (assert) {
template: hbs`{{user-info user=currentUser}}`,
beforeEach() {
this.siteSettings.prioritize_username_in_ux = false; this.siteSettings.prioritize_username_in_ux = false;
this.currentUser.name = "Evil Trout"; this.currentUser.name = "Evil Trout";
},
async test(assert) { await render(hbs`<UserInfo @user={{this.currentUser}} />`);
assert.equal(query(".name.bold").innerText.trim(), "Evil Trout");
assert.equal(query(".username.margin").innerText.trim(), "eviltrout"); assert.strictEqual(query(".name.bold").innerText.trim(), "Evil Trout");
}, assert.strictEqual(query(".username.margin").innerText.trim(), "eviltrout");
}); });
componentTest("prioritized username", { test("prioritized username", async function (assert) {
template: hbs`{{user-info user=currentUser}}`,
beforeEach() {
this.siteSettings.prioritize_username_in_ux = true; this.siteSettings.prioritize_username_in_ux = true;
this.currentUser.name = "Evil Trout"; this.currentUser.name = "Evil Trout";
},
async test(assert) { await render(hbs`<UserInfo @user={{this.currentUser}} />`);
assert.equal(query(".username.bold").innerText.trim(), "eviltrout");
assert.equal(query(".name.margin").innerText.trim(), "Evil Trout"); assert.strictEqual(query(".username.bold").innerText.trim(), "eviltrout");
}, assert.strictEqual(query(".name.margin").innerText.trim(), "Evil Trout");
}); });
componentTest("includeLink", { test("includeLink", async function (assert) {
template: hbs`{{user-info user=currentUser includeLink=includeLink}}`, await render(
hbs`<UserInfo @user={{this.currentUser}} @includeLink={{this.includeLink}} />`
);
async test(assert) {
this.set("includeLink", true); this.set("includeLink", true);
assert.ok(exists(`.username a[href="/u/${this.currentUser.username}"]`)); assert.ok(exists(`.username a[href="/u/${this.currentUser.username}"]`));
this.set("includeLink", false); this.set("includeLink", false);
assert.notOk(exists(`.username a[href="/u/${this.currentUser.username}"]`));
assert.notOk(
exists(`.username a[href="/u/${this.currentUser.username}"]`)
);
},
}); });
componentTest("includeAvatar", { test("includeAvatar", async function (assert) {
template: hbs`{{user-info user=currentUser includeAvatar=includeAvatar}}`, await render(
hbs`<UserInfo @user={{this.currentUser}} @includeAvatar={{this.includeAvatar}} />`
);
async test(assert) {
this.set("includeAvatar", true); this.set("includeAvatar", true);
assert.ok(exists(".user-image")); assert.ok(exists(".user-image"));
this.set("includeAvatar", false); this.set("includeAvatar", false);
assert.notOk(exists(".user-image")); assert.notOk(exists(".user-image"));
},
}); });
}); });

View File

@ -1,7 +1,7 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { render } from "@ember/test-helpers";
import { discourseModule, query } from "discourse/tests/helpers/qunit-helpers"; import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
function paste(element, text) { function paste(element, text) {
@ -10,17 +10,16 @@ function paste(element, text) {
element.dispatchEvent(e); element.dispatchEvent(e);
} }
discourseModule("Integration | Component | user-selector", function (hooks) { module("Integration | Component | user-selector", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("pasting a list of usernames", { test("pasting a list of usernames", async function (assert) {
template: hbs`{{user-selector usernames=usernames class="test-selector"}}`,
beforeEach() {
this.set("usernames", "evil,trout"); this.set("usernames", "evil,trout");
},
test(assert) { await render(
hbs`<UserSelector @usernames={{this.usernames}} class="test-selector" />`
);
let element = query(".test-selector"); let element = query(".test-selector");
assert.strictEqual(this.get("usernames"), "evil,trout"); assert.strictEqual(this.get("usernames"), "evil,trout");
@ -40,21 +39,18 @@ discourseModule("Integration | Component | user-selector", function (hooks) {
this.set("usernames", null); this.set("usernames", null);
paste(element, "eviltrout\nsam\ncodinghorror"); paste(element, "eviltrout\nsam\ncodinghorror");
assert.strictEqual(this.get("usernames"), "eviltrout,sam,codinghorror"); assert.strictEqual(this.get("usernames"), "eviltrout,sam,codinghorror");
},
}); });
componentTest("excluding usernames", { test("excluding usernames", async function (assert) {
template: hbs`{{user-selector usernames=usernames excludedUsernames=excludedUsernames class="test-selector"}}`,
beforeEach() {
this.set("usernames", "mark"); this.set("usernames", "mark");
this.set("excludedUsernames", ["jeff", "sam", "robin"]); this.set("excludedUsernames", ["jeff", "sam", "robin"]);
},
test(assert) { await render(
hbs`<UserSelector @usernames={{this.usernames}} @excludedUsernames={{this.excludedUsernames}} class="test-selector" />`
);
let element = query(".test-selector"); let element = query(".test-selector");
paste(element, "roman,penar,jeff,robin"); paste(element, "roman,penar,jeff,robin");
assert.strictEqual(this.get("usernames"), "mark,roman,penar"); assert.strictEqual(this.get("usernames"), "mark,roman,penar");
},
}); });
}); });

View File

@ -1,26 +1,18 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { blur, click, fillIn, render } from "@ember/test-helpers";
import { import { count, query } from "discourse/tests/helpers/qunit-helpers";
count,
discourseModule,
query,
} from "discourse/tests/helpers/qunit-helpers";
import { blur, click, fillIn } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
discourseModule("Integration | Component | value-list", function (hooks) { module("Integration | Component | value-list", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("adding a value", { test("adding a value", async function (assert) {
template: hbs`{{value-list values=values}}`,
beforeEach() {
this.set("values", "vinkas\nosama"); this.set("values", "vinkas\nosama");
},
async test(assert) { await render(hbs`<ValueList @values={{this.values}} />`);
await selectKit().expand(); await selectKit().expand();
await selectKit().fillInFilter("eviltrout"); await selectKit().fillInFilter("eviltrout");
await selectKit().keyboard("Enter"); await selectKit().keyboard("Enter");
@ -31,22 +23,18 @@ discourseModule("Integration | Component | value-list", function (hooks) {
"it adds the value to the list of values" "it adds the value to the list of values"
); );
assert.deepEqual( assert.strictEqual(
this.values, this.values,
"vinkas\nosama\neviltrout", "vinkas\nosama\neviltrout",
"it adds the value to the list of values" "it adds the value to the list of values"
); );
},
}); });
componentTest("changing a value", { test("changing a value", async function (assert) {
template: hbs`{{value-list values=values}}`,
beforeEach() {
this.set("values", "vinkas\nosama"); this.set("values", "vinkas\nosama");
},
async test(assert) { await render(hbs`<ValueList @values={{this.values}} />`);
await fillIn(".values .value[data-index='1'] .value-input", "jarek"); await fillIn(".values .value[data-index='1'] .value-input", "jarek");
await blur(".values .value[data-index='1'] .value-input"); await blur(".values .value[data-index='1'] .value-input");
@ -55,17 +43,13 @@ discourseModule("Integration | Component | value-list", function (hooks) {
"jarek" "jarek"
); );
assert.deepEqual(this.values, "vinkas\njarek", "updates the value list"); assert.deepEqual(this.values, "vinkas\njarek", "updates the value list");
},
}); });
componentTest("removing a value", { test("removing a value", async function (assert) {
template: hbs`{{value-list values=values}}`,
beforeEach() {
this.set("values", "vinkas\nosama"); this.set("values", "vinkas\nosama");
},
async test(assert) { await render(hbs`<ValueList @values={{this.values}} />`);
await click(".values .value[data-index='0'] .remove-value-btn"); await click(".values .value[data-index='0'] .remove-value-btn");
assert.strictEqual( assert.strictEqual(
@ -78,25 +62,23 @@ discourseModule("Integration | Component | value-list", function (hooks) {
await selectKit().expand(); await selectKit().expand();
assert.ok( assert.strictEqual(
query(".select-kit-collection li.select-kit-row span.name") query(".select-kit-collection li.select-kit-row span.name").innerText,
.innerText === "vinkas", "vinkas",
"it adds the removed value to choices" "it adds the removed value to choices"
); );
},
}); });
componentTest("selecting a value", { test("selecting a value", async function (assert) {
template: hbs`{{value-list values=values choices=choices}}`,
beforeEach() {
this.setProperties({ this.setProperties({
values: "vinkas\nosama", values: "vinkas\nosama",
choices: ["maja", "michael"], choices: ["maja", "michael"],
}); });
},
async test(assert) { await render(
hbs`<ValueList @values={{this.values}} @choices={{this.choices}} />`
);
await selectKit().expand(); await selectKit().expand();
await selectKit().selectRowByValue("maja"); await selectKit().selectRowByValue("maja");
@ -106,22 +88,18 @@ discourseModule("Integration | Component | value-list", function (hooks) {
"it adds the value to the list of values" "it adds the value to the list of values"
); );
assert.deepEqual( assert.strictEqual(
this.values, this.values,
"vinkas\nosama\nmaja", "vinkas\nosama\nmaja",
"it adds the value to the list of values" "it adds the value to the list of values"
); );
},
}); });
componentTest("array support", { test("array support", async function (assert) {
template: hbs`{{value-list values=values inputType='array'}}`,
beforeEach() {
this.set("values", ["vinkas", "osama"]); this.set("values", ["vinkas", "osama"]);
},
async test(assert) { await render(hbs`<ValueList @values={{this.values}} @inputType="array" />`);
this.set("values", ["vinkas", "osama"]); this.set("values", ["vinkas", "osama"]);
await selectKit().expand(); await selectKit().expand();
@ -139,17 +117,15 @@ discourseModule("Integration | Component | value-list", function (hooks) {
["vinkas", "osama", "eviltrout"], ["vinkas", "osama", "eviltrout"],
"it adds the value to the list of values" "it adds the value to the list of values"
); );
},
}); });
componentTest("delimiter support", { test("delimiter support", async function (assert) {
template: hbs`{{value-list values=values inputDelimiter='|'}}`,
beforeEach() {
this.set("values", "vinkas|osama"); this.set("values", "vinkas|osama");
},
async test(assert) { await render(
hbs`<ValueList @values={{this.values}} @inputDelimiter="|" />`
);
await selectKit().expand(); await selectKit().expand();
await selectKit().fillInFilter("eviltrout"); await selectKit().fillInFilter("eviltrout");
await selectKit().keyboard("Enter"); await selectKit().keyboard("Enter");
@ -160,11 +136,10 @@ discourseModule("Integration | Component | value-list", function (hooks) {
"it adds the value to the list of values" "it adds the value to the list of values"
); );
assert.deepEqual( assert.strictEqual(
this.values, this.values,
"vinkas|osama|eviltrout", "vinkas|osama|eviltrout",
"it adds the value to the list of values" "it adds the value to the list of values"
); );
},
}); });
}); });

View File

@ -1,17 +1,11 @@
import componentTest, { import { module, test } from "qunit";
setupRenderingTest, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
} from "discourse/tests/helpers/component-test"; import { click, render, waitFor } from "@ember/test-helpers";
import { import { createFile } from "discourse/tests/helpers/qunit-helpers";
createFile,
discourseModule,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import pretender, { response } from "discourse/tests/helpers/create-pretender"; import pretender, { response } from "discourse/tests/helpers/create-pretender";
import { click, waitFor } from "@ember/test-helpers";
discourseModule( module("Integration | Component | watched-word-uploader", function (hooks) {
"Integration | Component | watched-word-uploader",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () { hooks.beforeEach(function () {
@ -20,18 +14,11 @@ discourseModule(
}); });
}); });
componentTest("sets the proper action key on uploads", { test("sets the proper action key on uploads", async function (assert) {
template: hbs`{{watched-word-uploader
id="watched-word-uploader"
actionKey=actionNameKey
done=doneUpload
}}`,
async test(assert) {
const done = assert.async(); const done = assert.async();
this.set("actionNameKey", "flag"); this.set("actionNameKey", "flag");
this.set("doneUpload", function () { this.set("doneUpload", function () {
assert.equal( assert.strictEqual(
Object.entries(this._uppyInstance.getState().files)[0][1].meta Object.entries(this._uppyInstance.getState().files)[0][1].meta
.action_key, .action_key,
"flag" "flag"
@ -39,13 +26,20 @@ discourseModule(
done(); done();
}); });
await render(hbs`
<WatchedWordUploader
@id="watched-word-uploader"
@actionKey={{this.actionNameKey}}
@done={{this.doneUpload}}
/>
`);
const words = createFile("watched-words.txt"); const words = createFile("watched-words.txt");
await this.container await this.container
.lookup("service:app-events") .lookup("service:app-events")
.trigger("upload-mixin:watched-word-uploader:add-files", words); .trigger("upload-mixin:watched-word-uploader:add-files", words);
await waitFor(".bootbox span.d-button-label"); await waitFor(".bootbox span.d-button-label");
await click(".bootbox span.d-button-label"); await click(".bootbox span.d-button-label");
},
}); });
} });
);

View File

@ -0,0 +1,32 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { count } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
module("Integration | Component | Widget | actions-summary", function (hooks) {
setupRenderingTest(hooks);
test("post deleted", async function (assert) {
this.set("args", {
deleted_at: "2016-01-01",
deletedByUsername: "eviltrout",
deletedByAvatarTemplate: "/images/avatar.png",
});
await render(
hbs`<MountWidget @widget="actions-summary" @args={{this.args}} />`
);
assert.strictEqual(
count(".post-action .d-icon-far-trash-alt"),
1,
"it has the deleted icon"
);
assert.strictEqual(
count(".avatar[title=eviltrout]"),
1,
"it has the deleted by avatar"
);
});
});

View File

@ -0,0 +1,42 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
module("Integration | Component | Widget | avatar-flair", function (hooks) {
setupRenderingTest(hooks);
test("avatar flair with an icon", async function (assert) {
this.set("args", {
flair_url: "fa-bars",
flair_bg_color: "CC0000",
flair_color: "FFFFFF",
});
await render(
hbs`<MountWidget @widget="avatar-flair" @args={{this.args}} />`
);
assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-bars"), "it has the svg icon");
assert.strictEqual(
query(".avatar-flair").getAttribute("style"),
"background-color: #CC0000; color: #FFFFFF; ",
"it has styles"
);
});
test("avatar flair with an image", async function (assert) {
this.set("args", {
flair_url: "/images/avatar.png",
});
await render(
hbs`<MountWidget @widget="avatar-flair" @args={{this.args}} />`
);
assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(!exists("svg"), "it does not have an svg icon");
});
});

View File

@ -0,0 +1,66 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
module("Integration | Component | Widget | button", function (hooks) {
setupRenderingTest(hooks);
test("icon only button", async function (assert) {
this.set("args", { icon: "far-smile" });
await render(hbs`<MountWidget @widget="button" @args={{this.args}} />`);
assert.ok(exists("button.btn.btn-icon.no-text"), "it has all the classes");
assert.ok(exists("button .d-icon.d-icon-far-smile"), "it has the icon");
});
test("icon and text button", async function (assert) {
this.set("args", { icon: "plus", label: "topic.create" });
await render(hbs`<MountWidget @widget="button" @args={{this.args}} />`);
assert.ok(exists("button.btn.btn-icon-text"), "it has all the classes");
assert.ok(exists("button .d-icon.d-icon-plus"), "it has the icon");
assert.ok(exists("button span.d-button-label"), "it has the label");
});
test("emoji and text button", async function (assert) {
this.set("args", { emoji: "mega", label: "topic.create" });
await render(hbs`<MountWidget @widget="button" @args={{this.args}} />`);
assert.ok(exists("button.widget-button"), "renders the widget");
assert.ok(exists("button img.emoji"), "it renders the emoji");
assert.ok(exists("button span.d-button-label"), "it renders the label");
});
test("text only button", async function (assert) {
this.set("args", { label: "topic.create" });
await render(hbs`<MountWidget @widget="button" @args={{this.args}} />`);
assert.ok(exists("button.btn.btn-text"), "it has all the classes");
assert.ok(exists("button span.d-button-label"), "it has the label");
});
test("translatedLabel", async function (assert) {
this.set("args", { translatedLabel: "foo bar" });
await render(hbs`<MountWidget @widget="button" @args={{this.args}} />`);
assert.strictEqual(
query("button span.d-button-label").innerText,
"foo bar"
);
});
test("translatedTitle", async function (assert) {
this.set("args", { label: "topic.create", translatedTitle: "foo bar" });
await render(hbs`<MountWidget @widget="button" @args={{this.args}} />`);
assert.strictEqual(query("button").title, "foo bar");
});
});

View File

@ -0,0 +1,62 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render, triggerEvent } from "@ember/test-helpers";
import { count, exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import pretender, { response } from "discourse/tests/helpers/create-pretender";
import EmberObject from "@ember/object";
module(
"Integration | Component | Widget | default-notification-item",
function (hooks) {
setupRenderingTest(hooks);
test("sets notification as read on middle click", async function (assert) {
this.set(
"args",
EmberObject.create({
id: 3,
user_id: 1,
notification_type: 6,
read: false,
created_at: "2020-01-01T12:00:00.000Z",
post_number: 1,
topic_id: 10,
fancy_title: "Greetings!",
slug: "greetings",
data: {
topic_title: "Greetings!",
original_post_id: 14,
original_post_type: 1,
original_username: "discobot",
revision_number: null,
display_username: "discobot",
},
})
);
await render(
hbs`<MountWidget @widget="default-notification-item" @args={{this.args}} />`
);
let requests = 0;
pretender.put("/notifications/mark-read", (request) => {
++requests;
assert.strictEqual(
request.requestBody,
`id=${this.args.id}`,
"it sets correct request parameters"
);
return response({ success: true });
});
assert.ok(!exists("li.read"));
await triggerEvent("li", "mouseup", { button: 1, which: 2 });
assert.strictEqual(count("li.read"), 1);
assert.strictEqual(requests, 1);
});
}
);

View File

@ -0,0 +1,213 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { count, exists, queryAll } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import { NotificationLevels } from "discourse/lib/notification-levels";
const topCategoryIds = [2, 3, 1];
let mutedCategoryIds = [];
let unreadCategoryIds = [];
let categoriesByCount = [];
module("Integration | Component | Widget | hamburger-menu", function (hooks) {
setupRenderingTest(hooks);
test("prioritize faq", async function (assert) {
this.siteSettings.faq_url = "http://example.com/faq";
this.currentUser.set("read_faq", false);
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".faq-priority"));
assert.ok(!exists(".faq-link"));
});
test("prioritize faq - user has read", async function (assert) {
this.siteSettings.faq_url = "http://example.com/faq";
this.currentUser.set("read_faq", true);
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(!exists(".faq-priority"));
assert.ok(exists(".faq-link"));
});
test("staff menu - not staff", async function (assert) {
this.currentUser.set("staff", false);
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(!exists(".admin-link"));
});
test("staff menu - moderator", async function (assert) {
this.currentUser.set("moderator", true);
this.currentUser.set("can_review", true);
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".admin-link"));
assert.ok(exists(".review"));
assert.ok(!exists(".settings-link"));
});
test("staff menu - admin", async function (assert) {
this.currentUser.setProperties({ admin: true });
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".settings-link"));
});
test("logged in links", async function (assert) {
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".new-topics-link"));
assert.ok(exists(".unread-topics-link"));
});
test("general links", async function (assert) {
this.owner.unregister("current-user:main");
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(!exists("li[class='']"));
assert.ok(exists(".latest-topics-link"));
assert.ok(!exists(".new-topics-link"));
assert.ok(!exists(".unread-topics-link"));
assert.ok(exists(".top-topics-link"));
assert.ok(exists(".badge-link"));
assert.ok(exists(".category-link"));
assert.ok(exists(".about-link"));
assert.ok(exists(".keyboard-shortcuts-link"));
});
let maxCategoriesToDisplay;
test("top categories - anonymous", async function (assert) {
this.owner.unregister("current-user:main");
this.siteSettings.header_dropdown_category_count = 8;
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.strictEqual(count(".category-link"), 8);
assert.deepEqual(
[...queryAll(".category-link .category-name")].map((el) => el.innerText),
this.site
.get("categoriesByCount")
.slice(0, 8)
.map((c) => c.name)
);
});
test("top categories - allow_uncategorized_topics", async function (assert) {
this.owner.unregister("current-user:main");
this.siteSettings.allow_uncategorized_topics = false;
this.siteSettings.header_dropdown_category_count = 8;
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.strictEqual(count(".category-link"), 8);
assert.deepEqual(
[...queryAll(".category-link .category-name")].map((el) => el.innerText),
this.site
.get("categoriesByCount")
.filter((c) => c.name !== "uncategorized")
.slice(0, 8)
.map((c) => c.name)
);
});
test("top categories", async function (assert) {
this.siteSettings.header_dropdown_category_count = 8;
maxCategoriesToDisplay = this.siteSettings.header_dropdown_category_count;
categoriesByCount = this.site.get("categoriesByCount").slice();
categoriesByCount.every((c) => {
if (!topCategoryIds.includes(c.id)) {
if (mutedCategoryIds.length === 0) {
mutedCategoryIds.push(c.id);
c.set("notification_level", NotificationLevels.MUTED);
} else if (unreadCategoryIds.length === 0) {
unreadCategoryIds.push(c.id);
for (let i = 0; i < 5; i++) {
c.topicTrackingState.modifyState(123 + i, {
category_id: c.id,
last_read_post_number: 1,
highest_post_number: 2,
notification_level: NotificationLevels.TRACKING,
unread_not_too_old: true,
});
}
} else {
unreadCategoryIds.splice(0, 0, c.id);
for (let i = 0; i < 10; i++) {
c.topicTrackingState.modifyState(321 + i, {
category_id: c.id,
last_read_post_number: null,
created_in_new_period: true,
});
}
return false;
}
}
return true;
});
this.currentUser.set("top_category_ids", topCategoryIds);
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.strictEqual(
count(".category-link"),
maxCategoriesToDisplay,
"categories displayed limited by header_dropdown_category_count"
);
categoriesByCount = categoriesByCount.filter(
(c) => !mutedCategoryIds.includes(c.id)
);
let ids = [
...unreadCategoryIds,
...topCategoryIds,
...categoriesByCount.map((c) => c.id),
]
.uniq()
.slice(0, maxCategoriesToDisplay);
assert.deepEqual(
[...queryAll(".category-link .category-name")].map((el) => el.innerText),
ids.map(
(id) => categoriesByCount.find((category) => category.id === id).name
),
"top categories are in the correct order"
);
});
test("badges link - disabled", async function (assert) {
this.siteSettings.enable_badges = false;
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(!exists(".badge-link"));
});
test("badges link", async function (assert) {
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".badge-link"));
});
test("user directory link", async function (assert) {
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(exists(".user-directory-link"));
});
test("user directory link - disabled", async function (assert) {
this.siteSettings.enable_user_directory = false;
await render(hbs`<MountWidget @widget="hamburger-menu" />`);
assert.ok(!exists(".user-directory-link"));
});
});

View File

@ -0,0 +1,85 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { click, render } from "@ember/test-helpers";
import { exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
module("Integration | Component | Widget | header", function (hooks) {
setupRenderingTest(hooks);
test("rendering basics", async function (assert) {
await render(hbs`<MountWidget @widget="header" />`);
assert.ok(exists("header.d-header"));
assert.ok(exists("#site-logo"));
});
test("sign up / login buttons", async function (assert) {
this.owner.unregister("current-user:main");
this.set("args", { canSignUp: true });
this.set("showCreateAccount", () => (this.signupShown = true));
this.set("showLogin", () => (this.loginShown = true));
await render(hbs`
<MountWidget
@widget="header"
@showCreateAccount={{this.showCreateAccount}}
@showLogin={{this.showLogin}}
@args={{this.args}}
/>
`);
assert.ok(exists("button.sign-up-button"));
assert.ok(exists("button.login-button"));
await click("button.sign-up-button");
assert.ok(this.signupShown);
await click("button.login-button");
assert.ok(this.loginShown);
});
test("anon when login required", async function (assert) {
this.owner.unregister("current-user:main");
this.set("args", { canSignUp: true });
this.set("showCreateAccount", () => (this.signupShown = true));
this.set("showLogin", () => (this.loginShown = true));
this.siteSettings.login_required = true;
await render(hbs`
<MountWidget
@widget="header"
@showCreateAccount={{this.showCreateAccount}}
@showLogin={{this.showLogin}}
@args={{this.args}}
/>
`);
assert.ok(exists("button.login-button"));
assert.ok(exists("button.sign-up-button"));
assert.ok(!exists("#search-button"));
assert.ok(!exists("#toggle-hamburger-menu"));
});
test("logged in when login required", async function (assert) {
this.set("args", { canSignUp: true });
this.set("showCreateAccount", () => (this.signupShown = true));
this.set("showLogin", () => (this.loginShown = true));
this.siteSettings.login_required = true;
await render(hbs`
<MountWidget
@widget="header"
@showCreateAccount={{this.showCreateAccount}}
@showLogin={{this.showLogin}}
@args={{this.args}}
/>
`);
assert.ok(!exists("button.login-button"));
assert.ok(!exists("button.sign-up-button"));
assert.ok(exists("#search-button"));
assert.ok(exists("#toggle-hamburger-menu"));
assert.ok(exists("#current-user"));
});
});

View File

@ -0,0 +1,194 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { count, exists, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import Session from "discourse/models/session";
const bigLogo = "/images/d-logo-sketch.png?test";
const smallLogo = "/images/d-logo-sketch-small.png?test";
const mobileLogo = "/images/d-logo-sketch.png?mobile";
const darkLogo = "/images/d-logo-sketch.png?dark";
const title = "Cool Forum";
const prefersDark = "(prefers-color-scheme: dark)";
module("Integration | Component | Widget | home-logo", function (hooks) {
setupRenderingTest(hooks);
hooks.afterEach(function () {
Session.currentProp("darkModeAvailable", null);
Session.currentProp("defaultColorSchemeIsDark", null);
});
test("basics", async function (assert) {
this.siteSettings.site_logo_url = bigLogo;
this.siteSettings.site_logo_small_url = smallLogo;
this.siteSettings.title = title;
this.set("args", { minimized: false });
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(count(".title"), 1);
assert.strictEqual(count("img#site-logo.logo-big"), 1);
assert.strictEqual(query("#site-logo").getAttribute("src"), bigLogo);
assert.strictEqual(query("#site-logo").getAttribute("alt"), title);
});
test("basics - minimized", async function (assert) {
this.siteSettings.site_logo_url = bigLogo;
this.siteSettings.site_logo_small_url = smallLogo;
this.siteSettings.title = title;
this.set("args", { minimized: true });
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(count("img.logo-small"), 1);
assert.strictEqual(query("img.logo-small").getAttribute("src"), smallLogo);
assert.strictEqual(query("img.logo-small").getAttribute("alt"), title);
assert.strictEqual(query("img.logo-small").getAttribute("width"), "36");
});
test("no logo", async function (assert) {
this.siteSettings.site_logo_url = "";
this.siteSettings.site_logo_small_url = "";
this.siteSettings.title = title;
this.set("args", { minimized: false });
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(count("h1#site-text-logo.text-logo"), 1);
assert.strictEqual(query("#site-text-logo").innerText, title);
});
test("no logo - minimized", async function (assert) {
this.siteSettings.site_logo_url = "";
this.siteSettings.site_logo_small_url = "";
this.siteSettings.title = title;
this.set("args", { minimized: true });
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(count(".d-icon-home"), 1);
});
test("mobile logo", async function (assert) {
this.siteSettings.site_mobile_logo_url = mobileLogo;
this.siteSettings.site_logo_small_url = smallLogo;
this.site.mobileView = true;
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(count("img#site-logo.logo-mobile"), 1);
assert.strictEqual(query("#site-logo").getAttribute("src"), mobileLogo);
});
test("mobile without logo", async function (assert) {
this.siteSettings.site_logo_url = bigLogo;
this.site.mobileView = true;
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(count("img#site-logo.logo-big"), 1);
assert.strictEqual(query("#site-logo").getAttribute("src"), bigLogo);
});
test("logo with dark mode alternative", async function (assert) {
this.siteSettings.site_logo_url = bigLogo;
this.siteSettings.site_logo_dark_url = darkLogo;
Session.currentProp("darkModeAvailable", true);
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(count("img#site-logo.logo-big"), 1);
assert.strictEqual(query("#site-logo").getAttribute("src"), bigLogo);
assert.strictEqual(
query("picture source").getAttribute("media"),
prefersDark,
"includes dark mode media attribute"
);
assert.strictEqual(
query("picture source").getAttribute("srcset"),
darkLogo,
"includes dark mode alternative logo source"
);
});
test("mobile logo with dark mode alternative", async function (assert) {
this.siteSettings.site_logo_url = bigLogo;
this.siteSettings.site_mobile_logo_url = mobileLogo;
this.siteSettings.site_mobile_logo_dark_url = darkLogo;
Session.currentProp("darkModeAvailable", true);
this.site.mobileView = true;
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(query("#site-logo").getAttribute("src"), mobileLogo);
assert.strictEqual(
query("picture source").getAttribute("media"),
prefersDark,
"includes dark mode media attribute"
);
assert.strictEqual(
query("picture source").getAttribute("srcset"),
darkLogo,
"includes dark mode alternative logo source"
);
});
test("dark mode enabled but no dark logo set", async function (assert) {
this.siteSettings.site_logo_url = bigLogo;
this.siteSettings.site_logo_dark_url = "";
Session.currentProp("darkModeAvailable", true);
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(count("img#site-logo.logo-big"), 1);
assert.strictEqual(query("#site-logo").getAttribute("src"), bigLogo);
assert.ok(!exists("picture"), "does not include alternative logo");
});
test("dark logo set but no dark mode", async function (assert) {
this.siteSettings.site_logo_url = bigLogo;
this.siteSettings.site_logo_dark_url = darkLogo;
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(count("img#site-logo.logo-big"), 1);
assert.strictEqual(query("#site-logo").getAttribute("src"), bigLogo);
assert.ok(!exists("picture"), "does not include alternative logo");
});
test("dark color scheme and dark logo set", async function (assert) {
this.siteSettings.site_logo_url = bigLogo;
this.siteSettings.site_logo_dark_url = darkLogo;
Session.currentProp("defaultColorSchemeIsDark", true);
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(count("img#site-logo.logo-big"), 1);
assert.strictEqual(
query("#site-logo").getAttribute("src"),
darkLogo,
"uses dark logo"
);
assert.ok(!exists("picture"), "does not add dark mode alternative");
});
test("dark color scheme and dark logo not set", async function (assert) {
this.siteSettings.site_logo_url = bigLogo;
this.siteSettings.site_logo_dark_url = "";
Session.currentProp("defaultColorSchemeIsDark", true);
await render(hbs`<MountWidget @widget="home-logo" @args={{this.args}} />`);
assert.strictEqual(count("img#site-logo.logo-big"), 1);
assert.strictEqual(
query("#site-logo").getAttribute("src"),
bigLogo,
"uses regular logo on dark scheme if no dark logo"
);
});
});

View File

@ -0,0 +1,85 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { click, render } from "@ember/test-helpers";
import { count } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
module("Integration | Component | Widget | post-links", function (hooks) {
setupRenderingTest(hooks);
test("duplicate links", async function (assert) {
this.set("args", {
id: 2,
links: [
{
title: "Evil Trout Link",
url: "http://eviltrout.com",
reflection: true,
},
{
title: "Evil Trout Link",
url: "http://dupe.eviltrout.com",
reflection: true,
},
],
});
await render(hbs`<MountWidget @widget="post-links" @args={{this.args}} />`);
assert.strictEqual(
count(".post-links a.track-link"),
1,
"it hides the dupe link"
);
});
test("collapsed links", async function (assert) {
this.set("args", {
id: 1,
links: [
{
title: "Link 1",
url: "http://eviltrout.com?1",
reflection: true,
},
{
title: "Link 2",
url: "http://eviltrout.com?2",
reflection: true,
},
{
title: "Link 3",
url: "http://eviltrout.com?3",
reflection: true,
},
{
title: "Link 4",
url: "http://eviltrout.com?4",
reflection: true,
},
{
title: "Link 5",
url: "http://eviltrout.com?5",
reflection: true,
},
{
title: "Link 6",
url: "http://eviltrout.com?6",
reflection: true,
},
{
title: "Link 7",
url: "http://eviltrout.com?7",
reflection: true,
},
],
});
await render(hbs`<MountWidget @widget="post-links" @args={{this.args}} />`);
assert.strictEqual(count(".expand-links"), 1, "collapsed by default");
await click("a.expand-links");
assert.strictEqual(count(".post-links a.track-link"), 7);
});
});

View File

@ -0,0 +1,78 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { count, exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import { resetPostMenuExtraButtons } from "discourse/widgets/post-menu";
import { withPluginApi } from "discourse/lib/plugin-api";
module("Integration | Component | Widget | post-menu", function (hooks) {
setupRenderingTest(hooks);
hooks.afterEach(function () {
resetPostMenuExtraButtons();
});
test("add extra button", async function (assert) {
this.set("args", {});
withPluginApi("0.14.0", (api) => {
api.addPostMenuButton("coffee", () => {
return {
action: "drinkCoffee",
icon: "coffee",
className: "hot-coffee",
title: "coffee.title",
position: "first",
};
});
});
await render(hbs`<MountWidget @widget="post-menu" @args={{this.args}} />`);
assert.strictEqual(
count(".actions .extra-buttons .hot-coffee"),
1,
"It renders extra button"
);
});
test("removes button based on callback", async function (assert) {
this.set("args", { canCreatePost: true, canRemoveReply: true });
withPluginApi("0.14.0", (api) => {
api.removePostMenuButton("reply", (attrs) => {
return attrs.canRemoveReply;
});
});
await render(hbs`<MountWidget @widget="post-menu" @args={{this.args}} />`);
assert.ok(!exists(".actions .reply"), "it removes reply button");
});
test("does not remove button", async function (assert) {
this.set("args", { canCreatePost: true, canRemoveReply: false });
withPluginApi("0.14.0", (api) => {
api.removePostMenuButton("reply", (attrs) => {
return attrs.canRemoveReply;
});
});
await render(hbs`<MountWidget @widget="post-menu" @args={{this.args}} />`);
assert.ok(exists(".actions .reply"), "it does not remove reply button");
});
test("removes button", async function (assert) {
this.set("args", { canCreatePost: true });
withPluginApi("0.14.0", (api) => {
api.removePostMenuButton("reply");
});
await render(hbs`<MountWidget @widget="post-menu" @args={{this.args}} />`);
assert.ok(!exists(".actions .reply"), "it removes reply button");
});
});

View File

@ -0,0 +1,93 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
module(
"Integration | Component | Widget | post-small-action",
function (hooks) {
setupRenderingTest(hooks);
test("does not have delete/edit/recover buttons by default", async function (assert) {
this.set("args", { id: 123 });
await render(
hbs`<MountWidget @widget="post-small-action" @args={{this.args}} />`
);
assert.ok(!exists(".small-action-desc > .small-action-delete"));
assert.ok(!exists(".small-action-desc > .small-action-recover"));
assert.ok(!exists(".small-action-desc > .small-action-edit"));
});
test("shows edit button if canEdit", async function (assert) {
this.set("args", { id: 123, canEdit: true });
await render(
hbs`<MountWidget @widget="post-small-action" @args={{this.args}} />`
);
assert.ok(
exists(".small-action-desc > .small-action-edit"),
"it adds the edit small action button"
);
});
test("uses custom widget if actionDescriptionWidget", async function (assert) {
this.set("args", { id: 123, actionDescriptionWidget: "button" });
await render(
hbs`<MountWidget @widget="post-small-action" @args={{this.args}} />`
);
assert.ok(
exists(".small-action .widget-button"),
"it adds the custom widget"
);
});
test("does not show edit button if canRecover even if canEdit", async function (assert) {
this.set("args", { id: 123, canEdit: true, canRecover: true });
await render(
hbs`<MountWidget @widget="post-small-action" @args={{this.args}} />`
);
assert.ok(
!exists(".small-action-desc > .small-action-edit"),
"it does not add the edit small action button"
);
assert.ok(
exists(".small-action-desc > .small-action-recover"),
"it adds the recover small action button"
);
});
test("shows delete button if canDelete", async function (assert) {
this.set("args", { id: 123, canDelete: true });
await render(
hbs`<MountWidget @widget="post-small-action" @args={{this.args}} />`
);
assert.ok(
exists(".small-action-desc > .small-action-delete"),
"it adds the delete small action button"
);
});
test("shows undo button if canRecover", async function (assert) {
this.set("args", { id: 123, canRecover: true });
await render(
hbs`<MountWidget @widget="post-small-action" @args={{this.args}} />`
);
assert.ok(
exists(".small-action-desc > .small-action-recover"),
"it adds the recover small action button"
);
});
}
);

View File

@ -0,0 +1,154 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { count } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import Post from "discourse/models/post";
import Topic from "discourse/models/topic";
function postStreamTest(name, attrs) {
test(name, async function (assert) {
const site = this.container.lookup("site:main");
let posts = attrs.posts.call(this);
posts.forEach((p) => p.set("site", site));
this.set("posts", posts);
await render(
hbs`<MountWidget @widget="post-stream" @args={{hash posts=this.posts}} />`
);
attrs.test.call(this, assert);
});
}
module("Integration | Component | Widget | post-stream", function (hooks) {
setupRenderingTest(hooks);
postStreamTest("basics", {
posts() {
const site = this.container.lookup("site:main");
const topic = Topic.create();
topic.set("details.created_by", { id: 123 });
return [
Post.create({
topic,
id: 1,
post_number: 1,
user_id: 123,
primary_group_name: "trout",
avatar_template: "/images/avatar.png",
}),
Post.create({
topic,
id: 2,
post_number: 2,
post_type: site.get("post_types.moderator_action"),
}),
Post.create({ topic, id: 3, post_number: 3, hidden: true }),
Post.create({
topic,
id: 4,
post_number: 4,
post_type: site.get("post_types.whisper"),
}),
Post.create({
topic,
id: 5,
post_number: 5,
wiki: true,
via_email: true,
}),
Post.create({
topic,
id: 6,
post_number: 6,
via_email: true,
is_auto_generated: true,
}),
];
},
test(assert) {
assert.strictEqual(count(".post-stream"), 1);
assert.strictEqual(count(".topic-post"), 6, "renders all posts");
// look for special class bindings
assert.strictEqual(
count(".topic-post:nth-of-type(1).topic-owner"),
1,
"it applies the topic owner class"
);
assert.strictEqual(
count(".topic-post:nth-of-type(1).group-trout"),
1,
"it applies the primary group class"
);
assert.strictEqual(
count(".topic-post:nth-of-type(1).regular"),
1,
"it applies the regular class"
);
assert.strictEqual(
count(".topic-post:nth-of-type(2).moderator"),
1,
"it applies the moderator class"
);
assert.strictEqual(
count(".topic-post:nth-of-type(3).post-hidden"),
1,
"it applies the hidden class"
);
assert.strictEqual(
count(".topic-post:nth-of-type(4).whisper"),
1,
"it applies the whisper class"
);
assert.strictEqual(
count(".topic-post:nth-of-type(5).wiki"),
1,
"it applies the wiki class"
);
// it renders an article for the body with appropriate attributes
assert.strictEqual(count("article#post_2"), 1);
assert.strictEqual(count('article[data-user-id="123"]'), 1);
assert.strictEqual(count('article[data-post-id="3"]'), 1);
assert.strictEqual(count("article#post_5.via-email"), 1);
assert.strictEqual(count("article#post_6.is-auto-generated"), 1);
assert.strictEqual(
count("article:nth-of-type(1) .main-avatar"),
1,
"renders the main avatar"
);
},
});
postStreamTest("deleted posts", {
posts() {
const topic = Topic.create();
topic.set("details.created_by", { id: 123 });
return [
Post.create({
topic,
id: 1,
post_number: 1,
deleted_at: new Date().toString(),
}),
];
},
test(assert) {
assert.strictEqual(
count(".topic-post.deleted"),
1,
"it applies the deleted class"
);
assert.strictEqual(
count(".deleted-user-avatar"),
1,
"it has the trash avatar"
);
},
});
});

View File

@ -0,0 +1,920 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { click, render } from "@ember/test-helpers";
import {
count,
exists,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import EmberObject from "@ember/object";
import I18n from "I18n";
import createStore from "discourse/tests/helpers/create-store";
module("Integration | Component | Widget | post", function (hooks) {
setupRenderingTest(hooks);
test("basic elements", async function (assert) {
this.set("args", { shareUrl: "/example", post_number: 1 });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(exists(".names"), "includes poster name");
assert.ok(exists("a.post-date"), "includes post date");
});
test("post - links", async function (assert) {
this.set("args", {
cooked:
"<a href='http://link1.example.com/'>first link</a> and <a href='http://link2.example.com/?some=query'>second link</a>",
linkCounts: [
{ url: "http://link1.example.com/", clicks: 1, internal: true },
{ url: "http://link2.example.com/", clicks: 2, internal: true },
],
});
await render(
hbs`<MountWidget @widget="post-contents" @args={{this.args}} />`
);
assert.strictEqual(queryAll(".badge.clicks")[0].innerText, "1");
assert.strictEqual(queryAll(".badge.clicks")[1].innerText, "2");
});
test("post - onebox links", async function (assert) {
this.set("args", {
cooked: `
<p><a href="https://example.com">Other URL</a></p>
<aside class="onebox twitterstatus" data-onebox-src="https://twitter.com/codinghorror">
<header class="source">
<a href="https://twitter.com/codinghorror" target="_blank" rel="noopener">twitter.com</a>
</header>
<article class="onebox-body">
<h4><a href="https://twitter.com/codinghorror" target="_blank" rel="noopener">Jeff Atwood</a></h4>
<div class="twitter-screen-name"><a href="https://twitter.com/codinghorror" target="_blank" rel="noopener">@codinghorror</a></div>
</article>
</aside>`,
linkCounts: [
{ url: "https://example.com", clicks: 1 },
{ url: "https://twitter.com/codinghorror", clicks: 2 },
],
});
await render(
hbs`<MountWidget @widget="post-contents" @args={{this.args}} />`
);
assert.strictEqual(count(".badge.clicks"), 2);
assert.strictEqual(queryAll(".badge.clicks")[0].innerText, "1");
assert.strictEqual(queryAll(".badge.clicks")[1].innerText, "2");
});
test("wiki", async function (assert) {
this.set("args", { wiki: true, version: 2, canViewEditHistory: true });
this.set("showHistory", () => (this.historyShown = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @showHistory={{this.showHistory}} />
`);
await click(".post-info .wiki");
assert.ok(
this.historyShown,
"clicking the wiki icon displays the post history"
);
});
test("wiki without revision", async function (assert) {
this.set("args", { wiki: true, version: 1, canViewEditHistory: true });
this.set("editPost", () => (this.editPostCalled = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @editPost={{this.editPost}} />
`);
await click(".post-info .wiki");
assert.ok(this.editPostCalled, "clicking wiki icon edits the post");
});
test("via-email", async function (assert) {
this.set("args", { via_email: true, canViewRawEmail: true });
this.set("showRawEmail", () => (this.rawEmailShown = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @showRawEmail={{this.showRawEmail}} />
`);
await click(".post-info.via-email");
assert.ok(this.rawEmailShown, "clicking the envelope shows the raw email");
});
test("via-email without permission", async function (assert) {
this.set("args", { via_email: true, canViewRawEmail: false });
this.set("showRawEmail", () => (this.rawEmailShown = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @showRawEmail={{this.showRawEmail}} />
`);
await click(".post-info.via-email");
assert.ok(
!this.rawEmailShown,
"clicking the envelope doesn't show the raw email"
);
});
test("history", async function (assert) {
this.set("args", { version: 3, canViewEditHistory: true });
this.set("showHistory", () => (this.historyShown = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @showHistory={{this.showHistory}} />
`);
await click(".post-info.edits button");
assert.ok(this.historyShown, "clicking the pencil shows the history");
});
test("history without view permission", async function (assert) {
this.set("args", { version: 3, canViewEditHistory: false });
this.set("showHistory", () => (this.historyShown = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @showHistory={{this.showHistory}} />
`);
await click(".post-info.edits");
assert.ok(
!this.historyShown,
`clicking the pencil doesn't show the history`
);
});
test("whisper", async function (assert) {
this.set("args", { isWhisper: true });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.strictEqual(count(".topic-post.whisper"), 1);
assert.strictEqual(count(".post-info.whisper"), 1);
});
test("like count button", async function (assert) {
const store = createStore();
const topic = store.createRecord("topic", { id: 123 });
const post = store.createRecord("post", {
id: 1,
post_number: 1,
topic,
like_count: 3,
actions_summary: [{ id: 2, count: 1, hidden: false, can_act: true }],
});
this.set("post", post);
this.set("args", { likeCount: 1 });
await render(
hbs`<MountWidget @widget="post" @model={{this.post}} @args={{this.args}} />`
);
assert.strictEqual(count("button.like-count"), 1);
assert.ok(!exists(".who-liked"));
// toggle it on
await click("button.like-count");
assert.strictEqual(count(".who-liked"), 1);
assert.strictEqual(count(".who-liked a.trigger-user-card"), 1);
// toggle it off
await click("button.like-count");
assert.ok(!exists(".who-liked"));
assert.ok(!exists(".who-liked a.trigger-user-card"));
});
test(`like count with no likes`, async function (assert) {
this.set("args", { likeCount: 0 });
await render(
hbs`<MountWidget @widget="post" @model={{this.post}} @args={{this.args}} />`
);
assert.ok(!exists("button.like-count"));
});
test("share button", async function (assert) {
this.set("args", { shareUrl: "http://share-me.example.com" });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(exists(".actions button.share"), "it renders a share button");
});
test("liking", async function (assert) {
const args = { showLike: true, canToggleLike: true, id: 5 };
this.set("args", args);
this.set("toggleLike", () => {
args.liked = !args.liked;
args.likeCount = args.liked ? 1 : 0;
});
await render(hbs`
<MountWidget @widget="post-menu" @args={{this.args}} @toggleLike={{this.toggleLike}} />
`);
assert.ok(exists(".actions button.like"));
assert.ok(!exists(".actions button.like-count"));
await click(".actions button.like");
assert.ok(!exists(".actions button.like"));
assert.ok(exists(".actions button.has-like"));
assert.strictEqual(count(".actions button.like-count"), 1);
await click(".actions button.has-like");
assert.ok(exists(".actions button.like"));
assert.ok(!exists(".actions button.has-like"));
assert.ok(!exists(".actions button.like-count"));
});
test("anon liking", async function (assert) {
this.owner.unregister("current-user:main");
const args = { showLike: true };
this.set("args", args);
this.set("showLogin", () => (this.loginShown = true));
await render(hbs`
<MountWidget @widget="post-menu" @args={{this.args}} @showLogin={{this.showLogin}} />
`);
assert.ok(exists(".actions button.like"));
assert.ok(!exists(".actions button.like-count"));
assert.strictEqual(
query("button.like").getAttribute("title"),
I18n.t("post.controls.like"),
`shows the right button title for anonymous users`
);
await click(".actions button.like");
assert.ok(this.loginShown);
});
test("edit button", async function (assert) {
this.set("args", { canEdit: true });
this.set("editPost", () => (this.editPostCalled = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @editPost={{this.editPost}} />
`);
await click("button.edit");
assert.ok(this.editPostCalled, "it triggered the edit action");
});
test(`edit button - can't edit`, async function (assert) {
this.set("args", { canEdit: false });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("button.edit"), "button is not displayed");
});
test("recover button", async function (assert) {
this.set("args", { canDelete: true });
this.set("deletePost", () => (this.deletePostCalled = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @deletePost={{this.deletePost}} />
`);
await click("button.delete");
assert.ok(this.deletePostCalled, "it triggered the delete action");
});
test("delete topic button", async function (assert) {
this.set("args", { canDeleteTopic: true });
this.set("deletePost", () => (this.deletePostCalled = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @deletePost={{this.deletePost}} />
`);
await click("button.delete");
assert.ok(this.deletePostCalled, "it triggered the delete action");
});
test(`delete topic button - can't delete`, async function (assert) {
this.set("args", { canDeleteTopic: false });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("button.delete"), `button is not displayed`);
});
test(`delete topic button - can't delete when topic author without permission`, async function (assert) {
this.set("args", {
canDeleteTopic: false,
showFlagDelete: true,
canFlag: true,
});
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
await click(".show-more-actions");
assert.strictEqual(count("button.create-flag"), 1, `button is displayed`);
assert.strictEqual(count("button.delete"), 1, `button is displayed`);
assert.strictEqual(
query("button.delete").getAttribute("title"),
I18n.t("post.controls.delete_topic_disallowed"),
`shows the right button title for users without permissions`
);
});
test("recover topic button", async function (assert) {
this.set("args", { canRecoverTopic: true });
this.set("recoverPost", () => (this.recovered = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @recoverPost={{this.recoverPost}} />
`);
await click("button.recover");
assert.ok(this.recovered);
});
test(`recover topic button - can't recover`, async function (assert) {
this.set("args", { canRecoverTopic: false });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("button.recover"), `button is not displayed`);
});
test("delete post button", async function (assert) {
this.set("args", { canDelete: true, canFlag: true });
this.set("deletePost", () => (this.deletePostCalled = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @deletePost={{this.deletePost}} />
`);
await click(".show-more-actions");
await click("button.delete");
assert.ok(this.deletePostCalled, "it triggered the delete action");
});
test(`delete post button - can't delete`, async function (assert) {
this.set("args", { canDelete: false });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("button.delete"), `button is not displayed`);
});
test(`delete post button - can't delete, can't flag`, async function (assert) {
this.set("args", {
canDeleteTopic: false,
showFlagDelete: false,
canFlag: false,
});
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("button.delete"), `delete button is not displayed`);
assert.ok(!exists("button.create-flag"), `flag button is not displayed`);
});
test("recover post button", async function (assert) {
this.set("args", { canRecover: true });
this.set("recoverPost", () => (this.recovered = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @recoverPost={{this.recoverPost}} />
`);
await click("button.recover");
assert.ok(this.recovered);
});
test(`recover post button - can't recover`, async function (assert) {
this.set("args", { canRecover: false });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("button.recover"), `button is not displayed`);
});
test(`flagging`, async function (assert) {
this.set("args", { canFlag: true });
this.set("showFlags", () => (this.flagsShown = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @showFlags={{this.showFlags}} />
`);
assert.strictEqual(count("button.create-flag"), 1);
await click("button.create-flag");
assert.ok(this.flagsShown, "it triggered the action");
});
test(`flagging: can't flag`, async function (assert) {
this.set("args", { canFlag: false });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("button.create-flag"));
});
test(`flagging: can't flag when post is hidden`, async function (assert) {
this.set("args", { canFlag: true, hidden: true });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("button.create-flag"));
});
test(`read indicator`, async function (assert) {
this.set("args", { read: true });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(exists(".read-state.read"));
});
test(`unread indicator`, async function (assert) {
this.set("args", { read: false });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(exists(".read-state"));
});
test("reply directly above (suppressed)", async function (assert) {
this.set("args", {
replyToUsername: "eviltrout",
replyToAvatarTemplate: "/images/avatar.png",
replyDirectlyAbove: true,
});
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("a.reply-to-tab"), "hides the tab");
assert.ok(!exists(".avoid-tab"), "doesn't have the avoid tab class");
});
test("reply a few posts above (suppressed)", async function (assert) {
this.set("args", {
replyToUsername: "eviltrout",
replyToAvatarTemplate: "/images/avatar.png",
replyDirectlyAbove: false,
});
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(exists("a.reply-to-tab"), "shows the tab");
assert.strictEqual(count(".avoid-tab"), 1, "has the avoid tab class");
});
test("reply directly above", async function (assert) {
this.set("args", {
replyToUsername: "eviltrout",
replyToAvatarTemplate: "/images/avatar.png",
replyDirectlyAbove: true,
});
this.siteSettings.suppress_reply_directly_above = false;
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.strictEqual(count(".avoid-tab"), 1, "has the avoid tab class");
await click("a.reply-to-tab");
assert.strictEqual(count("section.embedded-posts.top .cooked"), 1);
assert.strictEqual(count("section.embedded-posts .d-icon-arrow-up"), 1);
});
test("cooked content hidden", async function (assert) {
this.set("args", { cooked_hidden: true });
this.set("expandHidden", () => (this.unhidden = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @expandHidden={{this.expandHidden}} />
`);
await click(".topic-body .expand-hidden");
assert.ok(this.unhidden, "triggers the action");
});
test("expand first post", async function (assert) {
const store = createStore();
this.set("args", { expandablePost: true });
this.set("post", store.createRecord("post", { id: 1234 }));
await render(
hbs`<MountWidget @widget="post" @model={{this.post}} @args={{this.args}} />`
);
await click(".topic-body .expand-post");
assert.ok(!exists(".expand-post"), "button is gone");
});
test("can't bookmark", async function (assert) {
this.set("args", { canBookmark: false });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("button.bookmark"));
assert.ok(!exists("button.bookmarked"));
});
test("bookmark", async function (assert) {
const args = { canBookmark: true };
this.set("args", args);
this.set("toggleBookmark", () => (args.bookmarked = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @toggleBookmark={{this.toggleBookmark}} />
`);
assert.strictEqual(count(".post-menu-area .bookmark"), 1);
assert.ok(!exists("button.bookmarked"));
});
test("can't show admin menu when you can't manage", async function (assert) {
this.set("args", { canManage: false });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists(".post-menu-area .show-post-admin-menu"));
});
test("show admin menu", async function (assert) {
this.set("args", { canManage: true });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists(".post-admin-menu"));
await click(".post-menu-area .show-post-admin-menu");
assert.strictEqual(count(".post-admin-menu"), 1, "it shows the popup");
await click(".post-menu-area");
assert.ok(!exists(".post-admin-menu"), "clicking outside clears the popup");
});
test("permanently delete topic", async function (assert) {
this.set("args", { canManage: true, canPermanentlyDelete: true });
this.set("permanentlyDeletePost", () => (this.deleted = true));
await render(
hbs`<MountWidget @widget="post" @args={{this.args}} @permanentlyDeletePost={{this.permanentlyDeletePost}} />`
);
await click(".post-menu-area .show-post-admin-menu");
await click(".post-admin-menu .permanently-delete");
assert.ok(this.deleted);
assert.ok(!exists(".post-admin-menu"), "also hides the menu");
});
test("permanently delete post", async function (assert) {
this.set("args", { canManage: true, canPermanentlyDelete: true });
this.set("permanentlyDeletePost", () => (this.deleted = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @permanentlyDeletePost={{this.permanentlyDeletePost}} />
`);
await click(".post-menu-area .show-post-admin-menu");
await click(".post-admin-menu .permanently-delete");
assert.ok(this.deleted);
assert.ok(!exists(".post-admin-menu"), "also hides the menu");
});
test("toggle moderator post", async function (assert) {
this.currentUser.set("moderator", true);
this.set("args", { canManage: true });
this.set("togglePostType", () => (this.toggled = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @togglePostType={{this.togglePostType}} />
`);
await click(".post-menu-area .show-post-admin-menu");
await click(".post-admin-menu .toggle-post-type");
assert.ok(this.toggled);
assert.ok(!exists(".post-admin-menu"), "also hides the menu");
});
test("toggle moderator post", async function (assert) {
this.currentUser.set("moderator", true);
this.set("args", { canManage: true });
this.set("togglePostType", () => (this.toggled = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @togglePostType={{this.togglePostType}} />
`);
await click(".post-menu-area .show-post-admin-menu");
await click(".post-admin-menu .toggle-post-type");
assert.ok(this.toggled);
assert.ok(!exists(".post-admin-menu"), "also hides the menu");
});
test("rebake post", async function (assert) {
this.set("args", { canManage: true });
this.set("rebakePost", () => (this.baked = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @rebakePost={{this.rebakePost}} />
`);
await click(".post-menu-area .show-post-admin-menu");
await click(".post-admin-menu .rebuild-html");
assert.ok(this.baked);
assert.ok(!exists(".post-admin-menu"), "also hides the menu");
});
test("unhide post", async function (assert) {
this.currentUser.admin = true;
this.set("args", { canManage: true, hidden: true });
this.set("unhidePost", () => (this.unhidden = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @unhidePost={{this.unhidePost}} />
`);
await click(".post-menu-area .show-post-admin-menu");
await click(".post-admin-menu .unhide-post");
assert.ok(this.unhidden);
assert.ok(!exists(".post-admin-menu"), "also hides the menu");
});
test("change owner", async function (assert) {
this.currentUser.admin = true;
this.set("args", { canManage: true });
this.set("changePostOwner", () => (this.owned = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @changePostOwner={{this.changePostOwner}} />
`);
await click(".post-menu-area .show-post-admin-menu");
await click(".post-admin-menu .change-owner");
assert.ok(this.owned);
assert.ok(!exists(".post-admin-menu"), "also hides the menu");
});
test("reply", async function (assert) {
this.set("args", { canCreatePost: true });
this.set("replyToPost", () => (this.replied = true));
await render(hbs`
<MountWidget @widget="post" @args={{this.args}} @replyToPost={{this.replyToPost}} />
`);
await click(".post-controls .create");
assert.ok(this.replied);
});
test("reply - without permissions", async function (assert) {
this.set("args", { canCreatePost: false });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists(".post-controls .create"));
});
test("replies - no replies", async function (assert) {
this.set("args", { replyCount: 0 });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("button.show-replies"));
});
test("replies - multiple replies", async function (assert) {
this.siteSettings.suppress_reply_directly_below = true;
this.set("args", { replyCount: 2, replyDirectlyBelow: true });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.strictEqual(count("button.show-replies"), 1);
});
test("replies - one below, suppressed", async function (assert) {
this.siteSettings.suppress_reply_directly_below = true;
this.set("args", { replyCount: 1, replyDirectlyBelow: true });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists("button.show-replies"));
});
test("replies - one below, not suppressed", async function (assert) {
this.siteSettings.suppress_reply_directly_below = false;
this.set("args", { id: 6654, replyCount: 1, replyDirectlyBelow: true });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
await click("button.show-replies");
assert.strictEqual(count("section.embedded-posts.bottom .cooked"), 1);
assert.strictEqual(count("section.embedded-posts .d-icon-arrow-down"), 1);
});
test("topic map not shown", async function (assert) {
this.set("args", { showTopicMap: false });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists(".topic-map"));
});
test("topic map - few posts", async function (assert) {
this.set("args", {
showTopicMap: true,
topicPostsCount: 2,
participants: [{ username: "eviltrout" }, { username: "codinghorror" }],
});
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(
!exists("li.avatars a.poster"),
"shows no participants when collapsed"
);
await click("nav.buttons button");
assert.strictEqual(
count(".topic-map-expanded a.poster"),
2,
"shows all when expanded"
);
});
test("topic map - participants", async function (assert) {
this.set("args", {
showTopicMap: true,
topicPostsCount: 10,
participants: [
{ username: "eviltrout" },
{ username: "codinghorror" },
{ username: "sam" },
{ username: "ZogStrIP" },
],
userFilters: ["sam", "codinghorror"],
});
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.strictEqual(
count("li.avatars a.poster"),
3,
"limits to three participants"
);
await click("nav.buttons button");
assert.ok(!exists("li.avatars a.poster"));
assert.strictEqual(
count(".topic-map-expanded a.poster"),
4,
"shows all when expanded"
);
assert.strictEqual(count("a.poster.toggled"), 2, "two are toggled");
});
test("topic map - links", async function (assert) {
this.set("args", {
showTopicMap: true,
topicLinks: [
{ url: "http://link1.example.com", clicks: 0 },
{ url: "http://link2.example.com", clicks: 0 },
{ url: "http://link3.example.com", clicks: 0 },
{ url: "http://link4.example.com", clicks: 0 },
{ url: "http://link5.example.com", clicks: 0 },
{ url: "http://link6.example.com", clicks: 0 },
],
});
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.strictEqual(count(".topic-map"), 1);
assert.strictEqual(count(".map.map-collapsed"), 1);
assert.ok(!exists(".topic-map-expanded"));
await click("nav.buttons button");
assert.ok(!exists(".map.map-collapsed"));
assert.strictEqual(count(".topic-map .d-icon-chevron-up"), 1);
assert.strictEqual(count(".topic-map-expanded"), 1);
assert.strictEqual(
count(".topic-map-expanded .topic-link"),
5,
"it limits the links displayed"
);
await click(".link-summary button");
assert.strictEqual(
count(".topic-map-expanded .topic-link"),
6,
"all links now shown"
);
});
test("topic map - no summary", async function (assert) {
this.set("args", { showTopicMap: true });
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.ok(!exists(".toggle-summary"));
});
test("topic map - has summary", async function (assert) {
this.set("args", { showTopicMap: true, hasTopicSummary: true });
this.set("showSummary", () => (this.summaryToggled = true));
await render(
hbs`<MountWidget @widget="post" @args={{this.args}} @showSummary={{this.showSummary}} />`
);
assert.strictEqual(count(".toggle-summary"), 1);
await click(".toggle-summary button");
assert.ok(this.summaryToggled);
});
test("pm map", async function (assert) {
this.set("args", {
showTopicMap: true,
showPMMap: true,
allowedGroups: [],
allowedUsers: [EmberObject.create({ username: "eviltrout" })],
});
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.strictEqual(count(".private-message-map"), 1);
assert.strictEqual(count(".private-message-map .user"), 1);
});
test("post notice - with username", async function (assert) {
const twoDaysAgo = new Date();
twoDaysAgo.setDate(twoDaysAgo.getDate() - 2);
this.siteSettings.display_name_on_posts = false;
this.siteSettings.prioritize_username_in_ux = true;
this.siteSettings.old_post_notice_days = 14;
this.set("args", {
username: "codinghorror",
name: "Jeff",
created_at: new Date(),
notice: {
type: "returning_user",
lastPostedAt: twoDaysAgo,
},
});
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.strictEqual(
query(".post-notice.returning-user:not(.old)").innerText.trim(),
I18n.t("post.notice.returning_user", {
user: "codinghorror",
time: "2 days ago",
})
);
});
test("post notice - with name", async function (assert) {
this.siteSettings.display_name_on_posts = true;
this.siteSettings.prioritize_username_in_ux = false;
this.siteSettings.old_post_notice_days = 14;
this.set("args", {
username: "codinghorror",
name: "Jeff",
created_at: new Date(2019, 0, 1),
notice: { type: "new_user" },
});
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
assert.strictEqual(
query(".post-notice.old.new-user").innerText.trim(),
I18n.t("post.notice.new_user", { user: "Jeff", time: "Jan '10" })
);
});
test("show group request in post", async function (assert) {
this.set("args", {
username: "foo",
requestedGroupName: "testGroup",
});
await render(hbs`<MountWidget @widget="post" @args={{this.args}} />`);
const link = query(".group-request a");
assert.strictEqual(link.innerText.trim(), I18n.t("groups.requests.handle"));
assert.strictEqual(
link.getAttribute("href"),
"/g/testGroup/requests?filter=foo"
);
});
});

View File

@ -0,0 +1,75 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
module("Integration | Component | Widget | poster-name", function (hooks) {
setupRenderingTest(hooks);
test("basic rendering", async function (assert) {
this.set("args", {
username: "eviltrout",
usernameUrl: "/u/eviltrout",
name: "Robin Ward",
user_title: "Trout Master",
});
await render(
hbs`<MountWidget @widget="poster-name" @args={{this.args}} />`
);
assert.ok(exists(".names"));
assert.ok(exists("span.username"));
assert.ok(exists('a[data-user-card="eviltrout"]'));
assert.strictEqual(query(".username a").innerText, "eviltrout");
assert.strictEqual(query(".full-name a").innerText, "Robin Ward");
assert.strictEqual(query(".user-title").innerText, "Trout Master");
});
test("extra classes and glyphs", async function (assert) {
this.set("args", {
username: "eviltrout",
usernameUrl: "/u/eviltrout",
staff: true,
admin: true,
moderator: true,
new_user: true,
primary_group_name: "fish",
});
await render(
hbs`<MountWidget @widget="poster-name" @args={{this.args}} />`
);
assert.ok(exists("span.staff"));
assert.ok(exists("span.admin"));
assert.ok(exists("span.moderator"));
assert.ok(exists(".d-icon-shield-alt"));
assert.ok(exists("span.new-user"));
assert.ok(exists("span.fish"));
});
test("disable display name on posts", async function (assert) {
this.siteSettings.display_name_on_posts = false;
this.set("args", { username: "eviltrout", name: "Robin Ward" });
await render(
hbs`<MountWidget @widget="poster-name" @args={{this.args}} />`
);
assert.ok(!exists(".full-name"));
});
test("doesn't render a name if it's similar to the username", async function (assert) {
this.siteSettings.prioritize_username_in_ux = true;
this.siteSettings.display_name_on_posts = true;
this.set("args", { username: "eviltrout", name: "evil-trout" });
await render(
hbs`<MountWidget @widget="poster-name" @args={{this.args}} />`
);
assert.ok(!exists(".second"));
});
});

View File

@ -0,0 +1,36 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
const CONTENT_DIV_SELECTOR = "li > a > div";
module(
"Integration | Component | Widget | quick-access-item",
function (hooks) {
setupRenderingTest(hooks);
test("content attribute is escaped", async function (assert) {
this.set("args", { content: "<b>bold</b>" });
await render(
hbs`<MountWidget @widget="quick-access-item" @args={{this.args}} />`
);
const contentDiv = query(CONTENT_DIV_SELECTOR);
assert.strictEqual(contentDiv.innerText, "<b>bold</b>");
});
test("escapedContent attribute is not escaped", async function (assert) {
this.set("args", { escapedContent: "&quot;quote&quot;" });
await render(
hbs`<MountWidget @widget="quick-access-item" @args={{this.args}} />`
);
const contentDiv = query(CONTENT_DIV_SELECTOR);
assert.strictEqual(contentDiv.innerText, '"quote"');
});
}
);

View File

@ -0,0 +1,26 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { count, exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
module("Integration | Component | Widget | small-user-list", function (hooks) {
setupRenderingTest(hooks);
test("renders avatars and support for unknown", async function (assert) {
this.set("args", {
users: [
{ id: 456, username: "eviltrout" },
{ id: 457, username: "someone", unknown: true },
],
});
await render(
hbs`<MountWidget @widget="small-user-list" @args={{this.args}} />`
);
assert.strictEqual(count('[data-user-card="eviltrout"]'), 1);
assert.ok(!exists('[data-user-card="someone"]'));
assert.ok(exists(".unknown"), "includes unknown user");
});
});

View File

@ -0,0 +1,69 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import Category from "discourse/models/category";
import Topic from "discourse/models/topic";
const createArgs = (topic) => {
return {
topic,
openUpwards: "true",
toggleMultiSelect: () => {},
deleteTopic: () => {},
recoverTopic: () => {},
toggleClosed: () => {},
toggleArchived: () => {},
toggleVisibility: () => {},
showTopicTimerModal: () => {},
showFeatureTopic: () => {},
showChangeTimestamp: () => {},
resetBumpDate: () => {},
convertToPublicTopic: () => {},
convertToPrivateMessage: () => {},
};
};
module(
"Integration | Component | Widget | topic-admin-menu-button",
function (hooks) {
setupRenderingTest(hooks);
test("topic-admin-menu-button is present for admin/moderators", async function (assert) {
this.currentUser.setProperties({
admin: true,
moderator: true,
id: 123,
});
const topic = Topic.create({ user_id: this.currentUser.id });
topic.set("category_id", Category.create({ read_restricted: true }).id);
this.siteSettings.allow_featured_topic_on_user_profiles = true;
this.set("args", createArgs(topic));
await render(
hbs`<MountWidget @widget="topic-admin-menu-button" @args={{this.args}} />`
);
assert.ok(exists(".toggle-admin-menu"), "admin wrench is present");
});
test("topic-admin-menu-button hides for non-admin when there is no action", async function (assert) {
this.currentUser.setProperties({
admin: false,
moderator: false,
id: 123,
});
const topic = Topic.create({ user_id: this.currentUser.id });
topic.set("category_id", Category.create({ read_restricted: true }).id);
this.siteSettings.allow_featured_topic_on_user_profiles = true;
this.set("args", createArgs(topic));
await render(
hbs`<MountWidget @widget="topic-admin-menu-button" @args={{this.args}} />`
);
assert.ok(!exists(".toggle-admin-menu"), "admin wrench is not present");
});
}
);

View File

@ -0,0 +1,55 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { render } from "@ember/test-helpers";
import { exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
module(
"Integration | Component | Widget | topic-participant",
function (hooks) {
setupRenderingTest(hooks);
test("one post", async function (assert) {
this.set("args", {
username: "test",
avatar_template: "/images/avatar.png",
post_count: 1,
});
await render(
hbs`<MountWidget @widget="topic-participant" @args={{this.args}} />`
);
assert.ok(exists("a.poster.trigger-user-card"));
assert.ok(!exists("span.post-count"), "don't show count for only 1 post");
assert.ok(!exists(".avatar-flair"), "no avatar flair");
});
test("many posts, a primary group with flair", async function (assert) {
this.set("args", {
username: "test",
avatar_template: "/images/avatar.png",
post_count: 2,
primary_group_name: "devs",
flair_name: "devs",
flair_url: "/images/d-logo-sketch-small.png",
flair_bg_color: "222",
});
await render(
hbs`<MountWidget @widget="topic-participant" @args={{this.args}} />`
);
assert.ok(exists("a.poster.trigger-user-card"));
assert.ok(exists("span.post-count"), "show count for many posts");
assert.ok(
exists(".group-devs a.poster"),
"add class for the group outside the link"
);
assert.ok(
exists(".avatar-flair.avatar-flair-devs"),
"show flair with group class"
);
});
}
);

View File

@ -0,0 +1,76 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { click, render } from "@ember/test-helpers";
import { exists } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import TopicStatusIcons from "discourse/helpers/topic-status-icons";
import createStore from "discourse/tests/helpers/create-store";
module("Integration | Component | Widget | topic-status", function (hooks) {
setupRenderingTest(hooks);
test("basics", async function (assert) {
const store = createStore();
this.set("args", {
topic: store.createRecord("topic", { closed: true }),
disableActions: true,
});
await render(
hbs`<MountWidget @widget="topic-status" @args={{this.args}} />`
);
assert.ok(exists(".topic-status .d-icon-lock"));
});
test("extendability", async function (assert) {
const store = createStore();
TopicStatusIcons.addObject([
"has_accepted_answer",
"far-check-square",
"solved",
]);
this.set("args", {
topic: store.createRecord("topic", {
has_accepted_answer: true,
}),
disableActions: true,
});
await render(
hbs`<MountWidget @widget="topic-status" @args={{this.args}} />`
);
assert.ok(exists(".topic-status .d-icon-far-check-square"));
});
test("toggling pin status", async function (assert) {
const store = createStore();
this.set("args", {
topic: store.createRecord("topic", { closed: true, pinned: true }),
});
await render(
hbs`<MountWidget @widget="topic-status" @args={{this.args}} />`
);
assert.ok(exists(".topic-statuses .pinned"), "pinned icon is shown");
assert.ok(
!exists(".topic-statuses .unpinned"),
"unpinned icon is not shown"
);
await click(".topic-statuses .pin-toggle-button");
assert.ok(!exists(".topic-statuses .pinned"), "pinned icon is not shown");
assert.ok(exists(".topic-statuses .unpinned"), "unpinned icon is shown");
await click(".topic-statuses .pin-toggle-button");
assert.ok(exists(".topic-statuses .pinned"), "pinned icon is shown");
assert.ok(
!exists(".topic-statuses .unpinned"),
"unpinned icon is not shown"
);
});
});

View File

@ -0,0 +1,221 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { click, render } from "@ember/test-helpers";
import { exists, query, queryAll } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import sinon from "sinon";
import DiscourseURL from "discourse/lib/url";
import I18n from "I18n";
module("Integration | Component | Widget | user-menu", function (hooks) {
setupRenderingTest(hooks);
test("basics", async function (assert) {
await render(hbs`<MountWidget @widget="user-menu" />`);
assert.ok(exists(".user-menu"));
assert.ok(exists(".user-preferences-link"));
assert.ok(exists(".user-notifications-link"));
assert.ok(exists(".user-bookmarks-link"));
assert.ok(exists(".quick-access-panel"));
assert.ok(exists(".notifications-dismiss"));
});
test("notifications", async function (assert) {
await render(hbs`<MountWidget @widget="user-menu" />`);
const links = queryAll(".quick-access-panel li a");
assert.strictEqual(links.length, 6);
assert.ok(links[1].href.includes("/t/a-slug/123"));
assert.ok(
links[2].href.includes(
"/u/eviltrout/notifications/likes-received?acting_username=aquaman"
)
);
assert.strictEqual(
links[2].text,
`aquaman ${I18n.t("notifications.liked_consolidated_description", {
count: 5,
})}`
);
assert.ok(links[3].href.includes("/u/test2/messages/group/test"));
assert.ok(
links[3].innerHTML.includes(
I18n.t("notifications.group_message_summary", {
count: 5,
group_name: "test",
})
)
);
assert.ok(links[4].href.includes("/u/test1"));
assert.ok(
links[4].innerHTML.includes(
I18n.t("notifications.invitee_accepted", { username: "test1" })
)
);
assert.ok(links[5].href.includes("/g/test"));
assert.ok(
links[5].innerHTML.includes(
I18n.t("notifications.membership_request_accepted", {
group_name: "test",
})
)
);
const routeToStub = sinon.stub(DiscourseURL, "routeTo");
await click(".user-notifications-link");
assert.ok(
routeToStub.calledWith(query(".user-notifications-link").dataset.url),
"a second click should redirect to the full notifications page"
);
});
test("log out", async function (assert) {
this.set("logout", () => (this.loggedOut = true));
await render(
hbs`<MountWidget @widget="user-menu" @logout={{this.logout}} />`
);
await click(".user-preferences-link");
assert.ok(exists(".logout"));
await click(".logout button");
assert.ok(this.loggedOut);
});
test("private messages - disabled", async function (assert) {
this.siteSettings.enable_personal_messages = false;
await render(hbs`<MountWidget @widget="user-menu" />`);
assert.ok(!exists(".user-pms-link"));
});
test("private messages - enabled", async function (assert) {
this.siteSettings.enable_personal_messages = true;
await render(hbs`<MountWidget @widget="user-menu" />`);
const userPmsLink = query(".user-pms-link").dataset.url;
assert.ok(userPmsLink);
await click(".user-pms-link");
const message = query(".quick-access-panel li a");
assert.ok(message);
assert.ok(
message.href.includes("/t/bug-can-not-render-emoji-properly/174/2"),
"should link to the next unread post"
);
assert.ok(
message.innerHTML.includes("mixtape"),
"should include the last poster's username"
);
assert.ok(
message.innerHTML.match(/<img.*class="emoji".*>/),
"should correctly render emoji in message title"
);
const routeToStub = sinon.stub(DiscourseURL, "routeTo");
await click(".user-pms-link");
assert.ok(
routeToStub.calledWith(userPmsLink),
"a second click should redirect to the full private messages page"
);
});
test("bookmarks", async function (assert) {
await render(hbs`<MountWidget @widget="user-menu" />`);
await click(".user-bookmarks-link");
const allBookmarks = queryAll(".quick-access-panel li a");
const bookmark = allBookmarks[0];
assert.ok(
bookmark.href.includes("/t/yelling-topic-title/119"),
"the Post bookmark should have a link to the topic"
);
assert.ok(
bookmark.innerHTML.includes("someguy"),
"should include the last poster's username"
);
assert.ok(
bookmark.innerHTML.match(/<img.*class="emoji".*>/),
"should correctly render emoji in bookmark title"
);
assert.ok(
bookmark.innerHTML.includes("d-icon-bookmark"),
"should use the correct icon based on no reminder_at present"
);
const routeToStub = sinon.stub(DiscourseURL, "routeTo");
await click(".user-bookmarks-link");
assert.ok(
routeToStub.calledWith(query(".user-bookmarks-link").dataset.url),
"a second click should redirect to the full bookmarks page"
);
const nonPostBookmarkableBookmark = allBookmarks[1];
assert.ok(
nonPostBookmarkableBookmark.href.includes("chat/message/2437"),
"bookmarkable_type that is not Post or Topic should use bookmarkable_url for the item link"
);
assert.ok(
nonPostBookmarkableBookmark.innerHTML.includes(
"d-icon-discourse-bookmark-clock"
),
"should use the correct icon based on reminder_at present"
);
});
test("anonymous", async function (assert) {
this.currentUser.setProperties({ is_anonymous: false, trust_level: 3 });
this.siteSettings.allow_anonymous_posting = true;
this.siteSettings.anonymous_posting_min_trust_level = 3;
this.set("toggleAnonymous", () => (this.anonymous = true));
await render(hbs`
<MountWidget @widget="user-menu" @toggleAnonymous={{this.toggleAnonymous}} />
`);
await click(".user-preferences-link");
assert.ok(exists(".enable-anonymous"));
await click(".enable-anonymous");
assert.ok(this.anonymous);
});
test("anonymous - disabled", async function (assert) {
this.siteSettings.allow_anonymous_posting = false;
await render(hbs`<MountWidget @widget="user-menu" />`);
await click(".user-preferences-link");
assert.ok(!exists(".enable-anonymous"));
});
test("anonymous - switch back", async function (assert) {
this.currentUser.setProperties({ is_anonymous: true });
this.siteSettings.allow_anonymous_posting = true;
this.set("toggleAnonymous", () => (this.anonymous = false));
await render(hbs`
<MountWidget @widget="user-menu" @toggleAnonymous={{this.toggleAnonymous}} />
`);
await click(".user-preferences-link");
assert.ok(exists(".disable-anonymous"));
await click(".disable-anonymous");
assert.notOk(this.anonymous);
});
});

View File

@ -0,0 +1,280 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { click, render } from "@ember/test-helpers";
import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import I18n from "I18n";
import hbs from "htmlbars-inline-precompile";
const DEFAULT_CONTENT = {
content: [
{ id: 1, label: "foo" },
{ id: 2, translatedLabel: "FooBar" },
"separator",
{ id: 3, translatedLabel: "With icon", icon: "times" },
{ id: 4, html: "<b>baz</b>" },
{ id: 5, translatedLabel: "Disabled", disabled: true },
],
label: "foo",
};
async function clickRowById(id) {
await click(`#my-dropdown .widget-dropdown-item.item-${id}`);
}
function rowById(id) {
return query(`#my-dropdown .widget-dropdown-item.item-${id}`);
}
async function toggle() {
await click("#my-dropdown .widget-dropdown-header");
}
function headerLabel() {
return query("#my-dropdown .widget-dropdown-header .label").innerText.trim();
}
function header() {
return query("#my-dropdown .widget-dropdown-header");
}
function body() {
return query("#my-dropdown .widget-dropdown-body");
}
const TEMPLATE = hbs`
<MountWidget
@widget="widget-dropdown"
@args={{hash
id="my-dropdown"
icon=this.icon
label=this.label
class=this.class
translatedLabel=this.translatedLabel
content=this.content
options=this.options
}}
/>
`;
module("Integration | Component | Widget | widget-dropdown", function (hooks) {
setupRenderingTest(hooks);
let _translations = I18n.translations;
hooks.afterEach(function () {
I18n.translations = _translations;
});
test("dropdown id", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
await render(TEMPLATE);
assert.ok(exists("#my-dropdown"));
});
test("label", async function (assert) {
I18n.translations = { en: { js: { foo: "FooBaz" } } };
this.setProperties(DEFAULT_CONTENT);
await render(TEMPLATE);
assert.strictEqual(headerLabel(), "FooBaz");
});
test("translatedLabel", async function (assert) {
I18n.translations = { en: { js: { foo: "FooBaz" } } };
this.setProperties(DEFAULT_CONTENT);
this.set("translatedLabel", "BazFoo");
await render(TEMPLATE);
assert.strictEqual(headerLabel(), this.translatedLabel);
});
test("content", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
await render(TEMPLATE);
await toggle();
assert.strictEqual(rowById(1).dataset.id, "1", "it creates rows");
assert.strictEqual(rowById(2).dataset.id, "2", "it creates rows");
assert.strictEqual(rowById(3).dataset.id, "3", "it creates rows");
});
test("onChange action", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
this.set("onChange", (item) => (query("#test").innerText = item.id));
await render(hbs`
<div id="test"></div>
<MountWidget
@widget="widget-dropdown"
@args={{hash
id="my-dropdown"
label=this.label
content=this.content
onChange=this.onChange
}}
/>
`);
await toggle();
await clickRowById(2);
assert.strictEqual(
query("#test").innerText,
"2",
"it calls the onChange actions"
);
});
test("can be opened and closed", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
await render(TEMPLATE);
assert.ok(exists("#my-dropdown.closed"));
assert.ok(!exists("#my-dropdown .widget-dropdown-body"));
await toggle();
assert.strictEqual(rowById(2).innerText.trim(), "FooBar");
assert.ok(exists("#my-dropdown.opened"));
assert.ok(exists("#my-dropdown .widget-dropdown-body"));
await toggle();
assert.ok(exists("#my-dropdown.closed"));
assert.ok(!exists("#my-dropdown .widget-dropdown-body"));
});
test("icon", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
this.set("icon", "times");
await render(TEMPLATE);
assert.ok(exists(header().querySelector(".d-icon-times")));
});
test("class", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
this.set("class", "activated");
await render(TEMPLATE);
assert.ok(exists("#my-dropdown.activated"));
});
test("content with translatedLabel", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
await render(TEMPLATE);
await toggle();
assert.strictEqual(rowById(2).innerText.trim(), "FooBar");
});
test("content with label", async function (assert) {
I18n.translations = { en: { js: { foo: "FooBaz" } } };
this.setProperties(DEFAULT_CONTENT);
await render(TEMPLATE);
await toggle();
assert.strictEqual(rowById(1).innerText.trim(), "FooBaz");
});
test("content with icon", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
await render(TEMPLATE);
await toggle();
assert.ok(exists(rowById(3).querySelector(".d-icon-times")));
});
test("content with html", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
await render(TEMPLATE);
await toggle();
assert.strictEqual(rowById(4).innerHTML.trim(), "<span><b>baz</b></span>");
});
test("separator", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
await render(TEMPLATE);
await toggle();
assert.ok(
query(
"#my-dropdown .widget-dropdown-item:nth-child(3)"
).classList.contains("separator")
);
});
test("hides widget if no content", async function (assert) {
this.setProperties({ content: null, label: "foo" });
await render(TEMPLATE);
assert.notOk(exists("#my-dropdown .widget-dropdown-header"));
assert.notOk(exists("#my-dropdown .widget-dropdown-body"));
});
test("headerClass option", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
this.set("options", { headerClass: "btn-small and-text" });
await render(TEMPLATE);
assert.ok(header().classList.contains("widget-dropdown-header"));
assert.ok(header().classList.contains("btn-small"));
assert.ok(header().classList.contains("and-text"));
});
test("bodyClass option", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
this.set("options", { bodyClass: "gigantic and-yet-small" });
await render(TEMPLATE);
await toggle();
assert.ok(body().classList.contains("widget-dropdown-body"));
assert.ok(body().classList.contains("gigantic"));
assert.ok(body().classList.contains("and-yet-small"));
});
test("caret option", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
this.set("options", { caret: true });
await render(TEMPLATE);
assert.ok(
exists("#my-dropdown .widget-dropdown-header .d-icon-caret-down")
);
});
test("disabled widget", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
this.set("options", { disabled: true });
await render(TEMPLATE);
assert.ok(exists("#my-dropdown.disabled"));
await toggle();
assert.strictEqual(rowById(1), null, "it does not display options");
});
test("disabled item", async function (assert) {
this.setProperties(DEFAULT_CONTENT);
await render(TEMPLATE);
await toggle();
assert.ok(exists(".widget-dropdown-item.item-5.disabled"));
});
});

View File

@ -0,0 +1,397 @@
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { click, render } from "@ember/test-helpers";
import { count, exists, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
import widgetHbs from "discourse/widgets/hbs-compiler";
import I18n from "I18n";
import { Promise } from "rsvp";
import { createWidget } from "discourse/widgets/widget";
import { next } from "@ember/runloop";
import { withPluginApi } from "discourse/lib/plugin-api";
module("Integration | Component | Widget | base", function (hooks) {
setupRenderingTest(hooks);
let _translations = I18n.translations;
hooks.afterEach(function () {
I18n.translations = _translations;
});
test("widget attributes are passed in via args", async function (assert) {
createWidget("hello-test", {
tagName: "div.test",
template: widgetHbs`Hello {{attrs.name}}`,
});
this.set("args", { name: "Robin" });
await render(hbs`<MountWidget @widget="hello-test" @args={{this.args}} />`);
assert.strictEqual(query(".test").innerText, "Hello Robin");
});
test("widget services", async function (assert) {
createWidget("service-test", {
tagName: "div.base-url-test",
services: ["router"],
html() {
return this.router.rootURL;
},
});
await render(hbs`<MountWidget @widget="service-test" />`);
assert.strictEqual(query(".base-url-test").innerText, "/");
});
test("hbs template - no tagName", async function (assert) {
createWidget("hbs-test", {
template: widgetHbs`<div class='test'>Hello {{attrs.name}}</div>`,
});
this.set("args", { name: "Robin" });
await render(hbs`<MountWidget @widget="hbs-test" @args={{this.args}} />`);
assert.strictEqual(query("div.test").innerText, "Hello Robin");
});
test("hbs template - with tagName", async function (assert) {
createWidget("hbs-test", {
tagName: "div.test",
template: widgetHbs`Hello {{attrs.name}}`,
});
this.set("args", { name: "Robin" });
await render(hbs`<MountWidget @widget="hbs-test" @args={{this.args}} />`);
assert.strictEqual(query("div.test").innerText, "Hello Robin");
});
test("hbs template - with data attributes", async function (assert) {
createWidget("hbs-test", {
template: widgetHbs`<div class='my-div' data-my-test='hello world'></div>`,
});
await render(hbs`<MountWidget @widget="hbs-test" @args={{this.args}} />`);
assert.strictEqual(query("div.my-div").dataset.myTest, "hello world");
});
test("buildClasses", async function (assert) {
createWidget("classname-test", {
tagName: "div.test",
buildClasses(attrs) {
return ["static", attrs.dynamic];
},
});
this.set("args", { dynamic: "cool-class" });
await render(
hbs`<MountWidget @widget="classname-test" @args={{this.args}} />`
);
assert.ok(exists(".test.static.cool-class"), "it has all the classes");
});
test("buildAttributes", async function (assert) {
createWidget("attributes-test", {
tagName: "div.test",
buildAttributes(attrs) {
return { "data-evil": "trout", "aria-label": attrs.label };
},
});
this.set("args", { label: "accessibility" });
await render(
hbs`<MountWidget @widget="attributes-test" @args={{this.args}} />`
);
assert.ok(exists('.test[data-evil="trout"]'));
assert.ok(exists('.test[aria-label="accessibility"]'));
});
test("buildId", async function (assert) {
createWidget("id-test", {
buildId(attrs) {
return `test-${attrs.id}`;
},
});
this.set("args", { id: 1234 });
await render(hbs`<MountWidget @widget="id-test" @args={{this.args}} />`);
assert.ok(exists("#test-1234"));
});
test("widget state", async function (assert) {
createWidget("state-test", {
tagName: "button.test",
buildKey: () => `button-test`,
template: widgetHbs`{{state.clicks}} clicks`,
defaultState() {
return { clicks: 0 };
},
click() {
this.state.clicks++;
},
});
await render(hbs`<MountWidget @widget="state-test" />`);
assert.ok(exists("button.test"), "it renders the button");
assert.strictEqual(query("button.test").innerText, "0 clicks");
await click(query("button"));
assert.strictEqual(query("button.test").innerText, "1 clicks");
});
test("widget update with promise", async function (assert) {
createWidget("promise-test", {
tagName: "button.test",
buildKey: () => "promise-test",
template: widgetHbs`
{{#if state.name}}
{{state.name}}
{{else}}
No name
{{/if}}
`,
click() {
return new Promise((resolve) => {
next(() => {
this.state.name = "Robin";
resolve();
});
});
},
});
await render(hbs`<MountWidget @widget="promise-test" />`);
assert.strictEqual(query("button.test").innerText.trim(), "No name");
await click(query("button"));
assert.strictEqual(query("button.test").innerText.trim(), "Robin");
});
test("widget attaching", async function (assert) {
createWidget("test-embedded", { tagName: "div.embedded" });
createWidget("attach-test", {
tagName: "div.container",
template: widgetHbs`{{attach widget="test-embedded" attrs=attrs}}`,
});
await render(hbs`<MountWidget @widget="attach-test" />`);
assert.ok(exists(".container"), "renders container");
assert.ok(exists(".container .embedded"), "renders attached");
});
test("magic attaching by name", async function (assert) {
createWidget("test-embedded", { tagName: "div.embedded" });
createWidget("attach-test", {
tagName: "div.container",
template: widgetHbs`{{test-embedded attrs=attrs}}`,
});
await render(hbs`<MountWidget @widget="attach-test" />`);
assert.ok(exists(".container"), "renders container");
assert.ok(exists(".container .embedded"), "renders attached");
});
test("custom attrs to a magic attached widget", async function (assert) {
createWidget("testing", {
tagName: "span.value",
template: widgetHbs`{{attrs.value}}`,
});
createWidget("attach-test", {
tagName: "div.container",
template: widgetHbs`{{testing value=(concat "hello" " " "world")}}`,
});
await render(hbs`<MountWidget @widget="attach-test" />`);
assert.ok(exists(".container"), "renders container");
assert.strictEqual(query(".container .value").innerText, "hello world");
});
test("using transformed values in a sub-expression", async function (assert) {
createWidget("testing", {
tagName: "span.value",
template: widgetHbs`{{attrs.value}}`,
});
createWidget("attach-test", {
transform() {
return { someValue: "world" };
},
tagName: "div.container",
template: widgetHbs`{{testing value=(concat "hello" " " transformed.someValue)}}`,
});
await render(hbs`<MountWidget @widget="attach-test" />`);
assert.ok(count(".container"), "renders container");
assert.strictEqual(query(".container .value").innerText, "hello world");
});
test("handlebars d-icon", async function (assert) {
createWidget("hbs-icon-test", {
template: widgetHbs`{{d-icon "arrow-down"}}`,
});
await render(
hbs`<MountWidget @widget="hbs-icon-test" @args={{this.args}} />`
);
assert.strictEqual(count(".d-icon-arrow-down"), 1);
});
test("handlebars i18n", async function (assert) {
createWidget("hbs-i18n-test", {
template: widgetHbs`
<span class='string'>{{i18n "hbs_test0"}}</span>
<span class='var'>{{i18n attrs.key}}</span>
<a href title={{i18n "hbs_test0"}}>test</a>
`,
});
I18n.translations = {
en: {
js: {
hbs_test0: "evil",
hbs_test1: "trout",
},
},
};
this.set("args", { key: "hbs_test1" });
await render(
hbs`<MountWidget @widget="hbs-i18n-test" @args={{this.args}} />`
);
// coming up
assert.strictEqual(query("span.string").innerText, "evil");
assert.strictEqual(query("span.var").innerText, "trout");
assert.strictEqual(query("a").title, "evil");
});
test("handlebars #each", async function (assert) {
createWidget("hbs-each-test", {
tagName: "ul",
template: widgetHbs`
{{#each attrs.items as |item|}}
<li>{{item}}</li>
{{/each}}
`,
});
this.set("args", {
items: ["one", "two", "three"],
});
await render(
hbs`<MountWidget @widget="hbs-each-test" @args={{this.args}} />`
);
assert.strictEqual(count("ul li"), 3);
assert.strictEqual(query("ul li:nth-of-type(1)").innerText, "one");
});
test("widget decorating", async function (assert) {
createWidget("decorate-test", {
tagName: "div.decorate",
template: widgetHbs`main content`,
});
withPluginApi("0.1", (api) => {
api.decorateWidget("decorate-test:before", (dec) => {
return dec.h("b", "before");
});
api.decorateWidget("decorate-test:after", (dec) => {
return dec.h("i", "after");
});
});
await render(hbs`<MountWidget @widget="decorate-test" />`);
assert.ok(exists(".decorate"));
assert.strictEqual(query(".decorate b").innerText, "before");
assert.strictEqual(query(".decorate i").innerText, "after");
});
test("widget settings", async function (assert) {
createWidget("settings-test", {
tagName: "div.settings",
template: widgetHbs`age is {{settings.age}}`,
settings: { age: 36 },
});
await render(hbs`<MountWidget @widget="settings-test" />`);
assert.strictEqual(query(".settings").innerText, "age is 36");
});
test("override settings", async function (assert) {
createWidget("ov-settings-test", {
tagName: "div.settings",
template: widgetHbs`age is {{settings.age}}`,
settings: { age: 36 },
});
withPluginApi("0.1", (api) => {
api.changeWidgetSetting("ov-settings-test", "age", 37);
});
await render(hbs`<MountWidget @widget="ov-settings-test" />`);
assert.strictEqual(query(".settings").innerText, "age is 37");
});
test("get accessor", async function (assert) {
createWidget("get-accessor-test", {
tagName: "div.test",
template: widgetHbs`Hello {{transformed.name}}`,
transform() {
return {
name: this.get("currentUser.username"),
};
},
});
await render(hbs`<MountWidget @widget="get-accessor-test" />`);
assert.strictEqual(query("div.test").innerText, "Hello eviltrout");
});
test("tagName", async function (assert) {
createWidget("test-override", { tagName: "div.not-override" });
createWidget("tag-name-override-test", {
template: widgetHbs`{{attach widget="test-override" attrs=attrs otherOpts=(hash tagName="section.override")}}`,
});
await render(hbs`<MountWidget @widget="tag-name-override-test" />`);
assert.ok(
exists("section.override"),
"renders container with overridden tagName"
);
});
});

View File

@ -1,40 +1,24 @@
import { import { module, test } from "qunit";
count, import { setupRenderingTest } from "discourse/tests/helpers/component-test";
discourseModule, import { click, fillIn, render } from "@ember/test-helpers";
exists, import { count, exists } from "discourse/tests/helpers/qunit-helpers";
} from "discourse/tests/helpers/qunit-helpers";
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { click, fillIn } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
discourseModule( module("Integration | Component | Wizard | invite-list", function (hooks) {
"Integration | Component | Wizard | invite-list",
function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("can add users", { test("can add users", async function (assert) {
template: hbs`{{invite-list field=field}}`,
beforeEach() {
this.set("field", {}); this.set("field", {});
},
async test(assert) { await render(hbs`<InviteList @field={{this.field}} />`);
assert.ok(
!exists(".users-list .invite-list-user"), assert.ok(!exists(".users-list .invite-list-user"), "no users at first");
"no users at first"
);
assert.ok(!exists(".new-user .invalid"), "not invalid at first"); assert.ok(!exists(".new-user .invalid"), "not invalid at first");
const firstVal = JSON.parse(this.field.value); const firstVal = JSON.parse(this.field.value);
assert.strictEqual(firstVal.length, 0, "empty JSON at first"); assert.strictEqual(firstVal.length, 0, "empty JSON at first");
assert.ok( assert.ok(this.field.warning, "it has a warning since no users were added");
this.field.warning,
"it has a warning since no users were added"
);
await click(".add-user"); await click(".add-user");
assert.ok( assert.ok(
@ -61,10 +45,7 @@ discourseModule(
"adds the email to the JSON" "adds the email to the JSON"
); );
assert.ok(val[0].role.length, "adds the role to the JSON"); assert.ok(val[0].role.length, "adds the role to the JSON");
assert.ok( assert.ok(!this.get("field.warning"), "no warning once the user is added");
!this.get("field.warning"),
"no warning once the user is added"
);
await fillIn(".invite-email", "eviltrout@example.com"); await fillIn(".invite-email", "eviltrout@example.com");
await click(".add-user"); await click(".add-user");
@ -86,15 +67,7 @@ discourseModule(
); );
assert.strictEqual(count(".new-user .invalid"), 1); assert.strictEqual(count(".new-user .invalid"), 1);
await click( await click(".invite-list .invite-list-user:nth-of-type(1) .remove-user");
".invite-list .invite-list-user:nth-of-type(1) .remove-user" assert.ok(!exists(".users-list .invite-list-user"), 0, "removed the user");
);
assert.ok(
!exists(".users-list .invite-list-user"),
0,
"removed the user"
);
},
}); });
} });
);

View File

@ -1,35 +0,0 @@
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { count, discourseModule } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
discourseModule(
"Integration | Component | Widget | actions-summary",
function (hooks) {
setupRenderingTest(hooks);
componentTest("post deleted", {
template: hbs`{{mount-widget widget="actions-summary" args=args}}`,
beforeEach() {
this.set("args", {
deleted_at: "2016-01-01",
deletedByUsername: "eviltrout",
deletedByAvatarTemplate: "/images/avatar.png",
});
},
test(assert) {
assert.strictEqual(
count(".post-action .d-icon-far-trash-alt"),
1,
"it has the deleted icon"
);
assert.strictEqual(
count(".avatar[title=eviltrout]"),
1,
"it has the deleted by avatar"
);
},
});
}
);

View File

@ -1,49 +0,0 @@
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import {
discourseModule,
exists,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
discourseModule(
"Integration | Component | Widget | avatar-flair",
function (hooks) {
setupRenderingTest(hooks);
componentTest("avatar flair with an icon", {
template: hbs`{{mount-widget widget="avatar-flair" args=args}}`,
beforeEach() {
this.set("args", {
flair_url: "fa-bars",
flair_bg_color: "CC0000",
flair_color: "FFFFFF",
});
},
test(assert) {
assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-bars"), "it has the svg icon");
assert.strictEqual(
queryAll(".avatar-flair").attr("style"),
"background-color: #CC0000; color: #FFFFFF; ",
"it has styles"
);
},
});
componentTest("avatar flair with an image", {
template: hbs`{{mount-widget widget="avatar-flair" args=args}}`,
beforeEach() {
this.set("args", {
flair_url: "/images/avatar.png",
});
},
test(assert) {
assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(!exists("svg"), "it does not have an svg icon");
},
});
}
);

View File

@ -1,97 +0,0 @@
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import {
discourseModule,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile";
discourseModule("Integration | Component | Widget | button", function (hooks) {
setupRenderingTest(hooks);
componentTest("icon only button", {
template: hbs`{{mount-widget widget="button" args=args}}`,
beforeEach() {
this.set("args", { icon: "far-smile" });
},
test(assert) {
assert.ok(
exists("button.btn.btn-icon.no-text"),
"it has all the classes"
);
assert.ok(exists("button .d-icon.d-icon-far-smile"), "it has the icon");
},
});
componentTest("icon and text button", {
template: hbs`{{mount-widget widget="button" args=args}}`,
beforeEach() {
this.set("args", { icon: "plus", label: "topic.create" });
},
test(assert) {
assert.ok(exists("button.btn.btn-icon-text"), "it has all the classes");
assert.ok(exists("button .d-icon.d-icon-plus"), "it has the icon");
assert.ok(exists("button span.d-button-label"), "it has the label");
},
});
componentTest("emoji and text button", {
template: hbs`{{mount-widget widget="button" args=args}}`,
beforeEach() {
this.set("args", { emoji: "mega", label: "topic.create" });
},
test(assert) {
assert.ok(exists("button.widget-button"), "renders the widget");
assert.ok(exists("button img.emoji"), "it renders the emoji");
assert.ok(exists("button span.d-button-label"), "it renders the label");
},
});
componentTest("text only button", {
template: hbs`{{mount-widget widget="button" args=args}}`,
beforeEach() {
this.set("args", { label: "topic.create" });
},
test(assert) {
assert.ok(exists("button.btn.btn-text"), "it has all the classes");
assert.ok(exists("button span.d-button-label"), "it has the label");
},
});
componentTest("translatedLabel", {
template: hbs`{{mount-widget widget="button" args=args}}`,
beforeEach() {
this.set("args", { translatedLabel: "foo bar" });
},
test(assert) {
assert.strictEqual(
query("button span.d-button-label").innerText,
"foo bar"
);
},
});
componentTest("translatedTitle", {
template: hbs`{{mount-widget widget="button" args=args}}`,
beforeEach() {
this.set("args", { label: "topic.create", translatedTitle: "foo bar" });
},
test(assert) {
assert.strictEqual(query("button").title, "foo bar");
},
});
});

Some files were not shown because too many files have changed in this diff Show More