164 lines
5.0 KiB
JavaScript
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",
|
|
);
|
|
});
|