// Path: src/main/java/com/burgstaller/okhttp/AuthenticationCacheInterceptor.java
// public class AuthenticationCacheInterceptor implements Interceptor {
//     private final Map<String, CachingAuthenticator> authCache;
//     private final CacheKeyProvider cacheKeyProvider;
// 
//     public AuthenticationCacheInterceptor(Map<String, CachingAuthenticator> authCache, CacheKeyProvider cacheKeyProvider) {
//         this.authCache = authCache;
//         this.cacheKeyProvider = cacheKeyProvider;
//     }
// 
//     public AuthenticationCacheInterceptor(Map<String, CachingAuthenticator> authCache) {
//         this(authCache, new DefaultCacheKeyProvider());
//     }
// 
//     @Override
//     public Response intercept(Chain chain) throws IOException {
//         final Request request = chain.request();
//         final String key = cacheKeyProvider.getCachingKey(request);
//         CachingAuthenticator authenticator = authCache.get(key);
//         Request authRequest = null;
//         Connection connection = chain.connection();
//         Route route = connection != null ? connection.route() : null;
//         if (authenticator != null) {
//             authRequest = authenticator.authenticateWithState(route, request);
//         }
//         if (authRequest == null) {
//             authRequest = request;
//         }
//         Response response = chain.proceed(authRequest);
// 
//         // Cached response was used, but it produced unauthorized response (cache expired).
//         int responseCode = response != null ? response.code() : 0;
//         if (authenticator != null && (responseCode == HTTP_UNAUTHORIZED || responseCode == HTTP_PROXY_AUTH)) {
//             // Remove cached authenticator and resend request
//             if (authCache.remove(key) != null) {
//                 response.body().close();
//                 Platform.get().log("Cached authentication expired. Sending a new request.", Platform.INFO, null);
//                 // Force sending a new request without "Authorization" header
//                 response = chain.proceed(request);
//             }
//         }
//         return response;
//     }
// }
// 
// Path: src/main/java/com/burgstaller/okhttp/CachingAuthenticatorDecorator.java
// public class CachingAuthenticatorDecorator implements Authenticator {
//     private final Authenticator innerAuthenticator;
//     private final Map<String, CachingAuthenticator> authCache;
//     private final CacheKeyProvider cacheKeyProvider;
// 
//     public CachingAuthenticatorDecorator(Authenticator innerAuthenticator, Map<String, CachingAuthenticator> authCache, CacheKeyProvider cacheKeyProvider) {
//         this.innerAuthenticator = innerAuthenticator;
//         this.authCache = authCache;
//         this.cacheKeyProvider = cacheKeyProvider;
//     }
// 
//     public CachingAuthenticatorDecorator(Authenticator innerAuthenticator, Map<String, CachingAuthenticator> authCache) {
//         this(innerAuthenticator, authCache, new DefaultCacheKeyProvider());
//     }
// 
//     @Override
//     public Request authenticate(Route route, Response response) throws IOException {
//         Request authenticated = innerAuthenticator.authenticate(route, response);
//         if (authenticated != null) {
//             String authorizationValue = authenticated.header("Authorization");
//             if (authorizationValue != null && innerAuthenticator instanceof CachingAuthenticator) {
//                 final String key = cacheKeyProvider.getCachingKey(authenticated);
//                 authCache.put(key, (CachingAuthenticator) innerAuthenticator);
//             }
//         }
//         return authenticated;
//     }
// }
// 
// Path: src/main/java/com/burgstaller/okhttp/digest/CachingAuthenticator.java
// public interface CachingAuthenticator extends Authenticator {
//     /**
//      * Authenticate the new request using cached information already established from an earlier
//      * authentication.
//      *
//      * @param route   the route to use
//      * @param request the new request to be authenticated.
//      * @return the modified request with updated auth headers.
//      * @throws IOException in case of a communication problem
//      */
//     Request authenticateWithState(Route route, Request request) throws IOException;
// }
// 
// Path: src/main/java/com/burgstaller/okhttp/digest/Credentials.java
// public class Credentials {
//     private String userName;
//     private String password;
// 
//     public Credentials(String userName, String password) {
//         if (userName == null || password == null) {
//             throw new IllegalArgumentException("username and password cannot be null");
//         }
//         this.userName = userName;
//         this.password = password;
//     }
// 
//     public String getUserName() {
//         return userName;
//     }
// 
//     public void setUserName(String userName) {
//         this.userName = userName;
//     }
// 
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// }


import com.burgstaller.okhttp.AuthenticationCacheInterceptor;
import com.burgstaller.okhttp.CachingAuthenticatorDecorator;
import com.burgstaller.okhttp.digest.CachingAuthenticator;
import com.burgstaller.okhttp.digest.Credentials;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
import okhttp3.logging.HttpLoggingInterceptor;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
package com.burgstaller.okhttp.basic;






/**
 * Unit test for basic authenticator.
 *
 * @author Rainer Burgstaller
 */
public class BasicAuthenticatorWithMockWebserverTest {

    @Rule
    public MockWebServer mockServer = new MockWebServer();

