0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-08 17:53:55 +08:00
discourse/plugins/discourse-calendar/test/javascripts/integration/components/rich-editor-extension-test.js
Régis Hanol 5cf6b4a29c
FIX: Support uppercase and separators in event custom field names (#40995)
Previously, event custom fields whose names contained uppercase letters,
dashes, or dots either crashed the event builder's advanced settings
dialog or were silently dropped on save, so the feature effectively only
worked with plain lowercase names.

This change normalizes custom field names consistently across the
composer, server parser, and rich-text editor so they round-trip
regardless of case or separator, and validates the
`discourse_post_event_allowed_custom_fields` site setting to reject
malformed, colliding, or reserved names up front.

Meta:
https://meta.discourse.org/t/event-custom-fields-can-only-be-lowercase/405386
2026-06-24 17:02:32 +02:00

97 lines
3.6 KiB
JavaScript
Vendored

import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { testMarkdown } from "discourse/tests/helpers/rich-editor-helper";
module("Integration | Component | RichEditorExtension", function (hooks) {
setupRenderingTest(hooks);
const testCases = {
"event alone": [
[
`[event start="2025-03-21 15:41" status="public" timezone="Europe/Paris"]\n[/event]\n`,
(assert) => {
assert
.dom(".composer-event-node")
.exists("Event node should be rendered");
assert
.dom(".composer-event__status")
.hasText("Public", "Status should be displayed");
assert
.dom(".composer-event__date-display")
.exists("Date should be displayed");
},
`[event start="2025-03-21 15:41" status=public timezone=Europe/Paris]\n[/event]\n`,
],
],
"event with content around": [
[
`Hello world\n\n[event start="2025-03-21 15:41" status="public" timezone="Europe/Paris"]\n[/event]\nGoodbye world`,
(assert) => {
assert
.dom("p")
.exists({ count: 2 }, "Should have paragraphs around event");
assert
.dom(".composer-event-node")
.exists("Event node should be rendered");
assert
.dom(".composer-event__status")
.hasText("Public", "Status should be displayed");
},
`Hello world\n\n[event start="2025-03-21 15:41" status=public timezone=Europe/Paris]\n[/event]\nGoodbye world`,
],
],
"event with content inside": [
[
`[event start="2025-03-21 15:41" status="public" timezone="Europe/Paris"]\ntest\n[/event]\n`,
(assert) => {
assert
.dom(".composer-event-node")
.exists("Event node should be rendered");
assert
.dom(".composer-event__status")
.hasText("Public", "Status should be displayed");
},
`[event start="2025-03-21 15:41" status=public timezone=Europe/Paris]\ntest\n\n[/event]\n`,
],
],
};
Object.entries(testCases).forEach(([name, tests]) => {
tests.forEach(([markdown, expectedHtml, expectedMarkdown]) => {
test(name, async function (assert) {
this.siteSettings.rich_editor = true;
await testMarkdown(assert, markdown, expectedHtml, expectedMarkdown);
});
});
});
test("event preserves allowed custom fields", async function (assert) {
this.siteSettings.rich_editor = true;
this.siteSettings.discourse_post_event_allowed_custom_fields =
"fancy_field";
await testMarkdown(
assert,
`[event start="2025-03-21 15:41" status="public" timezone="Europe/Paris" fancyField="hello world"]\n[/event]\n`,
(a) => {
a.dom(".composer-event-node").exists("Event node should be rendered");
},
`[event start="2025-03-21 15:41" status=public timezone=Europe/Paris fancyField="hello world"]\n[/event]\n`
);
});
test("event preserves custom fields with uppercase letters", async function (assert) {
this.siteSettings.rich_editor = true;
this.siteSettings.discourse_post_event_allowed_custom_fields = "dress_CODE";
await testMarkdown(
assert,
`[event start="2025-03-21 15:41" status="public" timezone="Europe/Paris" dressCode="black tie"]\n[/event]\n`,
(a) => {
a.dom(".composer-event-node").exists("Event node should be rendered");
},
`[event start="2025-03-21 15:41" status=public timezone=Europe/Paris dressCode="black tie"]\n[/event]\n`
);
});
});