testing/cross_backend/audit_cross_helpers.ts

Audit-row reads for the cross-backend suites, behind the _testing_drain_effects barrier.

Both spines write audit rows off the request path — a WS mutation is answered before its effects flush, and the Rust spine's emits are fire-and-forget — so a suite that reads audit_log_list right after the call it audits can miss the row, and an assertion that a row is absent then passes vacuously. list_audit_events drains before it lists, so no reader can skip the barrier, and holds every row it lists to its event type's metadata schema (assert_audit_event_metadata), so every reader checks the metadata of the rows it reads, on every spine — closed to undeclared keys when the fixture's setup asked for it.

view source

Declarations
#

4 declarations

assert_audit_metadata_fields
#

testing/cross_backend/audit_cross_helpers.ts view source

(fixture: Pick<AuditReadFixture, "reject_unknown_audit_metadata_keys">, metadata: Record<string, unknown> | null, expected: Record<string, unknown>, absent?: readonly string[]): void import {assert_audit_metadata_fields} from '@fuzdev/fuz_app/testing/cross_backend/audit_cross_helpers.js';

Assert an audit row's metadata carries expected — each field compared on its own, so a consumer's added key passes — and none of absent. When the fixture's setup closed the world (reject_unknown_audit_metadata_keys), the whole object must equal expected, so an undeclared key fails too.

fixture

the per-test fixture, whose flag picks the comparison

type Pick<AuditReadFixture, "reject_unknown_audit_metadata_keys">

metadata

the row's metadata

type Record<string, unknown> | null

expected

the declared fields and their values

type Record<string, unknown>

absent?

keys the row must not carry, e.g. an optional field left unset

type readonly string[]
optional default []

returns

void

AuditReadFixture
#

testing/cross_backend/audit_cross_helpers.ts view source

AuditReadFixture import type {AuditReadFixture} from '@fuzdev/fuz_app/testing/cross_backend/audit_cross_helpers.js';

The fixture members an audit read uses — every TestFixture has them.

fresh_transport

type (options?: { readonly origin?: string | null | undefined; } | undefined): FetchTransport

readonly

options?

type { readonly origin?: string | null | undefined; }
optional

create_session_headers

The keeper's session headers — the keeper holds the admin role the audit read needs.

type (extra?: Record<string, string> | undefined): Record<string, string>

readonly

extra?

type Record<string, string>
optional
returns Record<string, string>

create_daemon_token_headers

type (extra?: Record<string, string> | undefined): Record<string, string>

readonly

extra?

type Record<string, string>
optional
returns Record<string, string>

reject_unknown_audit_metadata_keys?

Refuse undeclared metadata keys — see TestFixture.reject_unknown_audit_metadata_keys.

type boolean

readonly

cross_drain_effects
#

testing/cross_backend/audit_cross_helpers.ts view source

(fixture: AuditReadFixture, rpc_path?: string): Promise<void> import {cross_drain_effects} from '@fuzdev/fuz_app/testing/cross_backend/audit_cross_helpers.js';

Await the backend's in-flight audit writes via _testing_drain_effects, so a following audit_log_list sees every row emitted before the call. The backend must mount the action — every spine test binary does; in-process suites mount create_testing_drain_effects_action.

Refuses an answer without tracked: true. A binary whose audit emitter was built without in-flight tracking answers the drain at once, waiting on nothing, and its audit reads race the writes — an absent row then reads as a pass. Every audit read runs through here, so each one checks the barrier is live.

fixture

the per-test fixture, whose daemon token authorizes the drain

rpc_path?

the RPC endpoint the drain action is mounted on

type string
optional default SPINE_RPC_PATH

returns

Promise<void>

list_audit_events
#

testing/cross_backend/audit_cross_helpers.ts view source

(fixture: AuditReadFixture, params: Record<string, unknown>, rpc_path?: string): Promise<{ id: string & $brand<"Uuid">; seq: number; event_type: string; ... 9 more ...; target_username: string | null; }[]> import {list_audit_events} from '@fuzdev/fuz_app/testing/cross_backend/audit_cross_helpers.js';

Drain the backend's audit writes (cross_drain_effects), then list audit rows as the keeper, parse them against AuditLogListOutput, and parse each row's metadata against its event type's schema (assert_audit_event_metadata), with unknown keys refused when fixture.reject_unknown_audit_metadata_keys is set. The wire schema leaves metadata a loose record, so without this a spine's metadata drift reaches no assertion.

fixture

the per-test fixture; the list runs on the keeper's session

params

audit_log_list params, e.g. {event_type: 'login', outcome: 'failure'}

type Record<string, unknown>

rpc_path?

the RPC endpoint both actions are mounted on

type string
optional default SPINE_RPC_PATH

returns

Promise<AuditLogEventWithUsernamesJson[]>

the listed events

Depends on
#

Imported by
#