Skip to content

Commit

Permalink
Increase code coverage and reliability
Browse files Browse the repository at this point in the history
  • Loading branch information
Ndiritu committed Sep 27, 2024
1 parent 5fa1f82 commit 86923aa
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import okhttp3.Response;

import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -28,7 +29,8 @@ public final class ContinuousAccessEvaluationClaims {
* @return the claims
*/
public static @Nullable String getClaimsFromResponse(@Nonnull Response response) {
if (response == null || response.code() != 401) {
Objects.requireNonNull(response, "parameter response cannot be null");
if (response.code() != 401) {
return null;
}
final List<String> authenticateHeader = response.headers(wwwAuthenticateHeader);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import okhttp3.OkHttpClient;

import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

Expand Down Expand Up @@ -52,16 +53,25 @@ private KiotaClientFactory() {}
return builder;
}

/**
* Creates an OkHttpClient Builder with the default configuration and middleware.
* @param interceptors The interceptors to add to the client. Will default to createDefaultInterceptors() if null.
* @return an OkHttpClient Builder instance.
*/
@Nonnull public static OkHttpClient.Builder create(@Nullable final List<Interceptor> interceptors) {
return create((new ArrayList<>(interceptors)).toArray(new Interceptor[interceptors.size()]));
}

/**
* Creates an OkHttpClient Builder with the default configuration and middleware including the AuthorizationHandler.
* @param authenticationProvider authentication provider to use for the AuthorizationHandler.
* @return an OkHttpClient Builder instance.
*/
@Nonnull public static OkHttpClient.Builder create(
@Nonnull final BaseBearerTokenAuthenticationProvider authenticationProvider) {
List<Interceptor> interceptors = Arrays.asList(createDefaultInterceptors());
ArrayList<Interceptor> interceptors = createDefaultInterceptorsAsList();
interceptors.add(new AuthorizationHandler(authenticationProvider));
return create((Interceptor[]) interceptors.toArray());
return create(interceptors);
}

/**
Expand All @@ -77,4 +87,12 @@ private KiotaClientFactory() {}
new HeadersInspectionHandler()
};
}

/**
* Creates the default interceptors for the client.
* @return an array of interceptors.
*/
@Nonnull public static ArrayList<Interceptor> createDefaultInterceptorsAsList() {
return new ArrayList<>(Arrays.asList(createDefaultInterceptors()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public AuthorizationHandler(
}

@Override
public Response intercept(final Chain chain) throws IOException {
public @Nonnull Response intercept(final Chain chain) throws IOException {
Objects.requireNonNull(chain, "parameter chain cannot be null");
final Request request = chain.request();

Expand Down Expand Up @@ -115,7 +115,7 @@ public Response intercept(final Chain chain) throws IOException {
private @Nonnull Request authenticateRequest(
@Nonnull final Request request,
@Nullable final Map<String, Object> additionalAuthenticationContext,
@Nonnull final Span span) {
final Span span) {

final AccessTokenProvider accessTokenProvider =
authenticationProvider.getAccessTokenProvider();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.microsoft.kiota.NativeResponseHandler;
import com.microsoft.kiota.RequestInformation;
import com.microsoft.kiota.authentication.AuthenticationProvider;
import com.microsoft.kiota.http.middleware.MockResponseHandler;
import com.microsoft.kiota.serialization.Parsable;
import com.microsoft.kiota.serialization.ParsableFactory;
import com.microsoft.kiota.serialization.ParseNode;
Expand All @@ -20,7 +21,6 @@
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Dispatcher;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
Expand Down Expand Up @@ -574,33 +574,4 @@ public ParseNodeFactory creatMockParseNodeFactory(
when(mockFactory.getValidContentType()).thenReturn(validContentType);
return mockFactory;
}

// Returns request body as response body
static class MockResponseHandler implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
final var request = chain.request();
final var requestBody = request.body();
if (request != null && requestBody != null) {
final var buffer = new Buffer();
requestBody.writeTo(buffer);
return new Response.Builder()
.code(200)
.message("OK")
.protocol(Protocol.HTTP_1_1)
.request(request)
.body(
ResponseBody.create(
buffer.readByteArray(),
MediaType.parse("application/json")))
.build();
}
return new Response.Builder()
.code(200)
.message("OK")
.protocol(Protocol.HTTP_1_1)
.request(request)
.build();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
import com.microsoft.kiota.authentication.AccessTokenProvider;
import com.microsoft.kiota.authentication.AllowedHostsValidator;
import com.microsoft.kiota.authentication.BaseBearerTokenAuthenticationProvider;
import com.microsoft.kiota.http.KiotaClientFactory;

import okhttp3.Interceptor.Chain;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
Expand Down Expand Up @@ -132,6 +134,35 @@ void testDoesNotRetryCAEChallengeForOneShotBodyRequests() throws IOException {
assertEquals(newAuthHeaderValue, response.request().header(authHeader));
}

@Test
void testDoesNotAttemptCAEChallengeIfNoClaimsPresent() throws IOException {
final Request request =
new Request.Builder().url("https://graph.microsoft.com/v1.0/me").build();
final Response mockResponse = mock(Response.class);
when(mockResponse.code()).thenReturn(HttpURLConnection.HTTP_UNAUTHORIZED);
final Chain mockChain = getMockChain(request, mockResponse);
final BaseBearerTokenAuthenticationProvider authProvider = getMockAuthenticationProvider();
final AuthorizationHandler handler = new AuthorizationHandler(authProvider);
Response response = handler.intercept(mockChain);

assertTrue(response.request().headers().names().contains(authHeader));
assertEquals(newAuthHeaderValue, response.request().header(authHeader));
assertEquals(401, response.code());
}

@Test
void testAuthorizationHandlerAddedByClientFactory() throws IOException {
final BaseBearerTokenAuthenticationProvider authProvider = getMockAuthenticationProvider();
OkHttpClient okHttpClient = KiotaClientFactory.create(authProvider).addInterceptor(new MockResponseHandler()).build();

final Request request =
new Request.Builder().url("https://graph.microsoft.com/v1.0/me").build();
Response response = okHttpClient.newCall(request).execute();

assertTrue(response.request().headers().names().contains(authHeader));
assertEquals(newAuthHeaderValue, response.request().header(authHeader));
}

private Chain getMockChain(Request mockRequest, Response mockResponse) throws IOException {
Chain mockChain = mock(Chain.class);
when(mockChain.request()).thenReturn(mockRequest);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.microsoft.kiota.http.middleware;

import java.io.IOException;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;

/**
* Returns the request body as the response body
*/
public class MockResponseHandler implements Interceptor {
private int statusCode;

public MockResponseHandler(int statusCode) {
this.statusCode = statusCode;
}

public MockResponseHandler() {
this.statusCode = 200;
}

@Override
public Response intercept(Chain chain) throws IOException {
final var request = chain.request();
final var requestBody = request.body();
if (request != null && requestBody != null) {
final var buffer = new Buffer();
requestBody.writeTo(buffer);
return new Response.Builder()
.code(this.statusCode)
.message("OK")
.protocol(Protocol.HTTP_1_1)
.request(request)
.body(
ResponseBody.create(
buffer.readByteArray(),
MediaType.parse("application/json")))
.build();
}
return new Response.Builder()
.code(this.statusCode)
.message("OK")
.protocol(Protocol.HTTP_1_1)
.request(request)
.body(ResponseBody.create("", MediaType.parse("application/json")))
.build();
}

}

0 comments on commit 86923aa

Please sign in to comment.