test: expand user-tweets coverage
This commit is contained in:
@@ -284,6 +284,35 @@ d('live CLI (Twitter/X)', () => {
|
|||||||
expect(tweets[0].author?.username?.toLowerCase()).toBe(testHandle.toLowerCase());
|
expect(tweets[0].author?.username?.toLowerCase()).toBe(testHandle.toLowerCase());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('user-tweets paged JSON returns { tweets, nextCursor }', async () => {
|
||||||
|
const testHandle =
|
||||||
|
process.env.BIRD_LIVE_USER_TWEETS_PAGED_HANDLE ?? process.env.BIRD_LIVE_USER_TWEETS_HANDLE ?? 'X';
|
||||||
|
const userTweets = await runBird(
|
||||||
|
[
|
||||||
|
...baseArgs,
|
||||||
|
'--cookie-timeout',
|
||||||
|
cookieTimeoutArg,
|
||||||
|
'user-tweets',
|
||||||
|
testHandle,
|
||||||
|
'-n',
|
||||||
|
'50',
|
||||||
|
'--max-pages',
|
||||||
|
'3',
|
||||||
|
'--delay',
|
||||||
|
'0',
|
||||||
|
'--json',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
timeoutMs: 45_000,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
expect(userTweets.exitCode).toBe(0);
|
||||||
|
const payload = parseJson<{ tweets?: Array<{ id?: string }>; nextCursor?: string | null }>(userTweets.stdout);
|
||||||
|
expect(Array.isArray(payload.tweets)).toBe(true);
|
||||||
|
expect(payload.tweets?.length).toBeGreaterThan(0);
|
||||||
|
expect(payload.tweets?.[0]?.id?.length).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
|
||||||
it('query-ids returns JSON', async () => {
|
it('query-ids returns JSON', async () => {
|
||||||
const queryIds = await runBird([...baseArgs, '--cookie-timeout', cookieTimeoutArg, 'query-ids', '--json'], {
|
const queryIds = await runBird([...baseArgs, '--cookie-timeout', cookieTimeoutArg, 'query-ids', '--json'], {
|
||||||
timeoutMs: 60_000,
|
timeoutMs: 60_000,
|
||||||
|
|||||||
@@ -394,6 +394,61 @@ describe('TwitterClient getUserTweetsPaged', () => {
|
|||||||
global.fetch = mockFetch as unknown as typeof fetch;
|
global.fetch = mockFetch as unknown as typeof fetch;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('requests only the remaining count', async () => {
|
||||||
|
mockFetch.mockResolvedValueOnce({
|
||||||
|
ok: true,
|
||||||
|
status: 200,
|
||||||
|
json: async () =>
|
||||||
|
makeTimelineResponse(
|
||||||
|
[makeTweetResult('1', 'Tweet 1'), makeTweetResult('2', 'Tweet 2'), makeTweetResult('3', 'Tweet 3')],
|
||||||
|
'cursor-2',
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
const client = new TwitterClient({ cookies: validCookies });
|
||||||
|
const result = await client.getUserTweetsPaged('12345', 5, { pageDelayMs: 0 });
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
|
||||||
|
const [url] = mockFetch.mock.calls[0];
|
||||||
|
const variablesRaw = new URL(url).searchParams.get('variables');
|
||||||
|
expect(variablesRaw).not.toBeNull();
|
||||||
|
const variables = JSON.parse(String(variablesRaw)) as { count?: number };
|
||||||
|
expect(variables.count).toBe(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('enforces a hard 10 page cap by default', async () => {
|
||||||
|
for (let page = 1; page <= 10; page += 1) {
|
||||||
|
const startId = (page - 1) * 20 + 1;
|
||||||
|
const tweets = Array.from({ length: 20 }, (_v, index) => {
|
||||||
|
const id = String(startId + index);
|
||||||
|
return makeTweetResult(id, `Tweet ${id}`);
|
||||||
|
});
|
||||||
|
mockFetch.mockResolvedValueOnce({
|
||||||
|
ok: true,
|
||||||
|
status: 200,
|
||||||
|
json: async () => makeTimelineResponse(tweets, `cursor-${page + 1}`),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = new TwitterClient({ cookies: validCookies });
|
||||||
|
const result = await client.getUserTweetsPaged('12345', 9999, { pageDelayMs: 0 });
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect(mockFetch).toHaveBeenCalledTimes(10);
|
||||||
|
expect(result.tweets?.length).toBe(200);
|
||||||
|
expect(result.nextCursor).toBe('cursor-11');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns error for invalid limit', async () => {
|
||||||
|
const client = new TwitterClient({ cookies: validCookies });
|
||||||
|
const result = await client.getUserTweetsPaged('12345', 0);
|
||||||
|
|
||||||
|
expect(result.success).toBe(false);
|
||||||
|
expect(result.error).toContain('Invalid limit');
|
||||||
|
expect(mockFetch).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it('fetches multiple pages with cursor', async () => {
|
it('fetches multiple pages with cursor', async () => {
|
||||||
mockFetch
|
mockFetch
|
||||||
.mockResolvedValueOnce({
|
.mockResolvedValueOnce({
|
||||||
|
|||||||
Reference in New Issue
Block a user