Skip to content

Commit 49f608f

Browse files
Improved tests
1 parent 19f5eb1 commit 49f608f

File tree

3 files changed

+71
-11
lines changed

3 files changed

+71
-11
lines changed

src/main/java/io/github/coffeelibs/tinyoauth2client/http/RedirectTarget.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.nio.channels.ServerSocketChannel;
1717
import java.nio.charset.StandardCharsets;
1818
import java.nio.file.Path;
19+
import java.util.Objects;
1920

2021
/**
2122
* A TCP connector to deal with the redirect response. We only listen for the expected response,
@@ -93,11 +94,11 @@ static void tryBind(ServerSocketChannel ch, int... ports) throws IOException {
9394
}
9495

9596
public void setSuccessResponse(Response successResponse) {
96-
this.successResponse = successResponse;
97+
this.successResponse = Objects.requireNonNull(successResponse);
9798
}
9899

99100
public void setErrorResponse(Response errorResponse) {
100-
this.errorResponse = errorResponse;
101+
this.errorResponse = Objects.requireNonNull(errorResponse);
101102
}
102103

103104
public URI getRedirectUri() {

src/test/java/io/github/coffeelibs/tinyoauth2client/AuthFlowTest.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public class WithMockedRedirectTarget {
6060
@BeforeEach
6161
@SuppressWarnings({"unchecked"})
6262
public void setup() throws IOException {
63-
authEndpoint = URI.create("https://login.example.com/?existing_param=existing-value");
63+
authEndpoint = URI.create("https://login.example.com/");
6464
redirectTarget = Mockito.mock(RedirectTarget.class);
6565
redirectTargetClass = Mockito.mockStatic(RedirectTarget.class);
6666
redirectTargetClass.when(() -> RedirectTarget.start(Mockito.any(), Mockito.any())).thenReturn(redirectTarget);
@@ -145,7 +145,26 @@ public void testWithErrorHtml() {
145145
}
146146

147147
@Test
148-
@DisplayName("authorize(...) succeeds if browser redirects to URI")
148+
@DisplayName("authorize(...) with existing query string in authorization endpoint")
149+
public void testAuthorizeWithExistingQueryParams() throws IOException {
150+
authEndpoint = URI.create("https://login.example.com/?existing_param=existing-value");
151+
var authFlow = AuthFlow.asClient("my-client");
152+
153+
var result = authFlow.authorize(authEndpoint, browser);
154+
155+
Assertions.assertInstanceOf(AuthFlow.AuthFlowWithCode.class, result);
156+
var browsedUriCaptor = ArgumentCaptor.forClass(URI.class);
157+
Mockito.verify(browser).accept(browsedUriCaptor.capture());
158+
var browsedUri = browsedUriCaptor.getValue();
159+
Assertions.assertNotNull(browsedUri);
160+
Assertions.assertNotNull(browsedUri.getRawQuery());
161+
var queryParams = URIUtil.parseQueryString(browsedUri.getRawQuery());
162+
Assertions.assertEquals("existing-value", queryParams.get("existing_param"));
163+
Assertions.assertEquals("code", queryParams.get("response_type"));
164+
}
165+
166+
@Test
167+
@DisplayName("authorize(...) with custom scopes")
149168
public void testAuthorize() throws IOException {
150169
var authFlow = AuthFlow.asClient("my-client");
151170

@@ -158,7 +177,6 @@ public void testAuthorize() throws IOException {
158177
Assertions.assertNotNull(browsedUri);
159178
Assertions.assertNotNull(browsedUri.getRawQuery());
160179
var queryParams = URIUtil.parseQueryString(browsedUri.getRawQuery());
161-
Assertions.assertEquals("existing-value", queryParams.get("existing_param"));
162180
Assertions.assertEquals(authFlow.clientId, queryParams.get("client_id"));
163181
Assertions.assertEquals("code", queryParams.get("response_type"));
164182
Assertions.assertEquals(redirectTarget.getCsrfToken(), queryParams.get("state"));

src/test/java/io/github/coffeelibs/tinyoauth2client/http/RedirectTargetTest.java

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,50 @@
2828
import java.util.concurrent.CompletableFuture;
2929
import java.util.concurrent.CountDownLatch;
3030
import java.util.concurrent.ExecutionException;
31-
import java.util.concurrent.Executors;
3231
import java.util.concurrent.atomic.AtomicReference;
3332

3433
@Timeout(value = 3)
34+
@SuppressWarnings("resource")
3535
public class RedirectTargetTest {
3636

37+
@Test
38+
@DisplayName("start() doesn't accept a relative path")
39+
public void testStartWithRelativePath() {
40+
Assertions.assertThrows(IllegalArgumentException.class, () -> RedirectTarget.start("hello"));
41+
}
42+
43+
@Test
44+
@DisplayName("setSuccessResponse() fails on null")
45+
public void testSetSuccessNull() throws IOException {
46+
try (var target = RedirectTarget.start("/")) {
47+
Assertions.assertThrows(NullPointerException.class, () -> target.setSuccessResponse(null));
48+
}
49+
}
50+
51+
@Test
52+
@DisplayName("setSuccessResponse() succeeds on non-null")
53+
public void testSetSuccessNonNull() throws IOException {
54+
try (var target = RedirectTarget.start("/")) {
55+
Assertions.assertDoesNotThrow(() -> target.setSuccessResponse(Response.empty(Response.Status.OK)));
56+
}
57+
}
58+
59+
@Test
60+
@DisplayName("setErrorResponse() fails on null")
61+
public void testSetErrorNull() throws IOException {
62+
try (var target = RedirectTarget.start("/")) {
63+
Assertions.assertThrows(NullPointerException.class, () -> target.setErrorResponse(null));
64+
}
65+
}
66+
67+
@Test
68+
@DisplayName("setErrorResponse() succeeds on non-null")
69+
public void testSetErrorNonNull() throws IOException {
70+
try (var target = RedirectTarget.start("/")) {
71+
Assertions.assertDoesNotThrow(() -> target.setErrorResponse(Response.empty(Response.Status.OK)));
72+
}
73+
}
74+
3775
@Test
3876
@DisplayName("start() doesn't leak resource on error")
3977
public void testStartExceptionally() throws IOException {
@@ -134,9 +172,11 @@ public void testRedirectError() throws IOException, InterruptedException, URISyn
134172

135173
@Test
136174
@DisplayName("http response 400 for missing code")
137-
public void testRedirectMissingCode() throws IOException, InterruptedException {
175+
public void testRedirectMissingCode() throws IOException, InterruptedException, URISyntaxException {
138176
try (var redirect = RedirectTarget.start("/")) {
139-
var uri = redirect.getRedirectUri();
177+
var baseUri = redirect.getRedirectUri();
178+
var query = "state=" + redirect.getCsrfToken();
179+
var uri = new URI(baseUri.getScheme(), baseUri.getAuthority(), baseUri.getPath(), query, baseUri.getFragment());
140180

141181
var accessToken = receiveAsync(redirect);
142182
var request = HttpRequest.newBuilder(uri).GET().build();
@@ -211,20 +251,21 @@ public void testInterrupt() throws IOException, InterruptedException {
211251
var threadStarted = new CountDownLatch(1);
212252
var threadExited = new CountDownLatch(1);
213253
var exception = new AtomicReference<Exception>();
214-
var future = Executors.newSingleThreadExecutor().submit(() -> {
254+
var thread = new Thread(() -> {
215255
try {
216256
threadStarted.countDown();
217-
return redirect.receive();
257+
redirect.receive();
218258
} catch (IOException e) {
219259
exception.set(e);
220260
throw new UncheckedIOException(e);
221261
} finally {
222262
threadExited.countDown();
223263
}
224264
});
265+
thread.start();
225266

226267
threadStarted.await();
227-
future.cancel(true);
268+
thread.interrupt();
228269
threadExited.await();
229270

230271
Assertions.assertInstanceOf(ClosedByInterruptException.class, exception.get());

0 commit comments

Comments
 (0)