diff --git a/app/assets/javascripts/admin/addon/mixins/setting-component.js b/app/assets/javascripts/admin/addon/mixins/setting-component.js index 0be2ccdd752..f54f179046b 100644 --- a/app/assets/javascripts/admin/addon/mixins/setting-component.js +++ b/app/assets/javascripts/admin/addon/mixins/setting-component.js @@ -214,8 +214,15 @@ export default Mixin.create({ this.afterSave(); } } catch (e) { - if (e.jqXHR?.responseJSON?.errors) { - this.set("validationMessage", e.jqXHR.responseJSON.errors[0]); + const json = e.jqXHR?.responseJSON; + if (json?.errors) { + let errorString = json.errors[0]; + + if (json.html_message) { + errorString = htmlSafe(errorString); + } + + this.set("validationMessage", errorString); } else { this.set("validationMessage", I18n.t("generic_error")); } diff --git a/app/assets/javascripts/discourse/tests/integration/components/site-setting-test.js b/app/assets/javascripts/discourse/tests/integration/components/site-setting-test.js index 58b7c2dbfcc..63d3e426afc 100644 --- a/app/assets/javascripts/discourse/tests/integration/components/site-setting-test.js +++ b/app/assets/javascripts/discourse/tests/integration/components/site-setting-test.js @@ -1,8 +1,9 @@ import { module, test } from "qunit"; import { setupRenderingTest } from "discourse/tests/helpers/component-test"; -import { render } from "@ember/test-helpers"; +import { click, fillIn, render } from "@ember/test-helpers"; import { query } from "discourse/tests/helpers/qunit-helpers"; import { hbs } from "ember-cli-htmlbars"; +import pretender, { response } from "discourse/tests/helpers/create-pretender"; module("Integration | Component | site-setting", function (hooks) { setupRenderingTest(hooks); @@ -18,4 +19,44 @@ module("Integration | Component | site-setting", function (hooks) { assert.strictEqual(query(".formatted-selection").innerText, "a.com, b.com"); }); + + test("Error response with html_message is rendered as HTML", async function (assert) { + this.set("setting", { + setting: "test_setting", + value: "", + type: "input-setting-string", + }); + + const message = "

Unable to update site settings

"; + + pretender.put("/admin/site_settings/test_setting", () => { + return response(422, { html_message: true, errors: [message] }); + }); + + await render(hbs``); + await fillIn(query(".setting input"), "value"); + await click(query(".setting .d-icon-check")); + + assert.strictEqual(query(".validation-error h1").outerHTML, message); + }); + + test("Error response without html_message is not rendered as HTML", async function (assert) { + this.set("setting", { + setting: "test_setting", + value: "", + type: "input-setting-string", + }); + + const message = "

Unable to update site settings

"; + + pretender.put("/admin/site_settings/test_setting", () => { + return response(422, { errors: [message] }); + }); + + await render(hbs``); + await fillIn(query(".setting input"), "value"); + await click(query(".setting .d-icon-check")); + + assert.strictEqual(query(".validation-error h1"), null); + }); });