Skip to content

Commit

Permalink
issue #444, add ability to directly assert a body field in a multipar…
Browse files Browse the repository at this point in the history
…t request
  • Loading branch information
ryber committed Nov 26, 2022
1 parent 294027d commit 974c74c
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 29 deletions.
23 changes: 19 additions & 4 deletions unirest-mocks/src/main/java/kong/unirest/core/Assert.java
Expand Up @@ -34,27 +34,42 @@ public interface Assert {
* Assert that any request to this method/path contained this header
* @param key the expected header key
* @param value the expected header value
* @return this Assert instance
* @throws UnirestAssertion when header does not exist
*/
void assertHeader(String key, String value);
Assert hadHeader(String key, String value);

/**
* Assert that any the request sent this body. this only applies to non-multipart requests.
* @param expected the expected body
* @return this Assert instance
* @throws UnirestAssertion when body does not exist
*/
void assertBody(String expected);
Assert hadBody(String expected);

/**
* Assert that any the request sent a multipart field
* @param name the field name
* @param value the field value
* @return this Assert instance
* @throws UnirestAssertion when body does not exist
*/
Assert hadField(String name, String value);

/**
* assert that this instance of method/path was invoked x times
* @param i the number of times invoked.
* @return this Assert instance
* @throws UnirestAssertion when the invocation count is not x
*/
void assertInvokedTimes(int i);
Assert wasInvokedTimes(int i);

/**
* verify that all Expectations were fulfilled at least once.
* @return this Assert instance
* @throws UnirestAssertion when all expectations have not been fulfilled
*/
void verifyAll();
Assert verifyAll();


}
32 changes: 24 additions & 8 deletions unirest-mocks/src/main/java/kong/unirest/core/Invocation.java
Expand Up @@ -27,13 +27,11 @@

import kong.unirest.core.json.JSONElement;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.lang.System.lineSeparator;

Expand Down Expand Up @@ -180,20 +178,37 @@ public boolean hasExpectedHeader(String key, String value) {
return allH.containsKey(key) && allH.get(key).contains(value);
}

public boolean hasBody(String body){
private Stream<Body> getBodyStream() {
return requests.stream()
.filter(r -> r.getBody().isPresent())
.map(r -> (Body)r.getBody().get())
.anyMatch(b -> bodyMatches(body, b));
.map(r -> (Body) r.getBody().get());
}

private boolean bodyMatches(String body, Body o) {
public boolean hasBody(String body){
return getBodyStream()
.anyMatch(b -> uniBodyMatches(body, b));
}

private boolean uniBodyMatches(String body, Body o) {
return tryCast(o, HttpRequestUniBody.class)
.map(h -> h.uniPart())
.map(u -> u.getValue().equals(body))
.orElse(false);
}

public boolean hasField(String name, String value) {
return getBodyStream()
.anyMatch(b -> hasField(name, value, b));
}

private boolean hasField(String name, String value, Body b) {
return tryCast(b, HttpRequestMultiPart.class)
.map(h -> h.multiParts())
.orElse(Collections.emptyList())
.stream()
.anyMatch(part -> part.getName().equals(name) && part.getValue().equals(value));
}

public Integer requestSize() {
return requests.size();
}
Expand Down Expand Up @@ -307,4 +322,5 @@ private static <T, M extends T> Optional<M> tryCast(T original, Class<M> too) {
}
return Optional.empty();
}

}
21 changes: 17 additions & 4 deletions unirest-mocks/src/main/java/kong/unirest/core/Routes.java
Expand Up @@ -99,20 +99,31 @@ private Optional<Invocation> getBestMatch(HttpRequest request, boolean expected)
}

