import test from 'node:test'; import assert from 'node:assert/strict'; import { InMemoryExactBroker, InMemoryFilterBroker } from '@open-matrix/federation/transport/inmem'; import { FederationPeer, ExactInstanceResolver } from '@open-matrix/federation/federation_peer'; import { getInternalTopic, getLegacyIngressTopic } from '@open-matrix/federation/topics'; import { createLegacyRequest, deserializeTaggedEnvelope, serializeLegacyEnvelope } from '@open-matrix/federation/envelope_codec'; import { parseMatrixUri } from '@open-matrix/federation/uri'; import { isRecord } from '../../src/util/guards'; import type { Transport } from '@open-matrix/federation/transport/base'; test('matrix3 compat: legacy request with ttlMs + flat replyTo is accepted and produces a reply', async () => { const backbone: Transport = new InMemoryExactBroker(); const localBus = new InMemoryFilterBroker(); const serverRealm = 'matrix-3'; const clientRealm = 'flowpad-demo.tab-01'; // Start EdgeGateway (server-side) const edge = new FederationPeer({ localRealm: serverRealm, backbone, localBus, }); edge.start(); // Local handler (no helper wrappers) that replies with a NON-standard reply payload // to prove lenient decoding on the EdgeGateway. const toPath = 'project/daemon.project.accepts.scan'; const internalTopic = getInternalTopic(serverRealm, toPath); localBus.subscribe(internalTopic, (_t, raw) => { const parsed = (() => { try { return JSON.parse(raw) as unknown; } catch { return null; } })(); if (!isRecord(parsed)) throw new Error('internal request must be a JSON object'); const replyTo = parsed.replyTo; if (typeof replyTo !== 'string') throw new Error('replyTo must be a string'); // Reply with `{ result: ... }` only (no correlationId, no ok), to exercise lenient reply parsing. localBus.publish(replyTo, JSON.stringify({ result: { hello: true } })); }); // Client mailbox watcher const clientMailbox = getLegacyIngressTopic(clientRealm); const serverMailbox = getLegacyIngressTopic(serverRealm); const correlationId = 'cid-ttlms-001'; const replyToPath = `_replies.emits.${correlationId}`; const repPromise = new Promise((resolve, reject) => { const timer = setTimeout(() => reject(new Error('timeout waiting for reply')), 250); const unsub = backbone.subscribe(clientMailbox, (_topic, payload) => { clearTimeout(timer); unsub(); const tagged = deserializeTaggedEnvelope(payload); if (!tagged) throw new Error('expected an envelope'); if (tagged.profile !== 'matrix3') throw new Error('expected matrix3 envelope'); if (tagged.kind !== 'reply') throw new Error('expected matrix3 reply envelope'); resolve(tagged.envelope.body); }); }); // Send raw legacy request with ttlMs (expiry semantics) and flat replyTo const req = createLegacyRequest({ toRealm: serverRealm, toPath, fromRealm: clientRealm, replyTo: replyToPath, correlationId, body: { depth: 1 }, ttlMs: 1234, type: 'request', }); backbone.publish(serverMailbox, serializeLegacyEnvelope(req)); const body = await repPromise; assert.deepEqual(body, { hello: true }); }); test('matrix3 compat: reply detection works for ok:true and ok:false', () => { const okRep = JSON.stringify({ toRealm: 'a', toPath: '_replies.emits.x', fromRealm: 'b', correlationId: 'x', ok: true, body: { v: 1 }, }); const badRep = JSON.stringify({ toRealm: 'a', toPath: '_replies.emits.x', fromRealm: 'b', correlationId: 'x', ok: false, body: null, error: { code: 'MX.FAIL', message: 'nope' }, }); const t1 = deserializeTaggedEnvelope(okRep); if (!t1) throw new Error('expected non-null'); if (t1.profile !== 'matrix3') throw new Error('expected matrix3 profile'); if (t1.kind !== 'reply') throw new Error('expected reply'); const t2 = deserializeTaggedEnvelope(badRep); if (!t2) throw new Error('expected non-null'); if (t2.profile !== 'matrix3') throw new Error('expected matrix3 profile'); if (t2.kind !== 'reply') throw new Error('expected reply'); }); test('matrix3 compat: URI parsing tolerant (legacy vs /-/ delimiter) canonicalizes to same toPath', () => { const a = parseMatrixUri('matrix-3/project/daemon.project.accepts.scan'); const b = parseMatrixUri('matrix-3/project/-/daemon/project/accepts/scan'); if (!a) throw new Error('expected non-null'); if (!b) throw new Error('expected non-null'); assert.equal(a.realm, 'matrix-3'); assert.equal(b.realm, 'matrix-3'); assert.equal(a.toPath, b.toPath); });