👷 ci: Add CI

This commit is contained in:
2026-05-10 13:37:51 +07:00
parent f84c9a4bb2
commit 4d2a1bb7ec
15 changed files with 361 additions and 114 deletions
@@ -5,9 +5,11 @@ import { EditorCanvasStage } from "./editor-canvas-stage";
vi.mock("../canvas-renderer", () => ({
CanvasRenderer: ({ onContextMenu }: { onContextMenu?: (x: number, y: number) => void }) => (
<button type="button" data-testid="canvas-renderer" onClick={() => onContextMenu?.(10, 12)}>
canvas
</button>
React.createElement(
"button",
{ type: "button", "data-testid": "canvas-renderer", onClick: () => onContextMenu?.(10, 12) },
"canvas",
)
),
}));
@@ -17,33 +19,33 @@ describe("EditorCanvasStage", () => {
const onCloseContextMenu = vi.fn();
render(
<EditorCanvasStage
isDark={false}
layers={[]}
canvasWidth={100}
canvasHeight={100}
selectedLayerId={null}
tool="pointer"
faceDetections={[]}
faceOverlayLayerId={null}
faceBlurPreview={null}
contextMenu={{ x: 10, y: 20 }}
labels={{ copy: "Copy", cut: "Cut", paste: "Paste" }}
onSelectLayer={() => undefined}
onMoveLayer={() => undefined}
onMoveLayerEnd={() => undefined}
onResizeLayer={() => undefined}
onResizeLayerEnd={() => undefined}
onRotateLayer={() => undefined}
onRotateLayerEnd={() => undefined}
onInteractionStart={() => undefined}
onInteractionEnd={() => undefined}
onContextMenu={() => undefined}
onCloseContextMenu={onCloseContextMenu}
onCopy={onCopy}
onCut={() => undefined}
onPaste={() => undefined}
/>,
React.createElement(EditorCanvasStage, {
isDark: false,
layers: [],
canvasWidth: 100,
canvasHeight: 100,
selectedLayerId: null,
tool: "pointer",
faceDetections: [],
faceOverlayLayerId: null,
faceBlurPreview: null,
contextMenu: { x: 10, y: 20 },
labels: { copy: "Copy", cut: "Cut", paste: "Paste" },
onSelectLayer: () => undefined,
onMoveLayer: () => undefined,
onMoveLayerEnd: () => undefined,
onResizeLayer: () => undefined,
onResizeLayerEnd: () => undefined,
onRotateLayer: () => undefined,
onRotateLayerEnd: () => undefined,
onInteractionStart: () => undefined,
onInteractionEnd: () => undefined,
onContextMenu: () => undefined,
onCloseContextMenu,
onCopy,
onCut: () => undefined,
onPaste: () => undefined,
}),
);
fireEvent.click(screen.getByText("Copy"));
@@ -99,7 +99,7 @@ export function EditorCanvasStage(props: EditorCanvasStageProps) {
faceOverlayLayerId={faceOverlayLayerId}
faceBlurPreview={faceBlurPreview}
/>
{contextMenu ? (
{contextMenu && (
<CanvasContextMenu
isDark={isDark}
x={contextMenu.x}
@@ -118,7 +118,7 @@ export function EditorCanvasStage(props: EditorCanvasStageProps) {
onCloseContextMenu();
}}
/>
) : null}
)}
</div>
</div>
</div>
@@ -4,24 +4,24 @@ import { describe, expect, it, vi } from "vitest";
import { EditorMobileSection } from "./editor-mobile-section";
vi.mock("../canvas-renderer", () => ({
CanvasRenderer: () => <div data-testid="canvas-renderer" />,
CanvasRenderer: () => React.createElement("div", { "data-testid": "canvas-renderer" }),
}));
describe("EditorMobileSection", () => {
it("shows face detection helper message in face mode", () => {
render(
<EditorMobileSection
isDark={false}
canvasWidth={100}
canvasHeight={120}
layers={[]}
selectedLayerId={null}
tool="face"
faceDetections={[{ x: 1, y: 1, width: 10, height: 10, label: "f" }]}
faceOverlayLayerId={null}
faceStatus="idle"
faceBlurPreview={null}
labels={{
React.createElement(EditorMobileSection, {
isDark: false,
canvasWidth: 100,
canvasHeight: 120,
layers: [],
selectedLayerId: null,
tool: "face",
faceDetections: [{ x: 1, y: 1, width: 10, height: 10, label: "f" }],
faceOverlayLayerId: null,
faceStatus: "idle",
faceBlurPreview: null,
labels: {
resize: "Resize",
faceMlFailedShort: "Face failed",
detectingFacesShort: "Detecting",
@@ -31,19 +31,19 @@ describe("EditorMobileSection", () => {
quick: "Quick",
face: "Face",
decor: "Decor",
}}
onOpenCanvasSize={() => undefined}
onImportImage={() => undefined}
onSelectLayer={() => undefined}
onMoveLayer={() => undefined}
onMoveLayerEnd={() => undefined}
onResizeLayer={() => undefined}
onResizeLayerEnd={() => undefined}
onRotateLayer={() => undefined}
onRotateLayerEnd={() => undefined}
onInteractionStart={() => undefined}
onInteractionEnd={() => undefined}
/>,
},
onOpenCanvasSize: () => undefined,
onImportImage: () => undefined,
onSelectLayer: () => undefined,
onMoveLayer: () => undefined,
onMoveLayerEnd: () => undefined,
onResizeLayer: () => undefined,
onResizeLayerEnd: () => undefined,
onRotateLayer: () => undefined,
onRotateLayerEnd: () => undefined,
onInteractionStart: () => undefined,
onInteractionEnd: () => undefined,
}),
);
expect(screen.getByText("Faces 1")).toBeInTheDocument();
@@ -110,7 +110,7 @@ export function EditorMobileSection(props: EditorMobileSectionProps) {
faceBlurPreview={faceBlurPreview}
/>
</div>
{tool === "face" ? (
{tool === "face" && (
<p className={`mt-2 text-[11px] ${isDark ? "text-[#9aa1ad]" : "text-[#6b7280]"}`}>
{faceStatus === "unsupported"
? labels.faceMlFailedShort
@@ -118,7 +118,7 @@ export function EditorMobileSection(props: EditorMobileSectionProps) {
? labels.detectingFacesShort
: labels.faceDetectionTip(faceDetections.length)}
</p>
) : null}
)}
</div>
<div className={`mt-3 rounded-2xl border p-3 ${isDark ? "border-white/10 bg-[#2a2c31]" : "border-black/10 bg-white"}`}>