diff --git a/javalin-plugins/javalin-swagger-plugin/src/main/kotlin/io/javalin/openapi/plugin/swagger/SwaggerPlugin.kt b/javalin-plugins/javalin-swagger-plugin/src/main/kotlin/io/javalin/openapi/plugin/swagger/SwaggerPlugin.kt index c67d80f..c491939 100644 --- a/javalin-plugins/javalin-swagger-plugin/src/main/kotlin/io/javalin/openapi/plugin/swagger/SwaggerPlugin.kt +++ b/javalin-plugins/javalin-swagger-plugin/src/main/kotlin/io/javalin/openapi/plugin/swagger/SwaggerPlugin.kt @@ -1,6 +1,7 @@ package io.javalin.openapi.plugin.swagger import io.javalin.Javalin +import io.javalin.http.HandlerType import io.javalin.plugin.Plugin import io.javalin.security.RouteRole @@ -61,14 +62,19 @@ open class SwaggerPlugin @JvmOverloads constructor(private val configuration: Sw customStylesheetFiles = configuration.customStylesheetFiles, customJavaScriptFiles = configuration.customJavaScriptFiles ) + /** Register handler for swagger ui */ + app.get(configuration.uiPath, swaggerHandler, *configuration.roles) - val swaggerWebJarHandler = SwaggerWebJarHandler( - swaggerWebJarPath = configuration.webJarPath - ) - - app - .get(configuration.uiPath, swaggerHandler, *configuration.roles) - .get("${configuration.webJarPath}/*", swaggerWebJarHandler, *configuration.roles) + /** Register webjar handler if and only if there isn't already a [SwaggerWebJarHandler] at configured route */ + app.javalinServlet().matcher + .findEntries(HandlerType.GET, "${configuration.webJarPath}/*") + .takeIf { routes -> routes.none { it.handler is SwaggerWebJarHandler } } + ?.run { + val swaggerWebJarHandler = SwaggerWebJarHandler( + swaggerWebJarPath = configuration.webJarPath + ) + app.get("${configuration.webJarPath}/*", swaggerWebJarHandler, *configuration.roles) + } } -} \ No newline at end of file +} diff --git a/javalin-plugins/javalin-swagger-plugin/src/test/kotlin/io/javalin/openapi/plugin/swagger/SwaggerPluginTest.kt b/javalin-plugins/javalin-swagger-plugin/src/test/kotlin/io/javalin/openapi/plugin/swagger/SwaggerPluginTest.kt index d3dba49..e5ce725 100644 --- a/javalin-plugins/javalin-swagger-plugin/src/test/kotlin/io/javalin/openapi/plugin/swagger/SwaggerPluginTest.kt +++ b/javalin-plugins/javalin-swagger-plugin/src/test/kotlin/io/javalin/openapi/plugin/swagger/SwaggerPluginTest.kt @@ -68,4 +68,100 @@ internal class SwaggerPluginTest { } } -} \ No newline at end of file + @Test + fun `should not fail if second swagger plugin is registered`(){ + val swaggerConfiguration = SwaggerConfiguration(); + val otherConfiguration = ExampleSwaggerPlugin(); + Javalin.create{ + it.plugins.register(SwaggerPlugin(swaggerConfiguration)) + it.plugins.register(otherConfiguration) + } + .start(8080) + .use{ + val javalinHost = "http://localhost:8080" + val webjarJsRoute = "/webjars/swagger-ui/${swaggerConfiguration.version}/swagger-ui-bundle.js" + + val response = Unirest.get("$javalinHost/swagger") + .asString() + .body + + assertThat(response).contains("""src="$webjarJsRoute"""") + assertThat(response).contains("""url: '/openapi?v=test'""") + assertThat(response).doesNotContain("""url: '/example-docs?v=test'""") + + val resourceResponse = Unirest.get("$javalinHost$webjarJsRoute") + .asString() + .body + + assertThat(resourceResponse).isNotBlank + + val otherResponse = Unirest.get("$javalinHost/example-ui") + .asString() + .body + + assertThat(otherResponse).contains("""url: '/example-docs?v=test'""") + assertThat(otherResponse).doesNotContain("""url: '/openapi?v=test'""") + } + } + + @Test + fun `should not fail if second swagger plugin is registered with routes`(){ + val swaggerConfiguration = SwaggerConfiguration(); + val otherConfiguration = ExampleSwaggerPlugin(); + Javalin.create{ + it.plugins.register(SwaggerPlugin(swaggerConfiguration)) + it.plugins.register(otherConfiguration) + }.get("/some/route/"){ ctx -> ctx.result("Hello World")} + .start(8080) + .use{ + val javalinHost = "http://localhost:8080" + + val webjarCssRoute = "/webjars/swagger-ui/${swaggerConfiguration.version}/swagger-ui.css" + val webjarJsRoute = "/webjars/swagger-ui/${swaggerConfiguration.version}/swagger-ui-bundle.js" + val webjarJsStandaloneRoute = "/webjars/swagger-ui/${swaggerConfiguration.version}/swagger-ui-standalone-preset.js" + + val response = Unirest.get("$javalinHost/swagger") + .asString() + .body + + assertThat(response).contains("""href="$webjarCssRoute"""") + assertThat(response).contains("""src="$webjarJsRoute"""") + assertThat(response).contains("""src="$webjarJsStandaloneRoute"""") + assertThat(response).contains("""url: '/openapi?v=test'""") + assertThat(response).doesNotContain("""url: '/example-docs?v=test'""") + + var resourceResponse = Unirest.get("$javalinHost$webjarCssRoute") + .asString() + .body + + assertThat(resourceResponse).isNotBlank + + resourceResponse = Unirest.get("$javalinHost$webjarJsRoute") + .asString() + .body + + assertThat(resourceResponse).isNotBlank + + resourceResponse = Unirest.get("$javalinHost$webjarJsStandaloneRoute") + .asString() + .body + + assertThat(resourceResponse).isNotBlank + + val otherResponse = Unirest.get("$javalinHost/example-ui") + .asString() + .body + + assertThat(otherResponse).contains("""url: '/example-docs?v=test'""") + assertThat(otherResponse).doesNotContain("""url: '/openapi?v=test'""") + } + } + + class ExampleSwaggerPlugin : SwaggerPlugin( + SwaggerConfiguration().apply { + this.documentationPath = "/example-docs" + this.uiPath = "/example-ui" + } + ) + +}