From 9a3f18f9bc507f5991901c865337acb62d08cacf Mon Sep 17 00:00:00 2001 From: Martin Brennan Date: Tue, 8 Aug 2023 15:38:37 +1000 Subject: [PATCH] FIX: Cook hashtags in small action posts (#23008) There is no decorateCooked equivalent for small action posts, so we need to manually call decorateHashtags when there is a custom message for small action posts in order for the hashtags to get their coloured icon/square. --- .../app/widgets/post-small-action.js | 6 ++- spec/system/hashtag_autocomplete_spec.rb | 43 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/discourse/app/widgets/post-small-action.js b/app/assets/javascripts/discourse/app/widgets/post-small-action.js index f90ec6db284..ddc56a676a7 100644 --- a/app/assets/javascripts/discourse/app/widgets/post-small-action.js +++ b/app/assets/javascripts/discourse/app/widgets/post-small-action.js @@ -8,6 +8,7 @@ import { h } from "virtual-dom"; import { iconNode } from "discourse-common/lib/icon-library"; import { userPath } from "discourse/lib/url"; import { htmlSafe } from "@ember/template"; +import { decorateHashtags } from "discourse/lib/hashtag-autocomplete"; export function actionDescriptionHtml(actionCode, createdAt, username, path) { const dt = new Date(createdAt); @@ -178,9 +179,12 @@ export default createWidget("post-small-action", { } if (!attrs.actionDescriptionWidget && attrs.cooked) { + const fragment = document.createElement("div"); + fragment.innerHTML = attrs.cooked; + decorateHashtags(fragment, this.site); customMessage.push( new RawHtml({ - html: `
${attrs.cooked}
`, + html: `
${fragment.innerHTML}
`, }) ); } diff --git a/spec/system/hashtag_autocomplete_spec.rb b/spec/system/hashtag_autocomplete_spec.rb index ef79c2d13e0..61b0ee1f571 100644 --- a/spec/system/hashtag_autocomplete_spec.rb +++ b/spec/system/hashtag_autocomplete_spec.rb @@ -149,6 +149,49 @@ describe "Using #hashtag autocompletion to search for and lookup categories and end end + it "decorates post small actions with hashtags in the custom message" do + post = + Fabricate(:small_action, raw: "this is a #cool-cat category and a #cooltag tag", topic: topic) + topic_page.visit_topic(topic) + expect(topic_page).to have_post_number(post.post_number) + expect(find(".small-action-custom-message")["innerHTML"]).to have_tag( + "a", + with: { + class: "hashtag-cooked", + href: tag.url, + "data-type": "tag", + "data-slug": tag.name, + "data-id": tag.id, + "aria-label": tag.name, + }, + ) do + with_tag( + "svg", + with: { + class: "fa d-icon d-icon-tag svg-icon hashtag-color--tag-#{tag.id} svg-string", + }, + ) { with_tag("use", with: { href: "#tag" }) } + end + expect(find(".small-action-custom-message")["innerHTML"]).to have_tag( + "a", + with: { + class: "hashtag-cooked", + href: category.url, + "data-type": "category", + "data-slug": category.slug, + "data-id": category.id, + "aria-label": category.name, + }, + ) do + with_tag( + "span", + with: { + class: "hashtag-category-badge hashtag-color--category-#{category.id}", + }, + ) + end + end + context "when a user cannot access the category for a hashtag cooked in another post" do fab!(:admin) { Fabricate(:admin) } fab!(:manager_group) { Fabricate(:group, name: "Managers") }