@@ -4,7 +4,7 @@ import { mkdtemp, writeFile } from 'node:fs/promises';
44import { tmpdir } from 'node:os' ;
55import { join } from 'node:path' ;
66import { after , describe , it } from 'node:test' ;
7- import type { CdxBom , EolReport } from '@herodevs/eol-shared' ;
7+ import type { CdxBom , EolReport , SPDX23 } from '@herodevs/eol-shared' ;
88import {
99 readSbomFromFile ,
1010 saveReportToFile ,
@@ -23,6 +23,19 @@ describe('file.svc', () => {
2323 components : [ ] ,
2424 } as unknown as CdxBom ;
2525
26+ const mockSpdxSbom : SPDX23 = {
27+ spdxVersion : 'SPDX-2.3' ,
28+ dataLicense : 'CC0-1.0' ,
29+ SPDXID : 'SPDXRef-DOCUMENT' ,
30+ name : 'test-sbom' ,
31+ documentNamespace : 'https://example.com/test' ,
32+ creationInfo : {
33+ created : '2024-01-01T00:00:00Z' ,
34+ creators : [ 'Tool: test' ] ,
35+ } ,
36+ packages : [ ] ,
37+ } ;
38+
2639 const mockReport : EolReport = {
2740 id : 'test-id' ,
2841 createdOn : new Date ( ) . toISOString ( ) ,
@@ -40,7 +53,7 @@ describe('file.svc', () => {
4053 } ) ;
4154
4255 describe ( 'readSbomFromFile' , ( ) => {
43- it ( 'should read and parse a valid SBOM file' , async ( ) => {
56+ it ( 'should read and parse a valid CycloneDX SBOM file' , async ( ) => {
4457 tempDir = await mkdtemp ( join ( tmpdir ( ) , 'file-svc-test-' ) ) ;
4558 const filePath = join ( tempDir , 'test.json' ) ;
4659 await writeFile ( filePath , JSON . stringify ( mockSbom ) ) ;
@@ -49,6 +62,18 @@ describe('file.svc', () => {
4962 assert . deepStrictEqual ( result , mockSbom ) ;
5063 } ) ;
5164
65+ it ( 'should read and convert a valid SPDX SBOM file to CycloneDX' , async ( ) => {
66+ tempDir = await mkdtemp ( join ( tmpdir ( ) , 'file-svc-test-' ) ) ;
67+ const filePath = join ( tempDir , 'spdx-test.json' ) ;
68+ await writeFile ( filePath , JSON . stringify ( mockSpdxSbom ) ) ;
69+
70+ const result = readSbomFromFile ( filePath ) ;
71+
72+ assert . strictEqual ( result . bomFormat , 'CycloneDX' ) ;
73+ assert . ok ( result . specVersion ) ;
74+ assert . ok ( Array . isArray ( result . components ) ) ;
75+ } ) ;
76+
5277 it ( 'should throw error for non-existent file' , ( ) => {
5378 assert . throws ( ( ) => readSbomFromFile ( '/non/existent/path' ) , / S B O M f i l e n o t f o u n d / ) ;
5479 } ) ;
@@ -60,6 +85,17 @@ describe('file.svc', () => {
6085
6186 assert . throws ( ( ) => readSbomFromFile ( filePath ) , / F a i l e d t o r e a d S B O M f i l e / ) ;
6287 } ) ;
88+
89+ it ( 'should throw error for invalid SBOM format (neither SPDX nor CycloneDX)' , async ( ) => {
90+ tempDir = await mkdtemp ( join ( tmpdir ( ) , 'file-svc-test-' ) ) ;
91+ const filePath = join ( tempDir , 'invalid-format.json' ) ;
92+ await writeFile ( filePath , JSON . stringify ( { invalid : 'format' } ) ) ;
93+
94+ assert . throws (
95+ ( ) => readSbomFromFile ( filePath ) ,
96+ / I n v a l i d S B O M f i l e f o r m a t \. E x p e c t e d S P D X 2 \. 3 o r C y c l o n e D X f o r m a t / ,
97+ ) ;
98+ } ) ;
6399 } ) ;
64100
65101 describe ( 'validateDirectory' , ( ) => {
0 commit comments