Files
frontend/apps/sn/tests/map-layer-model.test.cjs
T
2026-09-15 10:00:42 +09:00

167 lines
5.1 KiB
JavaScript

const assert = require("node:assert/strict");
const { test } = require("node:test");
const { loadTypeScript } = require("./load-typescript.cjs");
const layer = loadTypeScript("src/features/mapLayers/lib/layer-info.ts");
const { subscribeFlowDirectionMoveEnd } = loadTypeScript(
"src/features/mapLayers/lib/flow-direction-listener.ts",
);
test("레이어 camel/snake 별칭과 기존 우선순위 유지", () => {
assert.equal(
layer.getLayerTypeName({
lyrTyNm: " A ",
lyrTypeNm: "B",
lyr_type_nm: "C",
}),
"A",
);
assert.equal(
layer.getLayerTypeName({ lyr_type_nm: " tb_il_swage_prcs_fclt " }),
"tb_il_swage_prcs_fclt",
);
assert.equal(
layer.getLayerFilterSql({ filter_sql: "FCLT_CPCT >= 500" }),
"fclt_cpct>=500",
);
assert.equal(layer.getLayerTypeName(null), "");
});
test("처리시설 500 경계·동시체크·해제 모드 유지", () => {
const large = {
lyrTyNm: "tb_il_swage_prcs_fclt",
filtrSql: "FCLT_CPCT >= 500",
};
const small = { lyr_type_nm: "tb_il_swage_prcs_fclt", lyrNm: "500톤 미만" };
assert.equal(layer.getSwagePrcsFcltLayerMode([]), "none");
assert.equal(layer.getSwagePrcsFcltLayerMode([{ data: large }]), "gte500");
assert.equal(layer.getSwagePrcsFcltLayerMode([small]), "lt500");
assert.equal(layer.getSwagePrcsFcltLayerMode([large, small]), "all");
assert.equal(
layer.getSwagePrcsFcltCapacityKind({ ...large, lyrTyNm: "other" }),
null,
);
});
test("중첩 유하방향·관측소 정규화는 원본을 변경하지 않고 계약 플래그 유지", () => {
const original = [
{
lyrNm: "root",
children: [
{ lyrNm: "유하방향", minZoom: 0, clickPsblYn: "Y" },
{ lyr_type_nm: "tb_ms_rain_obsvtr_pstn_info", clickPsblYn: "Y" },
{ lyrTyNm: "other", clickPsblYn: "Y" },
],
},
];
const before = JSON.stringify(original);
const normalized = layer.normalizeRainObservationLayerInteraction(
layer.normalizeFlowDirectionLayerInfos(original),
);
const [flow, rain, other] = normalized[0].children;
assert.equal(flow.lyrTyNm, "tb_sn_swage_ppl_flow_direction");
assert.equal(flow.srvcNm, "api");
assert.equal(flow.cmncNm, "bbox");
assert.equal(flow.minViewSize, 0);
assert.equal(flow.clickPsblYn, "N");
assert.equal(rain.clickPsblYn, "N");
assert.equal(other.clickPsblYn, "Y");
assert.equal(JSON.stringify(original), before);
});
test("map/map2·줌·zIndex·BBOX 계산의 0과 빈값 구분", () => {
assert.equal(
layer.getFlowDirectionModeByPathname("/map2/"),
"PIPE_START_END",
);
assert.equal(layer.getFlowDirectionModeByPathname("/map"), "PIPE_DEPTH");
assert.equal(layer.getFiniteNumber(" "), null);
assert.equal(layer.getFiniteNumber("NaN"), null);
assert.equal(layer.getFiniteNumber(0), 0);
assert.equal(layer.getFlowDirectionMinZoom({}), 13);
assert.equal(layer.getFlowDirectionMinZoom({ minViewSize: 0 }), 0);
assert.equal(layer.getFlowDirectionZIndex({ drawOrdr: 0 }), 0);
assert.equal(layer.getFlowDirectionZIndex({}), 9998);
assert.deepEqual(
layer.expandFlowDirectionExtent([0, 10, 100, 110]),
[-35, -25, 135, 145],
);
assert.equal(
layer.formatFlowDirectionBbox([1.23456, -4, 5, 6]),
"1.235,-4.000,5.000,6.000",
);
});
test("관로 캐시 키는 같은 시설이라도 geometry가 다르면 구분", () => {
const feature = (coords) => ({
getId: () => null,
get: (name) => (name === "fclt_mng_no" ? " P-1 " : undefined),
getGeometry: () => ({ getCoordinates: () => coords }),
});
assert.equal(
layer.getFlowDirectionFeatureCacheKey(
feature([
[0, 0],
[1, 1],
]),
),
"fclt:P-1:[[0,0],[1,1]]",
);
assert.notEqual(
layer.getFlowDirectionFeatureCacheKey(
feature([
[0, 0],
[1, 1],
]),
),
layer.getFlowDirectionFeatureCacheKey(
feature([
[0, 0],
[2, 2],
]),
),
);
});
test("moveend는 최신 체크·레이어를 읽고 구독 해제·재구독 뒤 중복 호출하지 않는다", () => {
const listeners = new Map();
const map = {
on(event, handler) {
assert.equal(event, "moveend");
const key = {};
listeners.set(key, handler);
return key;
},
};
const unsubscribe = (key) => listeners.delete(key);
let state = { checked: false, layerInfo: { id: "A" } };
const calls = [];
const move = () => [...listeners.values()].forEach((handler) => handler());
const cleanup = subscribeFlowDirectionMoveEnd(
map,
() => state,
(info) => calls.push(info.id),
unsubscribe,
);
move();
state = { checked: true, layerInfo: { id: "B" } };
move();
state = { checked: true, layerInfo: null };
move();
assert.deepEqual(calls, ["B"]);
cleanup();
state = { checked: true, layerInfo: { id: "C" } };
move();
assert.deepEqual(calls, ["B"]);
const cleanupNext = subscribeFlowDirectionMoveEnd(
map,
() => state,
(info) => calls.push(info.id),
unsubscribe,
);
move();
assert.deepEqual(calls, ["B", "C"]);
assert.equal(listeners.size, 1);
cleanupNext();
assert.equal(listeners.size, 0);
});