@ahmttyydn/java-integration 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/CHANGELOG.md +762 -0
  2. package/README.md +37 -0
  3. package/package.json +46 -0
  4. package/pom.xml +242 -0
  5. package/scalar-core/pom.xml +92 -0
  6. package/scalar-core/src/main/java/com/scalar/maven/core/ScalarConstants.java +26 -0
  7. package/scalar-core/src/main/java/com/scalar/maven/core/ScalarHtmlRenderer.java +135 -0
  8. package/scalar-core/src/main/java/com/scalar/maven/core/ScalarProperties.java +596 -0
  9. package/scalar-core/src/main/java/com/scalar/maven/core/authentication/ScalarAuthenticationOptions.java +235 -0
  10. package/scalar-core/src/main/java/com/scalar/maven/core/authentication/flows/AuthorizationCodeFlow.java +160 -0
  11. package/scalar-core/src/main/java/com/scalar/maven/core/authentication/flows/ClientCredentialsFlow.java +88 -0
  12. package/scalar-core/src/main/java/com/scalar/maven/core/authentication/flows/ImplicitFlow.java +64 -0
  13. package/scalar-core/src/main/java/com/scalar/maven/core/authentication/flows/OAuthFlow.java +185 -0
  14. package/scalar-core/src/main/java/com/scalar/maven/core/authentication/flows/PasswordFlow.java +134 -0
  15. package/scalar-core/src/main/java/com/scalar/maven/core/authentication/flows/ScalarFlows.java +113 -0
  16. package/scalar-core/src/main/java/com/scalar/maven/core/authentication/schemes/ScalarApiKeySecurityScheme.java +77 -0
  17. package/scalar-core/src/main/java/com/scalar/maven/core/authentication/schemes/ScalarHttpSecurityScheme.java +115 -0
  18. package/scalar-core/src/main/java/com/scalar/maven/core/authentication/schemes/ScalarOAuth2SecurityScheme.java +75 -0
  19. package/scalar-core/src/main/java/com/scalar/maven/core/authentication/schemes/ScalarSecurityScheme.java +45 -0
  20. package/scalar-core/src/main/java/com/scalar/maven/core/config/DefaultHttpClient.java +77 -0
  21. package/scalar-core/src/main/java/com/scalar/maven/core/config/ScalarAgentOptions.java +68 -0
  22. package/scalar-core/src/main/java/com/scalar/maven/core/config/ScalarServer.java +197 -0
  23. package/scalar-core/src/main/java/com/scalar/maven/core/config/ScalarSource.java +151 -0
  24. package/scalar-core/src/main/java/com/scalar/maven/core/enums/CredentialsLocation.java +52 -0
  25. package/scalar-core/src/main/java/com/scalar/maven/core/enums/DeveloperToolsVisibility.java +58 -0
  26. package/scalar-core/src/main/java/com/scalar/maven/core/enums/DocumentDownloadType.java +67 -0
  27. package/scalar-core/src/main/java/com/scalar/maven/core/enums/OperationSorter.java +52 -0
  28. package/scalar-core/src/main/java/com/scalar/maven/core/enums/OperationTitleSource.java +52 -0
  29. package/scalar-core/src/main/java/com/scalar/maven/core/enums/Pkce.java +57 -0
  30. package/scalar-core/src/main/java/com/scalar/maven/core/enums/PropertyOrder.java +53 -0
  31. package/scalar-core/src/main/java/com/scalar/maven/core/enums/ScalarClient.java +208 -0
  32. package/scalar-core/src/main/java/com/scalar/maven/core/enums/ScalarLayout.java +52 -0
  33. package/scalar-core/src/main/java/com/scalar/maven/core/enums/ScalarTarget.java +158 -0
  34. package/scalar-core/src/main/java/com/scalar/maven/core/enums/ScalarTheme.java +102 -0
  35. package/scalar-core/src/main/java/com/scalar/maven/core/enums/TagSorter.java +47 -0
  36. package/scalar-core/src/main/java/com/scalar/maven/core/enums/ThemeMode.java +52 -0
  37. package/scalar-core/src/main/java/com/scalar/maven/core/internal/ScalarConfiguration.java +425 -0
  38. package/scalar-core/src/main/java/com/scalar/maven/core/internal/ScalarConfigurationMapper.java +69 -0
  39. package/scalar-core/src/main/resources/META-INF/resources/webjars/scalar/index.html +22 -0
  40. package/scalar-core/src/test/java/com/scalar/maven/core/ScalarConfigurationTest.java +144 -0
  41. package/scalar-core/src/test/java/com/scalar/maven/core/ScalarHtmlRendererTest.java +104 -0
  42. package/scalar-core/src/test/java/com/scalar/maven/core/ScalarPropertiesTest.java +525 -0
  43. package/scalar-core/src/test/java/com/scalar/maven/core/config/DefaultHttpClientTest.java +61 -0
  44. package/scalar-core/src/test/java/com/scalar/maven/core/config/ScalarAgentOptionsTest.java +80 -0
  45. package/scalar-core/src/test/java/com/scalar/maven/core/config/ScalarServerTest.java +118 -0
  46. package/scalar-core/src/test/java/com/scalar/maven/core/config/ScalarSourceTest.java +105 -0
  47. package/scalar-playground-webflux/pom.xml +52 -0
  48. package/scalar-playground-webflux/src/main/java/com/scalar/maven/playground/CustomScalarWebFluxController.java +34 -0
  49. package/scalar-playground-webflux/src/main/java/com/scalar/maven/playground/PlaygroundApplication.java +27 -0
  50. package/scalar-playground-webflux/src/main/resources/application.properties +7 -0
  51. package/scalar-playground-webmvc/pom.xml +52 -0
  52. package/scalar-playground-webmvc/src/main/java/com/scalar/maven/playground/CustomScalarWebMvcController.java +34 -0
  53. package/scalar-playground-webmvc/src/main/java/com/scalar/maven/playground/PlaygroundApplication.java +27 -0
  54. package/scalar-playground-webmvc/src/main/resources/application.properties +7 -0
  55. package/scalar-webflux/pom.xml +110 -0
  56. package/scalar-webflux/src/main/java/com/scalar/maven/webflux/ScalarWebFluxActuatorEndpoint.java +103 -0
  57. package/scalar-webflux/src/main/java/com/scalar/maven/webflux/ScalarWebFluxAutoConfiguration.java +63 -0
  58. package/scalar-webflux/src/main/java/com/scalar/maven/webflux/ScalarWebFluxController.java +109 -0
  59. package/scalar-webflux/src/main/java/com/scalar/maven/webflux/SpringBootScalarProperties.java +43 -0
  60. package/scalar-webflux/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +2 -0
  61. package/scalar-webflux/src/test/java/com/scalar/maven/webflux/ScalarWebFluxActuatorEndpointTest.java +136 -0
  62. package/scalar-webflux/src/test/java/com/scalar/maven/webflux/ScalarWebFluxControllerTest.java +162 -0
  63. package/scalar-webmvc/pom.xml +103 -0
  64. package/scalar-webmvc/src/main/java/com/scalar/maven/webmvc/ScalarWebMvcActuatorEndpoint.java +97 -0
  65. package/scalar-webmvc/src/main/java/com/scalar/maven/webmvc/ScalarWebMvcAutoConfiguration.java +63 -0
  66. package/scalar-webmvc/src/main/java/com/scalar/maven/webmvc/ScalarWebMvcController.java +103 -0
  67. package/scalar-webmvc/src/main/java/com/scalar/maven/webmvc/SpringBootScalarProperties.java +43 -0
  68. package/scalar-webmvc/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +2 -0
  69. package/scalar-webmvc/src/test/java/com/scalar/maven/webmvc/ScalarWebMvcActuatorEndpointTest.java +128 -0
  70. package/scalar-webmvc/src/test/java/com/scalar/maven/webmvc/ScalarWebMvcControllerTest.java +154 -0
