diff --git a/internal/commands/predicates.go b/internal/commands/predicates.go index eedda776e..7b212c705 100644 --- a/internal/commands/predicates.go +++ b/internal/commands/predicates.go @@ -1,14 +1,15 @@ package commands import ( + "strings" + "time" + "github.com/MakeNowJust/heredoc" "github.com/checkmarx/ast-cli/internal/commands/util/printer" "github.com/checkmarx/ast-cli/internal/params" "github.com/checkmarx/ast-cli/internal/wrappers" "github.com/pkg/errors" "github.com/spf13/cobra" - "strings" - "time" ) var systemStates = []wrappers.CustomState{ diff --git a/internal/commands/predicates_test.go b/internal/commands/predicates_test.go index 499decb31..94890dcda 100644 --- a/internal/commands/predicates_test.go +++ b/internal/commands/predicates_test.go @@ -4,9 +4,10 @@ package commands import ( "fmt" + "testing" + "github.com/checkmarx/ast-cli/internal/wrappers" "github.com/checkmarx/ast-cli/internal/wrappers/mock" - "testing" "gotest.tools/assert" ) diff --git a/internal/commands/scan.go b/internal/commands/scan.go index 4c0ee97a7..5de62de5a 100644 --- a/internal/commands/scan.go +++ b/internal/commands/scan.go @@ -110,6 +110,10 @@ const ( "\nTo use this feature, you would need to purchase a license." + "\nPlease contact our support team for assistance if you believe you have already purchased a license." + "\nLicensed packages: %s" + engineScsNotAllowed = "You are trying to run a scan with the \"scs\" scan type. This requires either the \"repository‑health\" or the \"secret‑detection\" package license, depending on which scanner you are running." + + "\nTo use this feature, you need to purchase the appropriate license." + + "\nIf you think that you have already purchased the relevant license, please contact our support team for assistance." + + "\nLicensed packages: %s" containerResolutionFileName = "containers-resolution.json" directoryCreationPrefix = "cx-" ScsScoreCardType = "scorecard" @@ -986,7 +990,9 @@ func setupScanTypeProjectAndConfig( configArr = append(configArr, containersConfig) } - var SCSConfig, scsErr = addSCSScan(cmd, resubmitConfig, userAllowedEngines[commonParams.EnterpriseSecretsType]) + scsLicensingV2Flag, _ := wrappers.GetSpecificFeatureFlag(featureFlagsWrapper, wrappers.ScsLicensingV2Enabled) + var SCSConfig, scsErr = addSCSScan(cmd, resubmitConfig, scsLicensingV2Flag.Status, userAllowedEngines[commonParams.RepositoryHealthType], + userAllowedEngines[commonParams.SecretDetectionType], userAllowedEngines[commonParams.EnterpriseSecretsType]) if scsErr != nil { return scsErr } else if SCSConfig != nil { @@ -1267,17 +1273,18 @@ func addAPISecScan(cmd *cobra.Command) map[string]interface{} { return nil } -func createResubmitConfig(resubmitConfig []wrappers.Config, scsRepoToken, scsRepoURL string, hasEnterpriseSecretsLicense bool) wrappers.SCSConfig { +func createResubmitConfig(resubmitConfig []wrappers.Config, scsRepoToken, scsRepoURL string, isScsSecretDetectionAllowed, + isScsScorecardAllowed bool) wrappers.SCSConfig { scsConfig := wrappers.SCSConfig{} for _, config := range resubmitConfig { resubmitTwoms := config.Value[configTwoms] - if resubmitTwoms != nil && hasEnterpriseSecretsLicense { + if resubmitTwoms != nil && isScsSecretDetectionAllowed { scsConfig.Twoms = resubmitTwoms.(string) } scsConfig.RepoURL = scsRepoURL scsConfig.RepoToken = scsRepoToken resubmitScoreCard := config.Value[ScsScoreCardType] - if resubmitScoreCard == trueString && scsRepoToken != "" && scsRepoURL != "" { + if resubmitScoreCard == trueString && scsRepoToken != "" && scsRepoURL != "" && isScsScorecardAllowed { scsConfig.Scorecard = trueString } else { scsConfig.Scorecard = falseString @@ -1330,8 +1337,12 @@ func isScorecardRunnable(isScsEnginesFlagSet, scsScorecardSelected bool, scsRepo return isURLSupportedByScorecard(scsRepoURL), nil } -func addSCSScan(cmd *cobra.Command, resubmitConfig []wrappers.Config, hasEnterpriseSecretsLicense bool) (map[string]interface{}, error) { - if !scanTypeEnabled(commonParams.ScsType) && !scanTypeEnabled(commonParams.MicroEnginesType) { +func addSCSScan(cmd *cobra.Command, resubmitConfig []wrappers.Config, scsLicensingV2, hasRepositoryHealthLicense, + hasSecretDetectionLicense, hasEnterpriseSecretsLicense bool) (map[string]interface{}, error) { + scsEnabled := scanTypeEnabled(commonParams.ScsType) + scsScorecardAllowed := isScsScorecardAllowed(scsLicensingV2, hasRepositoryHealthLicense, scsEnabled) + scsSecretDetectionAllowed := isScsSecretDetectionAllowed(scsLicensingV2, hasSecretDetectionLicense, hasEnterpriseSecretsLicense, scsEnabled) + if !scsScorecardAllowed && !scsSecretDetectionAllowed { return nil, nil } scsConfig := wrappers.SCSConfig{} @@ -1352,20 +1363,20 @@ func addSCSScan(cmd *cobra.Command, resubmitConfig []wrappers.Config, hasEnterpr scsEngines, _ := cmd.Flags().GetString(commonParams.SCSEnginesFlag) if resubmitConfig != nil { - scsConfig = createResubmitConfig(resubmitConfig, scsRepoToken, scsRepoURL, hasEnterpriseSecretsLicense) + scsConfig = createResubmitConfig(resubmitConfig, scsRepoToken, scsRepoURL, scsSecretDetectionAllowed, scsScorecardAllowed) scsMapConfig[resultsMapValue] = &scsConfig return scsMapConfig, nil } scsScoreCardSelected, scsSecretDetectionSelected := getSCSEnginesSelected(scsEngines) // secret-detection or scorecard - if scsSecretDetectionSelected && hasEnterpriseSecretsLicense { + if scsSecretDetectionSelected && scsSecretDetectionAllowed { scsConfig.Twoms = trueString } isScsEnginesFlagSet := scsEngines != "" - if scsScoreCardSelected { + if scsScoreCardSelected && scsScorecardAllowed { canRunScorecard, err := isScorecardRunnable(isScsEnginesFlagSet, scsScoreCardSelected, scsRepoToken, scsRepoURL, userScanTypes) if err != nil { return nil, err @@ -1386,25 +1397,39 @@ func addSCSScan(cmd *cobra.Command, resubmitConfig []wrappers.Config, hasEnterpr return scsMapConfig, nil } +func isScsScorecardAllowed(scsLicensingV2, hasRepositoryHealthLicense, hasScsLicense bool) bool { + if scsLicensingV2 { + return hasRepositoryHealthLicense + } + return hasScsLicense +} + +func isScsSecretDetectionAllowed(scsLicensingV2, hasSecretDetectionLicense, hasEnterpriseSecretsLicense, hasScsLicense bool) bool { + if scsLicensingV2 { + return hasSecretDetectionLicense + } + return hasScsLicense && hasEnterpriseSecretsLicense +} + func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper, featureFlagsWrapper wrappers.FeatureFlagsWrapper) error { var scanTypes []string - var SCSScanTypes []string - isSbomScan, _ := cmd.PersistentFlags().GetBool(commonParams.SbomFlag) + scsLicensingV2Flag, _ := wrappers.GetSpecificFeatureFlag(featureFlagsWrapper, wrappers.ScsLicensingV2Enabled) allowedEngines, err := jwtWrapper.GetAllowedEngines(featureFlagsWrapper) + + isSbomScan, _ := cmd.PersistentFlags().GetBool(commonParams.SbomFlag) + if err != nil { err = errors.Errorf("Error validating scan types: %v", err) return err } userScanTypes, _ := cmd.Flags().GetString(commonParams.ScanTypes) - userSCSScanTypes, _ := cmd.Flags().GetString(commonParams.SCSEnginesFlag) if len(userScanTypes) > 0 { userScanTypes = strings.ReplaceAll(strings.ToLower(userScanTypes), " ", "") userScanTypes = strings.Replace(strings.ToLower(userScanTypes), commonParams.KicsType, commonParams.IacType, 1) userScanTypes = strings.Replace(strings.ToLower(userScanTypes), commonParams.ContainersTypeFlag, commonParams.ContainersType, 1) - userSCSScanTypes = strings.Replace(strings.ToLower(userSCSScanTypes), commonParams.SCSEnginesFlag, commonParams.ScsType, 1) scanTypes = strings.Split(userScanTypes, ",") @@ -1422,6 +1447,13 @@ func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper, featu } for _, scanType := range scanTypes { + if scanType == commonParams.ScsType && scsLicensingV2Flag.Status { + // the SCS scan type is a special case because it contains two engines. + // Before the new licensing model, the main license was named "scs". + // Licenses are now separated for each engine, so this validation no longer makes sense. + // See validateSCSEngines. + continue + } if !allowedEngines[scanType] { keys := reflect.ValueOf(allowedEngines).MapKeys() err = errors.Errorf(engineNotAllowed, scanType, scanType, keys) @@ -1429,11 +1461,12 @@ func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper, featu } } - SCSScanTypes = strings.Split(userSCSScanTypes, ",") - if slices.Contains(SCSScanTypes, ScsSecretDetectionType) && !allowedEngines[commonParams.EnterpriseSecretsType] { - keys := reflect.ValueOf(allowedEngines).MapKeys() - err = errors.Errorf(engineNotAllowed, ScsSecretDetectionType, ScsSecretDetectionType, keys) - return err + userSCSScanTypes, _ := cmd.Flags().GetString(commonParams.SCSEnginesFlag) + if slices.Contains(scanTypes, commonParams.ScsType) { + err = validateSCSEngines(allowedEngines, userSCSScanTypes, scsLicensingV2Flag.Status) + if err != nil { + return err + } } } else { if isSbomScan { @@ -1455,6 +1488,25 @@ func validateScanTypes(cmd *cobra.Command, jwtWrapper wrappers.JWTWrapper, featu return nil } +func validateSCSEngines(allowedEngines map[string]bool, userSCSScanTypes string, scsLicensingV2 bool) error { + licensesAvailable := reflect.ValueOf(allowedEngines).MapKeys() + scsScanTypes := strings.Split(userSCSScanTypes, ",") + if scsLicensingV2 { + secretDetectionAllowed := allowedEngines[commonParams.SecretDetectionType] + repositoryHeatlhAllowed := allowedEngines[commonParams.RepositoryHealthType] + if userSCSScanTypes == "" && !secretDetectionAllowed && !repositoryHeatlhAllowed { + return errors.Errorf(engineScsNotAllowed, licensesAvailable) + } else if slices.Contains(scsScanTypes, ScsSecretDetectionType) && !secretDetectionAllowed { + return errors.Errorf(engineNotAllowed, commonParams.SecretDetectionType, commonParams.SecretDetectionType, licensesAvailable) + } else if slices.Contains(scsScanTypes, ScsScoreCardType) && !repositoryHeatlhAllowed { + return errors.Errorf(engineNotAllowed, commonParams.RepositoryHealthType, commonParams.RepositoryHealthType, licensesAvailable) + } + } else if slices.Contains(scsScanTypes, ScsSecretDetectionType) && !allowedEngines[commonParams.EnterpriseSecretsType] { + return errors.Errorf(engineNotAllowed, ScsSecretDetectionType, ScsSecretDetectionType, licensesAvailable) + } + return nil +} + func scanTypeEnabled(scanType string) bool { scanTypes := strings.Split(actualScanTypes, ",") for _, a := range scanTypes { diff --git a/internal/commands/scan_test.go b/internal/commands/scan_test.go index 5101d2606..ae0c42933 100644 --- a/internal/commands/scan_test.go +++ b/internal/commands/scan_test.go @@ -798,87 +798,143 @@ func TestAddScaScan(t *testing.T) { t.Errorf("Expected %+v, but got %+v", scaMapConfig, result) } } -func TestAddSCSScan_ResubmitWithOutScorecardFlags_ShouldPass(t *testing.T) { - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", +func TestAddSCSScan_ResubmitWithoutScorecardFlags_ShouldPass(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.ScanTypes, "", "Scan types") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "SCS Repo Token") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "SCS Repo URL") - _ = cmdCommand.Execute() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + } + cmdCommand.PersistentFlags().String(commonParams.ScanTypes, "", "Scan types") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "SCS Repo Token") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "SCS Repo URL") - _ = cmdCommand.Flags().Set(commonParams.ScanTypes, commonParams.ScsType) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, "") - _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, "") + _ = cmdCommand.Execute() - resubmitConfig := []wrappers.Config{ - { - Type: commonParams.ScsType, - Value: map[string]interface{}{ - configTwoms: trueString, - ScsScoreCardType: falseString, - }, - }, - } + _ = cmdCommand.Flags().Set(commonParams.ScanTypes, commonParams.ScsType) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, "") + _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, "") + + resubmitConfig := []wrappers.Config{ + { + Type: commonParams.ScsType, + Value: map[string]interface{}{ + configTwoms: trueString, + ScsScoreCardType: falseString, + }, + }, + } - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) - expectedConfig := wrappers.SCSConfig{ - Twoms: trueString, - Scorecard: falseString, - } + expectedConfig := wrappers.SCSConfig{ + Twoms: trueString, + Scorecard: falseString, + } - expectedMapConfig := make(map[string]interface{}) - expectedMapConfig[resultsMapType] = commonParams.MicroEnginesType - expectedMapConfig[resultsMapValue] = &expectedConfig + expectedMapConfig := make(map[string]interface{}) + expectedMapConfig[resultsMapType] = commonParams.MicroEnginesType + expectedMapConfig[resultsMapValue] = &expectedConfig - if !reflect.DeepEqual(result, expectedMapConfig) { - t.Errorf("Expected %+v, but got %+v", expectedMapConfig, result) + if !reflect.DeepEqual(result, expectedMapConfig) { + t.Errorf("Expected %+v, but got %+v", expectedMapConfig, result) + } + }) } } func TestAddSCSScan_ResubmitWithScorecardFlags_ShouldPass(t *testing.T) { - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.ScanTypes, "", "Scan types") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "SCS Repo Token") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "SCS Repo URL") - _ = cmdCommand.Execute() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + } + cmdCommand.PersistentFlags().String(commonParams.ScanTypes, "", "Scan types") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "SCS Repo Token") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "SCS Repo URL") - _ = cmdCommand.Flags().Set(commonParams.ScanTypes, commonParams.ScsType) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyRepo) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) + _ = cmdCommand.Execute() - resubmitConfig := []wrappers.Config{ - { - Type: commonParams.ScsType, - Value: map[string]interface{}{ - configTwoms: trueString, - ScsScoreCardType: trueString, - }, - }, - } + _ = cmdCommand.Flags().Set(commonParams.ScanTypes, commonParams.ScsType) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyRepo) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + resubmitConfig := []wrappers.Config{ + { + Type: commonParams.ScsType, + Value: map[string]interface{}{ + configTwoms: trueString, + ScsScoreCardType: trueString, + }, + }, + } - expectedConfig := wrappers.SCSConfig{ - Twoms: "true", - Scorecard: trueString, - RepoToken: dummyToken, - RepoURL: dummyRepo, - } + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) + + expectedConfig := wrappers.SCSConfig{ + Twoms: "true", + Scorecard: trueString, + RepoToken: dummyToken, + RepoURL: dummyRepo, + } - expectedMapConfig := make(map[string]interface{}) - expectedMapConfig[resultsMapType] = commonParams.MicroEnginesType - expectedMapConfig[resultsMapValue] = &expectedConfig + expectedMapConfig := make(map[string]interface{}) + expectedMapConfig[resultsMapType] = commonParams.MicroEnginesType + expectedMapConfig[resultsMapValue] = &expectedConfig - if !reflect.DeepEqual(result, expectedMapConfig) { - t.Errorf("Expected %+v, but got %+v", expectedMapConfig, result) + if !reflect.DeepEqual(result, expectedMapConfig) { + t.Errorf("Expected %+v, but got %+v", expectedMapConfig, result) + } + }) } } @@ -1095,510 +1151,869 @@ func TestCreateScan_WithSCSScorecard_ShouldFail(t *testing.T) { assert.Assert(t, err.Error() == SCSScoreCardError) } -func TestCreateScan_WithSCSSecretDetectionAndScorecard_scsMapHasBoth(t *testing.T) { - var resubmitConfig []wrappers.Config - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", - Long: `Scan a project`, +func TestAddSCSScan_WithSCSSecretDetectionAndScorecard_scsMapHasBoth(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") - _ = cmdCommand.Execute() - _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") - _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyRepo) - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } + cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") + _ = cmdCommand.Execute() + _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") + _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyRepo) + + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) + + scsConfig := wrappers.SCSConfig{ + Twoms: "true", + Scorecard: "true", + RepoURL: dummyRepo, + RepoToken: dummyToken, + } + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig - scsConfig := wrappers.SCSConfig{ - Twoms: "true", - Scorecard: "true", - RepoURL: dummyRepo, - RepoToken: dummyToken, + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } - scsMapConfig := make(map[string]interface{}) - scsMapConfig[resultsMapType] = commonParams.MicroEnginesType - scsMapConfig[resultsMapValue] = &scsConfig +} - if !reflect.DeepEqual(result, scsMapConfig) { - t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) +func TestAddSCSScan_WithoutSCSSecretDetection_scsMapNoSecretDetection(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: false, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } + cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") + _ = cmdCommand.Execute() + _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") + _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyRepo) + + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) + + scsConfig := wrappers.SCSConfig{ + Twoms: "", + Scorecard: "true", + RepoURL: dummyRepo, + RepoToken: dummyToken, + } + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig + + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } } -func TestCreateScan_WithoutSCSSecretDetection_scsMapNoSecretDetection(t *testing.T) { - var resubmitConfig []wrappers.Config - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", - Long: `Scan a project`, +func TestAddSCSScan_WithSCSSecretDetection_scsMapHasSecretDetection(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") - _ = cmdCommand.Execute() - _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") - _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyRepo) - result, _ := addSCSScan(cmdCommand, resubmitConfig, false) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } + cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") + _ = cmdCommand.Execute() + _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection") - scsConfig := wrappers.SCSConfig{ - Twoms: "", - Scorecard: "true", - RepoURL: dummyRepo, - RepoToken: dummyToken, - } - scsMapConfig := make(map[string]interface{}) - scsMapConfig[resultsMapType] = commonParams.MicroEnginesType - scsMapConfig[resultsMapValue] = &scsConfig + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) + + scsConfig := wrappers.SCSConfig{ + Twoms: "true", + } + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig - if !reflect.DeepEqual(result, scsMapConfig) { - t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } } -func TestCreateScan_WithSCSSecretDetection_scsMapHasSecretDetection(t *testing.T) { - var resubmitConfig []wrappers.Config - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", - Long: `Scan a project`, +func TestAddSCSScan_WithSCSSecretDetectionAndScorecardWithScanTypesAndNoScorecardFlags_scsMapHasSecretDetection(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") - _ = cmdCommand.Execute() - _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection") - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a pipe for capturing stdout + r, w, _ := os.Pipe() + oldStdout := os.Stdout + defer func() { os.Stdout = oldStdout }() + os.Stdout = w // Redirecting stdout to the pipe - scsConfig := wrappers.SCSConfig{ - Twoms: "true", - } - scsMapConfig := make(map[string]interface{}) - scsMapConfig[resultsMapType] = commonParams.MicroEnginesType - scsMapConfig[resultsMapValue] = &scsConfig + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } + cmdCommand.PersistentFlags().String(commonParams.ScanTypeFlag, "scs", "") + _ = cmdCommand.Execute() + _ = cmdCommand.Flags().Set(commonParams.ScanTypeFlag, "scs") - if !reflect.DeepEqual(result, scsMapConfig) { - t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) - } -} + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) -func TestCreateScan_WithSCSSecretDetectionAndScorecardWithScanTypesAndNoScorecardFlags_scsMapHasSecretDetection(t *testing.T) { - // Create a pipe for capturing stdout - r, w, _ := os.Pipe() - oldStdout := os.Stdout - defer func() { os.Stdout = oldStdout }() - os.Stdout = w // Redirecting stdout to the pipe + scsConfig := wrappers.SCSConfig{ + Twoms: "true", + } - var resubmitConfig []wrappers.Config - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", - Long: `Scan a project`, - } - cmdCommand.PersistentFlags().String(commonParams.ScanTypeFlag, "scs", "") - _ = cmdCommand.Execute() - _ = cmdCommand.Flags().Set(commonParams.ScanTypeFlag, "scs") + // Close the writer to signal that we are done capturing the output + w.Close() - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + // Read from the pipe (stdout) + var buf bytes.Buffer + _, err := io.Copy(&buf, r) // Copy the captured output to a buffer + if err != nil { + t.Fatalf("Failed to capture output: %v", err) + } - scsConfig := wrappers.SCSConfig{ - Twoms: "true", - } + output := buf.String() + if !strings.Contains(output, ScsRepoWarningMsg) { + t.Errorf("Expected output to contain %q, but got %q", ScsRepoWarningMsg, output) + } - // Close the writer to signal that we are done capturing the output - w.Close() + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig - // Read from the pipe (stdout) - var buf bytes.Buffer - _, err := io.Copy(&buf, r) // Copy the captured output to a buffer - if err != nil { - t.Fatalf("Failed to capture output: %v", err) + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } +} - output := buf.String() - if !strings.Contains(output, ScsRepoWarningMsg) { - t.Errorf("Expected output to contain %q, but got %q", ScsRepoWarningMsg, output) +func TestAddSCSScan_WithSCSSecretDetectionAndWithoutScanTypes_scsMapHasSecretDetection(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - scsMapConfig := make(map[string]interface{}) - scsMapConfig[resultsMapType] = commonParams.MicroEnginesType - scsMapConfig[resultsMapValue] = &scsConfig + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } - if !reflect.DeepEqual(result, scsMapConfig) { - t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) + + scsConfig := wrappers.SCSConfig{ + Twoms: "true", + } + + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig + + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } } -func TestCreateScan_WithSCSSecretDetectionAndScorecardShortenedGithubRepo_scsMapHasBoth(t *testing.T) { - // Create a pipe for capturing stdout - r, w, _ := os.Pipe() - oldStdout := os.Stdout - defer func() { os.Stdout = oldStdout }() - os.Stdout = w // Redirecting stdout to the pipe - - var resubmitConfig []wrappers.Config - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", - Long: `Scan a project`, +func TestAddSCSScan_WithSCSSecretDetectionAndScorecardShortenedGithubRepo_scsMapHasBoth(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") - _ = cmdCommand.Execute() - _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") - _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyShortenedGithubRepo) - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a pipe for capturing stdout + r, w, _ := os.Pipe() + oldStdout := os.Stdout + defer func() { os.Stdout = oldStdout }() + os.Stdout = w // Redirecting stdout to the pipe - // Close the writer to signal that we are done capturing the output - w.Close() + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } + cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") + _ = cmdCommand.Execute() + _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") + _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyShortenedGithubRepo) - // Read from the pipe (stdout) - var buf bytes.Buffer - _, err := io.Copy(&buf, r) // Copy the captured output to a buffer - if err != nil { - t.Fatalf("Failed to capture output: %v", err) - } + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) - output := buf.String() - if strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { - t.Errorf("Expected output to not contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) - } + // Close the writer to signal that we are done capturing the output + w.Close() - scsConfig := wrappers.SCSConfig{ - Twoms: "true", - Scorecard: "true", - RepoURL: dummyShortenedGithubRepo, - RepoToken: dummyToken, - } - scsMapConfig := make(map[string]interface{}) - scsMapConfig[resultsMapType] = commonParams.MicroEnginesType - scsMapConfig[resultsMapValue] = &scsConfig + // Read from the pipe (stdout) + var buf bytes.Buffer + _, err := io.Copy(&buf, r) // Copy the captured output to a buffer + if err != nil { + t.Fatalf("Failed to capture output: %v", err) + } + + output := buf.String() + if strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { + t.Errorf("Expected output to not contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) + } - if !reflect.DeepEqual(result, scsMapConfig) { - t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + scsConfig := wrappers.SCSConfig{ + Twoms: "true", + Scorecard: "true", + RepoURL: dummyShortenedGithubRepo, + RepoToken: dummyToken, + } + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig + + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } } -func TestCreateScan_WithSCSSecretDetectionAndScorecardShortenedGithubRepoWithTokenInURL_scsMapHasBoth(t *testing.T) { - // Create a pipe for capturing stdout - r, w, _ := os.Pipe() - oldStdout := os.Stdout - defer func() { os.Stdout = oldStdout }() - os.Stdout = w // Redirecting stdout to the pipe - - var resubmitConfig []wrappers.Config - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", - Long: `Scan a project`, +func TestAddSCSScan_WithSCSSecretDetectionAndScorecardShortenedGithubRepoWithTokenInURL_scsMapHasBoth(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") - _ = cmdCommand.Execute() - _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") - _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyShortenedRepoWithToken) - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a pipe for capturing stdout + r, w, _ := os.Pipe() + oldStdout := os.Stdout + defer func() { os.Stdout = oldStdout }() + os.Stdout = w // Redirecting stdout to the pipe - // Close the writer to signal that we are done capturing the output - w.Close() + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } + cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") + _ = cmdCommand.Execute() + _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") + _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyShortenedRepoWithToken) - // Read from the pipe (stdout) - var buf bytes.Buffer - _, err := io.Copy(&buf, r) // Copy the captured output to a buffer - if err != nil { - t.Fatalf("Failed to capture output: %v", err) - } + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) - output := buf.String() - if strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { - t.Errorf("Expected output to not contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) - } + // Close the writer to signal that we are done capturing the output + w.Close() - scsConfig := wrappers.SCSConfig{ - Twoms: "true", - Scorecard: "true", - RepoURL: dummyShortenedRepoWithToken, - RepoToken: dummyToken, - } - scsMapConfig := make(map[string]interface{}) - scsMapConfig[resultsMapType] = commonParams.MicroEnginesType - scsMapConfig[resultsMapValue] = &scsConfig + // Read from the pipe (stdout) + var buf bytes.Buffer + _, err := io.Copy(&buf, r) // Copy the captured output to a buffer + if err != nil { + t.Fatalf("Failed to capture output: %v", err) + } + + output := buf.String() + if strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { + t.Errorf("Expected output to not contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) + } - if !reflect.DeepEqual(result, scsMapConfig) { - t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + scsConfig := wrappers.SCSConfig{ + Twoms: "true", + Scorecard: "true", + RepoURL: dummyShortenedRepoWithToken, + RepoToken: dummyToken, + } + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig + + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } } -func TestCreateScan_WithSCSSecretDetectionAndScorecardGithubRepoWithTokenInURL_scsMapHasBoth(t *testing.T) { - // Create a pipe for capturing stdout - r, w, _ := os.Pipe() - oldStdout := os.Stdout - defer func() { os.Stdout = oldStdout }() - os.Stdout = w // Redirecting stdout to the pipe - - var resubmitConfig []wrappers.Config - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", - Long: `Scan a project`, +func TestAddSCSScan_WithSCSSecretDetectionAndScorecardGithubRepoWithTokenInURL_scsMapHasBoth(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") - _ = cmdCommand.Execute() - _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") - _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyRepoWithToken) - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a pipe for capturing stdout + r, w, _ := os.Pipe() + oldStdout := os.Stdout + defer func() { os.Stdout = oldStdout }() + os.Stdout = w // Redirecting stdout to the pipe + + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } + cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") + _ = cmdCommand.Execute() + _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") + _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyRepoWithToken) - // Close the writer to signal that we are done capturing the output - w.Close() + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) - // Read from the pipe (stdout) - var buf bytes.Buffer - _, err := io.Copy(&buf, r) // Copy the captured output to a buffer - if err != nil { - t.Fatalf("Failed to capture output: %v", err) - } + // Close the writer to signal that we are done capturing the output + w.Close() - output := buf.String() - if strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { - t.Errorf("Expected output to not contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) - } + // Read from the pipe (stdout) + var buf bytes.Buffer + _, err := io.Copy(&buf, r) // Copy the captured output to a buffer + if err != nil { + t.Fatalf("Failed to capture output: %v", err) + } - scsConfig := wrappers.SCSConfig{ - Twoms: "true", - Scorecard: "true", - RepoURL: dummyRepoWithToken, - RepoToken: dummyToken, - } - scsMapConfig := make(map[string]interface{}) - scsMapConfig[resultsMapType] = commonParams.MicroEnginesType - scsMapConfig[resultsMapValue] = &scsConfig + output := buf.String() + if strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { + t.Errorf("Expected output to not contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) + } + + scsConfig := wrappers.SCSConfig{ + Twoms: "true", + Scorecard: "true", + RepoURL: dummyRepoWithToken, + RepoToken: dummyToken, + } + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig - if !reflect.DeepEqual(result, scsMapConfig) { - t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } } -func TestCreateScan_WithSCSSecretDetectionAndScorecardGithubRepoWithTokenAndUsernameInURL_scsMapHasBoth(t *testing.T) { - // Create a pipe for capturing stdout - r, w, _ := os.Pipe() - oldStdout := os.Stdout - defer func() { os.Stdout = oldStdout }() - os.Stdout = w // Redirecting stdout to the pipe - - var resubmitConfig []wrappers.Config - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", - Long: `Scan a project`, +func TestAddSCSScan_WithSCSSecretDetectionAndScorecardGithubRepoWithTokenAndUsernameInURL_scsMapHasBoth(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") - _ = cmdCommand.Execute() - _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") - _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyRepoWithTokenAndUsername) - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a pipe for capturing stdout + r, w, _ := os.Pipe() + oldStdout := os.Stdout + defer func() { os.Stdout = oldStdout }() + os.Stdout = w // Redirecting stdout to the pipe - // Close the writer to signal that we are done capturing the output - w.Close() + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } + cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") + _ = cmdCommand.Execute() + _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") + _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyRepoWithTokenAndUsername) - // Read from the pipe (stdout) - var buf bytes.Buffer - _, err := io.Copy(&buf, r) // Copy the captured output to a buffer - if err != nil { - t.Fatalf("Failed to capture output: %v", err) - } + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) - output := buf.String() - if strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { - t.Errorf("Expected output to not contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) - } + // Close the writer to signal that we are done capturing the output + w.Close() - scsConfig := wrappers.SCSConfig{ - Twoms: "true", - Scorecard: "true", - RepoURL: dummyRepoWithTokenAndUsername, - RepoToken: dummyToken, - } - scsMapConfig := make(map[string]interface{}) - scsMapConfig[resultsMapType] = commonParams.MicroEnginesType - scsMapConfig[resultsMapValue] = &scsConfig + // Read from the pipe (stdout) + var buf bytes.Buffer + _, err := io.Copy(&buf, r) // Copy the captured output to a buffer + if err != nil { + t.Fatalf("Failed to capture output: %v", err) + } + + output := buf.String() + if strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { + t.Errorf("Expected output to not contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) + } + + scsConfig := wrappers.SCSConfig{ + Twoms: "true", + Scorecard: "true", + RepoURL: dummyRepoWithTokenAndUsername, + RepoToken: dummyToken, + } + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig - if !reflect.DeepEqual(result, scsMapConfig) { - t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } } -func TestCreateScan_WithSCSSecretDetectionAndScorecardShortenedGithubRepoWithTokenAndUsernameInURL_scsMapHasBoth(t *testing.T) { - // Create a pipe for capturing stdout - r, w, _ := os.Pipe() - oldStdout := os.Stdout - defer func() { os.Stdout = oldStdout }() - os.Stdout = w // Redirecting stdout to the pipe - - var resubmitConfig []wrappers.Config - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", - Long: `Scan a project`, +func TestAddSCSScan_WithSCSSecretDetectionAndScorecardShortenedGithubRepoWithTokenAndUsernameInURL_scsMapHasBoth(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") - _ = cmdCommand.Execute() - _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") - _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyShortenedRepoWithTokenAndUsername) - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a pipe for capturing stdout + r, w, _ := os.Pipe() + oldStdout := os.Stdout + defer func() { os.Stdout = oldStdout }() + os.Stdout = w // Redirecting stdout to the pipe - // Close the writer to signal that we are done capturing the output - w.Close() + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } + cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") + _ = cmdCommand.Execute() + _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") + _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyShortenedRepoWithTokenAndUsername) - // Read from the pipe (stdout) - var buf bytes.Buffer - _, err := io.Copy(&buf, r) // Copy the captured output to a buffer - if err != nil { - t.Fatalf("Failed to capture output: %v", err) - } + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) - output := buf.String() - if strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { - t.Errorf("Expected output to not contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) - } + // Close the writer to signal that we are done capturing the output + w.Close() - scsConfig := wrappers.SCSConfig{ - Twoms: "true", - Scorecard: "true", - RepoURL: dummyShortenedRepoWithTokenAndUsername, - RepoToken: dummyToken, - } - scsMapConfig := make(map[string]interface{}) - scsMapConfig[resultsMapType] = commonParams.MicroEnginesType - scsMapConfig[resultsMapValue] = &scsConfig + // Read from the pipe (stdout) + var buf bytes.Buffer + _, err := io.Copy(&buf, r) // Copy the captured output to a buffer + if err != nil { + t.Fatalf("Failed to capture output: %v", err) + } + + output := buf.String() + if strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { + t.Errorf("Expected output to not contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) + } + + scsConfig := wrappers.SCSConfig{ + Twoms: "true", + Scorecard: "true", + RepoURL: dummyShortenedRepoWithTokenAndUsername, + RepoToken: dummyToken, + } + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig - if !reflect.DeepEqual(result, scsMapConfig) { - t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } } -func TestCreateScan_WithSCSSecretDetectionAndScorecardGitLabRepo_scsMapHasSecretDetection(t *testing.T) { - // Create a pipe for capturing stdout - r, w, _ := os.Pipe() - oldStdout := os.Stdout - defer func() { os.Stdout = oldStdout }() - os.Stdout = w // Redirecting stdout to the pipe - - var resubmitConfig []wrappers.Config - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", - Long: `Scan a project`, +func TestAddSCSScan_WithSCSSecretDetectionAndScorecardGitLabRepo_scsMapHasSecretDetection(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") - _ = cmdCommand.Execute() - _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") - _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyGitlabRepo) - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a pipe for capturing stdout + r, w, _ := os.Pipe() + oldStdout := os.Stdout + defer func() { os.Stdout = oldStdout }() + os.Stdout = w // Redirecting stdout to the pipe - // Close the writer to signal that we are done capturing the output - w.Close() + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } + cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") + _ = cmdCommand.Execute() + _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") + _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummyGitlabRepo) - // Read from the pipe (stdout) - var buf bytes.Buffer - _, err := io.Copy(&buf, r) // Copy the captured output to a buffer - if err != nil { - t.Fatalf("Failed to capture output: %v", err) - } + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) - output := buf.String() - if !strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { - t.Errorf("Expected output to contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) - } + // Close the writer to signal that we are done capturing the output + w.Close() - scsConfig := wrappers.SCSConfig{ - Twoms: "true", - Scorecard: "", - RepoURL: "", - RepoToken: "", - } - scsMapConfig := make(map[string]interface{}) - scsMapConfig[resultsMapType] = commonParams.MicroEnginesType - scsMapConfig[resultsMapValue] = &scsConfig + // Read from the pipe (stdout) + var buf bytes.Buffer + _, err := io.Copy(&buf, r) // Copy the captured output to a buffer + if err != nil { + t.Fatalf("Failed to capture output: %v", err) + } + + output := buf.String() + if !strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { + t.Errorf("Expected output to contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) + } - if !reflect.DeepEqual(result, scsMapConfig) { - t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + scsConfig := wrappers.SCSConfig{ + Twoms: "true", + Scorecard: "", + RepoURL: "", + RepoToken: "", + } + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig + + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } } -func TestCreateScan_WithSCSSecretDetectionAndScorecardGitSSHRepo_scsMapHasSecretDetection(t *testing.T) { - // Create a pipe for capturing stdout - r, w, _ := os.Pipe() - oldStdout := os.Stdout - defer func() { os.Stdout = oldStdout }() - os.Stdout = w // Redirecting stdout to the pipe - - var resubmitConfig []wrappers.Config - cmdCommand := &cobra.Command{ - Use: "scan", - Short: "Scan a project", - Long: `Scan a project`, +func TestAddSCSScan_WithSCSSecretDetectionAndScorecardGitSSHRepo_scsMapHasSecretDetection(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + }{ + { + name: "scsLicensingV2 disabled", + scsLicensingV2: false, + hasRepositoryHealthLicense: false, + hasSecretDetectionLicense: false, + hasEnterpriseSecretsLicense: true, + }, + { + name: "scsLicensingV2 enabled", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + hasSecretDetectionLicense: true, + hasEnterpriseSecretsLicense: false, + }, } - cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") - cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") - _ = cmdCommand.Execute() - _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") - _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) - _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummySSHRepo) - result, _ := addSCSScan(cmdCommand, resubmitConfig, true) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a pipe for capturing stdout + r, w, _ := os.Pipe() + oldStdout := os.Stdout + defer func() { os.Stdout = oldStdout }() + os.Stdout = w // Redirecting stdout to the pipe + + var resubmitConfig []wrappers.Config + cmdCommand := &cobra.Command{ + Use: "scan", + Short: "Scan a project", + Long: `Scan a project`, + } + cmdCommand.PersistentFlags().String(commonParams.SCSEnginesFlag, "", "SCS Engine flag") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoTokenFlag, "", "GitHub token to be used with SCS engines") + cmdCommand.PersistentFlags().String(commonParams.SCSRepoURLFlag, "", "GitHub url to be used with SCS engines") + _ = cmdCommand.Execute() + _ = cmdCommand.Flags().Set(commonParams.SCSEnginesFlag, "secret-detection,scorecard") + _ = cmdCommand.Flags().Set(commonParams.SCSRepoTokenFlag, dummyToken) + _ = cmdCommand.Flags().Set(commonParams.SCSRepoURLFlag, dummySSHRepo) - // Close the writer to signal that we are done capturing the output - w.Close() + result, _ := addSCSScan(cmdCommand, resubmitConfig, tt.scsLicensingV2, + tt.hasRepositoryHealthLicense, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense) - // Read from the pipe (stdout) - var buf bytes.Buffer - _, err := io.Copy(&buf, r) // Copy the captured output to a buffer - if err != nil { - t.Fatalf("Failed to capture output: %v", err) - } + // Close the writer to signal that we are done capturing the output + w.Close() - output := buf.String() - if !strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { - t.Errorf("Expected output to contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) - } + // Read from the pipe (stdout) + var buf bytes.Buffer + _, err := io.Copy(&buf, r) // Copy the captured output to a buffer + if err != nil { + t.Fatalf("Failed to capture output: %v", err) + } - scsConfig := wrappers.SCSConfig{ - Twoms: "true", - Scorecard: "", - RepoURL: "", - RepoToken: "", - } - scsMapConfig := make(map[string]interface{}) - scsMapConfig[resultsMapType] = commonParams.MicroEnginesType - scsMapConfig[resultsMapValue] = &scsConfig + output := buf.String() + if !strings.Contains(output, ScsScorecardUnsupportedHostWarningMsg) { + t.Errorf("Expected output to contain %q, but got %q", ScsScorecardUnsupportedHostWarningMsg, output) + } - if !reflect.DeepEqual(result, scsMapConfig) { - t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + scsConfig := wrappers.SCSConfig{ + Twoms: "true", + Scorecard: "", + RepoURL: "", + RepoToken: "", + } + scsMapConfig := make(map[string]interface{}) + scsMapConfig[resultsMapType] = commonParams.MicroEnginesType + scsMapConfig[resultsMapValue] = &scsConfig + + if !reflect.DeepEqual(result, scsMapConfig) { + t.Errorf("Expected %+v, but got %+v", scsMapConfig, result) + } + }) } } @@ -2433,33 +2848,139 @@ func TestValidateScanTypes(t *testing.T) { userScanTypes string userSCSScanTypes string allowedEngines map[string]bool + scsLicensingV2 bool expectedError string }{ { - name: "No licenses available", + name: "no specific micro engines selected with no licenses available using new sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "", + allowedEngines: map[string]bool{"repository-health": false, "secret-detection": false}, + scsLicensingV2: true, + expectedError: "This requires either the \"repository‑health\" or the \"secret‑detection\" package license", + }, + { + name: "no specific micro engines selected with repository-health license available using new sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "", + allowedEngines: map[string]bool{"repository-health": true, "secret-detection": false}, + scsLicensingV2: true, + expectedError: "", + }, + { + name: "no specific micro engines selected with secret-detection license available using new sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "", + allowedEngines: map[string]bool{"repository-health": false, "secret-detection": true}, + scsLicensingV2: true, + expectedError: "", + }, + { + name: "no specific micro engines selected with all licenses available using new sscs licensing", userScanTypes: "scs", - userSCSScanTypes: "sast,secret-detection", + userSCSScanTypes: "", + allowedEngines: map[string]bool{"repository-health": true, "secret-detection": true}, + scsLicensingV2: true, + expectedError: "", + }, + { + name: "no specific micro engines selected with no licenses available using old sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "", allowedEngines: map[string]bool{"scs": false, "enterprise-secrets": false}, - expectedError: "It looks like the \"scs\" scan type does", + scsLicensingV2: false, + expectedError: "It looks like the \"scs\" scan type does not exist or", + }, + { + name: "no specific micro engines selected with scs license available using old sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "", + allowedEngines: map[string]bool{"scs": true, "enterprise-secrets": false}, + scsLicensingV2: false, + expectedError: "", }, { - name: "SCS license available, secret-detection not available", + name: "no specific micro engines selected with all licenses available using old sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "", + allowedEngines: map[string]bool{"scs": true, "enterprise-secrets": true}, + scsLicensingV2: false, + expectedError: "", + }, + { + name: "scorecard and secret-detection selected with no licenses available using old sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "scorecard,secret-detection", + allowedEngines: map[string]bool{"scs": false, "enterprise-secrets": false}, + scsLicensingV2: false, + expectedError: "It looks like the \"scs\" scan type does not exist or", + }, + { + name: "scorecard and secret-detection selected with no licenses available using new sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "scorecard,secret-detection", + allowedEngines: map[string]bool{"repository-health": false, "secret-detection": false}, + scsLicensingV2: true, + expectedError: "It looks like the \"secret-detection\" scan type does not exist or", + }, + { + name: "secret-detection selected with SCS license available, secret-detection not available using old sscs licensing", userScanTypes: "scs", userSCSScanTypes: "secret-detection", allowedEngines: map[string]bool{"scs": true, "enterprise-secrets": false}, - expectedError: "It looks like the \"secret-detection\" scan type does not exist", + scsLicensingV2: false, + expectedError: "It looks like the \"secret-detection\" scan type does not exist or", + }, + { + name: "secret-detection selected with repository-health license available, secret-detection not available using new sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "secret-detection", + allowedEngines: map[string]bool{"repository-health": true, "secret-detection": false}, + scsLicensingV2: true, + expectedError: "It looks like the \"secret-detection\" scan type does not exist or", + }, + { + name: "scorecard selected with secret-detection license available and repository-health not available using new sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "scorecard", + allowedEngines: map[string]bool{"repository-health": false, "secret-detection": true}, + scsLicensingV2: true, + expectedError: "It looks like the \"repository-health\" scan type does not exist or", }, { - name: "All licenses available", + name: "secret-detection selected with all licenses available using old sscs licensing", userScanTypes: "scs", userSCSScanTypes: "secret-detection", allowedEngines: map[string]bool{"scs": true, "enterprise-secrets": true}, + scsLicensingV2: false, + expectedError: "", + }, + { + name: "secret-detection selected with secret-detection license available using new sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "secret-detection", + allowedEngines: map[string]bool{"repository-health": false, "secret-detection": true}, + scsLicensingV2: true, + expectedError: "", + }, + { + name: "scorecard selected with repository-health license available using new sscs licensing", + userScanTypes: "scs", + userSCSScanTypes: "scorecard", + allowedEngines: map[string]bool{"repository-health": true, "secret-detection": false}, + scsLicensingV2: true, expectedError: "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + wrappers.ClearCache() + mock.Flag = wrappers.FeatureFlagResponseModel{ + Name: wrappers.ScsLicensingV2Enabled, + Status: tt.scsLicensingV2, + } + cmd := &cobra.Command{} cmd.Flags().String(commonParams.ScanTypes, tt.userScanTypes, "") cmd.Flags().String(commonParams.SCSEnginesFlag, tt.userSCSScanTypes, "") @@ -2469,6 +2990,7 @@ func TestValidateScanTypes(t *testing.T) { return tt.allowedEngines, nil }, } + featureFlagsWrapper := &mock.FeatureFlagsMockWrapper{} err := validateScanTypes(cmd, jwtWrapper, featureFlagsWrapper) if tt.expectedError != "" { @@ -2480,6 +3002,100 @@ func TestValidateScanTypes(t *testing.T) { } } +func TestIsScsScorecardAllowed(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasRepositoryHealthLicense bool + hasScsLicense bool + expectedAllowed bool + }{ + { + name: "scsLicensingV2 disabled and has scs license", + scsLicensingV2: false, + hasScsLicense: true, + expectedAllowed: true, + }, + { + name: "scsLicensingV2 disabled and does not have scs license", + scsLicensingV2: false, + hasScsLicense: false, + expectedAllowed: false, + }, + { + name: "scsLicensingV2 enabled and has repository health license", + scsLicensingV2: true, + hasRepositoryHealthLicense: true, + expectedAllowed: true, + }, + { + name: "scsLicensingV2 enabled and does not have repository health license", + scsLicensingV2: true, + hasRepositoryHealthLicense: false, + expectedAllowed: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actualAllowed := isScsScorecardAllowed(tt.scsLicensingV2, tt.hasRepositoryHealthLicense, tt.hasScsLicense) + assert.Equal(t, tt.expectedAllowed, actualAllowed) + }) + } +} + +func TestIsScsSecretDetectionAllowed(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + hasSecretDetectionLicense bool + hasEnterpriseSecretsLicense bool + hasScsLicense bool + expectedAllowed bool + }{ + { + name: "scsLicensingV2 disabled and has scs and enterprise secrets license", + scsLicensingV2: false, + hasEnterpriseSecretsLicense: true, + hasScsLicense: true, + expectedAllowed: true, + }, + { + name: "scsLicensingV2 disabled and has enterprise secrets but does not have scs license", + scsLicensingV2: false, + hasEnterpriseSecretsLicense: true, + hasScsLicense: false, + expectedAllowed: false, + }, + { + name: "scsLicensingV2 disabled and has scs license but does not have enterprise secrets license", + scsLicensingV2: false, + hasEnterpriseSecretsLicense: false, + hasScsLicense: true, + expectedAllowed: false, + }, + { + name: "scsLicensingV2 enabled and has secret detection license", + scsLicensingV2: true, + hasSecretDetectionLicense: true, + expectedAllowed: true, + }, + { + name: "scsLicensingV2 enabled and does not have secret detection license", + scsLicensingV2: true, + hasSecretDetectionLicense: false, + expectedAllowed: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actualAllowed := isScsSecretDetectionAllowed(tt.scsLicensingV2, tt.hasSecretDetectionLicense, tt.hasEnterpriseSecretsLicense, tt.hasScsLicense) + assert.Equal(t, tt.expectedAllowed, actualAllowed) + }) + } +} + func TestCreateScanWith_ScaResolver_Source_as_Zip(t *testing.T) { clearFlags() baseArgs := []string{ diff --git a/internal/commands/util/configuration_test.go b/internal/commands/util/configuration_test.go index 8b50ae91c..a465ccd68 100644 --- a/internal/commands/util/configuration_test.go +++ b/internal/commands/util/configuration_test.go @@ -1,12 +1,13 @@ package util import ( - "github.com/checkmarx/ast-cli/internal/params" - "github.com/spf13/viper" "os" "strings" "testing" + "github.com/checkmarx/ast-cli/internal/params" + "github.com/spf13/viper" + "github.com/checkmarx/ast-cli/internal/wrappers/configuration" asserts "github.com/stretchr/testify/assert" "gotest.tools/assert" diff --git a/internal/commands/util/pr_test.go b/internal/commands/util/pr_test.go index 349092c84..2c3f910ce 100644 --- a/internal/commands/util/pr_test.go +++ b/internal/commands/util/pr_test.go @@ -1,9 +1,10 @@ package util import ( + "testing" + "github.com/checkmarx/ast-cli/internal/wrappers/mock" asserts "github.com/stretchr/testify/assert" - "testing" "gotest.tools/assert" ) diff --git a/internal/params/flags.go b/internal/params/flags.go index a9040efa5..7541e6d5f 100644 --- a/internal/params/flags.go +++ b/internal/params/flags.go @@ -293,8 +293,12 @@ const ( Success = "success" SCSScorecardType = "sscs-scorecard" SCSSecretDetectionType = "sscs-secret-detection" + SecretDetectionType = "secret-detection" + SecretDetectionLabel = "Secret Detection" EnterpriseSecretsLabel = "Enterprise Secrets" EnterpriseSecretsType = "enterprise-secrets" + RepositoryHealthType = "repository-health" + RepositoryHealthLabel = "Repository Health" SCSScorecardOverviewType = "Scorecard" SCSSecretDetectionOverviewType = "2ms" ) diff --git a/internal/wrappers/feature-flags.go b/internal/wrappers/feature-flags.go index 7b8c4ce4d..a243db0f9 100644 --- a/internal/wrappers/feature-flags.go +++ b/internal/wrappers/feature-flags.go @@ -15,6 +15,7 @@ const SastCustomStateEnabled = "SAST_CUSTOM_STATES_ENABLED" const SCSEngineCLIEnabled = "NEW_2MS_SCORECARD_RESULTS_CLI_ENABLED" const RiskManagementEnabled = "RISK_MANAGEMENT_IDES_PROJECT_RESULTS_SCORES_API_ENABLED" const OssRealtimeEnabled = "OSS_REALTIME_ENABLED" +const ScsLicensingV2Enabled = "SSCS_NEW_LICENSING_ENABLED" const maxRetries = 3 var DefaultFFLoad bool = false diff --git a/internal/wrappers/jwt-helper.go b/internal/wrappers/jwt-helper.go index 9a964529d..7a3ec506f 100644 --- a/internal/wrappers/jwt-helper.go +++ b/internal/wrappers/jwt-helper.go @@ -21,18 +21,6 @@ type JWTStruct struct { jwt.RegisteredClaims // Embedding the standard claims } -var enabledEngines = []string{"sast", "sca", "api-security", "iac-security", "scs", "containers", "enterprise-secrets"} - -var defaultEngines = map[string]bool{ - "sast": true, - "sca": true, - "api-security": true, - "iac-security": true, - "containers": true, - "scs": true, - "enterprise-secrets": true, -} - type JWTWrapper interface { GetAllowedEngines(featureFlagsWrapper FeatureFlagsWrapper) (allowedEngines map[string]bool, err error) IsAllowedEngine(engine string) (bool, error) @@ -44,19 +32,48 @@ func NewJwtWrapper() JWTWrapper { return &JWTStruct{} } +func getEnabledEngines(scsLicensingV2 bool) (enabledEngines []string) { + enabledEngines = []string{"sast", "sca", "api-security", "iac-security", "containers"} + if scsLicensingV2 { + enabledEngines = append(enabledEngines, commonParams.RepositoryHealthType, commonParams.SecretDetectionType) + } else { + enabledEngines = append(enabledEngines, commonParams.ScsType, commonParams.EnterpriseSecretsType) + } + return enabledEngines +} + +func getDefaultEngines(scsLicensingV2 bool) (defaultEngines map[string]bool) { + defaultEngines = map[string]bool{ + "sast": true, + "sca": true, + "api-security": true, + "iac-security": true, + "containers": true, + } + if scsLicensingV2 { + defaultEngines[commonParams.RepositoryHealthType] = true + defaultEngines[commonParams.SecretDetectionType] = true + } else { + defaultEngines[commonParams.ScsType] = true + defaultEngines[commonParams.EnterpriseSecretsType] = true + } + return defaultEngines +} + // GetAllowedEngines will return a map with user allowed engines func (*JWTStruct) GetAllowedEngines(featureFlagsWrapper FeatureFlagsWrapper) (allowedEngines map[string]bool, err error) { + scsLicensingV2Flag, _ := GetSpecificFeatureFlag(featureFlagsWrapper, ScsLicensingV2Enabled) flagResponse, _ := GetSpecificFeatureFlag(featureFlagsWrapper, PackageEnforcementEnabled) if flagResponse.Status { jwtStruct, err := getJwtStruct() if err != nil { return nil, err } - allowedEngines = prepareEngines(jwtStruct.AstLicense.LicenseData.AllowedEngines) + allowedEngines = prepareEngines(jwtStruct.AstLicense.LicenseData.AllowedEngines, scsLicensingV2Flag.Status) return allowedEngines, nil } - return defaultEngines, nil + return getDefaultEngines(scsLicensingV2Flag.Status), nil } func getJwtStruct() (*JWTStruct, error) { @@ -82,14 +99,20 @@ func (*JWTStruct) IsAllowedEngine(engine string) (bool, error) { return false, nil } -func prepareEngines(engines []string) map[string]bool { +func prepareEngines(engines []string, scsLicensingV2 bool) map[string]bool { m := make(map[string]bool) for _, value := range engines { engine := strings.Replace(strings.ToLower(value), strings.ToLower(commonParams.APISecurityLabel), commonParams.APISecurityType, 1) - engine = strings.Replace(strings.ToLower(engine), strings.ToLower(commonParams.EnterpriseSecretsLabel), commonParams.EnterpriseSecretsType, 1) engine = strings.Replace(strings.ToLower(engine), commonParams.KicsType, commonParams.IacType, 1) + if scsLicensingV2 { + engine = strings.Replace(strings.ToLower(engine), strings.ToLower(commonParams.RepositoryHealthLabel), commonParams.RepositoryHealthType, 1) + engine = strings.Replace(strings.ToLower(engine), strings.ToLower(commonParams.SecretDetectionLabel), commonParams.SecretDetectionType, 1) + } else { + engine = strings.Replace(strings.ToLower(engine), strings.ToLower(commonParams.EnterpriseSecretsLabel), commonParams.EnterpriseSecretsType, 1) + } // Current limitation, CxOne is including non-engines in the JWT + enabledEngines := getEnabledEngines(scsLicensingV2) if utils.Contains(enabledEngines, strings.ToLower(engine)) { m[strings.ToLower(engine)] = true } diff --git a/internal/wrappers/jwt-helper_test.go b/internal/wrappers/jwt-helper_test.go new file mode 100644 index 000000000..8bf721983 --- /dev/null +++ b/internal/wrappers/jwt-helper_test.go @@ -0,0 +1,73 @@ +package wrappers + +import ( + "testing" + + "gotest.tools/assert" +) + +func TestGetDefaultEngines(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + expectedEngines map[string]bool + }{ + { + name: "using new sscs licensing", + scsLicensingV2: true, + expectedEngines: map[string]bool{ + "sast": true, + "sca": true, + "api-security": true, + "iac-security": true, + "containers": true, + "repository-health": true, + "secret-detection": true, + }, + }, + { + name: "using old sscs licensing", + scsLicensingV2: false, + expectedEngines: map[string]bool{ + "sast": true, + "sca": true, + "api-security": true, + "iac-security": true, + "containers": true, + "scs": true, + "enterprise-secrets": true, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actualEngines := getDefaultEngines(tt.scsLicensingV2) + assert.Equal(t, tt.expectedEngines, actualEngines) + }) + } +} + +func TestGetEnabledEngines(t *testing.T) { + tests := []struct { + name string + scsLicensingV2 bool + expectedEngines []string + }{ + { + name: "using new sscs licensing", + scsLicensingV2: true, + expectedEngines: []string{"sast", "sca", "api-security", "iac-security", "containers", "repository-health", "secret-detection"}, + }, + { + name: "using old sscs licensing", + scsLicensingV2: false, + expectedEngines: []string{"sast", "sca", "api-security", "iac-security", "containers", "scs", "enterprise-secrets"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actualEngines := getDefaultEngines(tt.scsLicensingV2) + assert.Equal(t, tt.expectedEngines, actualEngines) + }) + } +} diff --git a/internal/wrappers/mock/access-management-mock.go b/internal/wrappers/mock/access-management-mock.go index 737b70231..f1ffddaf2 100644 --- a/internal/wrappers/mock/access-management-mock.go +++ b/internal/wrappers/mock/access-management-mock.go @@ -2,6 +2,7 @@ package mock import ( "fmt" + "github.com/checkmarx/ast-cli/internal/logger" "github.com/checkmarx/ast-cli/internal/wrappers" diff --git a/internal/wrappers/mock/custom-states-mock.go b/internal/wrappers/mock/custom-states-mock.go index 6955527f6..d476a518e 100644 --- a/internal/wrappers/mock/custom-states-mock.go +++ b/internal/wrappers/mock/custom-states-mock.go @@ -1,7 +1,9 @@ package mock -import "github.com/checkmarx/ast-cli/internal/wrappers" -import "github.com/pkg/errors" +import ( + "github.com/checkmarx/ast-cli/internal/wrappers" + "github.com/pkg/errors" +) type CustomStatesMockWrapper struct{} diff --git a/internal/wrappers/mock/jwt-helper-mock.go b/internal/wrappers/mock/jwt-helper-mock.go index b7ed88970..2ef794c48 100644 --- a/internal/wrappers/mock/jwt-helper-mock.go +++ b/internal/wrappers/mock/jwt-helper-mock.go @@ -21,7 +21,8 @@ var engines = []string{"sast", "sca", "api-security", "iac-security", "scs", "co // GetAllowedEngines mock for tests func (j *JWTMockWrapper) GetAllowedEngines(featureFlagsWrapper wrappers.FeatureFlagsWrapper) (allowedEngines map[string]bool, err error) { if j.CustomGetAllowedEngines != nil { - return j.CustomGetAllowedEngines(featureFlagsWrapper) + allowedEngines, err = j.CustomGetAllowedEngines(featureFlagsWrapper) + return allowedEngines, err } allowedEngines = make(map[string]bool) diff --git a/internal/wrappers/mock/uploads-mock.go b/internal/wrappers/mock/uploads-mock.go index 0683e4408..59fc41bbb 100644 --- a/internal/wrappers/mock/uploads-mock.go +++ b/internal/wrappers/mock/uploads-mock.go @@ -2,6 +2,7 @@ package mock import ( "fmt" + "github.com/pkg/errors" "github.com/checkmarx/ast-cli/internal/wrappers" diff --git a/internal/wrappers/projects-http.go b/internal/wrappers/projects-http.go index 556444b6f..e618b5062 100644 --- a/internal/wrappers/projects-http.go +++ b/internal/wrappers/projects-http.go @@ -4,11 +4,12 @@ import ( "bytes" "encoding/json" "fmt" - "github.com/pkg/errors" - "github.com/spf13/viper" "net/http" "time" + "github.com/pkg/errors" + "github.com/spf13/viper" + errorConstants "github.com/checkmarx/ast-cli/internal/constants/errors" commonParams "github.com/checkmarx/ast-cli/internal/params" ) diff --git a/internal/wrappers/risk-management-http.go b/internal/wrappers/risk-management-http.go index e6d6a3085..0e0f64bb3 100644 --- a/internal/wrappers/risk-management-http.go +++ b/internal/wrappers/risk-management-http.go @@ -3,9 +3,10 @@ package wrappers import ( "encoding/json" "fmt" + "net/http" + "github.com/checkmarx/ast-cli/internal/logger" "github.com/checkmarx/ast-cli/internal/wrappers/configuration" - "net/http" commonParams "github.com/checkmarx/ast-cli/internal/params" "github.com/pkg/errors" diff --git a/internal/wrappers/scan-overview-http.go b/internal/wrappers/scan-overview-http.go index 28246ec10..9989ef94c 100644 --- a/internal/wrappers/scan-overview-http.go +++ b/internal/wrappers/scan-overview-http.go @@ -3,9 +3,10 @@ package wrappers import ( "encoding/json" "fmt" + "net/http" + "github.com/checkmarx/ast-cli/internal/logger" "github.com/checkmarx/ast-cli/internal/wrappers/configuration" - "net/http" commonParams "github.com/checkmarx/ast-cli/internal/params" "github.com/pkg/errors" diff --git a/internal/wrappers/scans-http.go b/internal/wrappers/scans-http.go index c16ec0a07..009310aef 100644 --- a/internal/wrappers/scans-http.go +++ b/internal/wrappers/scans-http.go @@ -4,10 +4,11 @@ import ( "bytes" "encoding/json" "fmt" + "net/http" + commonParams "github.com/checkmarx/ast-cli/internal/params" "github.com/pkg/errors" "github.com/spf13/viper" - "net/http" ) const ( diff --git a/test/integration/configuration_test.go b/test/integration/configuration_test.go index 2e57a2748..d38c91faa 100644 --- a/test/integration/configuration_test.go +++ b/test/integration/configuration_test.go @@ -3,12 +3,13 @@ package integration import ( - "github.com/checkmarx/ast-cli/internal/wrappers/configuration" - "github.com/spf13/viper" - "gotest.tools/assert" "os" "strings" "testing" + + "github.com/checkmarx/ast-cli/internal/wrappers/configuration" + "github.com/spf13/viper" + "gotest.tools/assert" ) const filePath = "data/config.yaml" diff --git a/test/integration/pr_test.go b/test/integration/pr_test.go index 1d12dfa99..0fa20b0fe 100644 --- a/test/integration/pr_test.go +++ b/test/integration/pr_test.go @@ -4,11 +4,12 @@ package integration import ( "fmt" - "github.com/checkmarx/ast-cli/internal/wrappers" "os" "strings" "testing" + "github.com/checkmarx/ast-cli/internal/wrappers" + "github.com/checkmarx/ast-cli/internal/commands/util" "github.com/checkmarx/ast-cli/internal/logger" diff --git a/test/integration/telemetry_test.go b/test/integration/telemetry_test.go index 9bd5f1a87..4ff2805a8 100644 --- a/test/integration/telemetry_test.go +++ b/test/integration/telemetry_test.go @@ -3,9 +3,10 @@ package integration import ( + "testing" + "github.com/checkmarx/ast-cli/internal/params" "github.com/stretchr/testify/assert" - "testing" ) func TestTelemetryAI(t *testing.T) {