timeline.test.js
1 import { describe, expect, it } from 'vitest'; 2 import { __test__ } from './timeline.js'; 3 describe('twitter timeline helpers', () => { 4 it('builds for-you variables with withCommunity', () => { 5 expect(__test__.buildTimelineVariables('for-you', 20)).toEqual({ 6 count: 20, 7 includePromotedContent: false, 8 latestControlAvailable: true, 9 requestContext: 'launch', 10 withCommunity: true, 11 }); 12 }); 13 it('builds following variables with seenTweetIds instead of withCommunity', () => { 14 expect(__test__.buildTimelineVariables('following', 20, 'cursor-1')).toEqual({ 15 count: 20, 16 includePromotedContent: false, 17 latestControlAvailable: true, 18 requestContext: 'launch', 19 seenTweetIds: [], 20 cursor: 'cursor-1', 21 }); 22 }); 23 it('encodes variables into timeline url', () => { 24 const url = __test__.buildHomeTimelineUrl('query123', 'HomeLatestTimeline', { 25 count: 20, 26 seenTweetIds: [], 27 }); 28 expect(url).toContain('/i/api/graphql/query123/HomeLatestTimeline'); 29 expect(url).toContain('variables='); 30 expect(url).toContain('features='); 31 expect(decodeURIComponent(url)).toContain('"seenTweetIds":[]'); 32 }); 33 it('parses tweets and bottom cursor from home timeline payload', () => { 34 const payload = { 35 data: { 36 home: { 37 home_timeline_urt: { 38 instructions: [ 39 { 40 entries: [ 41 { 42 entryId: 'tweet-1', 43 content: { 44 itemContent: { 45 tweet_results: { 46 result: { 47 rest_id: '1', 48 legacy: { 49 full_text: 'hello', 50 favorite_count: 3, 51 retweet_count: 2, 52 reply_count: 1, 53 created_at: 'now', 54 }, 55 core: { 56 user_results: { 57 result: { 58 legacy: { 59 screen_name: 'alice', 60 }, 61 }, 62 }, 63 }, 64 views: { 65 count: '9', 66 }, 67 }, 68 }, 69 }, 70 }, 71 }, 72 { 73 entryId: 'cursor-bottom-1', 74 content: { 75 entryType: 'TimelineTimelineCursor', 76 cursorType: 'Bottom', 77 value: 'cursor-next', 78 }, 79 }, 80 ], 81 }, 82 ], 83 }, 84 }, 85 }, 86 }; 87 const result = __test__.parseHomeTimeline(payload, new Set()); 88 expect(result.nextCursor).toBe('cursor-next'); 89 expect(result.tweets).toHaveLength(1); 90 expect(result.tweets[0]).toMatchObject({ 91 id: '1', 92 author: 'alice', 93 text: 'hello', 94 likes: 3, 95 retweets: 2, 96 replies: 1, 97 views: 9, 98 created_at: 'now', 99 url: 'https://x.com/alice/status/1', 100 }); 101 }); 102 });