1212 * #executeWithRetry onRetry branches (401/403, 429 with Retry-After),
1313 * #getResponseText 50MB size limit,
1414 * #getTtlForEndpoint / cache config (number, object with endpoint, default),
15- * #checkMalwareFirewall internals (rejected/undefined settled) ,
15+ * #checkMalwareBatch normalize with publicPolicy ,
1616 * downloadOrgFullScanFilesAsTar streaming,
1717 * streamFullScan data/error/end handlers,
1818 * uploadManifestFiles edge case
@@ -27,6 +27,7 @@ import { PassThrough } from 'node:stream'
2727
2828import { afterAll , beforeAll , describe , expect , it , vi } from 'vitest'
2929
30+ import { MAX_FIREWALL_COMPONENTS } from '../../src/constants.js'
3031import {
3132 createRequestBodyForFilepaths ,
3233 createUploadRequest ,
@@ -641,67 +642,70 @@ describe('SocketSdk - #parseRetryAfter via retry behavior', () => {
641642} )
642643
643644// =============================================================================
644- // 4e. socket-sdk-class.ts — #checkMalwareFirewall internals (lines 990-1018)
645- // Specifically: rejected promise and resp.ok=false branches
645+ // 4e. socket-sdk-class.ts — #checkMalwareBatch normalize with publicPolicy
646+ // Specifically: alerts with/without fix, ignore actions filtered
646647// =============================================================================
647648
648- describe ( 'SocketSdk - checkMalwareFirewall internals' , ( ) => {
649+ describe ( 'SocketSdk - checkMalware batch normalize with publicPolicy' , ( ) => {
650+ const artifact = {
651+ alerts : [
652+ {
653+ category : 'supplyChainRisk' ,
654+ fix : { description : 'Remove package' , type : 'remove' } ,
655+ key : 'mal-1' ,
656+ props : { note : 'data exfil' } ,
657+ severity : 'critical' ,
658+ type : 'malware' ,
659+ } ,
660+ {
661+ // Alert without fix property — criticalCVE is 'warn' in publicPolicy
662+ category : 'quality' ,
663+ key : 'cve-1' ,
664+ props : { } ,
665+ severity : 'high' ,
666+ type : 'criticalCVE' ,
667+ } ,
668+ {
669+ // deprecated is 'ignore' in publicPolicy — should be filtered out
670+ category : 'misc' ,
671+ key : 'dep-1' ,
672+ props : { } ,
673+ severity : 'low' ,
674+ type : 'deprecated' ,
675+ } ,
676+ ] ,
677+ name : 'evil-pkg' ,
678+ namespace : undefined ,
679+ score : {
680+ license : 0.9 ,
681+ maintenance : 0.8 ,
682+ overall : 0.1 ,
683+ quality : 0.7 ,
684+ supplyChain : 0.0 ,
685+ vulnerability : 0.0 ,
686+ } ,
687+ type : 'npm' ,
688+ version : '1.0.0' ,
689+ }
690+
649691 const getBaseUrl = setupLocalHttpServer (
650692 ( req : IncomingMessage , res : ServerResponse ) => {
651693 const url = req . url || ''
652694
653- // Batch purl path (org token) — exercises #normalizeArtifact.
695+ // Batch purl path — exercises #normalizeArtifact with publicPolicy .
654696 let body = ''
655697 req . on ( 'data' , ( chunk : Buffer ) => {
656698 body += chunk . toString ( )
657699 } )
658700 req . on ( 'end' , ( ) => {
659701 if ( url . includes ( '/purl' ) && req . method === 'POST' ) {
660- const artifact = {
661- alerts : [
662- {
663- action : 'error' ,
664- category : 'supplyChainRisk' ,
665- fix : { description : 'Remove package' , type : 'remove' } ,
666- key : 'mal-1' ,
667- props : { note : 'data exfil' } ,
668- severity : 'critical' ,
669- type : 'malware' ,
670- } ,
671- {
672- // Alert without fix property
673- action : 'warn' ,
674- category : 'quality' ,
675- key : 'cve-1' ,
676- props : { } ,
677- severity : 'high' ,
678- type : 'criticalCVE' ,
679- } ,
680- {
681- // Alert with ignore action — should be filtered out
682- action : 'ignore' ,
683- category : 'misc' ,
684- key : 'dep-1' ,
685- props : { } ,
686- severity : 'low' ,
687- type : 'deprecated' ,
688- } ,
689- ] ,
690- name : 'evil-pkg' ,
691- namespace : undefined ,
692- score : {
693- license : 0.9 ,
694- maintenance : 0.8 ,
695- overall : 0.1 ,
696- quality : 0.7 ,
697- supplyChain : 0.0 ,
698- vulnerability : 0.0 ,
699- } ,
700- type : 'npm' ,
701- version : '1.0.0' ,
702- }
702+ const parsed = JSON . parse ( body )
703+ const count = parsed . components ?. length ?? 0
704+ const lines = Array . from ( { length : count } , ( ) =>
705+ JSON . stringify ( artifact ) ,
706+ ) . join ( '\n' )
703707 res . writeHead ( 200 , { 'Content-Type' : 'application/x-ndjson' } )
704- res . end ( `${ JSON . stringify ( artifact ) } \n` )
708+ res . end ( `${ lines } \n` )
705709 } else {
706710 res . writeHead ( 404 )
707711 res . end ( )
@@ -711,21 +715,23 @@ describe('SocketSdk - checkMalwareFirewall internals', () => {
711715 )
712716
713717 it ( 'should normalize artifact with fix and without fix, filtering ignore actions' , async ( ) => {
714- const client = new SocketSdk ( 'org-api-token' , {
718+ const count = MAX_FIREWALL_COMPONENTS + 1
719+ const client = new SocketSdk ( 'test-api-token' , {
715720 baseUrl : `${ getBaseUrl ( ) } /v0/` ,
716721 retries : 0 ,
717722 } )
718723
719- const result = await client . checkMalware ( [
720- { purl : 'pkg:npm/evil-pkg@1.0.0' } ,
721- ] )
724+ const components = Array . from ( { length : count } , ( _ , i ) => ( {
725+ purl : `pkg:npm/evil-pkg@${ i + 1 } .0.0` ,
726+ } ) )
727+ const result = await client . checkMalware ( components )
722728
723729 expect ( result . success ) . toBe ( true )
724730 if ( ! result . success ) return
725- expect ( result . data ) . toHaveLength ( 1 )
731+ expect ( result . data ) . toHaveLength ( count )
726732 const pkg = result . data [ 0 ] !
727733
728- // Two alerts should remain (error + warn), ignore is filtered
734+ // Two alerts should remain (error + warn via publicPolicy ), deprecated is filtered
729735 expect ( pkg . alerts ) . toHaveLength ( 2 )
730736
731737 // First alert has fix
0 commit comments