import assert from 'node:assert/strict' import { readFile, readdir } from 'node:fs/promises' import path from 'node:path' import test from 'node:test' const root = path.resolve(import.meta.dirname, '..') const contractPath = path.join(root, 'contracts', 'numbered-ipc-registry.json') const libPath = path.join(root, 'src-tauri', 'src', 'lib.rs') const dispatcherPath = path.join(root, 'src-tauri', 'src', 'numbered_ipc_dispatch.rs') const clientPath = path.join(root, 'src', 'modules', 'numbered-ipc.ts') const rustRoot = path.join(root, 'src-tauri', 'src') const frontendRoot = path.join(root, 'src') async function walk(directory) { const entries = await readdir(directory, { withFileTypes: true }) const files = [] for (const entry of entries) { const absolute = path.join(directory, entry.name) if (entry.isDirectory()) files.push(...await walk(absolute)) else files.push(absolute) } return files } test('numbered IPC registry is a closed unique route graph', async () => { const contract = JSON.parse(await readFile(contractPath, 'utf8')) assert.equal(contract.schema, 'hololake.numbered-ipc-registry/v1') assert.equal(contract.record_id, 'HLP-NUMBERED-IPC-ROOT-001') assert.equal(contract.runtime.public_tauri_command, 'numbered_ipc') assert.equal(contract.runtime.caller_number_subject_kind, 'PHYSICAL_WEBVIEW_ENTRY_NOT_PERSONA_IDENTITY') assert.equal(contract.runtime.caller_number_grants_persona_binding, false) assert.equal(contract.runtime.legacy_direct_commands_allowed, false) assert.equal(contract.runtime.grant_single_use, true) assert.equal(contract.runtime.payload_bound_grants, true) assert.equal(contract.runtime.authority_binding_issued_server_side, true) assert.equal(contract.runtime.persona_binding_claimed, false) assert.equal(contract.runtime.unknown_route, 'FAIL_CLOSED') assert.ok(contract.operations.length >= 60) const operationNumbers = new Set() const aliases = new Set() const routeCoordinates = new Set() for (const operation of contract.operations) { assert.match(operation.operation_number, /^HLP-NIPC-OP-\d{4}$/) assert.match(operation.module_number, /^HLP-NIPC-MOD-\d{4}$/) assert.match(operation.channel_number, /^HLP-NIPC-CH-\d{4}$/) assert.match(operation.target_number, /^HLP-NIPC-TGT-\d{4}$/) assert.ok(operation.handler.includes('::')) assert.equal(operationNumbers.has(operation.operation_number), false) assert.equal(aliases.has(operation.alias), false) operationNumbers.add(operation.operation_number) aliases.add(operation.alias) const coordinate = [operation.channel_number, operation.module_number, operation.operation_number, operation.target_number].join('/') assert.equal(routeCoordinates.has(coordinate), false) routeCoordinates.add(coordinate) } const payloadAliases = [ ...contract.payload_contract.empty_object_aliases, ...contract.payload_contract.input_wrapper_aliases, ...Object.keys(contract.payload_contract.direct_field_aliases), ] assert.equal(new Set(payloadAliases).size, payloadAliases.length) assert.deepEqual([...payloadAliases].sort(), [...aliases].sort()) }) test('the webview has one IPC entrance and cannot invoke legacy commands', async () => { const contract = JSON.parse(await readFile(contractPath, 'utf8')) const aliases = new Set(contract.operations.map((operation) => operation.alias)) const files = (await walk(frontendRoot)).filter((file) => /\.(ts|tsx)$/.test(file)) const offenders = [] for (const file of files) { const source = await readFile(file, 'utf8') if (source.includes("from '@tauri-apps/api/core'") && !file.endsWith(path.join('modules', 'numbered-ipc.ts'))) { offenders.push(`${path.relative(root, file)}:raw-tauri-import`) } if (file.endsWith(path.join('modules', 'numbered-ipc.ts'))) { const calls = [...source.matchAll(/\binvoke(?:<[^>]+>)?\s*\(\s*['"]([^'"]+)['"]/g)] for (const call of calls) if (call[1] !== 'numbered_ipc') offenders.push(`${path.relative(root, file)}:${call[1]}`) } else { const calls = [...source.matchAll(/\binvoke(?:<[^>]+>)?\s*\(\s*['"]([^'"]+)['"]/g)] for (const call of calls) if (!aliases.has(call[1])) offenders.push(`${path.relative(root, file)}:unregistered-alias:${call[1]}`) } } assert.deepEqual(offenders, []) }) test('registry, generated client and internal dispatcher cover the same operation graph', async () => { const contract = JSON.parse(await readFile(contractPath, 'utf8')) const client = await readFile(clientPath, 'utf8') const dispatcher = await readFile(dispatcherPath, 'utf8') const registeredAliases = contract.operations.map((operation) => operation.alias).sort() const clientAliases = [...client.matchAll(/^ "([a-z0-9_]+)": \{$/gm)].map((match) => match[1]).sort() const registeredHandlers = contract.operations.map((operation) => operation.handler).sort() const dispatchedHandlers = [...dispatcher.matchAll(/^ "([a-z0-9_]+::[a-z0-9_]+)" =>/gm)] .map((match) => match[1]) .sort() assert.deepEqual(clientAliases, registeredAliases) assert.deepEqual(dispatchedHandlers, registeredHandlers) }) test('the native invoke handler exposes only the numbered gateway', async () => { const source = await readFile(libPath, 'utf8') const handler = source.match(/invoke_handler\(tauri::generate_handler!\[([\s\S]*?)\]\)/)?.[1] assert.ok(handler) const commands = [...handler.matchAll(/([a-z_]+::[a-z_]+)/g)].map((match) => match[1]) assert.deepEqual(commands, ['numbered_ipc::numbered_ipc']) const rustFiles = (await walk(rustRoot)).filter((file) => file.endsWith('.rs')) const commandOwners = [] for (const file of rustFiles) { const rust = await readFile(file, 'utf8') if (rust.includes('#[tauri::command]')) commandOwners.push(path.basename(file)) } assert.deepEqual(commandOwners, ['numbered_ipc.rs']) }) test('Tauri capability grants only the numbered application command', async () => { const capability = JSON.parse(await readFile(path.join(root, 'src-tauri', 'capabilities', 'default.json'), 'utf8')) assert.ok(capability.permissions.includes('allow-numbered-ipc')) const permission = await readFile(path.join(root, 'src-tauri', 'permissions', 'numbered-ipc.toml'), 'utf8') assert.match(permission, /identifier\s*=\s*"allow-numbered-ipc"/) assert.match(permission, /commands\.allow\s*=\s*\["numbered_ipc"\]/) })