Skip to content

Commit 5c62974

Browse files
committed
Add tests for various refresh reasons
1 parent 3057b1e commit 5c62974

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

msal4j-sdk/src/main/java/com/microsoft/aad/msal4j/AcquireTokenSilentSupplier.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ private AuthenticationResult makeRefreshRequest(AuthenticationResult cachedResul
100100
AuthenticationResult refreshedResult = acquireTokenByAuthorisationGrantSupplier.execute();
101101

102102
refreshedResult.metadata().tokenSource(TokenSource.IDENTITY_PROVIDER);
103+
refreshedResult.metadata().cacheRefreshReason(refreshReason);
103104

104105
log.info("Access token refreshed successfully.");
105106
return refreshedResult;

msal4j-sdk/src/test/java/com/microsoft/aad/msal4j/AcquireTokenSilentlyTest.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111
import static org.junit.jupiter.api.Assertions.assertNotNull;
1212
import static org.junit.jupiter.api.Assertions.assertEquals;
1313
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
14+
import static org.mockito.ArgumentMatchers.any;
15+
import static org.mockito.Mockito.*;
1416

1517
import java.io.IOException;
1618
import java.net.URISyntaxException;
1719
import java.nio.file.Files;
1820
import java.nio.file.Paths;
1921
import java.util.Collections;
22+
import java.util.HashMap;
2023
import java.util.concurrent.CompletableFuture;
2124
import java.util.concurrent.ExecutionException;
2225

@@ -116,6 +119,79 @@ void confidentialAppAcquireTokenSilently_claimsSkipCache() throws Throwable {
116119
assertInstanceOf(MsalInteractionRequiredException.class, ex.getCause());
117120
}
118121

122+
@Test
123+
void testTokenRefreshReasons() throws Exception {
124+
DefaultHttpClient httpClientMock = mock(DefaultHttpClient.class);
125+
126+
ConfidentialClientApplication cca =
127+
ConfidentialClientApplication.builder("clientId", ClientCredentialFactory.createFromSecret("password"))
128+
.authority("https://login.microsoftonline.com/tenant/")
129+
.instanceDiscovery(false)
130+
.validateAuthority(false)
131+
.httpClient(httpClientMock)
132+
.build();
133+
134+
HashMap<String, String> responseParameters = new HashMap<>();
135+
136+
//Acquire a token that expired an hour ago
137+
responseParameters.put("access_token", "expiredToken");
138+
responseParameters.put("id_token", TestHelper.createIdToken(new HashMap<>()));
139+
responseParameters.put("expires_in", "-3600");
140+
141+
ClientCredentialParameters clientCredentialParameters = ClientCredentialParameters.builder(Collections.singleton("someScopes")).build();
142+
when(httpClientMock.send(any(HttpRequest.class))).thenReturn(TestHelper.expectedResponse(200, TestHelper.getSuccessfulTokenResponse(responseParameters)));
143+
IAuthenticationResult result = cca.acquireToken(clientCredentialParameters).get();
144+
145+
//There should be one token in the cache, and no refresh behavior should have happened yet
146+
assertEquals(1, cca.tokenCache.accessTokens.size());
147+
assertEquals("expiredToken", result.accessToken());
148+
assertEquals(CacheRefreshReason.NOT_APPLICABLE, result.metadata().cacheRefreshReason());
149+
verify(httpClientMock, times(1)).send(any());
150+
151+
//Attempt to retrieve the cached token, however it is expired and should be refreshed.
152+
// In this test, it will be replaced with a token that expires in 1 minute
153+
responseParameters.put("access_token", "nearlyExpiredToken");
154+
responseParameters.put("expires_in", "60");
155+
156+
SilentParameters silentParameters = SilentParameters.builder(Collections.singleton("someScopes"), result.account()).build();
157+
when(httpClientMock.send(any(HttpRequest.class))).thenReturn(TestHelper.expectedResponse(200, TestHelper.getSuccessfulTokenResponse(responseParameters)));
158+
result = cca.acquireTokenSilently(silentParameters).get();
159+
160+
//Ensure there is still one token in the cache, however it is the new refreshed token rather than the token from the first mocked call
161+
assertEquals(1, cca.tokenCache.accessTokens.size());
162+
assertEquals("nearlyExpiredToken", result.accessToken());
163+
assertEquals(CacheRefreshReason.EXPIRED, result.metadata().cacheRefreshReason());
164+
verify(httpClientMock, times(2)).send(any());
165+
166+
//Attempt to retrieve the cached token, however it is within the 5-minute buffer and should be refreshed.
167+
// In this test, it will be replaced with a token that expires in 1 hour
168+
responseParameters.put("access_token", "normalToken");
169+
responseParameters.put("expires_in", "3600");
170+
171+
silentParameters = SilentParameters.builder(Collections.singleton("someScopes"), result.account()).build();
172+
when(httpClientMock.send(any(HttpRequest.class))).thenReturn(TestHelper.expectedResponse(200, TestHelper.getSuccessfulTokenResponse(responseParameters)));
173+
result = cca.acquireTokenSilently(silentParameters).get();
174+
175+
//Ensure there is still one token in the cache, however it is the new refreshed token rather than the token from the second mocked call
176+
assertEquals(1, cca.tokenCache.accessTokens.size());
177+
assertEquals("normalToken", result.accessToken());
178+
assertEquals(CacheRefreshReason.EXPIRED, result.metadata().cacheRefreshReason());
179+
verify(httpClientMock, times(3)).send(any());
180+
181+
//Finally, force the token to be refreshed
182+
responseParameters.put("access_token", "forcedRefreshToken");
183+
184+
silentParameters = SilentParameters.builder(Collections.singleton("someScopes"), result.account()).forceRefresh(true).build();
185+
when(httpClientMock.send(any(HttpRequest.class))).thenReturn(TestHelper.expectedResponse(200, TestHelper.getSuccessfulTokenResponse(responseParameters)));
186+
result = cca.acquireTokenSilently(silentParameters).get();
187+
188+
//Ensure there is still one token in the cache, however it is the new refreshed token rather than the token from the third mocked call
189+
assertEquals(1, cca.tokenCache.accessTokens.size());
190+
assertEquals("forcedRefreshToken", result.accessToken());
191+
assertEquals(CacheRefreshReason.FORCE_REFRESH, result.metadata().cacheRefreshReason());
192+
verify(httpClientMock, times(4)).send(any());
193+
}
194+
119195
String readResource(String resource) {
120196
try {
121197
return new String(Files.readAllBytes(Paths.get(getClass().getResource(resource).toURI())));

0 commit comments

Comments
 (0)