@Test // SPR-16494 @Ignore // https://github.com/reactor/reactor-netty/issues/283 public void serverDetectsClientDisconnect() { assumeTrue(this.server instanceof ReactorHttpServer); Flux<String> result = this.webClient.get() .uri("/infinite") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(String.class); StepVerifier.create(result) .expectNext("foo 0") .expectNext("foo 1") .thenCancel() .verify(Duration.ofSeconds(5L)); SseController controller = this.wac.getBean(SseController.class); controller.cancellation.block(Duration.ofSeconds(5)); }
@Test public void requestHeaderAndCookie() { this.builder.build().get().uri("/path").accept(MediaType.APPLICATION_JSON) .cookies(cookies -> cookies.add("id", "123")) // SPR-16178 .exchange(); ClientRequest request = verifyAndGetRequest(); assertEquals("application/json", request.headers().getFirst("Accept")); assertEquals("123", request.cookies().getFirst("id")); verifyNoMoreInteractions(this.exchangeFunction); }
@Test // SPR-17482 public void bodyToMonoVoidWithoutContentType() { this.server.enqueue(new MockResponse() .setResponseCode(HttpStatus.ACCEPTED.value()) .setChunkedBody("{\"foo\" : \"123\", \"baz\" : \"456\", \"baz\" : \"456\"}", 5)); Mono<Map<String, String>> mono = this.webClient.get() .uri("/sample").accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(new ParameterizedTypeReference<Map<String, String>>() {}); StepVerifier.create(mono).expectError(UnsupportedMediaTypeException.class).verify(Duration.ofSeconds(3)); assertEquals(1, this.server.getRequestCount()); }
@Test public void sseAsEvent() { Flux<ServerSentEvent<String>> result = this.webClient.get() .uri("/event") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(new ParameterizedTypeReference<ServerSentEvent<String>>() {}); StepVerifier.create(result) .consumeNextWith( event -> { assertEquals("0", event.id()); assertEquals("foo", event.data()); assertEquals("bar", event.comment()); assertNull(event.event()); assertNull(event.retry()); }) .consumeNextWith( event -> { assertEquals("1", event.id()); assertEquals("foo", event.data()); assertEquals("bar", event.comment()); assertNull(event.event()); assertNull(event.retry()); }) .expectComplete() .verify(Duration.ofSeconds(5L)); }
@Test public void shouldReceiveJsonAsResponseEntityString() { String content = "{\"bar\":\"barbar\",\"foo\":\"foofoo\"}"; prepareResponse(response -> response .setHeader("Content-Type", "application/json").setBody(content)); Mono<ResponseEntity<String>> result = this.webClient.get() .uri("/json").accept(MediaType.APPLICATION_JSON) .exchange() .flatMap(response -> response.toEntity(String.class)); StepVerifier.create(result) .consumeNextWith(entity -> { assertEquals(HttpStatus.OK, entity.getStatusCode()); assertEquals(MediaType.APPLICATION_JSON, entity.getHeaders().getContentType()); assertEquals(31, entity.getHeaders().getContentLength()); assertEquals(content, entity.getBody()); }) .expectComplete().verify(Duration.ofSeconds(3)); expectRequestCount(1); expectRequest(request -> { assertEquals("/json", request.getPath()); assertEquals("application/json", request.getHeader(HttpHeaders.ACCEPT)); }); }
@Test // SPR-16715 public void shouldReceiveJsonAsTypeReferenceString() { String content = "{\"containerValue\":{\"fooValue\":\"bar\"}}"; prepareResponse(response -> response .setHeader("Content-Type", "application/json").setBody(content)); Mono<ValueContainer<Foo>> result = this.webClient.get() .uri("/json").accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(new ParameterizedTypeReference<ValueContainer<Foo>>() {}); StepVerifier.create(result) .assertNext(valueContainer -> { Foo foo = valueContainer.getContainerValue(); assertNotNull(foo); assertEquals("bar", foo.getFooValue()); }) .expectComplete().verify(Duration.ofSeconds(3)); expectRequestCount(1); expectRequest(request -> { assertEquals("/json", request.getPath()); assertEquals("application/json", request.getHeader(HttpHeaders.ACCEPT)); }); }
@Test public void shouldReceiveJsonAsFluxPojo() { prepareResponse(response -> response .setHeader("Content-Type", "application/json") .setBody("[{\"bar\":\"bar1\",\"foo\":\"foo1\"},{\"bar\":\"bar2\",\"foo\":\"foo2\"}]")); Flux<Pojo> result = this.webClient.get() .uri("/pojos") .accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToFlux(Pojo.class); StepVerifier.create(result) .consumeNextWith(p -> assertThat(p.getBar(), Matchers.is("bar1"))) .consumeNextWith(p -> assertThat(p.getBar(), Matchers.is("bar2"))) .expectComplete() .verify(Duration.ofSeconds(3)); expectRequestCount(1); expectRequest(request -> { assertEquals("/pojos", request.getPath()); assertEquals("application/json", request.getHeader(HttpHeaders.ACCEPT)); }); }
@Test public void shouldReceiveJsonAsPojo() { prepareResponse(response -> response .setHeader("Content-Type", "application/json") .setBody("{\"bar\":\"barbar\",\"foo\":\"foofoo\"}")); Mono<Pojo> result = this.webClient.get() .uri("/pojo") .accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(Pojo.class); StepVerifier.create(result) .consumeNextWith(p -> assertEquals("barbar", p.getBar())) .expectComplete() .verify(Duration.ofSeconds(3)); expectRequestCount(1); expectRequest(request -> { assertEquals("/pojo", request.getPath()); assertEquals("application/json", request.getHeader(HttpHeaders.ACCEPT)); }); }
@Test public void shouldReceiveJsonAsString() { String content = "{\"bar\":\"barbar\",\"foo\":\"foofoo\"}"; prepareResponse(response -> response .setHeader("Content-Type", "application/json").setBody(content)); Mono<String> result = this.webClient.get() .uri("/json").accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(String.class); StepVerifier.create(result) .expectNext(content) .expectComplete().verify(Duration.ofSeconds(3)); expectRequestCount(1); expectRequest(request -> { assertEquals("/json", request.getPath()); assertEquals("application/json", request.getHeader(HttpHeaders.ACCEPT)); }); }
@Test public void shouldReceiveJsonAsFluxString() { String content = "{\"bar\":\"barbar\",\"foo\":\"foofoo\"}"; prepareResponse(response -> response .setHeader("Content-Type", "application/json").setBody(content)); Flux<String> result = this.webClient.get() .uri("/json").accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToFlux(String.class); StepVerifier.create(result) .expectNext(content) .expectComplete().verify(Duration.ofSeconds(3)); expectRequestCount(1); expectRequest(request -> { assertEquals("/json", request.getPath()); assertEquals("application/json", request.getHeader(HttpHeaders.ACCEPT)); }); }
private void testOnStatus(Throwable expected, Function<ClientResponse, Mono<? extends Throwable>> exceptionFunction) { HttpStatus errorStatus = HttpStatus.BAD_GATEWAY; this.server.enqueue(new MockResponse() .setResponseCode(errorStatus.value()) .setHeader("Content-Type", "application/json") .setChunkedBody("{\"error\" : {\"status\" : 502, \"message\" : \"Bad gateway.\"}}", 5)); Mono<String> mono = this.webClient.get() .uri("/json").accept(MediaType.APPLICATION_JSON) .retrieve() .onStatus(status -> status.equals(errorStatus), exceptionFunction) .bodyToMono(String.class); StepVerifier.create(mono).expectErrorSatisfies(actual -> assertSame(expected, actual)).verify(DELAY); assertEquals(1, this.server.getRequestCount()); }
@Test public void sseAsString() { Flux<String> result = this.webClient.get() .uri("/string") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(String.class); StepVerifier.create(result) .expectNext("foo 0") .expectNext("foo 1") .thenCancel() .verify(Duration.ofSeconds(5L)); }
@Test public void smileStreaming() { Flux<Person> result = this.webClient.get() .uri("/stream") .accept(new MediaType("application", "stream+x-jackson-smile")) .retrieve() .bodyToFlux(Person.class); StepVerifier.create(result) .expectNext(new Person("foo 0")) .expectNext(new Person("foo 1")) .thenCancel() .verify(); }
@Test public void sseAsString() { Flux<String> result = this.webClient.get() .uri("/string") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(String.class); StepVerifier.create(result) .expectNext("foo 0") .expectNext("foo 1") .expectComplete() .verify(Duration.ofSeconds(5L)); }
@Test public void sseAsPerson() { Flux<Person> result = this.webClient.get() .uri("/person") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(Person.class); StepVerifier.create(result) .expectNext(new Person("foo 0")) .expectNext(new Person("foo 1")) .thenCancel() .verify(Duration.ofSeconds(5L)); }
@Test public void jsonStreaming() { Flux<Person> result = this.webClient.get() .uri("/stream") .accept(APPLICATION_STREAM_JSON) .retrieve() .bodyToFlux(Person.class); StepVerifier.create(result) .expectNext(new Person("foo 0")) .expectNext(new Person("foo 1")) .thenCancel() .verify(); }
@Test public void sseAsPerson() { Flux<Person> result = this.webClient.get() .uri("/person") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(Person.class); StepVerifier.create(result) .expectNext(new Person("foo 0")) .expectNext(new Person("foo 1")) .expectComplete() .verify(Duration.ofSeconds(5L)); }
@Test public void bodyToMonoVoid() { this.server.enqueue(new MockResponse() .setResponseCode(201) .setHeader("Content-Type", "application/json") .setChunkedBody("{\"foo\" : {\"bar\" : \"123\", \"baz\" : \"456\"}}", 5)); Mono<Void> mono = this.webClient.get() .uri("/json").accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(Void.class); StepVerifier.create(mono).expectComplete().verify(Duration.ofSeconds(3)); assertEquals(1, this.server.getRequestCount()); }
@Test public void sseAsEventWithoutAcceptHeader() { Flux<ServerSentEvent<Person>> result = this.webClient.get() .uri("/event") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(new ParameterizedTypeReference<ServerSentEvent<Person>>() {}); verifyPersonEvents(result); }
@Test public void sseAsEvent() { Assume.assumeTrue(server instanceof JettyHttpServer); Flux<ServerSentEvent<Person>> result = this.webClient.get() .uri("/event") .accept(TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(new ParameterizedTypeReference<ServerSentEvent<Person>>() {}); verifyPersonEvents(result); }