Skip to content

Commit

Permalink
Adding MoccaHttpClient common functional tests #32 (#36)
Browse files Browse the repository at this point in the history
Adding module with common tests that have to be explicitly included with each MoccaHttpClient project.
Plus some enhancements to MoccaJaxrsClient.
  • Loading branch information
crankydillo authored Sep 15, 2021
1 parent 6399ab6 commit 1e08fc9
Show file tree
Hide file tree
Showing 18 changed files with 229 additions and 27 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
description = "Mocca is a GraphQL client for JVM languages with the goal of being easy to use, flexible and modular."

Set testModules = [
"mocca-functional-tests"
"mocca-functional-tests",
"mocca-http-client-tests"
]

subprojects {
Expand Down
3 changes: 3 additions & 0 deletions mocca-apache/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ dependencies {
implementation project(':mocca-client'),
lib.feign_apache
api lib.apache_client

testImplementation project(':mocca-http-client-tests'),
lib.testng
}
11 changes: 11 additions & 0 deletions mocca-apache/src/test/java/com/paypal/mocca/client/BasicTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.paypal.mocca.client;

import org.apache.http.impl.client.HttpClientBuilder;
import org.testng.annotations.Test;

@Test
public class BasicTest extends BasicMoccaHttpClientTest {
public BasicTest() {
super(new MoccaApacheClient(HttpClientBuilder.create().build()));
}
}
3 changes: 3 additions & 0 deletions mocca-google/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ dependencies {
implementation project(':mocca-client'),
lib.feign_google
api lib.google_client

testImplementation project(':mocca-http-client-tests'),
lib.testng
}
11 changes: 11 additions & 0 deletions mocca-google/src/test/java/com/paypal/mocca/client/BasicTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.paypal.mocca.client;

import com.google.api.client.http.javanet.NetHttpTransport;
import org.testng.annotations.Test;

@Test
public class BasicTest extends BasicMoccaHttpClientTest {
public BasicTest() {
super(new MoccaGoogleHttpClient(new NetHttpTransport()));
}
}
3 changes: 3 additions & 0 deletions mocca-hc5/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ dependencies {
implementation project(':mocca-client'),
lib.feign_hc5
api lib.hc5_client

testImplementation project(':mocca-http-client-tests'),
lib.testng
}
11 changes: 11 additions & 0 deletions mocca-hc5/src/test/java/com/paypal/mocca/client/BasicTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.paypal.mocca.client;

import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.testng.annotations.Test;

@Test
public class BasicTest extends BasicMoccaHttpClientTest {
public BasicTest() {
super(new MoccaApache5Client(HttpClientBuilder.create().build()));
}
}
4 changes: 4 additions & 0 deletions mocca-http-client-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Introduction

This module is a common test bed meant to be used by implementations of
`com.paypal.mocca.client.MoccaHttpClient`.
5 changes: 5 additions & 0 deletions mocca-http-client-tests/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
dependencies {
implementation project(':mocca-client'),
lib.jetty_server,
lib.testng
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.paypal.mocca.client;

import com.paypal.mocca.client.annotation.Query;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static org.testng.Assert.assertEquals;

/**
* Verifies that a supplied {@link MoccaHttpClient} works for
* some basic GraphQL call. The general idea being that we're
* just testing the basic HTTP parts function correctly (e.g.
* POST requests).
* <p></p>
* Unfortunately, there seems to be a Gradle or TestNG bug where
* if a class contains no tests but extends one that does, then
* Gradle build will not execute the test. Annotating the concrete
* class with `@Test` appears to 'solve' the problem.
*/
abstract class BasicMoccaHttpClientTest {
// TODO solve the gradlew problem described above. Some links:
// https://discuss.gradle.org/t/testng-tests-that-inherit-from-a-base-class-but-do-not-add-new-test-methods-are-not-detected/1259
// https://stackoverflow.com/questions/64087969/testng-cannot-find-test-methods-with-inheritance

private static final String GRAPHQL_GREETING = "Hello!";

private final MoccaHttpClient moccaHttpClient;
private Server graphqlServer;
private SampleDataClient sampleDataClient;

BasicMoccaHttpClientTest(MoccaHttpClient moccaHttpClient) {
this.moccaHttpClient = Arguments.requireNonNull(moccaHttpClient);
}

@BeforeClass
public void setUp() throws Exception {
final int port = 0; // signals use random port
graphqlServer = new Server(port);
graphqlServer.setHandler(new AbstractHandler() {
@Override
public void handle(String target, Request baseRequest, HttpServletRequest req, HttpServletResponse resp)
throws IOException {
baseRequest.setHandled(true);
resp.getWriter().write("{ \"data\": { \"greeting\": \"" + GRAPHQL_GREETING + "\" } }");
}
});
graphqlServer.start();
sampleDataClient = MoccaClient.Builder.sync(graphqlServer.getURI().toASCIIString())
.client(moccaHttpClient)
.build(SampleDataClient.class);
}

@AfterClass
public void tearDown() throws Exception {
graphqlServer.stop();
}

@Test(description = "Basic GraphQL call")
void testBasic() {
final String greeting = sampleDataClient.greeting();
assertEquals(greeting, GRAPHQL_GREETING);
}

public interface SampleDataClient extends MoccaClient {
@Query
String greeting();
}
}
3 changes: 3 additions & 0 deletions mocca-http2/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ targetCompatibility = 1.11
dependencies {
implementation project(':mocca-client'),
lib.feign_java11

testImplementation project(':mocca-http-client-tests'),
lib.testng
}
12 changes: 12 additions & 0 deletions mocca-http2/src/test/java/com/paypal/mocca/client/BasicTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.paypal.mocca.client;

import org.testng.annotations.Test;

import java.net.http.HttpClient;

@Test
public class BasicTest extends BasicMoccaHttpClientTest {
public BasicTest() {
super(new MoccaHttp2Client(HttpClient.newBuilder().build()));
}
}
10 changes: 8 additions & 2 deletions mocca-jaxrs2/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
dependencies {
implementation project(':mocca-client'),
lib.feign_jaxrs2
lib.feign_jaxrs2,
lib.slf4j_api
api lib.jaxrs2
}

testImplementation project(':mocca-http-client-tests'),
lib.testng,
lib.jersey_client,
lib.jersey_hk2
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.paypal.mocca.client;

import feign.jaxrs2.JAXRSClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
Expand All @@ -14,13 +16,18 @@
import java.util.concurrent.TimeUnit;

/**
* Mocca JAX-RS 2 client. In order to use a JAX-RS 2 client with Mocca, create a new instance of this class and pass it to
* Mocca builder.
* Mocca JAX-RS 2 client. In order to use a JAX-RS 2 client with Mocca, create a new instance of this class and pass it
* to Mocca builder.
* <br>
* See {@link com.paypal.mocca.client.MoccaClient.Builder.SyncBuilder#client(MoccaHttpClient)} for further information
* and code example.
* <br>
* Instances of this class are technically supposed to support concepts like setting the read and connect timeouts per
* request. However, those are ignored. The only timeouts that are used are what's established in the supplied
* {@link Client}.
*/
final public class MoccaJaxrsClient extends MoccaHttpClient {
private static Logger log = LoggerFactory.getLogger(MoccaJaxrsClient.class);

/**
* Create a Mocca JAX-RS 2 client using the supplied {@link Client}.
Expand All @@ -29,15 +36,18 @@ final public class MoccaJaxrsClient extends MoccaHttpClient {
*/
public MoccaJaxrsClient(final Client client) {
super(new JAXRSClient(new StubbornClientBuilder(client)));
log.debug("Users of this may attempt to set read timeout and connect timeout per request. " +
"However, those are ignored. They should be established in the supplied javax.ws.rs.Client.");
}

private static class StubbornClientBuilder extends ClientBuilder {
private static Logger log = LoggerFactory.getLogger(StubbornClientBuilder.class);
private static final String USAGE_ERR_MSG = "Only #build can be called.";

final Client client;
private final Client client;

private StubbornClientBuilder(final Client client) {
this.client = Arguments.requireNonNull(client);
private StubbornClientBuilder(Client client) {
this.client = client;
}

@Override
Expand All @@ -47,97 +57,113 @@ public Client build() {

@Override
public ClientBuilder withConfig(Configuration config) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder sslContext(SSLContext sslContext) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder keyStore(KeyStore keyStore, char[] password) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder trustStore(KeyStore trustStore) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder hostnameVerifier(HostnameVerifier verifier) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder executorService(ExecutorService executorService) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder scheduledExecutorService(ScheduledExecutorService scheduledExecutorService) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder connectTimeout(long timeout, TimeUnit unit) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder readTimeout(long timeout, TimeUnit unit) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
return this;
}

@Override
public Configuration getConfiguration() {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
return client.getConfiguration();
}

@Override
public ClientBuilder property(String name, Object value) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder register(Class<?> componentClass) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder register(Class<?> componentClass, int priority) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder register(Class<?> componentClass, Class<?>... contracts) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder register(Class<?> componentClass, Map<Class<?>, Integer> contracts) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder register(Object component) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder register(Object component, int priority) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder register(Object component, Class<?>... contracts) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}

@Override
public ClientBuilder register(Object component, Map<Class<?>, Integer> contracts) {
throw new UnsupportedOperationException(USAGE_ERR_MSG);
log.warn(USAGE_ERR_MSG);
return this;
}
}
}
12 changes: 12 additions & 0 deletions mocca-jaxrs2/src/test/java/com/paypal/mocca/client/BasicTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.paypal.mocca.client;

import org.testng.annotations.Test;

import javax.ws.rs.client.ClientBuilder;

@Test
public class BasicTest extends BasicMoccaHttpClientTest {
public BasicTest() {
super(new MoccaJaxrsClient(ClientBuilder.newClient()));
}
}
Loading

0 comments on commit 1e08fc9

Please sign in to comment.