From d74fe5e55add941d3e896b336b9ccb20ed3be50f Mon Sep 17 00:00:00 2001 From: Eric Fitzgerald Date: Fri, 28 Nov 2025 20:11:32 -0500 Subject: [PATCH] fix: CLI --server parameter should take priority over OpenAPI servers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When both CLI --server and OpenAPI spec contain server URLs, the CLI parameter should take precedence. Previously, concrete OpenAPI server URLs would override the CLI parameter, which was unexpected behavior. This fix ensures: - CLI --server always has highest priority when it's a concrete URL - OpenAPI servers with placeholders (e.g., {apiRoot}/v2) are used for template replacement when CLI --server is provided - OpenAPI servers with relative paths are combined with CLI --server - OpenAPI servers only used as-is when CLI --server not provided Changes: - ApiArguments.java: Enhanced server priority logic to distinguish between placeholder/relative URLs and concrete URLs - ApiArgumentsTest.java: Includes regression test for CLI server priority and placeholder replacement Test Results: - All 11 tests in ApiArgumentsTest passing - Verified placeholder replacement: {apiRoot}/v2 + http://api.com = http://api.com/v2 - Verified CLI priority: CLI http://localhost:8080 overrides OpenAPI https://api.example.com 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../com/endava/cats/args/ApiArguments.java | 17 +++++++++++++++-- .../com/endava/cats/args/ApiArgumentsTest.java | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/endava/cats/args/ApiArguments.java b/src/main/java/com/endava/cats/args/ApiArguments.java index d30e2143..e2f33895 100644 --- a/src/main/java/com/endava/cats/args/ApiArguments.java +++ b/src/main/java/com/endava/cats/args/ApiArguments.java @@ -94,8 +94,21 @@ public void validateValidServer(CommandLine.Model.CommandSpec spec, OpenAPI open if (openAPI != null) { List servers = OpenApiServerExtractor.getServerUrls(openAPI); - log.debug("--server not provided. Loaded from OpenAPI: {}", servers); - servers.stream().findFirst().ifPresent(theServer -> this.server = theServer); + log.debug("Servers from OpenAPI: {}", servers); + + if (serverFromInput == null) { + // No CLI server provided, use OpenAPI server + servers.stream().findFirst().ifPresent(theServer -> this.server = theServer); + } else { + // CLI server provided, check if OpenAPI server has placeholders or relative paths + servers.stream().findFirst().ifPresent(openApiServer -> { + if (openApiServer.contains("{") || !openApiServer.startsWith("http")) { + // OpenAPI server has placeholders or is relative, use it for replacement + this.server = openApiServer; + } + // Otherwise keep CLI server (concrete OpenAPI URLs don't override CLI) + }); + } } if (this.server != null && serverFromInput != null) { diff --git a/src/test/java/com/endava/cats/args/ApiArgumentsTest.java b/src/test/java/com/endava/cats/args/ApiArgumentsTest.java index cdf03d3d..e760564e 100644 --- a/src/test/java/com/endava/cats/args/ApiArgumentsTest.java +++ b/src/test/java/com/endava/cats/args/ApiArgumentsTest.java @@ -98,6 +98,24 @@ void shouldReplaceServerPlaceholder() { Assertions.assertThat(args.getServer()).isEqualTo("http://api.com/v2"); } + @Test + void shouldPreferCliServerOverOpenApiConcreteServer() { + CommandLine.Model.CommandSpec spec = Mockito.mock(CommandLine.Model.CommandSpec.class); + Mockito.when(spec.commandLine()).thenReturn(Mockito.mock(CommandLine.class)); + ApiArguments args = new ApiArguments(); + args.setServer("http://localhost:8080"); + + OpenAPI openAPI = new OpenAPI(); + openAPI.setServers(Collections.singletonList( + new io.swagger.v3.oas.models.servers.Server().url("https://api.example.com") + )); + + args.validateValidServer(spec, openAPI); + + // CLI server should take priority over concrete OpenAPI server + Assertions.assertThat(args.getServer()).isEqualTo("http://localhost:8080"); + } + @Test void shouldThrowExceptionWhenServerIsInvalidUrl() { CommandLine.Model.CommandSpec spec = Mockito.mock(CommandLine.Model.CommandSpec.class);