@@ -7,8 +7,9 @@ const mockGetContainerSbom = vi.fn();
77const mockGetSecurityRuntime = vi . fn ( ) ;
88const mockIsMobile = { value : false } ;
99const mockWindowNarrow = { value : false } ;
10- const { mockComputeSecurityDelta } = vi . hoisted ( ( ) => ( {
10+ const { mockComputeSecurityDelta, mockToSafeExternalUrl } = vi . hoisted ( ( ) => ( {
1111 mockComputeSecurityDelta : vi . fn ( ) ,
12+ mockToSafeExternalUrl : vi . fn ( ) ,
1213} ) ) ;
1314
1415vi . mock ( '@/services/container' , ( ) => ( {
@@ -37,6 +38,19 @@ vi.mock('@/utils/container-mapper', async () => {
3738 } ;
3839} ) ;
3940
41+ vi . mock ( '@/views/security/securityViewUtils' , async ( ) => {
42+ const actual = await vi . importActual < typeof import ( '@/views/security/securityViewUtils' ) > (
43+ '@/views/security/securityViewUtils' ,
44+ ) ;
45+ return {
46+ ...actual ,
47+ toSafeExternalUrl : ( ...args : Parameters < typeof actual . toSafeExternalUrl > ) => {
48+ mockToSafeExternalUrl ( ...args ) ;
49+ return actual . toSafeExternalUrl ( ...args ) ;
50+ } ,
51+ } ;
52+ } ) ;
53+
4054import { mount } from '@vue/test-utils' ;
4155import { clearIconCache , updateSettings } from '@/services/settings' ;
4256import SecurityView from '@/views/SecurityView.vue' ;
@@ -465,6 +479,44 @@ describe('SecurityView', () => {
465479 expect ( w . find ( 'a[href="https://avd.aquasec.com/nvd/cve-2026-9999"]' ) . exists ( ) ) . toBe ( true ) ;
466480 } ) ;
467481
482+ it ( 'computes safe vulnerability URLs once per vulnerability instead of per binding' , async ( ) => {
483+ mockContainers ( [
484+ makeContainer ( {
485+ id : 'container-1' ,
486+ displayName : 'nginx' ,
487+ security : {
488+ scan : {
489+ vulnerabilities : [
490+ {
491+ id : 'CVE-2026-9999' ,
492+ severity : 'CRITICAL' ,
493+ packageName : 'openssl' ,
494+ installedVersion : '3.0.0' ,
495+ fixedVersion : '3.0.10' ,
496+ title : 'OpenSSL buffer overflow' ,
497+ target : 'usr/lib/libcrypto.so' ,
498+ primaryUrl : 'https://avd.aquasec.com/nvd/cve-2026-9999' ,
499+ } ,
500+ ] ,
501+ } ,
502+ } ,
503+ } ) ,
504+ ] ) ;
505+
506+ const w = factory ( ) ;
507+ await vi . waitFor ( ( ) => expect ( mockGetSecurityVulnerabilityOverview ) . toHaveBeenCalledOnce ( ) ) ;
508+ await flushPromises ( ) ;
509+
510+ const vm = w . vm as any ;
511+ vm . openDetail ( vm . filteredSummaries [ 0 ] ) ;
512+ await flushPromises ( ) ;
513+
514+ expect ( mockToSafeExternalUrl ) . toHaveBeenCalledTimes ( 1 ) ;
515+ expect ( mockToSafeExternalUrl ) . toHaveBeenCalledWith (
516+ 'https://avd.aquasec.com/nvd/cve-2026-9999' ,
517+ ) ;
518+ } ) ;
519+
468520 it ( 'does not render vulnerability links for disallowed URL protocols' , async ( ) => {
469521 mockContainers ( [
470522 makeContainer ( {
0 commit comments