Skip to content

Commit b0d3888

Browse files
committed
Polish test
1 parent e03f015 commit b0d3888

File tree

1 file changed

+51
-72
lines changed

1 file changed

+51
-72
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/cloudfoundry/reactive/CloudFoundryWebFluxEndpointIntegrationTests.java

Lines changed: 51 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.util.Arrays;
2020
import java.util.Collections;
2121
import java.util.Map;
22-
import java.util.function.BiConsumer;
2322
import java.util.function.Consumer;
2423

2524
import org.junit.Test;
@@ -39,23 +38,24 @@
3938
import org.springframework.boot.actuate.endpoint.web.EndpointMediaTypes;
4039
import org.springframework.boot.actuate.endpoint.web.PathMapper;
4140
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpointDiscoverer;
42-
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
41+
import org.springframework.boot.autoconfigure.AutoConfigurations;
42+
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
43+
import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration;
44+
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
45+
import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext;
46+
import org.springframework.boot.test.context.runner.ContextConsumer;
47+
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
4348
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
44-
import org.springframework.boot.web.reactive.context.ReactiveWebServerInitializedEvent;
4549
import org.springframework.context.ApplicationContext;
46-
import org.springframework.context.ApplicationListener;
4750
import org.springframework.context.annotation.Bean;
4851
import org.springframework.context.annotation.Configuration;
4952
import org.springframework.context.annotation.Import;
5053
import org.springframework.core.convert.support.DefaultConversionService;
5154
import org.springframework.http.HttpStatus;
5255
import org.springframework.http.MediaType;
53-
import org.springframework.http.server.reactive.HttpHandler;
5456
import org.springframework.test.web.reactive.server.WebTestClient;
5557
import org.springframework.util.Base64Utils;
5658
import org.springframework.web.cors.CorsConfiguration;
57-
import org.springframework.web.reactive.config.EnableWebFlux;
58-
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
5959

