Refactor ExchangeActions

This commit is contained in:
Rossen Stoyanchev
2017-02-11 14:28:22 -05:00
parent 92f09c650f
commit d513fe87f2
12 changed files with 487 additions and 308 deletions

View File

@@ -17,9 +17,13 @@ package org.springframework.test.web.reactive.server;
import java.nio.ByteBuffer;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.core.ResolvableType;
@@ -27,8 +31,10 @@ import org.springframework.http.HttpHeaders;
import org.springframework.test.util.AssertionErrors;
import org.springframework.web.reactive.function.client.ClientResponse;
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
/**
* An API to apply assertion and other actions against a performed exchange.
* Entry point for applying assertions and actions on a performed exchange.
*
* @author Rossen Stoyanchev
* @since 5.0
@@ -69,39 +75,49 @@ public final class ExchangeActions {
}
/**
* Assert options for any response header specified by name.
* @return options for asserting headers
* Assert value(s) of the specified header name.
* @param headerName the header name
* @return options for asserting the header value(s)
*/
public StringMultiValueMapEntryAssertions assertHeader(String headerName) {
public ResponseHeaderAssertions assertHeader(String headerName) {
HttpHeaders headers = getResponse().headers().asHttpHeaders();
return new StringMultiValueMapEntryAssertions(this, headerName, headers, "Response header");
List<String> values = headers.getOrDefault(headerName, Collections.emptyList());
return new ResponseHeaderAssertions(this, headerName, values);
}
/**
* Assert the response is empty.
* Assert the response does not have any content.
*/
public void assertNoContent() {
Flux<?> body = getResponse().bodyToFlux(ByteBuffer.class);
StepVerifier.create(body).expectComplete().verify(getResponseTimeout());
public ExchangeActions assertBodyIsEmpty() {
Flux<?> body = this.exchangeInfo.getResponse().bodyToFlux(ByteBuffer.class);
StepVerifier.create(body).expectComplete().verify(this.exchangeInfo.getResponseTimeout());
return this;
}
/**
* Assert the content of the response.
* @param entityType the type of entity to decode the response as
* @param <T> the type of entity
* @return further options for asserting response entities
*/
public <T> ResponseContentAssertions<T> assertEntity(Class<T> entityType) {
return new ResponseContentAssertions<T>(this.exchangeInfo, ResolvableType.forClass(entityType));
public <T> ResponseEntityAssertions<T> assertEntity(Class<T> entityType) {
return assertEntity(ResolvableType.forClass(entityType));
}
/**
* Variant of {@link #assertEntity(Class)} with a {@link ResolvableType}.
* @param entityType the type of entity to decode the response as
* Assert the content of the response.
* @return further options for asserting response entities
*/
public <T> ResponseContentAssertions<T> assertEntity(ResolvableType entityType) {
return new ResponseContentAssertions<T>(this.exchangeInfo, entityType);
public <T> ResponseEntityAssertions<T> assertEntity(ResolvableType entityType) {
return new ResponseEntityAssertions<T>(this, this.exchangeInfo, entityType);
}
/**
* Assert the response decoded as a Map of the given key and value types.
*/
public <K, V> MapAssertions<K, V> assertBodyAsMap(Class<K> keyType, Class<V> valueType) {
ResolvableType type = ResolvableType.forClassWithGenerics(Map.class, keyType, valueType);
Mono<Map<K, V>> mono = this.exchangeInfo.getResponse().body(toMono(type));
Map<K, V> map = mono.block(this.exchangeInfo.getResponseTimeout());
return new MapAssertions<>(this, map, "Response body map");
}
/**
@@ -132,4 +148,11 @@ public final class ExchangeActions {
return this;
}
/**
* Return {@link ExchangeInfo} for direct access to request and response.
*/
public ExchangeInfo andReturn() {
return this.exchangeInfo;
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2002-2017 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.test.web.reactive.server;
import java.util.Arrays;
import java.util.List;
import static org.springframework.test.util.AssertionErrors.assertEquals;
import static org.springframework.test.util.AssertionErrors.assertTrue;
/**
* Assertions on a collection of values.
*
* @param <E> the type of element values in the collection
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class ListAssertions<E> extends ObjectAssertions<List<E>, ListAssertions<E>> {
protected ListAssertions(ExchangeActions actions, List<E> collection, String errorPrefix) {
super(actions, collection, errorPrefix);
}
/**
* Assert the size of the collection.
*/
public ListAssertions<E> hasSize(int size) {
assertEquals(getErrorPrefix() + " count", size, getValue().size());
return this;
}
/**
* Assert that the collection contains all of the given values.
*/
@SuppressWarnings("unchecked")
public ListAssertions<E> contains(E... entities) {
Arrays.stream(entities).forEach(entity -> {
boolean result = getValue().contains(entity);
assertTrue(getErrorPrefix() + " do not contain " + entity, result);
});
return this;
}
/**
* Assert the collection does not contain any of the given values.
*/
@SuppressWarnings("unchecked")
public ListAssertions<E> doesNotContain(E... entities) {
Arrays.stream(entities).forEach(entity -> {
boolean result = !getValue().contains(entity);
assertTrue(getErrorPrefix() + " should not contain " + entity, result);
});
return this;
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2002-2017 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.test.web.reactive.server;
import java.util.Arrays;
import java.util.Map;
import static org.springframework.test.util.AssertionErrors.assertEquals;
import static org.springframework.test.util.AssertionErrors.assertTrue;
/**
* Assertions on a map of values.
*
* @param <K, V> the type of values in map
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class MapAssertions<K, V> extends ObjectAssertions<Map<K, V>, MapAssertions<K, V>> {
protected MapAssertions(ExchangeActions actions, Map<K, V> map, String errorPrefix) {
super(actions, map, errorPrefix);
}
/**
* Assert the size of the map.
*/
public MapAssertions<K, V> hasSize(int size) {
assertEquals(getErrorPrefix() + " count", size, getValue().size());
return this;
}
/**
* Assert that the map contains all of the given values.
*/
@SuppressWarnings("unchecked")
public MapAssertions<K, V> contains(K key, V value) {
V actual = getValue().get(key);
assertEquals(getErrorPrefix() + " do not contain " + value, value, actual);
return this;
}
/**
* Assert that the map contains all of the given keys.
*/
@SuppressWarnings("unchecked")
public MapAssertions<K, V> containsKeys(K... keys) {
Arrays.stream(keys).forEach(key -> {
boolean result = getValue().containsKey(key);
assertTrue(getErrorPrefix() + " does not contain key " + key, result);
});
return this;
}
/**
* Assert that the map contains all of the given keys.
*/
@SuppressWarnings("unchecked")
public MapAssertions<K, V> containsValues(V... values) {
Arrays.stream(values).forEach(value -> {
boolean result = getValue().containsValue(value);
assertTrue(getErrorPrefix() + " does not contain value " + value, result);
});
return this;
}
/**
* Assert the map does not contain any of the given keys.
*/
@SuppressWarnings("unchecked")
public MapAssertions<K, V> doesNotContain(K... keys) {
Arrays.stream(keys).forEach(key -> {
boolean result = !getValue().containsKey(key);
assertTrue(getErrorPrefix() + " should not contain " + key, result);
});
return this;
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright 2002-2017 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.test.web.reactive.server;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.springframework.test.util.AssertionErrors;
import static org.springframework.test.util.AssertionErrors.assertEquals;
/**
* Assertions on an Object.
*
* @param <V> the type of Object to apply assertions to
* @param <S> assertion method return type
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class ObjectAssertions<V, S extends ObjectAssertions<V, S>> {
private final ExchangeActions exchangeActions;
private V value;
private final Supplier<V> valueSupplier;
private final String errorPrefix;
protected ObjectAssertions(ExchangeActions exchangeActions, V value, String errorPrefix) {
this(exchangeActions, () -> value, errorPrefix);
}
protected ObjectAssertions(ExchangeActions exchangeActions, Supplier<V> valueSupplier, String errorPrefix) {
this.exchangeActions = exchangeActions;
this.valueSupplier = valueSupplier;
this.errorPrefix = errorPrefix;
}
/**
* Assert the actual value is equal to the given expected value.
*/
public <T extends S> T isEqualTo(V expected) {
assertEquals(this.errorPrefix, expected, getValue());
return self();
}
/**
* Assert the actual value is not equal to the expected value.
*/
public <T extends S> T isNotEqualTo(V expected) {
assertEquals(this.errorPrefix, expected, getValue());
return self();
}
/**
* Apply custom assertions on the Object value with the help of
* {@link AssertionErrors} or an assertion library such as AssertJ.
* <p>Consider using statically imported methods for creating the assertion
* consumer to improve readability of tests.
* @param assertionConsumer consumer that will apply assertions.
*/
public <T extends S> T andAssert(Consumer<V> assertionConsumer) {
assertionConsumer.accept(getValue());
return self();
}
/**
* Apply custom actions on the Object value.
* <p>Consider using statically imported methods for creating the assertion
* consumer to improve readability of tests.
* @param consumer consumer that will apply the custom action
*/
public <T extends S> T andDo(Consumer<V> consumer) {
consumer.accept(getValue());
return self();
}
/**
* Continue with more assertions or actions on the response.
*/
public ExchangeActions and() {
return this.exchangeActions;
}
/**
* Return {@link ExchangeInfo} for direct access to request and response.
*/
public ExchangeInfo andReturn() {
return this.exchangeActions.andReturn();
}
// Protected methods for sub-classes
protected ExchangeActions getExchangeActions() {
return this.exchangeActions;
}
protected String getErrorPrefix() {
return this.errorPrefix;
}
protected V getValue() {
if (this.value == null) {
this.value = this.valueSupplier.get();
}
return this.value;
}
@SuppressWarnings("unchecked")
protected <T extends S> T self() {
return (T) this;
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2002-2017 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.test.web.reactive.server;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
import org.springframework.core.ResolvableType;
import static org.springframework.web.reactive.function.BodyExtractors.toFlux;
/**
* Provides options for asserting the content of the response.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class ResponseContentAssertions<T> extends ResponseEntityAssertions<T> {
ResponseContentAssertions(ExchangeInfo exchangeInfo, ResolvableType entityType) {
super(exchangeInfo, entityType);
}
/**
* Assert the response as a collection of entities.
*/
public ResponseEntityCollectionAssertions<T> collection() {
return new ResponseEntityCollectionAssertions<>(getExchangeInfo(), getEntityType());
}
/**
* Assert the response using a {@link StepVerifier}.
*/
public StepVerifier.FirstStep<T> stepVerifier() {
Flux<T> flux = getExchangeInfo().getResponse().body(toFlux(getEntityType()));
return StepVerifier.create(flux);
}
}

View File

@@ -15,91 +15,59 @@
*/
package org.springframework.test.web.reactive.server;
import java.util.function.Consumer;
import java.util.List;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.core.ResolvableType;
import org.springframework.test.util.AssertionErrors;
import static org.springframework.test.util.AssertionErrors.assertEquals;
import static org.springframework.web.reactive.function.BodyExtractors.toFlux;
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
/**
* Provides methods for asserting the response body as a single entity.
* Assertions on the response body decoded as a single entity.
*
* @param <T> the response entity type
*
* @author Rossen Stoyanchev
* @since 5.0
* @sine 5.0
*/
public class ResponseEntityAssertions<T> {
public class ResponseEntityAssertions<T> extends ObjectAssertions<T, ResponseEntityAssertions<T>> {
private final ExchangeInfo exchangeInfo;
private final ResolvableType entityType;
private T entity;
ResponseEntityAssertions(ExchangeInfo info, ResolvableType entityType) {
ResponseEntityAssertions(ExchangeActions actions, ExchangeInfo info, ResolvableType entityType) {
super(actions, () -> initEntity(info, entityType), "Response body");
this.exchangeInfo = info;
this.entityType = entityType;
}
protected ExchangeInfo getExchangeInfo() {
return this.exchangeInfo;
}
protected ResolvableType getEntityType() {
return this.entityType;
}
private T resolveEntity() {
if (this.entity == null) {
Mono<T> mono = this.exchangeInfo.getResponse().body(toMono(entityType));
this.entity = mono.block(this.exchangeInfo.getResponseTimeout());
}
return this.entity;
private static <T> T initEntity(ExchangeInfo exchangeInfo, ResolvableType entityType) {
Mono<T> mono = exchangeInfo.getResponse().body(toMono(entityType));
return mono.block(exchangeInfo.getResponseTimeout());
}
/**
* Assert the response entity is equal to the given expected entity.
* Assert the response decoded as a Collection of entities of the given type.
*/
public ResponseEntityAssertions<T> isEqualTo(T expected) {
assertEquals("Response body", expected, resolveEntity());
return this;
public ListAssertions<T> list() {
Flux<T> flux = this.exchangeInfo.getResponse().body(toFlux(this.entityType));
List<T> list = flux.collectList().block(this.exchangeInfo.getResponseTimeout());
return new ListAssertions<T>(getExchangeActions(), list, "Response entity collection");
}
/**
* Assert the response entity is not equal to the given expected entity.
* Assert the response content using a {@link StepVerifier}.
*/
public ResponseEntityAssertions<T> isNotEqualTo(T expected) {
assertEquals("Response body", expected, resolveEntity());
return this;
}
/**
* Apply custom assertions on the response entity with the help of
* {@link AssertionErrors} or an assertion library such as AssertJ.
* <p>Consider using statically imported methods for creating the assertion
* consumer to improve readability of tests.
* @param assertionConsumer consumer that will apply assertions.
*/
public ResponseEntityAssertions<T> andAssert(Consumer<T> assertionConsumer) {
assertionConsumer.accept(resolveEntity());
return this;
}
/**
* Apply custom actions on the response entity collection.
* <p>Consider using statically imported methods for creating the assertion
* consumer to improve readability of tests.
* @param consumer consumer that will apply the custom action
*/
public ResponseEntityAssertions<T> andDo(Consumer<T> consumer) {
consumer.accept(resolveEntity());
return this;
public StepVerifier.FirstStep<T> stepVerifier() {
Flux<T> flux = this.exchangeInfo.getResponse().body(toFlux(this.entityType));
return StepVerifier.create(flux);
}
}

View File

@@ -1,99 +0,0 @@
/*
* Copyright 2002-2017 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.test.web.reactive.server;
import java.util.Arrays;
import java.util.Collection;
import java.util.function.Consumer;
import reactor.core.publisher.Flux;
import org.springframework.core.ResolvableType;
import org.springframework.test.util.AssertionErrors;
import static org.springframework.test.util.AssertionErrors.assertEquals;
import static org.springframework.test.util.AssertionErrors.assertTrue;
import static org.springframework.web.reactive.function.BodyExtractors.toFlux;
/**
* Provides methods for asserting the response body as a collection of entities.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class ResponseEntityCollectionAssertions<T> {
private final Collection<T> entities;
ResponseEntityCollectionAssertions(ExchangeInfo info, ResolvableType entityType) {
Flux<T> flux = info.getResponse().body(toFlux(entityType));
this.entities = flux.collectList().block(info.getResponseTimeout());
}
/**
* Assert the number of entities.
*/
public ResponseEntityCollectionAssertions<T> hasSize(int size) {
assertEquals("Response entities count", size, this.entities.size());
return this;
}
/**
* Assert that the response contains all of the given entities.
*/
@SuppressWarnings("unchecked")
public ResponseEntityCollectionAssertions<T> contains(T... entities) {
Arrays.stream(entities).forEach(entity ->
assertTrue("Response does not contain " + entity, this.entities.contains(entity)));
return this;
}
/**
* Assert that the response does not contain any of the given entities.
*/
@SuppressWarnings("unchecked")
public ResponseEntityCollectionAssertions<T> doesNotContain(T... entities) {
Arrays.stream(entities).forEach(entity ->
assertTrue("Response should not contain " + entity, !this.entities.contains(entity)));
return this;
}
/**
* Apply custom assertions on the response entity collection with the help of
* {@link AssertionErrors} or an assertion library such as AssertJ.
* <p>Consider using statically imported methods for creating the assertion
* consumer to improve readability of tests.
* @param assertionConsumer consumer that will apply assertions.
*/
public ResponseEntityCollectionAssertions<T> andAssert(Consumer<Collection<T>> assertionConsumer) {
assertionConsumer.accept(this.entities);
return this;
}
/**
* Apply custom actions on the response entity collection.
* <p>Consider using statically imported methods for creating the assertion
* consumer to improve readability of tests.
* @param consumer consumer that will apply the custom action
*/
public ResponseEntityCollectionAssertions<T> andDo(Consumer<Collection<T>> consumer) {
consumer.accept(this.entities);
return this;
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2002-2017 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.test.web.reactive.server;
import java.util.List;
import org.springframework.util.CollectionUtils;
/**
* Assertions on the values of a specific header.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class ResponseHeaderAssertions extends StringAssertions {
private final List<String> values;
ResponseHeaderAssertions(ExchangeActions actions, String headerName, List<String> values) {
super(actions, initHeaderValue(values), "Response header [" + headerName + "]");
this.values = values;
}
private static String initHeaderValue(List<String> values) {
return CollectionUtils.isEmpty(values) ? null : values.get(0);
}
public ListAssertions<String> values() {
return new ListAssertions<>(getExchangeActions(), this.values, getErrorPrefix());
}
}

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.test.web.reactive.server;
import java.util.Collections;
import java.util.List;
import org.springframework.http.CacheControl;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
@@ -23,7 +26,7 @@ import org.springframework.http.MediaType;
import static org.springframework.test.util.AssertionErrors.assertEquals;
/**
* Provides methods for asserting specific, commonly used response headers.
* Assertions on specific, commonly used response headers.
*
* @author Rossen Stoyanchev
* @since 5.0

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2002-2017 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.test.web.reactive.server;
import java.util.Arrays;
import java.util.regex.Pattern;
import static org.springframework.test.util.AssertionErrors.assertTrue;
/**
* Assertions on a String value.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class StringAssertions extends ObjectAssertions<String, StringAssertions> {
public StringAssertions(ExchangeActions exchangeActions, String value, String errorPrefix) {
super(exchangeActions, value, errorPrefix);
}
/**
* The value {@link String#contains contains} the given sub-strings.
* @param values the values to match
*/
public StringAssertions contains(CharSequence... values) {
Arrays.stream(values).forEach(value -> {
String message = getErrorPrefix() + " does not contain " + value;
assertTrue(message, getValue().contains(value));
});
return this;
}
/**
* The value does not {@link String#contains contain} the given sub-strings.
* @param values the values to match
*/
public StringAssertions doesNotContain(CharSequence... values) {
Arrays.stream(values).forEach(value -> {
String message = getErrorPrefix() + " contains " + value + " but shouldn't";
assertTrue(message, !getValue().contains(value));
});
return this;
}
/**
* The value matches the given regex pattern value.
* @param pattern the values to be compiled with {@link Pattern}
*/
public StringAssertions matches(String pattern) {
boolean match = Pattern.compile(pattern).matcher(getValue()).matches();
String message = getErrorPrefix() + " with value " + getValue() + " does not match " + pattern;
assertTrue(message, match);
return this;
}
}

View File

@@ -1,79 +0,0 @@
/*
* Copyright 2002-2017 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.test.web.reactive.server;
import java.util.Arrays;
import java.util.regex.Pattern;
import org.springframework.util.MultiValueMap;
import static org.springframework.test.util.AssertionErrors.assertTrue;
/**
* Extension of {@link MultiValueMapEntryAssertions} for String values.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class StringMultiValueMapEntryAssertions extends MultiValueMapEntryAssertions<String> {
public StringMultiValueMapEntryAssertions(ExchangeActions actions, String name,
MultiValueMap<String, String> map, String errorMessagePrefix) {
super(actions, name, map, errorMessagePrefix);
}
/**
* The specified value {@link String#contains contains} the given sub-strings.
* @param values the values to match
*/
public ExchangeActions valueContains(CharSequence... values) {
String actual = getValue(0);
Arrays.stream(values).forEach(value -> {
String message = getErrorMessagePrefix() + " does not contain " + value;
assertTrue(message, actual.contains(value));
});
return getExchangeActions();
}
/**
* The specified value does not {@link String#contains contain} the given sub-strings.
* @param values the values to match
*/
public ExchangeActions valueDoesNotContain(CharSequence... values) {
String actual = getValue(0);
Arrays.stream(values).forEach(value -> {
String message = getErrorMessagePrefix() + " contains " + value + " but shouldn't";
assertTrue(message, !actual.contains(value));
});
return getExchangeActions();
}
/**
* The specified value matches the given regex pattern value.
* @param pattern the values to be compiled with {@link Pattern}
*/
public ExchangeActions valueMatches(String pattern) {
String actual = getValue(0);
boolean match = Pattern.compile(pattern).matcher(actual).matches();
String message = getErrorMessagePrefix() + " with value " + actual + " does not match " + pattern;
assertTrue(message, match);
return getExchangeActions();
}
}