Skip to content

Commit 82633f2

Browse files
committed
PR feedback, refactor common code
1 parent 51d1fff commit 82633f2

File tree

2 files changed

+64
-30
lines changed

2 files changed

+64
-30
lines changed

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

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,11 @@
2020
@ExtendWith(MockitoExtension.class)
2121
class OnBehalfOfTests {
2222

23-
private String getSuccessfulResponse(String accessToken) {
24-
return "{\"access_token\":\""+accessToken+"\",\"expires_in\": \""+ 60*60*1000 +"\",\"token_type\":" +
25-
"\"Bearer\",\"client_id\":\"client_id\",\"Content-Type\":\"text/html; charset=utf-8\"}";
26-
}
27-
28-
private HttpResponse expectedResponse(int statusCode, String response) {
29-
Map<String, List<String>> headers = new HashMap<String, List<String>>();
30-
headers.put("Content-Type", Collections.singletonList("application/json"));
31-
32-
HttpResponse httpResponse = new HttpResponse();
33-
httpResponse.statusCode(statusCode);
34-
httpResponse.body(response);
35-
httpResponse.addHeaders(headers);
36-
37-
return httpResponse;
38-
}
39-
4023
@Test
4124
void OnBehalfOf_InternalCacheLookup_Success() throws Exception {
4225
DefaultHttpClient httpClientMock = mock(DefaultHttpClient.class);
4326

44-
when(httpClientMock.send(any(HttpRequest.class))).thenReturn(expectedResponse(200, getSuccessfulResponse("token")));
27+
when(httpClientMock.send(any(HttpRequest.class))).thenReturn(TestHelper.expectedResponse(200, TestHelper.getSuccessfulTokenResponse(new HashMap<>())));
4528

4629
ConfidentialClientApplication cca =
4730
ConfidentialClientApplication.builder("clientId", ClientCredentialFactory.createFromSecret("password"))
@@ -51,7 +34,7 @@ void OnBehalfOf_InternalCacheLookup_Success() throws Exception {
5134
.httpClient(httpClientMock)
5235
.build();
5336

54-
OnBehalfOfParameters parameters = OnBehalfOfParameters.builder(Collections.singleton("scopes"), new UserAssertion(TestHelper.signedToken)).build();
37+
OnBehalfOfParameters parameters = OnBehalfOfParameters.builder(Collections.singleton("scopes"), new UserAssertion(TestHelper.signedAssertion)).build();
5538

5639
IAuthenticationResult result = cca.acquireToken(parameters).get();
5740
IAuthenticationResult result2 = cca.acquireToken(parameters).get();
@@ -73,23 +56,32 @@ void OnBehalfOf_TenantOverride() throws Exception {
7356
.httpClient(httpClientMock)
7457
.build();
7558

76-
when(httpClientMock.send(any(HttpRequest.class))).thenReturn(expectedResponse(200, getSuccessfulResponse("appTenantToken")));
77-
OnBehalfOfParameters parameters = OnBehalfOfParameters.builder(Collections.singleton("scopes"), new UserAssertion(TestHelper.signedToken)).build();
59+
HashMap<String, String> tokenResponseValues = new HashMap<>();
60+
tokenResponseValues.put("access_token", "accessTokenFirstCall");
61+
62+
when(httpClientMock.send(any(HttpRequest.class))).thenReturn(TestHelper.expectedResponse(200, TestHelper.getSuccessfulTokenResponse(tokenResponseValues)));
63+
OnBehalfOfParameters parameters = OnBehalfOfParameters.builder(Collections.singleton("scopes"), new UserAssertion(TestHelper.signedAssertion)).build();
7864

79-
//The two acquireToken calls have the same parameters and should only cause one call from the HTTP client
65+
//The two acquireToken calls have the same parameters...
8066
IAuthenticationResult resultAppLevelTenant = cca.acquireToken(parameters).get();
81-
cca.acquireToken(parameters).get();
67+
IAuthenticationResult resultAppLevelTenantCached = cca.acquireToken(parameters).get();
68+
//...so only one token should be added to the cache, and the mocked HTTP client's "send" method should only have been called once
8269
assertEquals(1, cca.tokenCache.accessTokens.size());
70+
assertEquals(resultAppLevelTenant.accessToken(), resultAppLevelTenantCached.accessToken());
8371
verify(httpClientMock, times(1)).send(any());
8472

85-
when(httpClientMock.send(any(HttpRequest.class))).thenReturn(expectedResponse(200, getSuccessfulResponse("requestTenantToken")));
86-
parameters = OnBehalfOfParameters.builder(Collections.singleton("scopes"), new UserAssertion(TestHelper.signedToken)).tenant("otherTenant").build();
73+
tokenResponseValues.put("access_token", "accessTokenSecondCall");
74+
75+
when(httpClientMock.send(any(HttpRequest.class))).thenReturn(TestHelper.expectedResponse(200, TestHelper.getSuccessfulTokenResponse(tokenResponseValues)));
76+
parameters = OnBehalfOfParameters.builder(Collections.singleton("scopes"), new UserAssertion(TestHelper.signedAssertion)).tenant("otherTenant").build();
8777

88-
//Overriding the tenant parameter in the request should lead to a new token call being made, but followup calls should not
78+
//Overriding the tenant parameter in the request should lead to a new token call being made...
8979
IAuthenticationResult resultRequestLevelTenant = cca.acquireToken(parameters).get();
90-
cca.acquireToken(parameters).get();
80+
IAuthenticationResult resultRequestLevelTenantCached = cca.acquireToken(parameters).get();
81+
//...which should be different from the original token, and thus the cache should have two tokens created from two HTTP calls
9182
assertEquals(2, cca.tokenCache.accessTokens.size());
92-
verify(httpClientMock, times(2)).send(any());
83+
assertEquals(resultRequestLevelTenant.accessToken(), resultRequestLevelTenantCached.accessToken());
9384
assertNotEquals(resultAppLevelTenant.accessToken(), resultRequestLevelTenant.accessToken());
85+
verify(httpClientMock, times(2)).send(any());
9486
}
9587
}

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

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,20 @@
1414
import java.net.URISyntaxException;
1515
import java.nio.file.Files;
1616
import java.nio.file.Paths;
17+
import java.util.Collections;
18+
import java.util.HashMap;
19+
import java.util.List;
20+
import java.util.Map;
1721

1822
class TestHelper {
1923

2024
//Signed JWT which should be enough to pass the parsing/validation in the library, useful if a unit test needs an
21-
// assertion in a request or token in a response but that is not the focus of the test
22-
static String signedToken = generateToken();
25+
// assertion but that is not the focus of the test
26+
static String signedAssertion = generateToken();
27+
private static final String successfulResponseFormat = "{\"access_token\":\"%s\",\"id_token\":\"%s\",\"refresh_token\":\"%s\"," +
28+
"\"client_id\":\"%s\",\"client_info\":\"%s\"," +
29+
"\"expires_on\": %d ,\"expires_in\": %d," +
30+
"\"token_type\":\"Bearer\"}";
2331

2432
static String readResource(Class<?> classInstance, String resource) {
2533
try {
@@ -55,4 +63,38 @@ static String generateToken() {
5563
throw new RuntimeException(e);
5664
}
5765
}
66+
67+
//Maps various values to the successfulResponseFormat string to create a valid token response
68+
static String getSuccessfulTokenResponse(HashMap<String, String> responseValues) {
69+
//Will default to expiring in one hour if expiry time values are not set
70+
long expiresIn = responseValues.containsKey("expires_in") ?
71+
Long.parseLong(responseValues.get("expires_in")) :
72+
3600;
73+
long expiresOn = responseValues.containsKey("expires_on")
74+
? Long.parseLong(responseValues.get("expires_0n")) :
75+
(System.currentTimeMillis() / 1000) + expiresIn;
76+
77+
return String.format(successfulResponseFormat,
78+
responseValues.getOrDefault("access_token", "access_token"),
79+
responseValues.getOrDefault("id_token", "id_token"),
80+
responseValues.getOrDefault("refresh_token", "refresh_token"),
81+
responseValues.getOrDefault("client_id", "client_id"),
82+
responseValues.getOrDefault("client_info", "client_info"),
83+
expiresOn,
84+
expiresIn
85+
);
86+
}
87+
88+
//Creates a valid HttpResponse that can be used when mocking HttpClient.send()
89+
static HttpResponse expectedResponse(int statusCode, String response) {
90+
Map<String, List<String>> headers = new HashMap<>();
91+
headers.put("Content-Type", Collections.singletonList("application/json"));
92+
93+
HttpResponse httpResponse = new HttpResponse();
94+
httpResponse.statusCode(statusCode);
95+
httpResponse.body(response);
96+
httpResponse.addHeaders(headers);
97+
98+
return httpResponse;
99+
}
58100
}

0 commit comments

Comments
 (0)