Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions app/api/__tests__/safety.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,23 @@ it('e2e tests are only in test/e2e or test/visual', () => {
expect(file).toMatch(/^test\/(e2e|visual)/)
}
})

// 8-4-4-4-12 hex digits
const UUID_RE = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'

// RFC 4122: version nibble (3rd group, 1st char) is 1-5,
// variant nibble (4th group, 1st char) is 8, 9, a, or b
const VALID_UUID_RE =
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i

it('all UUIDs in mock-api files are valid RFC 4122', () => {
const output = execSync(`git grep -n -oP '${UUID_RE}' -- 'mock-api/'`).toString().trim()
const invalid = output.split('\n').filter((line) => {
const uuid = line.split(':').slice(2).join(':')
return !VALID_UUID_RE.test(uuid)
})
expect(
invalid,
`Invalid UUIDs found:\n${invalid.join('\n')}\n\nUse a reliable generator (e.g., uuidgen) to create valid v4 UUIDs.`
).toEqual([])
})
2 changes: 1 addition & 1 deletion mock-api/disk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ export const disks: Json<Disk>[] = [
read_only: false,
},
{
id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
id: 'a1b2c3d4-e5f6-4890-abcd-ef1234567890',
name: 'read-only-disk',
description: 'A read-only disk created from a snapshot',
project_id: project.id,
Expand Down
2 changes: 1 addition & 1 deletion mock-api/floating-ip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const floatingIp2: Json<FloatingIp> = {

// An IPv6 floating IP for testing IP version filtering (from ip-pool-2)
export const floatingIp3: Json<FloatingIp> = {
id: 'b1c2d3e4-5f6a-7b8c-9d0e-1f2a3b4c5d6e',
id: 'b1c2d3e4-5f6a-4b8c-9d0e-1f2a3b4c5d6e',
name: 'ipv6-float',
description: 'An IPv6 address.',
instance_id: undefined,
Expand Down
6 changes: 3 additions & 3 deletions mock-api/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const projectNoVpcs: DbProject = {

// Projects for test silos (different IP pool configurations)
export const projectKosman: DbProject = {
id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
id: 'a1b2c3d4-e5f6-4890-abcd-ef1234567890',
name: 'kosman-project',
description: 'project in myriad silo (v4-only default pool)',
time_created: new Date(2024, 0, 5).toISOString(),
Expand All @@ -65,7 +65,7 @@ export const projectKosman: DbProject = {
}

export const projectAnscombe: DbProject = {
id: 'b2c3d4e5-f6a7-8901-bcde-f12345678901',
id: 'b2c3d4e5-f6a7-4901-bcde-f12345678901',
name: 'anscombe-project',
description: 'project in thrax silo (v6-only default pool)',
time_created: new Date(2024, 0, 7).toISOString(),
Expand All @@ -74,7 +74,7 @@ export const projectAnscombe: DbProject = {
}

export const projectAdorno: DbProject = {
id: 'c3d4e5f6-a7b8-9012-cdef-123456789012',
id: '738c46df-35b1-44a2-ae1f-31005a0cbfee',
name: 'adorno-project',
description: 'project in pelerines silo (no default pools)',
time_created: new Date(2024, 0, 9).toISOString(),
Expand Down
10 changes: 5 additions & 5 deletions mock-api/silo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const silos: Json<Silo[]> = [
},
// Test silos for IP pool configuration scenarios
{
id: '7a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d',
id: '7a1b2c3d-4e5f-4a7b-8c9d-0e1f2a3b4c5d',
name: 'thrax',
description: 'silo with v6-only default pool',
time_created: new Date(2024, 0, 1).toISOString(),
Expand All @@ -55,7 +55,7 @@ export const silos: Json<Silo[]> = [
mapped_fleet_roles: {},
},
{
id: '8b2c3d4e-5f6a-7b8c-9d0e-1f2a3b4c5d6e',
id: '8b2c3d4e-5f6a-4b8c-9d0e-1f2a3b4c5d6e',
name: 'pelerines',
description: 'silo with no default pools',
time_created: new Date(2024, 0, 3).toISOString(),
Expand All @@ -65,7 +65,7 @@ export const silos: Json<Silo[]> = [
mapped_fleet_roles: {},
},
{
id: '9c3d4e5f-6a7b-7c9d-8e1f-2a3b4c5d6e7f',
id: '9c3d4e5f-6a7b-4c9d-8e1f-2a3b4c5d6e7f',
name: 'no-pools',
description: 'silo with no IP pools',
time_created: new Date(2024, 0, 11).toISOString(),
Expand Down Expand Up @@ -218,13 +218,13 @@ type DbScimToken = Json<ScimClientBearerToken> & { siloId: string }

export const scimTokens: DbScimToken[] = [
{
id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
id: 'a1b2c3d4-e5f6-4890-abcd-ef1234567890',
time_created: new Date(2025, 8, 15).toISOString(),
time_expires: null,
siloId: defaultSilo.id,
},
{
id: 'b2c3d4e5-f6a7-8901-bcde-f12345678901',
id: 'b2c3d4e5-f6a7-4901-bcde-f12345678901',
time_created: new Date(2025, 8, 20).toISOString(),
time_expires: null,
siloId: defaultSilo.id,
Expand Down
8 changes: 4 additions & 4 deletions mock-api/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,25 +48,25 @@ export const user6: Json<User> = {

// Users for test silos (different IP pool configurations)
export const userKosman: Json<User> = {
id: '9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d',
id: '9a8b7c6d-5e4f-4a2b-9c0d-9e8f7a6b5c4d',
display_name: 'Aryeh Kosman',
silo_id: myriadSilo.id,
}

export const userAnscombe: Json<User> = {
id: 'a9b8c7d6-e5f4-a3b2-c1d0-e9f8a7b6c5d4',
id: 'a9b8c7d6-e5f4-43b2-81d0-e9f8a7b6c5d4',
display_name: 'Elizabeth Anscombe',
silo_id: thraxSilo.id,
}

export const userAdorno: Json<User> = {
id: 'b0c9d8e7-f6a5-b4c3-d2e1-f0a9b8c7d6e5',
id: 'b0c9d8e7-f6a5-44c3-92e1-f0a9b8c7d6e5',
display_name: 'Theodor Adorno',
silo_id: pelerinesSilo.id,
}

export const userNoPools: Json<User> = {
id: 'c1d0e9f8-a7b6-c5d4-e3f2-a1b0c9d8e7f6',
id: 'c1d0e9f8-a7b6-45d4-a3f2-a1b0c9d8e7f6',
display_name: 'Antonio Gramsci',
silo_id: noPoolsSilo.id,
}
Expand Down
12 changes: 6 additions & 6 deletions mock-api/vpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const vpc2: Json<Vpc> = {

// VPCs for test silos (IP pool configuration testing)
export const vpcKosman: Json<Vpc> = {
id: 'd1e2f3a4-b5c6-7890-abcd-ef1234567890',
id: 'd1e2f3a4-b5c6-4890-abcd-ef1234567890',
name: 'kosman-vpc',
description: 'VPC in myriad silo',
dns_name: 'kosman-vpc',
Expand All @@ -57,7 +57,7 @@ export const vpcKosman: Json<Vpc> = {
}

export const vpcAnscombe: Json<Vpc> = {
id: 'e2f3a4b5-c6d7-8901-bcde-f12345678901',
id: 'e2f3a4b5-c6d7-4901-bcde-f12345678901',
name: 'anscombe-vpc',
description: 'VPC in thrax silo',
dns_name: 'anscombe-vpc',
Expand All @@ -69,7 +69,7 @@ export const vpcAnscombe: Json<Vpc> = {
}

export const vpcAdorno: Json<Vpc> = {
id: 'f3a4b5c6-d7e8-9012-cdef-123456789012',
id: 'f3a4b5c6-d7e8-4012-8def-123456789012',
name: 'adorno-vpc',
description: 'VPC in pelerines silo',
dns_name: 'adorno-vpc',
Expand Down Expand Up @@ -213,7 +213,7 @@ export const vpcSubnet2: Json<VpcSubnet> = {

// Subnets for test silos
export const subnetKosman: Json<VpcSubnet> = {
id: 'a1b2c3d4-e5f6-7890-1234-567890abcdef',
id: 'a1b2c3d4-e5f6-4890-9234-567890abcdef',
name: 'kosman-subnet',
description: 'subnet in myriad silo',
time_created,
Expand All @@ -224,7 +224,7 @@ export const subnetKosman: Json<VpcSubnet> = {
}

export const subnetAnscombe: Json<VpcSubnet> = {
id: 'b2c3d4e5-f6a7-8901-2345-67890abcdef1',
id: 'b2c3d4e5-f6a7-4901-a345-67890abcdef1',
name: 'anscombe-subnet',
description: 'subnet in thrax silo',
time_created,
Expand All @@ -235,7 +235,7 @@ export const subnetAnscombe: Json<VpcSubnet> = {
}

export const subnetAdorno: Json<VpcSubnet> = {
id: 'c3d4e5f6-a7b8-9012-3456-7890abcdef12',
id: 'c3d4e5f6-a7b8-4012-b456-7890abcdef12',
name: 'adorno-subnet',
description: 'subnet in pelerines silo',
time_created,
Expand Down
Loading