import { beforeEach, describe, expect, it, vi } from "vitest"; import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import { SportIconUploader } from "../SportIconUploader"; import type { FormEvent } from "react"; beforeEach(() => { vi.restoreAllMocks(); }); describe("SportIconUploader", () => { it("stores the initial icon URL in a hidden input", () => { const { container } = render( ); expect(container.querySelector('input[name="iconUrl"]')).toHaveValue("nfl.svg"); expect(screen.getByText("Current icon")).toBeInTheDocument(); }); it("rejects non-SVG files before upload", async () => { const { container } = render(); const fileInput = container.querySelector('input[type="file"]') as HTMLInputElement; fireEvent.change(fileInput, { target: { files: [new File(["not svg"], "icon.png", { type: "image/png" })] }, }); expect(await screen.findByText("Choose an SVG file.")).toBeInTheDocument(); }); it("chooses an icon from an existing sport", () => { const { container } = render( ); fireEvent.change(screen.getByRole("combobox", { name: "Use an existing sport icon" }), { target: { value: "nba.svg" }, }); expect(container.querySelector('input[name="iconUrl"]')).toHaveValue("nba.svg"); expect(screen.getByText("Current icon")).toBeInTheDocument(); }); it("uploads an SVG and updates the hidden input", async () => { vi.stubGlobal( "fetch", vi.fn().mockResolvedValue({ ok: true, json: async () => ({ iconUrl: "https://res.cloudinary.com/demo/image/upload/v1/sports-icons/nfl.svg" }), }) ); const { container } = render(); const fileInput = container.querySelector('input[type="file"]') as HTMLInputElement; fireEvent.change(fileInput, { target: { files: [new File([""], "icon.svg", { type: "image/svg+xml" })] }, }); fireEvent.click(await screen.findByRole("button", { name: "Upload SVG" })); await waitFor(() => { expect(container.querySelector('input[name="iconUrl"]')).toHaveValue( "https://res.cloudinary.com/demo/image/upload/v1/sports-icons/nfl.svg" ); }); expect(screen.getByText("Icon uploaded. Save the sport to apply it.")).toBeInTheDocument(); }); it("does not submit a parent form when uploading an SVG", async () => { vi.stubGlobal( "fetch", vi.fn().mockResolvedValue({ ok: true, json: async () => ({ iconUrl: "https://res.cloudinary.com/demo/image/upload/v1/sports-icons/nfl.svg" }), }) ); const onSubmit = vi.fn((event: FormEvent) => event.preventDefault()); const { container } = render(
); const fileInput = container.querySelector('input[type="file"]') as HTMLInputElement; fireEvent.change(fileInput, { target: { files: [new File([""], "icon.svg", { type: "image/svg+xml" })] }, }); fireEvent.click(await screen.findByRole("button", { name: "Upload SVG" })); await waitFor(() => expect(global.fetch).toHaveBeenCalled()); expect(onSubmit).not.toHaveBeenCalled(); }); });