Files
MBN_STOCK_WEBVIEW/tests/Web/playlist-enabled-toggle-app-integration.test.cjs

123 lines
4.4 KiB
JavaScript

"use strict";
const test = require("node:test");
const assert = require("node:assert/strict");
const fs = require("node:fs");
const path = require("node:path");
const root = path.resolve(__dirname, "..", "..");
const app = fs.readFileSync(path.join(root, "Web", "app.js"), "utf8");
function functionSource(name, nextName) {
const start = app.indexOf(`function ${name}(`);
const end = app.indexOf(`function ${nextName}(`, start + 1);
assert.ok(start >= 0 && end > start, `${name} must precede ${nextName}`);
return app.slice(start, end).trim();
}
function recreateWith(stubs) {
const source = functionSource(
"recreatePlaylistEntryWithEnabled",
"playlistEntryManualEditBlockReason");
return new Function(
"namedKrxThemeRestoreWorkflow",
"namedNxtThemeRestoreWorkflow",
"namedForeignStockRestoreWorkflow",
"foreignIndexCandleRestoreWorkflow",
"manualFinancialWorkflow",
"manualListsWorkflow",
`return (${source});`)(
stubs.krx,
stubs.nxt,
stubs.foreignStock,
stubs.foreignIndex,
stubs.manualFinancial,
stubs.manualLists);
}
function stubSet() {
const recreate = label => (entry, enabled) => entry.trusted === label
? Object.freeze({ ...entry, enabled, retainedBrand: label })
: null;
return {
krx: {
isMaterializedEntry: entry => entry.trusted === "krx",
withEnabled: recreate("krx")
},
nxt: {
isMaterializedEntry: entry => entry.trusted === "nxt",
withEnabled: recreate("nxt")
},
foreignStock: {
source: "legacy-named-foreign-stock-workflow",
withEnabled: recreate("foreign-stock")
},
foreignIndex: { withEnabled: recreate("foreign-index") },
manualFinancial: { withEnabled: recreate("manual-financial") },
manualLists: { withEnabled: recreate("manual-lists") }
};
}
test("a frozen ordinary entry toggles through an immutable replacement", () => {
const recreate = recreateWith(stubSet());
const entry = Object.freeze({
id: "ordinary",
code: "5001",
enabled: true,
operator: Object.freeze({ source: "legacy-stock-workflow" })
});
const replacement = recreate(entry, false);
assert.notEqual(replacement, entry);
assert.equal(entry.enabled, true);
assert.equal(replacement.enabled, false);
assert.equal(replacement.id, entry.id);
});
test("every capability-branded entry delegates to its trust-preserving workflow", () => {
const recreate = recreateWith(stubSet());
const cases = [
["krx", { source: "legacy-theme-workflow", namedKrxRestore: {} }],
["nxt", { source: "legacy-theme-workflow", namedNxtRestore: {} }],
["foreign-stock", { source: "legacy-named-foreign-stock-workflow" }],
["foreign-index", { source: "legacy-foreign-index-candle-workflow" }],
["manual-financial", { source: "manual-financial-workflow" }],
["manual-lists", { source: "legacy-manual-lists-workflow" }]
];
for (const [trusted, operator] of cases) {
const entry = Object.freeze({ id: trusted, enabled: true, trusted, operator });
const replacement = recreate(entry, false);
assert.equal(replacement.retainedBrand, trusted);
assert.equal(replacement.enabled, false);
assert.equal(entry.enabled, true);
}
});
test("a proof-shaped but unbranded named entry fails closed instead of becoming a plain clone", () => {
const recreate = recreateWith(stubSet());
const forgedKrx = Object.freeze({
id: "forged-krx",
enabled: true,
operator: Object.freeze({
source: "legacy-theme-workflow",
namedKrxRestore: Object.freeze({ schemaVersion: 1 })
})
});
assert.equal(recreate(forgedKrx, false), null);
});
test("checkbox, enabled-all and current-row paths never assign into playlist entries", () => {
const render = functionSource("renderPlaylist", "selectPlaylistRow");
const all = functionSource("toggleAllEntriesEnabled", "moveSelected");
const current = functionSource("toggleCurrentEntryEnabled", "savePlaylist");
assert.match(render, /replacePlaylistEntryEnabledAt\(index, checkbox\.checked\)/u);
assert.match(render, /renderPlaylist\(\)/u);
assert.match(all, /state\.playlist\.map\(item => recreatePlaylistEntryWithEnabled/u);
assert.match(all, /replacements\.some\(item => !item\)/u);
assert.match(current,
/replacePlaylistEntryEnabledAt\(state\.currentIndex, item\.enabled === false\)/u);
assert.doesNotMatch(`${render}\n${all}\n${current}`, /item\.enabled\s*=(?!=)/u);
});