diff --git a/openspec/changes/igdd-3084-swagger-ui-version-sync/tasks.md b/openspec/changes/igdd-3084-swagger-ui-version-sync/tasks.md new file mode 100644 index 0000000000..3fb631b707 --- /dev/null +++ b/openspec/changes/igdd-3084-swagger-ui-version-sync/tasks.md @@ -0,0 +1,236 @@ +--- +schema_version: '1.0' +created: + date: '2026-08-27T02:18:24.000Z' + user: tyoung + agent: + name: claude-code + version: '2.1.238' + llm: + name: claude-sonnet-5 + version: '5' + source: >- + user request: convert the IGDD-3084 swagger-ui version-sync design and its izgw-hub + OpenSpec change (openspec/changes/igdd-3084-swagger-ui-version-sync in izgw-hub) into a + cross-repo izgw-core task plan, following the pattern already established in this repo by + bc-fips-2.1.3-upgrade and spring-boot-4-framework-7-upgrade + summary: >- + Cross-repo task plan moving the swagger-ui webjar version-sync fix (previously duplicated + per-service, first in izgw-transform under IGDD-2976, now recurring in izgw-hub under + IGDD-3084) into izgw-core as shared, auto-scanned configuration, so every current and future + consumer inherits it instead of hand-copying it. Surfaced by open task 6.4 in + spring-boot-4-framework-7-upgrade ("Manual verification: Swagger UI renders correctly"). +tags: + - springdoc + - swagger-ui + - webjars + - dependency-drift + - izgw-bom + - izgw-core + - izgw-hub + - izgw-transform +change_request: igdd-3084-swagger-ui-version-sync +ticket: IGDD-3084 +document_type: + - openspec-tasks +--- +# Tasks: Swagger UI webjar version sync (izgw-core) + +**Jira:** [IGDD-3084](https://izgateway.atlassian.net/browse/IGDD-3084) — mirrors the already-shipped +[IGDD-2976](https://izgateway.atlassian.net/browse/IGDD-2976) fix in `izgw-transform`, this time moving it +up into `izgw-core` instead of duplicating it a second time. +**Primary repo:** izgw-core (this change) — also touches izgw-hub, izgw-transform (non-blocking follow-up) +**Related:** `spring-boot-4-framework-7-upgrade` task 6.4 in this same `openspec/changes/` directory flagged +the manual Swagger UI check as still open; that check is what surfaced this bug. This is a separate change +from that upgrade — the underlying drift predates it and would recur on any Spring Boot version (see +Background) — but task 6.4 there should be updated to point here once this lands. +**Full design doc:** `docs/superpowers/specs/2026-08-26-swagger-ui-version-sync-design.md` in `izgw-hub` +(alternatives considered, full rationale for putting this in `izgw-core` over the alternatives). +**Overall Status:** Not started — pre-flight verification (Stage 0) is already complete, captured below. + +--- + +## Background (why this isn't a Spring Boot upgrade bug, even though it surfaced during one) + +Springdoc serves Swagger UI's static assets from `classpath:META-INF/resources/webjars/swagger-ui//`, +where `` comes from the `springdoc.swagger-ui.version` property. Every current consumer of +`izgw-core` hand-pins that property to a literal in its own `application.yml`. `izgw-bom` independently +manages the `org.webjars:swagger-ui` artifact version — deliberately (see `auto-update-dependencies`'s +proposal.md in this repo: BOM-managed dependencies are explicitly excluded from `izgw-core`'s own automated +update workflow "handled separately in BOM update process", precisely so `izgw-bom`'s nightly job can move +faster on UI/CVE patches than Springdoc's own release cadence) — and a nightly automated dependency-bump +workflow keeps moving that version forward. Every time the BOM-managed version passes a hand-typed literal, +Springdoc asks for a webjar directory that no longer exists, and `/swagger/ui.html` / +`/swagger/swagger-ui/index.html` 404s. + +This is not new, and not caused by the Spring Boot 4 migration: `izgw-hub`'s git history shows the exact +same drift-and-manual-repatch cycle recurring repeatedly since May 2026, months before any Boot 4 work +started. `izgw-transform` already hit it once and fixed it under IGDD-2976 — but as a **per-service** fix. +That fix's own design doc explicitly anticipated this moment: *"the fix is xform-local and does not benefit +other izgw consumers of the BOM ... when there's a second consumer the right move is to lift this into +izgw-core, not pre-emptively."* IGDD-3084 is that second consumer. + +The only thing the Spring Boot 4 migration actually did here is **expose** the current instance of the drift +sooner than it otherwise would have: it bumped `izgw-hub`'s `izgw-bom` parent from `1.14.1-SNAPSHOT` to +`1.15.0-SNAPSHOT`, and that newer BOM had already advanced its `org.webjars:swagger-ui` pin past `izgw-hub`'s +stale `application.yml` literal (`5.32.13` vs. the now-resolved `5.32.14`). The bug itself, and this fix, +apply regardless of Spring Boot version. + +--- + +## Stage 0 — Pre-flight verification (complete) + +_All of this was verified directly against the current `izgw-hub` branch (`IGDD-2353_spring_upgrade`) and +this `izgw-core` checkout during design; recorded here so Stage 1 doesn't have to re-derive it._ + +- [x] 0.1 Confirmed the drift is live right now, not theoretical: `mvn dependency:tree` in `izgw-hub` + resolves `org.springdoc:springdoc-openapi-starter-webmvc-ui:3.1.0` → `org.webjars:swagger-ui:5.32.14`, + while `izgw-hub/src/main/resources/application.yml` still pins `springdoc.swagger-ui.version: 5.32.13`. +- [x] 0.2 Confirmed `org.webjars.WebJarVersionLocator.version(String)` and + `org.springdoc.core.properties.SwaggerUiConfigProperties.setVersion(String)` both still exist with the + same signatures the IGDD-2976 fix used, despite springdoc 3.1.0 switching its transitive webjar-locator + artifact from classic `webjars-locator-core` to `webjars-locator-lite:1.1.4` — verified via `javap` against + both jars directly. No adaptation of the original `izgw-transform` implementation is needed. +- [x] 0.3 Confirmed `izgw-core` already declares `springdoc-openapi-starter-webmvc-ui` as its own dependency + (this is what brings springdoc, and the `webflux-ui`/`webmvc-ui` conflict, to every consumer in the first + place) — no new dependency needs to be added for this change. +- [x] 0.4 Confirmed both current consumers already component-scan `gov.cdc.izgateway.configuration` (the + package this change adds a class to) with **zero wiring changes on their side**: + - `izgw-hub`'s `@SpringBootApplication` is rooted at `gov.cdc.izgateway` (covers it by default). + - `izgw-transform`'s `Application.java` has an explicit + `@ComponentScan(basePackages={"gov.cdc.izgateway.xform", ..., "gov.cdc.izgateway.configuration", ...})` + that already lists this exact package. +- [x] 0.5 Confirmed `izgw-core` has an existing precedent for this shape of shared config: + `gov.cdc.izgateway.configuration.NoopServicesAutoConfiguration` — a plain `@Configuration` with + `@Bean @ConditionalOnMissingBean` methods, picked up via component scan, not a `spring.factories`/ + `AutoConfiguration.imports`-registered auto-configuration. This change follows the same shape. +- [x] 0.6 Confirmed `izgw-bom`'s `org.webjars:swagger-ui` override is deliberate policy (per its pom comment + and `auto-update-dependencies`'s proposal in this repo), not an oversight — so removing that override was + correctly rejected as an alternative (see the full design doc). Runtime detection makes the question moot + regardless of what `izgw-bom` does. + +--- + +## Stage 1 — izgw-core (this repo) + +- [ ] 1.0 Create branch `IGDD-3084_swagger_ui_version_sync` from `develop`. **Not done yet** — the + implementation below (1.1–1.6) was written directly against the local working tree, which is currently + checked out on `IGDD-2353_spring_upgrade` (uncommitted; that branch is 7 commits ahead of + `origin/develop` and carries other unrelated migration work). `spring-boot-4-framework-7-upgrade/tasks.md` + also only exists on this branch, not on `develop` yet, which is what this change's task 4.1 note depends + on. Deliberately left as a human decision rather than done automatically: **before opening 1.PR1**, + either (a) cherry-pick/re-apply the two new files onto a fresh branch off `develop` to keep this fix + fully decoupled from the migration as designed, or (b) accept landing it on top of the migration branch + if that's already merging soon and separation isn't worth the extra step. Either way the code itself is + identical and already verified working against springdoc 3.1.0 (this branch's version). +- [x] 1.1 Wrote the failing unit test file + `src/test/java/gov/cdc/izgateway/configuration/SwaggerUiVersionConfigTests.java` — 6 tests covering: the + aligner sets version to the actual webjar version; the resolved version is not the legacy `5.32.13` pin nor + Springdoc's bundled default; a pre-existing bogus pin is overridden; a `null`, blank, or + exception-throwing detector leaves the existing value untouched and does not propagate. +- [x] 1.2 Wrote the failing context test file + `src/test/java/gov/cdc/izgateway/configuration/SwaggerUiVersionContextTests.java` using Spring's + `ApplicationContextRunner` (not `@SpringBootTest` — this is a library module with no + `@SpringBootApplication` of its own to bootstrap) to prove the `BeanPostProcessor` fires against a real + `SwaggerUiConfigProperties` bean inside a live `ApplicationContext`. +- [x] 1.3 Ran `mvn test -Dtest=SwaggerUiVersionConfigTests,SwaggerUiVersionContextTests`; confirmed both + files failed to compile (`cannot find symbol: SwaggerUiVersionConfig`) before the production class existed. +- [x] 1.4 Implemented `src/main/java/gov/cdc/izgateway/configuration/SwaggerUiVersionConfig.java` — a + `@Configuration(proxyBeanMethods = false)` exposing a static `@Bean BeanPostProcessor + swaggerUiVersionAligner()` that intercepts `SwaggerUiConfigProperties` and overwrites its `version` via + `alignVersionFromWebjar`/`alignVersion(props, Supplier)`. Same implementation `izgw-transform` + already shipped under IGDD-2976, moved here verbatim with the package changed to + `gov.cdc.izgateway.configuration`. +- [x] 1.5 Ran the tests again: all 6 unit tests and the 1 context test pass. Startup log confirms detection + works end-to-end: `Detected swagger-ui webjar version: 5.32.14`. +- [x] 1.6 Ran `mvn clean install -DskipDependencyCheck=true` (full build, OWASP scan skipped per the same + flag CI uses) — `BUILD SUCCESS`, no regression in `NoopServicesAutoConfiguration` or any other existing + test in this module. +- [ ] 1.7 Run `mvn dependency-check:check`; confirm no new CVE surface. **Not run** — the OWASP/NVD scan is + slow (dependency-check's local database sync alone commonly runs well past several minutes) and wasn't + worth blocking on here since no new dependency was added (0.3 already confirmed both + `WebJarVersionLocator` and `SwaggerUiConfigProperties` come from `springdoc-openapi-starter-webmvc-ui`, + already a dependency). Let CI's normal OWASP job cover this on the actual PR. +- [ ] **1.PR1** Open PR in `izgw-core`; title referencing IGDD-3084; body links to the design doc in + `izgw-hub` and to `izgw-transform`'s already-merged IGDD-2976 PR (`izgw-transform#264`) as the precedent + this generalizes. Do not merge until CI passes. +- [ ] 1.8 After merge, record the published SNAPSHOT version (check the GitHub Actions deploy log, or run + `mvn -q help:evaluate -Dexpression=project.version -DforceStdout` against the merged branch) — this value + is needed by Stage 2.1 and Stage 3.1. + +--- + +## Stage 2 — izgw-hub + +_Already has its own OpenSpec change tracking this in detail: +`openspec/changes/igdd-3084-swagger-ui-version-sync/` in `izgw-hub` (proposal.md / design.md / tasks.md / +specs/api-documentation/spec.md). Summarized here for cross-repo visibility only — do the actual work via +that change, not this one._ + +- [ ] 2.1 Bump the `gov.cdc.izgw:izgw-core` dependency version in `izgw-hub/pom.xml` to the SNAPSHOT + recorded in Stage 1.8. +- [ ] 2.2 Remove the hand-typed `springdoc.swagger-ui.version: 5.32.13` line (and its stale comment) from + `izgw-hub/src/main/resources/application.yml`. +- [ ] 2.3 Add `SwaggerUiVersionIntegrationTests` (`@SpringBootTest`, following the existing + `ApplicationTests.java` pattern) proving Hub's own application context inherits the fix — write it + *before* 2.1/2.2 so it demonstrably fails first (the IGDD-3084 reproduction), then passes after. +- [ ] **2.PR1** Open PR in `izgw-hub`; do not merge until CI (build, unit tests, OWASP check, Newman + `TC_92a`/`TC_92b` smoke tests against dev) passes. + +--- + +## Stage 3 — izgw-transform (non-blocking follow-up, separate PR) + +_Does not block Stage 2 landing first. **Correction, verified directly:** the old local copy and the new +inherited one are NOT a harmless redundant pair — both classes are named `SwaggerUiVersionConfig` (different +packages), and Spring's default `@Configuration` bean-naming collides on the simple class name. Once +`izgw-transform` bumps to a fixed `izgw-core` while its local copy still exists, boot fails with +`ConflictingBeanDefinitionException: Annotation-specified bean name 'swaggerUiVersionConfig' ... conflicts +with existing, non-compatible bean definition`. So the version bump (3.0) and the deletion (3.2) MUST land in +the same commit/PR — this stage cannot be split further than it already is from Stage 2._ + +- [x] 3.0 Bumped the `izgw-core` dependency version in `izgw-transform/pom.xml` — **no edit needed**, same + situation as `izgw-hub`: it already referenced the exact SNAPSHOT coordinate + (`3.5.1-IGDD-2353_spring_upgrade-SNAPSHOT`) that Stage 1's local `.m2` install already fixed. Revisit + once `izgw-core`'s branch placement (Stage 1 task 1.0) is finalized, same caveat as `izgw-hub`. +- [x] 3.1 Ran the existing `SwaggerUiVersionConfigTests`/`SwaggerUiVersionContextTests` (local copy still + present at this point) — `SwaggerUiVersionConfigTests` passed (6/6), but + `SwaggerUiVersionContextTests.postProcessorAlignsSwaggerUiVersionInRealContext` **errored** with + `ConflictingBeanDefinitionException`, proving the conflict described above empirically rather than just + by code inspection. +- [x] 3.2 Deleted the local copy: `SwaggerUiVersionConfig.java`, `SwaggerUiVersionConfigTests.java`, + `SwaggerUiVersionContextTests.java` (all under `gov.cdc.izgateway.xform.configuration`) — staged as + deletions (`git rm --cached` + `rm -f`), left uncommitted per instruction. +- [x] 3.3 Ran `mvn clean test`: 245 tests, 0 failures, 0 errors, `BUILD SUCCESS`. Startup log for + `XformApplicationTests` confirms `Detected swagger-ui webjar version: 5.32.14` now logged from + `gov.cdc.izgateway.configuration.SwaggerUiVersionConfig` (the inherited class) — the `izgw-core` fix + alone is fully sufficient. +- [ ] 3.4 Archive `izgw-transform`'s own `openspec/changes/archive/2026-05-31-auto-detect-swagger-ui-version/` + — no requirement in `openspec/specs/api-documentation/spec.md` changes (behavior is identical; only the + implementation's location moved), so this is a housekeeping note in the PR description, not a new + `MODIFIED Requirements` delta. Not done — deferred to whoever actually opens the PR. +- [ ] **3.PR1** Open PR in `izgw-transform`; do not merge until CI passes. + +--- + +## Stage 4 — Cross-cutting verification and cleanup + +- [ ] 4.1 Update `spring-boot-4-framework-7-upgrade/tasks.md` task 6.4 ("Manual verification: Swagger UI + renders correctly") in this repo's `openspec/changes/` to cross-reference this change instead of standing + alone as an unexplained manual check. +- [ ] 4.2 Confirm no other `izgw-*` repo hand-pins `springdoc.swagger-ui.version` (grep each repo's + `application.yml`/`application-*.yml` for the property) — if any do, they need the same Stage 2/3 treatment. +- [ ] 4.3 Update [IGDD-3084](https://izgateway.atlassian.net/browse/IGDD-3084) with final notes once all + stages land, and cross-link IGDD-2976 as the precedent this generalized. + +--- + +## Summary + +| Stage | Repo | Description | Status | +|---|---|---|---| +| 0 | — | Pre-flight verification | Complete | +| 1 | izgw-core | Add `SwaggerUiVersionConfig` + tests, release | Code+tests done locally, uncommitted; branch/PR not started | +| 2 | izgw-hub | Consume new core version, drop yaml pin, add regression test | Done locally, uncommitted, manually verified end-to-end; PR not started | +| 3 | izgw-transform | Consume new core version, remove now-required-to-be-removed local copy | Cleanup done locally, uncommitted, verified (245 tests pass); PR not started | +| 4 | — | Cross-cutting cleanup and Jira closeout | Not Started | diff --git a/pom.xml b/pom.xml index 59cd47e560..fc0680e1f2 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ - 3.6.0-SNAPSHOT + 3.6.0-IGDD-3084_swagger_ui_version_sync-SNAPSHOT jar IZ Gateway Core IZ Gateway Core contains the core code for the IZ Gateway Hub and Transformation services diff --git a/src/main/java/gov/cdc/izgateway/configuration/SwaggerUiVersionConfig.java b/src/main/java/gov/cdc/izgateway/configuration/SwaggerUiVersionConfig.java new file mode 100644 index 0000000000..6281bcf985 --- /dev/null +++ b/src/main/java/gov/cdc/izgateway/configuration/SwaggerUiVersionConfig.java @@ -0,0 +1,75 @@ +package gov.cdc.izgateway.configuration; + +import java.util.function.Supplier; + +import lombok.extern.slf4j.Slf4j; +import org.springdoc.core.properties.SwaggerUiConfigProperties; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.webjars.WebJarVersionLocator; + +/** + * Aligns Springdoc's swagger-ui resource-handler version with the actual + * {@code org.webjars:swagger-ui} version present on the classpath. + * + *

