TDD,E2E 개선, 미적용 스타일 개선
CI / test (push) Failing after 2m54s
CI / e2e (push) Has been skipped
CI / pr_and_merge (push) Has been skipped

This commit is contained in:
2025-12-07 09:52:42 +09:00
parent e726f43f7c
commit a5b432fb7b
167 changed files with 7397 additions and 663 deletions
+127 -2
View File
@@ -16,14 +16,29 @@ vi.mock("@prisma/client", () => {
};
formSubmission = {
findMany: async ({ where: { projectId }, orderBy, take }: any) => {
let items = inMemoryFormSubmissions.filter((s) => s.projectId === projectId);
findMany: async (args: any = {}) => {
const where = args.where ?? {};
const orderBy = args.orderBy;
const take = args.take;
let items = [...inMemoryFormSubmissions];
if (where.projectId) {
items = items.filter((s) => s.projectId === where.projectId);
}
if (where.userId) {
items = items.filter((s) => s.userId === where.userId);
}
if (orderBy?.createdAt === "desc") {
items = items.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
}
if (typeof take === "number") {
items = items.slice(0, take);
}
return items;
},
};
@@ -169,3 +184,113 @@ describe("/api/projects/[slug]/submissions", () => {
expect(res.status).toBe(404);
});
});
describe("/api/projects/submissions", () => {
it("로그인한 사용자가 자신의 모든 프로젝트 제출 내역을 조회할 수 있어야 한다", async () => {
const project1 = {
id: "proj-1",
slug: "proj-1-slug",
userId: TEST_USER.id,
};
const project2 = {
id: "proj-2",
slug: "proj-2-slug",
userId: OTHER_USER.id,
};
inMemoryProjects.push(project1, project2);
const createdAt = new Date();
inMemoryFormSubmissions.push(
{
id: "sub-1",
projectId: project1.id,
projectSlug: project1.slug,
userId: TEST_USER.id,
createdAt,
payloadJson: { name: "홍길동" },
sensitiveEnc: undefined,
metaJson: null,
},
{
id: "sub-2",
projectId: project2.id,
projectSlug: project2.slug,
userId: OTHER_USER.id,
createdAt,
payloadJson: { name: "다른 유저" },
sensitiveEnc: undefined,
metaJson: null,
},
);
const { GET: getAllSubmissions } = await import("@/app/api/projects/submissions/route");
const headers = await buildAuthHeaders();
const res = await getAllSubmissions(
new Request(`${BASE_URL}/api/projects/submissions`, {
headers,
}),
);
expect(res.status).toBe(200);
const json = (await res.json()) as any[];
expect(Array.isArray(json)).toBe(true);
expect(json.length).toBe(1);
expect(json[0].id).toBe("sub-1");
expect(json[0].projectSlug).toBe(project1.slug);
expect(json[0].payload.name).toBe("홍길동");
});
it("민감정보는 전체 조회에서도 복호화된 값으로 payload 에 합쳐져야 한다", async () => {
const project = {
id: "proj-sensitive",
slug: "proj-sensitive",
userId: TEST_USER.id,
};
inMemoryProjects.push(project);
const { encryptJson } = await import("@/features/auth/authCrypto");
const sensitive = { email: "all@example.com", phone: "010-9999-8888" };
const sensitiveEnc = await encryptJson(sensitive);
const createdAt = new Date();
inMemoryFormSubmissions.push({
id: "sub-sensitive",
projectId: project.id,
projectSlug: project.slug,
userId: TEST_USER.id,
createdAt,
payloadJson: { name: "전체조회", message: "테스트" },
sensitiveEnc,
metaJson: null,
});
const { GET: getAllSubmissions } = await import("@/app/api/projects/submissions/route");
const headers = await buildAuthHeaders();
const res = await getAllSubmissions(
new Request(`${BASE_URL}/api/projects/submissions`, {
headers,
}),
);
expect(res.status).toBe(200);
const json = (await res.json()) as any[];
expect(json.length).toBe(1);
expect(json[0].payload.name).toBe("전체조회");
expect(json[0].payload.message).toBe("테스트");
expect(json[0].payload.email).toBe("all@example.com");
expect(json[0].payload.phone).toBe("010-9999-8888");
});
it("로그인하지 않은 경우 401 을 반환해야 한다", async () => {
const { GET: getAllSubmissions } = await import("@/app/api/projects/submissions/route");
const res = await getAllSubmissions(
new Request(`${BASE_URL}/api/projects/submissions`),
);
expect(res.status).toBe(401);
});
});