- 상품에 재고 없는 옵션(optionLabel/options — 예: 키링 색상)을 도입하고 주문 항목에 optionId/optionName 스냅샷 저장 - 주문 생성 시 옵션 검증: 옵션 상품에 미선택이면 OPTION_REQUIRED, 무옵션 상품에 optionId가 오면 INVALID_INPUT - 같은 상품의 색상별 항목을 지원하도록 상품 문서를 productId당 한 번만 읽게 정리 - 재고는 별도 플랫폼에서 관리하므로 서버 재고 개념 전면 제거(ProductDoc 재고 필드, availableStock, 주문 예약/차감, stock/adjust 엔드포인트, order/status restock) - 상세 카탈로그·주문 DTO에 옵션 노출, product/upsert가 optionLabel/options 수용 - 시드/업로드 스크립트의 재고 필드 기록 제거, vitest 계약 테스트 추가
38 lines
1.4 KiB
TypeScript
38 lines
1.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { resolveOrderOption } from "../../src/services/orderService";
|
|
import { HttpError } from "../../src/middleware/errors";
|
|
|
|
const options = [
|
|
{ id: "blue", name: "블루" },
|
|
{ id: "red", name: "레드" },
|
|
];
|
|
|
|
describe("resolveOrderOption", () => {
|
|
it("옵션 상품은 optionId 를 실제 옵션으로 해석한다", () => {
|
|
expect(resolveOrderOption({ options }, "blue")).toEqual({ id: "blue", name: "블루" });
|
|
});
|
|
|
|
it("옵션 상품에 optionId 가 없으면 OPTION_REQUIRED 로 거부한다", () => {
|
|
expect(() => resolveOrderOption({ options }, undefined)).toThrowError(
|
|
expect.objectContaining({ status: 400, code: "OPTION_REQUIRED" }) as HttpError,
|
|
);
|
|
});
|
|
|
|
it("옵션 상품에 존재하지 않는 optionId 도 OPTION_REQUIRED 로 거부한다", () => {
|
|
expect(() => resolveOrderOption({ options }, "green")).toThrowError(
|
|
expect.objectContaining({ status: 400, code: "OPTION_REQUIRED" }) as HttpError,
|
|
);
|
|
});
|
|
|
|
it("무옵션 상품은 optionId 없이 null 을 돌려준다", () => {
|
|
expect(resolveOrderOption({}, undefined)).toBeNull();
|
|
expect(resolveOrderOption({ options: [] }, undefined)).toBeNull();
|
|
});
|
|
|
|
it("무옵션 상품에 optionId 가 오면 INVALID_INPUT 으로 거부한다", () => {
|
|
expect(() => resolveOrderOption({}, "blue")).toThrowError(
|
|
expect.objectContaining({ status: 400, code: "INVALID_INPUT" }) as HttpError,
|
|
);
|
|
});
|
|
});
|