- 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)
107 lines
3.9 KiB
TypeScript
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()
|
|
})
|
|
})
|