From 3c5cf02882a30f1dd0c0c98a1c2490a29a10c8db Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 25 Aug 2016 09:41:00 +0100 Subject: [PATCH] Provide method to create TestRestTemplate with basic auth from existing Closes gh-6732 --- .../test/web/client/TestRestTemplate.java | 39 +++++++++++ .../web/client/TestRestTemplateTests.java | 66 +++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java b/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java index c45183972f..2441537483 100644 --- a/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java +++ b/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java @@ -18,9 +18,11 @@ package org.springframework.boot.test.web.client; import java.io.IOException; import java.net.URI; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -82,6 +84,8 @@ public class TestRestTemplate { private final RestTemplate restTemplate; + private final HttpClientOption[] httpClientOptions; + /** * Create a new {@link TestRestTemplate} instance. * @param restTemplateBuilder builder used to configure underlying @@ -118,6 +122,7 @@ public class TestRestTemplate { public TestRestTemplate(RestTemplate restTemplate, String username, String password, HttpClientOption... httpClientOptions) { Assert.notNull(restTemplate, "RestTemplate must not be null"); + this.httpClientOptions = httpClientOptions; if (ClassUtils.isPresent("org.apache.http.client.config.RequestConfig", null)) { restTemplate.setRequestFactory( new CustomHttpComponentsClientHttpRequestFactory(httpClientOptions)); @@ -900,6 +905,40 @@ public class TestRestTemplate { return this.restTemplate; } + /** + * Creates a new {@code TestRestTemplate} with the same configuration as this one, + * except that it will send basic authorization headers using the given + * {@code username} and {@code password}. + * @param username the username + * @param password the password + * @return the new template + * @since 1.4.1 + */ + public TestRestTemplate withBasicAuth(String username, String password) { + RestTemplate restTemplate = new RestTemplate(); + restTemplate.setErrorHandler(getRestTemplate().getErrorHandler()); + restTemplate.setMessageConverters(getRestTemplate().getMessageConverters()); + restTemplate.setInterceptors( + removeBasicAuthInterceptorIfPresent(getRestTemplate().getInterceptors())); + restTemplate.setRequestFactory(getRestTemplate().getRequestFactory()); + restTemplate.setUriTemplateHandler(getRestTemplate().getUriTemplateHandler()); + return new TestRestTemplate(restTemplate, username, password, + this.httpClientOptions); + } + + private List removeBasicAuthInterceptorIfPresent( + List interceptors) { + List updatedInterceptors = new ArrayList( + interceptors); + Iterator iterator = updatedInterceptors.iterator(); + while (iterator.hasNext()) { + if (iterator.next() instanceof BasicAuthorizationInterceptor) { + iterator.remove(); + } + } + return interceptors; + } + /** * Options used to customize the Apache Http Client if it is used. */ diff --git a/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java b/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java index 3be395db5c..68169d005b 100644 --- a/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java +++ b/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java @@ -18,6 +18,7 @@ package org.springframework.boot.test.web.client; import java.lang.reflect.Method; import java.net.URI; +import java.util.List; import org.apache.http.client.config.RequestConfig; import org.junit.Test; @@ -26,8 +27,11 @@ import org.springframework.boot.test.web.client.TestRestTemplate.CustomHttpCompo import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.HttpMethod; +import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.client.InterceptingClientHttpRequestFactory; +import org.springframework.http.client.support.BasicAuthorizationInterceptor; +import org.springframework.test.util.ReflectionTestUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils.MethodCallback; import org.springframework.web.client.RestOperations; @@ -127,4 +131,66 @@ public class TestRestTemplateTests { }); } + + @Test + public void withBasicAuthAddsBasicAuthInterceptorWhenNotAlreadyPresent() { + TestRestTemplate originalTemplate = new TestRestTemplate(); + TestRestTemplate basicAuthTemplate = originalTemplate.withBasicAuth("user", + "password"); + assertThat(basicAuthTemplate.getRestTemplate().getMessageConverters()) + .containsExactlyElementsOf( + originalTemplate.getRestTemplate().getMessageConverters()); + assertThat(basicAuthTemplate.getRestTemplate().getRequestFactory()) + .isInstanceOf(InterceptingClientHttpRequestFactory.class); + assertThat(ReflectionTestUtils.getField( + basicAuthTemplate.getRestTemplate().getRequestFactory(), + "requestFactory")) + .isInstanceOf(CustomHttpComponentsClientHttpRequestFactory.class); + assertThat(basicAuthTemplate.getRestTemplate().getUriTemplateHandler()) + .isSameAs(originalTemplate.getRestTemplate().getUriTemplateHandler()); + assertThat(basicAuthTemplate.getRestTemplate().getInterceptors()) + .containsExactlyElementsOf( + originalTemplate.getRestTemplate().getInterceptors()); + assertBasicAuthorizationInterceptorCredentials(basicAuthTemplate, "user", + "password"); + } + + @Test + public void withBasicAuthReplacesBasicAuthInterceptorWhenAlreadyPresent() { + TestRestTemplate originalTemplate = new TestRestTemplate("foo", "bar"); + TestRestTemplate basicAuthTemplate = originalTemplate.withBasicAuth("user", + "password"); + assertThat(basicAuthTemplate.getRestTemplate().getMessageConverters()) + .containsExactlyElementsOf( + originalTemplate.getRestTemplate().getMessageConverters()); + assertThat(basicAuthTemplate.getRestTemplate().getRequestFactory()) + .isInstanceOf(InterceptingClientHttpRequestFactory.class); + assertThat(ReflectionTestUtils.getField( + basicAuthTemplate.getRestTemplate().getRequestFactory(), + "requestFactory")) + .isInstanceOf(CustomHttpComponentsClientHttpRequestFactory.class); + assertThat(basicAuthTemplate.getRestTemplate().getUriTemplateHandler()) + .isSameAs(originalTemplate.getRestTemplate().getUriTemplateHandler()); + assertThat(basicAuthTemplate.getRestTemplate().getInterceptors()) + .containsExactlyElementsOf( + originalTemplate.getRestTemplate().getInterceptors()); + assertBasicAuthorizationInterceptorCredentials(basicAuthTemplate, "user", + "password"); + } + + private void assertBasicAuthorizationInterceptorCredentials( + TestRestTemplate testRestTemplate, String username, String password) { + @SuppressWarnings("unchecked") + List requestFactoryInterceptors = (List) ReflectionTestUtils + .getField(testRestTemplate.getRestTemplate().getRequestFactory(), + "interceptors"); + assertThat(requestFactoryInterceptors).hasSize(1); + ClientHttpRequestInterceptor interceptor = requestFactoryInterceptors.get(0); + assertThat(interceptor).isInstanceOf(BasicAuthorizationInterceptor.class); + assertThat(ReflectionTestUtils.getField(interceptor, "username")) + .isEqualTo(username); + assertThat(ReflectionTestUtils.getField(interceptor, "password")) + .isEqualTo(password); + + } }