@@ -438,6 +438,198 @@ describe("configureAdvSecTools", () => {
438438 undefined // continuationToken
439439 ) ;
440440 } ) ;
441+
442+ it ( "should handle optional parameters correctly when not provided" , async ( ) => {
443+ configureAdvSecTools ( server , tokenProvider , connectionProvider ) ;
444+
445+ const call = ( server . tool as jest . Mock ) . mock . calls . find ( ( [ toolName ] ) => toolName === "advsec_get_alerts" ) ;
446+ if ( ! call ) throw new Error ( "advsec_get_alerts tool not registered" ) ;
447+ const [ , , , handler ] = call ;
448+
449+ const mockResult : PagedList < Alert > = [ ] ;
450+ ( mockAlertApi . getAlerts as jest . Mock ) . mockResolvedValue ( mockResult ) ;
451+
452+ // Test with minimal parameters - only required ones
453+ const minimalParams = {
454+ project : "test-project" ,
455+ repository : "test-repo" ,
456+ } ;
457+
458+ await handler ( minimalParams ) ;
459+
460+ // When optional parameters aren't provided, they remain undefined
461+ expect ( mockAlertApi . getAlerts ) . toHaveBeenLastCalledWith (
462+ "test-project" ,
463+ "test-repo" ,
464+ undefined , // top (optional, no default applied by handler)
465+ undefined , // orderBy (optional, no default applied by handler)
466+ { } , // empty criteria object since no optional filters provided
467+ undefined , // expand
468+ undefined // continuationToken
469+ ) ;
470+ } ) ;
471+
472+ it ( "should include all optional parameters when provided" , async ( ) => {
473+ configureAdvSecTools ( server , tokenProvider , connectionProvider ) ;
474+
475+ const call = ( server . tool as jest . Mock ) . mock . calls . find ( ( [ toolName ] ) => toolName === "advsec_get_alerts" ) ;
476+ if ( ! call ) throw new Error ( "advsec_get_alerts tool not registered" ) ;
477+ const [ , , , handler ] = call ;
478+
479+ const mockResult : PagedList < Alert > = [ ] ;
480+ ( mockAlertApi . getAlerts as jest . Mock ) . mockResolvedValue ( mockResult ) ;
481+
482+ // Test with all optional parameters provided
483+ const allParamsParams = {
484+ project : "test-project" ,
485+ repository : "test-repo" ,
486+ alertType : "dependency" ,
487+ states : [ "active" , "dismissed" ] ,
488+ severities : [ "high" , "medium" ] ,
489+ ruleId : "rule123" ,
490+ ruleName : "security-rule" ,
491+ toolName : "CodeQL" ,
492+ ref : "refs/heads/main" ,
493+ onlyDefaultBranch : false ,
494+ top : 50 ,
495+ orderBy : "id" ,
496+ continuationToken : "token123" ,
497+ } ;
498+
499+ await handler ( allParamsParams ) ;
500+
501+ expect ( mockAlertApi . getAlerts ) . toHaveBeenLastCalledWith (
502+ "test-project" ,
503+ "test-repo" ,
504+ 50 , // top
505+ "id" , // orderBy
506+ expect . objectContaining ( {
507+ alertType : AlertType . Dependency ,
508+ states : [ State . Active , State . Dismissed ] ,
509+ severities : [ Severity . High , Severity . Medium ] ,
510+ ruleId : "rule123" ,
511+ ruleName : "security-rule" ,
512+ toolName : "CodeQL" ,
513+ ref : "refs/heads/main" ,
514+ onlyDefaultBranch : false ,
515+ } ) ,
516+ undefined , // expand
517+ "token123" // continuationToken
518+ ) ;
519+
520+ // Verify all optional fields are included
521+ const lastCall = ( mockAlertApi . getAlerts as jest . Mock ) . mock . calls [ 0 ] ;
522+ const criteria = lastCall [ 4 ] ;
523+ expect ( criteria ) . toHaveProperty ( "alertType" , AlertType . Dependency ) ;
524+ expect ( criteria ) . toHaveProperty ( "states" , [ State . Active , State . Dismissed ] ) ;
525+ expect ( criteria ) . toHaveProperty ( "severities" , [ Severity . High , Severity . Medium ] ) ;
526+ expect ( criteria ) . toHaveProperty ( "ruleId" , "rule123" ) ;
527+ expect ( criteria ) . toHaveProperty ( "ruleName" , "security-rule" ) ;
528+ expect ( criteria ) . toHaveProperty ( "toolName" , "CodeQL" ) ;
529+ expect ( criteria ) . toHaveProperty ( "ref" , "refs/heads/main" ) ;
530+ expect ( criteria ) . toHaveProperty ( "onlyDefaultBranch" , false ) ;
531+ } ) ;
532+
533+ it ( "should handle onlyDefaultBranch parameter correctly" , async ( ) => {
534+ configureAdvSecTools ( server , tokenProvider , connectionProvider ) ;
535+
536+ const call = ( server . tool as jest . Mock ) . mock . calls . find ( ( [ toolName ] ) => toolName === "advsec_get_alerts" ) ;
537+ if ( ! call ) throw new Error ( "advsec_get_alerts tool not registered" ) ;
538+ const [ , , , handler ] = call ;
539+
540+ const mockResult : PagedList < Alert > = [ ] ;
541+ ( mockAlertApi . getAlerts as jest . Mock ) . mockResolvedValue ( mockResult ) ;
542+
543+ // Test with onlyDefaultBranch explicitly set to false
544+ const falseParams = {
545+ project : "test-project" ,
546+ repository : "test-repo" ,
547+ onlyDefaultBranch : false ,
548+ } ;
549+
550+ await handler ( falseParams ) ;
551+
552+ expect ( mockAlertApi . getAlerts ) . toHaveBeenLastCalledWith (
553+ "test-project" ,
554+ "test-repo" ,
555+ undefined , // top (not provided)
556+ undefined , // orderBy (not provided)
557+ expect . objectContaining ( {
558+ onlyDefaultBranch : false ,
559+ } ) ,
560+ undefined , // expand
561+ undefined // continuationToken
562+ ) ;
563+
564+ // Test with onlyDefaultBranch explicitly set to true
565+ const trueParams = {
566+ project : "test-project" ,
567+ repository : "test-repo" ,
568+ onlyDefaultBranch : true ,
569+ } ;
570+
571+ await handler ( trueParams ) ;
572+
573+ expect ( mockAlertApi . getAlerts ) . toHaveBeenLastCalledWith (
574+ "test-project" ,
575+ "test-repo" ,
576+ undefined , // top (not provided)
577+ undefined , // orderBy (not provided)
578+ expect . objectContaining ( {
579+ onlyDefaultBranch : true ,
580+ } ) ,
581+ undefined , // expand
582+ undefined // continuationToken
583+ ) ;
584+ } ) ;
585+
586+ it ( "should handle secret alerts without confidenceLevels or validity" , async ( ) => {
587+ configureAdvSecTools ( server , tokenProvider , connectionProvider ) ;
588+
589+ const call = ( server . tool as jest . Mock ) . mock . calls . find ( ( [ toolName ] ) => toolName === "advsec_get_alerts" ) ;
590+ if ( ! call ) throw new Error ( "advsec_get_alerts tool not registered" ) ;
591+ const [ , , , handler ] = call ;
592+
593+ const mockResult : PagedList < Alert > = [ ] ;
594+ ( mockAlertApi . getAlerts as jest . Mock ) . mockResolvedValue ( mockResult ) ;
595+
596+ // Test secret alert without confidenceLevels or validity explicitly provided
597+ const secretWithoutParams = {
598+ project : "test-project" ,
599+ repository : "test-repo" ,
600+ alertType : "secret" ,
601+ } ;
602+
603+ await handler ( secretWithoutParams ) ;
604+
605+ const lastCall = ( mockAlertApi . getAlerts as jest . Mock ) . mock . calls [ 0 ] ;
606+ const criteria = lastCall [ 4 ] ;
607+ expect ( criteria ) . toHaveProperty ( "alertType" , AlertType . Secret ) ;
608+ // confidenceLevels and validity should not be included if not explicitly provided
609+ expect ( criteria ) . not . toHaveProperty ( "confidenceLevels" ) ;
610+ expect ( criteria ) . not . toHaveProperty ( "validity" ) ;
611+ } ) ;
612+
613+ it ( "should handle non-Error exception types" , async ( ) => {
614+ configureAdvSecTools ( server , tokenProvider , connectionProvider ) ;
615+
616+ const call = ( server . tool as jest . Mock ) . mock . calls . find ( ( [ toolName ] ) => toolName === "advsec_get_alerts" ) ;
617+ if ( ! call ) throw new Error ( "advsec_get_alerts tool not registered" ) ;
618+ const [ , , , handler ] = call ;
619+
620+ // Test with non-Error exception (string)
621+ ( mockAlertApi . getAlerts as jest . Mock ) . mockRejectedValue ( "String error" ) ;
622+
623+ const params = {
624+ project : "test-project" ,
625+ repository : "test-repo" ,
626+ } ;
627+
628+ const result = await handler ( params ) ;
629+
630+ expect ( result . isError ) . toBe ( true ) ;
631+ expect ( result . content [ 0 ] . text ) . toContain ( "Error fetching Advanced Security alerts: Unknown error occurred" ) ;
632+ } ) ;
441633 } ) ;
442634
443635 describe ( "advsec_get_alert_details tool" , ( ) => {
@@ -487,6 +679,44 @@ describe("configureAdvSecTools", () => {
487679 expect ( result . isError ) . toBeUndefined ( ) ;
488680 } ) ;
489681
682+ it ( "should fetch specific alert details with ref parameter" , async ( ) => {
683+ configureAdvSecTools ( server , tokenProvider , connectionProvider ) ;
684+
685+ const call = ( server . tool as jest . Mock ) . mock . calls . find ( ( [ toolName ] ) => toolName === "advsec_get_alert_details" ) ;
686+ if ( ! call ) throw new Error ( "advsec_get_alert_details tool not registered" ) ;
687+ const [ , , , handler ] = call ;
688+
689+ const mockResult : Alert = {
690+ alertId : 1 ,
691+ state : State . Active ,
692+ severity : Severity . High ,
693+ alertType : AlertType . Code ,
694+ title : "Test security alert" ,
695+ } ;
696+
697+ ( mockAlertApi . getAlert as jest . Mock ) . mockResolvedValue ( mockResult ) ;
698+
699+ const params = {
700+ project : "test-project" ,
701+ repository : "test-repo" ,
702+ alertId : 1 ,
703+ ref : "refs/heads/feature-branch" ,
704+ } ;
705+
706+ const result = await handler ( params ) ;
707+
708+ expect ( mockAlertApi . getAlert ) . toHaveBeenCalledWith (
709+ "test-project" ,
710+ 1 ,
711+ "test-repo" ,
712+ "refs/heads/feature-branch" , // ref
713+ undefined // expand
714+ ) ;
715+
716+ expect ( result . content [ 0 ] . text ) . toBe ( JSON . stringify ( mockResult , null , 2 ) ) ;
717+ expect ( result . isError ) . toBeUndefined ( ) ;
718+ } ) ;
719+
490720 it ( "should handle API errors correctly" , async ( ) => {
491721 configureAdvSecTools ( server , tokenProvider , connectionProvider ) ;
492722
@@ -510,6 +740,28 @@ describe("configureAdvSecTools", () => {
510740 expect ( result . content [ 0 ] . text ) . toContain ( "Error fetching alert details: Alert not found" ) ;
511741 } ) ;
512742
743+ it ( "should handle non-Error exception types" , async ( ) => {
744+ configureAdvSecTools ( server , tokenProvider , connectionProvider ) ;
745+
746+ const call = ( server . tool as jest . Mock ) . mock . calls . find ( ( [ toolName ] ) => toolName === "advsec_get_alert_details" ) ;
747+ if ( ! call ) throw new Error ( "advsec_get_alert_details tool not registered" ) ;
748+ const [ , , , handler ] = call ;
749+
750+ // Test with non-Error exception (string)
751+ ( mockAlertApi . getAlert as jest . Mock ) . mockRejectedValue ( "String error" ) ;
752+
753+ const params = {
754+ project : "test-project" ,
755+ repository : "test-repo" ,
756+ alertId : 999 ,
757+ } ;
758+
759+ const result = await handler ( params ) ;
760+
761+ expect ( result . isError ) . toBe ( true ) ;
762+ expect ( result . content [ 0 ] . text ) . toContain ( "Error fetching alert details: Unknown error occurred" ) ;
763+ } ) ;
764+
513765 it ( "should handle null API results correctly" , async ( ) => {
514766 configureAdvSecTools ( server , tokenProvider , connectionProvider ) ;
515767
0 commit comments