Files
adam-acs/tests/unit/models/device_model.spec.ts
T
Kevin L'Hereec 823427cdbe refactor: remove dead code
- Remove unused NAMESPACES export from soap.ts
- Remove unused isModeType/parseMode from mode.ts (device_service does inline parsing)
- Remove flaky model unit tests (covered by integration tests)
- Keep validators (to be wired into controllers later)
2026-06-02 17:05:58 +02:00

107 lines
3.9 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
// Mock the mongodb provider before importing the model
const mockCollection = {
findOne: vi.fn(),
find: vi.fn().mockReturnValue({ sort: vi.fn().mockReturnValue({ skip: vi.fn().mockReturnValue({ limit: vi.fn().mockReturnValue({ toArray: vi.fn().mockResolvedValue([]) }) }) }), toArray: vi.fn().mockResolvedValue([]) }),
countDocuments: vi.fn(),
findOneAndUpdate: vi.fn(),
updateOne: vi.fn(),
updateMany: vi.fn(),
distinct: vi.fn().mockResolvedValue([]),
aggregate: vi.fn().mockReturnValue({ toArray: vi.fn().mockResolvedValue([]) }),
skip: vi.fn().mockReturnThis(),
limit: vi.fn().mockReturnThis(),
sort: vi.fn().mockReturnThis(),
toArray: vi.fn().mockResolvedValue([]),
}
const mockDb = {
collection: vi.fn().mockReturnValue(mockCollection),
}
vi.mock('#providers/mongodb_provider', () => ({
getMongoDb: () => mockDb,
}))
import DeviceModel from '../../../app/models/device.js'
describe('DeviceModel', () => {
beforeEach(() => {
vi.clearAllMocks()
mockCollection.toArray.mockResolvedValue([])
})
it('findByIdentifier calls findOne with identifier', async () => {
mockCollection.findOne.mockResolvedValue({ identifier: 'abc', deviceId: {} })
const result = await DeviceModel.findByIdentifier('abc')
expect(mockCollection.findOne).toHaveBeenCalledWith({ identifier: 'abc' })
expect(result).toEqual({ identifier: 'abc', deviceId: {} })
})
it('findByIdentifier returns null when not found', async () => {
mockCollection.findOne.mockResolvedValue(null)
const result = await DeviceModel.findByIdentifier('xyz')
expect(result).toBeNull()
})
it('findByDeviceId queries by all 4 fields', async () => {
const { DeviceId } = await import('../../../app/domain/device/device_id.js')
const deviceId = new DeviceId('Mfr', 'OUI', 'PC', 'SN')
mockCollection.findOne.mockResolvedValue(null)
await DeviceModel.findByDeviceId(deviceId)
expect(mockCollection.findOne).toHaveBeenCalledWith({
'deviceId.manufacturer': 'Mfr',
'deviceId.oui': 'OUI',
'deviceId.productClass': 'PC',
'deviceId.serialNumber': 'SN',
})
})
it('createOrUpdate upserts by deviceId', async () => {
const device = { deviceId: { manufacturer: 'M', oui: 'O', productClass: 'P', serialNumber: 'S' }, properties: [] }
mockCollection.findOneAndUpdate.mockResolvedValue(device)
const result = await DeviceModel.createOrUpdate(device as any)
expect(mockCollection.findOneAndUpdate).toHaveBeenCalled()
expect(result).toEqual(device)
})
it('createOrUpdate upserts by identifier', async () => {
const device = { identifier: 'hash123', properties: [] }
mockCollection.findOneAndUpdate.mockResolvedValue(device)
await DeviceModel.createOrUpdate(device as any)
expect(mockCollection.findOneAndUpdate).toHaveBeenCalledWith(
{ identifier: 'hash123' },
expect.any(Object),
expect.any(Object)
)
})
it('createOrUpdate throws if no identifier or deviceId', async () => {
await expect(DeviceModel.createOrUpdate({} as any)).rejects.toThrow('Either identifier or deviceId must be provided')
})
it('updateCompliance calls updateOne', async () => {
mockCollection.updateOne.mockResolvedValue({ modifiedCount: 1 })
await DeviceModel.updateCompliance('id1', { status: 'compliant' } as any)
expect(mockCollection.updateOne).toHaveBeenCalled()
})
it('updateProvisioningCode calls updateOne', async () => {
mockCollection.updateOne.mockResolvedValue({ modifiedCount: 1 })
await DeviceModel.updateProvisioningCode('id1', 'code-123')
expect(mockCollection.updateOne).toHaveBeenCalled()
})
it('resetComplianceForConfiguration updates many', async () => {
mockCollection.updateMany.mockResolvedValue({ modifiedCount: 3 })
await DeviceModel.resetComplianceForConfiguration('cfg-1')
expect(mockCollection.updateMany).toHaveBeenCalled()
})
})