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/discourse-post-event-location-test.gjs
Kris 2f9f4e8401
FEATURE: render links to event topics as interactive cards (#40953)
When a link to an event topic is oneboxed from another post, it will now
render the event's interactive card instead of a generic quote, which
would sometimes be empty if the only content of the topic was the event.
This covers replies, the composer markdown preview, and the composer
rich text editor. When a card can't render it falls back to the standard
onebox quote.

This mirrors core's `localized_oneboxes` pattern for the event data, and
uses a cooked decorator to swap the quote for `<DiscoursePostEvent>`. In
the rich text editor a ProseMirror NodeView renders the read-only card.

Before:
<img width="828" height="298" alt="image"
src="https://github.com/user-attachments/assets/41df1ece-ca38-4747-8c5a-3dda0b06998a"
/>

After:
<img width="757" height="540" alt="image"
src="https://github.com/user-attachments/assets/6312242d-f7c1-43e3-b641-0d471680c107"
/>

A pared down read-only card is rendered in the composer for preview.

<img width="600" alt="image"
src="https://github.com/user-attachments/assets/c06cd020-6acb-4a45-87be-4621ff2bf308"
/>


<img width="800" alt="image"
src="https://github.com/user-attachments/assets/8250458b-0082-4be8-980a-bfb69a5191d3"
/>
2026-07-17 10:36:54 -04:00

58 lines
1.8 KiB
Text
Vendored

import { render } from "@ember/test-helpers";
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import Location from "discourse/plugins/discourse-calendar/discourse/components/discourse-post-event/location";
module(
"Integration | Component | DiscoursePostEventLocation",
function (hooks) {
setupRenderingTest(hooks);
test("renders a plain-text location", async function (assert) {
await render(
<template><Location @location="Conference Room A" /></template>
);
assert
.dom(".event-location")
.includesText("Conference Room A", "shows the location text");
});
test("renders a URL location as a plain link, never a onebox", async function (assert) {
await render(
<template>
<Location @location="https://youtube.com/watch?v=123" />
</template>
);
assert
.dom(".event-location a")
.hasAttribute("href", "https://youtube.com/watch?v=123")
.hasText("https://youtube.com/watch?v=123", "shows the raw url");
assert
.dom(".event-location a")
.doesNotHaveClass(
"onebox",
"leaves no onebox markup for the composer's onebox pass to hydrate"
);
});
test("links urls inside surrounding text", async function (assert) {
await render(
<template>
<Location @location="Zoom: https://zoom.us/j/123 (room 2)" />
</template>
);
assert
.dom(".event-location a")
.hasText("https://zoom.us/j/123", "links only the url part");
assert
.dom(".event-location")
.includesText("Zoom:", "keeps the text before the url");
assert
.dom(".event-location")
.includesText("(room 2)", "keeps the text after the url");
});
}
);