/ clis / twitter / likes.test.js
likes.test.js
 1  import { describe, expect, it } from 'vitest';
 2  import { __test__ } from './likes.js';
 3  describe('twitter likes helpers', () => {
 4      it('falls back when queryId contains unsafe characters', () => {
 5          expect(__test__.sanitizeQueryId('safe_Query-123', 'fallback')).toBe('safe_Query-123');
 6          expect(__test__.sanitizeQueryId('bad"id', 'fallback')).toBe('fallback');
 7          expect(__test__.sanitizeQueryId('bad/id', 'fallback')).toBe('fallback');
 8          expect(__test__.sanitizeQueryId(null, 'fallback')).toBe('fallback');
 9      });
10      it('builds likes url with the provided queryId', () => {
11          const url = __test__.buildLikesUrl('query123', '42', 20, 'cursor-1');
12          expect(url).toContain('/i/api/graphql/query123/Likes');
13          expect(decodeURIComponent(url)).toContain('"userId":"42"');
14          expect(decodeURIComponent(url)).toContain('"cursor":"cursor-1"');
15      });
16      it('parses likes timeline entries and bottom cursor', () => {
17          const payload = {
18              data: {
19                  user: {
20                      result: {
21                          timeline_v2: {
22                              timeline: {
23                                  instructions: [
24                                      {
25                                          entries: [
26                                              {
27                                                  entryId: 'tweet-1',
28                                                  content: {
29                                                      itemContent: {
30                                                          tweet_results: {
31                                                              result: {
32                                                                  rest_id: '1',
33                                                                  legacy: {
34                                                                      full_text: 'liked post',
35                                                                      favorite_count: 7,
36                                                                      retweet_count: 2,
37                                                                      created_at: 'now',
38                                                                  },
39                                                                  core: {
40                                                                      user_results: {
41                                                                          result: {
42                                                                              legacy: {
43                                                                                  screen_name: 'alice',
44                                                                                  name: 'Alice',
45                                                                              },
46                                                                          },
47                                                                      },
48                                                                  },
49                                                              },
50                                                          },
51                                                      },
52                                                  },
53                                              },
54                                              {
55                                                  entryId: 'cursor-bottom-1',
56                                                  content: {
57                                                      entryType: 'TimelineTimelineCursor',
58                                                      cursorType: 'Bottom',
59                                                      value: 'cursor-next',
60                                                  },
61                                              },
62                                          ],
63                                      },
64                                  ],
65                              },
66                          },
67                      },
68                  },
69              },
70          };
71          const result = __test__.parseLikes(payload, new Set());
72          expect(result.nextCursor).toBe('cursor-next');
73          expect(result.tweets).toHaveLength(1);
74          expect(result.tweets[0]).toMatchObject({
75              id: '1',
76              author: 'alice',
77              name: 'Alice',
78              text: 'liked post',
79              likes: 7,
80              retweets: 2,
81              created_at: 'now',
82              url: 'https://x.com/alice/status/1',
83          });
84      });
85  });