diff --git a/src/app/dashboard/referrals/page.copy-loading.test.tsx b/src/app/dashboard/referrals/page.copy-loading.test.tsx new file mode 100644 index 00000000..80d17d54 --- /dev/null +++ b/src/app/dashboard/referrals/page.copy-loading.test.tsx @@ -0,0 +1,66 @@ +// @vitest-environment jsdom + +import { render, screen, waitFor } from "@testing-library/react"; +import { afterEach, describe, expect, it, vi } from "vitest"; +import ReferralsPage from "./page"; + +function deferred() { + let resolve!: (value: T) => void; + const promise = new Promise((res) => { + resolve = res; + }); + return { promise, resolve }; +} + +describe("ReferralsPage copy loading state", () => { + afterEach(() => { + vi.unstubAllGlobals(); + }); + + it("disables referral link copying until the link is loaded", async () => { + const codeResponse = deferred<{ + ok: boolean; + json: () => Promise<{ code: string; link: string }>; + }>(); + + vi.stubGlobal( + "fetch", + vi.fn(async (input: RequestInfo | URL) => { + const url = input.toString(); + if (url === "/api/referrals/code") { + return codeResponse.promise; + } + + return { + ok: true, + json: async () => ({ + data: [], + stats: { + total_invited: 0, + total_registered: 0, + conversion_rate: 0, + }, + }), + }; + }) + ); + + render(); + + const copyButton = screen.getByRole("button", { name: /copy/i }); + expect(copyButton).toBeDisabled(); + + codeResponse.resolve({ + ok: true, + json: async () => ({ + code: "alice", + link: "https://ugig.net/?ref=alice", + }), + }); + + await waitFor(() => { + expect(screen.getByDisplayValue("https://ugig.net/?ref=alice")).toBeTruthy(); + }); + expect(copyButton).not.toBeDisabled(); + }); +}); diff --git a/src/app/dashboard/referrals/page.tsx b/src/app/dashboard/referrals/page.tsx index 81c74cef..38ed17cf 100644 --- a/src/app/dashboard/referrals/page.tsx +++ b/src/app/dashboard/referrals/page.tsx @@ -63,6 +63,11 @@ export default function ReferralsPage() { }, []); const copyLink = async () => { + if (!referralLink) { + setError("Referral link is still loading. Please try again."); + return; + } + await navigator.clipboard.writeText(referralLink); setCopied(true); setTimeout(() => setCopied(false), 2000); @@ -166,7 +171,8 @@ export default function ReferralsPage() { />