Skip to content

Commit

Permalink
client farcaster: test config and test coverage (#2567)
Browse files Browse the repository at this point in the history
* client-farcaster: test configuration

* client-farcaster: tests for cast

* client-farcaster: tests for client

* client-farcaster: tests for interaction

* client-farcaster: test utils

* client-farcaster: adding test for like iteration

---------

Co-authored-by: Sayo <[email protected]>
  • Loading branch information
ai16z-demirix and wtfsayo authored Jan 21, 2025
1 parent 80dbb30 commit 4b78912
Show file tree
Hide file tree
Showing 7 changed files with 487 additions and 4 deletions.
86 changes: 86 additions & 0 deletions packages/client-farcaster/__tests__/cast.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { createTestCast } from './test-utils';
import { FarcasterClient } from '../src/client';
import { NeynarAPIClient } from '@neynar/nodejs-sdk';

// Mock dependencies
vi.mock('@neynar/nodejs-sdk', () => ({
NeynarAPIClient: vi.fn().mockImplementation(() => ({
publishCast: vi.fn().mockResolvedValue({
success: true,
cast: {
hash: 'cast-1',
author: { fid: '123' },
text: 'Test cast',
timestamp: '2025-01-20T20:00:00Z'
}
}),
fetchBulkUsers: vi.fn().mockResolvedValue({
users: [{
fid: '123',
username: 'test.farcaster',
display_name: 'Test User',
pfp: {
url: 'https://example.com/pic.jpg'
}
}]
})
}))
}));

describe('Cast Functions', () => {
let client: FarcasterClient;

beforeEach(() => {
vi.clearAllMocks();
client = new FarcasterClient({
runtime: {
name: 'test-runtime',
memory: new Map(),
getMemory: vi.fn(),
setMemory: vi.fn(),
clearMemory: vi.fn()
},
url: 'https://api.example.com',
ssl: true,
neynar: new NeynarAPIClient({ apiKey: 'test-key' }),
signerUuid: 'test-signer',
cache: new Map(),
farcasterConfig: {
apiKey: 'test-key',
signerUuid: 'test-signer'
}
});
});

describe('createTestCast', () => {
it('should create a cast successfully', async () => {
const content = 'Test cast content';
const result = await createTestCast(client, content);

expect(result).toBeDefined();
expect(result.success).toBe(true);
expect(result.cast.text).toBe(content);
expect(client.neynar.publishCast).toHaveBeenCalledWith({
text: content,
signerUuid: 'test-signer'
});
});

it('should handle cast creation errors', async () => {
const content = 'Test cast content';
vi.mocked(client.neynar.publishCast).mockRejectedValueOnce(new Error('Cast creation failed'));
await expect(createTestCast(client, content)).rejects.toThrow('Cast creation failed');
});

it('should handle empty content', async () => {
const content = '';
await expect(createTestCast(client, content)).rejects.toThrow('Cast content cannot be empty');
});

it('should handle very long content', async () => {
const content = 'a'.repeat(321); // Farcaster limit is 320 characters
await expect(createTestCast(client, content)).rejects.toThrow('Cast content too long');
});
});
});
135 changes: 135 additions & 0 deletions packages/client-farcaster/__tests__/client.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { FarcasterClient } from '../src/client';
import { NeynarAPIClient } from '@neynar/nodejs-sdk';

// Mock dependencies
vi.mock('@neynar/nodejs-sdk', () => ({
NeynarAPIClient: vi.fn().mockImplementation(() => ({
publishCast: vi.fn().mockResolvedValue({
success: true,
cast: {
hash: 'cast-1',
author: { fid: '123' },
text: 'Test cast',
timestamp: '2025-01-20T20:00:00Z'
}
}),
fetchBulkUsers: vi.fn().mockResolvedValue({
users: [{
fid: '123',
username: 'test.farcaster',
display_name: 'Test User',
pfp: {
url: 'https://example.com/pic.jpg'
}
}]
}),
fetchCastsForUser: vi.fn().mockResolvedValue({
casts: [
{
hash: 'cast-1',
author: {
fid: '123',
username: 'test.farcaster',
display_name: 'Test User'
},
text: 'Test cast',
timestamp: '2025-01-20T20:00:00Z'
}
]
})
}))
}));

describe('FarcasterClient', () => {
let client: FarcasterClient;
const mockRuntime = {
name: 'test-runtime',
memory: new Map(),
getMemory: vi.fn(),
setMemory: vi.fn(),
clearMemory: vi.fn()
};

beforeEach(() => {
vi.clearAllMocks();
client = new FarcasterClient({
runtime: mockRuntime,
url: 'https://api.example.com',
ssl: true,
neynar: new NeynarAPIClient({ apiKey: 'test-key' }),
signerUuid: 'test-signer',
cache: new Map(),
farcasterConfig: {
apiKey: 'test-key',
signerUuid: 'test-signer'
}
});
});

describe('loadCastFromNeynarResponse', () => {
it('should load cast from Neynar response', async () => {
const neynarResponse = {
hash: 'cast-1',
author: { fid: '123' },
text: 'Test cast',
timestamp: '2025-01-20T20:00:00Z'
};

const cast = await client.loadCastFromNeynarResponse(neynarResponse);
expect(cast).toBeDefined();
expect(cast.hash).toBe('cast-1');
expect(cast.authorFid).toBe('123');
expect(cast.text).toBe('Test cast');
expect(cast.profile).toBeDefined();
expect(cast.profile.fid).toBe('123');
expect(cast.profile.username).toBe('test.farcaster');
});

it('should handle cast with parent', async () => {
const neynarResponse = {
hash: 'cast-2',
author: { fid: '123' },
text: 'Reply cast',
parent_hash: 'cast-1',
parent_author: { fid: '456' },
timestamp: '2025-01-20T20:00:00Z'
};

const cast = await client.loadCastFromNeynarResponse(neynarResponse);
expect(cast.inReplyTo).toBeDefined();
expect(cast.inReplyTo?.hash).toBe('cast-1');
expect(cast.inReplyTo?.fid).toBe('456');
});
});

describe('getProfile', () => {
it('should fetch profile successfully', async () => {
const profile = await client.getProfile('123');
expect(profile).toBeDefined();
expect(profile.fid).toBe('123');
expect(profile.username).toBe('test.farcaster');
expect(profile.name).toBe('Test User');
});

it('should handle profile fetch errors', async () => {
vi.mocked(client.neynar.fetchBulkUsers).mockRejectedValueOnce(new Error('Profile fetch failed'));
await expect(client.getProfile('123')).rejects.toThrow('Profile fetch failed');
});
});

describe('getCastsByFid', () => {
it('should fetch casts successfully', async () => {
const casts = await client.getCastsByFid({ fid: '123', pageSize: 10 });
expect(casts).toHaveLength(1);
expect(casts[0].hash).toBe('cast-1');
expect(casts[0].authorFid).toBe('123');
expect(casts[0].text).toBe('Test cast');
});

it('should handle cast fetch errors', async () => {
vi.mocked(client.neynar.fetchCastsForUser).mockRejectedValueOnce(new Error('Cast fetch failed'));
await expect(client.getCastsByFid({ fid: '123', pageSize: 10 })).rejects.toThrow('Cast fetch failed');
});
});
});
Loading

0 comments on commit 4b78912

Please sign in to comment.