import { describe, it, expect, vi, beforeEach } from "vitest"; import { PriceOracle } from "../../../src/pricing/index.js"; describe("Price Oracle", () => { let oracle: PriceOracle; let mockProvider: any; beforeEach(() => { mockProvider = { getNetwork: vi.fn().mockResolvedValue({ chainId: 1n }), call: vi.fn(), }; oracle = new PriceOracle("mainnet"); // @ts-ignore - access private property for testing oracle.provider = mockProvider; }); it("should fetch Chainlink price", async () => { // Mock Chainlink aggregator response mockProvider.call = vi.fn().mockResolvedValue( "0x0000000000000000000000000000000000000000000000000000000005f5e100" // 100000000 = $1.00 with 8 decimals ); const price = await oracle.getPrice( "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" // USDC ); expect(price).toBeDefined(); expect(price.name).toBe("chainlink"); expect(price.price).toBeGreaterThan(0n); }); it("should calculate weighted average with quorum", async () => { const sources = [ { name: "chainlink", price: 1000000n, decimals: 8, timestamp: Date.now(), }, { name: "uniswap-twap", price: 1010000n, decimals: 8, timestamp: Date.now(), }, ]; const result = await oracle.getPriceWithQuorum( "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", sources ); expect(result).toBeDefined(); expect(result.price).toBeGreaterThan(0n); // Weighted average should be between the two prices expect(result.price).toBeGreaterThanOrEqual(1000000n); expect(result.price).toBeLessThanOrEqual(1010000n); }); it("should handle missing token decimals gracefully", async () => { mockProvider.call = vi.fn().mockRejectedValue(new Error("Not found")); // Should not throw, should use default decimals await expect( oracle.getPrice("0xInvalidToken") ).rejects.toThrow(); }); });