Files
MBN_STOCK_WEBVIEW/tests/Web/named-krx-theme-restore-app-integration.test.cjs

84 lines
4.6 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");
const index = fs.readFileSync(path.join(root, "Web", "index.html"), "utf8");
const native = fs.readFileSync(path.join(root, "MainWindow.NamedKrxThemeRestore.cs"), "utf8");
const namedBridge = fs.readFileSync(path.join(root, "MainWindow.NamedPlaylists.cs"), "utf8");
function functionBody(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);
}
test("named KRX restore is correlated from one native load through page preflight", () => {
assert.match(index,
/src="named-krx-theme-restore-workflow\.js"[\s\S]*src="named-nxt-theme-restore-workflow\.js"/u);
assert.match(namedBridge,
/await PostNamedKrxThemeRestoreAsync\([\s\S]*await PostNamedNxtThemeRestoreAsync\(/u);
assert.match(native, /PostMessage\("named-krx-theme-restore-results"/u);
assert.match(app, /krxThemeRestorePending/u);
assert.match(app, /case "named-krx-theme-restore-results"/u);
assert.match(app, /case "named-krx-theme-restore-error"/u);
const finalize = functionBody("finalizeNamedManualRestores", "handleNamedManualListResults");
assert.match(finalize, /state\.namedPlaylist\.krxThemeRestorePending/u);
assert.match(finalize, /prepareNamedPagePreflight/u);
});
test("generic theme restore cannot trust a historical KRX code before native verification", () => {
const addTheme = functionBody("addThemeNamedCandidates", "addOverseasNamedCandidates");
assert.match(addTheme,
/rawRow\.groupCode === "테마" \|\| rawRow\.groupCode === "테마_NXT"/u);
const load = functionBody("handleNamedPlaylistLoadResults", "failNamedComparisonRestore");
assert.match(load, /namedKrxThemeRestoreWorkflow\.classify/u);
assert.match(load, /pendingKrxThemes\.length === 0/u);
assert.match(load, /krxThemeRestorePending = pendingKrxThemes\.length/u);
const resolve = functionBody("resolveNamedPlaylistRawRow", "prepareNamedPagePreflight");
assert.match(resolve,
/rawRow\?\.groupCode === "테마" \|\| rawRow\?\.groupCode === "테마_NXT"[\s\S]*return null/u);
});
test("current KRX identity stays branded in memory and old code is retained only for save", () => {
const materialize = functionBody("materializeNamedRestoration", "namedPlaylistPrepareBlockers");
assert.match(materialize,
/namedKrxThemeRestoreWorkflow\.isMaterializedEntry\(row\.entry\)/u);
const synchronize = functionBody("synchronizeThemeEntries", "clearOverseasTimeout");
assert.match(synchronize,
/namedKrxThemeRestoreWorkflow\.isMaterializedEntry\(item\)[\s\S]*\? item/u);
const fields = functionBody("namedLegacyFieldsForEntry", "isTrustedNamedPlaylistEntry");
assert.match(fields, /namedKrxThemeRestoreWorkflow\.legacySelectionForEntry\(entry\)/u);
assert.match(fields, /namedKrxThemeRestoreWorkflow\.matchesRaw\(entry, rawRow\)/u);
assert.match(fields, /KRX 테마의 과거 code와 현재 송출 code/u);
});
test("KRX failures are terminal and never trigger an automatic retry or playout", () => {
const failed = functionBody("failNamedKrxThemeRestore", "handleNamedKrxThemeRestoreResults");
assert.match(failed, /krxThemeRestorePending = null/u);
assert.doesNotMatch(app, /retryNamedKrxTheme|requestNamedKrxThemeRestore/u);
assert.doesNotMatch(native, /IPlayoutEngine|PrepareAsync|TakeInAsync|NextAsync|TakeOutAsync/u);
assert.match(native, /retryable = false/u);
});
test("KRX success accounting and post-load cancellation close every correlated busy record", () => {
const results = functionBody("handleNamedKrxThemeRestoreResults", "handleNamedKrxThemeRestoreError");
assert.match(results,
/state\.playlist\[pending\.itemIndex\] = entry;\s*restoredCount \+= 1;/u);
const clear = functionBody("clearNamedPlaylistLoadState", "saveNamedPlaylistBackup");
assert.match(clear, /krxThemeRestorePending = null/u);
const busy = functionBody("namedPlaylistBusy", "renderNamedPlaylist");
assert.match(busy, /state\.namedPlaylist\.krxThemeRestorePending/u);
const loadError = functionBody("handleNamedPlaylistError", "normalizePlayoutState");
assert.match(loadError, /error\.operation !== "load"/u);
assert.match(loadError,
/state\.namedPlaylist\.krxThemeRestorePending\?\.requestId === error\.requestId[\s\S]*krxThemeRestorePending = null/u);
assert.match(loadError, /복원 배치는 자동 재시도하지 않습니다/u);
});