59 lines
3.1 KiB
JavaScript
59 lines
3.1 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 bridge = fs.readFileSync(path.join(root, "MainWindow.LegacyComparisonImport.cs"), "utf8");
|
|
const host = fs.readFileSync(path.join(root, "MainWindow.xaml.cs"), "utf8");
|
|
const core = fs.readFileSync(
|
|
path.join(root, "src/MBN_STOCK_WEBVIEW.Core/Data/LegacyComparisonPairImport.cs"),
|
|
"utf8");
|
|
|
|
test("explicit one-time import is visible and persists only the normalized local schema", () => {
|
|
assert.match(index, /id="comparisonImportLegacy"/u);
|
|
assert.match(index, /<script src="comparison-import-workflow\.js"><\/script>/u);
|
|
assert.match(app, /comparisonImportMarkerStorageKey/u);
|
|
assert.match(app, /comparisonImportWorkflow\.normalizeStorageEnvelope/u);
|
|
assert.match(app, /comparisonImportWorkflow\.createStorageEnvelope/u);
|
|
assert.match(app, /comparisonImportWorkflow\.mergeImport/u);
|
|
assert.match(app, /persistComparisonLegacyImport/u);
|
|
assert.match(app, /window\.confirm\(/u);
|
|
assert.match(app, /postNative\("import-legacy-comparison-pairs", \{ requestId \}\)/u);
|
|
assert.doesNotMatch(app, /import-legacy-comparison-pairs"[^\n]*path/iu);
|
|
assert.match(app, /자동 재시도하지 않습니다/u);
|
|
});
|
|
|
|
test("native import owns the fixed path and performs only bound read validation", () => {
|
|
assert.match(core, /FixedRelativePath[\s\S]*종목비교\.dat/u);
|
|
assert.match(core, /FileMode\.Open/u);
|
|
assert.match(core, /FileAccess\.Read/u);
|
|
assert.match(core, /FileShare\.Read/u);
|
|
assert.match(core, /FileAttributes\.ReparsePoint/u);
|
|
assert.match(core, /GetFinalPathNameByHandleW/u);
|
|
assert.match(core, /GetFileInformationByHandle/u);
|
|
assert.match(core, /NumberOfLinks != 1/u);
|
|
assert.match(core, /Encoding\.GetEncoding\([\s\S]*949/u);
|
|
assert.match(core, /ExactFieldCount = 9/u);
|
|
assert.match(core, /new DataQueryParameter\("stock_name"/u);
|
|
assert.match(core, /new DataQueryParameter\("input_name"/u);
|
|
assert.doesNotMatch(core, /\b(?:INSERT\s+INTO|UPDATE\s+[A-Z_]|DELETE\s+FROM|MERGE\s+INTO)\b/iu);
|
|
assert.doesNotMatch(bridge, /Tornado|TakeIn|PrepareAsync|ExecuteNonQuery/iu);
|
|
});
|
|
|
|
test("bridge routing cancels correlation loss and never accepts a Web-provided path", () => {
|
|
assert.match(host, /TryHandleLegacyComparisonImportRequest\(request\.Type, request\.Payload\)/u);
|
|
assert.match(host, /InvalidateLegacyComparisonImportRequest\(\)/u);
|
|
assert.match(host, /ShutdownLegacyComparisonImportRuntime\(\)/u);
|
|
assert.match(host, /CancelRequest\(Volatile\.Read\(ref _legacyComparisonImportCancellation\)\)/u);
|
|
assert.match(bridge, /HasOnlyProperties\(payload, "requestId"\)/u);
|
|
assert.match(bridge, /_databaseActivityGate\.WaitAsync/u);
|
|
assert.match(bridge, /Volatile\.Read\(ref _playoutCommandInFlight\)/u);
|
|
assert.match(bridge, /Never retry or publish a stale result/u);
|
|
assert.doesNotMatch(bridge, /GetString\(payload, "path"\)/u);
|
|
});
|