Skip to content

Commit 32b0bf5

Browse files
authored
fix tests that fail for the wrong reasons (#45)
I noticed that the test `assertJwtEndpointWithNoKeyThrows()` was taking 10 seconds to run so I took a look into why that was. The test method has `@Test(expected=Exception.class)` but the exception that is thrown is different than the one that the test is expected - the test was throwing a SocketTimeoutException after 10 seconds (which is the OkHttpClient's default read timeout setting) because there was no mock requests enqueued in the mock web server. I refactored these tests to use `assertThrows` instead to assert against the details of the thrown Exceptions, and also fixed what seems like a bug in the `getAuthorizationHeader` method - if the client has an accessToken, it will be used as the header, even if the request path is one that needs a private-key-signed JWT token.
1 parent 29c6266 commit 32b0bf5

File tree

3 files changed

+49
-11
lines changed

3 files changed

+49
-11
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
<guava.version>28.0-jre</guava.version>
9393
<jsr305.version>3.0.2</jsr305.version>
9494
<jsr311-api.version>1.1.1</jsr311-api.version>
95-
<junit.version>4.13</junit.version>
95+
<junit.version>4.13.1</junit.version>
9696
<slf4j-api.version>1.7.12</slf4j-api.version>
9797
<mockito-core.version>3.2.4</mockito-core.version>
9898
<commons-io.version>2.6</commons-io.version>

src/main/java/com/spotify/github/v3/clients/GitHubClient.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,9 @@ private Request.Builder requestBuilder(final String path) {
542542
(3) Installation Token, generated from the JWT token. Also used in Github Apps.
543543
*/
544544
private String getAuthorizationHeader(final String path) {
545+
if (isJwtRequest(path) && getPrivateKey().isEmpty()) {
546+
throw new IllegalStateException("This endpoint needs a client with a private key for an App");
547+
}
545548
if (getAccessToken().isPresent()) {
546549
return String.format("token %s", token);
547550
} else if (getPrivateKey().isPresent()) {
@@ -603,12 +606,19 @@ private AccessToken generateInstallationToken(final String jwtToken, final int i
603606

604607
final Response response = client.newCall(request).execute();
605608

606-
if (response.body() == null) {
609+
if (!response.isSuccessful()) {
607610
throw new Exception(
608611
String.format(
609-
"Got status %s when getting an access token from GitHub: %s",
612+
"Got non-2xx status %s when getting an access token from GitHub: %s",
610613
response.code(), response.message()));
611614
}
615+
616+
if (response.body() == null) {
617+
throw new Exception(
618+
String.format(
619+
"Got empty response body when getting an access token from GitHub, HTTP status was: %s",
620+
response.message()));
621+
}
612622
final String text = response.body().string();
613623
response.body().close();
614624
return Json.create().fromJson(text, AccessToken.class);

src/test/java/com/spotify/github/v3/clients/GitHubAuthTest.java

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@
2222

2323
import static com.spotify.github.v3.clients.ChecksClientTest.loadResource;
2424
import static org.hamcrest.CoreMatchers.hasItem;
25+
import static org.hamcrest.CoreMatchers.instanceOf;
2526
import static org.hamcrest.CoreMatchers.is;
27+
import static org.hamcrest.CoreMatchers.notNullValue;
2628
import static org.hamcrest.CoreMatchers.startsWith;
2729
import static org.hamcrest.MatcherAssert.assertThat;
30+
import static org.junit.Assert.assertThrows;
2831

2932
import com.fasterxml.jackson.core.JsonProcessingException;
3033
import com.spotify.github.jackson.Json;
@@ -33,8 +36,10 @@
3336
import java.io.File;
3437
import java.io.IOException;
3538
import java.net.URI;
39+
import java.time.Duration;
3640
import java.time.ZonedDateTime;
3741
import java.util.Objects;
42+
import java.util.concurrent.TimeUnit;
3843
import okhttp3.OkHttpClient;
3944
import okhttp3.mockwebserver.MockResponse;
4045
import okhttp3.mockwebserver.MockWebServer;
@@ -72,7 +77,12 @@ public GitHubAuthTest() throws JsonProcessingException {}
7277

7378
@Before
7479
public void setUp() throws IOException {
75-
client = new OkHttpClient();
80+
client =
81+
new OkHttpClient.Builder()
82+
.connectTimeout(Duration.ofSeconds(1))
83+
.readTimeout(Duration.ofSeconds(1))
84+
.build();
85+
7686
mockServer.start();
7787
url = mockServer.url("/").uri();
7888
checksClient =
@@ -139,10 +149,20 @@ public void fetchesANewInstallationTokenIfExpired() throws Exception {
139149
assertThat(mockServer.takeRequest().getPath(), is("/repos/foo/bar/check-runs/123"));
140150
}
141151

142-
@Test(expected = Exception.class)
143-
public void throwsIfFetchingInstallationTokenRequestIsUnsuccessful() {
152+
@Test
153+
public void throwsIfFetchingInstallationTokenRequestIsUnsuccessful() throws Exception {
144154
mockServer.enqueue(new MockResponse().setResponseCode(500));
145-
checksClient.getCheckRun(123).join();
155+
RuntimeException ex =
156+
assertThrows(RuntimeException.class, () -> checksClient.getCheckRun(123).join());
157+
158+
assertThat(ex.getMessage(), is("Could not generate access token for github app"));
159+
160+
assertThat(ex.getCause(), is(notNullValue()));
161+
assertThat(ex.getCause().getMessage(), startsWith("Got non-2xx status 500 when getting an access token from GitHub"));
162+
163+
RecordedRequest recordedRequest = mockServer.takeRequest(1, TimeUnit.MILLISECONDS);
164+
// make sure it was the expected request that threw
165+
assertThat(recordedRequest.getRequestUrl().encodedPath(), is("/app/installations/1/access_tokens"));
146166
}
147167

148168
@Test
@@ -178,16 +198,24 @@ public void assertChecksApiContainsCorrectHeader() throws Exception {
178198
assertThat(request2.getMethod(), is("PATCH"));
179199
}
180200

181-
@Test(expected = Exception.class)
201+
@Test
182202
public void assertInstallationEndpointWithoutInstallationThrows() {
183203
final GitHubClient github = GitHubClient.create(client, url, key, 123);
184-
github.createRepositoryClient("foo", "bar").createChecksApiClient().getCheckRun(123).join();
204+
final RuntimeException ex = assertThrows(RuntimeException.class,
205+
() -> github.createRepositoryClient("foo", "bar").createChecksApiClient().getCheckRun(123)
206+
.join());
207+
assertThat(ex.getMessage(), is("This endpoint needs a client with an installation ID"));
185208
}
186209

187-
@Test(expected = Exception.class)
210+
@Test
188211
public void assertJwtEndpointWithNoKeyThrows() {
189212
final GitHubClient github = GitHubClient.create(client, url, "a-token");
190-
github.createRepositoryClient("foo", "bar").createGithubAppClient().getInstallations().join();
213+
214+
final IllegalStateException ex = assertThrows(IllegalStateException.class,
215+
() -> github.createRepositoryClient("foo", "bar").createGithubAppClient().getInstallations()
216+
.join());
217+
218+
assertThat(ex.getMessage(), is("This endpoint needs a client with a private key for an App"));
191219
}
192220

193221
@Test

0 commit comments

Comments
 (0)