Skip to content

Commit a413e70

Browse files
committed
Merge branch 'ianwallen-1354_unit_test_170'
2 parents 03d5485 + edd1b98 commit a413e70

File tree

12 files changed

+283
-27
lines changed

12 files changed

+283
-27
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,8 @@ public static void addHiddenRestControllers(String... classes) {
295295
*/
296296
protected synchronized OpenAPI getOpenApi(Locale locale) {
297297
OpenAPI openApi;
298-
if (openAPIService.getCachedOpenAPI() == null || springDocConfigProperties.isCacheDisabled()) {
298+
locale = locale == null ? Locale.getDefault() : locale;
299+
if (openAPIService.getCachedOpenAPI(locale) == null || springDocConfigProperties.isCacheDisabled()) {
299300
Instant start = Instant.now();
300301
openAPIService.build(locale);
301302
Map<String, Object> mappingsMap = openAPIService.getMappingsMap().entrySet().stream()
@@ -335,15 +336,15 @@ protected synchronized OpenAPI getOpenApi(Locale locale) {
335336
if (!CollectionUtils.isEmpty(openApi.getServers()) && !openApi.getServers().equals(serversCopy))
336337
openAPIService.setServersPresent(true);
337338

338-
openAPIService.setCachedOpenAPI(openApi);
339+
openAPIService.setCachedOpenAPI(openApi, locale);
339340
openAPIService.resetCalculatedOpenAPI();
340341

341342
LOGGER.info("Init duration for springdoc-openapi is: {} ms",
342343
Duration.between(start, Instant.now()).toMillis());
343344
}
344345
else {
345346
LOGGER.debug("Fetching openApi document from cache");
346-
openApi = openAPIService.updateServers(openAPIService.getCachedOpenAPI());
347+
openApi = openAPIService.updateServers(openAPIService.getCachedOpenAPI(locale));
347348
}
348349
return openApi;
349350
}
@@ -1109,8 +1110,9 @@ else if (existingOperation != null) {
11091110
/**
11101111
* Init open api builder.
11111112
*/
1112-
protected void initOpenAPIBuilder() {
1113-
if (openAPIService.getCachedOpenAPI() != null && springDocConfigProperties.isCacheDisabled()) {
1113+
protected void initOpenAPIBuilder(Locale locale) {
1114+
locale = locale == null ? Locale.getDefault() : locale;
1115+
if (openAPIService.getCachedOpenAPI(locale) != null && springDocConfigProperties.isCacheDisabled()) {
11141116
openAPIService = openAPIBuilderObjectFactory.getObject();
11151117
}
11161118
}

springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIService.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ public class OpenAPIService {
127127
private OpenAPI openAPI;
128128

129129
/**
130-
* The Cached open api.
130+
* The Cached open api map.
131131
*/
132-
private OpenAPI cachedOpenAPI;
132+
private final Map<String, OpenAPI> cachedOpenAPI = new HashMap<>();
133133

134134
/**
135135
* The Calculated open api.
@@ -303,8 +303,8 @@ public Operation buildTags(HandlerMethod handlerMethod, Operation operation, Ope
303303
Set<io.swagger.v3.oas.models.tags.Tag> tags = new HashSet<>();
304304
Set<String> tagsStr = new HashSet<>();
305305

306-
buildTagsFromClass(handlerMethod.getBeanType(), tags, tagsStr,locale);
307-
buildTagsFromMethod(handlerMethod.getMethod(), tags, tagsStr,locale);
306+
buildTagsFromClass(handlerMethod.getBeanType(), tags, tagsStr, locale);
307+
buildTagsFromMethod(handlerMethod.getMethod(), tags, tagsStr, locale);
308308

309309
if (!CollectionUtils.isEmpty(tagsStr))
310310
tagsStr = tagsStr.stream()
@@ -725,19 +725,21 @@ public Map<String, Object> getControllerAdviceMap() {
725725
/**
726726
* Gets cached open api.
727727
*
728+
* @param locale associated the the cache entry
728729
* @return the cached open api
729730
*/
730-
public OpenAPI getCachedOpenAPI() {
731-
return cachedOpenAPI;
731+
public OpenAPI getCachedOpenAPI(Locale locale) {
732+
return cachedOpenAPI.get(locale.getLanguage());
732733
}
733734

734735
/**
735736
* Sets cached open api.
736737
*
738+
* @param locale associated the the cache entry
737739
* @param cachedOpenAPI the cached open api
738740
*/
739-
public void setCachedOpenAPI(OpenAPI cachedOpenAPI) {
740-
this.cachedOpenAPI = cachedOpenAPI;
741+
public void setCachedOpenAPI(OpenAPI cachedOpenAPI, Locale locale) {
742+
this.cachedOpenAPI.put(locale.getLanguage(), cachedOpenAPI);
741743
}
742744

743745
/**

springdoc-openapi-common/src/test/java/org/springdoc/api/AbstractOpenApiResourceTest.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
package org.springdoc.api;
2222

23+
import java.util.HashMap;
2324
import java.util.List;
2425
import java.util.Locale;
2526
import java.util.Map;
@@ -52,6 +53,7 @@
5253

5354
import org.springframework.beans.factory.ObjectFactory;
5455
import org.springframework.context.ApplicationContext;
56+
import org.springframework.test.util.ReflectionTestUtils;
5557
import org.springframework.web.bind.annotation.RequestMethod;
5658

5759
import static java.util.Arrays.asList;
@@ -100,6 +102,7 @@ class AbstractOpenApiResourceTest {
100102
public void setUp() {
101103
openAPI = new OpenAPI();
102104
openAPI.setPaths(new Paths().addPathItem(PATH, new PathItem()));
105+
ReflectionTestUtils.setField(openAPIService, "cachedOpenAPI", new HashMap<>());
103106

104107
when(openAPIService.getCalculatedOpenAPI()).thenReturn(openAPI);
105108
when(openAPIService.getContext()).thenReturn(context);
@@ -168,10 +171,10 @@ void calculatePathFromRouterOperation() {
168171
@Test
169172
void preLoadingModeShouldNotOverwriteServers() throws InterruptedException {
170173
when(openAPIService.updateServers(any())).thenCallRealMethod();
171-
when(openAPIService.getCachedOpenAPI()).thenCallRealMethod();
174+
when(openAPIService.getCachedOpenAPI(any())).thenCallRealMethod();
172175
doAnswer(new CallsRealMethods()).when(openAPIService).setServersPresent(true);
173176
doAnswer(new CallsRealMethods()).when(openAPIService).setServerBaseUrl(any());
174-
doAnswer(new CallsRealMethods()).when(openAPIService).setCachedOpenAPI(any());
177+
doAnswer(new CallsRealMethods()).when(openAPIService).setCachedOpenAPI(any(), any());
175178

176179
String customUrl = "https://custom.com";
177180
String generatedUrl = "https://generated.com";
@@ -197,8 +200,8 @@ void preLoadingModeShouldNotOverwriteServers() throws InterruptedException {
197200
// emulate generating base url
198201
openAPIService.setServerBaseUrl(generatedUrl);
199202
openAPIService.updateServers(openAPI);
200-
201-
OpenAPI after = resource.getOpenApi(Locale.getDefault());
203+
Locale locale = Locale.US;
204+
OpenAPI after = resource.getOpenApi(locale);
202205

203206
assertThat(after.getServers().get(0).getUrl(), is(customUrl));
204207
}

springdoc-openapi-webflux-core/src/main/java/org/springdoc/webflux/api/OpenApiActuatorResource.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ public Mono<String> openapiYaml(ServerHttpRequest serverHttpRequest, Locale loca
122122
}
123123

124124
@Override
125-
protected void calculateServerUrl(ServerHttpRequest serverHttpRequest, String apiDocsUrl) {
126-
super.initOpenAPIBuilder();
125+
protected void calculateServerUrl(ServerHttpRequest serverHttpRequest, String apiDocsUrl, Locale locale) {
126+
super.initOpenAPIBuilder(locale);
127127
URI uri = getActuatorURI(serverHttpRequest.getURI().getScheme(), serverHttpRequest.getURI().getHost());
128128
openAPIService.setServerBaseUrl(uri.toString());
129129
}

springdoc-openapi-webflux-core/src/main/java/org/springdoc/webflux/api/OpenApiResource.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public OpenApiResource(ObjectFactory<OpenAPIService> openAPIBuilderObjectFactory
122122
*/
123123
protected Mono<String> openapiJson(ServerHttpRequest serverHttpRequest, String apiDocsUrl, Locale locale)
124124
throws JsonProcessingException {
125-
calculateServerUrl(serverHttpRequest, apiDocsUrl);
125+
calculateServerUrl(serverHttpRequest, apiDocsUrl, locale);
126126
OpenAPI openAPI = this.getOpenApi(locale);
127127
return Mono.just(writeJsonValue(openAPI));
128128
}
@@ -138,7 +138,7 @@ protected Mono<String> openapiJson(ServerHttpRequest serverHttpRequest, String a
138138
*/
139139
protected Mono<String> openapiYaml(ServerHttpRequest serverHttpRequest, String apiDocsUrl, Locale locale)
140140
throws JsonProcessingException {
141-
calculateServerUrl(serverHttpRequest, apiDocsUrl);
141+
calculateServerUrl(serverHttpRequest, apiDocsUrl, locale);
142142
OpenAPI openAPI = this.getOpenApi(locale);
143143
return Mono.just(writeYamlValue(openAPI));
144144
}
@@ -232,8 +232,8 @@ protected void getWebFluxRouterFunctionPaths(Locale locale) {
232232
* @param serverHttpRequest the server http request
233233
* @param apiDocsUrl the api docs url
234234
*/
235-
protected void calculateServerUrl(ServerHttpRequest serverHttpRequest, String apiDocsUrl) {
236-
initOpenAPIBuilder();
235+
protected void calculateServerUrl(ServerHttpRequest serverHttpRequest, String apiDocsUrl, Locale locale) {
236+
initOpenAPIBuilder(locale);
237237
String serverUrl = getServerUrl(serverHttpRequest,apiDocsUrl);
238238
openAPIService.setServerBaseUrl(serverUrl);
239239
}

springdoc-openapi-webmvc-core/src/main/java/org/springdoc/webmvc/api/OpenApiResource.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public OpenApiResource(ObjectFactory<OpenAPIService> openAPIBuilderObjectFactory
157157
public String openapiJson(HttpServletRequest request,
158158
String apiDocsUrl, Locale locale)
159159
throws JsonProcessingException {
160-
calculateServerUrl(request, apiDocsUrl);
160+
calculateServerUrl(request, apiDocsUrl, locale);
161161
OpenAPI openAPI = this.getOpenApi(locale);
162162
return writeJsonValue(openAPI);
163163
}
@@ -174,7 +174,7 @@ public String openapiJson(HttpServletRequest request,
174174
public String openapiYaml(HttpServletRequest request,
175175
String apiDocsUrl, Locale locale)
176176
throws JsonProcessingException {
177-
calculateServerUrl(request, apiDocsUrl);
177+
calculateServerUrl(request, apiDocsUrl, locale);
178178
OpenAPI openAPI = this.getOpenApi(locale);
179179
return writeYamlValue(openAPI);
180180
}
@@ -290,8 +290,8 @@ private Comparator<Map.Entry<RequestMappingInfo, HandlerMethod>> byReversedReque
290290
* @param request the request
291291
* @param apiDocsUrl the api docs url
292292
*/
293-
protected void calculateServerUrl(HttpServletRequest request, String apiDocsUrl) {
294-
super.initOpenAPIBuilder();
293+
protected void calculateServerUrl(HttpServletRequest request, String apiDocsUrl, Locale locale) {
294+
super.initOpenAPIBuilder(locale);
295295
String calculatedUrl = getServerUrl(request, apiDocsUrl);
296296
openAPIService.setServerBaseUrl(calculatedUrl);
297297
}

springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/app161/SpringDocApp161Test.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package test.org.springdoc.api.app161;
22

3+
import java.util.Locale;
4+
5+
import org.junit.jupiter.api.Test;
36
import test.org.springdoc.api.AbstractSpringDocTest;
47

58
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -9,5 +12,10 @@ public class SpringDocApp161Test extends AbstractSpringDocTest {
912
@SpringBootApplication
1013
static class SpringDocTestApp {}
1114

15+
@Test
16+
public void testApp() throws Exception {
17+
Locale.setDefault(Locale.US);
18+
super.testApp();
19+
}
1220

1321
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
*
3+
* * Copyright 2019-2020 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package test.org.springdoc.api.app171;
20+
21+
import javax.validation.Valid;
22+
import javax.validation.constraints.NotBlank;
23+
24+
import org.springframework.http.HttpEntity;
25+
import org.springframework.web.bind.annotation.GetMapping;
26+
import org.springframework.web.bind.annotation.RestController;
27+
28+
import io.swagger.v3.oas.annotations.tags.Tag;
29+
30+
@RestController
31+
@Tag(name = "greeting", description = "test")
32+
public class HelloLocaleController {
33+
34+
@GetMapping("/persons")
35+
public void persons(@Valid @NotBlank String name) {
36+
}
37+
38+
@GetMapping("/test")
39+
public HttpEntity<String> demo2() {
40+
return null;
41+
}
42+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
*
3+
* * Copyright 2019-2020 the original author or authors.
4+
* *
5+
* * Licensed under the Apache License, Version 2.0 (the "License");
6+
* * you may not use this file except in compliance with the License.
7+
* * You may obtain a copy of the License at
8+
* *
9+
* * https://www.apache.org/licenses/LICENSE-2.0
10+
* *
11+
* * Unless required by applicable law or agreed to in writing, software
12+
* * distributed under the License is distributed on an "AS IS" BASIS,
13+
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* * See the License for the specific language governing permissions and
15+
* * limitations under the License.
16+
*
17+
*/
18+
19+
package test.org.springdoc.api.app171;
20+
21+
import java.util.Locale;
22+
23+
import org.junit.jupiter.api.Test;
24+
import org.springdoc.core.Constants;
25+
import test.org.springdoc.api.AbstractSpringDocTest;
26+
27+
import org.springframework.boot.autoconfigure.SpringBootApplication;
28+
import org.springframework.http.HttpHeaders;
29+
import org.springframework.test.context.TestPropertySource;
30+
import org.springframework.test.web.servlet.MvcResult;
31+
32+
import static org.hamcrest.Matchers.is;
33+
import static org.skyscreamer.jsonassert.JSONAssert.assertEquals;
34+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
35+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
36+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
37+
38+
@TestPropertySource(properties = Constants.SPRINGDOC_CACHE_DISABLED + "=false")
39+
public class SpringDocApp171Test extends AbstractSpringDocTest {
40+
41+
@SpringBootApplication
42+
static class SpringDocTestApp {
43+
}
44+
45+
@Test
46+
@Override
47+
public void testApp() throws Exception {
48+
Locale.setDefault(Locale.US);
49+
testApp(Locale.US);
50+
testApp(Locale.FRANCE);
51+
}
52+
53+
private void testApp(Locale locale) throws Exception {
54+
className = getClass().getSimpleName();
55+
String testNumber = className.replaceAll("[^0-9]", "");
56+
MvcResult mockMvcResult =
57+
mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL).locale(locale).header(HttpHeaders.ACCEPT_LANGUAGE, locale.toLanguageTag())).andExpect(status().isOk())
58+
.andExpect(jsonPath("$.openapi", is("3.0.1"))).andReturn();
59+
String result = mockMvcResult.getResponse().getContentAsString();
60+
String expected = getContent("results/app" + testNumber + "-" + locale.getLanguage() + ".json");
61+
assertEquals(expected, result, true);
62+
}
63+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
greeting=Hello! Welcome to our website![FR]
2+
lang.change=Change the language[FR]
3+
lang.eng=English[FR]
4+
lang.fr=French[FR]
5+
mySample=toto[FR]
6+
test=This is a test message[FR]

0 commit comments

Comments
 (0)