Files
adam-acs/tests/unit/domain/command.spec.ts
T
Kevin L'Hereec 31578e368f feat: estimated next connection + fix build errors
- 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
2026-06-02 17:56:17 +02:00

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)
})
})