hololake-system-architecture/product-source/hololake-native-desktop/scripts/web-novel-workbench-admission.test.mjs

54 lines
3.1 KiB
JavaScript

import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
const read = (path) => readFileSync(new URL(`../${path}`, import.meta.url), 'utf8')
const registry = JSON.parse(read('contracts/numbered-ipc-registry.json'))
const runtime = read('src-tauri/src/module_package_runtime.rs')
const moduleAdapter = read('src-tauri/src/web_novel_modules.rs')
const frontend = [
read('src/modules/web-novel/WebNovelWorkspace.tsx'),
read('src/modules/web-novel/AuthorModuleCenter.tsx'),
read('src/modules/web-novel/AuthorWritingSidecar.tsx'),
].join('\n')
const packages = [
'WORKBENCH', 'OUTLINE', 'GRID', 'STORYWORLD', 'DELIVERY',
].map((name) => JSON.parse(read(`fixtures/module-packages/HLP-MOD-OFFICIAL-WEB-NOVEL-${name}-0001-0.1.0.ghmod`)))
test('web novel family has five immutable official identities behind one shared lifecycle', () => {
assert.equal(packages.length, 5)
assert.ok(packages.every((value) => value.manifest.registrationClass === 'OFFICIAL_LIGHTHOUSE'))
assert.ok(packages.every((value) => value.manifest.adapter === 'web-novel-workbench-v1'))
assert.equal(new Set(packages.map((value) => value.manifest.moduleNumber)).size, 5)
assert.match(runtime, /const BUNDLED_MODULES/)
assert.doesNotMatch(frontend, /install_web_novel_author_module|mount_web_novel_author_module|uninstall_web_novel_author_module/)
})
test('all 38 web novel effects cross exact numbered routes and no raw tauri command surface', () => {
const routes = registry.operations.filter((route) => Number(route.operation_number.slice(-4)) >= 103 && Number(route.operation_number.slice(-4)) <= 140)
assert.equal(routes.length, 38)
assert.deepEqual([...new Set(routes.map((route) => route.module_number))], [
'HLP-NIPC-MOD-0025', 'HLP-NIPC-MOD-0026', 'HLP-NIPC-MOD-0027', 'HLP-NIPC-MOD-0028', 'HLP-NIPC-MOD-0029',
])
assert.ok(routes.every((route) => route.admission === 'VERIFIED_HUMAN_ROUTE'))
assert.doesNotMatch(frontend, /from ['"]@tauri-apps\/api\/core['"]/)
for (const source of ['web_novel_workspace.rs', 'web_novel_import.rs', 'web_novel_author.rs', 'web_novel_modules.rs']) {
assert.doesNotMatch(read(`src-tauri/src/${source}`), /#\[tauri::command\]/)
}
})
test('advanced effects require their own exact active module number', () => {
assert.match(moduleAdapter, /require_module_active\(&app, OUTLINE\)/)
assert.match(moduleAdapter, /require_module_active\(&app, GRID\)/)
assert.match(moduleAdapter, /require_module_active\(&app, STORYWORLD\)/)
assert.match(moduleAdapter, /require_module_active\(&app, DELIVERY\)/)
assert.match(moduleAdapter, /shared signed package runtime/)
})
test('workspace is independently lazy-loaded and preserves old account data in place', () => {
assert.match(read('src/main.tsx'), /lazy\(\(\) => import\('\.\/modules\/web-novel\/WebNovelWorkspace'\)/)
assert.equal(packages[0].payload.adapterConfig.legacyDataPolicy, 'READ_IN_PLACE_NO_DESTRUCTIVE_MIGRATION')
assert.equal(packages[0].payload.adapterConfig.thirdPartyPublishDefault, 'DENY')
assert.doesNotMatch(read('src-tauri/src/web_novel_workspace.rs'), /serde_json::from_str[^\n]+unwrap_or_default\(\)/)
})