diff --git a/src/components/views/messages/DownloadActionButton.tsx b/src/components/views/messages/DownloadActionButton.tsx index 479e792fca..0072dd42a0 100644 --- a/src/components/views/messages/DownloadActionButton.tsx +++ b/src/components/views/messages/DownloadActionButton.tsx @@ -26,6 +26,12 @@ interface IProps { mediaEventHelperGet: () => MediaEventHelper | undefined; } +function useButtonTitle(loading: boolean, isEncrypted: boolean): string { + if (!loading) return _t("action|download"); + + return isEncrypted ? _t("timeline|download_action_decrypting") : _t("timeline|download_action_downloading"); +} + export default function DownloadActionButton({ mxEvent, mediaEventHelperGet }: IProps): ReactElement | null { const mediaEventHelper = useMemo(() => mediaEventHelperGet(), [mediaEventHelperGet]); const downloadUrl = mediaEventHelper?.media.srcHttp ?? ""; @@ -33,6 +39,8 @@ export default function DownloadActionButton({ mxEvent, mediaEventHelperGet }: I const { download, loading, canDownload } = useDownloadMedia(downloadUrl, fileName, mxEvent); + const buttonTitle = useButtonTitle(loading, mediaEventHelper?.media.isEncrypted ?? false); + if (!canDownload) return null; const spinner = loading ? : undefined; @@ -45,7 +53,7 @@ export default function DownloadActionButton({ mxEvent, mediaEventHelperGet }: I return ( ({ + decryptAttachment: jest.fn().mockResolvedValue(new Blob(["TESTFILE"], { type: "application/octet-stream" })), +})); + describe("DownloadActionButton", () => { + const plainEvent = new MatrixEvent({ + room_id: "!room:id", + sender: "@user:id", + type: "m.room.message", + content: { + body: "test", + msgtype: "m.image", + url: "mxc://matrix.org/1234", + }, + }); + + beforeEach(() => { + jest.restoreAllMocks(); + fetchMockJest.restore(); + }); + + afterEach(() => { + clearAllModals(); + }); + it("should show error if media API returns one", async () => { const cli = stubClient(); // eslint-disable-next-line no-restricted-properties @@ -26,24 +51,14 @@ describe("DownloadActionButton", () => { (mxc) => `https://matrix.org/_matrix/media/r0/download/${mxc.slice(6)}`, ); - fetchMockJest.get("https://matrix.org/_matrix/media/r0/download/matrix.org/1234", { + fetchMockJest.getOnce("https://matrix.org/_matrix/media/r0/download/matrix.org/1234", { status: 404, body: { errcode: "M_NOT_FOUND", error: "Not found" }, }); - const event = new MatrixEvent({ - room_id: "!room:id", - sender: "@user:id", - type: "m.room.message", - content: { - body: "test", - msgtype: "m.image", - url: "mxc://matrix.org/1234", - }, - }); - const mediaEventHelper = new MediaEventHelper(event); + const mediaEventHelper = new MediaEventHelper(plainEvent); - render( mediaEventHelper} />); + render( mediaEventHelper} />); const spy = jest.spyOn(Modal, "createDialog"); @@ -57,4 +72,85 @@ describe("DownloadActionButton", () => { ), ); }); + + it("should show download tooltip on hover", async () => { + stubClient(); + + const user = userEvent.setup(); + + fetchMockJest.getOnce("https://matrix.org/_matrix/media/r0/download/matrix.org/1234", "TESTFILE"); + + const event = new MatrixEvent({ + room_id: "!room:id", + sender: "@user:id", + type: "m.room.message", + content: { + body: "test", + msgtype: "m.image", + url: "mxc://matrix.org/1234", + }, + }); + + render( undefined} />); + + const button = screen.getByRole("button"); + await user.hover(button); + + await waitFor(() => { + expect(screen.getByRole("tooltip")).toHaveTextContent("Download"); + }); + }); + + it("should show downloading tooltip while unencrypted files are downloading", async () => { + const user = userEvent.setup(); + + stubClient(); + + fetchMockJest.getOnce("http://this.is.a.url/matrix.org/1234", "TESTFILE"); + + const mediaEventHelper = new MediaEventHelper(plainEvent); + + render( mediaEventHelper} />); + + const button = screen.getByRole("button"); + await user.hover(button); + + await user.click(button); + + await waitFor(() => { + expect(screen.getByRole("tooltip")).toHaveTextContent("Downloading"); + }); + }); + + it("should show decrypting tooltip while encrypted files are downloading", async () => { + const user = userEvent.setup(); + + stubClient(); + + fetchMockJest.getOnce("http://this.is.a.url/matrix.org/1234", "UFTUGJMF"); + + const e2eEvent = new MatrixEvent({ + room_id: "!room:id", + sender: "@user:id", + type: "m.room.message", + content: { + body: "test", + msgtype: "m.image", + file: { url: "mxc://matrix.org/1234" }, + }, + }); + + const mediaEventHelper = new MediaEventHelper(e2eEvent); + + render( mediaEventHelper} />); + + const button = screen.getByRole("button"); + await user.hover(button); + + await user.click(button); + + await waitFor(() => { + expect(screen.getByRole("tooltip")).toHaveTextContent("Decrypting"); + }); + }); });