import assert from 'node:assert/strict'; import { test } from 'node:test'; import { createLanes, type LaneRequest, type Settled } from '../src/fixes/mutationGate/lanes.ts'; import { classifyResponse, matchMutation, synthesizedBody, type MutationMatch } from '../src/fixes/mutationGate/matchers.ts'; import { installMutationGate } from '../src/fixes/mutationGate/index.ts'; import { X_FEATURES } from '../src/areas/table.ts'; import { FEATURE_DEFAULTS } from '../src/inject/features.ts'; const BASE = 'https://x.com/home'; const post = (body: BodyInit | null | undefined): RequestInit => ({ method: 'POST', body }); const likeBody = (id: unknown) => JSON.stringify({ variables: { tweet_id: id }, queryId: 'lI07N6Otwv1PhnEgXILM7A' }); const tick = () => new Promise(resolve => setImmediate(resolve)); // ---------- matchers ---------- test('matcher: like/unlike and follow/unfollow fixtures', () => { assert.deepEqual(matchMutation('/i/api/graphql/lI07N6Otwv1PhnEgXILM7A/FavoriteTweet', post(likeBody('1790000000000000001')), BASE), { kind: 'like', id: '1790000000000000001', key: 'tweet:1790000000000000001', want: true }); assert.deepEqual(matchMutation(new URL('https://x.com/i/api/graphql/ZYKSe-w7KEslx3JhSIk5LA/UnfavoriteTweet'), post(likeBody('42')), BASE), { kind: 'like', id: '42', key: 'tweet:42', want: false }); assert.deepEqual(matchMutation('https://x.com/i/api/1.1/friendships/create.json', post('include_profile_interstitial_type=1&user_id=783214&skip_status=1'), BASE), { kind: 'follow', id: '783214', key: 'user:783214', want: true }); assert.deepEqual(matchMutation('/i/api/1.1/friendships/destroy.json', post(new URLSearchParams({ user_id: '783214' })), BASE), { kind: 'follow', id: '783214', key: 'user:783214', want: false }); // Promoted like bodies carry extra variables and still match. assert.equal(matchMutation('/i/api/graphql/x/FavoriteTweet', post(JSON.stringify({ variables: { tweet_id: '7', promotedContent: { impressionId: 'a' } } })), BASE)?.key, 'tweet:7'); }); test('matcher: malformed, DM, read and other endpoints are untouched', () => { const none: [unknown, RequestInit | undefined][] = [ ['/i/api/graphql/x/FavoriteTweet', post('{not json')], ['/i/api/graphql/x/FavoriteTweet', post(likeBody(42))], ['/i/api/graphql/x/FavoriteTweet', post(likeBody('12a'))], ['/i/api/graphql/x/FavoriteTweet', post(JSON.stringify({ variables: {} }))], ['/i/api/graphql/x/FavoriteTweet', post('null')], ['/i/api/graphql/x/FavoriteTweet', post(new Blob(['x']))], ['/i/api/graphql/x/FavoriteTweet', { body: likeBody('1') }], ['/i/api/graphql/x/FavoriteTweet', undefined], ['/i/api/graphql/x/FavoriteTweets', post(likeBody('1'))], ['/i/api/graphql/x/CreateRetweets', post(likeBody('1'))], ['/i/api/graphql/x/DeleteRetweet', post(likeBody('1'))], ['/i/api/graphql/x/CreateBookmark', post(likeBody(1))], ['/i/api/graphql/x/DeleteBookmark', post(new Blob(['x']))], ['/i/api/graphql/x/TweetDetail', post(likeBody('1'))], ['/i/api/graphql/x/useDMReactionMutationAddMutation', post(likeBody('1'))], ['/i/api/1.1/dm/new2.json', post('user_id=1')], ['/i/api/1.1/friendships/cancel.json', post('user_id=1')], ['/i/api/1.1/friendships/update.json', post('user_id=1')], ['/i/api/1.1/friendships/create.json', post('user_id=abc')], ['/i/api/1.1/friendships/create.json', post('screen_name=jack')], ['/i/api/1.1/friendships/create.json', post('user_id=1&user_id=2')], ['/i/api/1.1/friendships/create.json', post(new FormData())], ['https://api.x.com/1.1/friendships/create.json', post('user_id=1')], ['https://evil.example/i/api/1.1/friendships/create.json', post('user_id=1')], [new Request('https://x.com/i/api/1.1/friendships/create.json', { method: 'POST', body: 'user_id=1' }), undefined], ['http://[bad', post('user_id=1')], [42, post('user_id=1')], ]; for (const [input, init] of none) assert.equal(matchMutation(input, init, BASE), null, `${String(input)} ${String(init?.body)}`); }); test('classifier: confirmed, requested and unknown outcomes', () => { const like: MutationMatch = { kind: 'like', id: '1', key: 'tweet:1', want: true }; const unlike: MutationMatch = { ...like, want: false }; const follow: MutationMatch = { kind: 'follow', id: '9', key: 'user:9', want: true }; const unfollow: MutationMatch = { ...follow, want: false }; assert.deepEqual(classifyResponse(like, 200, '{"data":{"favorite_tweet":"Done"}}'), { outcome: 'confirmed', state: true }); assert.deepEqual(classifyResponse(unlike, 200, '{"data":{"unfavorite_tweet":"Done"}}'), { outcome: 'confirmed', state: false }); assert.deepEqual(classifyResponse(like, 200, '{"errors":[{"code":139}],"data":{}}'), { outcome: 'confirmed', state: true }); assert.deepEqual(classifyResponse(unlike, 200, '{"errors":[{"code":139}]}'), { outcome: 'unknown' }); assert.deepEqual(classifyResponse(like, 429, '{"errors":[{"code":88}]}'), { outcome: 'unknown' }); assert.deepEqual(classifyResponse(like, 500, 'oops'), { outcome: 'unknown' }); assert.deepEqual(classifyResponse(like, 200, '{"data":{"favorite_tweet":"Nope"}}'), { outcome: 'unknown' }); assert.deepEqual(classifyResponse(follow, 200, '{"id_str":"9","following":false}'), { outcome: 'confirmed', state: true }); assert.deepEqual(classifyResponse(follow, 200, '{"id_str":"9","protected":true}'), { outcome: 'requested' }); assert.deepEqual(classifyResponse(follow, 200, '{"id_str":"9","follow_request_sent":true}'), { outcome: 'requested' }); assert.deepEqual(classifyResponse(unfollow, 200, '{"id_str":"9"}'), { outcome: 'confirmed', state: false }); assert.deepEqual(classifyResponse(follow, 403, '{"errors":[{"code":161}]}'), { outcome: 'unknown' }); assert.deepEqual(classifyResponse(follow, 200, '[]'), { outcome: 'unknown' }); }); test('synthesized bodies: like Done, follow clones the last user object', () => { assert.equal(synthesizedBody({ kind: 'like', id: '1', key: 'tweet:1', want: true }, undefined), '{"data":{"favorite_tweet":"Done"}}'); assert.equal(synthesizedBody({ kind: 'like', id: '1', key: 'tweet:1', want: false }, undefined), '{"data":{"unfavorite_tweet":"Done"}}'); const follow: MutationMatch = { kind: 'follow', id: '9', key: 'user:9', want: false }; assert.deepEqual(JSON.parse(synthesizedBody(follow, '{"id_str":"9","screen_name":"a","following":true}')), { id_str: '9', screen_name: 'a', following: false }); assert.deepEqual(JSON.parse(synthesizedBody(follow, '{"id_str":"8"}')), { id: 9, id_str: '9', following: false }); assert.deepEqual(JSON.parse(synthesizedBody(follow, 'garbage')), { id: 9, id_str: '9', following: false }); }); // ---------- lane FSM ---------- type Result = { kind: 'wire' | 'synthetic'; want: boolean; n?: number }; type Wire = { n: number; key: string; want: boolean; resolve(outcome: 'ok' | 'unknown' | 'reject'): void }; function harness() { const lanes = createLanes(); const wire: Wire[] = []; const open = new Map(); let maxConcurrent = 0; let n = 0; const click = (key: string, want: boolean, signal?: AbortSignal) => { const id = n++; const req: LaneRequest = { want, signal, send: () => new Promise((resolve, reject) => { open.set(key, (open.get(key) ?? 0) + 1); maxConcurrent = Math.max(maxConcurrent, open.get(key)!); wire.push({ n: id, key, want, resolve: outcome => { open.set(key, open.get(key)! - 1); if (outcome === 'reject') reject(new TypeError('Failed to fetch')); else resolve({ kind: 'wire', want, n: outcome === 'ok' ? id : -1 }); } }); }), classify: (result): Promise => Promise.resolve(result.n === -1 ? { outcome: 'unknown' } : { outcome: 'confirmed', state: result.want }), synthesize: () => ({ kind: 'synthetic', want }), }; return lanes.submit(key, req); }; return { lanes, wire, click, get maxConcurrent() { return maxConcurrent; } }; } test('lane table: idle sends; busy holds; same direction shares; opposite pair-cancels', async () => { const h = harness(); const a = h.click('t', true); // idle -> wire const b = h.click('t', false); // busy -> held const c = h.click('t', true); // opposite of held -> pair cancel b+c assert.equal(h.wire.length, 1); const d = h.click('t', false); // busy -> held again const e = h.click('t', false); // same as held -> shares assert.deepEqual(h.lanes.stats, { sent: 1, held: 2, shared: 1, paired: 1, synthesized: 0, cancelled: 0 }); h.wire[0]!.resolve('ok'); assert.deepEqual(await a, { kind: 'wire', want: true, n: 0 }); assert.deepEqual(await b, { kind: 'synthetic', want: false }); assert.deepEqual(await c, { kind: 'synthetic', want: true }); await tick(); assert.equal(h.wire.length, 2); // d released exactly once; e waits behind it assert.equal(h.wire[1]!.n, 3); h.wire[1]!.resolve('ok'); assert.deepEqual(await d, { kind: 'wire', want: false, n: 3 }); assert.deepEqual(await e, { kind: 'synthetic', want: false }); assert.equal(h.lanes.size(), 0); assert.equal(h.maxConcurrent, 1); }); test('lane table: pending matching confirmed state is satisfied without a request', async () => { const h = harness(); const a = h.click('t', true); const b = h.click('t', true); // stale duplicate like h.wire[0]!.resolve('ok'); await a; assert.deepEqual(await b, { kind: 'synthetic', want: true }); assert.equal(h.wire.length, 1); }); test('lane table: unknown outcome and rejection release the held request as-is', async () => { const h = harness(); const a = h.click('t', true); const b = h.click('t', true); h.wire[0]!.resolve('unknown'); assert.deepEqual(await a, { kind: 'wire', want: true, n: -1 }); await tick(); assert.equal(h.wire.length, 2); // not synthesized: X's own behavior stands const c = h.click('t', false); h.wire[1]!.resolve('reject'); await assert.rejects(b, TypeError); // rejection reaches X unchanged await tick(); assert.equal(h.wire.length, 3); h.wire[2]!.resolve('ok'); assert.deepEqual(await c, { kind: 'wire', want: false, n: 2 }); }); test('lane table: aborting a held request rejects it and it never reaches the wire', async () => { const h = harness(); const a = h.click('t', true); const controller = new AbortController(); const b = h.click('t', false, controller.signal); controller.abort(); await assert.rejects(b, (error: unknown) => (error as Error).name === 'AbortError'); h.wire[0]!.resolve('ok'); await a; await tick(); assert.equal(h.wire.length, 1); assert.equal(h.lanes.size(), 0); }); test('lane table: separate targets never block each other', () => { const h = harness(); void h.click('t1', true); void h.click('t2', true); void h.click('u1', false); assert.equal(h.wire.length, 3); }); function rng(seed: number) { return () => { seed = (seed * 1_103_515_245 + 12_345) & 0x7fffffff; return seed / 0x7fffffff; }; } test('property: wire ⊆ naive in click order, never concurrent, final state == last intent', async () => { for (let seed = 1; seed <= 300; seed++) { const random = rng(seed); const h = harness(); const keys = ['a', 'b', 'c']; const intent = new Map(); // X's optimistic view: each click toggles const server = new Map(); const naive: { n: number; key: string; want: boolean }[] = []; const failures = random() < 0.3; const results: Promise[] = []; const done = new Set(); const settleOne = () => { const openWire = h.wire.filter(w => !done.has(w)); if (!openWire.length) return; const w = openWire[Math.floor(random() * openWire.length)]!; done.add(w); const roll = random(); const outcome = failures && roll < 0.2 ? 'unknown' : failures && roll < 0.3 ? 'reject' : 'ok'; if (outcome === 'ok') server.set(w.key, w.want); w.resolve(outcome); }; for (let step = 0; step < 40; step++) { if (random() < 0.6) { const key = keys[Math.floor(random() * keys.length)]!; const want = !(intent.get(key) ?? false); intent.set(key, want); naive.push({ n: naive.length, key, want }); results.push(h.click(key, want).catch(() => {})); } else settleOne(); await tick(); } while (h.wire.length > done.size) { settleOne(); await tick(); } await Promise.all(results); assert.equal(h.maxConcurrent <= 1, true, `seed ${seed}: concurrent`); // Every wire request is one of X's own, sent in click order per target. for (const key of keys) { const sent = h.wire.filter(w => w.key === key).map(w => w.n); assert.deepEqual(sent, [...sent].sort((x, y) => x - y), `seed ${seed}: order`); for (const n of sent) assert.equal(naive[n]!.key, key); for (const w of h.wire) assert.equal(naive[w.n]!.want, w.want); if (!failures && intent.has(key) && naive.some(c => c.key === key)) { // With no failures the confirmed server state equals the last click intent. assert.equal(server.get(key) ?? false, intent.get(key), `seed ${seed}: final ${key}`); } } assert.equal(new Set(h.wire.map(w => w.n)).size, h.wire.length, `seed ${seed}: sent twice`); assert.ok(h.wire.length <= naive.length); assert.equal(h.lanes.size(), 0, `seed ${seed}: lanes drained`); } }); // ---------- fetch gate ---------- function fakeWindow(respond: (input: unknown, init?: RequestInit) => Promise) { const calls: { input: unknown; init?: RequestInit }[] = []; const original = function (input: unknown, init?: RequestInit) { calls.push({ input, init }); return respond(input, init); } as typeof fetch; return { win: { fetch: original, location: { href: BASE } }, original, calls }; } const json = (body: unknown, status = 200) => new Response(JSON.stringify(body), { status, headers: { 'content-type': 'application/json' } }); test('gate: unmatched requests return the original promise; rejections pass through', async () => { const failure = Promise.reject(new TypeError('Failed to fetch')); failure.catch(() => {}); const { win, calls } = fakeWindow((input, init) => String(input).includes('fail') || String(init?.body).includes('666') ? failure : Promise.resolve(json({}))); const gate = installMutationGate(win); assert.equal(gate.installed, true); assert.equal(win.fetch('/i/api/fail'), failure); await assert.rejects(win.fetch('/i/api/graphql/x/FavoriteTweet', post(likeBody('666')))); assert.equal(calls.length, 2); gate.dispose(); }); test('gate: burst like/unlike/like on one tweet sends one request and resolves every caller', async () => { let release!: () => void; const gateOpen = new Promise(resolve => { release = resolve; }); const { win, calls, original } = fakeWindow(async () => { await gateOpen; return json({ data: { favorite_tweet: 'Done' } }); }); const gate = installMutationGate(win); const url = '/i/api/graphql/lI07N6Otwv1PhnEgXILM7A/FavoriteTweet'; const unurl = '/i/api/graphql/ZYKSe-w7KEslx3JhSIk5LA/UnfavoriteTweet'; const a = win.fetch(url, post(likeBody('5'))); const b = win.fetch(unurl, post(likeBody('5'))); const c = win.fetch(url, post(likeBody('5'))); assert.equal(calls.length, 1); release(); assert.deepEqual(await (await a).json(), { data: { favorite_tweet: 'Done' } }); assert.deepEqual(await (await b).json(), { data: { unfavorite_tweet: 'Done' } }); assert.deepEqual(await (await c).json(), { data: { favorite_tweet: 'Done' } }); assert.equal(calls.length, 1); gate.dispose(); assert.equal(win.fetch, original); }); test('gate: kill switch leaves a captured wrapper as pure pass-through', async () => { const { win, calls } = fakeWindow(() => new Promise(() => {})); const gate = installMutationGate(win); const captured = win.fetch; const wrapped = { fetch: captured }; // e.g. another wrapper installed on top gate.dispose(); void wrapped.fetch('/i/api/graphql/x/FavoriteTweet', post(likeBody('1'))); void wrapped.fetch('/i/api/graphql/x/FavoriteTweet', post(likeBody('1'))); assert.equal(calls.length, 2); }); test('gate: composes with an earlier fetch wrapper instead of replacing it', async () => { const { win, original } = fakeWindow(() => Promise.resolve(json({ data: { favorite_tweet: 'Done' } }))); const seen: unknown[] = []; const observer = function (this: unknown, ...args: Parameters) { seen.push(args[0]); return Reflect.apply(original, this, args); } as typeof fetch; win.fetch = observer; const gate = installMutationGate(win); await win.fetch('/i/api/graphql/x/FavoriteTweet', post(likeBody('1'))); assert.equal(seen.length, 1); gate.dispose(); assert.equal(win.fetch, observer); }); // ---------- click guard: see tests/clickGuard.test.ts (held clicks are delivered, never dropped) ---------- // ---------- XHR transport (X's logged-in client sends these mutations with XMLHttpRequest) ---------- type XhrWire = { name: string; id: string }; function xhrEnv(liked: boolean) { const server = { liked, wire: [] as XhrWire[], inflight: new Map(), concurrent: false }; const replies: (() => void)[] = []; class FakeXHR extends EventTarget { #s = { readyState: 0, status: 0, text: '', method: '', url: '' }; responseType: XMLHttpRequestResponseType = ''; get readyState() { return this.#s.readyState; } get status() { return this.#s.status; } get responseText() { return this.#s.text; } get response() { return this.#s.text; } get responseURL() { return this.#s.readyState === 4 ? `https://x.com${this.#s.url}` : ''; } getResponseHeader() { return 'application/json'; } getAllResponseHeaders() { return 'content-type: application/json\r\n'; } open(method: string, url: string) { Object.assign(this.#s, { method, url, readyState: 1, status: 0, text: '' }); } send(body: string) { const name = this.#s.url.split('/').pop()!; const id = String(JSON.parse(body).variables.tweet_id); const n = (server.inflight.get(id) ?? 0) + 1; server.inflight.set(id, n); if (n > 1) server.concurrent = true; server.wire.push({ name, id }); replies.push(() => { server.inflight.set(id, server.inflight.get(id)! - 1); const want = name === 'FavoriteTweet'; let text: string; if (want && server.liked) text = '{"data":{},"errors":[{"code":139,"message":"already favorited"}]}'; else { server.liked = want; text = want ? '{"data":{"favorite_tweet":"Done"}}' : '{"data":{"unfavorite_tweet":"Done"}}'; } Object.assign(this.#s, { readyState: 4, status: 200, text }); for (const type of ['readystatechange', 'load', 'loadend']) this.dispatchEvent(new Event(type)); }); } abort() { Object.assign(this.#s, { readyState: 4, status: 0 }); for (const type of ['readystatechange', 'abort', 'loadend']) this.dispatchEvent(new Event(type)); this.#s.readyState = 0; } } const win = { fetch: (async () => json({})) as typeof fetch, location: { href: BASE }, XMLHttpRequest: FakeXHR as unknown as typeof XMLHttpRequest }; // X's click handler: sends the opposite of the current UI state and flips the UI optimistically. let ui = liked; const results: { xhr: XMLHttpRequest; events: string[] }[] = []; const click = (id = '5') => { const xhr = new win.XMLHttpRequest(); const events: string[] = []; for (const type of ['readystatechange', 'load', 'abort', 'loadend']) xhr.addEventListener(type, () => events.push(type === 'readystatechange' ? `rs${xhr.readyState}` : type)); xhr.open('POST', `/i/api/graphql/q/${ui ? 'UnfavoriteTweet' : 'FavoriteTweet'}`); xhr.send(likeBody(id)); ui = !ui; results.push({ xhr, events }); return xhr; }; return { win, server, replies, click, results, get ui() { return ui; } }; } test('gate (XHR): 7 like/unlike clicks with out-of-order completion: wire ⊆ naive, final server == last intent', async () => { const env = xhrEnv(true); const gate = installMutationGate(env.win); for (let i = 0; i < 7; i++) { env.click(); await tick(); } // Naive X sends 7 concurrent requests; the lane sends the first and pairs the rest away. assert.deepEqual(env.server.wire.map(w => w.name), ['UnfavoriteTweet']); // Complete whatever is on the wire, newest first (out of order). while (env.replies.length) { env.replies.pop()!(); await tick(); } await tick(); assert.equal(env.server.liked, env.ui, 'server state equals the last click intent'); assert.equal(env.server.concurrent, false); for (const { xhr, events } of env.results) { assert.equal(xhr.readyState, 4); assert.equal(xhr.status, 200); assert.equal(events.filter(e => e === 'loadend').length, 1, 'every X request completes exactly once'); assert.ok(JSON.parse(xhr.responseText).data, 'with a success body of its own shape'); } const held = env.results[1]!; assert.deepEqual(held.events, ['rs2', 'rs3', 'rs4', 'load', 'loadend'], 'browser event order for a synthesized completion'); assert.deepEqual(JSON.parse(held.xhr.responseText), { data: { favorite_tweet: 'Done' } }); assert.equal(held.xhr.getResponseHeader('Content-Type'), 'application/json; charset=utf-8'); assert.equal(gate.lanes.size(), 0); gate.dispose(); }); test('gate (XHR): randomized bursts keep wire ⊆ naive, never concurrent, final == last intent', async () => { for (let seed = 1; seed <= 40; seed++) { const random = rng(seed); const env = xhrEnv(random() < 0.5); const gate = installMutationGate(env.win); const clicks = 1 + Math.floor(random() * 8); for (let i = 0; i < clicks; i++) { env.click(); await tick(); // Sometimes the server answers an in-flight request before the next click, in any order. while (env.replies.length && random() < 0.4) { env.replies.splice(Math.floor(random() * env.replies.length), 1)[0]!(); await tick(); } } while (env.replies.length) { env.replies.splice(Math.floor(random() * env.replies.length), 1)[0]!(); await tick(); } await tick(); assert.equal(env.server.concurrent, false, `seed ${seed}: concurrent`); assert.ok(env.server.wire.length <= clicks, `seed ${seed}: wire ⊆ naive`); assert.equal(env.server.liked, env.ui, `seed ${seed}: final state`); for (const { events } of env.results) assert.equal(events.filter(e => e === 'loadend').length, 1, `seed ${seed}: one loadend each`); assert.equal(gate.lanes.size(), 0, `seed ${seed}: lanes drained`); gate.dispose(); } }); test('gate (XHR): abort of a held request never reaches the wire; unmatched XHRs are untouched', async () => { const env = xhrEnv(false); const nativeSend = env.win.XMLHttpRequest.prototype.send; const gate = installMutationGate(env.win); env.click(); // Favorite: on the wire const held = env.click(); // Unfavorite: held behind it held.abort(); await tick(); assert.deepEqual(env.results[1]!.events, ['rs4', 'abort', 'loadend']); assert.equal(held.readyState, 0); env.replies.shift()!(); await tick(); assert.deepEqual(env.server.wire.map(w => w.name), ['FavoriteTweet']); // Reuse after abort: the object behaves natively again. held.open('POST', '/i/api/graphql/q/UnfavoriteTweet'); assert.equal(held.readyState, 1); // A non-mutation XHR goes straight to the native send (the fake parses its body and throws on null). const plain = new env.win.XMLHttpRequest(); plain.open('GET', '/i/api/2/badge_count/badge_count.json'); assert.throws(() => plain.send(null)); assert.notEqual(env.win.XMLHttpRequest.prototype.send, nativeSend, 'hooked while installed'); gate.dispose(); assert.equal(env.win.XMLHttpRequest.prototype.send, nativeSend, 'dispose restores the native send'); }); test('feature flag: fixLikeFollow defaults on and is one of the Fixes', () => { assert.equal(FEATURE_DEFAULTS.fixLikeFollow, true); // A core flag: owned by no plugin, so no plugin switch can turn it off (src/areas/table.ts). assert.deepEqual(X_FEATURES.filter(feature => feature.area === null && feature.group === 'fixes').map(feature => feature.id), ['fixLikeFollow', 'fixScrollRestore', 'fixTimelineJump', 'fixHomeTab', 'fixNotificationBadge', 'fixNewPostsPill', 'fixMediaUpload', 'followingChronological', 'fixChatButton', 'composerRestorePrompt']); for (const key of ['fixScrollRestore', 'fixTimelineJump', 'fixHomeTab', 'fixNotificationBadge', 'fixNewPostsPill', 'fixMediaUpload', 'followingChronological', 'fixChatButton', 'composerRestorePrompt'] as const) { assert.equal(FEATURE_DEFAULTS[key], true, key); } }); // ---------- failed in-flight request: nothing unconfirmed is ever answered with a success ---------- type XResult = { kind: 'wire' | 'synthetic'; ok: boolean; n: number }; /** * Lane harness with X's view of each caller: a wire result with ok=false (429, 5xx) or a rejection * (network, abort) makes X revert that click's optimistic change; a success commits it. X's UI ends * on the intent of the last committed click (redux-optimist replay of absolute `following`/`favorited`). */ function failHarness(initial = false) { const lanes = createLanes(); const wire: { n: number; want: boolean; settle(outcome: 'ok' | 'fail' | 'odd' | 'reject' | 'abort'): void }[] = []; const clicks: { want: boolean; status: 'pending' | 'committed' | 'reverted'; how?: string }[] = []; let server = initial; let open = 0, maxOpen = 0; const click = (want: boolean) => { const n = clicks.length; const entry: { want: boolean; status: 'pending' | 'committed' | 'reverted'; how?: string } = { want, status: 'pending' }; clicks.push(entry); const promise = lanes.submit('user:9', { want, send: () => new Promise((resolve, reject) => { open++; maxOpen = Math.max(maxOpen, open); wire.push({ n, want, settle: outcome => { open--; if (outcome === 'ok') { server = want; resolve({ kind: 'wire', ok: true, n }); } else if (outcome === 'odd') resolve({ kind: 'wire', ok: true, n: -1 }); // a 200 the lane cannot read else if (outcome === 'fail') resolve({ kind: 'wire', ok: false, n }); else reject(outcome === 'abort' ? new DOMException('The operation was aborted.', 'AbortError') : new TypeError('Failed to fetch')); } }); }), classify: (result): Promise => Promise.resolve(result.ok && result.n >= 0 ? { outcome: 'confirmed', state: want } : { outcome: 'unknown' }), synthesize: () => ({ kind: 'synthetic', ok: true, n }), }); promise.then(result => { entry.status = result.ok ? 'committed' : 'reverted'; entry.how = result.kind; }, error => { entry.status = 'reverted'; entry.how = (error as Error).name; }); return promise.catch(() => undefined); }; const ui = () => [...clicks].reverse().find(c => c.status === 'committed')?.want ?? initial; return { lanes, wire, clicks, click, ui, get server() { return server; }, get maxOpen() { return maxOpen; } }; } test('lanes: follow (429) + unfollow + follow while it is in flight: no synthesized success, the last follow is sent', async () => { const h = failHarness(false); const a = h.click(true); const b = h.click(false); // held (after the confirm sheet) const c = h.click(true); // pairs with the held unfollow h.wire[0]!.settle('fail'); // HTTP 429 await Promise.all([a, b]); await tick(); assert.equal(h.clicks[1]!.how, 'AbortError', 'the unfollow fails like an aborted request: X reverts it'); assert.equal(h.wire.length, 2, 'the latest intent goes out once, as X made it'); assert.deepEqual([h.wire[1]!.n, h.wire[1]!.want], [2, true]); assert.equal(h.lanes.stats.synthesized, 0); h.wire[1]!.settle('ok'); await c; assert.equal(h.clicks[2]!.how, 'wire'); assert.equal(h.server, true); assert.equal(h.ui(), h.server); await tick(); assert.equal(h.lanes.size(), 0); }); test('lanes: follow (429) + unfollow + follow, and the released follow is rate-limited too', async () => { const h = failHarness(false); const all = [h.click(true), h.click(false), h.click(true)]; h.wire[0]!.settle('fail'); await tick(); await tick(); h.wire[1]!.settle('fail'); await Promise.all(all); assert.equal(h.server, false); assert.equal(h.ui(), false, 'every optimistic change reverted: X shows the real state'); assert.equal(h.lanes.stats.synthesized, 0); }); test('lanes: like (500) + held unlike: the unlike is sent for real, never answered by the lane', async () => { const h = failHarness(false); const a = h.click(true); const b = h.click(false); h.wire[0]!.settle('fail'); // HTTP 500 await a; await tick(); assert.equal(h.wire.length, 2); assert.deepEqual([h.wire[1]!.n, h.wire[1]!.want], [1, false]); h.wire[1]!.settle('ok'); await b; assert.equal(h.clicks[1]!.how, 'wire'); assert.equal(h.ui(), h.server); assert.equal(h.lanes.stats.synthesized, 0); }); test('lanes: X aborts the in-flight request: held pair fails, the latest intent is released', async () => { const h = failHarness(true); const all = [h.click(false), h.click(true), h.click(false)]; h.wire[0]!.settle('abort'); await tick(); await tick(); assert.equal(h.clicks[1]!.how, 'AbortError'); assert.equal(h.wire.length, 2); assert.equal(h.wire[1]!.n, 2); h.wire[1]!.settle('ok'); await Promise.all(all); assert.equal(h.server, false); assert.equal(h.ui(), false); assert.equal(h.lanes.stats.synthesized, 0); }); test('lanes: unknown outcome (a 200 the lane cannot read) confirms nothing', async () => { const h = failHarness(false); const all = [h.click(true), h.click(false), h.click(true), h.click(true)]; h.wire[0]!.settle('odd'); await tick(); await tick(); assert.equal(h.clicks[1]!.how, 'AbortError'); assert.equal(h.wire.length, 2, 'one follow of the trailing run is released, the other waits behind it'); assert.equal(h.wire[1]!.n, 2); h.wire[1]!.settle('ok'); await Promise.all(all); assert.equal(h.clicks[3]!.how, 'synthetic', 'the stale duplicate is satisfied by the confirmed follow'); assert.equal(h.wire.length, 2); assert.equal(h.ui(), true); assert.equal(h.server, true); }); test('lanes: a held click in the same direction as the in-flight one no longer swallows a later reversal', async () => { const h = failHarness(false); const all = [h.click(true), h.click(true), h.click(false)]; // stale double follow, then unfollow h.wire[0]!.settle('ok'); await tick(); await tick(); assert.equal(h.clicks[1]!.how, 'synthetic', 'already satisfied by the confirmed follow'); assert.equal(h.wire.length, 2, 'the unfollow is sent'); h.wire[1]!.settle('ok'); await Promise.all(all); assert.equal(h.server, false); assert.equal(h.ui(), false); }); test('property: with failures the final UI equals the server; each request sent once, in click order, never concurrent', async () => { for (let seed = 1; seed <= 400; seed++) { const random = rng(seed); const h = failHarness(random() < 0.5); const results: Promise[] = []; let intent = h.ui(); const settled = new Set(); const settleOne = () => { const index = h.wire.findIndex((_, i) => !settled.has(i)); if (index < 0) return; settled.add(index); const roll = random(); h.wire[index]!.settle(roll < 0.2 ? 'fail' : roll < 0.3 ? 'reject' : roll < 0.35 ? 'abort' : 'ok'); }; for (let step = 0; step < 30; step++) { if (random() < 0.6) { intent = !intent; results.push(h.click(intent)); } else settleOne(); await tick(); } while (h.wire.length > settled.size) { settleOne(); await tick(); } await Promise.all(results); assert.equal(h.ui(), h.server, `seed ${seed}: UI differs from the server`); assert.ok(h.maxOpen <= 1, `seed ${seed}: concurrent`); const ns = h.wire.map(w => w.n); assert.deepEqual(ns, [...ns].sort((x, y) => x - y), `seed ${seed}: order`); assert.equal(new Set(ns).size, ns.length, `seed ${seed}: sent twice`); for (const w of h.wire) assert.equal(h.clicks[w.n]!.want, w.want); assert.equal(h.lanes.size(), 0, `seed ${seed}: drained`); } });