import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { test } from 'node:test'; import { bestMp4, extractTweetMedia, isAllowedMediaUrl, isTappedUrl, mediaFilename, origPhotoUrl } from '../src/inject/media/parse.ts'; import { createMediaStore } from '../src/inject/media/store.ts'; import { ingestText, installMediaTap } from '../src/inject/media/tap.ts'; test('origPhotoUrl rewrites every query/suffix form to name=orig', () => { assert.equal(origPhotoUrl('https://pbs.twimg.com/media/Abc.jpg'), 'https://pbs.twimg.com/media/Abc?format=jpg&name=orig'); assert.equal(origPhotoUrl('https://pbs.twimg.com/media/Abc.png'), 'https://pbs.twimg.com/media/Abc?format=png&name=orig'); assert.equal(origPhotoUrl('https://pbs.twimg.com/media/Abc?format=webp&name=small'), 'https://pbs.twimg.com/media/Abc?format=webp&name=orig'); assert.equal(origPhotoUrl('https://pbs.twimg.com/media/Abc?format=jpg&name=900x900'), 'https://pbs.twimg.com/media/Abc?format=jpg&name=orig'); assert.equal(origPhotoUrl('https://pbs.twimg.com/media/Abc.jpeg?name=large'), 'https://pbs.twimg.com/media/Abc?format=jpg&name=orig'); assert.equal(origPhotoUrl('https://pbs.twimg.com/media/Abc'), 'https://pbs.twimg.com/media/Abc?format=jpg&name=orig'); }); test('bestMp4 picks the highest-bitrate mp4 and ignores HLS', () => { assert.equal(bestMp4([ { content_type: 'application/x-mpegURL', url: 'https://video.twimg.com/a.m3u8' }, { bitrate: 632000, content_type: 'video/mp4', url: 'https://video.twimg.com/low.mp4' }, { bitrate: 2176000, content_type: 'video/mp4', url: 'https://video.twimg.com/high.mp4' }, { bitrate: 950000, content_type: 'video/mp4', url: 'https://video.twimg.com/mid.mp4' }, ]), 'https://video.twimg.com/high.mp4'); assert.equal(bestMp4([{ bitrate: 0, content_type: 'video/mp4', url: 'https://video.twimg.com/gif.mp4' }]), 'https://video.twimg.com/gif.mp4'); assert.equal(bestMp4([{ content_type: 'application/x-mpegURL', url: 'x' }]), null); assert.equal(bestMp4(undefined), null); }); test('mediaFilename follows @user_id_n.ext', () => { assert.equal(mediaFilename('jack', '20', 0, { kind: 'photo', url: 'https://pbs.twimg.com/media/A?format=jpg&name=orig' }), '@jack_20_1.jpg'); assert.equal(mediaFilename('jack', '20', 1, { kind: 'photo', url: 'https://pbs.twimg.com/media/A?format=png&name=orig' }), '@jack_20_2.png'); assert.equal(mediaFilename('jack', '20', 2, { kind: 'video', url: 'https://video.twimg.com/v.mp4' }), '@jack_20_3.mp4'); assert.equal(mediaFilename('jack', '20', 0, { kind: 'animated_gif', url: 'https://video.twimg.com/g.mp4' }), '@jack_20_1.mp4'); assert.equal(mediaFilename('../evil', '1/2', 0, { kind: 'video', url: '' }), '@evil_12_1.mp4'); }); const tweet = (id: string, user: string, media: unknown[], extra: Record = {}) => ({ __typename: 'Tweet', rest_id: id, core: { user_results: { result: { __typename: 'User', core: { screen_name: user }, legacy: { screen_name: user } } } }, legacy: { id_str: id, full_text: 'hi', extended_entities: { media } }, ...extra, }); const photo = { type: 'photo', media_url_https: 'https://pbs.twimg.com/media/P1.jpg' }; const video = { type: 'video', media_url_https: 'https://pbs.twimg.com/ext_tw_video_thumb/1/pu/img/t.jpg', video_info: { variants: [ { bitrate: 256000, content_type: 'video/mp4', url: 'https://video.twimg.com/v/256.mp4' }, { bitrate: 832000, content_type: 'video/mp4', url: 'https://video.twimg.com/v/832.mp4' }, { content_type: 'application/x-mpegURL', url: 'https://video.twimg.com/v/pl.m3u8' }, ] } }; const gif = { type: 'animated_gif', video_info: { variants: [{ bitrate: 0, content_type: 'video/mp4', url: 'https://video.twimg.com/tweet_video/G.mp4' }] } }; const tweetDetail = { data: { threaded_conversation_with_injections_v2: { instructions: [ { type: 'TimelineAddEntries', entries: [ { entryId: 'tweet-100', content: { entryType: 'TimelineTimelineItem', itemContent: { itemType: 'TimelineTweet', tweet_results: { result: tweet('100', 'alice', [photo, video]) } } } }, { entryId: 'conversationthread-101', content: { entryType: 'TimelineTimelineModule', items: [ { entryId: 'x', item: { itemContent: { tweet_results: { result: { __typename: 'TweetWithVisibilityResults', tweet: tweet('101', 'bob', [gif]) } } } } }, ] } }, { entryId: 'tweet-102', content: { itemContent: { tweet_results: { result: { __typename: 'Tweet', rest_id: '102', legacy: { full_text: 'no media' } } } } } }, ] }, ] } } }; const homeTimeline = { data: { home: { home_timeline_urt: { instructions: [{ type: 'TimelineAddEntries', entries: [ { entryId: 'tweet-200', content: { itemContent: { tweet_results: { result: tweet('200', 'carol', [photo], { legacy: { id_str: '200', retweeted_status_result: { result: tweet('201', 'dave', [video]) } }, }) } } } }, ] }] } } } }; test('extractTweetMedia finds nested tweets in TweetDetail', () => { const found = extractTweetMedia(tweetDetail); assert.deepEqual(found.map(t => [t.tweetId, t.username, t.media.map(m => m.kind)]), [ ['100', 'alice', ['photo', 'video']], ['101', 'bob', ['animated_gif']], ]); assert.equal(found[0].media[0].url, 'https://pbs.twimg.com/media/P1?format=jpg&name=orig'); assert.equal(found[0].media[1].url, 'https://video.twimg.com/v/832.mp4'); assert.equal(found[1].media[0].url, 'https://video.twimg.com/tweet_video/G.mp4'); }); test('extractTweetMedia finds retweeted originals in HomeTimeline', () => { const found = extractTweetMedia(homeTimeline); assert.deepEqual(found.map(t => [t.tweetId, t.username]), [['201', 'dave']]); }); test('ingestText ignores malformed and oversize bodies', () => { const seen: string[] = []; ingestText('{not json', e => seen.push(e.tweetId)); ingestText(JSON.stringify(tweetDetail), e => seen.push(e.tweetId)); assert.deepEqual(seen, ['100', '101']); }); test('isTappedUrl / isAllowedMediaUrl', () => { assert.ok(isTappedUrl('https://x.com/i/api/graphql/abc123/TweetDetail?variables=%7B%7D')); assert.ok(isTappedUrl('https://x.com/i/api/graphql/abc/HomeLatestTimeline')); assert.ok(!isTappedUrl('https://x.com/i/api/graphql/abc/FavoriteTweet')); assert.ok(!isTappedUrl('https://x.com/i/api/graphql/abc/TweetDetailFoo')); assert.ok(isAllowedMediaUrl('https://pbs.twimg.com/media/A?format=jpg&name=orig')); assert.ok(isAllowedMediaUrl('https://video.twimg.com/v.mp4')); assert.ok(!isAllowedMediaUrl('https://x.com/i/api/1.1/foo')); assert.ok(!isAllowedMediaUrl('http://pbs.twimg.com/media/A')); }); test('media store is a bounded LRU', () => { const store = createMediaStore(2); store.set({ tweetId: 'a', username: '', media: [] }); store.set({ tweetId: 'b', username: '', media: [] }); store.get('a'); store.set({ tweetId: 'c', username: '', media: [] }); assert.equal(store.size, 2); assert.ok(store.get('a')); assert.equal(store.get('b'), undefined); }); test('fetch tap returns the original response untouched and reads a clone', async () => { const original = new Response(JSON.stringify(tweetDetail), { status: 200 }); const target = { fetch: (async () => original) as typeof fetch }; const seen: string[] = []; const handle = installMediaTap(target, e => seen.push(e.tweetId)); const response = await target.fetch('https://x.com/i/api/graphql/q/TweetDetail?x=1'); assert.equal(response, original); assert.equal(response.bodyUsed, false); assert.equal((await response.json()).data !== undefined, true); await new Promise(r => setTimeout(r, 10)); assert.deepEqual(seen, ['100', '101']); const rejecting = { fetch: (async () => { throw new TypeError('net'); }) as typeof fetch }; installMediaTap(rejecting, () => {}); await assert.rejects(rejecting.fetch('https://x.com/i/api/graphql/q/TweetDetail'), TypeError); handle.dispose(); }); test('the profile media tab (UserVideoTimeline, live 2026-10-01) is tapped and its posts get their media', () => { // X loads the profile's media tab ("Videos") with UserVideoTimeline instead of UserMedia; without // it in the list no post on that tab got a download button (seen live on //media). assert.ok(isTappedUrl('https://x.com/i/api/graphql/5A9PzD08T6PbvC2QlEYxMg/UserVideoTimeline?variables=%7B%7D')); assert.ok(!isTappedUrl('https://x.com/i/api/graphql/abc/UserVideoTimelineFoo')); // The response's shape as served live (ids, names and text invented). const body = JSON.parse(readFileSync(new URL('./fixtures/x/media/user-video-timeline.json', import.meta.url), 'utf8')); assert.deepEqual(extractTweetMedia(body), [{ tweetId: '1000000000000000001', username: 'someone', media: [ { kind: 'video', url: 'https://video.twimg.com/amplify_video/1000000000000000002/vid/avc1/1280x720/high.mp4' }, ] }]); });