|
| 1 | +/* |
| 2 | +Copyright 2026 Element Creations Ltd. |
| 3 | +
|
| 4 | +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial |
| 5 | +Please see LICENSE in the repository root for full details. |
| 6 | +*/ |
| 7 | + |
| 8 | +// @vitest-environment happy-dom |
| 9 | + |
| 10 | +import React from "react"; |
| 11 | +import { beforeEach, describe, expect, it, vi } from "vitest"; |
| 12 | +import { render, screen } from "test-utils-rtl"; |
| 13 | +import userEvent from "@testing-library/user-event"; |
| 14 | +import { EventType, type MatrixClient, MatrixEvent, MsgType, Room } from "matrix-js-sdk/src/matrix"; |
| 15 | + |
| 16 | +import { DocumentViewerCard } from "./DocumentViewerCard"; |
| 17 | +import { clientAndSDKContextRenderOptions, stubClient, TestSDKContext } from "../../../test/test-utils"; |
| 18 | + |
| 19 | +function mkFileEvent(): MatrixEvent { |
| 20 | + return new MatrixEvent({ |
| 21 | + room_id: "!room:example.org", |
| 22 | + sender: "@user:example.org", |
| 23 | + event_id: "$readme", |
| 24 | + type: EventType.RoomMessage, |
| 25 | + content: { |
| 26 | + body: "README.md", |
| 27 | + msgtype: MsgType.File, |
| 28 | + url: "mxc://example.org/readme", |
| 29 | + info: { mimetype: "text/markdown" }, |
| 30 | + }, |
| 31 | + }); |
| 32 | +} |
| 33 | + |
| 34 | +describe("DocumentViewerCard", () => { |
| 35 | + let client: MatrixClient; |
| 36 | + let sdkContext: TestSDKContext; |
| 37 | + |
| 38 | + beforeEach(() => { |
| 39 | + client = stubClient(); |
| 40 | + sdkContext = new TestSDKContext(); |
| 41 | + sdkContext._client = client; |
| 42 | + }); |
| 43 | + |
| 44 | + it("names the card after the file and mounts its viewer", async () => { |
| 45 | + render( |
| 46 | + <DocumentViewerCard mxEvent={mkFileEvent()} onClose={vi.fn()} />, |
| 47 | + clientAndSDKContextRenderOptions(client, sdkContext), |
| 48 | + ); |
| 49 | + |
| 50 | + expect(screen.getByRole("heading", { name: "README.md" })).toBeInTheDocument(); |
| 51 | + // The viewer is code split, so it shows up once its chunk has loaded. |
| 52 | + expect(await screen.findByRole("status")).toHaveTextContent("Loading document"); |
| 53 | + }); |
| 54 | + |
| 55 | + it("shows an error that can be closed when the attachment can no longer be opened", async () => { |
| 56 | + const user = userEvent.setup(); |
| 57 | + const onClose = vi.fn(); |
| 58 | + const mxEvent = mkFileEvent(); |
| 59 | + // A redaction while the card is open leaves an event no viewer handles. |
| 60 | + mxEvent.makeRedacted(mxEvent, new Room(mxEvent.getRoomId()!, client, client.getSafeUserId())); |
| 61 | + |
| 62 | + render( |
| 63 | + <DocumentViewerCard mxEvent={mxEvent} onClose={onClose} />, |
| 64 | + clientAndSDKContextRenderOptions(client, sdkContext), |
| 65 | + ); |
| 66 | + |
| 67 | + expect(screen.getByRole("heading", { name: "Document" })).toBeInTheDocument(); |
| 68 | + expect(screen.getByRole("alert")).toHaveTextContent("Unable to load this file."); |
| 69 | + |
| 70 | + await user.click(screen.getByRole("button", { name: "Close" })); |
| 71 | + expect(onClose).toHaveBeenCalledOnce(); |
| 72 | + }); |
| 73 | +}); |
0 commit comments