    private BasicAuthenticator sut;
    private BasicAuthenticator spy;
    private OkHttpClient client;
    private MockResponse unauthorizedResponse;
    private MockResponse successResponse;
// Path: src/main/java/com/burgstaller/okhttp/AuthenticationCacheInterceptor.java
// public class AuthenticationCacheInterceptor implements Interceptor {
//     private final Map<String, CachingAuthenticator> authCache;
//     private final CacheKeyProvider cacheKeyProvider;
// 
//     public AuthenticationCacheInterceptor(Map<String, CachingAuthenticator> authCache, CacheKeyProvider cacheKeyProvider) {
//         this.authCache = authCache;
//         this.cacheKeyProvider = cacheKeyProvider;
//     }
// 
//     public AuthenticationCacheInterceptor(Map<String, CachingAuthenticator> authCache) {
//         this(authCache, new DefaultCacheKeyProvider());
//     }
// 
//     @Override
//     public Response intercept(Chain chain) throws IOException {
//         final Request request = chain.request();
//         final String key = cacheKeyProvider.getCachingKey(request);
//         CachingAuthenticator authenticator = authCache.get(key);
//         Request authRequest = null;
//         Connection connection = chain.connection();
//         Route route = connection != null ? connection.route() : null;
//         if (authenticator != null) {
//             authRequest = authenticator.authenticateWithState(route, request);
//         }
//         if (authRequest == null) {
//             authRequest = request;
//         }
//         Response response = chain.proceed(authRequest);
// 
//         // Cached response was used, but it produced unauthorized response (cache expired).
//         int responseCode = response != null ? response.code() : 0;
//         if (authenticator != null && (responseCode == HTTP_UNAUTHORIZED || responseCode == HTTP_PROXY_AUTH)) {
//             // Remove cached authenticator and resend request
//             if (authCache.remove(key) != null) {
//                 response.body().close();
//                 Platform.get().log("Cached authentication expired. Sending a new request.", Platform.INFO, null);
//                 // Force sending a new request without "Authorization" header
//                 response = chain.proceed(request);
//             }
//         }
//         return response;
//     }
// }
// 
// Path: src/main/java/com/burgstaller/okhttp/CachingAuthenticatorDecorator.java
// public class CachingAuthenticatorDecorator implements Authenticator {
//     private final Authenticator innerAuthenticator;
//     private final Map<String, CachingAuthenticator> authCache;
//     private final CacheKeyProvider cacheKeyProvider;
// 
//     public CachingAuthenticatorDecorator(Authenticator innerAuthenticator, Map<String, CachingAuthenticator> authCache, CacheKeyProvider cacheKeyProvider) {
//         this.innerAuthenticator = innerAuthenticator;
//         this.authCache = authCache;
//         this.cacheKeyProvider = cacheKeyProvider;
//     }
// 
//     public CachingAuthenticatorDecorator(Authenticator innerAuthenticator, Map<String, CachingAuthenticator> authCache) {
//         this(innerAuthenticator, authCache, new DefaultCacheKeyProvider());
//     }
// 
//     @Override
//     public Request authenticate(Route route, Response response) throws IOException {
//         Request authenticated = innerAuthenticator.authenticate(route, response);
//         if (authenticated != null) {
//             String authorizationValue = authenticated.header("Authorization");
//             if (authorizationValue != null && innerAuthenticator instanceof CachingAuthenticator) {
//                 final String key = cacheKeyProvider.getCachingKey(authenticated);
//                 authCache.put(key, (CachingAuthenticator) innerAuthenticator);
//             }
//         }
//         return authenticated;
//     }
// }
// 
// Path: src/main/java/com/burgstaller/okhttp/digest/CachingAuthenticator.java
// public interface CachingAuthenticator extends Authenticator {
//     /**
//      * Authenticate the new request using cached information already established from an earlier
//      * authentication.
//      *
//      * @param route   the route to use
//      * @param request the new request to be authenticated.
//      * @return the modified request with updated auth headers.
//      * @throws IOException in case of a communication problem
//      */
//     Request authenticateWithState(Route route, Request request) throws IOException;
// }
// 
// Path: src/main/java/com/burgstaller/okhttp/digest/Credentials.java
// public class Credentials {
//     private String userName;
//     private String password;
// 
//     public Credentials(String userName, String password) {
//         if (userName == null || password == null) {
//             throw new IllegalArgumentException("username and password cannot be null");
//         }
//         this.userName = userName;
//         this.password = password;
//     }
// 
//     public String getUserName() {
//         return userName;
//     }
// 
//     public void setUserName(String userName) {
//         this.userName = userName;
//     }
// 
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// }


// Path: src/test/java/com/burgstaller/okhttp/basic/BasicAuthenticatorWithMockWebserverTest.java
import com.burgstaller.okhttp.AuthenticationCacheInterceptor;
import com.burgstaller.okhttp.CachingAuthenticatorDecorator;
import com.burgstaller.okhttp.digest.CachingAuthenticator;
import com.burgstaller.okhttp.digest.Credentials;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
import okhttp3.logging.HttpLoggingInterceptor;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

package com.burgstaller.okhttp.basic;






/**
 * Unit test for basic authenticator.
 *
 * @author Rainer Burgstaller
 */
public class BasicAuthenticatorWithMockWebserverTest {

    @Rule
    public MockWebServer mockServer = new MockWebServer();

    private BasicAuthenticator sut;
    private BasicAuthenticator spy;
    private OkHttpClient client;
    private MockResponse unauthorizedResponse;
    private MockResponse successResponse;
    private Credentials credentials;