DEV: Modernize chat's component tests (#19577)

1. `test()` and `render()` instead of `componentTest()`
2. Angle brackets
3. `strictEqual()`/`true()`/`false()` assertions

This removes all remaining uses of `componentTest` from core
This commit is contained in:
Jarek Radosz 2022-12-22 14:35:18 +01:00 committed by GitHub
parent 8546c2084a
commit dc3473fe06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 1397 additions and 1762 deletions

View File

@ -10,18 +10,19 @@ module(
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () {
this.set("channel", fabricators.chatChannel({}));
});
test("channel title is escaped in instructions correctly", async function (assert) { test("channel title is escaped in instructions correctly", async function (assert) {
this.set("channel.title", `<script>someeviltitle</script>`); this.set(
"channel",
await render( fabricators.chatChannel({
hbs`{{chat-channel-archive-modal-inner chatChannel=channel}}` title: `<script>someeviltitle</script>`,
})
); );
assert.ok( await render(
hbs`<ChatChannelArchiveModalInner @chatChannel={{this.channel}} />`
);
assert.true(
query(".chat-channel-archive-modal-instructions").innerHTML.includes( query(".chat-channel-archive-modal-instructions").innerHTML.includes(
"&lt;script&gt;someeviltitle&lt;/script&gt;" "&lt;script&gt;someeviltitle&lt;/script&gt;"
) )

View File

@ -20,39 +20,39 @@ module("Discourse Chat | Component | chat-channel-card", function (hooks) {
test("escapes channel title", async function (assert) { test("escapes channel title", async function (assert) {
this.channel.set("title", "<div class='xss'>evil</div>"); this.channel.set("title", "<div class='xss'>evil</div>");
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.notOk(exists(".xss")); assert.false(exists(".xss"));
}); });
test("escapes channel description", async function (assert) { test("escapes channel description", async function (assert) {
this.channel.set("description", "<div class='xss'>evil</div>"); this.channel.set("description", "<div class='xss'>evil</div>");
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.notOk(exists(".xss")); assert.false(exists(".xss"));
}); });
test("Closed channel", async function (assert) { test("Closed channel", async function (assert) {
this.channel.set("status", "closed"); this.channel.set("status", "closed");
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.ok(exists(".chat-channel-card.-closed")); assert.true(exists(".chat-channel-card.-closed"));
}); });
test("Archived channel", async function (assert) { test("Archived channel", async function (assert) {
this.channel.set("status", "archived"); this.channel.set("status", "archived");
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.ok(exists(".chat-channel-card.-archived")); assert.true(exists(".chat-channel-card.-archived"));
}); });
test("Muted channel", async function (assert) { test("Muted channel", async function (assert) {
this.channel.currentUserMembership.muted = true; this.channel.currentUserMembership.muted = true;
this.channel.currentUserMembership.following = true; this.channel.currentUserMembership.following = true;
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.equal( assert.strictEqual(
query(".chat-channel-card__tag.-muted").textContent.trim(), query(".chat-channel-card__tag.-muted").textContent.trim(),
I18n.t("chat.muted") I18n.t("chat.muted")
); );
@ -60,27 +60,27 @@ module("Discourse Chat | Component | chat-channel-card", function (hooks) {
test("Joined channel", async function (assert) { test("Joined channel", async function (assert) {
this.channel.currentUserMembership.set("following", true); this.channel.currentUserMembership.set("following", true);
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.equal( assert.strictEqual(
query(".chat-channel-card__tag.-joined").textContent.trim(), query(".chat-channel-card__tag.-joined").textContent.trim(),
I18n.t("chat.joined") I18n.t("chat.joined")
); );
assert.ok(exists(".toggle-channel-membership-button.-leave")); assert.true(exists(".toggle-channel-membership-button.-leave"));
}); });
test("Joinable channel", async function (assert) { test("Joinable channel", async function (assert) {
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.ok(exists(".chat-channel-card__join-btn")); assert.true(exists(".chat-channel-card__join-btn"));
}); });
test("Memberships count", async function (assert) { test("Memberships count", async function (assert) {
this.channel.set("membershipsCount", 4); this.channel.set("membershipsCount", 4);
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.equal( assert.strictEqual(
query(".chat-channel-card__members").textContent.trim(), query(".chat-channel-card__members").textContent.trim(),
I18n.t("chat.channel.memberships_count", { count: 4 }) I18n.t("chat.channel.memberships_count", { count: 4 })
); );
@ -88,41 +88,41 @@ module("Discourse Chat | Component | chat-channel-card", function (hooks) {
test("No description", async function (assert) { test("No description", async function (assert) {
this.channel.set("description", null); this.channel.set("description", null);
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.notOk(exists(".chat-channel-card__description")); assert.false(exists(".chat-channel-card__description"));
}); });
test("Description", async function (assert) { test("Description", async function (assert) {
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.equal( assert.strictEqual(
query(".chat-channel-card__description").textContent.trim(), query(".chat-channel-card__description").textContent.trim(),
this.channel.description this.channel.description
); );
}); });
test("Name", async function (assert) { test("Name", async function (assert) {
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.equal( assert.strictEqual(
query(".chat-channel-card__name").innerText.trim(), query(".chat-channel-card__name").innerText.trim(),
this.channel.title this.channel.title
); );
}); });
test("Settings button", async function (assert) { test("Settings button", async function (assert) {
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.ok(exists(".chat-channel-card__setting")); assert.true(exists(".chat-channel-card__setting"));
}); });
test("Read restricted chatable", async function (assert) { test("Read restricted chatable", async function (assert) {
this.channel.set("chatable.read_restricted", true); this.channel.set("chatable.read_restricted", true);
await render(hbs`{{chat-channel-card channel=channel}}`); await render(hbs`<ChatChannelCard @channel={{this.channel}} />`);
assert.ok(exists(".d-icon-lock")); assert.true(exists(".d-icon-lock"));
assert.equal( assert.strictEqual(
query(".chat-channel-card").style.borderLeftColor, query(".chat-channel-card").style.borderLeftColor,
"rgb(213, 99, 83)" "rgb(213, 99, 83)"
); );

View File

@ -10,18 +10,19 @@ module(
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
hooks.beforeEach(function () {
this.set("channel", fabricators.chatChannel({}));
});
test("channel title is escaped in instructions correctly", async function (assert) { test("channel title is escaped in instructions correctly", async function (assert) {
this.set("channel.title", `<script>someeviltitle</script>`); this.set(
"channel",
await render( fabricators.chatChannel({
hbs`{{chat-channel-delete-modal-inner chatChannel=channel}}` title: `<script>someeviltitle</script>`,
})
); );
assert.ok( await render(
hbs`<ChatChannelDeleteModalInner @chatChannel={{this.channel}} />`
);
assert.true(
query(".chat-channel-delete-modal-instructions").innerHTML.includes( query(".chat-channel-delete-modal-instructions").innerHTML.includes(
"&lt;script&gt;someeviltitle&lt;/script&gt;" "&lt;script&gt;someeviltitle&lt;/script&gt;"
) )

View File

@ -1,81 +1,62 @@
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 { click } from "@ember/test-helpers";
import { exists, query } from "discourse/tests/helpers/qunit-helpers"; import { exists, 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 I18n from "I18n"; import I18n from "I18n";
import { module } from "qunit"; import { module, test } from "qunit";
module("Discourse Chat | Component | chat-channel-leave-btn", function (hooks) { module("Discourse Chat | Component | chat-channel-leave-btn", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("accepts an optional onLeaveChannel callback", { test("accepts an optional onLeaveChannel callback", async function (assert) {
template: hbs`{{chat-channel-leave-btn channel=channel onLeaveChannel=onLeaveChannel}}`, this.set("foo", 1);
this.set("onLeaveChannel", () => this.set("foo", 2));
this.set("channel", {
id: 1,
chatable_type: "DirectMessage",
chatable: {
users: [{ id: 1 }],
},
});
beforeEach() { await render(
this.set("foo", 1); hbs`<ChatChannelLeaveBtn @channel={{this.channel}} @onLeaveChannel={{this.onLeaveChannel}} />`
this.set("onLeaveChannel", () => this.set("foo", 2)); );
this.set("channel", {
id: 1,
chatable_type: "DirectMessage",
chatable: {
users: [{ id: 1 }],
},
});
},
async test(assert) { pretender.post("/chat/chat_channels/:chatChannelId/unfollow", () => {
pretender.post("/chat/chat_channels/:chatChannelId/unfollow", () => { return [200, { current_user_membership: { following: false } }, {}];
return [200, { current_user_membership: { following: false } }, {}]; });
}); assert.strictEqual(this.foo, 1);
assert.equal(this.foo, 1);
await click(".chat-channel-leave-btn"); await click(".chat-channel-leave-btn");
assert.strictEqual(this.foo, 2);
assert.equal(this.foo, 2);
},
}); });
componentTest("has a specific title for direct message channel", { test("has a specific title for direct message channel", async function (assert) {
template: hbs`{{chat-channel-leave-btn channel=channel}}`, this.set("channel", { chatable_type: "DirectMessage" });
beforeEach() { await render(hbs`<ChatChannelLeaveBtn @channel={{this.channel}} />`);
this.set("channel", { chatable_type: "DirectMessage" });
},
async test(assert) { const btn = query(".chat-channel-leave-btn");
const btn = query(".chat-channel-leave-btn"); assert.strictEqual(btn.title, I18n.t("chat.direct_messages.leave"));
assert.equal(btn.title, I18n.t("chat.direct_messages.leave"));
},
}); });
componentTest("has a specific title for message channel", { test("has a specific title for message channel", async function (assert) {
template: hbs`{{chat-channel-leave-btn channel=channel}}`, this.set("channel", { chatable_type: "Topic" });
beforeEach() { await render(hbs`<ChatChannelLeaveBtn @channel={{this.channel}} />`);
this.set("channel", { chatable_type: "Topic" });
},
async test(assert) { const btn = query(".chat-channel-leave-btn");
const btn = query(".chat-channel-leave-btn"); assert.strictEqual(btn.title, I18n.t("chat.leave"));
assert.equal(btn.title, I18n.t("chat.leave"));
},
}); });
componentTest("is not visible on mobile", { test("is not visible on mobile", async function (assert) {
template: hbs`{{chat-channel-leave-btn channel=channel}}`, this.site.mobileView = true;
this.set("channel", { chatable_type: "Topic" });
beforeEach() { await render(hbs`<ChatChannelLeaveBtn @channel={{this.channel}} />`);
this.site.mobileView = true;
this.set("channel", { chatable_type: "Topic" });
},
async test(assert) { assert.false(exists(".chat-channel-leave-btn"));
assert.notOk(exists(".chat-channel-leave-btn"));
},
}); });
}); });

View File

@ -35,13 +35,13 @@ module("Discourse Chat | Component | chat-channel-metadata", function (hooks) {
hbs`<ChatChannelMetadata @channel={{this.channel}} @unreadIndicator={{this.unreadIndicator}}/>` hbs`<ChatChannelMetadata @channel={{this.channel}} @unreadIndicator={{this.unreadIndicator}}/>`
); );
assert.ok(exists(".chat-channel-unread-indicator")); assert.true(exists(".chat-channel-unread-indicator"));
this.unreadIndicator = false; this.unreadIndicator = false;
await render( await render(
hbs`<ChatChannelMetadata @channel={{this.channel}} @unreadIndicator={{this.unreadIndicator}}/>` hbs`<ChatChannelMetadata @channel={{this.channel}} @unreadIndicator={{this.unreadIndicator}}/>`
); );
assert.notOk(exists(".chat-channel-unread-indicator")); assert.false(exists(".chat-channel-unread-indicator"));
}); });
}); });

View File

@ -24,24 +24,24 @@ module(
}); });
test("channel title", async function (assert) { test("channel title", async function (assert) {
await render(hbs`{{chat-channel-preview-card channel=channel}}`); await render(hbs`<ChatChannelPreviewCard @channel={{this.channel}} />`);
assert.equal( assert.strictEqual(
query(".chat-channel-title__name").innerText, query(".chat-channel-title__name").innerText,
this.channel.title, this.channel.title,
"it shows the channel title" "it shows the channel title"
); );
assert.ok( assert.true(
exists(query(".chat-channel-title__category-badge")), exists(query(".chat-channel-title__category-badge")),
"it shows the category hashtag badge" "it shows the category hashtag badge"
); );
}); });
test("channel description", async function (assert) { test("channel description", async function (assert) {
await render(hbs`{{chat-channel-preview-card channel=channel}}`); await render(hbs`<ChatChannelPreviewCard @channel={{this.channel}} />`);
assert.equal( assert.strictEqual(
query(".chat-channel-preview-card__description").innerText, query(".chat-channel-preview-card__description").innerText,
this.channel.description, this.channel.description,
"the channel description is shown" "the channel description is shown"
@ -51,32 +51,32 @@ module(
test("no channel description", async function (assert) { test("no channel description", async function (assert) {
this.channel.set("description", null); this.channel.set("description", null);
await render(hbs`{{chat-channel-preview-card channel=channel}}`); await render(hbs`<ChatChannelPreviewCard @channel={{this.channel}} />`);
assert.notOk( assert.false(
exists(".chat-channel-preview-card__description"), exists(".chat-channel-preview-card__description"),
"no line is left for the channel description if there is none" "no line is left for the channel description if there is none"
); );
assert.ok( assert.true(
exists(".chat-channel-preview-card.-no-description"), exists(".chat-channel-preview-card.-no-description"),
"it adds a modifier class for styling" "it adds a modifier class for styling"
); );
}); });
test("join", async function (assert) { test("join", async function (assert) {
await render(hbs`{{chat-channel-preview-card channel=channel}}`); await render(hbs`<ChatChannelPreviewCard @channel={{this.channel}} />`);
assert.ok( assert.true(
exists(".toggle-channel-membership-button.-join"), exists(".toggle-channel-membership-button.-join"),
"it shows the join channel button" "it shows the join channel button"
); );
}); });
test("browse all", async function (assert) { test("browse all", async function (assert) {
await render(hbs`{{chat-channel-preview-card channel=channel}}`); await render(hbs`<ChatChannelPreviewCard @channel={{this.channel}} />`);
assert.ok( assert.true(
exists(".chat-channel-preview-card__browse-all"), exists(".chat-channel-preview-card__browse-all"),
"it shows a link to browse all channels" "it shows a link to browse all channels"
); );
@ -84,9 +84,9 @@ module(
test("closed channel", async function (assert) { test("closed channel", async function (assert) {
this.channel.set("status", "closed"); this.channel.set("status", "closed");
await render(hbs`{{chat-channel-preview-card channel=channel}}`); await render(hbs`<ChatChannelPreviewCard @channel={{this.channel}} />`);
assert.notOk( assert.false(
exists(".chat-channel-preview-card__join-channel-btn"), exists(".chat-channel-preview-card__join-channel-btn"),
"it does not show the join channel button" "it does not show the join channel button"
); );

View File

@ -1,145 +1,115 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { exists, query } from "discourse/tests/helpers/qunit-helpers"; import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import fabricators from "../helpers/fabricators"; import fabricators from "../helpers/fabricators";
import { CHATABLE_TYPES } from "discourse/plugins/chat/discourse/models/chat-channel"; import { CHATABLE_TYPES } from "discourse/plugins/chat/discourse/models/chat-channel";
import { module } from "qunit"; import { module, test } from "qunit";
import { render } from "@ember/test-helpers";
module("Discourse Chat | Component | chat-channel-title", function (hooks) { module("Discourse Chat | Component | chat-channel-title", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("category channel", { test("category channel", async function (assert) {
template: hbs`{{chat-channel-title channel=channel}}`, this.set(
"channel",
fabricators.chatChannel({
chatable_type: CHATABLE_TYPES.categoryChannel,
})
);
beforeEach() { await render(hbs`<ChatChannelTitle @channel={{this.channel}} />`);
this.set(
"channel",
fabricators.chatChannel({
chatable_type: CHATABLE_TYPES.categoryChannel,
})
);
},
async test(assert) { assert.strictEqual(
assert.equal( query(".chat-channel-title__category-badge").getAttribute("style"),
query(".chat-channel-title__category-badge").getAttribute("style"), `color: #${this.channel.chatable.color}`
`color: #${this.channel.chatable.color}` );
); assert.strictEqual(
assert.equal( query(".chat-channel-title__name").innerText,
query(".chat-channel-title__name").innerText, this.channel.title
this.channel.title );
);
},
}); });
componentTest("category channel - escapes title", { test("category channel - escapes title", async function (assert) {
template: hbs`{{chat-channel-title channel=channel}}`, this.set(
"channel",
fabricators.chatChannel({
chatable_type: CHATABLE_TYPES.categoryChannel,
title: "<div class='xss'>evil</div>",
})
);
beforeEach() { await render(hbs`<ChatChannelTitle @channel={{this.channel}} />`);
this.set(
"channel",
fabricators.chatChannel({
chatable_type: CHATABLE_TYPES.categoryChannel,
title: "<div class='xss'>evil</div>",
})
);
},
async test(assert) { assert.false(exists(".xss"));
assert.notOk(exists(".xss"));
},
}); });
componentTest("category channel - read restricted", { test("category channel - read restricted", async function (assert) {
template: hbs`{{chat-channel-title channel=channel}}`, this.set(
"channel",
fabricators.chatChannel({
chatable_type: CHATABLE_TYPES.categoryChannel,
chatable: { read_restricted: true },
})
);
beforeEach() { await render(hbs`<ChatChannelTitle @channel={{this.channel}} />`);
this.set(
"channel",
fabricators.chatChannel({
chatable_type: CHATABLE_TYPES.categoryChannel,
chatable: { read_restricted: true },
})
);
},
async test(assert) { assert.true(exists(".d-icon-lock"));
assert.ok(exists(".d-icon-lock"));
},
}); });
componentTest("category channel - not read restricted", { test("category channel - not read restricted", async function (assert) {
template: hbs`{{chat-channel-title channel=channel}}`, this.set(
"channel",
fabricators.chatChannel({
chatable_type: CHATABLE_TYPES.categoryChannel,
chatable: { read_restricted: false },
})
);
beforeEach() { await render(hbs`<ChatChannelTitle @channel={{this.channel}} />`);
this.set(
"channel",
fabricators.chatChannel({
chatable_type: CHATABLE_TYPES.categoryChannel,
chatable: { read_restricted: false },
})
);
},
async test(assert) { assert.false(exists(".d-icon-lock"));
assert.notOk(exists(".d-icon-lock"));
},
}); });
componentTest("direct message channel - one user", { test("direct message channel - one user", async function (assert) {
template: hbs`{{chat-channel-title channel=channel}}`, this.set("channel", fabricators.directMessageChatChannel());
beforeEach() { await render(hbs`<ChatChannelTitle @channel={{this.channel}} />`);
this.set("channel", fabricators.directMessageChatChannel());
},
async test(assert) { const user = this.channel.chatable.users[0];
const user = this.channel.chatable.users[0];
assert.ok( assert.true(
exists(`.chat-user-avatar-container .avatar[title="${user.username}"]`) exists(`.chat-user-avatar-container .avatar[title="${user.username}"]`)
); );
assert.equal( assert.strictEqual(
query(".chat-channel-title__name").innerText.trim(), query(".chat-channel-title__name").innerText.trim(),
user.username user.username
); );
},
}); });
componentTest("direct message channel - multiple users", { test("direct message channel - multiple users", async function (assert) {
template: hbs`{{chat-channel-title channel=channel}}`, const channel = fabricators.directMessageChatChannel();
beforeEach() { channel.chatable.users.push({
const channel = fabricators.directMessageChatChannel(); id: 2,
username: "joffrey",
name: null,
avatar_template: "/letter_avatar_proxy/v3/letter/t/31188e/{size}.png",
});
channel.chatable.users.push({ this.set("channel", channel);
id: 2,
username: "joffrey",
name: null,
avatar_template: "/letter_avatar_proxy/v3/letter/t/31188e/{size}.png",
});
this.set("channel", channel); await render(hbs`<ChatChannelTitle @channel={{this.channel}} />`);
},
async test(assert) { const users = this.channel.chatable.users;
const users = this.channel.chatable.users; assert.strictEqual(
parseInt(query(".chat-channel-title__users-count").innerText.trim(), 10),
assert.equal( users.length
parseInt( );
query(".chat-channel-title__users-count").innerText.trim(), assert.strictEqual(
10 query(".chat-channel-title__name").innerText.trim(),
), users.mapBy("username").join(", ")
users.length );
);
assert.equal(
query(".chat-channel-title__name").innerText.trim(),
users.mapBy("username").join(", ")
);
},
}); });
}); });

View File

@ -1,28 +1,21 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { 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";
import { click } from "@ember/test-helpers"; import { click, render } from "@ember/test-helpers";
import { module } from "qunit"; import { module, test } from "qunit";
module("Discourse Chat | Component | chat-composer-dropdown", function (hooks) { module("Discourse Chat | Component | chat-composer-dropdown", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("buttons", { test("buttons", async function (assert) {
template: hbs`{{chat-composer-dropdown buttons=buttons}}`, this.set("buttons", [{ id: "foo", icon: "times", action: () => {} }]);
async beforeEach() { await render(hbs`<ChatComposerDropdown @buttons={{this.buttons}} />`);
this.set("buttons", [{ id: "foo", icon: "times", action: () => {} }]); await click(".chat-composer-dropdown__trigger-btn");
},
async test(assert) { assert.true(exists(".chat-composer-dropdown__item.foo"));
await click(".chat-composer-dropdown__trigger-btn"); assert.true(
exists(".chat-composer-dropdown__action-btn.foo .d-icon-times")
assert.ok(exists(".chat-composer-dropdown__item.foo")); );
assert.ok(
exists(".chat-composer-dropdown__action-btn.foo .d-icon-times")
);
},
}); });
}); });

View File

@ -1,26 +1,23 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { 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";
import { module } from "qunit"; import { module, test } from "qunit";
import { render } from "@ember/test-helpers";
module( module(
"Discourse Chat | Component | chat-composer-inline-buttons", "Discourse Chat | Component | chat-composer-inline-buttons",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("buttons", { test("buttons", async function (assert) {
template: hbs`{{chat-composer-inline-buttons buttons=buttons}}`, this.set("buttons", [{ id: "foo", icon: "times", action: () => {} }]);
async beforeEach() { await render(
this.set("buttons", [{ id: "foo", icon: "times", action: () => {} }]); hbs`<ChatComposerInlineButtons @buttons={{this.buttons}} />`
}, );
async test(assert) { assert.true(exists(".chat-composer-inline-button.foo"));
assert.ok(exists(".chat-composer-inline-button.foo")); assert.true(exists(".chat-composer-inline-button.foo .d-icon-times"));
assert.ok(exists(".chat-composer-inline-button.foo .d-icon-times"));
},
}); });
} }
); );

View File

@ -1,87 +1,73 @@
import { set } from "@ember/object"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { 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 ChatChannel from "discourse/plugins/chat/discourse/models/chat-channel"; import ChatChannel from "discourse/plugins/chat/discourse/models/chat-channel";
import { module } from "qunit"; import { module, test } from "qunit";
import { render } from "@ember/test-helpers";
module( module(
"Discourse Chat | Component | chat-composer placeholder", "Discourse Chat | Component | chat-composer placeholder",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("direct message to self shows Jot something down", { test("direct message to self shows Jot something down", async function (assert) {
template: hbs`{{chat-composer chatChannel=chatChannel}}`, this.currentUser.set("id", 1);
this.set(
"chatChannel",
ChatChannel.create({
chatable_type: "DirectMessage",
chatable: {
users: [{ id: 1 }],
},
})
);
beforeEach() { await render(hbs`<ChatComposer @chatChannel={{this.chatChannel}} />`);
set(this.currentUser, "id", 1);
this.set(
"chatChannel",
ChatChannel.create({
chatable_type: "DirectMessage",
chatable: {
users: [{ id: 1 }],
},
})
);
},
async test(assert) { assert.strictEqual(
assert.equal( query(".chat-composer-input").placeholder,
query(".chat-composer-input").placeholder, "Jot something down"
"Jot something down" );
);
},
}); });
componentTest("direct message to multiple folks shows their names", { test("direct message to multiple folks shows their names", async function (assert) {
template: hbs`{{chat-composer chatChannel=chatChannel}}`, this.set(
"chatChannel",
ChatChannel.create({
chatable_type: "DirectMessage",
chatable: {
users: [
{ name: "Tomtom" },
{ name: "Steaky" },
{ username: "zorro" },
],
},
})
);
beforeEach() { await render(hbs`<ChatComposer @chatChannel={{this.chatChannel}} />`);
this.set(
"chatChannel",
ChatChannel.create({
chatable_type: "DirectMessage",
chatable: {
users: [
{ name: "Tomtom" },
{ name: "Steaky" },
{ username: "zorro" },
],
},
})
);
},
async test(assert) { assert.strictEqual(
assert.equal( query(".chat-composer-input").placeholder,
query(".chat-composer-input").placeholder, "Chat with Tomtom, Steaky, @zorro"
"Chat with Tomtom, Steaky, @zorro" );
);
},
}); });
componentTest("message to channel shows send message to channel name", { test("message to channel shows send message to channel name", async function (assert) {
template: hbs`{{chat-composer chatChannel=chatChannel}}`, this.set(
"chatChannel",
ChatChannel.create({
chatable_type: "Category",
title: "just-cats",
})
);
beforeEach() { await render(hbs`<ChatComposer @chatChannel={{this.chatChannel}} />`);
this.set(
"chatChannel",
ChatChannel.create({
chatable_type: "Category",
title: "just-cats",
})
);
},
async test(assert) { assert.strictEqual(
assert.equal( query(".chat-composer-input").placeholder,
query(".chat-composer-input").placeholder, "Chat with #just-cats"
"Chat with #just-cats" );
);
},
}); });
} }
); );

View File

@ -1,158 +1,132 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { exists, query } from "discourse/tests/helpers/qunit-helpers"; import { 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"; import { click, render } from "@ember/test-helpers";
import { module } from "qunit"; import { module, test } from "qunit";
module("Discourse Chat | Component | chat-composer-upload", function (hooks) { module("Discourse Chat | Component | chat-composer-upload", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("file - uploading in progress", { test("file - uploading in progress", async function (assert) {
template: hbs`{{chat-composer-upload upload=upload}}`, this.set("upload", {
progress: 50,
extension: ".pdf",
fileName: "test.pdf",
});
beforeEach() { await render(hbs`<ChatComposerUpload @upload={{this.upload}} />`);
this.set("upload", {
progress: 50,
extension: ".pdf",
fileName: "test.pdf",
});
},
async test(assert) { assert.true(exists(".upload-progress[value=50]"));
assert.ok(exists(".upload-progress[value=50]")); assert.strictEqual(
assert.strictEqual( query(".uploading").innerText.trim(),
query(".uploading").innerText.trim(), I18n.t("uploading")
I18n.t("uploading") );
);
},
}); });
componentTest("image - uploading in progress", { test("image - uploading in progress", async function (assert) {
template: hbs`{{chat-composer-upload upload=upload}}`, this.set("upload", {
extension: ".png",
progress: 78,
fileName: "test.png",
});
beforeEach() { await render(hbs`<ChatComposerUpload @upload={{this.upload}} />`);
this.set("upload", {
extension: ".png",
progress: 78,
fileName: "test.png",
});
},
async test(assert) { assert.true(exists(".d-icon-far-image"));
assert.ok(exists(".d-icon-far-image")); assert.true(exists(".upload-progress[value=78]"));
assert.ok(exists(".upload-progress[value=78]")); assert.strictEqual(
assert.strictEqual( query(".uploading").innerText.trim(),
query(".uploading").innerText.trim(), I18n.t("uploading")
I18n.t("uploading") );
);
},
}); });
componentTest("image - preprocessing upload in progress", { test("image - preprocessing upload in progress", async function (assert) {
template: hbs`{{chat-composer-upload upload=upload}}`, this.set("upload", {
extension: ".png",
progress: 78,
fileName: "test.png",
processing: true,
});
beforeEach() { await render(hbs`<ChatComposerUpload @upload={{this.upload}} />`);
this.set("upload", {
extension: ".png",
progress: 78,
fileName: "test.png",
processing: true,
});
},
async test(assert) { assert.strictEqual(
assert.strictEqual( query(".processing").innerText.trim(),
query(".processing").innerText.trim(), I18n.t("processing")
I18n.t("processing") );
);
},
}); });
componentTest("file - upload complete", { test("file - upload complete", async function (assert) {
template: hbs`{{chat-composer-upload isDone=true upload=upload}}`, this.set("upload", {
type: ".pdf",
original_filename: "some file.pdf",
extension: "pdf",
});
beforeEach() { await render(
this.set("upload", { hbs`<ChatComposerUpload @isDone={{true}} @upload={{this.upload}} />`
type: ".pdf", );
original_filename: "some file.pdf",
extension: "pdf",
});
},
async test(assert) { assert.true(exists(".d-icon-file-alt"));
assert.ok(exists(".d-icon-file-alt")); assert.strictEqual(query(".file-name").innerText.trim(), "some file.pdf");
assert.strictEqual(query(".file-name").innerText.trim(), "some file.pdf"); assert.strictEqual(query(".extension-pill").innerText.trim(), "pdf");
assert.strictEqual(query(".extension-pill").innerText.trim(), "pdf");
},
}); });
componentTest("image - upload complete", { test("image - upload complete", async function (assert) {
template: hbs`{{chat-composer-upload isDone=true upload=upload}}`, this.set("upload", {
type: ".png",
original_filename: "bar_image.png",
extension: "png",
short_path: "/images/avatar.png",
});
beforeEach() { await render(
this.set("upload", { hbs`<ChatComposerUpload @isDone={{true}} @upload={{this.upload}} />`
type: ".png", );
original_filename: "bar_image.png",
extension: "png",
short_path: "/images/avatar.png",
});
},
async test(assert) { assert.true(exists("img.preview-img[src='/images/avatar.png']"));
assert.ok(exists("img.preview-img[src='/images/avatar.png']")); assert.strictEqual(query(".file-name").innerText.trim(), "bar_image.png");
assert.strictEqual(query(".file-name").innerText.trim(), "bar_image.png"); assert.strictEqual(query(".extension-pill").innerText.trim(), "png");
assert.strictEqual(query(".extension-pill").innerText.trim(), "png");
},
}); });
componentTest("removing completed upload", { test("removing completed upload", async function (assert) {
template: hbs`{{chat-composer-upload isDone=true upload=upload onCancel=(action "removeUpload" upload)}}`, this.set("uploadRemoved", false);
this.set("removeUpload", () => {
this.set("uploadRemoved", true);
});
this.set("upload", {
type: ".png",
original_filename: "bar_image.png",
extension: "png",
short_path: "/images/avatar.png",
});
beforeEach() { await render(
this.set("uploadRemoved", false); hbs`<ChatComposerUpload @isDone={{true}} @upload={{this.upload}} @onCancel={{fn this.removeUpload this.upload}} />`
this.set("actions", { );
removeUpload: () => {
this.set("uploadRemoved", true);
},
});
this.set("upload", {
type: ".png",
original_filename: "bar_image.png",
extension: "png",
short_path: "/images/avatar.png",
});
},
async test(assert) { await click(".remove-upload");
await click(".remove-upload"); assert.strictEqual(this.uploadRemoved, true);
assert.strictEqual(this.uploadRemoved, true);
},
}); });
componentTest("cancelling in progress upload", { test("cancelling in progress upload", async function (assert) {
template: hbs`{{chat-composer-upload upload=upload onCancel=(action "removeUpload" upload)}}`, this.set("uploadRemoved", false);
this.set("removeUpload", () => {
this.set("uploadRemoved", true);
});
this.set("upload", {
type: ".png",
original_filename: "bar_image.png",
extension: "png",
short_path: "/images/avatar.png",
});
beforeEach() { await render(
this.set("uploadRemoved", false); hbs`<ChatComposerUpload @upload={{this.upload}} @onCancel={{fn this.removeUpload this.upload}} />`
this.set("actions", { );
removeUpload: () => {
this.set("uploadRemoved", true);
},
});
this.set("upload", {
type: ".png",
original_filename: "bar_image.png",
extension: "png",
short_path: "/images/avatar.png",
});
},
async test(assert) { await click(".remove-upload");
await click(".remove-upload"); assert.strictEqual(this.uploadRemoved, true);
assert.strictEqual(this.uploadRemoved, true);
},
}); });
}); });

View File

@ -1,6 +1,4 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import pretender from "discourse/tests/helpers/create-pretender"; import pretender from "discourse/tests/helpers/create-pretender";
import { import {
count, count,
@ -8,8 +6,8 @@ import {
exists, exists,
} 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, settled, waitFor } from "@ember/test-helpers"; import { click, render, settled, waitFor } from "@ember/test-helpers";
import { module } from "qunit"; import { module, test } from "qunit";
import { run } from "@ember/runloop"; import { run } from "@ember/runloop";
const fakeUpload = { const fakeUpload = {
@ -48,116 +46,107 @@ function setupUploadPretender() {
module("Discourse Chat | Component | chat-composer-uploads", function (hooks) { module("Discourse Chat | Component | chat-composer-uploads", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest( test("loading uploads from an outside source (e.g. draft or editing message)", async function (assert) {
"loading uploads from an outside source (e.g. draft or editing message)", await render(hbs`
{ <ChatComposerUploads @fileUploadElementId="chat-widget-uploader" />
template: hbs`{{chat-composer-uploads fileUploadElementId="chat-widget-uploader"}}`, `);
async test(assert) { this.appEvents = this.container.lookup("service:appEvents");
this.appEvents = this.container.lookup("service:appEvents"); this.appEvents.trigger("chat-composer:load-uploads", [fakeUpload]);
this.appEvents.trigger("chat-composer:load-uploads", [fakeUpload]); await settled();
await settled();
assert.strictEqual(count(".chat-composer-upload"), 1); assert.strictEqual(count(".chat-composer-upload"), 1);
assert.strictEqual(exists(".chat-composer-upload"), true); assert.strictEqual(exists(".chat-composer-upload"), true);
},
}
);
componentTest("upload starts and completes", {
template: hbs`{{chat-composer-uploads fileUploadElementId="chat-widget-uploader" onUploadChanged=onUploadChanged}}`,
beforeEach() {
setupUploadPretender();
this.set("changedUploads", null);
this.set("onUploadChanged", (uploads) => {
this.set("changedUploads", uploads);
});
},
async test(assert) {
const done = assert.async();
this.appEvents = this.container.lookup("service:appEvents");
this.appEvents.on(
"upload-mixin:chat-composer-uploader:upload-success",
(fileName, upload) => {
assert.strictEqual(fileName, "avatar.png");
assert.deepEqual(upload, mockUploadResponse);
done();
}
);
this.appEvents.trigger(
"upload-mixin:chat-composer-uploader:add-files",
createFile("avatar.png")
);
await waitFor(".chat-composer-upload");
assert.strictEqual(count(".chat-composer-upload"), 1);
},
}); });
componentTest("removing a completed upload", { test("upload starts and completes", async function (assert) {
template: hbs`{{chat-composer-uploads fileUploadElementId="chat-widget-uploader" onUploadChanged=onUploadChanged}}`, setupUploadPretender();
this.set("changedUploads", null);
this.set("onUploadChanged", (uploads) => {
this.set("changedUploads", uploads);
});
beforeEach() { await render(hbs`
this.set("changedUploads", null); <ChatComposerUploads @fileUploadElementId="chat-widget-uploader" @onUploadChanged={{this.onUploadChanged}} />
this.set("onUploadChanged", (uploads) => { `);
this.set("changedUploads", uploads);
});
},
async test(assert) { const done = assert.async();
this.appEvents = this.container.lookup("service:appEvents"); this.appEvents = this.container.lookup("service:appEvents");
run(() => this.appEvents.on(
this.appEvents.trigger("chat-composer:load-uploads", [fakeUpload]) "upload-mixin:chat-composer-uploader:upload-success",
); (fileName, upload) => {
assert.strictEqual(count(".chat-composer-upload"), 1); assert.strictEqual(fileName, "avatar.png");
assert.deepEqual(upload, mockUploadResponse);
done();
}
);
await click(".remove-upload"); this.appEvents.trigger(
assert.strictEqual(count(".chat-composer-upload"), 0); "upload-mixin:chat-composer-uploader:add-files",
}, createFile("avatar.png")
);
await waitFor(".chat-composer-upload");
assert.strictEqual(count(".chat-composer-upload"), 1);
}); });
componentTest("cancelling in progress upload", { test("removing a completed upload", async function (assert) {
template: hbs`{{chat-composer-uploads fileUploadElementId="chat-widget-uploader" onUploadChanged=onUploadChanged}}`, this.set("changedUploads", null);
this.set("onUploadChanged", (uploads) => {
this.set("changedUploads", uploads);
});
beforeEach() { await render(hbs`
setupUploadPretender(); <ChatComposerUploads @fileUploadElementId="chat-widget-uploader" @onUploadChanged={{this.onUploadChanged}} />
`);
this.set("changedUploads", null); this.appEvents = this.container.lookup("service:appEvents");
this.set("onUploadChanged", (uploads) => { run(() =>
this.set("changedUploads", uploads); this.appEvents.trigger("chat-composer:load-uploads", [fakeUpload])
}); );
}, assert.strictEqual(count(".chat-composer-upload"), 1);
async test(assert) { await click(".remove-upload");
const image = createFile("avatar.png"); assert.strictEqual(count(".chat-composer-upload"), 0);
const done = assert.async(); });
this.appEvents = this.container.lookup("service:appEvents");
this.appEvents.on( test("cancelling in progress upload", async function (assert) {
`upload-mixin:chat-composer-uploader:upload-cancelled`, setupUploadPretender();
(fileId) => {
assert.strictEqual(
fileId.includes("uppy-avatar/"),
true,
"upload was cancelled"
);
done();
}
);
this.appEvents.trigger( this.set("changedUploads", null);
"upload-mixin:chat-composer-uploader:add-files", this.set("onUploadChanged", (uploads) => {
image this.set("changedUploads", uploads);
); });
await waitFor(".chat-composer-upload"); await render(hbs`
assert.strictEqual(count(".chat-composer-upload"), 1); <ChatComposerUploads @fileUploadElementId="chat-widget-uploader" @onUploadChanged={{this.onUploadChanged}} />
`);
await click(".remove-upload"); const image = createFile("avatar.png");
assert.strictEqual(count(".chat-composer-upload"), 0); const done = assert.async();
}, this.appEvents = this.container.lookup("service:appEvents");
this.appEvents.on(
`upload-mixin:chat-composer-uploader:upload-cancelled`,
(fileId) => {
assert.strictEqual(
fileId.includes("uppy-avatar/"),
true,
"upload was cancelled"
);
done();
}
);
this.appEvents.trigger(
"upload-mixin:chat-composer-uploader:add-files",
image
);
await waitFor(".chat-composer-upload");
assert.strictEqual(count(".chat-composer-upload"), 1);
await click(".remove-upload");
assert.strictEqual(count(".chat-composer-upload"), 0);
}); });
}); });

View File

@ -1,26 +1,21 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { 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";
import { module } from "qunit"; import { module, test } from "qunit";
import { render } from "@ember/test-helpers";
module("Discourse Chat | Component | chat-emoji-avatar", function (hooks) { module("Discourse Chat | Component | chat-emoji-avatar", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("uses an emoji as avatar", { test("uses an emoji as avatar", async function (assert) {
template: hbs`{{chat-emoji-avatar emoji=emoji}}`, this.set("emoji", ":otter:");
async beforeEach() { await render(hbs`<ChatEmojiAvatar @emoji={{this.emoji}} />`);
this.set("emoji", ":otter:");
},
async test(assert) { assert.true(
assert.ok( exists(
exists( `.chat-emoji-avatar .chat-emoji-avatar-container .emoji[title=otter]`
`.chat-emoji-avatar .chat-emoji-avatar-container .emoji[title=otter]` )
) );
);
},
}); });
}); });

View File

@ -83,21 +83,21 @@ module("Discourse Chat | Component | chat-emoji-picker", function (hooks) {
test("When displaying navigation", async function (assert) { test("When displaying navigation", async function (assert) {
await render(hbs`<ChatEmojiPicker />`); await render(hbs`<ChatEmojiPicker />`);
assert.ok( assert.true(
exists( exists(
`.chat-emoji-picker__section-btn.active[data-section="favorites"]` `.chat-emoji-picker__section-btn.active[data-section="favorites"]`
), ),
"it renders first section as active" "it renders first section as active"
); );
assert.ok( assert.true(
exists( exists(
`.chat-emoji-picker__section-btn[data-section="smileys_&_emotion"]` `.chat-emoji-picker__section-btn[data-section="smileys_&_emotion"]`
) )
); );
assert.ok( assert.true(
exists(`.chat-emoji-picker__section-btn[data-section="people_&_body"]`) exists(`.chat-emoji-picker__section-btn[data-section="people_&_body"]`)
); );
assert.ok( assert.true(
exists(`.chat-emoji-picker__section-btn[data-section="objects"]`) exists(`.chat-emoji-picker__section-btn[data-section="objects"]`)
); );
}); });
@ -107,11 +107,11 @@ module("Discourse Chat | Component | chat-emoji-picker", function (hooks) {
await click(".chat-emoji-picker__fitzpatrick-modifier-btn.current.t1"); await click(".chat-emoji-picker__fitzpatrick-modifier-btn.current.t1");
await click(".chat-emoji-picker__fitzpatrick-modifier-btn.t6"); await click(".chat-emoji-picker__fitzpatrick-modifier-btn.t6");
assert.ok( assert.true(
exists(`img[src="/images/emoji/twitter/raised_hands/6.png"]`), exists(`img[src="/images/emoji/twitter/raised_hands/6.png"]`),
"it applies the tone to emojis" "it applies the tone to emojis"
); );
assert.ok( assert.true(
exists(".chat-emoji-picker__fitzpatrick-modifier-btn.current.t6"), exists(".chat-emoji-picker__fitzpatrick-modifier-btn.current.t6"),
"it changes the current scale to t6" "it changes the current scale to t6"
); );
@ -127,7 +127,7 @@ module("Discourse Chat | Component | chat-emoji-picker", function (hooks) {
await click(`.chat-emoji-picker__section-btn[data-section="objects"]`); await click(`.chat-emoji-picker__section-btn[data-section="objects"]`);
assert.ok( assert.true(
document.querySelector("#ember-testing-container").scrollTop > 0, document.querySelector("#ember-testing-container").scrollTop > 0,
"it scrolls to the section" "it scrolls to the section"
); );
@ -142,21 +142,21 @@ module("Discourse Chat | Component | chat-emoji-picker", function (hooks) {
1, 1,
"it filters the emojis list" "it filters the emojis list"
); );
assert.ok( assert.true(
exists('.chat-emoji-picker__sections > img[alt="grinning"]'), exists('.chat-emoji-picker__sections > img[alt="grinning"]'),
"it filters the correct emoji" "it filters the correct emoji"
); );
await fillIn(".dc-filter-input", "Grinning"); await fillIn(".dc-filter-input", "Grinning");
assert.ok( assert.true(
exists('.chat-emoji-picker__sections > img[alt="grinning"]'), exists('.chat-emoji-picker__sections > img[alt="grinning"]'),
"it is case insensitive" "it is case insensitive"
); );
await fillIn(".dc-filter-input", "smiley_cat"); await fillIn(".dc-filter-input", "smiley_cat");
assert.ok( assert.true(
exists('.chat-emoji-picker__sections > img[alt="grinning"]'), exists('.chat-emoji-picker__sections > img[alt="grinning"]'),
"it filters the correct emoji using search alias" "it filters the correct emoji using search alias"
); );
@ -193,7 +193,7 @@ module("Discourse Chat | Component | chat-emoji-picker", function (hooks) {
test("When opening the picker", async function (assert) { test("When opening the picker", async function (assert) {
await render(hbs`<ChatEmojiPicker />`); await render(hbs`<ChatEmojiPicker />`);
assert.ok(document.activeElement.classList.contains("dc-filter-input")); assert.true(document.activeElement.classList.contains("dc-filter-input"));
}); });
test("When hovering an emoji", async function (assert) { test("When hovering an emoji", async function (assert) {

View File

@ -30,15 +30,15 @@ module("Discourse Chat | Component | chat-live-pane", function (hooks) {
); );
await render( await render(
hbs`{{chat-live-pane loadingMorePast=true chat=chat chatChannel=channel}}` hbs`<ChatLivePane @loadingMorePast={{true}} @chat={{this.chat}} @chatChannel={{this.channel}} />`
); );
assert.ok(exists(".chat-skeleton")); assert.true(exists(".chat-skeleton"));
await render( await render(
hbs`{{chat-live-pane loadingMoreFuture=true chat=chat chatChannel=channel}}` hbs`<ChatLivePane @loadingMoreFuture={{true}} @chat={{this.chat}} @chatChannel={{this.channel}} />`
); );
assert.ok(exists(".chat-skeleton")); assert.true(exists(".chat-skeleton"));
}); });
}); });

View File

@ -1,34 +1,25 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { exists, query } from "discourse/tests/helpers/qunit-helpers"; import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import { module } from "qunit"; import { module, test } from "qunit";
import { render } from "@ember/test-helpers";
module("Discourse Chat | Component | chat-message-avatar", function (hooks) { module("Discourse Chat | Component | chat-message-avatar", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("chat_webhook_event", { test("chat_webhook_event", async function (assert) {
template: hbs`{{chat-message-avatar message=message}}`, this.set("message", { chat_webhook_event: { emoji: ":heart:" } });
beforeEach() { await render(hbs`<ChatMessageAvatar @message={{this.message}} />`);
this.set("message", { chat_webhook_event: { emoji: ":heart:" } });
},
async test(assert) { assert.strictEqual(query(".chat-emoji-avatar .emoji").title, "heart");
assert.equal(query(".chat-emoji-avatar .emoji").title, "heart");
},
}); });
componentTest("user", { test("user", async function (assert) {
template: hbs`{{chat-message-avatar message=message}}`, this.set("message", { user: { username: "discobot" } });
beforeEach() { await render(hbs`<ChatMessageAvatar @message={{this.message}} />`);
this.set("message", { user: { username: "discobot" } });
},
async test(assert) { assert.true(exists('.chat-user-avatar [data-user-card="discobot"]'));
assert.ok(exists('.chat-user-avatar [data-user-card="discobot"]'));
},
}); });
}); });

View File

@ -1,6 +1,4 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { click, render } from "@ember/test-helpers"; import { click, render } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { import {
@ -57,9 +55,9 @@ module("Discourse Chat | Component | chat message collapser", function (hooks) {
test("escapes uploads header", async function (assert) { test("escapes uploads header", async function (assert) {
this.set("uploads", [{ original_filename: evilString }]); this.set("uploads", [{ original_filename: evilString }]);
await render(hbs`{{chat-message-collapser uploads=uploads}}`); await render(hbs`<ChatMessageCollapser @uploads={{this.uploads}} />`);
assert.ok( assert.true(
query(".chat-message-collapser-link-small").innerHTML.includes( query(".chat-message-collapser-link-small").innerHTML.includes(
evilStringEscaped evilStringEscaped
) )
@ -74,115 +72,109 @@ module(
test("escapes youtube header", async function (assert) { test("escapes youtube header", async function (assert) {
this.set("cooked", youtubeCooked.replace("ytId1", evilString)); this.set("cooked", youtubeCooked.replace("ytId1", evilString));
await render(hbs`{{chat-message-collapser cooked=cooked}}`); await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
assert.ok( assert.true(
query(".chat-message-collapser-link").href.includes( query(".chat-message-collapser-link").href.includes(
"%3Cscript%3Esomeeviltitle%3C/script%3E" "%3Cscript%3Esomeeviltitle%3C/script%3E"
) )
); );
}); });
componentTest("shows youtube link in header", { test("shows youtube link in header", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", youtubeCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", youtubeCooked);
},
async test(assert) { const link = queryAll(".chat-message-collapser-link");
const link = document.querySelectorAll(".chat-message-collapser-link");
assert.equal(link.length, 2, "two youtube links rendered"); assert.strictEqual(link.length, 2, "two youtube links rendered");
assert.strictEqual( assert.strictEqual(link[0].href, "https://www.youtube.com/watch?v=ytId1");
link[0].href, assert.strictEqual(link[1].href, "https://www.youtube.com/watch?v=ytId2");
"https://www.youtube.com/watch?v=ytId1"
);
assert.strictEqual(
link[1].href,
"https://www.youtube.com/watch?v=ytId2"
);
},
}); });
componentTest("shows all user written text", { test("shows all user written text", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, youtubeCooked.youtubeid;
this.set("cooked", youtubeCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
youtubeCooked.youtubeid;
this.set("cooked", youtubeCooked);
},
async test(assert) { const text = queryAll(".chat-message-collapser p");
const text = document.querySelectorAll(".chat-message-collapser p");
assert.equal(text.length, 3, "shows all written text"); assert.strictEqual(text.length, 3, "shows all written text");
assert.strictEqual( assert.strictEqual(
text[0].innerText, text[0].innerText,
"written text", "written text",
"first line of written text" "first line of written text"
); );
assert.strictEqual( assert.strictEqual(
text[1].innerText, text[1].innerText,
"more written text", "more written text",
"third line of written text" "third line of written text"
); );
assert.strictEqual( assert.strictEqual(
text[2].innerText, text[2].innerText,
"and even more", "and even more",
"fifth line of written text" "fifth line of written text"
); );
},
}); });
componentTest("collapses and expands cooked youtube", { test("collapses and expands cooked youtube", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", youtubeCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", youtubeCooked);
},
async test(assert) { const youtubeDivs = queryAll(".onebox");
const youtubeDivs = document.querySelectorAll(".onebox");
assert.equal(youtubeDivs.length, 2, "two youtube previews rendered"); assert.strictEqual(
youtubeDivs.length,
2,
"two youtube previews rendered"
);
await click( await click(
document.querySelectorAll(".chat-message-collapser-opened")[0], queryAll(".chat-message-collapser-opened")[0],
"close first preview" "close first preview"
); );
assert.notOk( assert.false(
visible(".onebox[data-youtube-id='ytId1']"), visible(".onebox[data-youtube-id='ytId1']"),
"first youtube preview hidden" "first youtube preview hidden"
); );
assert.ok( assert.true(
visible(".onebox[data-youtube-id='ytId2']"), visible(".onebox[data-youtube-id='ytId2']"),
"second youtube preview still visible" "second youtube preview still visible"
); );
await click(".chat-message-collapser-closed"); await click(".chat-message-collapser-closed");
assert.equal(youtubeDivs.length, 2, "two youtube previews rendered"); assert.strictEqual(
youtubeDivs.length,
2,
"two youtube previews rendered"
);
await click( await click(
document.querySelectorAll(".chat-message-collapser-opened")[1], queryAll(".chat-message-collapser-opened")[1],
"close second preview" "close second preview"
); );
assert.ok( assert.true(
visible(".onebox[data-youtube-id='ytId1']"), visible(".onebox[data-youtube-id='ytId1']"),
"first youtube preview still visible" "first youtube preview still visible"
); );
assert.notOk( assert.false(
visible(".onebox[data-youtube-id='ytId2']"), visible(".onebox[data-youtube-id='ytId2']"),
"second youtube preview hidden" "second youtube preview hidden"
); );
await click(".chat-message-collapser-closed"); await click(".chat-message-collapser-closed");
assert.equal(youtubeDivs.length, 2, "two youtube previews rendered"); assert.strictEqual(
}, youtubeDivs.length,
2,
"two youtube previews rendered"
);
}); });
} }
); );
@ -193,65 +185,57 @@ module(
setupRenderingTest(hooks); setupRenderingTest(hooks);
const imageTextCooked = "<p>A picture of Tomtom</p>"; const imageTextCooked = "<p>A picture of Tomtom</p>";
componentTest("shows filename for one image", { test("shows filename for one image", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked uploads=uploads}}`, this.set("cooked", imageTextCooked);
this.set("uploads", [{ original_filename: "tomtom.jpeg" }]);
beforeEach() { await render(
this.set("cooked", imageTextCooked); hbs`<ChatMessageCollapser @cooked={{this.cooked}} @uploads={{this.uploads}} />`
this.set("uploads", [{ original_filename: "tomtom.jpeg" }]); );
},
async test(assert) { assert.true(
assert.ok( query(".chat-message-collapser-link-small").innerText.includes(
query(".chat-message-collapser-link-small").innerText.includes( "tomtom.jpeg"
"tomtom.jpeg" )
) );
);
},
}); });
componentTest("shows number of files for multiple images", { test("shows number of files for multiple images", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked uploads=uploads}}`, this.set("cooked", imageTextCooked);
this.set("uploads", [{}, {}]);
beforeEach() { await render(
this.set("cooked", imageTextCooked); hbs`<ChatMessageCollapser @cooked={{this.cooked}} @uploads={{this.uploads}} />`
this.set("uploads", [{}, {}]); );
},
async test(assert) { assert.true(
assert.ok( query(".chat-message-collapser-link-small").innerText.includes(
query(".chat-message-collapser-link-small").innerText.includes( "2 files"
"2 files" )
) );
);
},
}); });
componentTest("collapses and expands images", { test("collapses and expands images", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked uploads=uploads}}`, this.set("cooked", imageTextCooked);
this.set("uploads", [{ original_filename: "tomtom.png" }]);
beforeEach() { await render(
this.set("cooked", imageTextCooked); hbs`<ChatMessageCollapser @cooked={{this.cooked}} @uploads={{this.uploads}} />`
this.set("uploads", [{ original_filename: "tomtom.png" }]); );
},
async test(assert) { const uploads = ".chat-uploads";
const uploads = ".chat-uploads"; const chatImageUpload = ".chat-img-upload";
const chatImageUpload = ".chat-img-upload";
assert.ok(visible(uploads)); assert.true(visible(uploads));
assert.ok(visible(chatImageUpload)); assert.true(visible(chatImageUpload));
await click(".chat-message-collapser-opened"); await click(".chat-message-collapser-opened");
assert.false(visible(uploads));
assert.false(visible(chatImageUpload));
assert.notOk(visible(uploads)); await click(".chat-message-collapser-closed");
assert.notOk(visible(chatImageUpload)); assert.true(visible(uploads));
assert.true(visible(chatImageUpload));
await click(".chat-message-collapser-closed");
assert.ok(visible(uploads));
assert.ok(visible(chatImageUpload));
},
}); });
} }
); );
@ -261,93 +245,79 @@ module(
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("shows links for animated image", { test("shows links for animated image", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", animatedImageCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", animatedImageCooked);
},
async test(assert) { const links = queryAll("a.chat-message-collapser-link-small");
const links = document.querySelectorAll(
"a.chat-message-collapser-link-small"
);
assert.ok(links[0].innerText.trim().includes("avatar.png")); assert.true(links[0].innerText.trim().includes("avatar.png"));
assert.ok(links[0].href.includes("avatar.png")); assert.true(links[0].href.includes("avatar.png"));
assert.ok( assert.true(
links[1].innerText.trim().includes("d-logo-sketch-small.png") links[1].innerText.trim().includes("d-logo-sketch-small.png")
); );
assert.ok(links[1].href.includes("d-logo-sketch-small.png")); assert.true(links[1].href.includes("d-logo-sketch-small.png"));
},
}); });
componentTest("shows all user written text", { test("shows all user written text", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", animatedImageCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", animatedImageCooked);
},
async test(assert) { const text = queryAll(".chat-message-collapser p");
const text = document.querySelectorAll(".chat-message-collapser p");
assert.equal(text.length, 5, "shows all written text"); assert.strictEqual(text.length, 5, "shows all written text");
assert.strictEqual(text[0].innerText, "written text"); assert.strictEqual(text[0].innerText, "written text");
assert.strictEqual(text[2].innerText, "more written text"); assert.strictEqual(text[2].innerText, "more written text");
assert.strictEqual(text[4].innerText, "and even more"); assert.strictEqual(text[4].innerText, "and even more");
},
}); });
componentTest("collapses and expands animated image onebox", { test("collapses and expands animated image onebox", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", animatedImageCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", animatedImageCooked);
},
async test(assert) { const animatedOneboxes = queryAll(".animated.onebox");
const animatedOneboxes = document.querySelectorAll(".animated.onebox");
assert.equal(animatedOneboxes.length, 2, "two oneboxes rendered"); assert.strictEqual(animatedOneboxes.length, 2, "two oneboxes rendered");
await click( await click(
document.querySelectorAll(".chat-message-collapser-opened")[0], queryAll(".chat-message-collapser-opened")[0],
"close first preview" "close first preview"
); );
assert.notOk( assert.false(
visible(".onebox[src='/images/avatar.png']"), visible(".onebox[src='/images/avatar.png']"),
"first onebox hidden" "first onebox hidden"
); );
assert.ok( assert.true(
visible(".onebox[src='/images/d-logo-sketch-small.png']"), visible(".onebox[src='/images/d-logo-sketch-small.png']"),
"second onebox still visible" "second onebox still visible"
); );
await click(".chat-message-collapser-closed"); await click(".chat-message-collapser-closed");
assert.equal(animatedOneboxes.length, 2, "two oneboxes rendered"); assert.strictEqual(animatedOneboxes.length, 2, "two oneboxes rendered");
await click( await click(
document.querySelectorAll(".chat-message-collapser-opened")[1], queryAll(".chat-message-collapser-opened")[1],
"close second preview" "close second preview"
); );
assert.ok( assert.true(
visible(".onebox[src='/images/avatar.png']"), visible(".onebox[src='/images/avatar.png']"),
"first onebox still visible" "first onebox still visible"
); );
assert.notOk( assert.false(
visible(".onebox[src='/images/d-logo-sketch-small.png']"), visible(".onebox[src='/images/d-logo-sketch-small.png']"),
"second onebox hidden" "second onebox hidden"
); );
await click(".chat-message-collapser-closed"); await click(".chat-message-collapser-closed");
assert.equal(animatedOneboxes.length, 2, "two oneboxes rendered"); assert.strictEqual(animatedOneboxes.length, 2, "two oneboxes rendered");
},
}); });
} }
); );
@ -357,91 +327,77 @@ module(
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("shows links for animated image", { test("shows links for animated image", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", externalImageCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", externalImageCooked);
},
async test(assert) { const links = queryAll("a.chat-message-collapser-link-small");
const links = document.querySelectorAll(
"a.chat-message-collapser-link-small"
);
assert.ok(links[0].innerText.trim().includes("http://cat1.com")); assert.true(links[0].innerText.trim().includes("http://cat1.com"));
assert.ok(links[0].href.includes("http://cat1.com")); assert.true(links[0].href.includes("http://cat1.com"));
assert.ok(links[1].innerText.trim().includes("http://cat2.com")); assert.true(links[1].innerText.trim().includes("http://cat2.com"));
assert.ok(links[1].href.includes("http://cat2.com")); assert.true(links[1].href.includes("http://cat2.com"));
},
}); });
componentTest("shows all user written text", { test("shows all user written text", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", externalImageCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", externalImageCooked);
},
async test(assert) { const text = queryAll(".chat-message-collapser p");
const text = document.querySelectorAll(".chat-message-collapser p");
assert.equal(text.length, 5, "shows all written text"); assert.strictEqual(text.length, 5, "shows all written text");
assert.strictEqual(text[0].innerText, "written text"); assert.strictEqual(text[0].innerText, "written text");
assert.strictEqual(text[2].innerText, "more written text"); assert.strictEqual(text[2].innerText, "more written text");
assert.strictEqual(text[4].innerText, "and even more"); assert.strictEqual(text[4].innerText, "and even more");
},
}); });
componentTest("collapses and expands image oneboxes", { test("collapses and expands image oneboxes", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", externalImageCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", externalImageCooked);
},
async test(assert) { const imageOneboxes = queryAll(".onebox");
const imageOneboxes = document.querySelectorAll(".onebox");
assert.equal(imageOneboxes.length, 2, "two oneboxes rendered"); assert.strictEqual(imageOneboxes.length, 2, "two oneboxes rendered");
await click( await click(
document.querySelectorAll(".chat-message-collapser-opened")[0], queryAll(".chat-message-collapser-opened")[0],
"close first preview" "close first preview"
); );
assert.notOk( assert.false(
visible(".onebox[href='http://cat1.com']"), visible(".onebox[href='http://cat1.com']"),
"first onebox hidden" "first onebox hidden"
); );
assert.ok( assert.true(
visible(".onebox[href='http://cat2.com']"), visible(".onebox[href='http://cat2.com']"),
"second onebox still visible" "second onebox still visible"
); );
await click(".chat-message-collapser-closed"); await click(".chat-message-collapser-closed");
assert.equal(imageOneboxes.length, 2, "two oneboxes rendered"); assert.strictEqual(imageOneboxes.length, 2, "two oneboxes rendered");
await click( await click(
document.querySelectorAll(".chat-message-collapser-opened")[1], queryAll(".chat-message-collapser-opened")[1],
"close second preview" "close second preview"
); );
assert.ok( assert.true(
visible(".onebox[href='http://cat1.com']"), visible(".onebox[href='http://cat1.com']"),
"first onebox still visible" "first onebox still visible"
); );
assert.notOk( assert.false(
visible(".onebox[href='http://cat2.com']"), visible(".onebox[href='http://cat2.com']"),
"second onebox hidden" "second onebox hidden"
); );
await click(".chat-message-collapser-closed"); await click(".chat-message-collapser-closed");
assert.equal(imageOneboxes.length, 2, "two oneboxes rendered"); assert.strictEqual(imageOneboxes.length, 2, "two oneboxes rendered");
},
}); });
} }
); );
@ -458,129 +414,107 @@ module(
.replace("shows alt", evilString) .replace("shows alt", evilString)
.replace("/images/d-logo-sketch-small.png", evilString) .replace("/images/d-logo-sketch-small.png", evilString)
); );
await render(hbs`{{chat-message-collapser cooked=cooked}}`); await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
assert.ok( assert.true(
queryAll(".chat-message-collapser-link-small")[0].innerHTML.includes( queryAll(".chat-message-collapser-link-small")[0].innerHTML.includes(
evilStringEscaped evilStringEscaped
) )
); );
assert.ok( assert.true(
queryAll(".chat-message-collapser-link-small")[1].innerHTML.includes( queryAll(".chat-message-collapser-link-small")[1].innerHTML.includes(
"%3Cscript%3Esomeeviltitle%3C/script%3E" "%3Cscript%3Esomeeviltitle%3C/script%3E"
) )
); );
}); });
componentTest("shows alt or links (if no alt) for linked image", { test("shows alt or links (if no alt) for linked image", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", imageCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", imageCooked);
},
async test(assert) { const links = queryAll("a.chat-message-collapser-link-small");
const links = document.querySelectorAll(
"a.chat-message-collapser-link-small"
);
assert.ok(links[0].innerText.trim().includes("shows alt")); assert.true(links[0].innerText.trim().includes("shows alt"));
assert.ok(links[0].href.includes("/images/avatar.png")); assert.true(links[0].href.includes("/images/avatar.png"));
assert.ok( assert.true(
links[1].innerText.trim().includes("/images/d-logo-sketch-small.png") links[1].innerText.trim().includes("/images/d-logo-sketch-small.png")
); );
assert.ok(links[1].href.includes("/images/d-logo-sketch-small.png")); assert.true(links[1].href.includes("/images/d-logo-sketch-small.png"));
},
}); });
componentTest("shows all user written text", { test("shows all user written text", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", imageCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", imageCooked);
},
async test(assert) { const text = queryAll(".chat-message-collapser p");
const text = document.querySelectorAll(".chat-message-collapser p");
assert.equal(text.length, 6, "shows all written text"); assert.strictEqual(text.length, 6, "shows all written text");
assert.strictEqual(text[0].innerText, "written text"); assert.strictEqual(text[0].innerText, "written text");
assert.strictEqual(text[2].innerText, "more written text"); assert.strictEqual(text[2].innerText, "more written text");
assert.strictEqual(text[4].innerText, "and even more"); assert.strictEqual(text[4].innerText, "and even more");
},
}); });
componentTest("collapses and expands images", { test("collapses and expands images", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", imageCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", imageCooked);
},
async test(assert) { const images = queryAll("img");
const images = document.querySelectorAll("img");
assert.equal(images.length, 3); assert.strictEqual(images.length, 3);
await click( await click(
document.querySelectorAll(".chat-message-collapser-opened")[0], queryAll(".chat-message-collapser-opened")[0],
"close first preview" "close first preview"
); );
assert.notOk( assert.false(
visible("img[src='/images/avatar.png']"), visible("img[src='/images/avatar.png']"),
"first image hidden" "first image hidden"
); );
assert.ok( assert.true(
visible("img[src='/images/d-logo-sketch-small.png']"), visible("img[src='/images/d-logo-sketch-small.png']"),
"second image still visible" "second image still visible"
); );
await click(".chat-message-collapser-closed"); await click(".chat-message-collapser-closed");
assert.equal(images.length, 3); assert.strictEqual(images.length, 3);
await click( await click(
document.querySelectorAll(".chat-message-collapser-opened")[1], queryAll(".chat-message-collapser-opened")[1],
"close second preview" "close second preview"
); );
assert.ok( assert.true(
visible("img[src='/images/avatar.png']"), visible("img[src='/images/avatar.png']"),
"first image still visible" "first image still visible"
); );
assert.notOk( assert.false(
visible("img[src='/images/d-logo-sketch-small.png']"), visible("img[src='/images/d-logo-sketch-small.png']"),
"second image hidden" "second image hidden"
); );
await click(".chat-message-collapser-closed"); await click(".chat-message-collapser-closed");
assert.equal(images.length, 3); assert.strictEqual(images.length, 3);
},
}); });
componentTest("does not show collapser for emoji images", { test("does not show collapser for emoji images", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", imageCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", imageCooked);
},
async test(assert) { const links = queryAll("a.chat-message-collapser-link-small");
const links = document.querySelectorAll( const images = queryAll("img");
"a.chat-message-collapser-link-small" const collapser = queryAll(".chat-message-collapser-opened");
);
const images = document.querySelectorAll("img");
const collapser = document.querySelectorAll(
".chat-message-collapser-opened"
);
assert.equal(links.length, 2); assert.strictEqual(links.length, 2);
assert.equal(images.length, 3, "shows images and emoji"); assert.strictEqual(images.length, 3, "shows images and emoji");
assert.equal(collapser.length, 2); assert.strictEqual(collapser.length, 2);
},
}); });
} }
); );
@ -597,9 +531,9 @@ module(
.replace("https://imgur.com/gallery/yyVx5lJ", evilString) .replace("https://imgur.com/gallery/yyVx5lJ", evilString)
.replace("Le tomtom album", evilString) .replace("Le tomtom album", evilString)
); );
await render(hbs`{{chat-message-collapser cooked=cooked}}`); await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
assert.ok( assert.true(
query(".chat-message-collapser-link-small").href.includes( query(".chat-message-collapser-link-small").href.includes(
"%3Cscript%3Esomeeviltitle%3C/script%3E" "%3Cscript%3Esomeeviltitle%3C/script%3E"
) )
@ -610,71 +544,53 @@ module(
); );
}); });
componentTest("removes album title overlay", { test("removes album title overlay", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", galleryCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", galleryCooked);
},
async test(assert) { assert.false(visible(".album-title"), "album title removed");
assert.notOk(visible(".album-title"), "album title removed");
},
}); });
componentTest("shows gallery link", { test("shows gallery link", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", galleryCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", galleryCooked);
},
async test(assert) { assert.true(
assert.ok( query(".chat-message-collapser-link-small").innerText.includes(
query(".chat-message-collapser-link-small").innerText.includes( "Le tomtom album"
"Le tomtom album" )
) );
);
},
}); });
componentTest("shows all user written text", { test("shows all user written text", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", galleryCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", galleryCooked);
},
async test(assert) { const text = queryAll(".chat-message-collapser p");
const text = document.querySelectorAll(".chat-message-collapser p");
assert.equal(text.length, 2, "shows all written text"); assert.strictEqual(text.length, 2, "shows all written text");
assert.strictEqual(text[0].innerText, "written text"); assert.strictEqual(text[0].innerText, "written text");
assert.strictEqual(text[1].innerText, "more written text"); assert.strictEqual(text[1].innerText, "more written text");
},
}); });
componentTest("collapses and expands images", { test("collapses and expands images", async function (assert) {
template: hbs`{{chat-message-collapser cooked=cooked}}`, this.set("cooked", galleryCooked);
beforeEach() { await render(hbs`<ChatMessageCollapser @cooked={{this.cooked}} />`);
this.set("cooked", galleryCooked);
},
async test(assert) { assert.true(visible("img"), "image visible initially");
assert.ok(visible("img"), "image visible initially");
await click( await click(
document.querySelectorAll(".chat-message-collapser-opened")[0], queryAll(".chat-message-collapser-opened")[0],
"close preview" "close preview"
); );
assert.false(visible("img"), "image hidden");
assert.notOk(visible("img"), "image hidden"); await click(".chat-message-collapser-closed");
assert.true(visible("img"), "image visible initially");
await click(".chat-message-collapser-closed");
assert.ok(visible("img"), "image visible initially");
},
}); });
} }
); );

View File

@ -1,140 +1,111 @@
import Bookmark from "discourse/models/bookmark"; import Bookmark from "discourse/models/bookmark";
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { exists, query } from "discourse/tests/helpers/qunit-helpers"; import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import I18n from "I18n"; import I18n from "I18n";
import { module } from "qunit"; import { module, test } from "qunit";
import User from "discourse/models/user"; import User from "discourse/models/user";
import { render } from "@ember/test-helpers";
module("Discourse Chat | Component | chat-message-info", function (hooks) { module("Discourse Chat | Component | chat-message-info", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("chat_webhook_event", { test("chat_webhook_event", async function (assert) {
template: hbs`{{chat-message-info message=message}}`, this.set("message", { chat_webhook_event: { username: "discobot" } });
beforeEach() { await render(hbs`<ChatMessageInfo @message={{this.message}} />`);
this.set("message", { chat_webhook_event: { username: "discobot" } });
},
async test(assert) { assert.strictEqual(
assert.equal( query(".chat-message-info__username").innerText.trim(),
query(".chat-message-info__username").innerText.trim(), this.message.chat_webhook_event.username
this.message.chat_webhook_event.username );
); assert.strictEqual(
assert.equal( query(".chat-message-info__bot-indicator").textContent.trim(),
query(".chat-message-info__bot-indicator").textContent.trim(), I18n.t("chat.bot")
I18n.t("chat.bot") );
);
},
}); });
componentTest("user", { test("user", async function (assert) {
template: hbs`{{chat-message-info message=message}}`, this.set("message", { user: { username: "discobot" } });
beforeEach() { await render(hbs`<ChatMessageInfo @message={{this.message}} />`);
this.set("message", { user: { username: "discobot" } });
},
async test(assert) { assert.strictEqual(
assert.equal( query(".chat-message-info__username").innerText.trim(),
query(".chat-message-info__username").innerText.trim(), this.message.user.username
this.message.user.username );
);
},
}); });
componentTest("date", { test("date", async function (assert) {
template: hbs`{{chat-message-info message=message}}`, this.set("message", {
user: { username: "discobot" },
created_at: moment(),
});
beforeEach() { await render(hbs`<ChatMessageInfo @message={{this.message}} />`);
this.set("message", {
user: { username: "discobot" },
created_at: moment(),
});
},
async test(assert) { assert.true(exists(".chat-message-info__date"));
assert.ok(exists(".chat-message-info__date"));
},
}); });
componentTest("bookmark (with reminder)", { test("bookmark (with reminder)", async function (assert) {
template: hbs`{{chat-message-info message=message}}`, this.set("message", {
user: { username: "discobot" },
bookmark: Bookmark.create({
reminder_at: moment(),
name: "some name",
}),
});
beforeEach() { await render(hbs`<ChatMessageInfo @message={{this.message}} />`);
this.set("message", {
user: { username: "discobot" },
bookmark: Bookmark.create({
reminder_at: moment(),
name: "some name",
}),
});
},
async test(assert) { assert.true(
assert.ok( exists(".chat-message-info__bookmark .d-icon-discourse-bookmark-clock")
exists(".chat-message-info__bookmark .d-icon-discourse-bookmark-clock") );
);
},
}); });
componentTest("bookmark (no reminder)", { test("bookmark (no reminder)", async function (assert) {
template: hbs`{{chat-message-info message=message}}`, this.set("message", {
user: { username: "discobot" },
bookmark: Bookmark.create({
name: "some name",
}),
});
beforeEach() { await render(hbs`<ChatMessageInfo @message={{this.message}} />`);
this.set("message", {
user: { username: "discobot" },
bookmark: Bookmark.create({
name: "some name",
}),
});
},
async test(assert) { assert.true(exists(".chat-message-info__bookmark .d-icon-bookmark"));
assert.ok(exists(".chat-message-info__bookmark .d-icon-bookmark"));
},
}); });
componentTest("user status", { test("user status", async function (assert) {
template: hbs`{{chat-message-info message=message}}`, const status = { description: "off to dentist", emoji: "tooth" };
this.set("message", { user: User.create({ status }) });
beforeEach() { await render(hbs`<ChatMessageInfo @message={{this.message}} />`);
const status = { description: "off to dentist", emoji: "tooth" };
this.set("message", { user: User.create({ status }) });
},
async test(assert) { assert.true(exists(".chat-message-info__status .user-status-message"));
assert.ok(exists(".chat-message-info__status .user-status-message"));
},
}); });
componentTest("reviewable", { test("reviewable", async function (assert) {
template: hbs`{{chat-message-info message=message}}`, this.set("message", {
user: { username: "discobot" },
user_flag_status: 0,
});
beforeEach() { await render(hbs`<ChatMessageInfo @message={{this.message}} />`);
this.set("message", {
user: { username: "discobot" },
user_flag_status: 0,
});
},
async test(assert) { assert.strictEqual(
assert.equal( query(".chat-message-info__flag > .svg-icon-title").title,
query(".chat-message-info__flag > .svg-icon-title").title, I18n.t("chat.you_flagged")
I18n.t("chat.you_flagged") );
);
this.set("message", { this.set("message", {
user: { username: "discobot" }, user: { username: "discobot" },
reviewable_id: 1, reviewable_id: 1,
}); });
assert.equal( assert.strictEqual(
query(".chat-message-info__flag a .svg-icon-title").title, query(".chat-message-info__flag a .svg-icon-title").title,
I18n.t("chat.flagged") I18n.t("chat.flagged")
); );
},
}); });
}); });

View File

@ -18,11 +18,15 @@ module(
this.set("chat", { publicChannels: [this.channel] }); this.set("chat", { publicChannels: [this.channel] });
this.set("selectedMessageIds", [1]); this.set("selectedMessageIds", [1]);
await render( await render(hbs`
hbs`{{chat-message-move-to-channel-modal-inner selectedMessageIds=selectedMessageIds sourceChannel=channel chat=chat}}` <ChatMessageMoveToChannelModalInner
); @selectedMessageIds={{this.selectedMessageIds}}
@sourceChannel={{this.channel}}
@chat={{this.chat}}
/>
`);
assert.ok( assert.true(
query(".chat-message-move-to-channel-modal-inner").innerHTML.includes( query(".chat-message-move-to-channel-modal-inner").innerHTML.includes(
"&lt;script&gt;someeviltitle&lt;/script&gt;" "&lt;script&gt;someeviltitle&lt;/script&gt;"
) )

View File

@ -1,104 +1,87 @@
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 { click } from "@ember/test-helpers";
import { exists, query } from "discourse/tests/helpers/qunit-helpers"; import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { module } from "qunit"; import { module, test } from "qunit";
module("Discourse Chat | Component | chat-message-reaction", function (hooks) { module("Discourse Chat | Component | chat-message-reaction", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("accepts arbitrary class property", { test("accepts arbitrary class property", async function (assert) {
template: hbs`{{chat-message-reaction reaction=(hash emoji="heart") class="foo"}}`, await render(hbs`
<ChatMessageReaction @reaction={{hash emoji="heart"}} @class="foo" />
`);
async test(assert) { assert.true(exists(".chat-message-reaction.foo"));
assert.ok(exists(".chat-message-reaction.foo"));
},
}); });
componentTest("adds reacted class when user reacted", { test("adds reacted class when user reacted", async function (assert) {
template: hbs`{{chat-message-reaction reaction=(hash emoji="heart" reacted=true)}}`, await render(hbs`
<ChatMessageReaction @reaction={{hash emoji="heart" reacted=true}} />
`);
async test(assert) { assert.true(exists(".chat-message-reaction.reacted"));
assert.ok(exists(".chat-message-reaction.reacted"));
},
}); });
componentTest("adds reaction name as class", { test("adds reaction name as class", async function (assert) {
template: hbs`{{chat-message-reaction reaction=(hash emoji="heart")}}`, await render(hbs`<ChatMessageReaction @reaction={{hash emoji="heart"}} />`);
async test(assert) { assert.true(exists(`.chat-message-reaction[data-emoji-name="heart"]`));
assert.ok(exists(`.chat-message-reaction[data-emoji-name="heart"]`));
},
}); });
componentTest("adds show class when count is positive", { test("adds show class when count is positive", async function (assert) {
template: hbs`{{chat-message-reaction reaction=(hash emoji="heart" count=this.count)}}`, this.set("count", 0);
beforeEach() { await render(hbs`
this.set("count", 0); <ChatMessageReaction @reaction={{hash emoji="heart" count=this.count}} />
}, `);
async test(assert) { assert.false(exists(".chat-message-reaction.show"));
assert.notOk(exists(".chat-message-reaction.show"));
this.set("count", 1);
assert.true(exists(".chat-message-reaction.show"));
});
test("title/alt attributes", async function (assert) {
await render(hbs`<ChatMessageReaction @reaction={{hash emoji="heart"}} />`);
assert.strictEqual(query(".chat-message-reaction").title, ":heart:");
assert.strictEqual(query(".chat-message-reaction img").alt, ":heart:");
});
test("count of reactions", async function (assert) {
this.set("count", 0);
await render(hbs`
<ChatMessageReaction @reaction={{hash emoji="heart" count=this.count}} />
`);
assert.false(exists(".chat-message-reaction .count"));
this.set("count", 2);
assert.strictEqual(query(".chat-message-reaction .count").innerText, "2");
});
test("reactions image", async function (assert) {
await render(hbs`<ChatMessageReaction @reaction={{hash emoji="heart"}} />`);
const src = query(".chat-message-reaction img").src;
assert.true(/heart\.png/.test(src));
});
test("click action", async function (assert) {
this.set("count", 0);
this.set("react", () => {
this.set("count", 1); this.set("count", 1);
});
assert.ok(exists(".chat-message-reaction.show")); await render(hbs`
}, <ChatMessageReaction class="show" @reaction={{hash emoji="heart" count=this.count}} @react={{this.react}} />
}); `);
componentTest("title/alt attributes", { assert.false(exists(".chat-message-reaction .count"));
template: hbs`{{chat-message-reaction reaction=(hash emoji="heart")}}`,
async test(assert) { await click(".chat-message-reaction");
assert.equal(query(".chat-message-reaction").title, ":heart:"); assert.strictEqual(query(".chat-message-reaction .count").innerText, "1");
assert.equal(query(".chat-message-reaction img").alt, ":heart:");
},
});
componentTest("count of reactions", {
template: hbs`{{chat-message-reaction reaction=(hash emoji="heart" count=this.count)}}`,
beforeEach() {
this.set("count", 0);
},
async test(assert) {
assert.notOk(exists(".chat-message-reaction .count"));
this.set("count", 2);
assert.equal(query(".chat-message-reaction .count").innerText, "2");
},
});
componentTest("reactions image", {
template: hbs`{{chat-message-reaction reaction=(hash emoji="heart")}}`,
async test(assert) {
const src = query(".chat-message-reaction img").src;
assert.ok(/heart\.png/.test(src));
},
});
componentTest("click action", {
template: hbs`{{chat-message-reaction class="show" reaction=(hash emoji="heart" count=this.count) react=this.react}}`,
beforeEach() {
this.set("count", 0);
this.set("react", () => {
this.set("count", 1);
});
},
async test(assert) {
assert.notOk(exists(".chat-message-reaction .count"));
await click(".chat-message-reaction");
assert.equal(query(".chat-message-reaction .count").innerText, "1");
},
}); });
}); });

View File

@ -1,44 +1,35 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { 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 I18n from "I18n"; import I18n from "I18n";
import { module } from "qunit"; import { module, test } from "qunit";
import { render } from "@ember/test-helpers";
module("Discourse Chat | Component | chat-message-separator", function (hooks) { module("Discourse Chat | Component | chat-message-separator", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("newest message", { test("newest message", async function (assert) {
template: hbs`{{chat-message-separator message=message}}`, this.set("message", { newestMessage: true });
async beforeEach() { await render(hbs`<ChatMessageSeparator @message={{this.message}} />`);
this.set("message", { newestMessage: true });
},
async test(assert) { assert.strictEqual(
assert.equal( query(".chat-message-separator.new-message .text").innerText.trim(),
query(".chat-message-separator.new-message .text").innerText.trim(), I18n.t("chat.new_messages")
I18n.t("chat.new_messages") );
);
},
}); });
componentTest("first message of the day", { test("first message of the day", async function (assert) {
template: hbs`{{chat-message-separator message=message}}`, this.set("date", moment().format("LLL"));
this.set("message", { firstMessageOfTheDayAt: this.date });
async beforeEach() { await render(hbs`<ChatMessageSeparator @message={{this.message}} />`);
this.set("date", moment().format("LLL"));
this.set("message", { firstMessageOfTheDayAt: this.date });
},
async test(assert) { assert.strictEqual(
assert.equal( query(
query( ".chat-message-separator.first-daily-message .text"
".chat-message-separator.first-daily-message .text" ).innerText.trim(),
).innerText.trim(), this.date
this.date );
);
},
}); });
}); });

View File

@ -60,26 +60,28 @@ module("Discourse Chat | Component | chat-message", function (hooks) {
}; };
} }
const template = hbs`{{chat-message const template = hbs`
message=message <ChatMessage
canInteractWithChat=canInteractWithChat @message={{this.message}}
details=this.details @canInteractWithChat={{this.canInteractWithChat}}
chatChannel=chatChannel @details={{this.details}}
setReplyTo=setReplyTo @chatChannel={{this.chatChannel}}
replyMessageClicked=replyMessageClicked @setReplyTo={{this.setReplyTo}}
editButtonClicked=editButtonClicked @replyMessageClicked={{this.replyMessageClicked}}
selectingMessages=selectingMessages @editButtonClicked={{this.editButtonClicked}}
onStartSelectingMessages=onStartSelectingMessages @selectingMessages={{this.selectingMessages}}
onSelectMessage=onSelectMessage @onStartSelectingMessages={{this.onStartSelectingMessages}}
bulkSelectMessages=bulkSelectMessages @onSelectMessage={{this.onSelectMessage}}
onHoverMessage=onHoverMessage @bulkSelectMessages={{this.bulkSelectMessages}}
afterReactionAdded=reStickScrollIfNeeded @onHoverMessage={{this.onHoverMessage}}
}}`; @afterReactionAdded={{this.reStickScrollIfNeeded}}
/>
`;
test("Message with edits", async function (assert) { test("Message with edits", async function (assert) {
this.setProperties(generateMessageProps({ edited: true })); this.setProperties(generateMessageProps({ edited: true }));
await render(template); await render(template);
assert.ok( assert.true(
exists(".chat-message-edited"), exists(".chat-message-edited"),
"has the correct edited css class" "has the correct edited css class"
); );
@ -88,7 +90,7 @@ module("Discourse Chat | Component | chat-message", function (hooks) {
test("Deleted message", async function (assert) { test("Deleted message", async function (assert) {
this.setProperties(generateMessageProps({ deleted_at: moment() })); this.setProperties(generateMessageProps({ deleted_at: moment() }));
await render(template); await render(template);
assert.ok( assert.true(
exists(".chat-message-deleted .chat-message-expand"), exists(".chat-message-deleted .chat-message-expand"),
"has the correct deleted css class and expand button within" "has the correct deleted css class and expand button within"
); );
@ -97,7 +99,7 @@ module("Discourse Chat | Component | chat-message", function (hooks) {
test("Hidden message", async function (assert) { test("Hidden message", async function (assert) {
this.setProperties(generateMessageProps({ hidden: true })); this.setProperties(generateMessageProps({ hidden: true }));
await render(template); await render(template);
assert.ok( assert.true(
exists(".chat-message-hidden .chat-message-expand"), exists(".chat-message-hidden .chat-message-expand"),
"has the correct hidden css class and expand button within" "has the correct hidden css class and expand button within"
); );
@ -109,7 +111,7 @@ module("Discourse Chat | Component | chat-message", function (hooks) {
await render(template); await render(template);
await waitFor("div[data-visible=true]"); await waitFor("div[data-visible=true]");
assert.ok( assert.true(
exists(".chat-message-container[data-visible=true]"), exists(".chat-message-container[data-visible=true]"),
"message is marked as visible" "message is marked as visible"
); );

View File

@ -1,76 +1,62 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { exists } from "discourse/tests/helpers/qunit-helpers"; import { exists } from "discourse/tests/helpers/qunit-helpers";
import { module } from "qunit"; import { module, test } from "qunit";
import { render } from "@ember/test-helpers";
module("Discourse Chat | Component | chat-message-text", function (hooks) { module("Discourse Chat | Component | chat-message-text", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("yields", { test("yields", async function (assert) {
template: hbs`{{#chat-message-text cooked=cooked uploads=uploads}} <div class="yield-me"></div> {{/chat-message-text}}`, this.set("cooked", "<p></p>");
beforeEach() { await render(hbs`
this.set("cooked", "<p></p>"); <ChatMessageText @cooked={{this.cooked}} @uploads={{this.uploads}}>
}, <div class="yield-me"></div>
</ChatMessageText>
`);
async test(assert) { assert.true(exists(".yield-me"));
assert.ok(exists(".yield-me"));
},
}); });
componentTest("shows collapsed", { test("shows collapsed", async function (assert) {
template: hbs`{{chat-message-text cooked=cooked uploads=uploads}}`, this.set(
"cooked",
'<div class="onebox lazyYT lazyYT-container" data-youtube-id="WaT_rLGuUr8" data-youtube-title="Japanese Katsu Curry (Pork Cutlet)"/>'
);
beforeEach() { await render(
this.set( hbs`<ChatMessageText @cooked={{this.cooked}} @uploads={{this.uploads}} />`
"cooked", );
'<div class="onebox lazyYT lazyYT-container" data-youtube-id="WaT_rLGuUr8" data-youtube-title="Japanese Katsu Curry (Pork Cutlet)"/>'
);
},
async test(assert) { assert.true(exists(".chat-message-collapser"));
assert.ok(exists(".chat-message-collapser"));
},
}); });
componentTest("does not collapse a non-image onebox", { test("does not collapse a non-image onebox", async function (assert) {
template: hbs`{{chat-message-text cooked=cooked}}`, this.set("cooked", '<p><a href="http://cat1.com" class="onebox"></a></p>');
beforeEach() { await render(hbs`<ChatMessageText @cooked={{this.cooked}} />`);
this.set(
"cooked",
'<p><a href="http://cat1.com" class="onebox"></a></p>'
);
},
async test(assert) { assert.false(exists(".chat-message-collapser"));
assert.notOk(exists(".chat-message-collapser"));
},
}); });
componentTest("shows edits - regular message", { test("shows edits - regular message", async function (assert) {
template: hbs`{{chat-message-text cooked=cooked edited=true}}`, this.set("cooked", "<p></p>");
beforeEach() { await render(
this.set("cooked", "<p></p>"); hbs`<ChatMessageText @cooked={{this.cooked}} @edited={{true}} />`
}, );
async test(assert) { assert.true(exists(".chat-message-edited"));
assert.ok(exists(".chat-message-edited"));
},
}); });
componentTest("shows edits - collapsible message", { test("shows edits - collapsible message", async function (assert) {
template: hbs`{{chat-message-text cooked=cooked edited=true}}`, this.set("cooked", '<div class="onebox lazyYT-container"></div>');
beforeEach() { await render(
this.set("cooked", '<div class="onebox lazyYT-container"></div>'); hbs`<ChatMessageText @cooked={{this.cooked}} @edited={{true}} />`
}, );
async test(assert) { assert.true(exists(".chat-message-edited"));
assert.ok(exists(".chat-message-edited"));
},
}); });
}); });

View File

@ -1,182 +1,166 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { exists, query } from "discourse/tests/helpers/qunit-helpers"; import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import fabricators from "../helpers/fabricators"; import fabricators from "../helpers/fabricators";
import MockPresenceChannel from "../helpers/mock-presence-channel"; import MockPresenceChannel from "../helpers/mock-presence-channel";
import { module } from "qunit"; import { module, test } from "qunit";
import { render } from "@ember/test-helpers";
module( module(
"Discourse Chat | Component | chat-replying-indicator", "Discourse Chat | Component | chat-replying-indicator",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("not displayed when no one is replying", { test("not displayed when no one is replying", async function (assert) {
template: hbs`{{chat-replying-indicator presenceChannel=presenceChannel chatChannel=chatChannel}}`, this.set("chatChannel", fabricators.chatChannel());
this.set(
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
async beforeEach() { await render(
this.set("chatChannel", fabricators.chatChannel()); hbs`<ChatReplyingIndicator @presenceChannel={{this.presenceChannel}} @chatChannel={{this.chatChannel}} />`
this.set( );
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
},
async test(assert) { assert.false(exists(".chat-replying-indicator__text"));
assert.notOk(exists(".chat-replying-indicator__text"));
},
}); });
componentTest("displays indicator when user is replying", { test("displays indicator when user is replying", async function (assert) {
template: hbs`{{chat-replying-indicator presenceChannel=presenceChannel chatChannel=chatChannel}}`, this.set("chatChannel", fabricators.chatChannel());
this.set(
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
async beforeEach() { await render(
this.set("chatChannel", fabricators.chatChannel()); hbs`<ChatReplyingIndicator @presenceChannel={{this.presenceChannel}} @chatChannel={{this.chatChannel}} />`
this.set( );
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
},
async test(assert) { const sam = { id: 1, username: "sam" };
const sam = { id: 1, username: "sam" }; this.set("presenceChannel.users", [sam]);
this.set("presenceChannel.users", [sam]);
assert.equal( assert.strictEqual(
query(".chat-replying-indicator__text").innerText, query(".chat-replying-indicator__text").innerText,
`${sam.username} is typing` `${sam.username} is typing`
); );
},
}); });
componentTest("displays indicator when 2 or 3 users are replying", { test("displays indicator when 2 or 3 users are replying", async function (assert) {
template: hbs`{{chat-replying-indicator presenceChannel=presenceChannel chatChannel=chatChannel}}`, this.set("chatChannel", fabricators.chatChannel());
this.set(
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
async beforeEach() { await render(
this.set("chatChannel", fabricators.chatChannel()); hbs`<ChatReplyingIndicator @presenceChannel={{this.presenceChannel}} @chatChannel={{this.chatChannel}} />`
this.set( );
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
},
async test(assert) { const sam = { id: 1, username: "sam" };
const sam = { id: 1, username: "sam" }; const mark = { id: 2, username: "mark" };
const mark = { id: 2, username: "mark" }; this.set("presenceChannel.users", [sam, mark]);
this.set("presenceChannel.users", [sam, mark]);
assert.equal( assert.strictEqual(
query(".chat-replying-indicator__text").innerText, query(".chat-replying-indicator__text").innerText,
`${sam.username} and ${mark.username} are typing` `${sam.username} and ${mark.username} are typing`
); );
},
}); });
componentTest("displays indicator when 3 users are replying", { test("displays indicator when 3 users are replying", async function (assert) {
template: hbs`{{chat-replying-indicator presenceChannel=presenceChannel chatChannel=chatChannel}}`, this.set("chatChannel", fabricators.chatChannel());
this.set(
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
async beforeEach() { await render(
this.set("chatChannel", fabricators.chatChannel()); hbs`<ChatReplyingIndicator @presenceChannel={{this.presenceChannel}} @chatChannel={{this.chatChannel}} />`
this.set( );
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
},
async test(assert) { const sam = { id: 1, username: "sam" };
const sam = { id: 1, username: "sam" }; const mark = { id: 2, username: "mark" };
const mark = { id: 2, username: "mark" }; const joffrey = { id: 3, username: "joffrey" };
const joffrey = { id: 3, username: "joffrey" }; this.set("presenceChannel.users", [sam, mark, joffrey]);
this.set("presenceChannel.users", [sam, mark, joffrey]);
assert.equal( assert.strictEqual(
query(".chat-replying-indicator__text").innerText, query(".chat-replying-indicator__text").innerText,
`${sam.username}, ${mark.username} and ${joffrey.username} are typing` `${sam.username}, ${mark.username} and ${joffrey.username} are typing`
); );
},
}); });
componentTest("displays indicator when more than 3 users are replying", { test("displays indicator when more than 3 users are replying", async function (assert) {
template: hbs`{{chat-replying-indicator presenceChannel=presenceChannel chatChannel=chatChannel}}`, this.set("chatChannel", fabricators.chatChannel());
this.set(
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
async beforeEach() { await render(
this.set("chatChannel", fabricators.chatChannel()); hbs`<ChatReplyingIndicator @presenceChannel={{this.presenceChannel}} @chatChannel={{this.chatChannel}} />`
this.set( );
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
},
async test(assert) { const sam = { id: 1, username: "sam" };
const sam = { id: 1, username: "sam" }; const mark = { id: 2, username: "mark" };
const mark = { id: 2, username: "mark" }; const joffrey = { id: 3, username: "joffrey" };
const joffrey = { id: 3, username: "joffrey" }; const taylor = { id: 4, username: "taylor" };
const taylor = { id: 4, username: "taylor" }; this.set("presenceChannel.users", [sam, mark, joffrey, taylor]);
this.set("presenceChannel.users", [sam, mark, joffrey, taylor]);
assert.equal( assert.strictEqual(
query(".chat-replying-indicator__text").innerText, query(".chat-replying-indicator__text").innerText,
`${sam.username}, ${mark.username} and 2 others are typing` `${sam.username}, ${mark.username} and 2 others are typing`
); );
},
}); });
componentTest("filters current user from list of repliers", { test("filters current user from list of repliers", async function (assert) {
template: hbs`{{chat-replying-indicator presenceChannel=presenceChannel chatChannel=chatChannel}}`, this.set("chatChannel", fabricators.chatChannel());
this.set(
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
async beforeEach() { await render(
this.set("chatChannel", fabricators.chatChannel()); hbs`<ChatReplyingIndicator @presenceChannel={{this.presenceChannel}} @chatChannel={{this.chatChannel}} />`
this.set( );
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
})
);
},
async test(assert) { const sam = { id: 1, username: "sam" };
const sam = { id: 1, username: "sam" }; this.set("presenceChannel.users", [sam, this.currentUser]);
this.set("presenceChannel.users", [sam, this.currentUser]);
assert.equal( assert.strictEqual(
query(".chat-replying-indicator__text").innerText, query(".chat-replying-indicator__text").innerText,
`${sam.username} is typing` `${sam.username} is typing`
); );
},
}); });
componentTest("resets presence when channel is draft", { test("resets presence when channel is draft", async function (assert) {
template: hbs`{{chat-replying-indicator presenceChannel=presenceChannel chatChannel=chatChannel}}`, this.set("chatChannel", fabricators.chatChannel());
this.set(
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
subscribed: true,
})
);
async beforeEach() { await render(
this.set("chatChannel", fabricators.chatChannel()); hbs`<ChatReplyingIndicator @presenceChannel={{this.presenceChannel}} @chatChannel={{this.chatChannel}} />`
this.set( );
"presenceChannel",
MockPresenceChannel.create({
name: `/chat-reply/${this.chatChannel.id}`,
subscribed: true,
})
);
},
async test(assert) { assert.true(this.presenceChannel.subscribed);
assert.ok(this.presenceChannel.subscribed);
this.set("chatChannel", fabricators.chatChannel({ isDraft: true })); this.set("chatChannel", fabricators.chatChannel({ isDraft: true }));
assert.false(this.presenceChannel.subscribed);
assert.notOk(this.presenceChannel.subscribed);
},
}); });
} }
); );

View File

@ -1,93 +1,80 @@
import ChatChannel from "discourse/plugins/chat/discourse/models/chat-channel"; import ChatChannel from "discourse/plugins/chat/discourse/models/chat-channel";
import { set } from "@ember/object"; import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import componentTest, {
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { exists, query } from "discourse/tests/helpers/qunit-helpers"; import { 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 { module } from "qunit"; import { module, test } from "qunit";
import { render } from "@ember/test-helpers";
module( module(
"Discourse Chat | Component | chat-retention-reminder", "Discourse Chat | Component | chat-retention-reminder",
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("Shows for public channels when user needs it", { test("Shows for public channels when user needs it", async function (assert) {
template: hbs`{{chat-retention-reminder chatChannel=chatChannel}}`, this.set(
"chatChannel",
ChatChannel.create({ chatable_type: "Category" })
);
this.currentUser.set("needs_channel_retention_reminder", true);
this.siteSettings.chat_channel_retention_days = 100;
async beforeEach() { await render(
this.set( hbs`<ChatRetentionReminder @chatChannel={{this.chatChannel}} />`
"chatChannel", );
ChatChannel.create({ chatable_type: "Category" })
);
set(this.currentUser, "needs_channel_retention_reminder", true);
this.siteSettings.chat_channel_retention_days = 100;
},
async test(assert) { assert.strictEqual(
assert.equal( query(".chat-retention-reminder-text").innerText.trim(),
query(".chat-retention-reminder-text").innerText.trim(), I18n.t("chat.retention_reminders.public", { days: 100 })
I18n.t("chat.retention_reminders.public", { days: 100 }) );
);
},
}); });
componentTest( test("Doesn't show for public channels when user has dismissed it", async function (assert) {
"Doesn't show for public channels when user has dismissed it", this.set(
{ "chatChannel",
template: hbs`{{chat-retention-reminder chatChannel=chatChannel}}`, ChatChannel.create({ chatable_type: "Category" })
);
this.currentUser.set("needs_channel_retention_reminder", false);
this.siteSettings.chat_channel_retention_days = 100;
async beforeEach() { await render(
this.set( hbs`<ChatRetentionReminder @chatChannel={{this.chatChannel}} />`
"chatChannel", );
ChatChannel.create({ chatable_type: "Category" })
);
set(this.currentUser, "needs_channel_retention_reminder", false);
this.siteSettings.chat_channel_retention_days = 100;
},
async test(assert) { assert.false(exists(".chat-retention-reminder"));
assert.notOk(exists(".chat-retention-reminder"));
},
}
);
componentTest("Shows for direct message channels when user needs it", {
template: hbs`{{chat-retention-reminder chatChannel=chatChannel}}`,
async beforeEach() {
this.set(
"chatChannel",
ChatChannel.create({ chatable_type: "DirectMessage" })
);
set(this.currentUser, "needs_dm_retention_reminder", true);
this.siteSettings.chat_dm_retention_days = 100;
},
async test(assert) {
assert.equal(
query(".chat-retention-reminder-text").innerText.trim(),
I18n.t("chat.retention_reminders.dm", { days: 100 })
);
},
}); });
componentTest("Doesn't show for dm channels when user has dismissed it", { test("Shows for direct message channels when user needs it", async function (assert) {
template: hbs`{{chat-retention-reminder chatChannel=chatChannel}}`, this.set(
"chatChannel",
ChatChannel.create({ chatable_type: "DirectMessage" })
);
this.currentUser.set("needs_dm_retention_reminder", true);
this.siteSettings.chat_dm_retention_days = 100;
async beforeEach() { await render(
this.set( hbs`<ChatRetentionReminder @chatChannel={{this.chatChannel}} />`
"chatChannel", );
ChatChannel.create({ chatable_type: "DirectMessage" })
);
set(this.currentUser, "needs_dm_retention_reminder", false);
this.siteSettings.chat_dm_retention_days = 100;
},
async test(assert) { assert.strictEqual(
assert.notOk(exists(".chat-retention-reminder")); query(".chat-retention-reminder-text").innerText.trim(),
}, I18n.t("chat.retention_reminders.dm", { days: 100 })
);
});
test("Doesn't show for dm channels when user has dismissed it", async function (assert) {
this.set(
"chatChannel",
ChatChannel.create({ chatable_type: "DirectMessage" })
);
this.currentUser.set("needs_dm_retention_reminder", false);
this.siteSettings.chat_dm_retention_days = 100;
await render(
hbs`<ChatRetentionReminder @chatChannel={{this.chatChannel}} />`
);
assert.false(exists(".chat-retention-reminder"));
}); });
} }
); );

View File

@ -1,10 +1,8 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { exists, query } from "discourse/tests/helpers/qunit-helpers"; import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { module } from "qunit"; import { module, test } from "qunit";
import { settled } from "@ember/test-helpers"; import { render, settled } from "@ember/test-helpers";
const IMAGE_FIXTURE = { const IMAGE_FIXTURE = {
id: 290, id: 290,
@ -54,65 +52,53 @@ const TXT_FIXTURE = {
module("Discourse Chat | Component | chat-upload", function (hooks) { module("Discourse Chat | Component | chat-upload", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("with an image", { test("with an image", async function (assert) {
template: hbs`{{chat-upload upload=upload}}`, this.set("upload", IMAGE_FIXTURE);
beforeEach() { await render(hbs`<ChatUpload @upload={{this.upload}} />`);
this.set("upload", IMAGE_FIXTURE);
},
async test(assert) { assert.true(exists("img.chat-img-upload"), "displays as an image");
assert.true(exists("img.chat-img-upload"), "displays as an image"); const image = query("img.chat-img-upload");
const image = query("img.chat-img-upload"); assert.strictEqual(image.loading, "lazy", "is lazy loading");
assert.strictEqual(image.loading, "lazy", "is lazy loading");
assert.strictEqual( assert.strictEqual(
image.style.backgroundColor, image.style.backgroundColor,
"rgb(120, 131, 112)", "rgb(120, 131, 112)",
"sets background to dominant color" "sets background to dominant color"
); );
image.dispatchEvent(new Event("load")); // Fake that the image has loaded image.dispatchEvent(new Event("load")); // Fake that the image has loaded
await settled(); await settled();
assert.strictEqual( assert.strictEqual(
image.style.backgroundColor, image.style.backgroundColor,
"", "",
"removes the background color once the image has loaded" "removes the background color once the image has loaded"
); );
},
}); });
componentTest("with a video", { test("with a video", async function (assert) {
template: hbs`{{chat-upload upload=upload}}`, this.set("upload", VIDEO_FIXTURE);
beforeEach() { await render(hbs`<ChatUpload @upload={{this.upload}} />`);
this.set("upload", VIDEO_FIXTURE);
},
async test(assert) { assert.true(exists("video.chat-video-upload"), "displays as an video");
assert.true(exists("video.chat-video-upload"), "displays as an video"); const video = query("video.chat-video-upload");
const video = query("video.chat-video-upload"); assert.true(video.hasAttribute("controls"), "has video controls");
assert.ok(video.hasAttribute("controls"), "has video controls"); assert.strictEqual(
assert.strictEqual( video.getAttribute("preload"),
video.getAttribute("preload"), "metadata",
"metadata", "video has correct preload settings"
"video has correct preload settings" );
);
},
}); });
componentTest("non image upload", { test("non image upload", async function (assert) {
template: hbs`{{chat-upload upload=upload}}`, this.set("upload", TXT_FIXTURE);
beforeEach() { await render(hbs`<ChatUpload @upload={{this.upload}} />`);
this.set("upload", TXT_FIXTURE);
},
async test(assert) { assert.true(exists("a.chat-other-upload"), "displays as a link");
assert.true(exists("a.chat-other-upload"), "displays as a link"); const link = query("a.chat-other-upload");
const link = query("a.chat-other-upload"); assert.strictEqual(link.href, TXT_FIXTURE.url, "has the correct URL");
assert.strictEqual(link.href, TXT_FIXTURE.url, "has the correct URL");
},
}); });
}); });

View File

@ -1,9 +1,8 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { 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";
import { module } from "qunit"; import { module, test } from "qunit";
import { render } from "@ember/test-helpers";
const user = { const user = {
id: 1, id: 1,
@ -15,41 +14,37 @@ const user = {
module("Discourse Chat | Component | chat-user-avatar", function (hooks) { module("Discourse Chat | Component | chat-user-avatar", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("user is not online", { test("user is not online", async function (assert) {
template: hbs`{{chat-user-avatar chat=chat user=user}}`, this.set("user", user);
this.set("chat", { presenceChannel: { users: [] } });
async beforeEach() { await render(
this.set("user", user); hbs`<ChatUserAvatar @chat={{this.chat}} @user={{this.user}} />`
this.set("chat", { presenceChannel: { users: [] } }); );
},
async test(assert) { assert.true(
assert.ok( exists(
exists( `.chat-user-avatar .chat-user-avatar-container[data-user-card=${user.username}] .avatar[title=${user.username}]`
`.chat-user-avatar .chat-user-avatar-container[data-user-card=${user.username}] .avatar[title=${user.username}]` )
) );
); assert.false(exists(".chat-user-avatar.is-online"));
assert.notOk(exists(".chat-user-avatar.is-online"));
},
}); });
componentTest("user is online", { test("user is online", async function (assert) {
template: hbs`{{chat-user-avatar chat=chat user=user}}`, this.set("user", user);
this.set("chat", {
presenceChannel: { users: [{ id: user.id }] },
});
async beforeEach() { await render(
this.set("user", user); hbs`<ChatUserAvatar @chat={{this.chat}} @user={{this.user}} />`
this.set("chat", { );
presenceChannel: { users: [{ id: user.id }] },
});
},
async test(assert) { assert.true(
assert.ok( exists(
exists( `.chat-user-avatar .chat-user-avatar-container[data-user-card=${user.username}] .avatar[title=${user.username}]`
`.chat-user-avatar .chat-user-avatar-container[data-user-card=${user.username}] .avatar[title=${user.username}]` )
) );
); assert.true(exists(".chat-user-avatar.is-online"));
assert.ok(exists(".chat-user-avatar.is-online"));
},
}); });
}); });

View File

@ -1,9 +1,8 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest,
} from "discourse/tests/helpers/component-test";
import { 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 { module } from "qunit"; import { module, test } from "qunit";
import { render } from "@ember/test-helpers";
function displayName() { function displayName() {
return query(".chat-user-display-name").innerText.trim(); return query(".chat-user-display-name").innerText.trim();
@ -14,30 +13,22 @@ module(
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("username and no name", { test("username and no name", async function (assert) {
template: hbs`{{chat-user-display-name user=user}}`, this.siteSettings.prioritize_username_in_ux = true;
this.set("user", { username: "bob", name: null });
async beforeEach() { await render(hbs`<ChatUserDisplayName @user={{this.user}} />`);
this.siteSettings.prioritize_username_in_ux = true;
this.set("user", { username: "bob", name: null });
},
async test(assert) { assert.strictEqual(displayName(), "bob");
assert.equal(displayName(), "bob");
},
}); });
componentTest("username and name", { test("username and name", async function (assert) {
template: hbs`{{chat-user-display-name user=user}}`, this.siteSettings.prioritize_username_in_ux = true;
this.set("user", { username: "bob", name: "Bobcat" });
async beforeEach() { await render(hbs`<ChatUserDisplayName @user={{this.user}} />`);
this.siteSettings.prioritize_username_in_ux = true;
this.set("user", { username: "bob", name: "Bobcat" });
},
async test(assert) { assert.strictEqual(displayName(), "bob — Bobcat");
assert.equal(displayName(), "bob — Bobcat");
},
}); });
} }
); );
@ -47,30 +38,22 @@ module(
function (hooks) { function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("no name", { test("no name", async function (assert) {
template: hbs`{{chat-user-display-name user=user}}`, this.siteSettings.prioritize_username_in_ux = false;
this.set("user", { username: "bob", name: null });
async beforeEach() { await render(hbs`<ChatUserDisplayName @user={{this.user}} />`);
this.siteSettings.prioritize_username_in_ux = false;
this.set("user", { username: "bob", name: null });
},
async test(assert) { assert.strictEqual(displayName(), "bob");
assert.equal(displayName(), "bob");
},
}); });
componentTest("name and username", { test("name and username", async function (assert) {
template: hbs`{{chat-user-display-name user=user}}`, this.siteSettings.prioritize_username_in_ux = false;
this.set("user", { username: "bob", name: "Bobcat" });
async beforeEach() { await render(hbs`<ChatUserDisplayName @user={{this.user}} />`);
this.siteSettings.prioritize_username_in_ux = false;
this.set("user", { username: "bob", name: "Bobcat" });
},
async test(assert) { assert.strictEqual(displayName(), "Bobcat — bob");
assert.equal(displayName(), "Bobcat — bob");
},
}); });
} }
); );

View File

@ -1,45 +1,38 @@
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 { click } from "@ember/test-helpers";
import hbs from "htmlbars-inline-precompile"; import hbs from "htmlbars-inline-precompile";
import { exists, query, visible } from "discourse/tests/helpers/qunit-helpers"; import { exists, visible } from "discourse/tests/helpers/qunit-helpers";
import { module } from "qunit"; import { module, test } from "qunit";
import { htmlSafe } from "@ember/template"; import { htmlSafe } from "@ember/template";
module("Discourse Chat | Component | collapser", function (hooks) { module("Discourse Chat | Component | collapser", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("renders header", { test("renders header", async function (assert) {
template: hbs`{{collapser header=header}}`, this.set("header", htmlSafe(`<div class="cat">tomtom</div>`));
beforeEach() { await render(hbs`<Collapser @header={{this.header}} />`);
this.set("header", htmlSafe("<div class='cat'>tomtom</div>"));
},
async test(assert) { assert.true(exists(".cat"));
const element = query(".cat");
assert.ok(exists(element));
},
}); });
componentTest("collapses and expands yielded body", { test("collapses and expands yielded body", async function (assert) {
template: hbs`{{#collapser}}<div class='cat'>body text</div>{{/collapser}}`, await render(hbs`
<Collapser>
<div class="cat">body text</div>
</Collapser>
`);
test: async function (assert) { const openButton = ".chat-message-collapser-closed";
const openButton = ".chat-message-collapser-closed"; const closeButton = ".chat-message-collapser-opened";
const closeButton = ".chat-message-collapser-opened"; const body = ".cat";
const body = ".cat";
assert.ok(visible(body)); assert.true(visible(body));
await click(closeButton);
assert.notOk(visible(body)); await click(closeButton);
assert.false(visible(body));
await click(openButton); await click(openButton);
assert.true(visible(body));
assert.ok(visible(body));
},
}); });
}); });

View File

@ -10,26 +10,26 @@ module("Discourse Chat | Component | dc-filter-input", function (hooks) {
test("Left icon", async function (assert) { test("Left icon", async function (assert) {
await render(hbs`<DcFilterInput @icons={{hash left="bell"}} />`); await render(hbs`<DcFilterInput @icons={{hash left="bell"}} />`);
assert.ok(exists(".d-icon-bell.-left")); assert.true(exists(".d-icon-bell.-left"));
}); });
test("Right icon", async function (assert) { test("Right icon", async function (assert) {
await render(hbs`<DcFilterInput @icons={{hash right="bell"}} />`); await render(hbs`<DcFilterInput @icons={{hash right="bell"}} />`);
assert.ok(exists(".d-icon-bell.-right")); assert.true(exists(".d-icon-bell.-right"));
}); });
test("Class attribute", async function (assert) { test("Class attribute", async function (assert) {
await render(hbs`<DcFilterInput @class="foo" />`); await render(hbs`<DcFilterInput @class="foo" />`);
assert.ok(exists(".dc-filter-input-container.foo")); assert.true(exists(".dc-filter-input-container.foo"));
}); });
test("Html attributes", async function (assert) { test("Html attributes", async function (assert) {
await render(hbs`<DcFilterInput data-foo="1" placeholder="bar" />`); await render(hbs`<DcFilterInput data-foo="1" placeholder="bar" />`);
assert.ok(exists('.dc-filter-input[data-foo="1"]')); assert.true(exists('.dc-filter-input[data-foo="1"]'));
assert.ok(exists('.dc-filter-input[placeholder="bar"]')); assert.true(exists('.dc-filter-input[placeholder="bar"]'));
}); });
test("Filter action", async function (assert) { test("Filter action", async function (assert) {
@ -40,17 +40,17 @@ module("Discourse Chat | Component | dc-filter-input", function (hooks) {
await render(hbs`<DcFilterInput @filterAction={{this.action}} />`); await render(hbs`<DcFilterInput @filterAction={{this.action}} />`);
await fillIn(".dc-filter-input", "foo"); await fillIn(".dc-filter-input", "foo");
assert.equal(this.value, "foo"); assert.strictEqual(this.value, "foo");
}); });
test("Focused state", async function (assert) { test("Focused state", async function (assert) {
await render(hbs`<DcFilterInput @filterAction={{this.action}} />`); await render(hbs`<DcFilterInput @filterAction={{this.action}} />`);
await triggerEvent(".dc-filter-input", "focusin"); await triggerEvent(".dc-filter-input", "focusin");
assert.ok(exists(".dc-filter-input-container.is-focused")); assert.true(exists(".dc-filter-input-container.is-focused"));
await triggerEvent(".dc-filter-input", "focusout"); await triggerEvent(".dc-filter-input", "focusout");
assert.notOk(exists(".dc-filter-input-container.is-focused")); assert.false(exists(".dc-filter-input-container.is-focused"));
}); });
}); });

View File

@ -1,13 +1,11 @@
import componentTest, { import { setupRenderingTest } from "discourse/tests/helpers/component-test";
setupRenderingTest, import { click, fillIn, render } from "@ember/test-helpers";
} 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";
import { exists, query } from "discourse/tests/helpers/qunit-helpers"; import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import { createDirectMessageChannelDraft } from "discourse/plugins/chat/discourse/models/chat-channel"; import { createDirectMessageChannelDraft } from "discourse/plugins/chat/discourse/models/chat-channel";
import { Promise } from "rsvp"; import { Promise } from "rsvp";
import fabricators from "../helpers/fabricators"; import fabricators from "../helpers/fabricators";
import { module } from "qunit"; import { module, test } from "qunit";
function mockChat(context, options = {}) { function mockChat(context, options = {}) {
const mock = context.container.lookup("service:chat"); const mock = context.container.lookup("service:chat");
@ -25,143 +23,119 @@ function mockChat(context, options = {}) {
module("Discourse Chat | Component | direct-message-creator", function (hooks) { module("Discourse Chat | Component | direct-message-creator", function (hooks) {
setupRenderingTest(hooks); setupRenderingTest(hooks);
componentTest("search", { test("search", async function (assert) {
template: hbs`{{direct-message-creator channel=channel chat=chat}}`, this.set("chat", mockChat(this));
this.set("channel", createDirectMessageChannelDraft());
beforeEach() { await render(
this.set("chat", mockChat(this)); hbs`<DirectMessageCreator @channel={{this.channel}} @chat={{this.chat}} />`
this.set("channel", createDirectMessageChannelDraft()); );
},
async test(assert) { await fillIn(".filter-usernames", "hawk");
await fillIn(".filter-usernames", "hawk"); assert.true(exists("li.user[data-username='hawk']"));
assert.ok(exists("li.user[data-username='hawk']"));
},
}); });
componentTest("select/deselect", { test("select/deselect", async function (assert) {
template: hbs`{{direct-message-creator channel=channel chat=chat}}`, this.set("chat", mockChat(this));
this.set("channel", createDirectMessageChannelDraft());
beforeEach() { await render(
this.set("chat", mockChat(this)); hbs`<DirectMessageCreator @channel={{this.channel}} @chat={{this.chat}} />`
this.set("channel", createDirectMessageChannelDraft()); );
}, assert.false(exists(".selected-user"));
async test(assert) { await fillIn(".filter-usernames", "hawk");
assert.notOk(exists(".selected-user")); await click("li.user[data-username='hawk']");
assert.true(exists(".selected-user"));
await fillIn(".filter-usernames", "hawk"); await click(".selected-user");
await click("li.user[data-username='hawk']"); assert.false(exists(".selected-user"));
assert.ok(exists(".selected-user"));
await click(".selected-user");
assert.notOk(exists(".selected-user"));
},
}); });
componentTest("no search results", { test("no search results", async function (assert) {
template: hbs`{{direct-message-creator channel=channel chat=chat}}`, this.set("chat", mockChat(this, { users: [] }));
this.set("channel", createDirectMessageChannelDraft());
beforeEach() { await render(
this.set("chat", mockChat(this, { users: [] })); hbs`<DirectMessageCreator @channel={{this.channel}} @chat={{this.chat}} />`
this.set("channel", createDirectMessageChannelDraft()); );
},
async test(assert) { await fillIn(".filter-usernames", "bad cat");
await fillIn(".filter-usernames", "bad cat"); assert.true(exists(".no-results"));
assert.ok(exists(".no-results"));
},
}); });
componentTest("loads user on first load", { test("loads user on first load", async function (assert) {
template: hbs`{{direct-message-creator channel=channel chat=chat}}`, this.set("chat", mockChat(this));
this.set("channel", createDirectMessageChannelDraft());
beforeEach() { await render(
this.set("chat", mockChat(this)); hbs`<DirectMessageCreator @channel={{this.channel}} @chat={{this.chat}} />`
this.set("channel", createDirectMessageChannelDraft()); );
},
async test(assert) { assert.true(exists("li.user[data-username='hawk']"));
assert.ok(exists("li.user[data-username='hawk']")); assert.true(exists("li.user[data-username='mark']"));
assert.ok(exists("li.user[data-username='mark']"));
},
}); });
componentTest("do not load more users after selection", { test("do not load more users after selection", async function (assert) {
template: hbs`{{direct-message-creator channel=channel chat=chat}}`, this.set("chat", mockChat(this));
this.set("channel", createDirectMessageChannelDraft());
beforeEach() { await render(
this.set("chat", mockChat(this)); hbs`<DirectMessageCreator @channel={{this.channel}} @chat={{this.chat}} />`
this.set("channel", createDirectMessageChannelDraft()); );
},
async test(assert) { await click("li.user[data-username='hawk']");
await click("li.user[data-username='hawk']"); assert.false(exists("li.user[data-username='mark']"));
assert.notOk(exists("li.user[data-username='mark']"));
},
}); });
componentTest("apply is-focused to filter-area on focus input", { test("apply is-focused to filter-area on focus input", async function (assert) {
template: hbs`{{direct-message-creator channel=channel chat=chat}}<button class="test-blur">blur</button>`, this.set("chat", mockChat(this));
this.set("channel", createDirectMessageChannelDraft());
beforeEach() { await render(
this.set("chat", mockChat(this)); hbs`<DirectMessageCreator @channel={{this.channel}} @chat={{this.chat}} /><button class="test-blur">blur</button>`
this.set("channel", createDirectMessageChannelDraft()); );
},
async test(assert) { await click(".filter-usernames");
await click(".filter-usernames"); assert.true(exists(".filter-area.is-focused"));
assert.ok(exists(".filter-area.is-focused")); await click(".test-blur");
assert.false(exists(".filter-area.is-focused"));
await click(".test-blur");
assert.notOk(exists(".filter-area.is-focused"));
},
}); });
componentTest("state is reset on channel change", { test("state is reset on channel change", async function (assert) {
template: hbs`{{direct-message-creator channel=channel chat=chat}}`, this.set("chat", mockChat(this));
this.set("channel", createDirectMessageChannelDraft());
beforeEach() { await render(
this.set("chat", mockChat(this)); hbs`<DirectMessageCreator @channel={{this.channel}} @chat={{this.chat}} />`
this.set("channel", createDirectMessageChannelDraft()); );
},
async test(assert) { await fillIn(".filter-usernames", "hawk");
await fillIn(".filter-usernames", "hawk"); assert.strictEqual(query(".filter-usernames").value, "hawk");
assert.equal(query(".filter-usernames").value, "hawk"); this.set("channel", fabricators.chatChannel());
this.set("channel", createDirectMessageChannelDraft());
this.set("channel", fabricators.chatChannel()); assert.strictEqual(query(".filter-usernames").value, "");
this.set("channel", createDirectMessageChannelDraft()); assert.true(exists(".filter-area.is-focused"));
assert.true(exists("li.user[data-username='hawk']"));
assert.equal(query(".filter-usernames").value, "");
assert.ok(exists(".filter-area.is-focused"));
assert.ok(exists("li.user[data-username='hawk']"));
},
}); });
componentTest("shows user status", { test("shows user status", async function (assert) {
template: hbs`{{direct-message-creator channel=channel chat=chat}}`, const userWithStatus = {
username: "hawk",
status: { emoji: "tooth", description: "off to dentist" },
};
const chat = mockChat(this, { users: [userWithStatus] });
this.set("chat", chat);
this.set("channel", createDirectMessageChannelDraft());
beforeEach() { await render(
const userWithStatus = { hbs`<DirectMessageCreator @channel={{this.channel}} @chat={{this.chat}} />`
username: "hawk", );
status: { emoji: "tooth", description: "off to dentist" },
};
const chat = mockChat(this, { users: [userWithStatus] });
this.set("chat", chat);
this.set("channel", createDirectMessageChannelDraft());
},
async test(assert) { await fillIn(".filter-usernames", "hawk");
await fillIn(".filter-usernames", "hawk"); assert.true(exists(".user-status-message"));
assert.ok(exists(".user-status-message"));
},
}); });
}); });

View File

@ -15,15 +15,17 @@ module("Discourse Chat | Component | on-visibility-action", function (hooks) {
this.set("root", document.querySelector("#ember-testing")); this.set("root", document.querySelector("#ember-testing"));
await render( await render(hbs`
hbs`{{#if display}}{{on-visibility-action action=action root=root}}{{/if}}` {{#if display}}
); <OnVisibilityAction @action={{this.action}} @root={{this.root}} />
{{/if}}
`);
assert.equal(this.value, null); assert.strictEqual(this.value, null);
this.set("display", true); this.set("display", true);
await waitUntil(() => this.value !== null); await waitUntil(() => this.value !== null);
assert.equal(this.value, "foo"); assert.strictEqual(this.value, "foo");
}); });
}); });

View File

@ -15,7 +15,7 @@ module("Discourse Chat | Component | user-card-chat-button", function (hooks) {
await render(hbs`<UserCardChatButton/>`); await render(hbs`<UserCardChatButton/>`);
assert.ok(exists(".user-card-chat-btn"), "it shows the chat button"); assert.true(exists(".user-card-chat-btn"), "it shows the chat button");
}); });
test("when current user cant send direct messages", async function (assert) { test("when current user cant send direct messages", async function (assert) {
@ -25,7 +25,7 @@ module("Discourse Chat | Component | user-card-chat-button", function (hooks) {
await render(hbs`<UserCardChatButton/>`); await render(hbs`<UserCardChatButton/>`);
assert.notOk( assert.false(
exists(".user-card-chat-btn"), exists(".user-card-chat-btn"),
"it doesnt show the chat button" "it doesnt show the chat button"
); );

View File

@ -21,7 +21,7 @@ module(
test("empty state when there are no notifications", async function (assert) { test("empty state when there are no notifications", async function (assert) {
await render(template); await render(template);
assert.ok(exists(".empty-state .empty-state-body")); assert.true(exists(".empty-state .empty-state-body"));
assert.strictEqual( assert.strictEqual(
query(".empty-state .empty-state-title").textContent.trim(), query(".empty-state .empty-state-title").textContent.trim(),
I18n.t("user_menu.no_chat_notifications_title") I18n.t("user_menu.no_chat_notifications_title")