Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GitHubApiWireMockRule #541

Merged
merged 1 commit into from
Sep 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.15</version>
<version>1.18</version>
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java15</artifactId>
<artifactId>java17</artifactId>
<version>1.0</version>
</signature>
</configuration>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public abstract class AbstractGitHubApiTestBase extends AbstractGitHubApiWireMoc

@Before
public void setUp() throws Exception {
assumeTrue( "All tests inheriting from this class are not guaranteed to work without proxy", useProxy);
assumeTrue( "All tests inheriting from this class are not guaranteed to work without proxy", githubApi.isUseProxy());
}

protected GHUser getUser() {
Expand Down
96 changes: 33 additions & 63 deletions src/test/java/org/kohsuke/github/AbstractGitHubApiWireMockTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.TestWatcher;
import org.kohsuke.github.junit.GitHubApiWireMockRule;
import org.kohsuke.github.junit.WireMockRule;

import java.io.File;
Expand All @@ -21,55 +23,36 @@
import static com.github.tomakehurst.wiremock.client.WireMock.*;

/**
* @author Kohsuke Kawaguchi
* @author Liam Newman
*/
public abstract class AbstractGitHubApiWireMockTest extends Assert {

// By default the wiremock tests will run without proxy or taking a snapshot.
// The tests will use only the stubbed data and will fail if requests are made for missing data.
// You can use the proxy without taking a snapshot while writing and debugging tests.
// You cannot take a snapshot without proxying.
protected final static boolean takeSnapshot = System.getProperty("test.github.takeSnapshot", "false") != "false";
protected final static boolean useProxy = takeSnapshot || System.getProperty("test.github.useProxy", "false") != "false";
private final GitHubBuilder githubBuilder = createGitHubBuilder();

public final static String STUBBED_USER_LOGIN = "placeholder-user";
public final static String STUBBED_USER_PASSWORD = "placeholder-password";

/**
* {@link GitHub} instance for use during test.
* Traffic will be part of snapshot when taken.
*/
protected GitHub gitHub;
private final String baseFilesClassPath = this.getClass().getName().replace('.', '/');
protected final String baseRecordPath = "src/test/resources/" + baseFilesClassPath + "/wiremock";

/**
* {@link GitHub} instance for use before/after test.
* Traffic will not be part of snapshot when taken.
* Should only be used when isUseProxy() or isTakeSnapShot().
*/
protected GitHub gitHubBeforeAfter;

protected final String baseFilesClassPath = this.getClass().getName().replace('.', '/');
protected final String baseRecordPath = "src/test/resources/" + baseFilesClassPath + "/wiremock";

@Rule
public WireMockRule githubApi = new WireMockRule(WireMockConfiguration.options()
.dynamicPort()
.usingFilesUnderDirectory(baseRecordPath)
.extensions(
new ResponseTransformer() {
@Override
public Response transform(Request request, Response response, FileSource files,
Parameters parameters) {
if ("application/json"
.equals(response.getHeaders().getContentTypeHeader().mimeTypePart())
&& !response.getHeaders().getHeader("Content-Encoding").containsValue("gzip")) {
return Response.Builder.like(response)
.but()
.body(response.getBodyAsString()
.replace("https://api.github.com/",
"http://localhost:" + githubApi.port() + "/")
)
.build();
}
return response;
}

@Override
public String getName() {
return "github-api-url-rewrite";
}
})
public GitHubApiWireMockRule githubApi = new GitHubApiWireMockRule(
WireMockConfiguration.options()
.dynamicPort()
.usingFilesUnderDirectory(baseRecordPath)
);

private static GitHubBuilder createGitHubBuilder() {
Expand All @@ -96,13 +79,6 @@ private static GitHubBuilder createGitHubBuilder() {
} catch (IOException e) {
}

if (!useProxy) {
// This sets the user and password to a placeholder for wiremock testing
// This makes the tests believe they are running with permissions
// The recorded stubs will behave like they running with permissions
builder.withPassword(STUBBED_USER_LOGIN, STUBBED_USER_PASSWORD);
}

return builder.withRateLimitHandler(RateLimitHandler.FAIL);
}

Expand All @@ -112,31 +88,25 @@ protected GitHubBuilder getGitHubBuilder() {

@Before
public void wireMockSetup() throws Exception {
if(useProxy) {
githubApi.stubFor(
proxyAllTo("https://api.github.com/")
.atPriority(100)
);
} else {
// Just to be super clear
githubApi.stubFor(
any(urlPathMatching(".*"))
.willReturn(status(500).withBody("Stubbed data not found. Set test.github.use-proxy to have WireMock proxy to github"))
.atPriority(100));
}
GitHubBuilder builder = getGitHubBuilder();

if (!githubApi.isUseProxy()) {
// This sets the user and password to a placeholder for wiremock testing
// This makes the tests believe they are running with permissions
// The recorded stubs will behave like they running with permissions
builder.withPassword(STUBBED_USER_LOGIN, STUBBED_USER_PASSWORD);
}

gitHub = getGitHubBuilder()
gitHub = builder
.withEndpoint("http://localhost:" + githubApi.port())
.build();
}

@After
public void snapshotRequests() {
if (takeSnapshot) {
githubApi.snapshotRecord(recordSpec()
.forTarget("https://api.github.com")
.extractTextBodiesOver(255));
if (githubApi.isUseProxy()) {
gitHubBeforeAfter = builder
.withEndpoint("https://api.github.com/")
.build();
} else {
gitHubBeforeAfter = null;
}
}
}
10 changes: 5 additions & 5 deletions src/test/java/org/kohsuke/github/GHOrganizationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class GHOrganizationTest extends AbstractGitHubApiTestBase {
@Override
public void setUp() throws Exception {
super.setUp();
if (useProxy) {
if (githubApi.isUseProxy()) {
org = gitHub.getOrganization("github-api-test-org");
}
}
Expand All @@ -39,9 +39,9 @@ public void testCreateRepositoryWithAutoInitialization() throws IOException {

@After
public void cleanUp() throws Exception {
if (useProxy) {
GHRepository repository = org.getRepository(GITHUB_API_TEST);
repository.delete();
}
if (githubApi.isUseProxy()) {
GHRepository repository = org.getRepository(GITHUB_API_TEST);
repository.delete();
}
}
}
23 changes: 14 additions & 9 deletions src/test/java/org/kohsuke/github/PullRequestTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@
*/
public class PullRequestTest extends AbstractGitHubApiWireMockTest {

@Before
@After
public void cleanUp() throws Exception {
// Cleanup is only needed when proxying
if (!githubApi.isUseProxy()) return;

for (GHPullRequest pr : getRepository(this.gitHubBeforeAfter).getPullRequests(GHIssueState.OPEN)) {
pr.close();
}
}

@Test
public void createPullRequest() throws Exception {
String name = "createPullRequest";
Expand Down Expand Up @@ -220,17 +231,11 @@ public void getUser() throws IOException {
}
}

@After
public void cleanUp() throws Exception {
// Cleanup is only needed when proxying
if (useProxy) {
for (GHPullRequest pr : getRepository().getPullRequests(GHIssueState.OPEN)) {
pr.close();
}
}
protected GHRepository getRepository() throws IOException {
return getRepository(gitHub);
}

private GHRepository getRepository() throws IOException {
private GHRepository getRepository(GitHub gitHub) throws IOException {
return gitHub.getOrganization("github-api-test-org").getRepository("github-api");
}
}
22 changes: 11 additions & 11 deletions src/test/java/org/kohsuke/github/WireMockStatusReporterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ public class WireMockStatusReporterTest extends AbstractGitHubApiWireMockTest {

@Test
public void user_whenProxying_AuthCorrectlyConfigured() throws Exception {
assumeFalse("Test only valid when not taking a snapshot", takeSnapshot);
assumeTrue("Test only valid when proxying (-Dtest.github.useProxy to enable)", useProxy);
assumeFalse("Test only valid when not taking a snapshot", githubApi.isTakeSnapshot());
assumeTrue("Test only valid when proxying (-Dtest.github.useProxy to enable)", githubApi.isUseProxy());

assertThat(
"GitHub connection believes it is anonymous. Make sure you set GITHUB_OAUTH or both GITHUB_USER and GITHUB_PASSWORD environment variables",
Expand All @@ -42,8 +42,8 @@ public void user_whenProxying_AuthCorrectlyConfigured() throws Exception {

@Test
public void user_whenNotProxying_Stubbed() throws Exception {
assumeFalse("Test only valid when not taking a snapshot", takeSnapshot);
assumeFalse("Test only valid when not proxying", useProxy);
assumeFalse("Test only valid when not taking a snapshot", githubApi.isTakeSnapshot());
assumeFalse("Test only valid when not proxying", githubApi.isUseProxy());

assertThat(gitHub.isAnonymous(), is(false));
assertThat(gitHub.login, equalTo(STUBBED_USER_LOGIN));
Expand All @@ -59,8 +59,8 @@ public void user_whenNotProxying_Stubbed() throws Exception {

@Test
public void BasicBehaviors_whenNotProxying() throws Exception {
assumeFalse("Test only valid when not taking a snapshot", takeSnapshot);
assumeFalse("Test only valid when not proxying", useProxy);
assumeFalse("Test only valid when not taking a snapshot", githubApi.isTakeSnapshot());
assumeFalse("Test only valid when not proxying", githubApi.isUseProxy());

Exception e = null;
GHRepository repo = null;
Expand Down Expand Up @@ -96,8 +96,8 @@ public void BasicBehaviors_whenNotProxying() throws Exception {

@Test
public void BasicBehaviors_whenProxying() throws Exception {
assumeFalse("Test only valid when not taking a snapshot", takeSnapshot);
assumeTrue("Test only valid when proxying (-Dtest.github.useProxy to enable)", useProxy);
assumeFalse("Test only valid when not taking a snapshot", githubApi.isTakeSnapshot());
assumeTrue("Test only valid when proxying (-Dtest.github.useProxy to enable)", githubApi.isUseProxy());
Exception e = null;
GHRepository repo = null;

Expand All @@ -123,15 +123,15 @@ public void BasicBehaviors_whenProxying() throws Exception {

@Test
public void whenSnapshot_EnsureProxy() throws Exception {
assumeTrue("Test only valid when Snapshotting (-Dtest.github.takeSnapshot to enable)", takeSnapshot);
assumeTrue("Test only valid when Snapshotting (-Dtest.github.takeSnapshot to enable)", githubApi.isTakeSnapshot());

assertTrue("When taking a snapshot, proxy should automatically be enabled", useProxy);
assertTrue("When taking a snapshot, proxy should automatically be enabled", githubApi.isUseProxy());
}

@Ignore("Not implemented yet")
@Test
public void whenSnapshot_EnsureRecordToExpectedLocation() throws Exception {
assumeTrue("Test only valid when Snapshotting (-Dtest.github.takeSnapshot to enable)", takeSnapshot);
assumeTrue("Test only valid when Snapshotting (-Dtest.github.takeSnapshot to enable)", githubApi.isTakeSnapshot());

}
}
94 changes: 94 additions & 0 deletions src/test/java/org/kohsuke/github/junit/GitHubApiWireMockRule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package org.kohsuke.github.junit;

import com.github.tomakehurst.wiremock.common.FileSource;
import com.github.tomakehurst.wiremock.core.Options;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.github.tomakehurst.wiremock.extension.Parameters;
import com.github.tomakehurst.wiremock.extension.ResponseTransformer;
import com.github.tomakehurst.wiremock.http.Request;
import com.github.tomakehurst.wiremock.http.Response;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.client.WireMock.status;

/**
* @author Liam Newman
*/
public class GitHubApiWireMockRule extends WireMockRule {

// By default the wiremock tests will run without proxy or taking a snapshot.
// The tests will use only the stubbed data and will fail if requests are made for missing data.
// You can use the proxy without taking a snapshot while writing and debugging tests.
// You cannot take a snapshot without proxying.
private final static boolean takeSnapshot = System.getProperty("test.github.takeSnapshot", "false") != "false";
private final static boolean useProxy = takeSnapshot || System.getProperty("test.github.useProxy", "false") != "false";

public GitHubApiWireMockRule(WireMockConfiguration options) {
this(options, true);
}

public GitHubApiWireMockRule(WireMockConfiguration options, boolean failOnUnmatchedRequests) {
super(options
.extensions(
new ResponseTransformer() {
@Override
public Response transform(Request request, Response response, FileSource files,
Parameters parameters) {
if ("application/json"
.equals(response.getHeaders().getContentTypeHeader().mimeTypePart())
&& !response.getHeaders().getHeader("Content-Encoding").containsValue("gzip")) {
return Response.Builder.like(response)
.but()
.body(response.getBodyAsString()
.replace("https://api.github.com/",
"http://localhost:" + request.getPort() + "/")
)
.build();
}
return response;
}

@Override
public String getName() {
return "github-api-url-rewrite";
}
}),
failOnUnmatchedRequests);
}

public boolean isUseProxy() {
return GitHubApiWireMockRule.useProxy;
}

public boolean isTakeSnapshot() {
return GitHubApiWireMockRule.takeSnapshot;
}

@Override
protected void before() {
super.before();
if(isUseProxy()) {
this.stubFor(
proxyAllTo("https://api.github.com/")
.atPriority(100)
);
} else {
// Just to be super clear
this.stubFor(
any(urlPathMatching(".*"))
.willReturn(status(500).withBody("Stubbed data not found. Set test.github.use-proxy to have WireMock proxy to github"))
.atPriority(100));
}
}

@Override
protected void after() {
super.after();
if (isTakeSnapshot()) {
this.snapshotRecord(recordSpec()
.forTarget("https://api.github.com")
.captureHeader("If-None-Match")
.extractTextBodiesOver(255));
}
}
}
Loading