package org.zalando.riptide; import lombok.Value; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.springframework.http.HttpMethod; import org.springframework.test.web.client.MockRestServiceServer; import java.net.URI; import java.util.Arrays; import java.util.Collection; import java.util.function.BiFunction; import java.util.function.Function; import static org.springframework.http.HttpMethod.DELETE; import static org.springframework.http.HttpMethod.GET; import static org.springframework.http.HttpMethod.HEAD; import static org.springframework.http.HttpMethod.OPTIONS; import static org.springframework.http.HttpMethod.PATCH; import static org.springframework.http.HttpMethod.POST; import static org.springframework.http.HttpMethod.PUT; import static org.springframework.http.HttpMethod.TRACE; import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; import static org.zalando.riptide.Route.call; import static org.zalando.riptide.Route.pass; /** * A test that verifies that the specific request methods in {@link Rest}, e.g. {@link Rest#get(URI)} delegate the * chosen method to {@link Rest#execute(HttpMethod, URI)} correctly * * @see Rest#get() * @see Rest#execute(HttpMethod) * @see Rest#get(URI) * @see Rest#execute(HttpMethod, URI) * @see Rest#get(String, Object...) * @see Rest#execute(HttpMethod, String, Object...) */ @RunWith(Parameterized.class) public final class MethodDelegateTest { private final HttpMethod method; private final Tester tester; public MethodDelegateTest(final HttpMethod method, final Tester tester) { this.method = method; this.tester = tester; } @Parameterized.Parameters(name = "{0} {1}") @SuppressWarnings("unchecked") public static Collection<Object[]> data() { return Arrays.asList(new Object[][] { {GET, new NoParam(Rest::get)}, {HEAD, new NoParam(Rest::head)}, {POST, new NoParam(Rest::post)}, {PUT, new NoParam(Rest::put)}, {PATCH, new NoParam(Rest::patch)}, {DELETE, new NoParam(Rest::delete)}, {OPTIONS, new NoParam(Rest::options)}, {TRACE, new NoParam(Rest::trace)}, {GET, new UriParam(Rest::get, URI.create("https://example.com"))}, {HEAD, new UriParam(Rest::head, URI.create("https://example.com"))}, {POST, new UriParam(Rest::post, URI.create("https://example.com"))}, {PUT, new UriParam(Rest::put, URI.create("https://example.com"))}, {PATCH, new UriParam(Rest::patch, URI.create("https://example.com"))}, {DELETE, new UriParam(Rest::delete, URI.create("https://example.com"))}, {OPTIONS, new UriParam(Rest::options, URI.create("https://example.com"))}, {TRACE, new UriParam(Rest::trace, URI.create("https://example.com"))}, {GET, new UriTemplateParam(Rest::get, "https://example.com")}, {HEAD, new UriTemplateParam(Rest::head, "https://example.com")}, {POST, new UriTemplateParam(Rest::post, "https://example.com")}, {PUT, new UriTemplateParam(Rest::put, "https://example.com")}, {PATCH, new UriTemplateParam(Rest::patch, "https://example.com")}, {DELETE, new UriTemplateParam(Rest::delete, "https://example.com")}, {OPTIONS, new UriTemplateParam(Rest::options, "https://example.com")}, {TRACE, new UriTemplateParam(Rest::trace, "https://example.com")}, }); } private interface Tester { Requester test(final Rest unit); } @Value private static final class NoParam implements Tester { Function<Rest, Requester> function; @Override public Requester test(final Rest unit) { return function.apply(unit); } @Override public String toString() { return "No URI"; } } @Value private static final class UriParam implements Tester { BiFunction<Rest, URI, Requester> function; URI parameter; @Override public Requester test(final Rest unit) { return function.apply(unit, parameter); } @Override public String toString() { return "URI"; } } @Value private static final class UriTemplateParam implements Tester { TriFunction<Rest, String, Object[], Requester> function; String parameter; @Override public Requester test(final Rest unit) { return function.apply(unit, parameter, new Object[0]); } @Override public String toString() { return "URI Template"; } } @FunctionalInterface public interface TriFunction<T, U, V, R> { R apply(T t, U u, V v); } @Test public void shouldDelegate() { final MockSetup setup = new MockSetup("https://example.com"); final Rest unit = setup.getRest(); final MockRestServiceServer server = setup.getServer(); server.expect(requestTo("https://example.com")) .andExpect(method(method)) .andRespond(withSuccess()); tester.test(unit) .call(call(pass())); server.verify(); } }