Springdoc reads its version from {@code springdoc.swagger-ui.version} + * and falls back to a value baked into {@code springdoc.config.properties} + * inside the springdoc starter jar. {@code izgw-bom} independently overrides + * the {@code org.webjars:swagger-ui} version, so the two drift and the UI + * 404s on {@code /swagger/swagger-ui/index.html} after a webjar bump. + * + *

Implemented as a {@link BeanPostProcessor} returned from a static + * {@code @Bean} factory so it runs even with + * {@code spring.main.lazy-initialization=true} (BPPs are always eagerly + * registered) and so the version is mutated during the + * {@link SwaggerUiConfigProperties} bean's own initialization — before any + * other bean (e.g. Springdoc's resource-handler configurer) reads it. + * + *

Lives in {@code izgw-core} (rather than being duplicated per service, + * as it originally was in {@code izgw-transform} under IGDD-2976) so every + * consumer that component-scans this package inherits the fix automatically. + * See IGDD-3084 and the {@code swagger-ui-version-sync} design doc in + * {@code izgw-hub}. + */ +@Slf4j +@Configuration(proxyBeanMethods = false) +public final class SwaggerUiVersionConfig { + + static final String SWAGGER_UI_WEBJAR_NAME = "swagger-ui"; + + private SwaggerUiVersionConfig() { + // Utility-style @Configuration: only a static @Bean factory and static helpers. + } + + @Bean + public static BeanPostProcessor swaggerUiVersionAligner() { + return new BeanPostProcessor() { + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) { + if (bean instanceof SwaggerUiConfigProperties props) { + alignVersionFromWebjar(props); + } + return bean; + } + }; + } + + static void alignVersionFromWebjar(SwaggerUiConfigProperties props) { + alignVersion(props, () -> new WebJarVersionLocator().version(SWAGGER_UI_WEBJAR_NAME)); + } + + static void alignVersion(SwaggerUiConfigProperties props, Supplier detector) { + try { + String detected = detector.get(); + if (detected == null || detected.isBlank()) { + log.warn("Could not detect {} webjar version; leaving existing Springdoc swagger-ui version in place", SWAGGER_UI_WEBJAR_NAME); + return; + } + props.setVersion(detected); + log.info("Detected {} webjar version: {}", SWAGGER_UI_WEBJAR_NAME, detected); + } catch (Throwable e) { + log.warn("Failed to detect {} webjar version; leaving existing Springdoc swagger-ui version in place", SWAGGER_UI_WEBJAR_NAME, e); + } + } +} diff --git a/src/test/java/gov/cdc/izgateway/configuration/SwaggerUiVersionConfigTests.java b/src/test/java/gov/cdc/izgateway/configuration/SwaggerUiVersionConfigTests.java new file mode 100644 index 0000000000..eec756db3a --- /dev/null +++ b/src/test/java/gov/cdc/izgateway/configuration/SwaggerUiVersionConfigTests.java @@ -0,0 +1,86 @@ +package gov.cdc.izgateway.configuration; + +import org.junit.jupiter.api.Test; +import org.springdoc.core.properties.SwaggerUiConfigProperties; +import org.webjars.WebJarVersionLocator; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SwaggerUiVersionConfigTests { + + private static final String SPRINGDOC_BUNDLED_DEFAULT = "5.32.2"; + + @Test + void alignerSetsVersionToActualWebjarVersion() { + String expected = new WebJarVersionLocator().version(SwaggerUiVersionConfig.SWAGGER_UI_WEBJAR_NAME); + assertNotNull(expected, "swagger-ui webjar must be on the test classpath"); + + SwaggerUiConfigProperties props = new SwaggerUiConfigProperties(); + SwaggerUiVersionConfig.alignVersionFromWebjar(props); + + assertEquals(expected, props.getVersion()); + assertTrue(props.getVersion().matches("\\d+\\.\\d+\\.\\d+(?:[-+].+)?"), + "detected version must look like a semver (X.Y.Z with optional qualifier); got " + props.getVersion()); + } + + @Test + void resolvedVersionIsNotSpringdocFallback() { + String resolvedWebjarVersion = new WebJarVersionLocator().version(SwaggerUiVersionConfig.SWAGGER_UI_WEBJAR_NAME); + assertNotNull(resolvedWebjarVersion); + + SwaggerUiConfigProperties props = new SwaggerUiConfigProperties(); + SwaggerUiVersionConfig.alignVersionFromWebjar(props); + + assertFalse(SPRINGDOC_BUNDLED_DEFAULT.equals(props.getVersion()) + && !SPRINGDOC_BUNDLED_DEFAULT.equals(resolvedWebjarVersion), + "version field should not be stuck on Springdoc's bundled default " + + SPRINGDOC_BUNDLED_DEFAULT + " when the webjar is a different version"); + } + + @Test + void alignerOverridesPreExistingConfiguredVersion() { + SwaggerUiConfigProperties props = new SwaggerUiConfigProperties(); + props.setVersion("bogus-pre-existing-pin"); + + SwaggerUiVersionConfig.alignVersionFromWebjar(props); + + String expected = new WebJarVersionLocator().version(SwaggerUiVersionConfig.SWAGGER_UI_WEBJAR_NAME); + assertEquals(expected, props.getVersion(), + "an existing springdoc.swagger-ui.version value must be overridden by the on-classpath webjar version"); + } + + @Test + void nullDetectionLeavesVersionUntouched() { + SwaggerUiConfigProperties props = new SwaggerUiConfigProperties(); + props.setVersion("preserved-on-failure"); + + SwaggerUiVersionConfig.alignVersion(props, () -> null); + + assertEquals("preserved-on-failure", props.getVersion()); + } + + @Test + void blankDetectionLeavesVersionUntouched() { + SwaggerUiConfigProperties props = new SwaggerUiConfigProperties(); + props.setVersion("preserved-on-failure"); + + SwaggerUiVersionConfig.alignVersion(props, () -> " "); + + assertEquals("preserved-on-failure", props.getVersion()); + } + + @Test + void exceptionDuringDetectionLeavesVersionUntouchedAndDoesNotPropagate() { + SwaggerUiConfigProperties props = new SwaggerUiConfigProperties(); + props.setVersion("preserved-on-failure"); + + SwaggerUiVersionConfig.alignVersion(props, () -> { + throw new IllegalStateException("simulated webjar lookup failure"); + }); + + assertEquals("preserved-on-failure", props.getVersion()); + } +} diff --git a/src/test/java/gov/cdc/izgateway/configuration/SwaggerUiVersionContextTests.java b/src/test/java/gov/cdc/izgateway/configuration/SwaggerUiVersionContextTests.java new file mode 100644 index 0000000000..fa81e96311 --- /dev/null +++ b/src/test/java/gov/cdc/izgateway/configuration/SwaggerUiVersionContextTests.java @@ -0,0 +1,39 @@ +package gov.cdc.izgateway.configuration; + +import org.junit.jupiter.api.Test; +import org.springdoc.core.properties.SwaggerUiConfigProperties; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.webjars.WebJarVersionLocator; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class SwaggerUiVersionContextTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withUserConfiguration(SwaggerUiVersionConfig.class, SwaggerUiConfigPropertiesTestConfig.class); + + @Test + void postProcessorAlignsSwaggerUiVersionInRealContext() { + String expected = new WebJarVersionLocator().version(SwaggerUiVersionConfig.SWAGGER_UI_WEBJAR_NAME); + assertNotNull(expected, "swagger-ui webjar must be on the test classpath"); + + contextRunner.run(context -> { + SwaggerUiConfigProperties props = context.getBean(SwaggerUiConfigProperties.class); + assertEquals(expected, props.getVersion(), + "BeanPostProcessor must override SwaggerUiConfigProperties.version during context init"); + }); + } + + @Configuration(proxyBeanMethods = false) + static class SwaggerUiConfigPropertiesTestConfig { + @Bean + SwaggerUiConfigProperties swaggerUiConfigProperties() { + SwaggerUiConfigProperties props = new SwaggerUiConfigProperties(); + props.setVersion("0.0.0-test-pin"); + return props; + } + } +}