/** * Shared test utilities for DashCaddy test suite */ const express = require('express'); /** * Create a mock credential manager */ function createMockCredentialManager() { return { store: jest.fn().mockResolvedValue(true), retrieve: jest.fn().mockResolvedValue(null), delete: jest.fn().mockResolvedValue(true), list: jest.fn().mockResolvedValue([]), getMetadata: jest.fn().mockResolvedValue(null), rotateEncryptionKey: jest.fn().mockResolvedValue(true), exportBackup: jest.fn().mockResolvedValue('encrypted-backup'), importBackup: jest.fn().mockResolvedValue(true), }; } /** * Create a mock crypto utils module */ function createMockCryptoUtils() { const fixedKey = Buffer.alloc(32, 'a'); return { encrypt: jest.fn(data => `mock-iv:mock-tag:${Buffer.from(String(data)).toString('base64')}`), decrypt: jest.fn(data => { const parts = data.split(':'); return Buffer.from(parts[2], 'base64').toString('utf8'); }), isEncrypted: jest.fn(data => typeof data === 'string' && data.split(':').length === 3), encryptFields: jest.fn((obj, fields) => ({ ...obj, _encrypted: true, _encryptedFields: fields })), decryptFields: jest.fn(obj => { const result = { ...obj }; delete result._encrypted; delete result._encryptedFields; return result; }), loadOrCreateKey: jest.fn(() => fixedKey), clearCachedKey: jest.fn(), rotateKey: jest.fn(() => ({ oldKey: fixedKey, newKey: Buffer.alloc(32, 'b') })), deriveKey: jest.fn().mockResolvedValue(fixedKey), decryptWithKey: jest.fn(data => { const parts = data.split(':'); return Buffer.from(parts[2], 'base64').toString('utf8'); }), readEncryptedFile: jest.fn().mockReturnValue(null), writeEncryptedFile: jest.fn(), migrateToEncrypted: jest.fn(obj => obj), }; } /** * Create a mock state manager */ function createMockStateManager() { let data = []; return { read: jest.fn().mockResolvedValue(data), write: jest.fn().mockResolvedValue(), update: jest.fn(async fn => { data = fn(data); return data; }), addItem: jest.fn().mockResolvedValue(), removeItem: jest.fn().mockResolvedValue(), updateItem: jest.fn().mockResolvedValue(), findItem: jest.fn().mockResolvedValue(null), _setData: (newData) => { data = newData; }, }; } /** * Create a mock logger */ function createMockLogger() { return { info: jest.fn(), warn: jest.fn(), error: jest.fn(), debug: jest.fn(), }; } /** * Build a minimal Express app for route testing with supertest */ function buildTestApp(routeFactory, deps, prefix = '/api') { const app = express(); app.use(express.json()); const router = routeFactory(deps); app.use(prefix, router); // Error handler const { errorMiddleware } = require('../../error-handler'); app.use(errorMiddleware); return app; } /** * Create mock Express req/res/next for middleware testing */ function createMockReqRes(overrides = {}) { const req = { method: 'GET', path: '/test', headers: {}, cookies: {}, ip: '127.0.0.1', protocol: 'https', secure: true, body: {}, params: {}, query: {}, get: jest.fn(header => req.headers[header.toLowerCase()]), ...overrides, }; const res = { status: jest.fn().mockReturnThis(), json: jest.fn().mockReturnThis(), send: jest.fn().mockReturnThis(), set: jest.fn().mockReturnThis(), cookie: jest.fn().mockReturnThis(), setHeader: jest.fn().mockReturnThis(), getHeader: jest.fn(), end: jest.fn(), }; const next = jest.fn(); return { req, res, next }; } module.exports = { createMockCredentialManager, createMockCryptoUtils, createMockStateManager, createMockLogger, buildTestApp, createMockReqRes, };