Context
A product holds no keys and only behaves in conversation with a host, so testing a product end-to-end needs both a host and a wallet/phone on the other end. The wallet is the hard part — manual, device-bound, not scriptable in CI — and standing up a real host per test is impractical. Tests need a host they can drive directly and deterministically, without a device.
Goal
Provide a faithful, in-core mock host: the same truapi-server core with a mock platform in the OS seam — "swap the seam, keep the core." Because the mock replaces only truapi-platform's capability seam (not the dispatcher, accounts, signing orchestration, permissions, statement store, or SSO), it is faithful by construction and cannot drift from a real host. It should be usable from both Rust (the native core) and JS (the real WASM core), and stay out of production builds.
Proposed shape
MockPlatform — Rust, in truapi-platform, behind a mock feature. A config-driven, in-memory implementation of all 11 capability traits, so it satisfies the blanket Platform:
let platform = MockPlatform::with_config(MockConfig {
device_permissions: PermissionPolicy::DenyAll,
chain: ChainBehavior::Scripted(frames),
faults: MockFaults { storage_error: Some("disk full".into()), ..Default::default() },
..Default::default()
});
Namespaced in-memory storage (product: / core:), per-capability permission policy, fault injection (MockFaults), configurable chain (ChainBehavior: Silent / Scripted / Closed / ConnectError), and recording oracles (navigations, notifications, confirmations, auth-state, sent RPC) for assertions.
createMockHost — JS, in @parity/truapi-host-wasm/web. The HostCallbacks sibling of MockPlatform, mocking the full generated host surface (kept complete by tsc), so the real WASM core runs against a mocked seam:
const mock = createMockHost();
const provider = await createWebWorkerProvider(
new HostWorker(), mock.callbacks, { runtimeConfig: mockRuntimeConfig() },
);
Scope
MockPlatform plus its config and oracle types in truapi-platform, behind a mock feature.
- Through-core tests driving
MockPlatform via TrUApiCore::from_platform_with_config + receive_from_product, proving requests flow through the real dispatcher and services (feature support, storage round-trip, permission-deny, preimage + confirm gate, and a fault surfacing as a wire error).
createMockHost + mockRuntimeConfig in @parity/truapi-host-wasm/web.
- A headless WASM-bridge test: the real WASM core invokes
createMockHost's callbacks across the JS↔SCALE↔WASM boundary (no browser, no worker).
- CI coverage for the
truapi-host-wasm package (build the WASM, run the tests).
- README docs for both crates.
Acceptance criteria
- The mock swaps only the platform seam; the real dispatcher and services run on top of it.
- Requests dispatch faithfully through the real core in tests, and the real WASM core drives the JS mock across the bridge.
- The
mock feature is off by default and never enters the production WASM build.
Gating
Depends on #104 — the truapi-server, truapi-platform, and truapi-host-wasm crates exist only on that branch.
Context
A product holds no keys and only behaves in conversation with a host, so testing a product end-to-end needs both a host and a wallet/phone on the other end. The wallet is the hard part — manual, device-bound, not scriptable in CI — and standing up a real host per test is impractical. Tests need a host they can drive directly and deterministically, without a device.
Goal
Provide a faithful, in-core mock host: the same
truapi-servercore with a mock platform in the OS seam — "swap the seam, keep the core." Because the mock replaces onlytruapi-platform's capability seam (not the dispatcher, accounts, signing orchestration, permissions, statement store, or SSO), it is faithful by construction and cannot drift from a real host. It should be usable from both Rust (the native core) and JS (the real WASM core), and stay out of production builds.Proposed shape
MockPlatform— Rust, intruapi-platform, behind amockfeature. A config-driven, in-memory implementation of all 11 capability traits, so it satisfies the blanketPlatform:Namespaced in-memory storage (
product:/core:), per-capability permission policy, fault injection (MockFaults), configurable chain (ChainBehavior:Silent/Scripted/Closed/ConnectError), and recording oracles (navigations, notifications, confirmations, auth-state, sent RPC) for assertions.createMockHost— JS, in@parity/truapi-host-wasm/web. TheHostCallbackssibling ofMockPlatform, mocking the full generated host surface (kept complete bytsc), so the real WASM core runs against a mocked seam:Scope
MockPlatformplus its config and oracle types intruapi-platform, behind amockfeature.MockPlatformviaTrUApiCore::from_platform_with_config+receive_from_product, proving requests flow through the real dispatcher and services (feature support, storage round-trip, permission-deny, preimage + confirm gate, and a fault surfacing as a wire error).createMockHost+mockRuntimeConfigin@parity/truapi-host-wasm/web.createMockHost's callbacks across the JS↔SCALE↔WASM boundary (no browser, no worker).truapi-host-wasmpackage (build the WASM, run the tests).Acceptance criteria
mockfeature is off by default and never enters the production WASM build.Gating
Depends on #104 — the
truapi-server,truapi-platform, andtruapi-host-wasmcrates exist only on that branch.