CI빌드 오류 수정
CI / test (push) Successful in 4m48s
CI / e2e (push) Has been skipped
CI / pr_and_merge (push) Successful in 1m13s

This commit is contained in:
2025-12-07 10:12:38 +09:00
parent a5b432fb7b
commit 4902a0b5a9
5 changed files with 22 additions and 15 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
/// <reference types="next" /> /// <reference types="next" />
/// <reference types="next/image-types/global" /> /// <reference types="next/image-types/global" />
import "./.next/dev/types/routes.d.ts"; import "./.next/types/routes.d.ts";
// NOTE: This file should not be edited // NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
+7 -1
View File
@@ -112,11 +112,17 @@ export async function POST(request: Request) {
// 퍼블릭 슬러그 페이지(/p/[slug])가 DB 조회 없이도 최신 스냅샷을 바로 렌더링할 수 있도록 // 퍼블릭 슬러그 페이지(/p/[slug])가 DB 조회 없이도 최신 스냅샷을 바로 렌더링할 수 있도록
// 메모리 기반 캐시에 프로젝트 스냅샷을 저장해 둔다. // 메모리 기반 캐시에 프로젝트 스냅샷을 저장해 둔다.
const rawContent = project.contentJson;
let contentBlocks: Block[] = [];
if (Array.isArray(rawContent)) {
contentBlocks = rawContent as unknown as Block[];
}
try { try {
cachePublicProject({ cachePublicProject({
slug: project.slug, slug: project.slug,
title: project.title, title: project.title,
contentJson: (project.contentJson ?? []) as Block[], contentJson: contentBlocks,
}); });
} catch { } catch {
// 캐시 저장 실패는 퍼블릭 렌더링에만 영향을 주므로, API 응답 자체는 정상적으로 계속 진행한다. // 캐시 저장 실패는 퍼블릭 렌더링에만 영향을 주므로, API 응답 자체는 정상적으로 계속 진행한다.
+6 -1
View File
@@ -50,7 +50,12 @@ export default async function PublicProjectPage({ params }: PageParams) {
notFound(); notFound();
} }
blocks = (project.contentJson ?? []) as Block[]; const rawContent = project.contentJson;
let contentBlocks: Block[] = [];
if (Array.isArray(rawContent)) {
contentBlocks = rawContent as unknown as Block[];
}
blocks = contentBlocks;
title = project.title; title = project.title;
} }
+7 -12
View File
@@ -98,8 +98,7 @@ describe("/api/forms/submit", () => {
// fetch 를 목킹하여 payload 와 헤더가 기대대로 전달되는지 검증한다. // fetch 를 목킹하여 payload 와 헤더가 기대대로 전달되는지 검증한다.
const fetchMock = vi.fn(async () => new Response("ok", { status: 200 })); const fetchMock = vi.fn(async () => new Response("ok", { status: 200 }));
// @ts-expect-error - 글로벌 fetch 재정의 (globalThis as any).fetch = fetchMock;
global.fetch = fetchMock;
const formData = new FormData(); const formData = new FormData();
formData.append("email_address", "test@example.com"); formData.append("email_address", "test@example.com");
@@ -119,7 +118,7 @@ describe("/api/forms/submit", () => {
expect(json.ok).toBe(true); expect(json.ok).toBe(true);
expect(fetchMock).toHaveBeenCalledTimes(1); expect(fetchMock).toHaveBeenCalledTimes(1);
const [url, options] = fetchMock.mock.calls[0] as [string, RequestInit]; const [url, options] = fetchMock.mock.calls[0] as unknown as [string, RequestInit];
expect(url).toBe(destinationUrl); expect(url).toBe(destinationUrl);
expect(options.method).toBe("POST"); expect(options.method).toBe("POST");
expect(options.headers).toMatchObject({ expect(options.headers).toMatchObject({
@@ -152,8 +151,7 @@ describe("/api/forms/submit", () => {
}; };
const fetchMock = vi.fn(async () => new Response("ok", { status: 200 })); const fetchMock = vi.fn(async () => new Response("ok", { status: 200 }));
// @ts-expect-error - 글로벌 fetch 재정의 (globalThis as any).fetch = fetchMock;
global.fetch = fetchMock;
const formData = new FormData(); const formData = new FormData();
formData.append("email_address", "json@example.com"); formData.append("email_address", "json@example.com");
@@ -206,8 +204,7 @@ describe("/api/forms/submit", () => {
}; };
const fetchMock = vi.fn(async () => new Response("ok", { status: 200 })); const fetchMock = vi.fn(async () => new Response("ok", { status: 200 }));
// @ts-expect-error - 글로벌 fetch 재정의 (globalThis as any).fetch = fetchMock;
global.fetch = fetchMock;
const formData = new FormData(); const formData = new FormData();
formData.append("email_address", "success-webhook@example.com"); formData.append("email_address", "success-webhook@example.com");
@@ -266,7 +263,7 @@ describe("/api/forms/submit", () => {
expect(json.message).toBe(config.successMessage); expect(json.message).toBe(config.successMessage);
expect(fetchMock).toHaveBeenCalledTimes(1); expect(fetchMock).toHaveBeenCalledTimes(1);
const [url, options] = fetchMock.mock.calls[0] as [string, RequestInit]; const [url, options] = fetchMock.mock.calls[0] as unknown as [string, RequestInit];
expect(url).toBe(destinationUrl); expect(url).toBe(destinationUrl);
expect(options.method).toBe("POST"); expect(options.method).toBe("POST");
}); });
@@ -319,8 +316,7 @@ describe("/api/forms/submit", () => {
}; };
const fetchMock = vi.fn(async () => new Response("remote error", { status: 503 })); const fetchMock = vi.fn(async () => new Response("remote error", { status: 503 }));
// @ts-expect-error - 글로벌 fetch 재정의 (globalThis as any).fetch = fetchMock;
global.fetch = fetchMock;
const formData = new FormData(); const formData = new FormData();
formData.append("email_address", "fail-remote@example.com"); formData.append("email_address", "fail-remote@example.com");
@@ -361,8 +357,7 @@ describe("/api/forms/submit", () => {
const fetchMock = vi.fn(async () => { const fetchMock = vi.fn(async () => {
throw new Error("network error"); throw new Error("network error");
}); });
// @ts-expect-error - 글로벌 fetch 재정의 (globalThis as any).fetch = fetchMock;
global.fetch = fetchMock;
const formData = new FormData(); const formData = new FormData();
formData.append("email_address", "exception@example.com"); formData.append("email_address", "exception@example.com");
File diff suppressed because one or more lines are too long