test(federation): buildFriendContextId determinism (cross-instance invariant)

The friend contextId must be byte-identical on both peers for a given
canonical pair regardless of argument order. Initial-sync backfill keys
on contextId; if the two sides computed different values for the same
friendship, missed events would never reconcile.
This commit is contained in:
Jannis Braun
2026-04-25 22:24:04 +02:00
parent bd70950de7
commit 0677c21ab9
@@ -133,3 +133,21 @@ describe('queueReadStateRelay — mutation log capture', () => {
expect(rows[0]?.contextType).toBe('dm');
});
});
describe('buildFriendContextId — cross-instance determinism', () => {
it('produces the same value regardless of argument order', async () => {
const { buildFriendContextId } = await import('./federationOutbox.js');
expect(buildFriendContextId('alice', 'bob')).toBe(buildFriendContextId('bob', 'alice'));
});
it('produces the same value on home and on orbit for the same canonical pair', async () => {
// home computes: buildFriendContextId(myHomeUserId, theirHomeUserId)
// orbit computes: buildFriendContextId(theirHomeUserId, myHomeUserId)
// Both must equal — initial-sync backfill depends on this invariant.
const { buildFriendContextId } = await import('./federationOutbox.js');
const home = buildFriendContextId('home-id-1', 'orbit-id-2');
const orbit = buildFriendContextId('orbit-id-2', 'home-id-1');
expect(home).toBe(orbit);
expect(home).toBe('friend:home-id-1:orbit-id-2');
});
});