Complete legacy operator UI and playout migration
This commit is contained in:
149
tests/Web/named-manual-restore-workflow.test.cjs
Normal file
149
tests/Web/named-manual-restore-workflow.test.cjs
Normal file
@@ -0,0 +1,149 @@
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
|
||||
const workflow = require("../../Web/named-manual-restore-workflow.js");
|
||||
const manualLists = require("../../Web/manual-lists-workflow.js");
|
||||
const manualFinancial = require("../../Web/manual-financial-workflow.js");
|
||||
|
||||
function raw(overrides = {}) {
|
||||
return {
|
||||
itemIndex: 0,
|
||||
enabled: true,
|
||||
groupCode: "INDIVIDUAL",
|
||||
subject: "INDEX",
|
||||
graphicType: "MANUAL_NET_SELL",
|
||||
subtype: "MANUAL_NET_SELL",
|
||||
dataCode: "",
|
||||
...overrides
|
||||
};
|
||||
}
|
||||
|
||||
const options = { id: "db-invalid-00000001-0", fadeDuration: 6 };
|
||||
const rows = Array.from({ length: 5 }, (_, index) => ({
|
||||
leftName: `L${index}`, leftAmount: `${index}`,
|
||||
rightName: `R${index}`, rightAmount: `${index + 10}`
|
||||
}));
|
||||
|
||||
test("s5025 raw restoration accepts only canonical or exact legacy audience signatures", () => {
|
||||
const canonical = workflow.classify(raw(), options);
|
||||
assert.equal(canonical.kind, "net-sell");
|
||||
assert.equal(canonical.audience, "INDIVIDUAL");
|
||||
|
||||
const legacy = workflow.classify(raw({
|
||||
groupCode: "외국인 순매도 상위(수동)",
|
||||
subject: "",
|
||||
graphicType: "순매도 상위",
|
||||
subtype: "순매도 상위"
|
||||
}), options);
|
||||
assert.equal(legacy.audience, "FOREIGN");
|
||||
assert.equal(legacy.historical, true);
|
||||
assert.equal(workflow.classify(raw({
|
||||
groupCode: "외국인 순매도 상위",
|
||||
subject: "",
|
||||
graphicType: "순매도 상위",
|
||||
subtype: "순매도 상위"
|
||||
}), options), null);
|
||||
assert.equal(workflow.classify(raw({ dataCode: "path.dat" }), options), null);
|
||||
});
|
||||
|
||||
test("s5025 becomes playable only after one correlated trusted five-row read", () => {
|
||||
const pending = workflow.classify(raw({ enabled: false }), options);
|
||||
const request = workflow.createManualListReadRequest("named-net-read", pending);
|
||||
const entry = workflow.materializeManualList(pending, {
|
||||
requestId: "named-net-read",
|
||||
audience: "INDIVIDUAL",
|
||||
rows
|
||||
}, request);
|
||||
assert.ok(entry);
|
||||
assert.equal(entry.enabled, false);
|
||||
assert.equal(entry.builderKey, "s5025");
|
||||
assert.equal(manualLists.restorePlaylistEntry(entry).operator.audience, "INDIVIDUAL");
|
||||
assert.equal(workflow.materializeManualList(pending, {
|
||||
requestId: "stale-read",
|
||||
audience: "INDIVIDUAL",
|
||||
rows
|
||||
}, request), null);
|
||||
});
|
||||
|
||||
test("versioned and historical VI raw rows require the current exact native snapshot", () => {
|
||||
const version = "a".repeat(64);
|
||||
const current = workflow.classify(raw({
|
||||
groupCode: "PAGED_VI",
|
||||
subject: manualLists.viSnapshotSubject,
|
||||
graphicType: "INPUT_ORDER",
|
||||
subtype: "CURRENT",
|
||||
dataCode: version
|
||||
}), options);
|
||||
const request = workflow.createManualListReadRequest("named-vi-read", current);
|
||||
const payload = {
|
||||
requestId: "named-vi-read",
|
||||
itemCount: 2,
|
||||
pageCount: 1,
|
||||
items: [{ code: "005930", name: "삼성전자" }, { code: "000660", name: "SK하이닉스" }],
|
||||
version
|
||||
};
|
||||
assert.equal(workflow.materializeManualList(current, payload, request).builderKey, "s5074");
|
||||
assert.equal(workflow.materializeManualList(current, { ...payload, version: "b".repeat(64) }, request), null);
|
||||
|
||||
const historical = workflow.classify(raw({
|
||||
groupCode: "",
|
||||
subject: "삼성전자,SK하이닉스",
|
||||
graphicType: "5단 표그래프",
|
||||
subtype: "VI 발동(수동)",
|
||||
dataCode: ""
|
||||
}), options);
|
||||
const historicalRequest = workflow.createManualListReadRequest("named-vi-history", historical);
|
||||
assert.ok(workflow.materializeManualList(historical, {
|
||||
...payload,
|
||||
requestId: "named-vi-history"
|
||||
}, historicalRequest));
|
||||
assert.equal(workflow.materializeManualList(historical, {
|
||||
...payload,
|
||||
requestId: "named-vi-history",
|
||||
items: [...payload.items].reverse()
|
||||
}, historicalRequest), null);
|
||||
assert.equal(workflow.classify(raw({
|
||||
groupCode: "",
|
||||
subject: "삼성전자,삼성전자",
|
||||
graphicType: "5단 표그래프",
|
||||
subtype: "VI 발동(수동)"
|
||||
}), options), null);
|
||||
assert.equal(workflow.classify(raw({
|
||||
groupCode: "",
|
||||
subject: "삼성전자, SK하이닉스",
|
||||
graphicType: "5단 표그래프",
|
||||
subtype: "VI 발동(수동)"
|
||||
}), options), null);
|
||||
});
|
||||
|
||||
test("GraphE raw rows yield only a fresh-load descriptor with exact screen, market and name", () => {
|
||||
for (const profile of manualFinancial.sourceContract.screens) {
|
||||
const pending = workflow.classify(raw({
|
||||
groupCode: "코스피",
|
||||
subject: "삼성전자",
|
||||
graphicType: profile.label,
|
||||
subtype: "",
|
||||
dataCode: ""
|
||||
}), options);
|
||||
assert.equal(pending.kind, "financial");
|
||||
assert.equal(pending.screen, profile.screen);
|
||||
assert.equal(pending.builderKey, profile.builderKey);
|
||||
assert.equal(pending.market, "kospi");
|
||||
assert.deepEqual(pending.identity, { screen: profile.screen, stockName: "삼성전자" });
|
||||
}
|
||||
const profile = manualFinancial.sourceContract.screens[0];
|
||||
assert.equal(workflow.classify(raw({
|
||||
groupCode: "UNKNOWN",
|
||||
subject: "삼성전자",
|
||||
graphicType: profile.graphicType,
|
||||
subtype: "",
|
||||
dataCode: ""
|
||||
}), options), null);
|
||||
assert.equal(workflow.classify(raw({
|
||||
groupCode: "KOSPI",
|
||||
subject: "삼성전자",
|
||||
graphicType: profile.graphicType,
|
||||
subtype: "",
|
||||
dataCode: "005930"
|
||||
}), options), null);
|
||||
});
|
||||
Reference in New Issue
Block a user