Files
attest/__tests__/unit/predicate.test.ts
Brian DeHamer 19ad753d23 test suite re-write (#356)
Signed-off-by: Brian DeHamer <bdehamer@github.com>
2026-02-19 10:14:47 -08:00

143 lines
4.2 KiB
TypeScript

import fs from 'fs/promises'
import os from 'os'
import path from 'path'
import { predicateFromInputs, PredicateInputs } from '../../src/predicate'
describe('predicateFromInputs', () => {
const blankInputs: PredicateInputs = {
predicateType: '',
predicate: '',
predicatePath: ''
}
let tempDir: string
beforeEach(async () => {
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'predicate-test-'))
})
afterEach(async () => {
await fs.rm(tempDir, { recursive: true, force: true })
})
describe('input validation', () => {
it('should throw when predicate-type is not provided', async () => {
await expect(predicateFromInputs(blankInputs)).rejects.toThrow(
/predicate-type must be provided/
)
})
it('should throw when neither predicate nor predicate-path is provided', async () => {
const inputs: PredicateInputs = {
...blankInputs,
predicateType: 'https://example.com/predicate'
}
await expect(predicateFromInputs(inputs)).rejects.toThrow(
/one of predicate-path or predicate must be provided/i
)
})
it('should throw when both predicate and predicate-path are provided', async () => {
const inputs: PredicateInputs = {
predicateType: 'https://example.com/predicate',
predicate: '{}',
predicatePath: '/path/to/predicate.json'
}
await expect(predicateFromInputs(inputs)).rejects.toThrow(
/only one of predicate-path or predicate may be provided/i
)
})
})
describe('with predicate string', () => {
it('should parse and return the predicate', async () => {
const predicateType = 'https://example.com/predicate'
const predicateContent = { foo: 'bar', nested: { value: 123 } }
const inputs: PredicateInputs = {
...blankInputs,
predicateType,
predicate: JSON.stringify(predicateContent)
}
const result = await predicateFromInputs(inputs)
expect(result).toEqual({
type: predicateType,
params: predicateContent
})
})
it('should throw when predicate string exceeds max size', async () => {
const predicateType = 'https://example.com/predicate'
const largeContent = JSON.stringify({ data: 'x'.repeat(16 * 1024 * 1024) })
const inputs: PredicateInputs = {
...blankInputs,
predicateType,
predicate: largeContent
}
await expect(predicateFromInputs(inputs)).rejects.toThrow(
/predicate string exceeds maximum/
)
})
it('should throw when predicate is invalid JSON', async () => {
const inputs: PredicateInputs = {
...blankInputs,
predicateType: 'https://example.com/predicate',
predicate: 'not valid json'
}
await expect(predicateFromInputs(inputs)).rejects.toThrow(/JSON/)
})
})
describe('with predicate path', () => {
it('should read and parse predicate from file', async () => {
const predicateType = 'https://example.com/predicate'
const predicateContent = { buildType: 'test', metadata: { version: '1.0' } }
const filePath = path.join(tempDir, 'predicate.json')
await fs.writeFile(filePath, JSON.stringify(predicateContent))
const inputs: PredicateInputs = {
...blankInputs,
predicateType,
predicatePath: filePath
}
const result = await predicateFromInputs(inputs)
expect(result).toEqual({
type: predicateType,
params: predicateContent
})
})
it('should throw when predicate file does not exist', async () => {
const inputs: PredicateInputs = {
...blankInputs,
predicateType: 'https://example.com/predicate',
predicatePath: '/nonexistent/file.json'
}
await expect(predicateFromInputs(inputs)).rejects.toThrow(/file not found/)
})
it('should throw when predicate file contains invalid JSON', async () => {
const filePath = path.join(tempDir, 'invalid.json')
await fs.writeFile(filePath, 'not valid json')
const inputs: PredicateInputs = {
...blankInputs,
predicateType: 'https://example.com/predicate',
predicatePath: filePath
}
await expect(predicateFromInputs(inputs)).rejects.toThrow(/JSON/)
})
})
})