@Override
public void assertHeader(String key, String value) {
public Assert hadHeader(String key, String value) {
if (invokes.stream().noneMatch(i -> i.hasExpectedHeader(key, value))) {
throw new UnirestAssertion(
"No invocation found with header [%s: %s]\nFound:\n%s",
key, value, allHeaders());
}
return this;
}

@Override
public void assertBody(String expected) {
public Assert hadBody(String expected) {
if(invokes.stream().noneMatch(i -> i.hasBody(expected))){
throw new UnirestAssertion(
"No invocation found with body");
}
return this;
}

@Override
public Assert hadField(String name, String value) {
if(invokes.stream().noneMatch(i -> i.hasField(name, value))){
throw new UnirestAssertion(
"No invocation found with body");
}
return this;
}

private Headers allHeaders() {
Expand All @@ -126,13 +137,14 @@ private Headers allHeaders() {
}

@Override
public void assertInvokedTimes(int i) {
public Assert wasInvokedTimes(int i) {
Integer sum = sumInvokes();
if (sum != i) {
throw new UnirestAssertion(
"Incorrect number of invocations. Expected %s got %s\n%s %s",
i, sum, method, path);
}
return this;
}

private Integer sumInvokes() {
Expand All @@ -142,8 +154,9 @@ private Integer sumInvokes() {
}

@Override
public void verifyAll() {
public Assert verifyAll() {
invokes.forEach(Invocation::verify);
return this;
}


Expand Down
49 changes: 36 additions & 13 deletions unirest-mocks/src/test/java/kong/tests/AssertTest.java
Expand Up @@ -25,19 +25,14 @@

package kong.tests;


import kong.unirest.core.Assert;
import kong.unirest.core.HttpMethod;
import kong.unirest.core.HttpResponse;
import kong.unirest.core.Unirest;
import kong.unirest.core.*;
import org.junit.jupiter.api.Test;

import java.util.function.Supplier;

import static kong.unirest.core.HttpMethod.GET;
import static kong.unirest.core.HttpMethod.POST;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.*;

class AssertTest extends Base {

Expand All @@ -47,13 +42,13 @@ void canAssertANumberOfTimes() {
Unirest.get(path).asEmpty();

Assert exp = client.assertThat(HttpMethod.GET, path);
exp.assertInvokedTimes(2);
exp.wasInvokedTimes(2);

assertException(() -> exp.assertInvokedTimes(1),
assertException(() -> exp.wasInvokedTimes(1),
"Incorrect number of invocations. Expected 1 got 2\n" +
"GET http://basic");

assertException(() -> exp.assertInvokedTimes(3),
assertException(() -> exp.wasInvokedTimes(3),
"Incorrect number of invocations. Expected 3 got 2\n" +
"GET http://basic");
}
Expand Down Expand Up @@ -83,9 +78,9 @@ void assertHeader() {
Unirest.get(path).header("monster", "grover").asEmpty();

Assert expect = client.assertThat(GET, path);
expect.assertHeader("monster", "grover");
expect.hadHeader("monster", "grover");

assertException(() -> expect.assertHeader("monster", "oscar"),
assertException(() -> expect.hadHeader("monster", "oscar"),
"No invocation found with header [monster: oscar]\nFound:\nmonster: grover");
}

Expand Down Expand Up @@ -156,7 +151,35 @@ void assertBody() {

Unirest.post(path).body("hey buddy").asString();

client.assertThat(POST, path).assertBody("hey buddy");
client.assertThat(POST, path).hadBody("hey buddy");
}

@Test
void assertBody_fail() {
client.expect(POST, path);

Unirest.post(path).body("hey buddy").asString();

assertThrows(UnirestAssertion.class,
() -> client.assertThat(POST, path).hadBody("I'm a big ol beat"));
}

@Test
void assertBody_multipart() {
client.expect(POST, path);

Unirest.post(path).field("hey", "buddy").asString();

client.assertThat(POST, path).hadField("hey", "buddy");
}

@Test
void assertBody_multipart_fails() {
client.expect(POST, path);

Unirest.post(path).field("hey", "buddy").asString();
assertThrows(UnirestAssertion.class, () -> client.assertThat(POST, path).hadField("nope", "buddy"));
assertThrows(UnirestAssertion.class, () -> client.assertThat(POST, path).hadField("hey", "nope"));
}

@Test
Expand Down

0 comments on commit 974c74c

Please sign in to comment.