mirror of
https://github.com/discourse/discourse.git
synced 2025-06-09 06:18:14 +08:00
DEV: refactor topic-summary widget to topic-map-summary component (#25447)
* shift topic-summary widget to topic-map-summary component * remove relativeDate memoization which was causing bug where displayed date never updated
This commit is contained in:
@ -3,12 +3,7 @@ import { longDate, relativeAge } from "discourse/lib/formatter";
|
|||||||
|
|
||||||
export default class RelativeDate extends Component {
|
export default class RelativeDate extends Component {
|
||||||
get datetime() {
|
get datetime() {
|
||||||
if (this.memoizedDatetime) {
|
return new Date(this.args.date);
|
||||||
return this.memoizedDatetime;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.memoizedDatetime = new Date(this.args.date);
|
|
||||||
return this.memoizedDatetime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
|
@ -0,0 +1,154 @@
|
|||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
|
import DButton from "discourse/components/d-button";
|
||||||
|
import RelativeDate from "discourse/components/relative-date";
|
||||||
|
import TopicParticipants from "discourse/components/topic-map/topic-participants";
|
||||||
|
import number from "discourse/helpers/number";
|
||||||
|
import slice from "discourse/helpers/slice";
|
||||||
|
import i18n from "discourse-common/helpers/i18n";
|
||||||
|
import { avatarImg } from "discourse-common/lib/avatar-utils";
|
||||||
|
import gt from "truth-helpers/helpers/gt";
|
||||||
|
|
||||||
|
export default class TopicMapSummary extends Component {
|
||||||
|
get toggleMapButton() {
|
||||||
|
return {
|
||||||
|
title: this.args.collapsed
|
||||||
|
? "topic.expand_details"
|
||||||
|
: "topic.collapse_details",
|
||||||
|
icon: this.args.collapsed ? "chevron-down" : "chevron-up",
|
||||||
|
ariaExpanded: this.args.collapsed ? "false" : "true",
|
||||||
|
ariaControls: "topic-map-expanded",
|
||||||
|
action: this.args.toggleMap,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get shouldShowParticipants() {
|
||||||
|
return (
|
||||||
|
this.args.collapsed &&
|
||||||
|
this.args.postAttrs.topicPostsCount > 2 &&
|
||||||
|
this.args.postAttrs.participants &&
|
||||||
|
this.args.postAttrs.participants.length > 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get createdByAvatar() {
|
||||||
|
return htmlSafe(
|
||||||
|
avatarImg({
|
||||||
|
avatarTemplate: this.args.postAttrs.createdByAvatarTemplate,
|
||||||
|
size: "tiny",
|
||||||
|
title:
|
||||||
|
this.args.postAttrs.createdByName ||
|
||||||
|
this.args.postAttrs.createdByUsername,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get lastPostAvatar() {
|
||||||
|
return htmlSafe(
|
||||||
|
avatarImg({
|
||||||
|
avatarTemplate: this.args.postAttrs.lastPostAvatarTemplate,
|
||||||
|
size: "tiny",
|
||||||
|
title:
|
||||||
|
this.args.postAttrs.lastPostName ||
|
||||||
|
this.args.postAttrs.lastPostUsername,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<nav class="buttons">
|
||||||
|
<DButton
|
||||||
|
@icon={{this.toggleMapButton.icon}}
|
||||||
|
@title={{this.toggleMapButton.title}}
|
||||||
|
@ariaExpanded={{this.toggleMapButton.ariaExpanded}}
|
||||||
|
@ariaControls={{this.toggleMapButton.ariaControls}}
|
||||||
|
@action={{this.toggleMapButton.action}}
|
||||||
|
class="btn"
|
||||||
|
/>
|
||||||
|
</nav>
|
||||||
|
<ul>
|
||||||
|
<li class="created-at">
|
||||||
|
<h4 role="presentation">{{i18n "created_lowercase"}}</h4>
|
||||||
|
<div class="topic-map-post created-at">
|
||||||
|
<a
|
||||||
|
class="trigger-user-card"
|
||||||
|
data-user-card={{@postAttrs.createdByUsername}}
|
||||||
|
title={{@postAttrs.createdByUsername}}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
{{this.createdByAvatar}}
|
||||||
|
<RelativeDate @date={{@postAttrs.topicCreatedAt}} />
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="last-reply">
|
||||||
|
<a href={{@postAttrs.lastPostUrl}}>
|
||||||
|
<h4 role="presentation">{{i18n "last_reply_lowercase"}}</h4>
|
||||||
|
<div class="topic-map-post last-reply">
|
||||||
|
<a
|
||||||
|
class="trigger-user-card"
|
||||||
|
data-user-card={{@postAttrs.lastPostUsername}}
|
||||||
|
title={{@postAttrs.lastPostUsername}}
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
{{this.lastPostAvatar}}
|
||||||
|
<RelativeDate @date={{@postAttrs.lastPostAt}} />
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="replies">
|
||||||
|
{{number @postAttrs.topicReplyCount noTitle="true"}}
|
||||||
|
<h4 role="presentation">{{i18n
|
||||||
|
"replies_lowercase"
|
||||||
|
count=@postAttrs.topicReplyCount
|
||||||
|
}}</h4>
|
||||||
|
</li>
|
||||||
|
<li class="secondary views">
|
||||||
|
{{number
|
||||||
|
@postAttrs.topicViews
|
||||||
|
noTitle="true"
|
||||||
|
class=@postAttrs.topicViewsHeat
|
||||||
|
}}
|
||||||
|
<h4 role="presentation">{{i18n
|
||||||
|
"views_lowercase"
|
||||||
|
count=@postAttrs.topicViews
|
||||||
|
}}</h4>
|
||||||
|
</li>
|
||||||
|
{{#if (gt @postAttrs.participantCount 0)}}
|
||||||
|
<li class="secondary users">
|
||||||
|
{{number @postAttrs.participantCount noTitle="true"}}
|
||||||
|
<h4 role="presentation">{{i18n
|
||||||
|
"users_lowercase"
|
||||||
|
count=@postAttrs.participantCount
|
||||||
|
}}</h4>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if (gt @postAttrs.topicLikeCount 0)}}
|
||||||
|
<li class="secondary likes">
|
||||||
|
{{number @postAttrs.topicLikeCount noTitle="true"}}
|
||||||
|
<h4 role="presentation">{{i18n
|
||||||
|
"likes_lowercase"
|
||||||
|
count=@postAttrs.topicLikeCount
|
||||||
|
}}</h4>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
{{#if (gt @postAttrs.topicLinkCount 0)}}
|
||||||
|
<li class="secondary links">
|
||||||
|
{{number @postAttrs.topicLinkCount noTitle="true"}}
|
||||||
|
<h4 role="presentation">{{i18n
|
||||||
|
"links_lowercase"
|
||||||
|
count=@postAttrs.topicLinkCount
|
||||||
|
}}</h4>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if this.shouldShowParticipants}}
|
||||||
|
<li class="avatars">
|
||||||
|
<TopicParticipants
|
||||||
|
@participants={{slice 0 3 @postAttrs.participants}}
|
||||||
|
@userFilters={{@postAttrs.userFilters}}
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
}
|
@ -1,9 +1,7 @@
|
|||||||
import { htmlSafe } from "@ember/template";
|
import { htmlSafe } from "@ember/template";
|
||||||
import { hbs } from "ember-cli-htmlbars";
|
import { hbs } from "ember-cli-htmlbars";
|
||||||
import { h } from "virtual-dom";
|
import { h } from "virtual-dom";
|
||||||
import { dateNode, numberNode } from "discourse/helpers/node";
|
|
||||||
import { replaceEmoji } from "discourse/widgets/emoji";
|
import { replaceEmoji } from "discourse/widgets/emoji";
|
||||||
import { avatarFor } from "discourse/widgets/post";
|
|
||||||
import RenderGlimmer from "discourse/widgets/render-glimmer";
|
import RenderGlimmer from "discourse/widgets/render-glimmer";
|
||||||
import { createWidget } from "discourse/widgets/widget";
|
import { createWidget } from "discourse/widgets/widget";
|
||||||
import I18n from "discourse-i18n";
|
import I18n from "discourse-i18n";
|
||||||
@ -46,170 +44,6 @@ createWidget("topic-map-show-links", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
createWidget("topic-map-summary", {
|
|
||||||
tagName: "section.map",
|
|
||||||
|
|
||||||
buildClasses(attrs, state) {
|
|
||||||
if (state.collapsed) {
|
|
||||||
return "map-collapsed";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
html(attrs, state) {
|
|
||||||
const contents = [];
|
|
||||||
contents.push(
|
|
||||||
h("li.created-at", [
|
|
||||||
h(
|
|
||||||
"h4",
|
|
||||||
{
|
|
||||||
attributes: { role: "presentation" },
|
|
||||||
},
|
|
||||||
I18n.t("created_lowercase")
|
|
||||||
),
|
|
||||||
h("div.topic-map-post.created-at", [
|
|
||||||
avatarFor("tiny", {
|
|
||||||
username: attrs.createdByUsername,
|
|
||||||
template: attrs.createdByAvatarTemplate,
|
|
||||||
name: attrs.createdByName,
|
|
||||||
}),
|
|
||||||
dateNode(attrs.topicCreatedAt),
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
);
|
|
||||||
contents.push(
|
|
||||||
h(
|
|
||||||
"li.last-reply",
|
|
||||||
h("a", { attributes: { href: attrs.lastPostUrl } }, [
|
|
||||||
h(
|
|
||||||
"h4",
|
|
||||||
{
|
|
||||||
attributes: { role: "presentation" },
|
|
||||||
},
|
|
||||||
I18n.t("last_reply_lowercase")
|
|
||||||
),
|
|
||||||
h("div.topic-map-post.last-reply", [
|
|
||||||
avatarFor("tiny", {
|
|
||||||
username: attrs.lastPostUsername,
|
|
||||||
template: attrs.lastPostAvatarTemplate,
|
|
||||||
name: attrs.lastPostName,
|
|
||||||
}),
|
|
||||||
dateNode(attrs.lastPostAt),
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
)
|
|
||||||
);
|
|
||||||
contents.push(
|
|
||||||
h("li.replies", [
|
|
||||||
numberNode(attrs.topicReplyCount),
|
|
||||||
h(
|
|
||||||
"h4",
|
|
||||||
{
|
|
||||||
attributes: { role: "presentation" },
|
|
||||||
},
|
|
||||||
I18n.t("replies_lowercase", {
|
|
||||||
count: attrs.topicReplyCount,
|
|
||||||
}).toString()
|
|
||||||
),
|
|
||||||
])
|
|
||||||
);
|
|
||||||
contents.push(
|
|
||||||
h("li.secondary.views", [
|
|
||||||
numberNode(attrs.topicViews, { className: attrs.topicViewsHeat }),
|
|
||||||
h(
|
|
||||||
"h4",
|
|
||||||
{
|
|
||||||
attributes: { role: "presentation" },
|
|
||||||
},
|
|
||||||
I18n.t("views_lowercase", { count: attrs.topicViews }).toString()
|
|
||||||
),
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
if (attrs.participantCount > 0) {
|
|
||||||
contents.push(
|
|
||||||
h("li.secondary.users", [
|
|
||||||
numberNode(attrs.participantCount),
|
|
||||||
h(
|
|
||||||
"h4",
|
|
||||||
{
|
|
||||||
attributes: { role: "presentation" },
|
|
||||||
},
|
|
||||||
I18n.t("users_lowercase", {
|
|
||||||
count: attrs.participantCount,
|
|
||||||
}).toString()
|
|
||||||
),
|
|
||||||
])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrs.topicLikeCount) {
|
|
||||||
contents.push(
|
|
||||||
h("li.secondary.likes", [
|
|
||||||
numberNode(attrs.topicLikeCount),
|
|
||||||
h(
|
|
||||||
"h4",
|
|
||||||
{
|
|
||||||
attributes: { role: "presentation" },
|
|
||||||
},
|
|
||||||
I18n.t("likes_lowercase", {
|
|
||||||
count: attrs.topicLikeCount,
|
|
||||||
}).toString()
|
|
||||||
),
|
|
||||||
])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attrs.topicLinkLength > 0) {
|
|
||||||
contents.push(
|
|
||||||
h("li.secondary.links", [
|
|
||||||
numberNode(attrs.topicLinkLength),
|
|
||||||
h(
|
|
||||||
"h4",
|
|
||||||
{
|
|
||||||
attributes: { role: "presentation" },
|
|
||||||
},
|
|
||||||
I18n.t("links_lowercase", {
|
|
||||||
count: attrs.topicLinkLength,
|
|
||||||
}).toString()
|
|
||||||
),
|
|
||||||
])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
state.collapsed &&
|
|
||||||
attrs.topicPostsCount > 2 &&
|
|
||||||
attrs.participants &&
|
|
||||||
attrs.participants.length > 0
|
|
||||||
) {
|
|
||||||
const participants = renderParticipants.call(
|
|
||||||
this,
|
|
||||||
"li.avatars",
|
|
||||||
"",
|
|
||||||
attrs.userFilters,
|
|
||||||
attrs.participants.slice(0, 3)
|
|
||||||
);
|
|
||||||
contents.push(participants);
|
|
||||||
}
|
|
||||||
|
|
||||||
const nav = h(
|
|
||||||
"nav.buttons",
|
|
||||||
this.attach("button", {
|
|
||||||
title: state.collapsed
|
|
||||||
? "topic.expand_details"
|
|
||||||
: "topic.collapse_details",
|
|
||||||
icon: state.collapsed ? "chevron-down" : "chevron-up",
|
|
||||||
ariaExpanded: state.collapsed ? "false" : "true",
|
|
||||||
ariaControls: "topic-map-expanded",
|
|
||||||
action: "toggleMap",
|
|
||||||
className: "btn",
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return [nav, h("ul", contents)];
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
createWidget("topic-map-link", {
|
createWidget("topic-map-link", {
|
||||||
tagName: "a.topic-link.track-link",
|
tagName: "a.topic-link.track-link",
|
||||||
|
|
||||||
@ -326,7 +160,7 @@ export default createWidget("topic-map", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
html(attrs, state) {
|
html(attrs, state) {
|
||||||
const contents = [this.attach("topic-map-summary", attrs, { state })];
|
const contents = [this.buildTopicMapSummary(attrs, state)];
|
||||||
|
|
||||||
if (!state.collapsed) {
|
if (!state.collapsed) {
|
||||||
contents.push(this.attach("topic-map-expanded", attrs));
|
contents.push(this.attach("topic-map-expanded", attrs));
|
||||||
@ -344,6 +178,29 @@ export default createWidget("topic-map", {
|
|||||||
|
|
||||||
toggleMap() {
|
toggleMap() {
|
||||||
this.state.collapsed = !this.state.collapsed;
|
this.state.collapsed = !this.state.collapsed;
|
||||||
|
this.scheduleRerender();
|
||||||
|
},
|
||||||
|
|
||||||
|
buildTopicMapSummary(attrs, state) {
|
||||||
|
const { collapsed } = state;
|
||||||
|
const wrapperClass = collapsed
|
||||||
|
? "section.map.map-collapsed"
|
||||||
|
: "section.map";
|
||||||
|
|
||||||
|
return new RenderGlimmer(
|
||||||
|
this,
|
||||||
|
wrapperClass,
|
||||||
|
hbs`<TopicMap::TopicMapSummary
|
||||||
|
@postAttrs={{@data.postAttrs}}
|
||||||
|
@toggleMap={{@data.toggleMap}}
|
||||||
|
@collapsed={{@data.collapsed}}
|
||||||
|
/>`,
|
||||||
|
{
|
||||||
|
toggleMap: this.toggleMap.bind(this),
|
||||||
|
postAttrs: attrs,
|
||||||
|
collapsed,
|
||||||
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
buildSummaryBox(attrs) {
|
buildSummaryBox(attrs) {
|
||||||
|
@ -661,29 +661,23 @@ acceptance("Topic stats update automatically", function () {
|
|||||||
test("Likes count updates automatically", async function (assert) {
|
test("Likes count updates automatically", async function (assert) {
|
||||||
await visit("/t/internationalization-localization/280");
|
await visit("/t/internationalization-localization/280");
|
||||||
|
|
||||||
const likesDisplay = query("#post_1 .topic-map .likes .number");
|
const likesCountSelectors = "#post_1 .topic-map .likes .number";
|
||||||
const oldLikes = likesDisplay.textContent;
|
const oldLikesCount = query(likesCountSelectors).textContent;
|
||||||
|
|
||||||
const likesChangedFixture = {
|
const likesChangedFixture = {
|
||||||
id: 280,
|
id: 280,
|
||||||
type: "stats",
|
type: "stats",
|
||||||
like_count: 999,
|
like_count: parseInt(oldLikesCount, 10) + 42,
|
||||||
};
|
};
|
||||||
|
const expectedLikesCount = likesChangedFixture.like_count.toString();
|
||||||
|
|
||||||
// simulate the topic like_count being changed
|
// simulate the topic like_count being changed
|
||||||
await publishToMessageBus("/topic/280", likesChangedFixture);
|
await publishToMessageBus("/topic/280", likesChangedFixture);
|
||||||
|
|
||||||
const newLikes = likesDisplay.textContent;
|
assert.dom(likesCountSelectors).hasText(expectedLikesCount);
|
||||||
|
|
||||||
assert.notEqual(
|
assert.notEqual(
|
||||||
oldLikes,
|
oldLikesCount,
|
||||||
newLikes,
|
expectedLikesCount,
|
||||||
"it updates the like count on the topic stats"
|
"it updates the likes count on the topic stats"
|
||||||
);
|
|
||||||
assert.equal(
|
|
||||||
newLikes,
|
|
||||||
likesChangedFixture.like_count,
|
|
||||||
"it updates the like count with the expected value"
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -703,83 +697,70 @@ acceptance("Topic stats update automatically", function () {
|
|||||||
test("Replies count updates automatically", async function (assert) {
|
test("Replies count updates automatically", async function (assert) {
|
||||||
await visit("/t/internationalization-localization/280");
|
await visit("/t/internationalization-localization/280");
|
||||||
|
|
||||||
const repliesDisplay = query("#post_1 .topic-map .replies .number");
|
const repliesCountSelectors = "#post_1 .topic-map .replies .number";
|
||||||
const oldReplies = repliesDisplay.textContent;
|
const oldRepliesCount = query(repliesCountSelectors).textContent;
|
||||||
|
const expectedRepliesCount = (
|
||||||
|
postsChangedFixture.posts_count - 1
|
||||||
|
).toString();
|
||||||
|
|
||||||
// simulate the topic posts_count being changed
|
// simulate the topic posts_count being changed
|
||||||
await publishToMessageBus("/topic/280", postsChangedFixture);
|
await publishToMessageBus("/topic/280", postsChangedFixture);
|
||||||
|
|
||||||
const newLikes = repliesDisplay.textContent;
|
assert.dom(repliesCountSelectors).hasText(expectedRepliesCount);
|
||||||
|
|
||||||
assert.notEqual(
|
assert.notEqual(
|
||||||
oldReplies,
|
oldRepliesCount,
|
||||||
newLikes,
|
expectedRepliesCount,
|
||||||
"it updates the replies count on the topic stats"
|
"it updates the replies count on the topic stats"
|
||||||
);
|
);
|
||||||
assert.equal(
|
|
||||||
newLikes,
|
|
||||||
postsChangedFixture.posts_count - 1, // replies = posts_count - 1
|
|
||||||
"it updates the replies count with the expected value"
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Last replier avatar updates automatically", async function (assert) {
|
test("Last replier avatar updates automatically", async function (assert) {
|
||||||
await visit("/t/internationalization-localization/280");
|
await visit("/t/internationalization-localization/280");
|
||||||
|
const avatarSelectors = "#post_1 .topic-map .last-reply .avatar";
|
||||||
|
const avatarImg = query(avatarSelectors);
|
||||||
|
|
||||||
const avatarImg = query("#post_1 .topic-map .last-reply .avatar");
|
|
||||||
const oldAvatarTitle = avatarImg.title;
|
const oldAvatarTitle = avatarImg.title;
|
||||||
const oldAvatarSrc = avatarImg.src;
|
const oldAvatarSrc = avatarImg.src;
|
||||||
|
const expectedAvatarTitle = postsChangedFixture.last_poster.name;
|
||||||
|
const expectedAvatarSrc = postsChangedFixture.last_poster.avatar_template;
|
||||||
|
|
||||||
// simulate the topic posts_count being changed
|
// simulate the topic posts_count being changed
|
||||||
await publishToMessageBus("/topic/280", postsChangedFixture);
|
await publishToMessageBus("/topic/280", postsChangedFixture);
|
||||||
|
|
||||||
const newAvatarTitle = avatarImg.title;
|
assert.dom(avatarSelectors).hasAttribute("title", expectedAvatarTitle);
|
||||||
const newAvatarSrc = avatarImg.src;
|
|
||||||
|
|
||||||
assert.notEqual(
|
assert.notEqual(
|
||||||
oldAvatarTitle,
|
oldAvatarTitle,
|
||||||
newAvatarTitle,
|
expectedAvatarTitle,
|
||||||
"it updates the last poster avatar title on the topic stats"
|
"it updates the last poster avatar title on the topic stats"
|
||||||
);
|
);
|
||||||
assert.equal(
|
|
||||||
newAvatarTitle,
|
assert.dom(avatarSelectors).hasAttribute("src", expectedAvatarSrc);
|
||||||
postsChangedFixture.last_poster.name,
|
|
||||||
"it updates the last poster avatar title with the expected value"
|
|
||||||
);
|
|
||||||
assert.notEqual(
|
assert.notEqual(
|
||||||
oldAvatarSrc,
|
oldAvatarSrc,
|
||||||
newAvatarSrc,
|
expectedAvatarSrc,
|
||||||
"it updates the last poster avatar src on the topic stats"
|
"it updates the last poster avatar src on the topic stats"
|
||||||
);
|
);
|
||||||
assert.equal(
|
|
||||||
newAvatarSrc,
|
|
||||||
`${document.location.origin}${postsChangedFixture.last_poster.avatar_template}`,
|
|
||||||
"it updates the last poster avatar src with the expected value"
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Last replied at updates automatically", async function (assert) {
|
test("Last replied at updates automatically", async function (assert) {
|
||||||
await visit("/t/internationalization-localization/280");
|
await visit("/t/internationalization-localization/280");
|
||||||
|
|
||||||
const lastRepliedAtDisplay = query(
|
const lastRepliedAtSelectors =
|
||||||
"#post_1 .topic-map .last-reply .relative-date"
|
"#post_1 .topic-map .last-reply .relative-date";
|
||||||
);
|
const lastRepliedAtDisplay = query(lastRepliedAtSelectors);
|
||||||
const oldTime = lastRepliedAtDisplay.dataset.time;
|
const oldTime = lastRepliedAtDisplay.dataset.time;
|
||||||
|
const expectedTime = Date.parse(
|
||||||
|
postsChangedFixture.last_posted_at
|
||||||
|
).toString();
|
||||||
|
|
||||||
// simulate the topic posts_count being changed
|
// simulate the topic posts_count being changed
|
||||||
await publishToMessageBus("/topic/280", postsChangedFixture);
|
await publishToMessageBus("/topic/280", postsChangedFixture);
|
||||||
|
|
||||||
const newTime = lastRepliedAtDisplay.dataset.time;
|
assert.dom(lastRepliedAtSelectors).hasAttribute("data-time", expectedTime);
|
||||||
|
|
||||||
assert.notEqual(
|
assert.notEqual(
|
||||||
oldTime,
|
oldTime,
|
||||||
newTime,
|
expectedTime,
|
||||||
"it updates the last posted time on the topic stats"
|
"it updates the last posted time on the topic stats"
|
||||||
);
|
);
|
||||||
assert.equal(
|
|
||||||
newTime,
|
|
||||||
new Date(postsChangedFixture.last_posted_at).getTime(),
|
|
||||||
"it updates the last posted time with the expected value"
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user