Files
frontend/apps/sn/tests/dredging-registration.test.cjs
T
2026-09-15 10:00:42 +09:00

164 lines
5.0 KiB
JavaScript

const assert = require("node:assert/strict");
const { test } = require("node:test");
const { loadTypeScript } = require("./load-typescript.cjs");
const base = "app/(with-base-layout)/oper/dredging/lib/";
const { createDredgingRegistrationSession } = loadTypeScript(
`${base}registration-request.ts`,
);
/** 실제 wire 필드 외에 화면 전용 ID·관경·거리까지 포함해 구분을 검증한다. */
const fixture = () => [
{
localId: "ui-group",
registrationMode: "PHOTO",
dredgingDate: "2026-09-01",
locationSource: "EXIF",
location: { longitude: 127.1, latitude: 37.1 },
pipe: {
fid: "F-1",
mngInstCd: "4173000",
fcltMngNo: "P-1",
pipeDiameterMm: 600,
distanceMeters: 1,
},
photos: [
{
key: "photo-1",
file: { name: "관로.jpg" },
metadata: {
capturedAt: "2026-09-01T09:10:00",
location: { longitude: 127.1, latitude: 37.1 },
},
},
],
},
];
const attachments = () => new Map([["photo-1", { atflCd: "A", atflId: "B" }]]);
test("HTTP 응답 유실 후 재시도는 동일 payload와 clientRequestId를 전송", async () => {
let issued = 0;
const session = createDredgingRegistrationSession(
() => `request-${++issued}`,
);
const requests = [];
const client = loadTypeScript(`${base}client.ts`, {
"@/components/lib/api": {
postRawJson: async (url, body) => {
requests.push({ url, body });
if (requests.length === 1) throw new TypeError("network lost");
return { alreadyRegisteredCount: 1 };
},
},
"@/components/lib/utils": {},
"@/shared/lib/fetch-all-pages": {},
});
await assert.rejects(
client.saveDredgingRegistrations(session.prepare(fixture(), attachments())),
);
await client.saveDredgingRegistrations(
session.prepare(fixture(), attachments()),
);
assert.equal(issued, 1);
assert.deepEqual(requests[0], requests[1]);
assert.equal(requests[0].url, "v1/dredging/registrations");
assert.deepEqual(requests[0].body.groups[0].photos[0], {
atflCd: "A",
atflId: "B",
originalFileName: "관로.jpg",
clientCapturedAt: "2026-09-01T09:10:00",
clientLongitude: 127.1,
clientLatitude: 37.1,
});
});
test("날짜·위치·관로·사진 변경은 새 ID, 원래 입력 복원은 기존 ID", () => {
let issued = 0;
const session = createDredgingRegistrationSession(
() => `request-${++issued}`,
);
const first = session.prepare(fixture(), attachments()).clientRequestId;
const edits = [
(group) => {
group.dredgingDate = "2026-09-02";
},
(group) => {
group.location.latitude = 37.2;
},
(group) => {
group.pipe.fid = "F-2";
},
(group) => {
group.photos[0].metadata.capturedAt = "2026-09-01T10:00:00";
},
];
for (const edit of edits) {
const groups = fixture();
edit(groups[0]);
assert.notEqual(
session.prepare(groups, attachments()).clientRequestId,
first,
);
}
const changedAttachments = attachments();
changedAttachments.set("photo-1", { atflCd: "C", atflId: "D" });
assert.notEqual(
session.prepare(fixture(), changedAttachments).clientRequestId,
first,
);
assert.equal(
session.prepare(fixture(), attachments()).clientRequestId,
first,
);
});
test("화면 전용 그룹 ID·관경·거리 변화는 중복방지 키를 바꾸지 않는다", () => {
let issued = 0;
const session = createDredgingRegistrationSession(
() => `request-${++issued}`,
);
const first = session.prepare(fixture(), attachments());
const groups = fixture();
groups[0].localId = "new-ui";
groups[0].pipe.pipeDiameterMm = 900;
groups[0].pipe.distanceMeters = 3;
assert.deepEqual(session.prepare(groups, attachments()), first);
});
test("새 등록 세션은 같은 입력이라도 새 UUID를 발급", () => {
const first = createDredgingRegistrationSession().prepare(
fixture(),
attachments(),
).clientRequestId;
const second = createDredgingRegistrationSession().prepare(
fixture(),
attachments(),
).clientRequestId;
assert.notEqual(first, second);
assert.match(
first,
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
);
});
test("첨부 객체의 속성 순서가 달라도 같은 등록 ID를 재사용", () => {
let issued = 0;
const session = createDredgingRegistrationSession(() => `request-${++issued}`);
const first = session.prepare(fixture(), attachments());
const reordered = new Map([["photo-1", { atflId: "B", atflCd: "A" }]]);
assert.deepEqual(session.prepare(fixture(), reordered), first);
assert.equal(issued, 1);
});
test("실제 저장의 누락 첨부는 키 발급 전 거부하며 선행 모의 모드는 허용", () => {
let issued = 0;
const session = createDredgingRegistrationSession(
() => `request-${++issued}`,
);
assert.throws(() => session.prepare(fixture(), new Map()), /첨부 식별자/);
assert.equal(issued, 0);
assert.equal(
session.prepare(fixture(), new Map(), false).clientRequestId,
"request-1",
);
});