import { beforeEach, describe, expect, it, vi } from 'vitest' import ConfigurationEngine from '../../../app/services/configuration_engine.js' vi.mock('#models/configuration', () => ({ default: { findOne: vi.fn(), findAllEnabled: vi.fn() }, })) vi.mock('#models/device', () => ({ default: { getCollection: vi.fn(), findOne: vi.fn() }, })) import ConfigurationModel from '#models/configuration' import DeviceModel from '#models/device' describe('ConfigurationEngine', () => { let engine: ConfigurationEngine beforeEach(() => { engine = new ConfigurationEngine() vi.clearAllMocks() }) describe('complianceReport', () => { it('throws when configuration is not found', async () => { vi.mocked(ConfigurationModel.findOne).mockResolvedValue(null as any) await expect(engine.complianceReport('missing-config')).rejects.toThrow( 'Configuration missing-config not found' ) }) it('returns an empty report when no devices match', async () => { vi.mocked(ConfigurationModel.findOne).mockResolvedValue({ identifier: 'config-1', name: 'Config 1', criteria: {}, inventory: [], desiredParameters: [], policy: 'maintain', } as any) vi.mocked(DeviceModel.getCollection).mockReturnValue({ find: () => ({ toArray: async () => [] }), } as any) const report = await engine.complianceReport('config-1') expect(report).toMatchObject({ configurationId: 'config-1', configurationName: 'Config 1', totalDevices: 0, compliantCount: 0, nonCompliantCount: 0, devices: [], }) }) it('counts compliant and non-compliant devices', async () => { const config = { identifier: 'config-1', name: 'Config 1', criteria: {}, inventory: [], desiredParameters: [], policy: 'maintain', } const devices = [ { identifier: 'device-1', deviceId: { serialNumber: 'SN1' } }, { identifier: 'device-2', deviceId: { serialNumber: 'SN2' } }, ] vi.mocked(ConfigurationModel.findOne).mockResolvedValue(config as any) vi.mocked(DeviceModel.getCollection).mockReturnValue({ find: () => ({ toArray: async () => devices }), } as any) vi.spyOn(engine, 'evaluateSpecific') .mockResolvedValueOnce({ configuration: config as any, inventoryPaths: [], parameterDiffs: [], firmwareMigrationPath: [], isAlreadyCompliant: true, skipFirmware: false, }) .mockResolvedValueOnce({ configuration: config as any, inventoryPaths: [], parameterDiffs: [ { name: 'Device.ManagementServer.URL', currentValue: 'http://old', targetValue: 'http://acs', type: 'string', }, ], firmwareMigrationPath: [], isAlreadyCompliant: false, skipFirmware: false, }) const report = await engine.complianceReport('config-1') expect(report.totalDevices).toBe(2) expect(report.compliantCount).toBe(1) expect(report.nonCompliantCount).toBe(1) expect(report.devices.map((device) => device.compliant)).toEqual([true, false]) }) it('skips null parameterCriteria names when matching devices', async () => { const config = { identifier: 'config-1', name: 'Config 1', criteria: { parameterCriteria: [{ name: null as any, value: 'x' }] }, inventory: [], desiredParameters: [], policy: 'maintain', } const device = { identifier: 'device-1', deviceId: { serialNumber: 'SN1' } } vi.mocked(ConfigurationModel.findOne).mockResolvedValue(config as any) vi.mocked(DeviceModel.getCollection).mockReturnValue({ find: () => ({ toArray: async () => [device] }), } as any) vi.spyOn(engine, 'evaluateSpecific').mockResolvedValue({ configuration: config as any, inventoryPaths: [], parameterDiffs: [], firmwareMigrationPath: [], isAlreadyCompliant: true, skipFirmware: false, }) const report = await engine.complianceReport('config-1') expect(report.totalDevices).toBe(1) expect(report.compliantCount).toBe(1) expect(engine.evaluateSpecific).toHaveBeenCalledWith(device, config) }) }) describe('evaluateSpecific', () => { it('falls back to plain object parameters when getParameter is unavailable', async () => { const device = { identifier: 'device-1', deviceId: { serialNumber: 'SN1' }, parameters: [ { name: 'Device.ManagementServer.URL', value: 'http://acs', }, ], } const config = { identifier: 'config-1', name: 'Config 1', version: '1.0.0', priority: 100, policy: 'maintain', enabled: true, tags: [], criteria: {}, inventory: [], desiredParameters: [ { name: 'Device.ManagementServer.URL', value: 'http://acs', type: 'string', }, ], } const result = await engine.evaluateSpecific(device as any, config as any) expect(result.isAlreadyCompliant).toBe(true) expect(result.parameterDiffs).toEqual([]) }) }) })