- Domain: DeviceId, Command, DeviceParameter, DeviceProperty, Mode - Protocol: SOAP parsing, CWMPMessageBuilder (all methods) - References: config_loader, WassupProvider (timeout, errors) - Integration: MongoDB tests (CRUD, pagination, references) - Fix: Home.vue IP lookup for Device.WANDevice path - Total: 384 tests passing
96 lines
3.0 KiB
TypeScript
96 lines
3.0 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 })
|
|
expect(cmd.status).toBe(CommandStatus.COMPLETED)
|
|
expect(cmd.result).toEqual({ success: true })
|
|
expect(cmd.isCompleted()).toBe(true)
|
|
})
|
|
|
|
it('complete throws if PENDING', () => {
|
|
const cmd = makeCommand()
|
|
expect(() => cmd.complete({})).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({})
|
|
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({})
|
|
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)
|
|
})
|
|
})
|