@@ -189,6 +189,84 @@ public void testAuthorize() throws IOException {
189189
190190 }
191191
192+ @ Nested
193+ @ DisplayName ("refresh(...)" )
194+ public class RefreshTokens {
195+
196+ private AuthFlow authFlow ;
197+ private HttpClient httpClient ;
198+ private HttpResponse <String > httpRespone ;
199+ private MockedStatic <HttpClient > httpClientClass ;
200+
201+ @ BeforeEach
202+ @ SuppressWarnings ("unchecked" )
203+ public void setup () throws IOException , InterruptedException {
204+ authFlow = AuthFlow .asClient ("my-client" );
205+
206+ httpClient = Mockito .mock (HttpClient .class );
207+ httpRespone = Mockito .mock (HttpResponse .class );
208+ httpClientClass = Mockito .mockStatic (HttpClient .class );
209+
210+ httpClientClass .when (HttpClient ::newHttpClient ).thenReturn (httpClient );
211+ Mockito .doReturn (httpRespone ).when (httpClient ).send (Mockito .any (), Mockito .any ());
212+ }
213+
214+ @ AfterEach
215+ public void tearDown () {
216+ httpClientClass .close ();
217+ }
218+
219+ @ Test
220+ @ DisplayName ("body contains all params" )
221+ public void testRefresh () throws IOException , InterruptedException {
222+ Mockito .doReturn (200 ).when (httpRespone ).statusCode ();
223+ var tokenEndpoint = URI .create ("http://example.com/oauth2/token" );
224+ var bodyCaptor = ArgumentCaptor .forClass (String .class );
225+ var bodyPublisher = Mockito .mock (HttpRequest .BodyPublisher .class );
226+ try (var bodyPublishersClass = Mockito .mockStatic (HttpRequest .BodyPublishers .class )) {
227+ bodyPublishersClass .when (() -> HttpRequest .BodyPublishers .ofString (Mockito .any ())).thenReturn (bodyPublisher );
228+
229+ authFlow .refresh (tokenEndpoint , "r3fr3sh70k3n" , "offline_access" );
230+
231+ bodyPublishersClass .verify (() -> HttpRequest .BodyPublishers .ofString (bodyCaptor .capture ()));
232+ }
233+ var body = bodyCaptor .getValue ();
234+ var params = URIUtil .parseQueryString (body );
235+ Assertions .assertEquals ("refresh_token" , params .get ("grant_type" ));
236+ Assertions .assertEquals (authFlow .clientId , params .get ("client_id" ));
237+ Assertions .assertEquals ("r3fr3sh70k3n" , params .get ("refresh_token" ));
238+ Assertions .assertEquals ("offline_access" , params .get ("scope" ));
239+ }
240+
241+ @ Test
242+ @ DisplayName ("send POST request to token endpoint" )
243+ public void testGetAccessToken200 () throws IOException , InterruptedException {
244+ Mockito .doReturn (200 ).when (httpRespone ).statusCode ();
245+ Mockito .doReturn ("BODY" ).when (httpRespone ).body ();
246+ var requestCaptor = ArgumentCaptor .forClass (HttpRequest .class );
247+ var tokenEndpoint = URI .create ("http://example.com/oauth2/token" );
248+
249+ var result = authFlow .refresh (tokenEndpoint , "r3fr3sh70k3n" );
250+
251+ Assertions .assertEquals ("BODY" , result );
252+ Mockito .verify (httpClient ).send (requestCaptor .capture (), Mockito .any ());
253+ var request = requestCaptor .getValue ();
254+ Assertions .assertSame (tokenEndpoint , request .uri ());
255+ Assertions .assertEquals ("POST" , request .method ());
256+ Assertions .assertEquals ("application/x-www-form-urlencoded" , request .headers ().firstValue ("Content-Type" ).orElse (null ));
257+ }
258+
259+ @ Test
260+ @ DisplayName ("non-success response from token endpoint leads to IOException" )
261+ public void testGetAccessToken404 () {
262+ Mockito .doReturn (404 ).when (httpRespone ).statusCode ();
263+ var tokenEndpoint = URI .create ("http://example.com/oauth2/token" );
264+
265+ Assertions .assertThrows (IOException .class , () -> authFlow .refresh (tokenEndpoint , "r3fr3sh70k3n" ));
266+ }
267+
268+ }
269+
192270 @ Nested
193271 @ DisplayName ("After receiving auth code" )
194272 public class WithAuthCode {
@@ -224,9 +302,9 @@ public void testGetAccessTokenQuery() throws IOException, InterruptedException {
224302 Mockito .doReturn (200 ).when (httpRespone ).statusCode ();
225303 var tokenEndpoint = URI .create ("http://example.com/oauth2/token" );
226304 var bodyCaptor = ArgumentCaptor .forClass (String .class );
227- var replacementBody = HttpRequest .BodyPublishers . ofString ( "foo" );
305+ var bodyPublisher = Mockito . mock ( HttpRequest .BodyPublisher . class );
228306 try (var bodyPublishersClass = Mockito .mockStatic (HttpRequest .BodyPublishers .class )) {
229- bodyPublishersClass .when (() -> HttpRequest .BodyPublishers .ofString (Mockito .any ())).thenReturn (replacementBody );
307+ bodyPublishersClass .when (() -> HttpRequest .BodyPublishers .ofString (Mockito .any ())).thenReturn (bodyPublisher );
230308
231309 authFlowWithCode .getAccessToken (tokenEndpoint );
232310
0 commit comments