@coinbase/agentkit
Version:
Coinbase AgentKit core primitives
207 lines (206 loc) • 8.87 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const farcasterActionProvider_1 = require("./farcasterActionProvider");
const schemas_1 = require("./schemas");
// Mock fetch globally
const mockFetch = jest.fn();
global.fetch = mockFetch;
describe("Farcaster Action Provider Input Schemas", () => {
describe("Account Details Schema", () => {
it("should successfully parse empty input", () => {
const validInput = {};
const result = schemas_1.FarcasterAccountDetailsSchema.safeParse(validInput);
expect(result.success).toBe(true);
expect(result.data).toEqual(validInput);
});
});
describe("Post Cast Schema", () => {
it("should successfully parse valid cast text", () => {
const validInput = {
castText: "Hello, Farcaster!",
};
const result = schemas_1.FarcasterPostCastSchema.safeParse(validInput);
expect(result.success).toBe(true);
expect(result.data).toEqual(validInput);
});
it("should successfully parse valid cast text with embeds", () => {
const validInput = {
castText: "Hello, Farcaster!",
embeds: [{ url: "https://example.com" }],
};
const result = schemas_1.FarcasterPostCastSchema.safeParse(validInput);
expect(result.success).toBe(true);
expect(result.data).toEqual(validInput);
});
it("should fail when embed URL is invalid", () => {
const invalidInput = {
castText: "Hello, Farcaster!",
embeds: [{ url: "invalid-url" }],
};
const result = schemas_1.FarcasterPostCastSchema.safeParse(invalidInput);
expect(result.success).toBe(false);
});
it("should fail when there are more than 2 embeds", () => {
const invalidInput = {
castText: "Hello, Farcaster!",
embeds: [
{ url: "https://example1.com" },
{ url: "https://example2.com" },
{ url: "https://example3.com" },
],
};
const result = schemas_1.FarcasterPostCastSchema.safeParse(invalidInput);
expect(result.success).toBe(false);
});
it("should fail parsing cast text over 280 characters", () => {
const invalidInput = {
castText: "a".repeat(281),
};
const result = schemas_1.FarcasterPostCastSchema.safeParse(invalidInput);
expect(result.success).toBe(false);
});
});
});
describe("Farcaster Action Provider", () => {
const mockConfig = {
neynarApiKey: "test-api-key",
signerUuid: "test-signer-uuid",
agentFid: "193",
};
let actionProvider;
beforeEach(() => {
jest.clearAllMocks();
actionProvider = new farcasterActionProvider_1.FarcasterActionProvider(mockConfig);
});
describe("accountDetails", () => {
const mockUserResponse = {
users: [
{
object: "user",
fid: 193,
username: "derek",
display_name: "Derek",
},
],
};
it("should successfully retrieve Farcaster account details", async () => {
mockFetch.mockResolvedValueOnce({
json: () => Promise.resolve(mockUserResponse),
});
const result = await actionProvider.accountDetails({});
expect(mockFetch).toHaveBeenCalledWith(`https://api.neynar.com/v2/farcaster/user/bulk?fids=${mockConfig.agentFid}`, {
method: "GET",
headers: {
accept: "application/json",
"x-api-key": mockConfig.neynarApiKey,
"x-neynar-experimental": "true",
},
});
expect(mockFetch).toHaveBeenCalledTimes(1);
expect(result).toContain("Successfully retrieved Farcaster account details");
expect(result).toContain(JSON.stringify(mockUserResponse.users[0]));
});
it("should handle errors when retrieving account details", async () => {
const error = new Error("API request failed");
mockFetch.mockRejectedValueOnce(error);
const result = await actionProvider.accountDetails({});
expect(mockFetch).toHaveBeenCalledTimes(1);
expect(result).toBe(`Error retrieving Farcaster account details:\n${error}`);
});
});
describe("postCast", () => {
const mockCastResponse = {
hash: "0x123",
};
it("should successfully post a cast", async () => {
mockFetch.mockResolvedValueOnce({
json: () => Promise.resolve(mockCastResponse),
});
const args = {
castText: "Hello, Farcaster!",
};
const result = await actionProvider.postCast(args);
expect(mockFetch).toHaveBeenCalledWith("https://api.neynar.com/v2/farcaster/cast", {
method: "POST",
headers: {
api_key: mockConfig.neynarApiKey,
"Content-Type": "application/json",
},
body: JSON.stringify({
signer_uuid: mockConfig.signerUuid,
text: args.castText,
embeds: undefined,
}),
});
expect(mockFetch).toHaveBeenCalledTimes(1);
expect(result).toContain("Successfully posted cast to Farcaster");
expect(result).toContain(JSON.stringify(mockCastResponse));
});
it("should successfully post a cast with embeds", async () => {
mockFetch.mockResolvedValueOnce({
json: () => Promise.resolve(mockCastResponse),
});
const args = {
castText: "Hello, Farcaster!",
embeds: [{ url: "https://example.com" }],
};
const result = await actionProvider.postCast(args);
expect(mockFetch).toHaveBeenCalledWith("https://api.neynar.com/v2/farcaster/cast", {
method: "POST",
headers: {
api_key: mockConfig.neynarApiKey,
"Content-Type": "application/json",
},
body: JSON.stringify({
signer_uuid: mockConfig.signerUuid,
text: args.castText,
embeds: args.embeds,
}),
});
expect(mockFetch).toHaveBeenCalledTimes(1);
expect(result).toContain("Successfully posted cast to Farcaster");
expect(result).toContain(JSON.stringify(mockCastResponse));
});
it("should handle errors when posting cast", async () => {
const error = new Error("Failed to post cast");
mockFetch.mockRejectedValueOnce(error);
const args = {
castText: "Hello, Farcaster!",
};
const result = await actionProvider.postCast(args);
expect(mockFetch).toHaveBeenCalledTimes(1);
expect(result).toBe(`Error posting to Farcaster:\n${error}`);
});
});
describe("constructor", () => {
it("should use environment variables when config is not provided", () => {
const originalEnv = process.env;
process.env = {
...originalEnv,
NEYNAR_API_KEY: "env-api-key",
NEYNAR_MANAGER_SIGNER: "env-signer-uuid",
AGENT_FID: "env-agent-fid",
};
const provider = new farcasterActionProvider_1.FarcasterActionProvider();
expect(provider).toBeDefined();
process.env = originalEnv;
});
it("should throw error when required config is missing", () => {
const originalEnv = process.env;
process.env = { ...originalEnv };
delete process.env.NEYNAR_API_KEY;
delete process.env.NEYNAR_MANAGER_SIGNER;
delete process.env.AGENT_FID;
expect(() => new farcasterActionProvider_1.FarcasterActionProvider()).toThrow();
process.env = originalEnv;
});
});
describe("supportsNetwork", () => {
it("should return true when protocolFamily is evm", () => {
expect(actionProvider.supportsNetwork({ protocolFamily: "evm" })).toBe(true);
});
it("should return false when protocolFamily is not evm", () => {
expect(actionProvider.supportsNetwork({ protocolFamily: "solana" })).toBe(false);
});
});
});