@@ -0,0 +1,97 @@
1
+ package com.scalar.maven.webmvc;
2
+
3
+ import com.scalar.maven.core.ScalarHtmlRenderer;
4
+ import com.scalar.maven.core.ScalarProperties;
5
+ import jakarta.servlet.http.HttpServletRequest;
6
+ import org.springframework.beans.factory.ObjectProvider;
7
+ import org.springframework.beans.factory.annotation.Autowired;
8
+ import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
9
+ import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
10
+ import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpoint;
11
+ import org.springframework.http.MediaType;
12
+ import org.springframework.http.ResponseEntity;
13
+
14
+ import java.io.IOException;
15
+
16
+ /**
17
+ * Actuator endpoint for serving the Scalar API Reference interface in Spring WebMVC applications.
18
+ *
19
+ * <p>
20
+ * This endpoint provides access to the Scalar API Reference interface through
21
+ * Spring Boot Actuator endpoints. It serves the same HTML content as the
22
+ * regular ScalarWebMvcController but is accessible at the actuator path.
23
+ * </p>
24
+ *
25
+ * <p>
26
+ * The endpoint is only enabled when {@code scalar.actuatorEnabled=true} is set
27
+ * in the configuration properties.
28
+ * </p>
29
+ *
30
+ * <p>
31
+ * Access the endpoint at: {@code /actuator/scalar}
32
+ * </p>
33
+ */
34
+ @Endpoint(id = "scalar")
35
+ @WebEndpoint(id = "scalar")
36
+ public class ScalarWebMvcActuatorEndpoint {
37
+
38
+ @Autowired
39
+ private ObjectProvider<SpringBootScalarProperties> propertiesProvider;
40
+
41
+ /**
42
+ * Serves the Scalar API Reference interface as an actuator endpoint.
43
+ *
44
+ * <p>
45
+ * This method returns the same HTML content as the regular ScalarWebMvcController
46
+ * but is accessible through the actuator endpoint system.
47
+ * </p>
48
+ *
49
+ * @param request the HTTP request
50
+ * @return a ResponseEntity containing the HTML content for the API Reference
51
+ * interface
52
+ * @throws IOException if the HTML template cannot be loaded
53
+ */
54
+ @ReadOperation(produces = MediaType.TEXT_HTML_VALUE)
55
+ public final ResponseEntity<String> scalarUi(HttpServletRequest request) throws IOException {
56
+ ScalarProperties properties = propertiesProvider.getObject();
57
+ ScalarProperties configuredProperties = configureProperties(properties, request);
58
+
59
+ String html = ScalarHtmlRenderer.render(configuredProperties);
60
+
61
+ return ResponseEntity.ok()
62
+ .contentType(MediaType.TEXT_HTML)
63
+ .body(html);
64
+ }
65
+
66
+ /**
67
+ * Serves the JavaScript bundle for the Scalar API Reference.
68
+ *
69
+ * <p>
70
+ * This endpoint returns the JavaScript file that powers the Scalar API
71
+ * Reference interface. The file is served with the appropriate MIME type.
72
+ * </p>
73
+ *
74
+ * @return a ResponseEntity containing the JavaScript bundle
75
+ * @throws IOException if the JavaScript file cannot be loaded
76
+ */
77
+ @ReadOperation(produces = "application/javascript")
78
+ public final ResponseEntity<byte[]> scalarJs() throws IOException {
79
+ byte[] jsContent = ScalarHtmlRenderer.getScalarJsContent();
80
+ return ResponseEntity.ok()
81
+ .contentType(MediaType.valueOf("application/javascript"))
82
+ .body(jsContent);
83
+ }
84
+
85
+ /**
86
+ * Hook method that allows subclasses to configure properties before rendering.
87
+ * Override this method to customize the ScalarProperties before they are
88
+ * converted to JSON and rendered.
89
+ *
90
+ * @param properties the properties to configure
91
+ * @param request the HTTP request
92
+ * @return the configured properties
93
+ */
94
+ protected ScalarProperties configureProperties(ScalarProperties properties, HttpServletRequest request) {
95
+ return properties;
96
+ }
97
+ }
@@ -0,0 +1,63 @@
1
+ package com.scalar.maven.webmvc;
2
+
3
+ import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
4
+ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
5
+ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
6
+ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
7
+ import org.springframework.boot.context.properties.EnableConfigurationProperties;
8
+ import org.springframework.context.annotation.Bean;
9
+ import org.springframework.context.annotation.Configuration;
10
+
11
+ /**
12
+ * Auto-configuration for the Scalar API Reference integration in Spring WebMVC applications.
13
+ *
14
+ * <p>
15
+ * This class provides automatic configuration for the Scalar API Reference
16
+ * in Spring Boot WebMVC applications. It automatically creates the necessary beans
17
+ * when the scalar integration is enabled.
18
+ * </p>
19
+ *
20
+ * <p>
21
+ * The auto-configuration is conditional on the {@code scalar.enabled} property
22
+ * being set to {@code true} (which is the default).
23
+ * </p>
24
+ *
25
+ * <p>
26
+ * This configuration:
27
+ * </p>
28
+ * <ul>
29
+ * <li>Enables configuration properties via {@link SpringBootScalarProperties}</li>
30
+ * <li>Creates a {@link ScalarWebMvcController} bean for serving the API reference</li>
31
+ * <li>Creates a {@link ScalarWebMvcActuatorEndpoint} bean when actuator is enabled</li>
32
+ * </ul>
33
+ */
34
+ @Configuration
35
+ @EnableConfigurationProperties(SpringBootScalarProperties.class)
36
+ @ConditionalOnProperty(prefix = "scalar", name = "enabled", havingValue = "true", matchIfMissing = true)
37
+ public class ScalarWebMvcAutoConfiguration {
38
+
39
+ /**
40
+ * Creates a ScalarWebMvcController bean.
41
+ *
42
+ * @return a configured ScalarWebMvcController instance
43
+ */
44
+ @Bean
45
+ @ConditionalOnMissingBean(ScalarWebMvcController.class)
46
+ public ScalarWebMvcController scalarWebMvcController() {
47
+ return new ScalarWebMvcController();
48
+ }
49
+
50
+ /**
51
+ * Creates a ScalarWebMvcActuatorEndpoint bean when actuator support is enabled.
52
+ * This endpoint exposes the Scalar UI at /actuator/scalar.
53
+ *
54
+ * @return a configured ScalarWebMvcActuatorEndpoint instance
55
+ */
56
+ @Bean
57
+ @ConditionalOnProperty(prefix = "scalar", name = "actuatorEnabled", havingValue = "true")
58
+ @ConditionalOnClass(name = "org.springframework.boot.actuate.endpoint.annotation.Endpoint")
59
+ @ConditionalOnAvailableEndpoint(endpoint = ScalarWebMvcActuatorEndpoint.class)
60
+ public ScalarWebMvcActuatorEndpoint scalarWebMvcActuatorEndpoint() {
61
+ return new ScalarWebMvcActuatorEndpoint();
62
+ }
63
+ }
@@ -0,0 +1,103 @@
1
+ package com.scalar.maven.webmvc;
2
+
3
+ import com.scalar.maven.core.ScalarConstants;
4
+ import com.scalar.maven.core.ScalarHtmlRenderer;
5
+ import com.scalar.maven.core.ScalarProperties;
6
+ import jakarta.servlet.http.HttpServletRequest;
7
+ import org.springframework.beans.factory.ObjectProvider;
8
+ import org.springframework.beans.factory.annotation.Autowired;
9
+ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
10
+ import org.springframework.http.MediaType;
11
+ import org.springframework.http.ResponseEntity;
12
+ import org.springframework.web.bind.annotation.GetMapping;
13
+ import org.springframework.web.bind.annotation.RestController;
14
+
15
+ import java.io.IOException;
16
+
17
+ /**
18
+ * REST controller for serving the Scalar API Reference interface in Spring WebMVC applications.
19
+ *
20
+ * <p>
21
+ * This controller provides endpoints for accessing the Scalar API Reference
22
+ * interface and the associated JavaScript bundle. It automatically configures
23
+ * the interface based on the provided {@link ScalarProperties}.
24
+ * </p>
25
+ *
26
+ * <p>
27
+ * The controller serves two main endpoints:
28
+ * </p>
29
+ * <ul>
30
+ * <li>{@code /scalar} (or custom path) - The main API Reference interface</li>
31
+ * <li>{@code /scalar/scalar.js} (or custom path) - The JavaScript bundle</li>
32
+ * </ul>
33
+ *
34
+ * <p>
35
+ * This controller can be extended to customize behavior by overriding the
36
+ * {@link #configureProperties(ScalarProperties, HttpServletRequest)} method.
37
+ * </p>
38
+ */
39
+ @RestController
40
+ @ConditionalOnMissingBean(ScalarWebMvcController.class)
41
+ public class ScalarWebMvcController {
42
+
43
+ @Autowired
44
+ private ObjectProvider<SpringBootScalarProperties> propertiesProvider;
45
+
46
+ /**
47
+ * Serves the main API Reference interface.
48
+ *
49
+ * <p>
50
+ * This endpoint returns an HTML page that displays the Scalar API Reference
51
+ * interface. The page is configured with the OpenAPI specification URL from
52
+ * the properties.
53
+ * </p>
54
+ *
55
+ * @param request the HTTP request
56
+ * @return a ResponseEntity containing the HTML content for the API Reference
57
+ * interface
58
+ * @throws IOException if the HTML template cannot be loaded
59
+ */
60
+ @GetMapping("${scalar.path:/scalar}")
61
+ public final ResponseEntity<String> getDocs(HttpServletRequest request) throws IOException {
62
+ ScalarProperties properties = propertiesProvider.getObject();
63
+ ScalarProperties configuredProperties = configureProperties(properties, request);
64
+
65
+ String html = ScalarHtmlRenderer.render(configuredProperties);
66
+
67
+ return ResponseEntity.ok()
68
+ .contentType(MediaType.TEXT_HTML)
69
+ .body(html);
70
+ }
71
+
72
+ /**
73
+ * Serves the JavaScript bundle for the Scalar API Reference.
74
+ *
75
+ * <p>
76
+ * This endpoint returns the JavaScript file that powers the Scalar API
77
+ * Reference interface. The file is served with the appropriate MIME type.
78
+ * </p>
79
+ *
80
+ * @return a ResponseEntity containing the JavaScript bundle
81
+ * @throws IOException if the JavaScript file cannot be loaded
82
+ */
83
+ @GetMapping("${scalar.path:/scalar}/" + ScalarConstants.JS_FILENAME)
84
+ public final ResponseEntity<byte[]> getScalarJs() throws IOException {
85
+ byte[] jsContent = ScalarHtmlRenderer.getScalarJsContent();
86
+ return ResponseEntity.ok()
87
+ .contentType(MediaType.valueOf("application/javascript"))
88
+ .body(jsContent);
89
+ }
90
+
91
+ /**
92
+ * Hook method that allows subclasses to configure properties before rendering.
93
+ * Override this method to customize the ScalarProperties before they are
94
+ * converted to JSON and rendered.
95
+ *
96
+ * @param properties the properties to configure
97
+ * @param request the HTTP request
98
+ * @return the configured properties
99
+ */
100
+ protected ScalarProperties configureProperties(ScalarProperties properties, HttpServletRequest request) {
101
+ return properties;
102
+ }
103
+ }
@@ -0,0 +1,43 @@
1
+ package com.scalar.maven.webmvc;
2
+
3
+ import com.scalar.maven.core.ScalarProperties;
4
+ import org.springframework.boot.context.properties.ConfigurationProperties;
5
+ import org.springframework.context.annotation.Scope;
6
+
7
+ /**
8
+ * Spring Boot configuration properties wrapper for Scalar API Reference integration.
9
+ *
10
+ * <p>
11
+ * This class extends {@link ScalarProperties} and adds Spring Boot's
12
+ * {@link ConfigurationProperties} annotation to enable automatic property binding
13
+ * from Spring Boot configuration files (e.g., application.properties, application.yml).
14
+ * </p>
15
+ *
16
+ * <p>
17
+ * This wrapper allows the core {@link ScalarProperties} class to remain
18
+ * framework-agnostic while providing Spring Boot-specific functionality in the
19
+ * WebMVC integration module.
20
+ * </p>
21
+ *
22
+ * <p>
23
+ * Example usage in application.properties:
24
+ * </p>
25
+ *
26
+ * <pre>
27
+ * scalar.url=https://example.com/openapi.json
28
+ * scalar.path=/docs
29
+ * scalar.enabled=true
30
+ * scalar.showSidebar=true
31
+ * scalar.hideModels=false
32
+ * scalar.darkMode=true
33
+ * scalar.theme=default
34
+ * scalar.layout=modern
35
+ * </pre>
36
+ */
37
+ @ConfigurationProperties(prefix = "scalar")
38
+ @Scope("prototype")
39
+ public class SpringBootScalarProperties extends ScalarProperties {
40
+ // All functionality is inherited from ScalarProperties
41
+ // This class only adds the @ConfigurationProperties annotation
42
+ }
43
+
@@ -0,0 +1,2 @@
1
+ com.scalar.maven.webmvc.ScalarWebMvcAutoConfiguration
2
+
@@ -0,0 +1,128 @@
1
+ package com.scalar.maven.webmvc;
2
+
3
+ import jakarta.servlet.http.HttpServletRequest;
4
+ import org.junit.jupiter.api.BeforeEach;
5
+ import org.junit.jupiter.api.DisplayName;
6
+ import org.junit.jupiter.api.Nested;
7
+ import org.junit.jupiter.api.Test;
8
+ import org.junit.jupiter.api.extension.ExtendWith;
9
+ import org.mockito.Mock;
10
+ import org.mockito.junit.jupiter.MockitoExtension;
11
+ import org.springframework.beans.factory.ObjectProvider;
12
+ import org.springframework.http.HttpStatus;
13
+ import org.springframework.http.MediaType;
14
+ import org.springframework.http.ResponseEntity;
15
+ import org.springframework.test.util.ReflectionTestUtils;
16
+
17
+ import static org.assertj.core.api.Assertions.assertThat;
18
+ import static org.mockito.Mockito.lenient;
19
+ import static org.mockito.Mockito.when;
20
+
21
+ @ExtendWith(MockitoExtension.class)
22
+ @DisplayName("ScalarWebMvcActuatorEndpoint")
23
+ class ScalarWebMvcActuatorEndpointTest {
24
+
25
+ @Mock
26
+ private SpringBootScalarProperties properties;
27
+
28
+ @Mock
29
+ private ObjectProvider<SpringBootScalarProperties> propertiesProvider;
30
+
31
+ @Mock
32
+ private HttpServletRequest request;
33
+
34
+ private ScalarWebMvcActuatorEndpoint endpoint;
35
+
36
+ @BeforeEach
37
+ void setUp() {
38
+ lenient().when(propertiesProvider.getObject()).thenReturn(properties);
39
+ endpoint = new ScalarWebMvcActuatorEndpoint();
40
+ ReflectionTestUtils.setField(endpoint, "propertiesProvider", propertiesProvider);
41
+ }
42
+
43
+ @Nested
44
+ @DisplayName("Scalar UI Endpoint")
45
+ class ScalarUiEndpoint {
46
+
47
+ @Test
48
+ @DisplayName("should return HTML with default configuration")
49
+ void shouldReturnHtmlWithDefaultConfiguration() throws Exception {
50
+ // Given
51
+ when(properties.getUrl()).thenReturn("https://registry.scalar.com/@scalar/apis/galaxy?format=json");
52
+ when(properties.getPageTitle()).thenReturn("Scalar API Reference");
53
+ when(properties.getPath()).thenReturn("/scalar");
54
+
55
+ // When
56
+ ResponseEntity<String> response = endpoint.scalarUi(request);
57
+
58
+ // Then
59
+ assertThat(response)
60
+ .isNotNull()
61
+ .satisfies(resp -> {
62
+ assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
63
+ assertThat(resp.getHeaders().getContentType()).isEqualTo(MediaType.TEXT_HTML);
64
+ });
65
+
66
+ String html = response.getBody();
67
+ assertThat(html)
68
+ .isNotNull()
69
+ .contains("<!doctype html>")
70
+ .contains("<title>Scalar API Reference</title>")
71
+ .contains("Scalar.createApiReference('#app',");
72
+ }
73
+
74
+ @Test
75
+ @DisplayName("should return HTML with custom URL")
76
+ void shouldReturnHtmlWithCustomUrl() throws Exception {
77
+ // Given
78
+ when(properties.getUrl()).thenReturn("https://example.com/api/openapi.json");
79
+ when(properties.getPageTitle()).thenReturn("Scalar API Reference");
80
+ when(properties.getPath()).thenReturn("/scalar");
81
+
82
+ // When
83
+ ResponseEntity<String> response = endpoint.scalarUi(request);
84
+
85
+ // Then
86
+ assertThat(response)
87
+ .isNotNull()
88
+ .satisfies(resp -> {
89
+ assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
90
+ assertThat(resp.getHeaders().getContentType()).isEqualTo(MediaType.TEXT_HTML);
91
+ });
92
+
93
+ String html = response.getBody();
94
+ assertThat(html)
95
+ .isNotNull()
96
+ .contains("<!doctype html>")
97
+ .contains("<title>Scalar API Reference</title>")
98
+ .contains("Scalar.createApiReference('#app',");
99
+ }
100
+ }
101
+
102
+ @Nested
103
+ @DisplayName("JavaScript Endpoint")
104
+ class JavaScriptEndpoint {
105
+
106
+ @Test
107
+ @DisplayName("should return JavaScript file with correct content type")
108
+ void shouldReturnJavaScriptFileWithCorrectContentType() throws Exception {
109
+ // When
110
+ ResponseEntity<byte[]> response = endpoint.scalarJs();
111
+
112
+ // Then
113
+ assertThat(response)
114
+ .isNotNull()
115
+ .satisfies(resp -> {
116
+ assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
117
+ assertThat(resp.getHeaders().getContentType())
118
+ .isEqualTo(MediaType.valueOf("application/javascript"));
119
+ });
120
+
121
+ byte[] body = response.getBody();
122
+ assertThat(body)
123
+ .isNotNull()
124
+ .isNotEmpty();
125
+ }
126
+ }
127
+ }
128
+
@@ -0,0 +1,154 @@
1
+ package com.scalar.maven.webmvc;
2
+
3
+ import jakarta.servlet.http.HttpServletRequest;
4
+ import org.junit.jupiter.api.BeforeEach;
5
+ import org.junit.jupiter.api.DisplayName;
6
+ import org.junit.jupiter.api.Nested;
7
+ import org.junit.jupiter.api.Test;
8
+ import org.junit.jupiter.api.extension.ExtendWith;
9
+ import org.mockito.Mock;
10
+ import org.mockito.junit.jupiter.MockitoExtension;
11
+ import org.springframework.beans.factory.ObjectProvider;
12
+ import org.springframework.http.HttpStatus;
13
+ import org.springframework.http.MediaType;
14
+ import org.springframework.http.ResponseEntity;
15
+ import org.springframework.test.util.ReflectionTestUtils;
16
+
17
+ import static org.assertj.core.api.Assertions.assertThat;
18
+ import static org.mockito.Mockito.lenient;
19
+ import static org.mockito.Mockito.when;
20
+
21
+ @ExtendWith(MockitoExtension.class)
22
+ @DisplayName("ScalarWebMvcController")
23
+ class ScalarWebMvcControllerTest {
24
+
25
+ @Mock
26
+ private SpringBootScalarProperties properties;
27
+
28
+ @Mock
29
+ private ObjectProvider<SpringBootScalarProperties> propertiesProvider;
30
+
31
+ @Mock
32
+ private HttpServletRequest request;
33
+
34
+ private ScalarWebMvcController controller;
35
+
36
+ @BeforeEach
37
+ void setUp() {
38
+ lenient().when(propertiesProvider.getObject()).thenReturn(properties);
39
+ controller = new ScalarWebMvcController();
40
+ ReflectionTestUtils.setField(controller, "propertiesProvider", propertiesProvider);
41
+ }
42
+
43
+ @Nested
44
+ @DisplayName("GET /scalar endpoint")
45
+ class GetDocsEndpoint {
46
+
47
+ @Test
48
+ @DisplayName("should return HTML with default configuration")
49
+ void shouldReturnHtmlWithDefaultConfiguration() throws Exception {
50
+ // Given
51
+ when(properties.getUrl()).thenReturn("https://registry.scalar.com/@scalar/apis/galaxy?format=json");
52
+ when(properties.getPageTitle()).thenReturn("Scalar API Reference");
53
+ when(properties.getPath()).thenReturn("/scalar");
54
+
55
+ // When
56
+ ResponseEntity<String> response = controller.getDocs(request);
57
+
58
+ // Then
59
+ assertThat(response)
60
+ .isNotNull()
61
+ .satisfies(resp -> {
62
+ assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
63
+ assertThat(resp.getHeaders().getContentType()).isEqualTo(MediaType.TEXT_HTML);
64
+ });
65
+
66
+ String html = response.getBody();
67
+ assertThat(html)
68
+ .isNotNull()
69
+ .contains("<!doctype html>")
70
+ .contains("<title>Scalar API Reference</title>")
71
+ .contains("Scalar.createApiReference('#app',");
72
+ }
73
+
74
+ @Test
75
+ @DisplayName("should return HTML with custom URL")
76
+ void shouldReturnHtmlWithCustomUrl() throws Exception {
77
+ // Given
78
+ when(properties.getUrl()).thenReturn("https://example.com/api/openapi.json");
79
+ when(properties.getPageTitle()).thenReturn("Scalar API Reference");
80
+ when(properties.getPath()).thenReturn("/scalar");
81
+
82
+ // When
83
+ ResponseEntity<String> response = controller.getDocs(request);
84
+
85
+ // Then
86
+ assertThat(response)
87
+ .isNotNull()
88
+ .satisfies(resp -> {
89
+ assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
90
+ assertThat(resp.getHeaders().getContentType()).isEqualTo(MediaType.TEXT_HTML);
91
+ });
92
+
93
+ String html = response.getBody();
94
+ assertThat(html)
95
+ .isNotNull()
96
+ .contains("<!doctype html>")
97
+ .contains("<title>Scalar API Reference</title>")
98
+ .contains("Scalar.createApiReference('#app',");
99
+ }
100
+
101
+ @Test
102
+ @DisplayName("should return HTML with custom pageTitle")
103
+ void shouldReturnHtmlWithCustomPageTitle() throws Exception {
104
+ // Given
105
+ when(properties.getPageTitle()).thenReturn("My Custom API Documentation");
106
+ when(properties.getPath()).thenReturn("/scalar");
107
+
108
+ // When
109
+ ResponseEntity<String> response = controller.getDocs(request);
110
+
111
+ // Then
112
+ assertThat(response)
113
+ .isNotNull()
114
+ .satisfies(resp -> {
115
+ assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
116
+ assertThat(resp.getHeaders().getContentType()).isEqualTo(MediaType.TEXT_HTML);
117
+ });
118
+
119
+ String html = response.getBody();
120
+ assertThat(html)
121
+ .isNotNull()
122
+ .contains("<!doctype html>")
123
+ .contains("<title>My Custom API Documentation</title>")
124
+ .contains("Scalar.createApiReference('#app',");
125
+ }
126
+ }
127
+
128
+ @Nested
129
+ @DisplayName("GET /scalar/scalar.js endpoint")
130
+ class GetScalarJsEndpoint {
131
+
132
+ @Test
133
+ @DisplayName("should return JavaScript file with correct content type")
134
+ void shouldReturnJavaScriptFileWithCorrectContentType() throws Exception {
135
+ // When
136
+ ResponseEntity<byte[]> response = controller.getScalarJs();
137
+
138
+ // Then
139
+ assertThat(response)
140
+ .isNotNull()
141
+ .satisfies(resp -> {
142
+ assertThat(resp.getStatusCode()).isEqualTo(HttpStatus.OK);
143
+ assertThat(resp.getHeaders().getContentType())
144
+ .isEqualTo(MediaType.valueOf("application/javascript"));
145
+ });
146
+
147
+ byte[] body = response.getBody();
148
+ assertThat(body)
149
+ .isNotNull()
150
+ .isNotEmpty();
151
+ }
152
+ }
153
+ }
154
+