1차 싱크 완료
CI / test (push) Failing after 41m13s
CI / pr_and_merge (push) Has been skipped

This commit is contained in:
2025-11-24 21:32:37 +09:00
parent 7a8ad7c057
commit 672cca5271
83 changed files with 6681 additions and 325 deletions
+1146 -171
View File
File diff suppressed because it is too large Load Diff
+153
View File
@@ -128,6 +128,7 @@ describe("/api/forms/submit", () => {
expect(res.status).toBe(200);
const json = (await res.json()) as any;
expect(json.ok).toBe(true);
expect(json.message).toBe(config.successMessage);
expect(fetchMock).toHaveBeenCalledTimes(1);
const [url, options] = fetchMock.mock.calls[0] as unknown as [string, RequestInit];
@@ -144,4 +145,156 @@ describe("/api/forms/submit", () => {
expect(parsed.source).toBe("builder");
expect(parsed.formId).toBe("contact-json");
});
it("webhook 모드 성공 시에도 successMessage 가 응답 message 필드에 포함되어야 한다", async () => {
const destinationUrl = `${BASE_URL}/webhook-success-message`;
const config: FormBlockProps = {
kind: "contact",
submitTarget: "webhook",
destinationUrl,
method: "POST",
headers: { Authorization: "Bearer success-token" },
extraParams: { source: "builder" },
successMessage: "웹훅으로 전송되었습니다.",
errorMessage: "웹훅 전송 실패",
fieldIds: [],
submitButtonId: null,
};
const fetchMock = vi.fn(async () => new Response("ok", { status: 200 }));
// @ts-expect-error - 글로벌 fetch 재정의
global.fetch = fetchMock;
const formData = new FormData();
formData.append("email_address", "success-webhook@example.com");
formData.append("__config", JSON.stringify(config));
const { POST: handleSubmit } = await import("@/app/api/forms/submit/route");
const res = await handleSubmit(
new Request(`${BASE_URL}/api/forms/submit`, {
method: "POST",
body: formData,
}),
);
expect(res.status).toBe(200);
const json = (await res.json()) as any;
expect(json.ok).toBe(true);
expect(json.message).toBe(config.successMessage);
});
it("webhook 모드에서 destinationUrl 이 없으면 400 과 destinationUrl_missing 및 errorMessage 가 포함되어야 한다", async () => {
const config: FormBlockProps = {
kind: "contact",
submitTarget: "webhook",
// destinationUrl 누락
successMessage: "성공 메시지",
errorMessage: "Webhook URL 이 설정되지 않았습니다.",
fieldIds: [],
submitButtonId: null,
} as any;
const formData = new FormData();
formData.append("email_address", "missing-destination@example.com");
formData.append("__config", JSON.stringify(config));
const { POST: handleSubmit } = await import("@/app/api/forms/submit/route");
const res = await handleSubmit(
new Request(`${BASE_URL}/api/forms/submit`, {
method: "POST",
body: formData,
}),
);
expect(res.status).toBe(400);
const json = (await res.json()) as any;
expect(json.ok).toBe(false);
expect(json.error).toBe("destinationUrl_missing");
expect(json.message).toBe(config.errorMessage);
});
it("webhook 모드에서 원격 응답이 실패하면 502 와 webhook_failed, errorMessage 가 포함되어야 한다", async () => {
const destinationUrl = `${BASE_URL}/webhook-fail`;
const config: FormBlockProps = {
kind: "contact",
submitTarget: "webhook",
destinationUrl,
method: "POST",
headers: {},
extraParams: {},
successMessage: "성공 메시지",
errorMessage: "웹훅 호출이 실패했습니다.",
fieldIds: [],
submitButtonId: null,
};
const fetchMock = vi.fn(async () => new Response("remote error", { status: 503 }));
// @ts-expect-error - 글로벌 fetch 재정의
global.fetch = fetchMock;
const formData = new FormData();
formData.append("email_address", "fail-remote@example.com");
formData.append("__config", JSON.stringify(config));
const { POST: handleSubmit } = await import("@/app/api/forms/submit/route");
const res = await handleSubmit(
new Request(`${BASE_URL}/api/forms/submit`, {
method: "POST",
body: formData,
}),
);
expect(res.status).toBe(502);
const json = (await res.json()) as any;
expect(json.ok).toBe(false);
expect(json.error).toBe("webhook_failed");
expect(json.message).toBe(config.errorMessage);
});
it("webhook 모드에서 fetch 예외가 발생하면 500 과 webhook_exception, errorMessage 가 포함되어야 한다", async () => {
const destinationUrl = `${BASE_URL}/webhook-exception`;
const config: FormBlockProps = {
kind: "contact",
submitTarget: "webhook",
destinationUrl,
method: "POST",
headers: {},
extraParams: {},
successMessage: "성공 메시지",
errorMessage: "웹훅 호출 중 예외가 발생했습니다.",
fieldIds: [],
submitButtonId: null,
};
const fetchMock = vi.fn(async () => {
throw new Error("network error");
});
// @ts-expect-error - 글로벌 fetch 재정의
global.fetch = fetchMock;
const formData = new FormData();
formData.append("email_address", "exception@example.com");
formData.append("__config", JSON.stringify(config));
const { POST: handleSubmit } = await import("@/app/api/forms/submit/route");
const res = await handleSubmit(
new Request(`${BASE_URL}/api/forms/submit`, {
method: "POST",
body: formData,
}),
);
expect(res.status).toBe(500);
const json = (await res.json()) as any;
expect(json.ok).toBe(false);
expect(json.error).toBe("webhook_exception");
expect(json.message).toBe(config.errorMessage);
});
});