Files
attest-sbom/__tests__/sbom.test.ts
T

131 lines
3.8 KiB
TypeScript
Raw Normal View History

2024-02-28 17:22:13 -08:00
import {
storePredicate,
parseSBOMFromPath,
generateSBOMPredicate,
SBOM
} from '../src/sbom'
import type { Predicate } from '@actions/attest'
import * as fs from 'fs'
import os from 'os'
import * as path from 'path'
describe('parseSBOMFromPath', () => {
let tempDir = '/'
beforeEach(() => {
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'sbom'))
})
afterEach(() => {
fs.rmSync(tempDir, { recursive: true })
2024-02-28 17:22:13 -08:00
})
it('correctly parses an SPDX file', async () => {
const spdxSBOM = JSON.stringify({
spdxVersion: 'SPDX-2.2',
SPDXID: 'SPDXRef-DOCUMENT'
})
const filePath = path.join(tempDir, 'spdxSBOM.json')
fs.writeFileSync(filePath, spdxSBOM)
await expect(parseSBOMFromPath(filePath)).resolves.toEqual({
type: 'spdx',
object: JSON.parse(spdxSBOM)
})
})
it('correctly parses a CycloneDX file', async () => {
const cycloneDXSBOM = JSON.stringify({
bomFormat: 'CycloneDX',
serialNumber: '123',
specVersion: '1.2'
})
const filePath = path.join(tempDir, 'cyclonedxSBOM.json')
fs.writeFileSync(filePath, cycloneDXSBOM)
await expect(parseSBOMFromPath(filePath)).resolves.toEqual({
type: 'cyclonedx',
object: JSON.parse(cycloneDXSBOM)
})
})
it('throws an error for unsupported SBOM formats', async () => {
const filePath = path.join(tempDir, 'random.json')
fs.writeFileSync(filePath, JSON.stringify({ random: 'value' }))
await expect(parseSBOMFromPath(filePath)).rejects.toThrow(
'Unsupported SBOM format'
)
})
})
describe('storePredicate', () => {
it('should store the predicate to a temporary file', () => {
const predicate = { params: { key: 'value' } } as Predicate
// Mocking the process.env['RUNNER_TEMP'] value
const originalEnv = process.env
process.env = { ...originalEnv, RUNNER_TEMP: '/tmp' }
const tempFile = storePredicate(predicate)
// Verify that the temporary file exists
expect(fs.existsSync(tempFile)).toBe(true)
// Read the content of the temporary file
const fileContent = fs.readFileSync(tempFile, 'utf-8')
// Verify that the content matches the predicate params
expect(JSON.parse(fileContent)).toEqual(predicate.params)
// Clean up the temporary file
fs.unlinkSync(tempFile)
// Restore the original process.env
process.env = originalEnv
})
it('should throw an error if RUNNER_TEMP environment variable is missing', () => {
const predicate = { params: { key: 'value' } } as Predicate
// Mocking the process.env['RUNNER_TEMP'] value
const originalEnv = process.env
process.env = {}
// Verify that an error is thrown
expect(() => storePredicate(predicate)).toThrow(
'Missing RUNNER_TEMP environment variable'
)
// Restore the original process.env
process.env = originalEnv
})
})
describe('generateSBOMPredicate', () => {
it('generates SPDX predicate correctly', () => {
const sbom = { type: 'spdx', object: { spdxVersion: 'SPDX-2.2' } } as SBOM
const result = generateSBOMPredicate(sbom)
expect(result.type).toContain('https://spdx.dev/Document/v2.2')
expect(result.params).toEqual(sbom.object)
})
2025-06-17 09:51:48 -07:00
it('throws an error for missing SPDX version', () => {
const sbom = { type: 'spdx' } as SBOM
expect(() => generateSBOMPredicate(sbom)).toThrow(
'Cannot find spdxVersion in the SBOM'
)
})
2024-02-28 17:22:13 -08:00
it('generates CycloneDX predicate correctly', () => {
const sbom = { type: 'cyclonedx', object: {} } as SBOM
const result = generateSBOMPredicate(sbom)
expect(result.type).toEqual('https://cyclonedx.org/bom')
expect(result.params).toEqual(sbom.object)
})
it('throws error for unsupported SBOM formats', () => {
2025-06-17 09:51:48 -07:00
const sbom = { type: 'foo', object: {} }
2024-02-28 17:22:13 -08:00
// @ts-expect-error test error case
2025-06-17 09:51:48 -07:00
expect(() => generateSBOMPredicate(sbom)).toThrow('Unsupported SBOM format')
2024-02-28 17:22:13 -08:00
})
})