@admin-jigsaw/jigsaw-sdk
Version:
Returns predefined data for Jigsaw platform and exposes functionality to retrieve the necessary data
170 lines (169 loc) • 8.96 kB
JavaScript
import { describe, it, expect, vi, beforeEach } from "vitest";
import { JigsawClient } from "../index";
import { mainnet, sonic } from "viem/chains";
import { MOCK_HOLDING_ADDRESS, MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2, } from "./utils/testClient";
// Mock the getChainConfig function
vi.mock("../constants/chains", () => ({
getChainConfig: vi.fn().mockImplementation((chainId) => {
if (chainId === sonic.id) {
return {
constants: {
strategyManagerAddress: "0x1234567890123456789012345678901234567890",
},
strategies: {
aave: {
aaveStrategies: {
"USDC.e": { stratAddress: MOCK_STRATEGY_ADDRESS_1 },
scUSD: { stratAddress: MOCK_STRATEGY_ADDRESS_2 },
},
},
pendle: {
strategies: {
wS: [{ stratAddress: MOCK_STRATEGY_ADDRESS_1 }],
},
},
},
};
}
// Default to mainnet config
return {
constants: {
strategyManagerAddress: "0x1234567890123456789012345678901234567890",
},
strategies: {
aave: {
aaveStrategies: {
"USD0++": { stratAddress: MOCK_STRATEGY_ADDRESS_1 },
USDC: { stratAddress: MOCK_STRATEGY_ADDRESS_2 },
},
},
reservoir: {
rUSD: { apy: "5.0", stratAddress: MOCK_STRATEGY_ADDRESS_1 },
},
dinero: {
pxETH: { apy: "7.5", stratAddress: MOCK_STRATEGY_ADDRESS_2 },
},
pendle: {
strategies: {
WETH: [{ stratAddress: MOCK_STRATEGY_ADDRESS_1 }],
wstETH: [{ stratAddress: MOCK_STRATEGY_ADDRESS_2 }],
},
},
},
};
}),
}));
describe("JigsawClient Symbol Filtering", () => {
let client;
let mockReadContract;
beforeEach(() => {
// Create a new client instance for each test
client = new JigsawClient("http://localhost:8545", mainnet.id);
// Mock the readContract method
mockReadContract = vi.fn();
client.client.readContract = mockReadContract;
});
describe("getUserStrategies", () => {
it("should return all strategies when no symbol filter is provided", async () => {
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockReadContract.mockResolvedValue(mockStrategies);
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS);
expect(result).toEqual(mockStrategies);
expect(mockReadContract).toHaveBeenCalledWith({
address: "0x1234567890123456789012345678901234567890",
abi: expect.any(Array),
functionName: "getHoldingToStrategy",
args: [MOCK_HOLDING_ADDRESS],
});
});
it("should filter strategies by exact symbol match - USD0++ on mainnet", async () => {
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockReadContract.mockResolvedValue(mockStrategies);
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "USD0++");
expect(result).toEqual([MOCK_STRATEGY_ADDRESS_1]);
});
it("should filter strategies by exact symbol match - USDC.e on sonic", async () => {
// Create client for Sonic chain
const sonicClient = new JigsawClient("http://localhost:8545", sonic.id);
const mockSonicReadContract = vi.fn();
sonicClient.client.readContract = mockSonicReadContract;
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockSonicReadContract.mockResolvedValue(mockStrategies);
const result = await sonicClient.getUserStrategies(MOCK_HOLDING_ADDRESS, "USDC.e");
expect(result).toEqual([MOCK_STRATEGY_ADDRESS_1]);
});
it("should be case insensitive when filtering", async () => {
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockReadContract.mockResolvedValue(mockStrategies);
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "usd0++");
expect(result).toEqual([MOCK_STRATEGY_ADDRESS_1]);
});
it("should handle mixed case symbols correctly", async () => {
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockReadContract.mockResolvedValue(mockStrategies);
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "Usd0++");
expect(result).toEqual([MOCK_STRATEGY_ADDRESS_1]);
});
it("should return empty array for non-existent symbol", async () => {
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockReadContract.mockResolvedValue(mockStrategies);
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "NONEXISTENT");
expect(result).toEqual([]);
});
it("should filter reservoir strategies correctly", async () => {
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockReadContract.mockResolvedValue(mockStrategies);
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "rUSD");
expect(result).toEqual([MOCK_STRATEGY_ADDRESS_1]);
});
it("should filter dinero strategies correctly", async () => {
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockReadContract.mockResolvedValue(mockStrategies);
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "pxETH");
expect(result).toEqual([MOCK_STRATEGY_ADDRESS_2]);
});
it("should filter pendle strategies correctly", async () => {
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockReadContract.mockResolvedValue(mockStrategies);
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "WETH");
expect(result).toEqual([MOCK_STRATEGY_ADDRESS_1]);
});
it("should handle symbols with special characters without modification", async () => {
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockReadContract.mockResolvedValue(mockStrategies);
// Test that USD0++ is searched for exactly, not mapped from USD0
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "USD0++");
expect(result).toEqual([MOCK_STRATEGY_ADDRESS_1]);
});
it("should NOT match USD0 to USD0++ (special case handling removed)", async () => {
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockReadContract.mockResolvedValue(mockStrategies);
// This should return empty array since USD0 should not be mapped to USD0++
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "USD0");
expect(result).toEqual([]);
});
it("should handle contract read errors gracefully", async () => {
mockReadContract.mockRejectedValue(new Error("Contract read failed"));
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "USD0++");
expect(result).toEqual([]);
});
it("should handle non-array responses from contract", async () => {
mockReadContract.mockResolvedValue(null);
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "USD0++");
expect(result).toEqual([]);
});
it("should handle empty strategy arrays", async () => {
mockReadContract.mockResolvedValue([]);
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, "USD0++");
expect(result).toEqual([]);
});
it("should handle whitespace in symbols correctly", async () => {
const mockStrategies = [MOCK_STRATEGY_ADDRESS_1, MOCK_STRATEGY_ADDRESS_2];
mockReadContract.mockResolvedValue(mockStrategies);
// Test that trimmed symbols don't get special handling
const result = await client.getUserStrategies(MOCK_HOLDING_ADDRESS, " USD0++ ");
// Since we removed special case handling, this should return empty
expect(result).toEqual([]);
});
});
});