mirror of
https://github.com/discourse/discourse-solved.git
synced 2025-07-01 11:22:12 +00:00
DEV: Add compatibility with the Glimmer Post Stream (#363)
This commit is contained in:
parent
ae01ad30c3
commit
8e72136f54
@ -0,0 +1,166 @@
|
|||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import { on } from "@ember/modifier";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import { service } from "@ember/service";
|
||||||
|
import { htmlSafe } from "@ember/template";
|
||||||
|
import AsyncContent from "discourse/components/async-content";
|
||||||
|
import PostCookedHtml from "discourse/components/post/cooked-html";
|
||||||
|
import concatClass from "discourse/helpers/concat-class";
|
||||||
|
import icon from "discourse/helpers/d-icon";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
import { iconHTML } from "discourse/lib/icon-library";
|
||||||
|
import { formatUsername } from "discourse/lib/utilities";
|
||||||
|
import { i18n } from "discourse-i18n";
|
||||||
|
|
||||||
|
export default class SolvedAcceptedAnswer extends Component {
|
||||||
|
@service siteSettings;
|
||||||
|
@service store;
|
||||||
|
|
||||||
|
@tracked expanded = false;
|
||||||
|
|
||||||
|
get acceptedAnswer() {
|
||||||
|
return this.topic.accepted_answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
get quoteId() {
|
||||||
|
return `accepted-answer-${this.topic.id}-${this.acceptedAnswer.post_number}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get topic() {
|
||||||
|
return this.args.post.topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasExcerpt() {
|
||||||
|
return !!this.acceptedAnswer.excerpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
get htmlAccepter() {
|
||||||
|
const username = this.acceptedAnswer.accepter_username;
|
||||||
|
const name = this.acceptedAnswer.accepter_name;
|
||||||
|
|
||||||
|
if (!this.siteSettings.show_who_marked_solved) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formattedUsername =
|
||||||
|
this.siteSettings.display_name_on_posts && name
|
||||||
|
? name
|
||||||
|
: formatUsername(username);
|
||||||
|
|
||||||
|
return htmlSafe(
|
||||||
|
i18n("solved.marked_solved_by", {
|
||||||
|
username: formattedUsername,
|
||||||
|
username_lower: username.toLowerCase(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get htmlSolvedBy() {
|
||||||
|
const username = this.acceptedAnswer.username;
|
||||||
|
const name = this.acceptedAnswer.name;
|
||||||
|
const postNumber = this.acceptedAnswer.post_number;
|
||||||
|
|
||||||
|
if (!username || !postNumber) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const displayedUser =
|
||||||
|
this.siteSettings.display_name_on_posts && name
|
||||||
|
? name
|
||||||
|
: formatUsername(username);
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
icon: iconHTML("square-check", { class: "accepted" }),
|
||||||
|
username_lower: username.toLowerCase(),
|
||||||
|
username: displayedUser,
|
||||||
|
post_path: `${this.topic.url}/${postNumber}`,
|
||||||
|
post_number: postNumber,
|
||||||
|
user_path: this.store.createRecord("user", { username }).path,
|
||||||
|
};
|
||||||
|
|
||||||
|
return htmlSafe(i18n("solved.accepted_html", data));
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
toggleExpandedPost() {
|
||||||
|
if (!this.hasExcerpt) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.expanded = !this.expanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async loadExpandedAcceptedAnswer(postNumber) {
|
||||||
|
const acceptedAnswer = await ajax(
|
||||||
|
`/posts/by_number/${this.topic.id}/${postNumber}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.store.createRecord("post", acceptedAnswer);
|
||||||
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<aside
|
||||||
|
class="quote accepted-answer"
|
||||||
|
data-post={{this.acceptedAnswer.post_number}}
|
||||||
|
data-topic={{this.topic.id}}
|
||||||
|
data-expanded={{this.expanded}}
|
||||||
|
>
|
||||||
|
{{! template-lint-disable no-invalid-interactive }}
|
||||||
|
<div
|
||||||
|
class={{concatClass
|
||||||
|
"title"
|
||||||
|
(unless this.hasExcerpt "title-only")
|
||||||
|
(if this.hasExcerpt "quote__title--can-toggle-content")
|
||||||
|
}}
|
||||||
|
{{on "click" this.toggleExpandedPost}}
|
||||||
|
>
|
||||||
|
<div class="accepted-answer--solver-accepter">
|
||||||
|
<div class="accepted-answer--solver">
|
||||||
|
{{this.htmlSolvedBy}}
|
||||||
|
</div>
|
||||||
|
<div class="accepted-answer--accepter">
|
||||||
|
{{this.htmlAccepter}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{#if this.hasExcerpt}}
|
||||||
|
<div class="quote-controls">
|
||||||
|
<button
|
||||||
|
aria-controls={{this.quoteId}}
|
||||||
|
aria-expanded={{this.expanded}}
|
||||||
|
class="quote-toggle btn-flat"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
{{icon
|
||||||
|
(if this.expanded "chevron-up" "chevron-down")
|
||||||
|
title="post.expand_collapse"
|
||||||
|
}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
{{#if this.hasExcerpt}}
|
||||||
|
<blockquote id={{this.quoteId}}>
|
||||||
|
{{#if this.expanded}}
|
||||||
|
<AsyncContent
|
||||||
|
@asyncData={{this.loadExpandedAcceptedAnswer}}
|
||||||
|
@context={{this.acceptedAnswer.post_number}}
|
||||||
|
>
|
||||||
|
<:content as |expandedAnswer|>
|
||||||
|
<div class="expanded-quote" data-post-id={{expandedAnswer.id}}>
|
||||||
|
<PostCookedHtml
|
||||||
|
@post={{expandedAnswer}}
|
||||||
|
@streamElement={{false}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</:content>
|
||||||
|
</AsyncContent>
|
||||||
|
{{else}}
|
||||||
|
{{htmlSafe this.acceptedAnswer.excerpt}}
|
||||||
|
{{/if}}
|
||||||
|
</blockquote>
|
||||||
|
{{/if}}
|
||||||
|
</aside>
|
||||||
|
</template>
|
||||||
|
}
|
@ -0,0 +1,136 @@
|
|||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { computed } from "@ember/object";
|
||||||
|
import { withSilencedDeprecations } from "discourse/lib/deprecated";
|
||||||
|
import { iconHTML } from "discourse/lib/icon-library";
|
||||||
|
import { withPluginApi } from "discourse/lib/plugin-api";
|
||||||
|
import { formatUsername } from "discourse/lib/utilities";
|
||||||
|
import Topic from "discourse/models/topic";
|
||||||
|
import User from "discourse/models/user";
|
||||||
|
import PostCooked from "discourse/widgets/post-cooked";
|
||||||
|
import RenderGlimmer from "discourse/widgets/render-glimmer";
|
||||||
|
import { i18n } from "discourse-i18n";
|
||||||
|
import SolvedAcceptAnswerButton from "../components/solved-accept-answer-button";
|
||||||
|
import SolvedAcceptedAnswer from "../components/solved-accepted-answer";
|
||||||
|
import SolvedUnacceptAnswerButton from "../components/solved-unaccept-answer-button";
|
||||||
|
|
||||||
|
function initializeWithApi(api) {
|
||||||
|
customizePost(api);
|
||||||
|
customizePostMenu(api);
|
||||||
|
|
||||||
|
if (api.addDiscoveryQueryParam) {
|
||||||
|
api.addDiscoveryQueryParam("solved", { replace: true, refreshModel: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function customizePost(api) {
|
||||||
|
api.addTrackedPostProperties(
|
||||||
|
"can_accept_answer",
|
||||||
|
"can_unaccept_answer",
|
||||||
|
"accepted_answer",
|
||||||
|
"topic_accepted_answer"
|
||||||
|
);
|
||||||
|
|
||||||
|
api.renderAfterWrapperOutlet(
|
||||||
|
"post-content-cooked-html",
|
||||||
|
class extends Component {
|
||||||
|
static shouldRender(args) {
|
||||||
|
return args.post.post_number === 1 && args.post.topic.accepted_answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
<template><SolvedAcceptedAnswer @post={{@outletArgs.post}} /></template>
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
withSilencedDeprecations("discourse.post-stream-widget-overrides", () =>
|
||||||
|
customizeWidgetPost(api)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function customizeWidgetPost(api) {
|
||||||
|
api.decorateWidget("post-contents:after-cooked", (helper) => {
|
||||||
|
let post = helper.getModel();
|
||||||
|
|
||||||
|
if (helper.attrs.post_number === 1 && post?.topic?.accepted_answer) {
|
||||||
|
return new RenderGlimmer(
|
||||||
|
helper.widget,
|
||||||
|
"div",
|
||||||
|
<template><SolvedAcceptedAnswer @post={{@data.post}} /></template>,
|
||||||
|
{ post }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function customizePostMenu(api) {
|
||||||
|
api.registerValueTransformer(
|
||||||
|
"post-menu-buttons",
|
||||||
|
({
|
||||||
|
value: dag,
|
||||||
|
context: {
|
||||||
|
post,
|
||||||
|
firstButtonKey,
|
||||||
|
secondLastHiddenButtonKey,
|
||||||
|
lastHiddenButtonKey,
|
||||||
|
},
|
||||||
|
}) => {
|
||||||
|
let solvedButton;
|
||||||
|
|
||||||
|
if (post.can_accept_answer) {
|
||||||
|
solvedButton = SolvedAcceptAnswerButton;
|
||||||
|
} else if (post.accepted_answer) {
|
||||||
|
solvedButton = SolvedUnacceptAnswerButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
solvedButton &&
|
||||||
|
dag.add(
|
||||||
|
"solved",
|
||||||
|
solvedButton,
|
||||||
|
post.topic_accepted_answer && !post.accepted_answer
|
||||||
|
? {
|
||||||
|
before: lastHiddenButtonKey,
|
||||||
|
after: secondLastHiddenButtonKey,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
before: [
|
||||||
|
"assign", // button added by the assign plugin
|
||||||
|
firstButtonKey,
|
||||||
|
],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "extend-for-solved-button",
|
||||||
|
initialize() {
|
||||||
|
withPluginApi("1.34.0", initializeWithApi);
|
||||||
|
|
||||||
|
withPluginApi("0.8.10", (api) => {
|
||||||
|
api.replaceIcon(
|
||||||
|
"notification.solved.accepted_notification",
|
||||||
|
"square-check"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
withPluginApi("0.11.0", (api) => {
|
||||||
|
api.addAdvancedSearchOptions({
|
||||||
|
statusOptions: [
|
||||||
|
{
|
||||||
|
name: i18n("search.advanced.statuses.solved"),
|
||||||
|
value: "solved",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: i18n("search.advanced.statuses.unsolved"),
|
||||||
|
value: "unsolved",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
withPluginApi("0.11.7", (api) => {
|
||||||
|
api.addSearchSuggestion("status:solved");
|
||||||
|
api.addSearchSuggestion("status:unsolved");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
@ -1,186 +0,0 @@
|
|||||||
import { computed } from "@ember/object";
|
|
||||||
import { iconHTML } from "discourse/lib/icon-library";
|
|
||||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
|
||||||
import { formatUsername } from "discourse/lib/utilities";
|
|
||||||
import Topic from "discourse/models/topic";
|
|
||||||
import User from "discourse/models/user";
|
|
||||||
import PostCooked from "discourse/widgets/post-cooked";
|
|
||||||
import { i18n } from "discourse-i18n";
|
|
||||||
import SolvedAcceptAnswerButton, {
|
|
||||||
acceptAnswer,
|
|
||||||
} from "../components/solved-accept-answer-button";
|
|
||||||
import SolvedUnacceptAnswerButton, {
|
|
||||||
unacceptAnswer,
|
|
||||||
} from "../components/solved-unaccept-answer-button";
|
|
||||||
|
|
||||||
function initializeWithApi(api) {
|
|
||||||
customizePostMenu(api);
|
|
||||||
|
|
||||||
api.includePostAttributes(
|
|
||||||
"can_accept_answer",
|
|
||||||
"can_unaccept_answer",
|
|
||||||
"accepted_answer",
|
|
||||||
"topic_accepted_answer"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (api.addDiscoveryQueryParam) {
|
|
||||||
api.addDiscoveryQueryParam("solved", { replace: true, refreshModel: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
api.decorateWidget("post-contents:after-cooked", (dec) => {
|
|
||||||
if (dec.attrs.post_number === 1) {
|
|
||||||
const postModel = dec.getModel();
|
|
||||||
if (postModel) {
|
|
||||||
const topic = postModel.topic;
|
|
||||||
if (topic.accepted_answer) {
|
|
||||||
const hasExcerpt = !!topic.accepted_answer.excerpt;
|
|
||||||
const excerpt = hasExcerpt
|
|
||||||
? ` <blockquote> ${topic.accepted_answer.excerpt} </blockquote> `
|
|
||||||
: "";
|
|
||||||
const solvedQuote = `
|
|
||||||
<aside class='quote accepted-answer' data-post="${topic.get("accepted_answer").post_number}" data-topic="${topic.id}">
|
|
||||||
<div class='title ${hasExcerpt ? "" : "title-only"}'>
|
|
||||||
<div class="accepted-answer--solver-accepter">
|
|
||||||
<div class="accepted-answer--solver">
|
|
||||||
${topic.solvedByHtml}
|
|
||||||
<\/div>
|
|
||||||
<div class="accepted-answer--accepter">
|
|
||||||
${topic.accepterHtml}
|
|
||||||
<\/div>
|
|
||||||
</div>
|
|
||||||
<div class="quote-controls"><\/div>
|
|
||||||
</div>
|
|
||||||
${excerpt}
|
|
||||||
</aside>`;
|
|
||||||
|
|
||||||
const cooked = new PostCooked({ cooked: solvedQuote }, dec);
|
|
||||||
return dec.rawHtml(cooked.init());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
api.attachWidgetAction("post", "acceptAnswer", function () {
|
|
||||||
acceptAnswer(this.model, this.appEvents, this.currentUser);
|
|
||||||
});
|
|
||||||
|
|
||||||
api.attachWidgetAction("post", "unacceptAnswer", function () {
|
|
||||||
unacceptAnswer(this.model, this.appEvents);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function customizePostMenu(api) {
|
|
||||||
api.registerValueTransformer(
|
|
||||||
"post-menu-buttons",
|
|
||||||
({
|
|
||||||
value: dag,
|
|
||||||
context: {
|
|
||||||
post,
|
|
||||||
firstButtonKey,
|
|
||||||
secondLastHiddenButtonKey,
|
|
||||||
lastHiddenButtonKey,
|
|
||||||
},
|
|
||||||
}) => {
|
|
||||||
let solvedButton;
|
|
||||||
|
|
||||||
if (post.can_accept_answer) {
|
|
||||||
solvedButton = SolvedAcceptAnswerButton;
|
|
||||||
} else if (post.accepted_answer) {
|
|
||||||
solvedButton = SolvedUnacceptAnswerButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
solvedButton &&
|
|
||||||
dag.add(
|
|
||||||
"solved",
|
|
||||||
solvedButton,
|
|
||||||
post.topic_accepted_answer && !post.accepted_answer
|
|
||||||
? {
|
|
||||||
before: lastHiddenButtonKey,
|
|
||||||
after: secondLastHiddenButtonKey,
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
before: [
|
|
||||||
"assign", // button added by the assign plugin
|
|
||||||
firstButtonKey,
|
|
||||||
],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "extend-for-solved-button",
|
|
||||||
initialize() {
|
|
||||||
Topic.reopen({
|
|
||||||
// keeping this here cause there is complex localization
|
|
||||||
solvedByHtml: computed("accepted_answer", "id", function () {
|
|
||||||
const username = this.get("accepted_answer.username");
|
|
||||||
const name = this.get("accepted_answer.name");
|
|
||||||
const postNumber = this.get("accepted_answer.post_number");
|
|
||||||
|
|
||||||
if (!username || !postNumber) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const displayedUser =
|
|
||||||
this.siteSettings.display_name_on_posts && name
|
|
||||||
? name
|
|
||||||
: formatUsername(username);
|
|
||||||
|
|
||||||
return i18n("solved.accepted_html", {
|
|
||||||
icon: iconHTML("square-check", { class: "accepted" }),
|
|
||||||
username_lower: username.toLowerCase(),
|
|
||||||
username: displayedUser,
|
|
||||||
post_path: `${this.url}/${postNumber}`,
|
|
||||||
post_number: postNumber,
|
|
||||||
user_path: User.create({ username }).path,
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
accepterHtml: computed("accepted_answer", function () {
|
|
||||||
const username = this.get("accepted_answer.accepter_username");
|
|
||||||
const name = this.get("accepted_answer.accepter_name");
|
|
||||||
if (!this.siteSettings.show_who_marked_solved) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
const formattedUsername =
|
|
||||||
this.siteSettings.display_name_on_posts && name
|
|
||||||
? name
|
|
||||||
: formatUsername(username);
|
|
||||||
return i18n("solved.marked_solved_by", {
|
|
||||||
username: formattedUsername,
|
|
||||||
username_lower: username.toLowerCase(),
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
withPluginApi("1.34.0", initializeWithApi);
|
|
||||||
|
|
||||||
withPluginApi("0.8.10", (api) => {
|
|
||||||
api.replaceIcon(
|
|
||||||
"notification.solved.accepted_notification",
|
|
||||||
"square-check"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
withPluginApi("0.11.0", (api) => {
|
|
||||||
api.addAdvancedSearchOptions({
|
|
||||||
statusOptions: [
|
|
||||||
{
|
|
||||||
name: i18n("search.advanced.statuses.solved"),
|
|
||||||
value: "solved",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n("search.advanced.statuses.unsolved"),
|
|
||||||
value: "unsolved",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
withPluginApi("0.11.7", (api) => {
|
|
||||||
api.addSearchSuggestion("status:solved");
|
|
||||||
api.addSearchSuggestion("status:unsolved");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
@ -58,10 +58,14 @@ $solved-color: var(--success);
|
|||||||
}
|
}
|
||||||
|
|
||||||
aside.quote.accepted-answer {
|
aside.quote.accepted-answer {
|
||||||
.title {
|
> .title {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
||||||
|
&.quote__title--can-toggle-content {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.accepted-answer--solver-accepter {
|
.accepted-answer--solver-accepter {
|
||||||
|
@ -15,6 +15,10 @@ describe "About page", type: :system do
|
|||||||
SiteSetting.show_who_marked_solved = true
|
SiteSetting.show_who_marked_solved = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%w[enabled disabled].each do |value|
|
||||||
|
before { SiteSetting.glimmer_post_stream_mode = value }
|
||||||
|
|
||||||
|
context "when glimmer_post_stream_mode=#{value}" do
|
||||||
it "accepts post as solution and shows in OP" do
|
it "accepts post as solution and shows in OP" do
|
||||||
sign_in(accepter)
|
sign_in(accepter)
|
||||||
|
|
||||||
@ -34,3 +38,5 @@ describe "About page", type: :system do
|
|||||||
expect(topic_page.find("blockquote")).to have_content("The answer is 42")
|
expect(topic_page.find("blockquote")).to have_content("The answer is 42")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@ -8,7 +8,13 @@ import pretender, {
|
|||||||
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
|
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
|
||||||
import { postStreamWithAcceptedAnswerExcerpt } from "../helpers/discourse-solved-helpers";
|
import { postStreamWithAcceptedAnswerExcerpt } from "../helpers/discourse-solved-helpers";
|
||||||
|
|
||||||
acceptance("Discourse Solved Plugin", function (needs) {
|
["enabled", "disabled"].forEach((postStreamMode) => {
|
||||||
|
acceptance(
|
||||||
|
`Discourse Solved Plugin (glimmer_post_stream_mode = ${postStreamMode})`,
|
||||||
|
function (needs) {
|
||||||
|
needs.settings({
|
||||||
|
glimmer_post_stream_mode: postStreamMode,
|
||||||
|
});
|
||||||
needs.user();
|
needs.user();
|
||||||
|
|
||||||
test("A topic with an accepted answer shows an excerpt of the answer, if provided", async function (assert) {
|
test("A topic with an accepted answer shows an excerpt of the answer, if provided", async function (assert) {
|
||||||
@ -42,4 +48,6 @@ acceptance("Discourse Solved Plugin", function (needs) {
|
|||||||
assert.dom(".fps-topic").exists({ count: 1 }, "has one post");
|
assert.dom(".fps-topic").exists({ count: 1 }, "has one post");
|
||||||
assert.dom(".topic-statuses .solved").exists("shows the right icon");
|
assert.dom(".topic-statuses .solved").exists("shows the right icon");
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user