diff --git a/desktop/src/shared/lib/useResolvedLinkPreviews.ts b/desktop/src/shared/lib/useResolvedLinkPreviews.ts index fb828d8ad3..136f8f4b1c 100644 --- a/desktop/src/shared/lib/useResolvedLinkPreviews.ts +++ b/desktop/src/shared/lib/useResolvedLinkPreviews.ts @@ -376,12 +376,10 @@ export function useResolvedLinkPreviews( return React.useMemo( () => - previews.map((preview) => - resolveLinkPreview( - preview, - resolvedMetadata[metadataCacheKey(preview.href)], - ), - ), + previews.flatMap((preview) => { + const metadata = resolvedMetadata[metadataCacheKey(preview.href)]; + return metadata === null ? [] : [resolveLinkPreview(preview, metadata)]; + }), [previews, resolvedMetadata], ); } diff --git a/desktop/tests/e2e/messaging.spec.ts b/desktop/tests/e2e/messaging.spec.ts index 5b0c63f2e2..fe1fb53ac1 100644 --- a/desktop/tests/e2e/messaging.spec.ts +++ b/desktop/tests/e2e/messaging.spec.ts @@ -104,7 +104,7 @@ async function measureThreadSummaryGeometry(summaryRow: Locator) { } test.beforeEach(async ({ page }, testInfo) => { - const mock = testInfo.title.includes("agent owner label") + const baseMock = testInfo.title.includes("agent owner label") ? { searchProfiles: [ { @@ -232,6 +232,9 @@ test.beforeEach(async ({ page }, testInfo) => { : undefined, } : undefined; + const mock = testInfo.title.includes("unresolvable preview") + ? { linkPreviewMetadata: null, linkPreviewMetadataDelayMs: 150 } + : baseMock; await installMockBridge(page, mock); }); @@ -586,6 +589,27 @@ test("completed link previews send when one URL has an unsnapshotable fragment", ).toEqual(previewUrls.slice(0, 2)); }); +test("unresolvable preview disappears after the terminal miss", async ({ + page, +}) => { + const previewUrl = "https://x.com/tellaho/status"; + await page.goto("/"); + await page.getByTestId("channel-general").click(); + await page.getByTestId("message-input").fill(previewUrl); + + const composerPreviews = page.locator("[data-composer-link-previews]"); + await expect(composerPreviews).toBeVisible(); + await expect( + composerPreviews.locator("[data-link-preview-composer-card]"), + ).toHaveAttribute("data-image-state", "pending"); + await expect(composerPreviews).toHaveCount(0); + + await page.getByTestId("send-message").click(); + const row = page.getByTestId("message-row").last(); + await expect(row).toContainText(previewUrl); + await expect(row.locator("[data-link-preview]")).toHaveCount(0); +}); + test("send does not wait for a pending link preview snapshot", async ({ page, }) => {