UNPKG

pipe-protocol

Version:

A protocol for large scale Interplanetary Intertool Agent Context

218 lines 9.1 kB
"use strict"; /** * @file IpfsNode Test Suite * @version 1.0.0 * @status STABLE - COMPLETE TEST COVERAGE * @lastModified 2024-02-03 * * Tests for core IPFS node functionality. * * Test Coverage: * - Node lifecycle (init/stop) * - Storage operations (memory/persistent) * - Network operations * - Data operations (add/get) * - Error handling */ Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const ipfsNode_1 = require("../ipfsNode"); const helia_1 = require("helia"); const sha2_1 = require("multiformats/hashes/sha2"); const multiformats_1 = require("multiformats"); // Mock helia and its dependencies vitest_1.vi.mock('helia', () => ({ createHelia: vitest_1.vi.fn() })); vitest_1.vi.mock('multiformats/hashes/sha2', () => ({ sha256: { digest: vitest_1.vi.fn(), code: 0x12 // Required for CID creation } })); (0, vitest_1.describe)('IpfsNode', () => { let node; let mockBlockstore; (0, vitest_1.beforeEach)(() => { // Reset all mocks vitest_1.vi.resetAllMocks(); // Create mock blockstore mockBlockstore = { put: vitest_1.vi.fn(), get: vitest_1.vi.fn(), has: vitest_1.vi.fn(), delete: vitest_1.vi.fn() }; // Create mock helia instance const mockCid = { toString: () => 'bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi', toV1: () => mockCid }; const pinnedCids = new Set(); const mockHelia = { blockstore: mockBlockstore, pins: { add: vitest_1.vi.fn().mockImplementation(async (cid) => { pinnedCids.add(cid); }), rm: vitest_1.vi.fn().mockImplementation(async (cid) => { pinnedCids.delete(cid); }), ls: vitest_1.vi.fn().mockImplementation(async function* () { for (const cid of pinnedCids) { yield cid; } }) }, stop: vitest_1.vi.fn() }; // Setup default mock implementations vitest_1.vi.mocked(helia_1.createHelia).mockResolvedValue(mockHelia); // Mock sha256 digest to return a valid hash vitest_1.vi.mocked(sha2_1.sha256.digest).mockResolvedValue({ code: sha2_1.sha256.code, size: 32, digest: new Uint8Array(32), bytes: new Uint8Array(32) }); // Mock CID behavior vitest_1.vi.spyOn(multiformats_1.CID, 'createV1').mockReturnValue(mockCid); vitest_1.vi.spyOn(multiformats_1.CID, 'parse').mockReturnValue(mockCid); node = new ipfsNode_1.IpfsNode({ storage: 'memory' }); }); (0, vitest_1.afterEach)(async () => { await node.stop(); }); (0, vitest_1.describe)('Initialization', () => { (0, vitest_1.it)('should initialize successfully', async () => { await node.init(); const peerId = await node.getPeerId(); (0, vitest_1.expect)(peerId).toBeDefined(); }); (0, vitest_1.it)('should handle initialization errors', async () => { vitest_1.vi.mocked(helia_1.createHelia).mockRejectedValueOnce(new Error('Failed to initialize')); const invalidNode = new ipfsNode_1.IpfsNode({ storage: 'memory' }); await (0, vitest_1.expect)(invalidNode.init()).rejects.toThrow('Failed to initialize'); }); }); (0, vitest_1.describe)('Data Operations', () => { (0, vitest_1.beforeEach)(async () => { await node.init(); }); (0, vitest_1.it)('should add and retrieve data', async () => { const data = new TextEncoder().encode('test data'); // Mock the blockstore operations mockBlockstore.put.mockResolvedValueOnce(undefined); mockBlockstore.get.mockResolvedValueOnce(data); const cid = await node.add(data); (0, vitest_1.expect)(cid).toBeDefined(); const retrieved = await node.get(cid); (0, vitest_1.expect)(retrieved).not.toBeNull(); if (retrieved) { (0, vitest_1.expect)(new TextDecoder().decode(retrieved)).toBe('test data'); } }); (0, vitest_1.it)('should handle non-existent CIDs', async () => { mockBlockstore.get.mockRejectedValueOnce(new Error('Not found')); const result = await node.get('bafkreiern4acpjlva5gookrtc534gr4nmuj7dy3qvcq5txgc6vqxe7wjqe'); (0, vitest_1.expect)(result).toBeNull(); }); }); (0, vitest_1.describe)('Pin Operations', () => { (0, vitest_1.beforeEach)(async () => { await node.init(); }); (0, vitest_1.it)('should pin and unpin content', async () => { const data = new TextEncoder().encode('test data'); // Mock the blockstore operations for add mockBlockstore.put.mockResolvedValueOnce(undefined); const cid = await node.add(data); // Mock pin operations mockBlockstore.has.mockResolvedValueOnce(true); await node.pin(cid); const pinnedCids = await node.getPinnedCids(); (0, vitest_1.expect)(pinnedCids).toContain(cid); await node.unpin(cid); const afterUnpinCids = await node.getPinnedCids(); (0, vitest_1.expect)(afterUnpinCids).not.toContain(cid); }); }); (0, vitest_1.describe)('Network Operations', () => { (0, vitest_1.it)('should handle offline mode', async () => { node = new ipfsNode_1.IpfsNode({ storage: 'memory', enableNetworking: false }); await node.init(); const addrs = node.getMultiaddrs(); (0, vitest_1.expect)(addrs).toHaveLength(0); }); (0, vitest_1.it)('should handle online mode', async () => { node = new ipfsNode_1.IpfsNode({ storage: 'memory', enableNetworking: true }); await node.init(); const addrs = node.getMultiaddrs(); (0, vitest_1.expect)(addrs.length).toBeGreaterThan(0); }); }); (0, vitest_1.describe)('Error Handling', () => { (0, vitest_1.it)('should handle operations before initialization', async () => { const data = new TextEncoder().encode('test data'); await (0, vitest_1.expect)(node.add(data)).rejects.toThrow('IPFS node not initialized'); }); (0, vitest_1.it)('should handle cleanup after stop', async () => { const node = new ipfsNode_1.IpfsNode({ storage: 'memory' }); // Setup mocks for initialization const mockHelia = { blockstore: mockBlockstore, pins: { add: vitest_1.vi.fn(), rm: vitest_1.vi.fn(), ls: vitest_1.vi.fn() }, stop: vitest_1.vi.fn(), libp2p: {}, datastore: {}, logger: console, routing: {}, start: vitest_1.vi.fn(), isStarted: vitest_1.vi.fn() }; // Type assertion needed for complex Helia type vitest_1.vi.mocked(helia_1.createHelia).mockResolvedValueOnce(mockHelia); // Initialize the node await node.init(); // Setup mock for successful add operation mockBlockstore.put.mockResolvedValueOnce(undefined); const mockDigest = new Uint8Array(32).fill(1); // Fill with some data instead of zeros vitest_1.vi.mocked(sha2_1.sha256.digest).mockResolvedValueOnce({ code: sha2_1.sha256.code, size: 32, digest: mockDigest, bytes: mockDigest }); // Mock CID behavior const mockCid = { toString: () => 'bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi', toV1: () => mockCid }; vitest_1.vi.spyOn(multiformats_1.CID, 'createV1').mockReturnValue(mockCid); vitest_1.vi.spyOn(multiformats_1.CID, 'parse').mockReturnValue(mockCid); // Add some data const data = new TextEncoder().encode('test data'); const cid = await node.add(data); // Stop the node await node.stop(); // Verify that operations after stop throw the correct error await (0, vitest_1.expect)(node.get(cid)).rejects.toThrow('IPFS node not initialized'); await (0, vitest_1.expect)(node.add(data)).rejects.toThrow('IPFS node not initialized'); await (0, vitest_1.expect)(node.pin(cid)).rejects.toThrow('IPFS node not initialized'); }); }); }); //# sourceMappingURL=ipfsNode.test.js.map