Provide simple way to create ClientResponse
This commit introduces ClientResponse.Builder, an easier way to create a ClientResponse from an existing response, or from scratch. Issue: SPR-16553
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.reactive.function.client;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferFactory;
|
||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseCookie;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class DefaultClientResponseBuilderTests {
|
||||
|
||||
private DataBufferFactory dataBufferFactory;
|
||||
|
||||
@Before
|
||||
public void createBufferFactory() {
|
||||
this.dataBufferFactory = new DefaultDataBufferFactory();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normal() {
|
||||
Flux<DataBuffer> body = Flux.just("baz")
|
||||
.map(s -> s.getBytes(StandardCharsets.UTF_8))
|
||||
.map(dataBufferFactory::wrap);
|
||||
|
||||
ClientResponse response = ClientResponse.create(HttpStatus.BAD_GATEWAY, ExchangeStrategies.withDefaults())
|
||||
.header("foo", "bar")
|
||||
.cookie("baz", "qux")
|
||||
.body(body)
|
||||
.build();
|
||||
|
||||
assertEquals(HttpStatus.BAD_GATEWAY, response.statusCode());
|
||||
HttpHeaders responseHeaders = response.headers().asHttpHeaders();
|
||||
assertEquals("bar", responseHeaders.getFirst("foo"));
|
||||
assertNotNull("qux", response.cookies().getFirst("baz"));
|
||||
assertEquals("qux", response.cookies().getFirst("baz").getValue());
|
||||
|
||||
StepVerifier.create(response.bodyToFlux(String.class))
|
||||
.expectNext("baz")
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void from() throws Exception {
|
||||
Flux<DataBuffer> otherBody = Flux.just("foo", "bar")
|
||||
.map(s -> s.getBytes(StandardCharsets.UTF_8))
|
||||
.map(dataBufferFactory::wrap);
|
||||
|
||||
ClientResponse other = ClientResponse.create(HttpStatus.BAD_REQUEST, ExchangeStrategies.withDefaults())
|
||||
.header("foo", "bar")
|
||||
.cookie("baz", "qux")
|
||||
.body(otherBody)
|
||||
.build();
|
||||
|
||||
Flux<DataBuffer> body = Flux.just("baz")
|
||||
.map(s -> s.getBytes(StandardCharsets.UTF_8))
|
||||
.map(dataBufferFactory::wrap);
|
||||
|
||||
ClientResponse result = ClientResponse.from(other)
|
||||
.headers(httpHeaders -> httpHeaders.set("foo", "baar"))
|
||||
.cookies(cookies -> cookies.set("baz", ResponseCookie.from("baz", "quux").build()))
|
||||
.body(body)
|
||||
.build();
|
||||
|
||||
assertEquals(HttpStatus.BAD_REQUEST, result.statusCode());
|
||||
assertEquals(1, result.headers().asHttpHeaders().size());
|
||||
assertEquals("baar", result.headers().asHttpHeaders().getFirst("foo"));
|
||||
assertEquals(1, result.cookies().size());
|
||||
assertEquals("quux", result.cookies().getFirst("baz").getValue());
|
||||
|
||||
StepVerifier.create(result.bodyToFlux(String.class))
|
||||
.expectNext("baz")
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.reactive.function.client.support;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ReactiveHttpInputMessage;
|
||||
import org.springframework.http.ResponseCookie;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.reactive.function.BodyExtractor;
|
||||
import org.springframework.web.reactive.function.BodyExtractors;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class ClientResponseWrapperTests {
|
||||
|
||||
private ClientResponse mockResponse;
|
||||
|
||||
private ClientResponseWrapper wrapper;
|
||||
|
||||
@Before
|
||||
public void createWrapper() {
|
||||
this.mockResponse = mock(ClientResponse.class);
|
||||
this.wrapper = new ClientResponseWrapper(mockResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void response() throws Exception {
|
||||
assertSame(mockResponse, wrapper.response());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void statusCode() throws Exception {
|
||||
HttpStatus status = HttpStatus.BAD_REQUEST;
|
||||
when(mockResponse.statusCode()).thenReturn(status);
|
||||
|
||||
assertSame(status, wrapper.statusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headers() throws Exception {
|
||||
ClientResponse.Headers headers = mock(ClientResponse.Headers.class);
|
||||
when(mockResponse.headers()).thenReturn(headers);
|
||||
|
||||
assertSame(headers, wrapper.headers());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cookies() throws Exception {
|
||||
MultiValueMap<String, ResponseCookie> cookies = mock(MultiValueMap.class);
|
||||
when(mockResponse.cookies()).thenReturn(cookies);
|
||||
|
||||
assertSame(cookies, wrapper.cookies());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyExtractor() throws Exception {
|
||||
Mono<String> result = Mono.just("foo");
|
||||
BodyExtractor<Mono<String>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(String.class);
|
||||
when(mockResponse.body(extractor)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.body(extractor));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyToMonoClass() throws Exception {
|
||||
Mono<String> result = Mono.just("foo");
|
||||
when(mockResponse.bodyToMono(String.class)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.bodyToMono(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyToMonoParameterizedTypeReference() throws Exception {
|
||||
Mono<String> result = Mono.just("foo");
|
||||
ParameterizedTypeReference<String> reference = new ParameterizedTypeReference<String>() {};
|
||||
when(mockResponse.bodyToMono(reference)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.bodyToMono(reference));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyToFluxClass() throws Exception {
|
||||
Flux<String> result = Flux.just("foo");
|
||||
when(mockResponse.bodyToFlux(String.class)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.bodyToFlux(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyToFluxParameterizedTypeReference() throws Exception {
|
||||
Flux<String> result = Flux.just("foo");
|
||||
ParameterizedTypeReference<String> reference = new ParameterizedTypeReference<String>() {};
|
||||
when(mockResponse.bodyToFlux(reference)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.bodyToFlux(reference));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toEntityClass() throws Exception {
|
||||
Mono<ResponseEntity<String>> result = Mono.just(new ResponseEntity<>("foo", HttpStatus.OK));
|
||||
when(mockResponse.toEntity(String.class)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.toEntity(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toEntityParameterizedTypeReference() throws Exception {
|
||||
Mono<ResponseEntity<String>> result = Mono.just(new ResponseEntity<>("foo", HttpStatus.OK));
|
||||
ParameterizedTypeReference<String> reference = new ParameterizedTypeReference<String>() {};
|
||||
when(mockResponse.toEntity(reference)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.toEntity(reference));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toEntityListClass() throws Exception {
|
||||
Mono<ResponseEntity<List<String>>> result = Mono.just(new ResponseEntity<>(singletonList("foo"), HttpStatus.OK));
|
||||
when(mockResponse.toEntityList(String.class)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.toEntityList(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toEntityListParameterizedTypeReference() throws Exception {
|
||||
Mono<ResponseEntity<List<String>>> result = Mono.just(new ResponseEntity<>(singletonList("foo"), HttpStatus.OK));
|
||||
ParameterizedTypeReference<String> reference = new ParameterizedTypeReference<String>() {};
|
||||
when(mockResponse.toEntityList(reference)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.toEntityList(reference));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,10 +23,17 @@ import java.util.Optional;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.http.HttpCookie;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.ReactiveHttpInputMessage;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.reactive.function.BodyExtractor;
|
||||
import org.springframework.web.reactive.function.BodyExtractors;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
@@ -128,4 +135,55 @@ public class ServerRequestWrapperTests {
|
||||
assertSame(pathVariables, wrapper.pathVariables());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cookies() throws Exception {
|
||||
MultiValueMap<String, HttpCookie> cookies = mock(MultiValueMap.class);
|
||||
when(mockRequest.cookies()).thenReturn(cookies);
|
||||
|
||||
assertSame(cookies, wrapper.cookies());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyExtractor() throws Exception {
|
||||
Mono<String> result = Mono.just("foo");
|
||||
BodyExtractor<Mono<String>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(String.class);
|
||||
when(mockRequest.body(extractor)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.body(extractor));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyToMonoClass() throws Exception {
|
||||
Mono<String> result = Mono.just("foo");
|
||||
when(mockRequest.bodyToMono(String.class)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.bodyToMono(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyToMonoParameterizedTypeReference() throws Exception {
|
||||
Mono<String> result = Mono.just("foo");
|
||||
ParameterizedTypeReference<String> reference = new ParameterizedTypeReference<String>() {};
|
||||
when(mockRequest.bodyToMono(reference)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.bodyToMono(reference));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyToFluxClass() throws Exception {
|
||||
Flux<String> result = Flux.just("foo");
|
||||
when(mockRequest.bodyToFlux(String.class)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.bodyToFlux(String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bodyToFluxParameterizedTypeReference() throws Exception {
|
||||
Flux<String> result = Flux.just("foo");
|
||||
ParameterizedTypeReference<String> reference = new ParameterizedTypeReference<String>() {};
|
||||
when(mockRequest.bodyToFlux(reference)).thenReturn(result);
|
||||
|
||||
assertSame(result, wrapper.bodyToFlux(reference));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user