feat: restore legacy named playlist workflows
This commit is contained in:
122
tests/Web/playlist-enabled-toggle-app-integration.test.cjs
Normal file
122
tests/Web/playlist-enabled-toggle-app-integration.test.cjs
Normal file
@@ -0,0 +1,122 @@
|
||||
"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);
|
||||
});
|
||||
Reference in New Issue
Block a user