6060
import static org.mockito.ArgumentMatchers.any;
6161
import static org.mockito.ArgumentMatchers.eq;
@@ -67,6 +67,7 @@
6767
* Tests for {@link CloudFoundryWebFluxEndpointHandlerMapping}.
6868
*
6969
* @author Madhura Bhave
70+
* @author Stephane Nicoll
7071
*/
7172
public class CloudFoundryWebFluxEndpointIntegrationTests {
7273

@@ -76,47 +77,54 @@ public class CloudFoundryWebFluxEndpointIntegrationTests {
7677
private static ReactiveCloudFoundrySecurityService securityService = mock(
7778
ReactiveCloudFoundrySecurityService.class);
7879

80+
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner(
81+
AnnotationConfigReactiveWebServerApplicationContext::new)
82+
.withConfiguration(
83+
AutoConfigurations.of(WebFluxAutoConfiguration.class,
84+
HttpHandlerAutoConfiguration.class,
85+
ReactiveWebServerFactoryAutoConfiguration.class))
86+
.withUserConfiguration(TestEndpointConfiguration.class)
87+
.withPropertyValues("server.port=0");
88+
7989
@Test
8090
public void operationWithSecurityInterceptorForbidden() {
8191
given(tokenValidator.validate(any())).willReturn(Mono.empty());
8292
given(securityService.getAccessLevel(any(), eq("app-id")))
8393
.willReturn(Mono.just(AccessLevel.RESTRICTED));
84-
load(TestEndpointConfiguration.class,
85-
(client) -> client.get().uri("/cfApplication/test")
86-
.accept(MediaType.APPLICATION_JSON)
87-
.header("Authorization", "bearer " + mockAccessToken()).exchange()
88-
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN));
94+
this.contextRunner.run(withWebTestClient((client) -> client.get()
95+
.uri("/cfApplication/test").accept(MediaType.APPLICATION_JSON)
96+
.header("Authorization", "bearer " + mockAccessToken()).exchange()
97+
.expectStatus().isEqualTo(HttpStatus.FORBIDDEN)));
8998
}
9099

91100
@Test
92101
public void operationWithSecurityInterceptorSuccess() {
93102
given(tokenValidator.validate(any())).willReturn(Mono.empty());
94103
given(securityService.getAccessLevel(any(), eq("app-id")))
95104
.willReturn(Mono.just(AccessLevel.FULL));
96-
load(TestEndpointConfiguration.class,
97-
(client) -> client.get().uri("/cfApplication/test")
98-
.accept(MediaType.APPLICATION_JSON)
99-
.header("Authorization", "bearer " + mockAccessToken()).exchange()
100-
.expectStatus().isEqualTo(HttpStatus.OK));
105+
this.contextRunner.run(withWebTestClient((client) -> client.get()
106+
.uri("/cfApplication/test").accept(MediaType.APPLICATION_JSON)
107+
.header("Authorization", "bearer " + mockAccessToken()).exchange()
108+
.expectStatus().isEqualTo(HttpStatus.OK)));
101109
}
102110

103111
@Test
104112
public void responseToOptionsRequestIncludesCorsHeaders() {
105-
load(TestEndpointConfiguration.class, (client) -> client.options()
113+
this.contextRunner.run(withWebTestClient((client) -> client.options()
106114
.uri("/cfApplication/test").accept(MediaType.APPLICATION_JSON)
107115
.header("Access-Control-Request-Method", "POST")
108116
.header("Origin", "http://example.com").exchange().expectStatus().isOk()
109117
.expectHeader()
110118
.valueEquals("Access-Control-Allow-Origin", "http://example.com")
111-
.expectHeader().valueEquals("Access-Control-Allow-Methods", "GET,POST"));
119+
.expectHeader().valueEquals("Access-Control-Allow-Methods", "GET,POST")));
112120
}
113121

114122
@Test
115123
public void linksToOtherEndpointsWithFullAccess() {
116124
given(tokenValidator.validate(any())).willReturn(Mono.empty());
117125
given(securityService.getAccessLevel(any(), eq("app-id")))
118126
.willReturn(Mono.just(AccessLevel.FULL));
119-
load(TestEndpointConfiguration.class, (client) -> client.get()
127+
this.contextRunner.run(withWebTestClient((client) -> client.get()
120128
.uri("/cfApplication").accept(MediaType.APPLICATION_JSON)
121129
.header("Authorization", "bearer " + mockAccessToken()).exchange()
122130
.expectStatus().isOk().expectBody().jsonPath("_links.length()")
@@ -128,37 +136,35 @@ public void linksToOtherEndpointsWithFullAccess() {
128136
.isEqualTo(false).jsonPath("_links.test.href").isNotEmpty()
129137
.jsonPath("_links.test.templated").isEqualTo(false)
130138
.jsonPath("_links.test-part.href").isNotEmpty()
131-
.jsonPath("_links.test-part.templated").isEqualTo(true));
139+
.jsonPath("_links.test-part.templated").isEqualTo(true)));
132140
}
133141

134142
@Test
135143
public void linksToOtherEndpointsForbidden() {
136144
CloudFoundryAuthorizationException exception = new CloudFoundryAuthorizationException(
137145
Reason.INVALID_TOKEN, "invalid-token");
138146
willThrow(exception).given(tokenValidator).validate(any());
139-
load(TestEndpointConfiguration.class,
140-
(client) -> client.get().uri("/cfApplication")
141-
.accept(MediaType.APPLICATION_JSON)
142-
.header("Authorization", "bearer " + mockAccessToken()).exchange()
143-
.expectStatus().isUnauthorized());
147+
this.contextRunner.run(withWebTestClient((client) -> client.get()
148+
.uri("/cfApplication").accept(MediaType.APPLICATION_JSON)
149+
.header("Authorization", "bearer " + mockAccessToken()).exchange()
150+
.expectStatus().isUnauthorized()));
144151
}
145152

146153
@Test
147154
public void linksToOtherEndpointsWithRestrictedAccess() {
148155
given(tokenValidator.validate(any())).willReturn(Mono.empty());
149156
given(securityService.getAccessLevel(any(), eq("app-id")))
150157
.willReturn(Mono.just(AccessLevel.RESTRICTED));
151-
load(TestEndpointConfiguration.class,
152-
(client) -> client.get().uri("/cfApplication")
153-
.accept(MediaType.APPLICATION_JSON)
154-
.header("Authorization", "bearer " + mockAccessToken()).exchange()
155-
.expectStatus().isOk().expectBody().jsonPath("_links.length()")
156-
.isEqualTo(2).jsonPath("_links.self.href").isNotEmpty()
157-
.jsonPath("_links.self.templated").isEqualTo(false)
158-
.jsonPath("_links.info.href").isNotEmpty()
159-
.jsonPath("_links.info.templated").isEqualTo(false)
160-
.jsonPath("_links.env").doesNotExist().jsonPath("_links.test")
161-
.doesNotExist().jsonPath("_links.test-part").doesNotExist());
158+
this.contextRunner.run(withWebTestClient((client) -> client.get()
159+
.uri("/cfApplication").accept(MediaType.APPLICATION_JSON)
160+
.header("Authorization", "bearer " + mockAccessToken()).exchange()
161+
.expectStatus().isOk().expectBody().jsonPath("_links.length()")
162+
.isEqualTo(2).jsonPath("_links.self.href").isNotEmpty()
163+
.jsonPath("_links.self.templated").isEqualTo(false)
164+
.jsonPath("_links.info.href").isNotEmpty()
165+
.jsonPath("_links.info.templated").isEqualTo(false).jsonPath("_links.env")
166+
.doesNotExist().jsonPath("_links.test").doesNotExist()
167+
.jsonPath("_links.test-part").doesNotExist()));
162168
}
163169

164170
private AnnotationConfigReactiveWebServerApplicationContext createApplicationContext(
@@ -168,23 +174,14 @@ private AnnotationConfigReactiveWebServerApplicationContext createApplicationCon
168174
return context;
169175
}
170176

171-
private void load(Class<?> configuration, Consumer<WebTestClient> clientConsumer) {
172-
BiConsumer<ApplicationContext, WebTestClient> consumer = (context,
173-
client) -> clientConsumer.accept(client);
174-
AnnotationConfigReactiveWebServerApplicationContext context = createApplicationContext(
175-
configuration, CloudFoundryReactiveConfiguration.class);
176-
context.refresh();
177-
try {
178-
consumer.accept(context, WebTestClient.bindToServer()
179-
.baseUrl("http://localhost:" + getPort(context)).build());
180-
}
181-
finally {
182-
context.close();
183-
}
184-
}
185-
186-
protected int getPort(AnnotationConfigReactiveWebServerApplicationContext context) {
187-
return context.getBean(CloudFoundryReactiveConfiguration.class).port;
177+
private ContextConsumer<AssertableReactiveWebApplicationContext> withWebTestClient(
178+
Consumer<WebTestClient> clientConsumer) {
179+
return (context) -> {
180+
int port = ((AnnotationConfigReactiveWebServerApplicationContext) context
181+
.getSourceApplicationContext()).getWebServer().getPort();
182+
clientConsumer.accept(WebTestClient.bindToServer()
183+
.baseUrl("http://localhost:" + port).build());
184+
};
188185
}
189186

190187
private String mockAccessToken() {
@@ -194,11 +191,8 @@ private String mockAccessToken() {
194191
}
195192

196193
@Configuration
197-
@EnableWebFlux
198194
static class CloudFoundryReactiveConfiguration {
199195

200-
private int port;
201-
202196
@Bean
203197
public CloudFoundrySecurityInterceptor interceptor() {
204198
return new CloudFoundrySecurityInterceptor(tokenValidator, securityService,
@@ -242,21 +236,6 @@ public EndpointDelegate endpointDelegate() {
242236
return mock(EndpointDelegate.class);
243237
}
244238

245-
@Bean
246-
public NettyReactiveWebServerFactory netty() {
247-
return new NettyReactiveWebServerFactory(0);
248-
}
249-
250-
@Bean
251-
public HttpHandler httpHandler(ApplicationContext applicationContext) {
252-
return WebHttpHandlerBuilder.applicationContext(applicationContext).build();
253-
}
254-
255-
@Bean
256-
public ApplicationListener<ReactiveWebServerInitializedEvent> serverInitializedListener() {
257-
return (event) -> this.port = event.getWebServer().getPort();
258-
}
259-
260239
}
261240

262241
@Endpoint(id = "test")

0 commit comments

Comments
 (0)