mirror of
https://github.com/discourse/discourse.git
synced 2026-08-08 17:53:55 +08:00
Policy nodes in the rich editor now display a summary of their attributes (groups, version, renew, accept, etc.) and expose an edit button that opens the policy builder modal pre-populated with the current values. Changes are applied directly to the node, so policies can be tweaked without dropping back to markdown source. Also migrates the policy builder form to FormKit, replacing the bespoke `policy-form-field` component. This brings tooltips, proper field-level validation and a layout consistent with the rest of the UI. The "add users to group" picker now excludes automatic groups, which cannot be assigned to. Before: <img width="1238" height="337" alt="image" src="https://github.com/user-attachments/assets/44b21b44-a669-4474-8d14-5855326debfa" /> <img width="1030" height="1539" alt="image" src="https://github.com/user-attachments/assets/a816a491-ba25-4b0a-aa50-cbee32c60962" /> After: <img width="1280" height="574" alt="image" src="https://github.com/user-attachments/assets/6c4b4e18-674d-4e5a-be20-6008c730d348" /> <img width="1160" height="1499" alt="image" src="https://github.com/user-attachments/assets/7d47782c-9b53-43ee-b135-3bb3a2b9ae43" />
128 lines
6 KiB
JavaScript
Vendored
128 lines
6 KiB
JavaScript
Vendored
import { module, test } from "qunit";
|
|
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
|
import { setupRichEditor } from "discourse/tests/helpers/rich-editor-helper";
|
|
|
|
module(
|
|
"Integration | Component | prosemirror-editor - policy plugin extension",
|
|
function (hooks) {
|
|
setupRenderingTest(hooks);
|
|
|
|
hooks.beforeEach(function () {
|
|
this.siteSettings.policy_enabled = true;
|
|
});
|
|
|
|
test("policy with multiple groups", async function (assert) {
|
|
const markdown = `[policy groups="staff,admins" version="2"]\nI accept the terms\n\n[/policy]\n\n`;
|
|
const [{ value }] = await setupRichEditor(assert, markdown);
|
|
|
|
const policyElement = document.querySelector(".ProseMirror .policy");
|
|
assert.dom(policyElement).hasAttribute("data-groups", "staff,admins");
|
|
assert.dom(policyElement).hasAttribute("data-version", "2");
|
|
assert.dom("p", policyElement).hasText("I accept the terms");
|
|
|
|
assert.strictEqual(value, markdown);
|
|
});
|
|
|
|
test("policy with all attributes", async function (assert) {
|
|
const markdown = `[policy group="staff" version="1" accept="true" revoke="false" reminder="daily" renew="30" renew-start="2023-01-01" add-users-to-group="members" private="true"]\nComplex policy\n\n[/policy]\n\n`;
|
|
const [{ value }] = await setupRichEditor(assert, markdown);
|
|
|
|
const policyElement = document.querySelector(".ProseMirror .policy");
|
|
assert.dom(policyElement).hasAttribute("data-group", "staff");
|
|
assert.dom(policyElement).hasAttribute("data-version", "1");
|
|
assert.dom(policyElement).hasAttribute("data-accept", "true");
|
|
assert.dom(policyElement).hasAttribute("data-revoke", "false");
|
|
assert.dom(policyElement).hasAttribute("data-reminder", "daily");
|
|
assert.dom(policyElement).hasAttribute("data-renew", "30");
|
|
assert.dom(policyElement).hasAttribute("data-renew-start", "2023-01-01");
|
|
assert
|
|
.dom(policyElement)
|
|
.hasAttribute("data-add-users-to-group", "members");
|
|
assert.dom(policyElement).hasAttribute("data-private", "true");
|
|
assert.dom(".policy-node-edit-button", policyElement).exists();
|
|
assert.dom(".policy-attrs dt", policyElement).exists({ count: 9 });
|
|
assert.dom(".policy-attrs dd", policyElement).exists({ count: 9 });
|
|
assert.dom("p", policyElement).hasText("Complex policy");
|
|
|
|
assert.strictEqual(value, markdown);
|
|
});
|
|
|
|
test("policy with content around", async function (assert) {
|
|
const markdown = `Hello world\n\n[policy group="everyone" version="1"]\nI accept\n\n[/policy]\n\nGoodbye world`;
|
|
const [{ value }] = await setupRichEditor(assert, markdown);
|
|
|
|
const policyElement = document.querySelector(".ProseMirror .policy");
|
|
assert.dom(policyElement).hasAttribute("data-group", "everyone");
|
|
assert.dom("p", policyElement).hasText("I accept");
|
|
|
|
assert.strictEqual(value, markdown);
|
|
});
|
|
|
|
test("empty policy", async function (assert) {
|
|
const markdown = `[policy group="staff" version="1"]\n[/policy]\n\n`;
|
|
const [{ value }] = await setupRichEditor(assert, markdown);
|
|
|
|
const policyElement = document.querySelector(".ProseMirror .policy");
|
|
assert.dom(policyElement).hasAttribute("data-group", "staff");
|
|
assert.dom(policyElement).hasAttribute("data-version", "1");
|
|
assert.dom("p", policyElement).doesNotExist();
|
|
|
|
assert.strictEqual(value, markdown);
|
|
});
|
|
|
|
test("policy with multiline content", async function (assert) {
|
|
const markdown = `[policy group="staff" version="1"]\nFirst line\n\nSecond paragraph\n\n[/policy]\n\n`;
|
|
const [{ value }] = await setupRichEditor(assert, markdown);
|
|
|
|
const policyElement = document.querySelector(".ProseMirror .policy");
|
|
assert.dom("p", policyElement).exists({ count: 2 });
|
|
assert.dom("p:first-child", policyElement).hasText("First line");
|
|
assert.dom("p:last-child", policyElement).hasText("Second paragraph");
|
|
|
|
assert.strictEqual(value, markdown);
|
|
});
|
|
|
|
test("policy filters out empty attributes", async function (assert) {
|
|
const inputMarkdown = `[policy group="staff" version="1" accept="" revoke=""]\nTest\n[/policy]`;
|
|
const expectedMarkdown = `[policy group="staff" version="1"]\nTest\n\n[/policy]\n\n`;
|
|
const [{ value }] = await setupRichEditor(assert, inputMarkdown);
|
|
|
|
const policyElement = document.querySelector(".ProseMirror .policy");
|
|
assert.dom(policyElement).hasAttribute("data-group", "staff");
|
|
assert.dom(policyElement).hasAttribute("data-version", "1");
|
|
assert.dom(policyElement).doesNotHaveAttribute("data-accept");
|
|
assert.dom(policyElement).doesNotHaveAttribute("data-revoke");
|
|
assert.dom("p", policyElement).hasText("Test");
|
|
|
|
assert.strictEqual(value, expectedMarkdown);
|
|
});
|
|
|
|
test("policy renders basic structure in rich editor", async function (assert) {
|
|
const markdown = `[policy group="staff" version="1"]\nI accept this policy\n\n[/policy]\n\n`;
|
|
const [{ value }] = await setupRichEditor(assert, markdown);
|
|
|
|
const policyElement = document.querySelector(".ProseMirror .policy");
|
|
assert.dom(policyElement).exists();
|
|
assert.dom(policyElement).hasClass("policy");
|
|
assert.dom(policyElement).hasAttribute("data-group", "staff");
|
|
assert.dom(policyElement).hasAttribute("data-version", "1");
|
|
|
|
// Check that content is preserved
|
|
assert.dom("p", policyElement).hasText("I accept this policy");
|
|
|
|
assert.strictEqual(value, markdown);
|
|
});
|
|
|
|
test("policy handles empty content", async function (assert) {
|
|
const markdown = `[policy groups="admins" version="2"]\n[/policy]\n\n`;
|
|
const [{ value }] = await setupRichEditor(assert, markdown);
|
|
|
|
const policyElement = document.querySelector(".ProseMirror .policy");
|
|
assert.dom(policyElement).exists();
|
|
assert.dom(policyElement).hasAttribute("data-groups", "admins");
|
|
assert.dom(policyElement).hasAttribute("data-version", "2");
|
|
|
|
assert.strictEqual(value, markdown);
|
|
});
|
|
}
|
|
);
|