feat(ai-character): 관리자 인증 셸 구현
This commit is contained in:
68
src/shared/ui/__tests__/image-crop-dialog.test.tsx
Normal file
68
src/shared/ui/__tests__/image-crop-dialog.test.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import { fireEvent, render, screen } from "@testing-library/react";
|
||||
import { expect, test, vi } from "vitest";
|
||||
|
||||
import { ImageCropDialog } from "@/shared/ui/image-crop-dialog";
|
||||
import type { CropRenderRequest } from "@/shared/lib/crop-image";
|
||||
|
||||
const image = {
|
||||
file: new File(["image"], "profile.png", { type: "image/png" }),
|
||||
height: 600,
|
||||
previewUrl: "blob:profile",
|
||||
width: 600,
|
||||
};
|
||||
|
||||
test("ImageCropDialog provides move, zoom, reset, preview, cancel, and apply controls", async () => {
|
||||
const onApply = vi.fn();
|
||||
const onCancel = vi.fn();
|
||||
const renderCrop = vi.fn((request: CropRenderRequest) => Promise.resolve(new File([String(request.zoom)], "crop.png", { type: "image/png" })));
|
||||
|
||||
render(<ImageCropDialog image={image} onApply={onApply} onCancel={onCancel} open policy={{ aspect: 1, maxWidth: 800, noUpscale: true }} renderCrop={renderCrop} />);
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "오른쪽으로 이동" }));
|
||||
fireEvent.change(screen.getByRole("slider", { name: "확대 비율" }), { target: { value: "1.5" } });
|
||||
expect(screen.getByText("예상 결과 600 × 600px")).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "초기화" }));
|
||||
fireEvent.click(screen.getByRole("button", { name: "적용" }));
|
||||
await screen.findByText("예상 결과 600 × 600px");
|
||||
|
||||
expect(renderCrop).toHaveBeenCalledWith(expect.objectContaining({ offsetX: 0, offsetY: 0, outputHeight: 600, outputWidth: 600, zoom: 1 }));
|
||||
expect(onApply).toHaveBeenCalledWith(expect.any(File));
|
||||
fireEvent.click(screen.getByRole("button", { name: "취소" }));
|
||||
expect(onCancel).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test("ImageCropDialog supports keyboard movement and no-upscale sizing", async () => {
|
||||
const renderCrop = vi.fn((request: CropRenderRequest) => Promise.resolve(new File([`${request.offsetX}`], "crop.png", { type: "image/png" })));
|
||||
|
||||
render(<ImageCropDialog image={image} onApply={vi.fn()} onCancel={vi.fn()} open policy={{ aspect: 2, maxWidth: 800, noUpscale: true }} renderCrop={renderCrop} />);
|
||||
|
||||
const preview = screen.getByRole("application", { name: "이미지 crop 미리보기" });
|
||||
fireEvent.keyDown(preview, { key: "ArrowRight" });
|
||||
fireEvent.keyDown(preview, { key: "+" });
|
||||
fireEvent.click(screen.getByRole("button", { name: "적용" }));
|
||||
|
||||
expect(await screen.findByText("예상 결과 600 × 300px")).toBeInTheDocument();
|
||||
expect(renderCrop).toHaveBeenCalledWith(expect.objectContaining({ offsetX: 10, outputHeight: 300, outputWidth: 600, zoom: 1.1 }));
|
||||
});
|
||||
|
||||
test("ImageCropDialog supports free ratio output and pointer drag movement", async () => {
|
||||
const renderCrop = vi.fn((request: CropRenderRequest) => Promise.resolve(new File([`${request.offsetX},${request.offsetY}`], "crop.png", { type: "image/png" })));
|
||||
|
||||
render(<ImageCropDialog image={{ ...image, height: 600, width: 1200 }} onApply={vi.fn()} onCancel={vi.fn()} open policy={{ aspect: "free", maxWidth: 800, noUpscale: true }} renderCrop={renderCrop} />);
|
||||
|
||||
const preview = screen.getByRole("application", { name: "이미지 crop 미리보기" });
|
||||
fireEvent.pointerDown(preview, { clientX: 100, clientY: 100, pointerId: 1 });
|
||||
fireEvent.pointerMove(preview, { clientX: 130, clientY: 115, pointerId: 1 });
|
||||
fireEvent.pointerUp(preview, { pointerId: 1 });
|
||||
fireEvent.click(screen.getByRole("button", { name: "적용" }));
|
||||
|
||||
expect(await screen.findByText("예상 결과 800 × 400px")).toBeInTheDocument();
|
||||
expect(renderCrop).toHaveBeenCalledWith(expect.objectContaining({ offsetX: 30, offsetY: 15, outputHeight: 400, outputWidth: 800 }));
|
||||
});
|
||||
|
||||
test("ImageCropDialog renders nothing when closed", () => {
|
||||
render(<ImageCropDialog image={image} onApply={vi.fn()} onCancel={vi.fn()} open={false} policy={{ aspect: 1, maxWidth: 800, noUpscale: true }} />);
|
||||
|
||||
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
||||
});
|
||||
Reference in New Issue
Block a user