- Store lastPeriodicInformAt on device when PERIODIC Inform received - Display 'Prochaine connexion' in DeviceDetail identity card - Fix tsconfig exclude (tests, inertia, coverage) for Docker build - Fix TS errors in tests (CommandResult type, unused imports) - Fix distinctCriteriaValues typing in controller
96 lines
3.2 KiB
TypeScript
96 lines
3.2 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { Command, CommandStatus, CommandType, Priority } from '../../../app/domain/commands/command.js'
|
|
import { DeviceId } from '../../../app/domain/device/device_id.js'
|
|
|
|
function makeCommand(status = CommandStatus.PENDING) {
|
|
return new Command('cmd-1', new DeviceId('Mfr', 'OUI', 'PC', 'SN'), CommandType.REFRESH, {}, Priority.NORMAL, new Date(), status)
|
|
}
|
|
|
|
describe('Command', () => {
|
|
it('creates with PENDING status by default', () => {
|
|
const cmd = makeCommand()
|
|
expect(cmd.status).toBe(CommandStatus.PENDING)
|
|
expect(cmd.canExecute()).toBe(true)
|
|
expect(cmd.isCompleted()).toBe(false)
|
|
})
|
|
|
|
it('markAsSent transitions PENDING → SENT', () => {
|
|
const cmd = makeCommand()
|
|
cmd.markAsSent()
|
|
expect(cmd.status).toBe(CommandStatus.SENT)
|
|
expect(cmd.executedAt).not.toBeNull()
|
|
})
|
|
|
|
it('markAsSent throws if not PENDING', () => {
|
|
const cmd = makeCommand(CommandStatus.SENT)
|
|
expect(() => cmd.markAsSent()).toThrow('Cannot mark command as sent')
|
|
})
|
|
|
|
it('markAsWaiting transitions SENT → WAITING', () => {
|
|
const cmd = makeCommand()
|
|
cmd.markAsSent()
|
|
cmd.markAsWaiting()
|
|
expect(cmd.status).toBe(CommandStatus.WAITING)
|
|
})
|
|
|
|
it('markAsWaiting throws if not SENT', () => {
|
|
const cmd = makeCommand()
|
|
expect(() => cmd.markAsWaiting()).toThrow('Cannot mark command as waiting')
|
|
})
|
|
|
|
it('complete transitions SENT → COMPLETED', () => {
|
|
const cmd = makeCommand()
|
|
cmd.markAsSent()
|
|
cmd.complete({ success: true, timestamp: new Date() })
|
|
expect(cmd.status).toBe(CommandStatus.COMPLETED)
|
|
expect(cmd.result?.success).toBe(true)
|
|
expect(cmd.isCompleted()).toBe(true)
|
|
})
|
|
|
|
it('complete throws if PENDING', () => {
|
|
const cmd = makeCommand()
|
|
expect(() => cmd.complete({ success: true, timestamp: new Date() } as any)).toThrow('Cannot complete command')
|
|
})
|
|
|
|
it('fail transitions to FAILED', () => {
|
|
const cmd = makeCommand()
|
|
cmd.markAsSent()
|
|
cmd.fail('timeout')
|
|
expect(cmd.status).toBe(CommandStatus.FAILED)
|
|
expect(cmd.error).toBe('timeout')
|
|
expect(cmd.isCompleted()).toBe(true)
|
|
})
|
|
|
|
it('fail throws if already COMPLETED', () => {
|
|
const cmd = makeCommand()
|
|
cmd.markAsSent()
|
|
cmd.complete({ success: true, timestamp: new Date() } as any)
|
|
expect(() => cmd.fail('oops')).toThrow('Cannot fail a successful command')
|
|
})
|
|
|
|
it('cancel transitions PENDING → CANCELLED', () => {
|
|
const cmd = makeCommand()
|
|
cmd.cancel()
|
|
expect(cmd.status).toBe(CommandStatus.CANCELLED)
|
|
expect(cmd.isCompleted()).toBe(true)
|
|
})
|
|
|
|
it('cancel throws if COMPLETED', () => {
|
|
const cmd = makeCommand()
|
|
cmd.markAsSent()
|
|
cmd.complete({ success: true, timestamp: new Date() } as any)
|
|
expect(() => cmd.cancel()).toThrow('Cannot cancel command')
|
|
})
|
|
|
|
it('hasExpired returns true for old commands', () => {
|
|
const old = new Date(Date.now() - 60 * 60 * 1000) // 1h ago
|
|
const cmd = new Command('x', new DeviceId('M', 'O', 'P', 'S'), CommandType.REFRESH, {}, Priority.NORMAL, old)
|
|
expect(cmd.hasExpired(30)).toBe(true)
|
|
})
|
|
|
|
it('hasExpired returns false for fresh commands', () => {
|
|
const cmd = makeCommand()
|
|
expect(cmd.hasExpired(30)).toBe(false)
|
|
})
|
|
})
|