mmday-firebase/tests/types/iso.test.ts
윤정민 107f75c23a Serialize API dates as UTC ISO strings via response DTOs
- Firestore Timestamp가 res.json으로 그대로 나가 {_seconds,_nanoseconds}로 직렬화되던 문제 수정
- 앱의 포인트 내역(/reward/ledger)과 예측 기록(/stats/history) 크래시 원인 제거
- 클라 소비 7개 핸들러(reward/attendance/prediction/user/stats/kbo/chat)의 모든 응답에 명시적 DTO 타입 도입
- 날짜 와이어 형식을 순수 UTC ISO 8601(...Z)로 통일 — 채팅의 기존 KST(+09:00) 출력도 UTC로 전환
- DTO는 필드를 명시적으로 나열해 조립 (스프레드 덤프 제거) — 문서에 새 Timestamp 필드가 생겨도 다시 새지 않는다
- 재사용되는 주문 형태만 toOrderDto로 분리, 나머지는 응답 경계에서 직접 조립
- Firestore 저장 형식은 변경하지 않음. 출석 idempotent 재요청 경로는 저장된 Timestamp/문자열을 모두 처리
- DTO 직렬화 회귀 테스트 추가 (_seconds 부재, UTC ISO 형식, optional 키 생략, 미지 필드 차단)
2026-07-20 16:28:45 +09:00

38 lines
1.4 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { Timestamp } from "firebase-admin/firestore";
import { toIso, toIsoOrUndefined } from "../../src/types/dto/iso";
const UTC_ISO = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
describe("toIso", () => {
it("Timestamp 를 UTC ISO 문자열로 바꾼다", () => {
const ts = Timestamp.fromDate(new Date("2026-07-20T05:30:00.000Z"));
expect(toIso(ts)).toBe("2026-07-20T05:30:00.000Z");
});
it("항상 Z 로 끝나는 UTC 형식을 낸다 (KST 오프셋 없음)", () => {
const ts = Timestamp.fromDate(new Date("2026-07-20T14:30:00+09:00"));
const iso = toIso(ts);
expect(iso).toMatch(UTC_ISO);
expect(iso).not.toContain("+09:00");
expect(iso).toBe("2026-07-20T05:30:00.000Z");
});
});
describe("toIsoOrUndefined", () => {
it("값이 있으면 toIso 와 같은 결과를 낸다", () => {
const ts = Timestamp.fromDate(new Date("2026-01-02T03:04:05.678Z"));
expect(toIsoOrUndefined(ts)).toBe("2026-01-02T03:04:05.678Z");
});
it("undefined / null 이면 undefined 를 낸다", () => {
expect(toIsoOrUndefined(undefined)).toBeUndefined();
expect(toIsoOrUndefined(null)).toBeUndefined();
});
it("undefined 필드는 JSON 직렬화에서 키가 사라진다", () => {
const dto = { at: toIsoOrUndefined(undefined) };
expect(JSON.parse(JSON.stringify(dto))).toEqual({});
});
});