UNPKG

create-datadao

Version:

A CLI tool to generate and deploy DataDAOs on the Vana network

346 lines (288 loc) 12.4 kB
const { setupConfig } = require('../config'); const { createMockInquirer, createMockWallet } = require('../../__tests__/mocks/factories'); // Mock dependencies jest.mock('../wallet'); jest.mock('../validation'); jest.mock('inquirer'); jest.mock('chalk', () => ({ blue: jest.fn((text) => text), yellow: jest.fn((text) => text), cyan: jest.fn((text) => text), green: jest.fn((text) => text), red: jest.fn((text) => text), })); const { deriveWalletFromPrivateKey } = require('../wallet'); const { validatePrivateKey, normalizePrivateKey } = require('../validation'); const inquirer = require('inquirer'); describe('Config Functions', () => { let originalConsoleLog; beforeAll(() => { originalConsoleLog = console.log; console.log = jest.fn(); }); afterAll(() => { console.log = originalConsoleLog; }); beforeEach(() => { jest.clearAllMocks(); // Setup default mocks validatePrivateKey.mockReturnValue(true); normalizePrivateKey.mockImplementation((key) => key.startsWith('0x') ? key : '0x' + key); deriveWalletFromPrivateKey.mockReturnValue(createMockWallet()); }); describe('setupConfig', () => { test('collects complete configuration successfully', async () => { const mockResponses = { dlpName: 'TestDAO', tokenName: 'TestToken', tokenSymbol: 'TEST', privateKey: '0x1234567890123456789012345678901234567890123456789012345678901234', pinataApiKey: 'test-pinata-key', pinataApiSecret: 'test-pinata-secret', googleClientId: 'test-client-id', googleClientSecret: 'test-client-secret', githubUsername: 'test-user' }; inquirer.prompt.mockImplementation((questions) => { const answers = {}; for (const question of Array.isArray(questions) ? questions : [questions]) { answers[question.name] = mockResponses[question.name] || question.default || ''; } return Promise.resolve(answers); }); const mockWallet = createMockWallet(); deriveWalletFromPrivateKey.mockReturnValue(mockWallet); const result = await setupConfig(); expect(result).toEqual({ dlpName: 'TestDAO', tokenName: 'TestToken', tokenSymbol: 'TEST', privateKey: '0x1234567890123456789012345678901234567890123456789012345678901234', address: mockWallet.address, publicKey: mockWallet.publicKey, pinataApiKey: 'test-pinata-key', pinataApiSecret: 'test-pinata-secret', googleClientId: 'test-client-id', googleClientSecret: 'test-client-secret', githubUsername: 'test-user', network: 'moksha', rpcUrl: 'https://rpc.moksha.vana.org', chainId: 14800 }); expect(normalizePrivateKey).toHaveBeenCalledWith(mockResponses.privateKey); expect(deriveWalletFromPrivateKey).toHaveBeenCalledWith(mockResponses.privateKey); }); test('uses default values when no input provided', async () => { inquirer.prompt.mockImplementation((questions) => { const answers = {}; for (const question of Array.isArray(questions) ? questions : [questions]) { answers[question.name] = question.default || ''; } return Promise.resolve(answers); }); const mockWallet = createMockWallet(); deriveWalletFromPrivateKey.mockReturnValue(mockWallet); const result = await setupConfig(); expect(result.dlpName).toBe('MyDataDAO'); expect(result.tokenName).toBe('MyDataToken'); expect(result.tokenSymbol).toBe('MDT'); expect(result.network).toBe('moksha'); expect(result.rpcUrl).toBe('https://rpc.moksha.vana.org'); expect(result.chainId).toBe(14800); }); test('normalizes private key during collection', async () => { const privateKeyWithoutPrefix = '1234567890123456789012345678901234567890123456789012345678901234'; const privateKeyWithPrefix = '0x1234567890123456789012345678901234567890123456789012345678901234'; inquirer.prompt.mockImplementation((questions) => { const answers = {}; for (const question of Array.isArray(questions) ? questions : [questions]) { if (question.name === 'privateKey') { answers[question.name] = privateKeyWithoutPrefix; } else { answers[question.name] = question.default || ''; } } return Promise.resolve(answers); }); normalizePrivateKey.mockReturnValue(privateKeyWithPrefix); deriveWalletFromPrivateKey.mockReturnValue(createMockWallet()); const result = await setupConfig(); expect(normalizePrivateKey).toHaveBeenCalledWith(privateKeyWithoutPrefix); expect(deriveWalletFromPrivateKey).toHaveBeenCalledWith(privateKeyWithPrefix); expect(result.privateKey).toBe(privateKeyWithPrefix); }); test('validates private key input', async () => { // First call should fail validation, second should pass let callCount = 0; validatePrivateKey .mockImplementationOnce(() => 'Invalid private key format') .mockImplementationOnce(() => true); inquirer.prompt.mockImplementation((questions) => { const questionsArray = Array.isArray(questions) ? questions : [questions]; const privateKeyQuestion = questionsArray.find(q => q.name === 'privateKey'); if (privateKeyQuestion && privateKeyQuestion.validate) { // Test the validation function const firstResult = privateKeyQuestion.validate('invalid-key'); expect(firstResult).toBe('Invalid private key format'); const secondResult = privateKeyQuestion.validate('0x1234567890123456789012345678901234567890123456789012345678901234'); expect(secondResult).toBe(true); } // Return answers for all questions const answers = {}; for (const q of questionsArray) { if (q.name === 'privateKey') { answers[q.name] = '0x1234567890123456789012345678901234567890123456789012345678901234'; } else { answers[q.name] = q.default || ''; } } return Promise.resolve(answers); }); deriveWalletFromPrivateKey.mockReturnValue(createMockWallet()); await setupConfig(); expect(validatePrivateKey).toHaveBeenCalledWith('invalid-key'); expect(validatePrivateKey).toHaveBeenCalledWith('0x1234567890123456789012345678901234567890123456789012345678901234'); }); test('handles wallet derivation errors gracefully', async () => { inquirer.prompt.mockResolvedValue({ dlpName: 'TestDAO', tokenName: 'TestToken', tokenSymbol: 'TEST', privateKey: '0x1234567890123456789012345678901234567890123456789012345678901234', pinataApiKey: '', pinataApiSecret: '', googleClientId: '', googleClientSecret: '', githubUsername: 'test-user' }); deriveWalletFromPrivateKey.mockImplementation(() => { throw new Error('Failed to derive wallet'); }); await expect(setupConfig()).rejects.toThrow('Failed to derive wallet'); }); test('includes all required configuration sections', async () => { inquirer.prompt.mockImplementation((questions) => { // Verify we're prompted for all sections const questionNames = Array.isArray(questions) ? questions.map(q => q.name) : [questions.name]; return Promise.resolve( questionNames.reduce((acc, name) => { acc[name] = `test-${name}`; return acc; }, {}) ); }); deriveWalletFromPrivateKey.mockReturnValue(createMockWallet()); const result = await setupConfig(); // Verify all required sections are present expect(result).toHaveProperty('dlpName'); expect(result).toHaveProperty('tokenName'); expect(result).toHaveProperty('tokenSymbol'); expect(result).toHaveProperty('privateKey'); expect(result).toHaveProperty('address'); expect(result).toHaveProperty('publicKey'); expect(result).toHaveProperty('pinataApiKey'); expect(result).toHaveProperty('pinataApiSecret'); expect(result).toHaveProperty('googleClientId'); expect(result).toHaveProperty('googleClientSecret'); expect(result).toHaveProperty('githubUsername'); expect(result).toHaveProperty('network'); expect(result).toHaveProperty('rpcUrl'); expect(result).toHaveProperty('chainId'); }); test.skip('displays correct console messages', async () => { // TODO: Fix chalk mock to work with console.log assertions inquirer.prompt.mockResolvedValue({ dlpName: 'TestDAO', tokenName: 'TestToken', tokenSymbol: 'TEST', privateKey: '0x1234567890123456789012345678901234567890123456789012345678901234', pinataApiKey: '', pinataApiSecret: '', googleClientId: '', googleClientSecret: '', githubUsername: 'test-user' }); deriveWalletFromPrivateKey.mockReturnValue(createMockWallet()); await setupConfig(); // Debug: see what console.log was actually called with console.log.mock.calls.forEach((call, index) => { console.error(`Call ${index}:`, call); }); // Verify console.log was called with expected messages expect(console.log).toHaveBeenCalledWith( expect.stringContaining('Please provide the following information') ); expect(console.log).toHaveBeenCalledWith( expect.stringContaining('Wallet Configuration:') ); expect(console.log).toHaveBeenCalledWith( expect.stringContaining('External Services:') ); expect(console.log).toHaveBeenCalledWith( expect.stringContaining('GitHub Integration:') ); }); test('handles empty optional fields', async () => { inquirer.prompt.mockResolvedValue({ dlpName: 'TestDAO', tokenName: 'TestToken', tokenSymbol: 'TEST', privateKey: '0x1234567890123456789012345678901234567890123456789012345678901234', pinataApiKey: '', pinataApiSecret: '', googleClientId: '', googleClientSecret: '', githubUsername: 'test-user' }); deriveWalletFromPrivateKey.mockReturnValue(createMockWallet()); const result = await setupConfig(); expect(result.pinataApiKey).toBe(''); expect(result.pinataApiSecret).toBe(''); expect(result.googleClientId).toBe(''); expect(result.googleClientSecret).toBe(''); }); test('validates GitHub username is required', async () => { let githubQuestion = null; inquirer.prompt.mockImplementation((questions) => { const questionsArray = Array.isArray(questions) ? questions : [questions]; const githubQ = questionsArray.find(q => q.name === 'githubUsername'); if (githubQ) { githubQuestion = githubQ; // Test validation expect(githubQ.validate('')).toBe('GitHub username is required'); expect(githubQ.validate('test-user')).toBe(true); } return Promise.resolve( questionsArray.reduce((acc, q) => { acc[q.name] = q.name === 'githubUsername' ? 'test-user' : (q.default || ''); return acc; }, {}) ); }); deriveWalletFromPrivateKey.mockReturnValue(createMockWallet()); await setupConfig(); expect(githubQuestion).toBeTruthy(); expect(githubQuestion.validate).toBeDefined(); }); test('includes network configuration', async () => { inquirer.prompt.mockResolvedValue({ dlpName: 'TestDAO', tokenName: 'TestToken', tokenSymbol: 'TEST', privateKey: '0x1234567890123456789012345678901234567890123456789012345678901234', pinataApiKey: '', pinataApiSecret: '', googleClientId: '', googleClientSecret: '', githubUsername: 'test-user' }); deriveWalletFromPrivateKey.mockReturnValue(createMockWallet()); const result = await setupConfig(); expect(result.network).toBe('moksha'); expect(result.rpcUrl).toBe('https://rpc.moksha.vana.org'); expect(result.chainId).toBe(14800); }); }); });