import { fireEvent, render, screen, waitFor } from "@testing-library/react"; import { expect, test, vi } from "vitest"; import { CommunityPostForm } from "@/features/community-posts/components/CommunityPostForm"; import { parseCommunityPostPrice } from "@/features/community-posts/components/community-post-form-helpers"; import type { ApiClient, ApiRequestOptions } from "@/shared/api/client"; type CapturedRequest = { readonly body?: BodyInit | null; readonly method?: string; readonly path: string; }; function createClient(requests: CapturedRequest[]): ApiClient { return { async request(options: ApiRequestOptions): Promise { requests.push({ body: options.body, method: options.method, path: options.path }); return options.responseSchema.parse(null); }, }; } function renderForm(requests: CapturedRequest[]) { const onCreated = vi.fn(); render( Promise.resolve({ file, height: 600, previewUrl: "blob:post", width: 800 })} onCreated={onCreated} />); return onCreated; } test.each([ "-1", "1.5", "100000", ])("Community price preserves and rejects invalid raw input %s through the submit button", async (rawValue) => { const requests: CapturedRequest[] = []; const onCreated = renderForm(requests); fireEvent.change(screen.getByLabelText("내용"), { target: { value: "가격 검증 게시글" } }); fireEvent.change(screen.getByLabelText("가격"), { target: { value: rawValue } }); fireEvent.click(screen.getByRole("button", { name: "생성" })); expect(screen.getByLabelText("가격")).toHaveValue(Number(rawValue)); expect(await screen.findByText("가격은 0 이상 99,999 이하 정수 캔으로 입력하세요.")).toBeInTheDocument(); expect(requests.filter((request) => request.method === "POST")).toHaveLength(0); expect(onCreated).not.toHaveBeenCalled(); }); test.each(["0", "99999"])("Community price allows boundary input %s", async (value) => { const requests: CapturedRequest[] = []; const onCreated = renderForm(requests); fireEvent.change(screen.getByLabelText("내용"), { target: { value: "가격 경계 게시글" } }); fireEvent.change(screen.getByLabelText("가격"), { target: { value } }); fireEvent.click(screen.getByRole("button", { name: "생성" })); await waitFor(() => expect(onCreated).toHaveBeenCalledTimes(1)); expect(requests.filter((request) => request.method === "POST")).toHaveLength(1); }); test("Community price parser rejects blank, negative, and decimal raw input", () => { expect(parseCommunityPostPrice("")).toBeNull(); expect(parseCommunityPostPrice("-1")).toBeNull(); expect(parseCommunityPostPrice("1.5")).toBeNull(); });