From 1b150db5b0d5114bb12f96a92bd410345384e093 Mon Sep 17 00:00:00 2001 From: kireetivar Date: Fri, 15 May 2026 13:38:48 +0530 Subject: [PATCH] fix: "aviator ssc audit" preflight issue counting for "--no-filterset" option --- .../ssc/cli/cmd/AviatorSSCAuditCommand.java | 14 ++++- .../ssc/helper/AviatorSSCAuditHelper.java | 21 ++++--- .../cli/cmd/AviatorSSCAuditCommandTest.java | 57 +++++++++++++++++++ 3 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 fcli-core/fcli-aviator/src/test/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCAuditCommandTest.java diff --git a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCAuditCommand.java b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCAuditCommand.java index a8f668050b2..73819f195ff 100644 --- a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCAuditCommand.java +++ b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCAuditCommand.java @@ -90,7 +90,7 @@ public JsonNode getJsonNode(UnirestInstance unirest) { refreshMetricsIfNeeded(unirest, av, logger); - long auditableIssueCount = AviatorSSCAuditHelper.getAuditableIssueCount(unirest, av, logger, noFilterSet, filterSetOptions, folderNames); + long auditableIssueCount = AviatorSSCAuditHelper.getAuditableIssueCount(unirest, av, logger, isNoFilterSet(), getFilterSetTitleOrId(), folderNames); if (auditableIssueCount == 0) { logger.progress("Audit skipped - no auditable issues found matching the specified filters."); ObjectNode result = AviatorSSCAuditHelper.buildResultNode(av, null, "SKIPPED"); @@ -122,6 +122,14 @@ public JsonNode getJsonNode(UnirestInstance unirest) { } } + String getFilterSetTitleOrId() { + return filterSetOptions.getFilterSetTitleOrId(); + } + + boolean isNoFilterSet() { + return noFilterSet; + } + private void refreshMetricsIfNeeded(UnirestInstance unirest, SSCAppVersionDescriptor av, AviatorLoggerImpl logger) { if (refreshOptions.isRefresh() && av.isRefreshRequired()) { logger.progress("Status: Metrics for application version %s:%s are out of date, starting refresh...", av.getApplicationName(), av.getVersionName()); @@ -245,8 +253,8 @@ private JsonNode processFpr(UnirestInstance unirest, SSCAppVersionDescriptor av, .sscAppVersion(av.getVersionName()) .logger(logger) .tagMappingPath(tagMapping) - .filterSetNameOrId(filterSetOptions.getFilterSetTitleOrId()) - .noFilterSet(noFilterSet) + .filterSetNameOrId(getFilterSetTitleOrId()) + .noFilterSet(isNoFilterSet()) .folderNames(folderNames) .folderPriorityOrder(folderPriorityOrder) .build()); diff --git a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/AviatorSSCAuditHelper.java b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/AviatorSSCAuditHelper.java index df21a6b07cb..542ee85bb86 100644 --- a/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/AviatorSSCAuditHelper.java +++ b/fcli-core/fcli-aviator/src/main/java/com/fortify/cli/aviator/ssc/helper/AviatorSSCAuditHelper.java @@ -38,7 +38,6 @@ import com.fortify.cli.common.rest.unirest.UnexpectedHttpResponseException; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc.appversion.helper.SSCAppVersionDescriptor; -import com.fortify.cli.ssc.issue.cli.mixin.SSCIssueFilterSetOptionMixin; import com.fortify.cli.ssc.issue.helper.SSCIssueFilterHelper; import com.fortify.cli.ssc.issue.helper.SSCIssueFilterSetDescriptor; import com.fortify.cli.ssc.issue.helper.SSCIssueFilterSetHelper; @@ -193,23 +192,28 @@ public static String getProgressMessage(FPRAuditResult auditResult) { /** * Queries SSC to get the number of auditable issues for a given application version. */ - public static long getAuditableIssueCount(UnirestInstance unirest, SSCAppVersionDescriptor av, AviatorLoggerImpl logger, boolean noFilterSet, SSCIssueFilterSetOptionMixin filterSetOptions, List folderNames) { + public static long getAuditableIssueCount(UnirestInstance unirest, SSCAppVersionDescriptor av, AviatorLoggerImpl logger, boolean noFilterSet, String filterSetTitleOrId, List folderNames) { logger.progress("Status: Checking for auditable issues..."); LOG.debug("Starting auditable issue count for SSC version {} (application='{}', version='{}') with pageLimit={}, noFilterSet={}", av.getVersionId(), av.getApplicationName(), av.getVersionName(), PAGE_LIMIT, noFilterSet); + String effectiveFilterSetTitleOrId = filterSetTitleOrId != null && !filterSetTitleOrId.isBlank() + ? filterSetTitleOrId + : null; + boolean effectiveNoFilterSet = noFilterSet && effectiveFilterSetTitleOrId == null; + // Apply filter set if specified SSCIssueFilterSetDescriptor filterSetDescriptor = null; String filterSetGuid = null; - if (!noFilterSet) { + if (!effectiveNoFilterSet) { SSCIssueFilterSetHelper filterSetHelper = new SSCIssueFilterSetHelper(unirest, av.getVersionId()); - filterSetDescriptor = filterSetHelper.getDescriptorByTitleOrId(filterSetOptions.getFilterSetTitleOrId(), false); + filterSetDescriptor = filterSetHelper.getDescriptorByTitleOrId(effectiveFilterSetTitleOrId, false); if (filterSetDescriptor != null) { logger.progress("Status: Applying filter set '%s' for issue count check", filterSetDescriptor.getTitle()); - filterSetGuid = filterSetDescriptor.getGuid(); + filterSetGuid = filterSetDescriptor.getGuid(); LOG.debug("Applied SSC filter set '{}' with guid {} while counting auditable issues for version {}", - filterSetDescriptor.getTitle(), filterSetGuid, av.getVersionId()); + filterSetDescriptor.getTitle(), filterSetGuid, av.getVersionId()); } else { LOG.debug("No SSC filter set resolved from options while counting auditable issues for version {}", av.getVersionId()); @@ -219,7 +223,7 @@ public static long getAuditableIssueCount(UnirestInstance unirest, SSCAppVersion // Apply folder filter if specified String folderFilter = null; if (folderNames != null && !folderNames.isEmpty()) { - folderFilter = getFolderFilter(noFilterSet, filterSetDescriptor, folderNames); + folderFilter = getFolderFilter(effectiveNoFilterSet, filterSetDescriptor, folderNames); logger.progress("Status: Applying folder filter for: %s", String.join(", ", folderNames)); LOG.debug("Applied folder filter '{}' for folders {} while counting auditable issues for version {}", folderFilter, folderNames, av.getVersionId()); @@ -237,6 +241,9 @@ public static long getAuditableIssueCount(UnirestInstance unirest, SSCAppVersion .queryString("qm", "issues") .queryString("q", "audited:false") .queryString("start", start); + if (effectiveNoFilterSet) { + request.queryString("showhidden", "true"); + } if (filterSetGuid != null) { request.queryString("filterset", filterSetGuid); } diff --git a/fcli-core/fcli-aviator/src/test/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCAuditCommandTest.java b/fcli-core/fcli-aviator/src/test/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCAuditCommandTest.java new file mode 100644 index 00000000000..e98fa9a5587 --- /dev/null +++ b/fcli-core/fcli-aviator/src/test/java/com/fortify/cli/aviator/ssc/cli/cmd/AviatorSSCAuditCommandTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2021-2026 Open Text. + * + * The only warranties for products and services of Open Text + * and its affiliates and licensors ("Open Text") are as may + * be set forth in the express warranty statements accompanying + * such products and services. Nothing herein should be construed + * as constituting an additional warranty. Open Text shall not be + * liable for technical or editorial errors or omissions contained + * herein. The information contained herein is subject to change + * without notice. + */ +package com.fortify.cli.aviator.ssc.cli.cmd; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Collections; + +import org.junit.jupiter.api.Test; + +import picocli.CommandLine; + +class AviatorSSCAuditCommandTest { + @Test + void testAllowsCombinedFilterOptions() { + var cmd = parse("--filterset", "Security Auditor View", "--no-filterset"); + assertEquals("Security Auditor View", cmd.getFilterSetTitleOrId()); + assertTrue(cmd.isNoFilterSet()); + } + + @Test + void testAllowsFilterSetOption() { + var cmd = parse("--filterset", "Security Auditor View"); + assertEquals("Security Auditor View", cmd.getFilterSetTitleOrId()); + assertFalse(cmd.isNoFilterSet()); + } + + @Test + void testAllowsNoFilterSetOption() { + var cmd = parse("--no-filterset"); + assertTrue(cmd.isNoFilterSet()); + assertNull(cmd.getFilterSetTitleOrId()); + } + + private static AviatorSSCAuditCommand parse(String... args) { + var cmd = new AviatorSSCAuditCommand(); + var fullArgs = new ArrayList(); + Collections.addAll(fullArgs, "--av", "test:1.0"); + Collections.addAll(fullArgs, args); + new CommandLine(cmd).parseArgs(fullArgs.toArray(String[]::new)); + return cmd; + } +} \ No newline at end of file