Files
adam-acs/tests/unit/utils/provisioning_code.spec.ts
T
Kevin L'HereecandCopilot d1c65dbf1e chore: initial commit — AdonisJS v7 TR-069 ACS
- Docker infrastructure (Dockerfile, docker-compose.yml, genieacs-sim)
- AdonisJS v7 app with Inertia.js + Vue 3
- MongoDB integration
- CWMP/TR-069 state machine engine
- Configuration engine with compliance tracking
- Branding: ADAM ACS (favicon, navbar, locales)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-29 16:46:37 +02:00

120 lines
3.8 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import {
computeContentHash,
buildProvisioningCode,
parseProvisioningCode,
} from '../../../app/utils/provisioning_code.js'
import type { Configuration } from '../../../app/domain/configuration/configuration.js'
import { PolicyType } from '../../../app/domain/configuration/configuration.js'
function makeConfig(overrides: Partial<Configuration> = {}): Configuration {
return {
identifier: 'BM632w-standard',
name: 'Configuration standard BM632w',
version: '1.0.1',
priority: 100,
policy: PolicyType.ONCE,
enabled: true,
tags: [],
criteria: { productClass: 'BM632w' },
inventory: [],
desiredParameters: [
{ name: 'Device.Param.B', value: 'hello', type: 'string' },
{ name: 'Device.Param.A', value: 42, type: 'int' },
],
firmwareTarget: { productClass: 'BM632w', targetVersion: '2.1.0' },
createdAt: new Date(),
updatedAt: new Date(),
...overrides,
}
}
describe('computeContentHash', () => {
it('returns a 12-character hex string', () => {
const hash = computeContentHash(makeConfig())
expect(hash).toMatch(/^[a-f0-9]{12}$/)
})
it('is deterministic for the same config', () => {
const config = makeConfig()
expect(computeContentHash(config)).toBe(computeContentHash(config))
})
it('sorts desiredParameters by name for consistency', () => {
const config1 = makeConfig({
desiredParameters: [
{ name: 'B.Param', value: 1, type: 'int' },
{ name: 'A.Param', value: 2, type: 'int' },
],
})
const config2 = makeConfig({
desiredParameters: [
{ name: 'A.Param', value: 2, type: 'int' },
{ name: 'B.Param', value: 1, type: 'int' },
],
})
expect(computeContentHash(config1)).toBe(computeContentHash(config2))
})
it('changes when desiredParameters change', () => {
const config1 = makeConfig({
desiredParameters: [{ name: 'A.Param', value: 1, type: 'int' }],
})
const config2 = makeConfig({
desiredParameters: [{ name: 'A.Param', value: 2, type: 'int' }],
})
expect(computeContentHash(config1)).not.toBe(computeContentHash(config2))
})
it('changes when firmwareTarget changes', () => {
const config1 = makeConfig({
firmwareTarget: { productClass: 'BM632w', targetVersion: '2.0.0' },
})
const config2 = makeConfig({
firmwareTarget: { productClass: 'BM632w', targetVersion: '3.0.0' },
})
expect(computeContentHash(config1)).not.toBe(computeContentHash(config2))
})
})
describe('buildProvisioningCode', () => {
it('returns the correct format', () => {
const config = makeConfig()
const code = buildProvisioningCode(config)
expect(code).toMatch(/^BM632w-standard\(v1\.0\.1\)-[a-f0-9]{12}$/)
})
it('matches the regex pattern from the spec', () => {
const config = makeConfig()
const code = buildProvisioningCode(config)
expect(code).toMatch(/^(.+)\(v(.+)\)-([a-f0-9]{12})$/)
})
})
describe('parseProvisioningCode', () => {
it('parses a valid provisioning code', () => {
const result = parseProvisioningCode('BM632w-standard(v1.0.1)-a1b2c3d4e5f6')
expect(result).toEqual({
identifier: 'BM632w-standard',
version: '1.0.1',
hash: 'a1b2c3d4e5f6',
})
})
it('returns null for invalid format', () => {
expect(parseProvisioningCode('invalid')).toBeNull()
expect(parseProvisioningCode('')).toBeNull()
expect(parseProvisioningCode('id(v1.0)-short')).toBeNull() // hash too short
})
it('round-trips with buildProvisioningCode', () => {
const config = makeConfig()
const code = buildProvisioningCode(config)
const parsed = parseProvisioningCode(code)
expect(parsed).not.toBeNull()
expect(parsed!.identifier).toBe('BM632w-standard')
expect(parsed!.version).toBe('1.0.1')
expect(parsed!.hash).toMatch(/^[a-f0-9]{12}$/)
})
})