This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { createCliContext } from '../src/cli/shared.js';
|
||||
|
||||
describe('createCliContext', () => {
|
||||
it('resolves profileName from CLI options before env', () => {
|
||||
const ctx = createCliContext([], { BIRD_PROFILE_NAME: 'env-profile' } as NodeJS.ProcessEnv);
|
||||
|
||||
expect(ctx.resolveProfileNameFromOptions({ profileName: 'cli-profile' })).toBe('cli-profile');
|
||||
});
|
||||
|
||||
it('resolves profileName from env when CLI option is absent', () => {
|
||||
const ctx = createCliContext([], { BIRD_PROFILE_NAME: 'env-profile' } as NodeJS.ProcessEnv);
|
||||
|
||||
expect(ctx.resolveProfileNameFromOptions({})).toBe('env-profile');
|
||||
});
|
||||
});
|
||||
@@ -9,6 +9,7 @@ describe('bookmarks command', () => {
|
||||
const ctx = {
|
||||
resolveTimeoutFromOptions: () => undefined,
|
||||
resolveRelayBaseUrlFromOptions: () => 'https://relay.example',
|
||||
resolveProfileNameFromOptions: () => undefined,
|
||||
p: () => '',
|
||||
printTweets: () => undefined,
|
||||
} as unknown as CliContext;
|
||||
|
||||
@@ -14,6 +14,7 @@ describe('news command', () => {
|
||||
resolveTimeoutFromOptions: () => 30000,
|
||||
resolveQuoteDepthFromOptions: () => undefined,
|
||||
resolveRelayBaseUrlFromOptions: () => 'https://relay.example',
|
||||
resolveProfileNameFromOptions: () => undefined,
|
||||
p: (type: string) => `[${type}] `,
|
||||
colors: {
|
||||
accent: (text: string) => text,
|
||||
|
||||
@@ -9,6 +9,7 @@ describe('replies command', () => {
|
||||
({
|
||||
resolveTimeoutFromOptions: () => undefined,
|
||||
resolveQuoteDepthFromOptions: () => 1,
|
||||
resolveProfileNameFromOptions: () => undefined,
|
||||
extractTweetId: (input: string) => input,
|
||||
resolveRelayBaseUrlFromOptions: () => 'https://relay.example',
|
||||
p: () => '',
|
||||
@@ -74,6 +75,38 @@ describe('replies command', () => {
|
||||
errorSpy.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it('passes profileName to TwitterClient', async () => {
|
||||
const program = new Command();
|
||||
registerReadCommands(program, {
|
||||
...createMockContext(),
|
||||
resolveProfileNameFromOptions: () => 'work',
|
||||
});
|
||||
|
||||
const getTweetSpy = vi.spyOn(TwitterClient.prototype, 'getTweet').mockImplementation(async function () {
|
||||
const headers = (this as unknown as { getHeaders: () => Record<string, string> }).getHeaders();
|
||||
expect(headers).toEqual({ 'x-profile-name': 'work' });
|
||||
return {
|
||||
success: true,
|
||||
tweet: {
|
||||
id: '123',
|
||||
text: 'hello',
|
||||
author: { username: 'tester', name: 'Tester' },
|
||||
createdAt: '2024-01-01T00:00:00Z',
|
||||
url: 'https://x.com/tester/status/123',
|
||||
},
|
||||
};
|
||||
});
|
||||
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => undefined);
|
||||
|
||||
try {
|
||||
await program.parseAsync(['node', 'bird', 'read', '123', '--json']);
|
||||
expect(getTweetSpy).toHaveBeenCalledTimes(1);
|
||||
} finally {
|
||||
getTweetSpy.mockRestore();
|
||||
logSpy.mockRestore();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('thread command', () => {
|
||||
@@ -81,6 +114,7 @@ describe('thread command', () => {
|
||||
({
|
||||
resolveTimeoutFromOptions: () => undefined,
|
||||
resolveQuoteDepthFromOptions: () => 1,
|
||||
resolveProfileNameFromOptions: () => undefined,
|
||||
extractTweetId: (input: string) => input,
|
||||
resolveRelayBaseUrlFromOptions: () => 'https://relay.example',
|
||||
p: () => '',
|
||||
|
||||
@@ -14,6 +14,7 @@ describe('search command', () => {
|
||||
resolveTimeoutFromOptions: () => undefined,
|
||||
resolveQuoteDepthFromOptions: () => undefined,
|
||||
resolveRelayBaseUrlFromOptions: () => 'https://relay.example',
|
||||
resolveProfileNameFromOptions: () => undefined,
|
||||
p: () => '',
|
||||
printTweetsResult: vi.fn(),
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ import { TwitterClient } from '../src/lib/twitter-client.js';
|
||||
const baseCtx = {
|
||||
resolveTimeoutFromOptions: () => undefined,
|
||||
resolveRelayBaseUrlFromOptions: () => 'https://relay.example',
|
||||
resolveProfileNameFromOptions: () => undefined,
|
||||
p: () => '',
|
||||
printTweets: () => undefined,
|
||||
} as unknown as CliContext;
|
||||
|
||||
@@ -46,6 +46,7 @@ describe('root help output', () => {
|
||||
cmd.outputHelp();
|
||||
|
||||
expect(help).toContain('--relay-base-url');
|
||||
expect(help).toContain('--profile-name');
|
||||
expect(help).not.toContain('--auth-token');
|
||||
expect(help).not.toContain('--ct0');
|
||||
expect(help).toContain('--timeout');
|
||||
|
||||
@@ -124,6 +124,41 @@ describe('TwitterClient core coverage', () => {
|
||||
expect(headers).toEqual({});
|
||||
});
|
||||
|
||||
it('adds x-profile-name header when profileName is set', () => {
|
||||
const client = new TwitterClient({ relayBaseUrl: testRelayBaseUrl, profileName: 'work' });
|
||||
const clientPrivate = client as unknown as TwitterClientPrivate;
|
||||
|
||||
expect(clientPrivate.getHeaders()).toEqual({ 'x-profile-name': 'work' });
|
||||
});
|
||||
|
||||
it('ignores blank profileName values', () => {
|
||||
const client = new TwitterClient({ relayBaseUrl: testRelayBaseUrl, profileName: ' ' });
|
||||
const clientPrivate = client as unknown as TwitterClientPrivate;
|
||||
|
||||
expect(clientPrivate.getHeaders()).toEqual({});
|
||||
});
|
||||
|
||||
it('adds x-profile-name to JSON headers when profileName is set', () => {
|
||||
const client = new TwitterClient({ relayBaseUrl: testRelayBaseUrl, profileName: 'work' });
|
||||
const clientPrivate = client as unknown as TwitterClientPrivate & {
|
||||
getJsonHeaders: () => Record<string, string>;
|
||||
};
|
||||
|
||||
expect(clientPrivate.getJsonHeaders()).toEqual({
|
||||
'content-type': 'application/json',
|
||||
'x-profile-name': 'work',
|
||||
});
|
||||
});
|
||||
|
||||
it('adds x-profile-name to upload headers when profileName is set', () => {
|
||||
const client = new TwitterClient({ relayBaseUrl: testRelayBaseUrl, profileName: 'work' });
|
||||
const clientPrivate = client as unknown as TwitterClientPrivate & {
|
||||
getUploadHeaders: () => Record<string, string>;
|
||||
};
|
||||
|
||||
expect(clientPrivate.getUploadHeaders()).toEqual({ 'x-profile-name': 'work' });
|
||||
});
|
||||
|
||||
describe('fetchUserArticlePlainText failures', () => {
|
||||
it('returns empty object when response is not ok', async () => {
|
||||
const mockFetch = vi.fn().mockResolvedValueOnce(makeResponse({ ok: false, status: 500 }));
|
||||
|
||||
Reference in New Issue
Block a user