From d1040932a54a0508943e635dd80a7672ed62676c Mon Sep 17 00:00:00 2001 From: Coracle-Bot Date: Tue, 15 Sep 2026 17:59:05 +0000 Subject: [PATCH] Assert the quote placeholder on a quote nothing can answer (#544) --- e2e/USER_STORIES.md | 3 ++- e2e/specs/content-rendering.spec.ts | 23 +++++++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/e2e/USER_STORIES.md b/e2e/USER_STORIES.md index 09fcf2a2..2ad9a9a0 100644 --- a/e2e/USER_STORIES.md +++ b/e2e/USER_STORIES.md @@ -1008,8 +1008,9 @@ Acceptance: quote strip. - Clicking that strip takes alice to (or scrolls her to) her original message. - A room message quoting a thread post renders as a bordered card naming the - author and content, briefly showing a loading state first. + author and content. - Clicking that card opens the quoted post. +- A quote whose event has not arrived shows a loading placeholder in its place. ### US-066 — See distinctive inline tokens diff --git a/e2e/specs/content-rendering.spec.ts b/e2e/specs/content-rendering.spec.ts index e6308bb6..716b50fb 100644 --- a/e2e/specs/content-rendering.spec.ts +++ b/e2e/specs/content-rendering.spec.ts @@ -1,4 +1,4 @@ -import {npubEncode} from "nostr-tools/nip19" +import {neventEncode, npubEncode} from "nostr-tools/nip19" import {HOUR, MINUTE} from "@welshman/lib" import {MESSAGE, makeEvent} from "@welshman/util" import {Article, Thread} from "@welshman/domain" @@ -14,6 +14,11 @@ const INVOICE = "ypqdq5xysxxatsyp3k7enxv4jsxqzpuaztrnwngzn3kdzw5hydlzf03qdgm2hdq27cqv3" + "agm2awhz5se903vruatfhq77w3ls4evs3ch9zw97j25emudupq63nyw24cg27h2rspfj9" +// An event id no fixture publishes. A quote card is in its loading state until the quoted event +// arrives, and only one that never arrives holds it there long enough to assert: the relay is a +// container on loopback, so a quote it can answer resolves before a locator has resolved. +const UNKNOWN_EVENT_ID = "6f1ac4b0d2e37f5981c6ab4e2d0937fc85be1a2d3c4f5061728394a5b6c7d8e9" + // A cashu token keeps its own scheme in the value, and needs fifty-odd payload characters after // it before the parser will take it. const CASHU = @@ -298,6 +303,7 @@ test("US-065 see quoted and embedded content", async ({seed, as}) => { let reply!: Seeded let thread!: Seeded let threadQuote!: Seeded + let unresolvable!: Seeded const scenario = await seed(({relay, user, at}) => { const space = relay("space") @@ -338,6 +344,12 @@ test("US-065 see quoted and embedded content", async ({seed, as}) => { thread = topic reply = space.reply(user.bob, point, "totally agree with this", at(20, MINUTE)) threadQuote = space.reply(user.bob, topic, "worth a read", at(15, MINUTE)) + unresolvable = space.message( + user.bob, + "general", + `nostr:${neventEncode({id: UNKNOWN_EVENT_ID, relays: [space.url]})}\n\nand this one`, + at(10, MINUTE), + ) }) const {url} = scenario.space("space") @@ -345,9 +357,12 @@ test("US-065 see quoted and embedded content", async ({seed, as}) => { const threadMessage = page.locator(`[data-event="${threadQuote.id}"]`) - // First, because it is the state a quote card is in until the quoted event arrives, and a - // thread is not part of the room's own feed — the card has to go and fetch it. - await expect(threadMessage.getByText("Loading event...")).toBeVisible() + // The state a quote card is in until the quoted event arrives. It is asserted on the quote + // nothing can answer rather than on the thread below, which resolves off an open socket to + // loopback and is as likely to be a card by the time this runs as a placeholder. + const unresolvableMessage = page.locator(`[data-event="${unresolvable.id}"]`) + + await expect(unresolvableMessage.getByText("Loading event...")).toBeVisible() const replyMessage = page.locator(`[data-event="${reply.id}"]`) const quoteStrip = replyMessage.locator(".border-l-2")