"use strict"; const fs = require("node:fs"); const path = require("node:path"); const test = require("node:test"); const assert = require("node:assert/strict"); const root = path.resolve(__dirname, "..", ".."); const native = fs.readFileSync(path.join(root, "MainWindow.ManualLists.cs"), "utf8"); const playout = fs.readFileSync(path.join(root, "MainWindow.Playout.cs"), "utf8"); const factory = fs.readFileSync(path.join(root, "LegacySceneRuntimeFactory.cs"), "utf8"); test("native VI responses expose the canonical version and no-op persistence receipt", () => { assert.match(native, /ReadSnapshotAsync\(_lifetimeCancellation\.Token\)/u); assert.match(native, /version = snapshot\.RowVersion/u); assert.match(native, /persisted = result\.Persisted/u); assert.match(native, /version = result\.Snapshot\.RowVersion/u); }); test("VI writes require a closed expected version and compare it under the data gate before mutation", () => { assert.match(native, /HasOnlyProperties\(payload, "requestId", "expectedVersion", "items"\)/u); assert.match(native, /TrustedViManualReference\.IsRowVersion\(expectedVersion\)/u); const methodStart = native.indexOf("private async Task HandleViManualListWriteAsync"); const methodEnd = native.indexOf("private async Task TryEnterManualMutationGatesAsync", methodStart); const method = native.slice(methodStart, methodEnd); const gate = method.indexOf("TryEnterManualMutationGatesAsync"); const reread = method.indexOf("var currentSnapshot = await store.ReadSnapshotAsync"); const compare = method.indexOf("currentSnapshot.RowVersion"); const stale = method.indexOf('"STALE_DATA"'); const mutation = method.indexOf("var result = await store.WriteAsync"); assert.ok(methodStart >= 0 && methodEnd > methodStart); assert.ok(gate >= 0 && gate < reread && reread < compare && compare < stale && stale < mutation); assert.match(method.slice(stale, mutation), /retryable: false,[\s\S]*outcomeUnknown: false/u); }); test("different post-error readback always enters OutcomeUnknown quarantine", () => { assert.equal(native.includes('"SAVE_FAILED"'), false); assert.match(native, /수동 순매도 저장 중 파일 내용이 달라져 결과를 확정할 수 없습니다/u); assert.match(native, /VI 수동 목록 저장 중 파일 내용이 달라져 결과를 확정할 수 없습니다/u); assert.ok((native.match(/PostManualOperatorQuarantine\(requestId, "save-/gu) || []).length >= 4); }); test("configured external operator paths are disabled before any directory creation", () => { const configuredGuard = native.indexOf("if (!string.IsNullOrWhiteSpace(configuredDirectory))"); const privatePrepare = native.indexOf("TrustedManualDirectory.PreparePrivateWritableDirectory"); assert.ok(configuredGuard >= 0); assert.ok(privatePrepare > configuredGuard); assert.equal(native.includes("Directory.CreateDirectory(directory)"), false); }); test("trusted VI source is injected and checked for both page plan and page load", () => { assert.match(playout, /trustedViSource: _viManualListStore/u); assert.match(factory, /ITrustedViStockNameSnapshotSource\? trustedViSource/u); assert.ok((factory.match(/TrustedViManualReference\.ResolveAsync/gu) || []).length >= 2); });