import { Test, TestingModule } from '@nestjs/testing'; import Database from 'better-sqlite3'; import path from 'path'; import { ConfigService } from './config.service'; // Mock better-sqlite3 jest.mock('better-sqlite3', () => { const mockDb = { exec: jest.fn(), prepare: jest.fn().mockReturnValue({ run: jest.fn().mockReturnValue({}), get: jest.fn(), all: jest.fn(), }), close: jest.fn(), }; return jest.fn(() => mockDb); }); describe('ConfigService', () => { let service: ConfigService; let mockDb: any; beforeEach(async () => { jest.clearAllMocks(); const module: TestingModule = await Test.createTestingModule({ providers: [ConfigService], }).compile(); service = module.get(ConfigService); mockDb = (Database as jest.MockedFunction).mock.results[0] ?.value; }); it('should be defined', () => { expect(service).toBeDefined(); }); describe('constructor', () => { it('should create database and table on initialization', () => { expect(Database).toHaveBeenCalledWith( path.resolve(__dirname, '../../../data', 'database.db'), ); expect(mockDb.exec).toHaveBeenCalledWith( expect.stringContaining('CREATE TABLE IF NOT EXISTS settings'), ); expect(mockDb.close).toHaveBeenCalled(); }); }); describe('getSettings', () => { beforeEach(() => { // Reset the mock for each test mockDb.prepare.mockClear(); mockDb.close.mockClear(); }); it('should return all settings when no key provided', () => { const mockAll = mockDb.prepare().all; mockAll.mockReturnValue([ { key: 'testKey', value: JSON.stringify('testValue') }, ]); const result = service.getSettings(); expect(mockDb.prepare).toHaveBeenCalledWith( 'SELECT key, value FROM settings', ); expect(result).toEqual({ testKey: 'testValue' }); expect(mockDb.close).toHaveBeenCalled(); }); it('should return specific setting when key provided', () => { const mockGet = mockDb.prepare().get; mockGet.mockReturnValue({ value: JSON.stringify('testValue') }); const result = service.getSettings('testKey'); expect(mockDb.prepare).toHaveBeenCalledWith( 'SELECT value FROM settings WHERE key = ?', ); expect(result).toEqual('testValue'); expect(mockDb.close).toHaveBeenCalled(); }); it('should return default value when key not found', () => { const mockGet = mockDb.prepare().get; mockGet.mockReturnValue(undefined); const result = service.getSettings('missingKey', 'defaultValue'); expect(result).toEqual('defaultValue'); expect(mockDb.close).toHaveBeenCalled(); }); }); describe('setSettings', () => { beforeEach(() => { mockDb.prepare.mockClear(); mockDb.close.mockClear(); }); it('should insert settings successfully', () => { const settings = { key1: 'value1', key2: 'value2' }; const result = service.setSettings(settings); expect(Database).toHaveBeenCalledTimes(2); // Constructor + setSettings expect(mockDb.prepare).toHaveBeenCalledWith( 'INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)', ); const mockRun = mockDb.prepare().run; expect(mockRun).toHaveBeenCalledTimes(2); expect(mockRun).toHaveBeenCalledWith('key1', JSON.stringify('value1')); expect(mockRun).toHaveBeenCalledWith('key2', JSON.stringify('value2')); expect(mockDb.close).toHaveBeenCalled(); expect(result).toBe(true); }); it('should return false on database error', () => { const settings = { key1: 'value1' }; const mockRun = mockDb.prepare().run; mockRun.mockImplementation(() => { throw new Error('Database error'); }); const result = service.setSettings(settings); expect(result).toBe(false); }); }); describe('deleteSetting', () => { beforeEach(() => { mockDb.prepare.mockClear(); mockDb.close.mockClear(); }); it('should delete setting successfully', () => { const mockRun = mockDb.prepare().run; mockRun.mockReturnValue({ changes: 1 }); const result = service.deleteSetting('testKey'); expect(mockDb.prepare).toHaveBeenCalledWith( 'DELETE FROM settings WHERE key = ?', ); expect(mockRun).toHaveBeenCalledWith('testKey'); expect(mockDb.close).toHaveBeenCalled(); expect(result).toBe(true); }); it('should return false on database error', () => { const mockRun = mockDb.prepare().run; mockRun.mockImplementation(() => { throw new Error('Database error'); }); const result = service.deleteSetting('testKey'); expect(result).toBe(false); }); }); });