/*
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.web.servlet.htmlunit;
import com.gargoylesoftware.htmlunit.WebClient;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcConfigurer;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
/**
* {@code MockMvcWebClientBuilder} simplifies the creation of an HtmlUnit
* {@link WebClient} that delegates to a {@link MockMvc} instance.
*
* <p>The {@code MockMvc} instance used by the builder may be
* {@linkplain #mockMvcSetup supplied directly} or created transparently
* from a {@link #webAppContextSetup WebApplicationContext}.
*
* @author Rob Winch
* @author Sam Brannen
* @since 4.2
* @see #mockMvcSetup(MockMvc)
* @see #webAppContextSetup(WebApplicationContext)
* @see #webAppContextSetup(WebApplicationContext, MockMvcConfigurer)
* @see #withDelegate(WebClient)
* @see #build()
*/
public class MockMvcWebClientBuilder extends MockMvcWebConnectionBuilderSupport<MockMvcWebClientBuilder> {
private WebClient webClient;
protected MockMvcWebClientBuilder(MockMvc mockMvc) {
super(mockMvc);
}
protected MockMvcWebClientBuilder(WebApplicationContext context) {
super(context);
}
protected MockMvcWebClientBuilder(WebApplicationContext context, MockMvcConfigurer configurer) {
super(context, configurer);
}
/**
* Create a new {@code MockMvcWebClientBuilder} based on the supplied
* {@link MockMvc} instance.
* @param mockMvc the {@code MockMvc} instance to use; never {@code null}
* @return the MockMvcWebClientBuilder to customize
*/
public static MockMvcWebClientBuilder mockMvcSetup(MockMvc mockMvc) {
Assert.notNull(mockMvc, "MockMvc must not be null");
return new MockMvcWebClientBuilder(mockMvc);
}
/**
* Create a new {@code MockMvcWebClientBuilder} based on the supplied
* {@link WebApplicationContext}.
* @param context the {@code WebApplicationContext} to create a {@link MockMvc}
* instance from; never {@code null}
* @return the MockMvcWebClientBuilder to customize
*/
public static MockMvcWebClientBuilder webAppContextSetup(WebApplicationContext context) {
Assert.notNull(context, "WebApplicationContext must not be null");
return new MockMvcWebClientBuilder(context);
}
/**
* Create a new {@code MockMvcWebClientBuilder} based on the supplied
* {@link WebApplicationContext} and {@link MockMvcConfigurer}.
* @param context the {@code WebApplicationContext} to create a {@link MockMvc}
* instance from; never {@code null}
* @param configurer the {@code MockMvcConfigurer} to apply; never {@code null}
* @return the MockMvcWebClientBuilder to customize
*/
public static MockMvcWebClientBuilder webAppContextSetup(WebApplicationContext context, MockMvcConfigurer configurer) {
Assert.notNull(context, "WebApplicationContext must not be null");
Assert.notNull(configurer, "MockMvcConfigurer must not be null");
return new MockMvcWebClientBuilder(context, configurer);
}
/**
* Supply the {@code WebClient} that the client {@linkplain #build built}
* by this builder should delegate to when processing
* non-{@linkplain WebRequestMatcher matching} requests.
* @param webClient the {@code WebClient} to delegate to for requests
* that do not match; never {@code null}
* @return this builder for further customization
* @see #build()
*/
public MockMvcWebClientBuilder withDelegate(WebClient webClient) {
Assert.notNull(webClient, "WebClient must not be null");
webClient.setWebConnection(createConnection(webClient));
this.webClient = webClient;
return this;
}
/**
* Build the {@link WebClient} configured via this builder.
* <p>The returned client will use the configured {@link MockMvc} instance
* for processing any {@linkplain WebRequestMatcher matching} requests
* and a delegate {@code WebClient} for all other requests.
* <p>If a {@linkplain #withDelegate delegate} has been explicitly configured,
* it will be used; otherwise, a default {@code WebClient} will be configured
* as the delegate.
* @return the {@code WebClient} to use
* @see #withDelegate(WebClient)
*/
public WebClient build() {
return (this.webClient != null ? this.webClient : withDelegate(new WebClient()).build());
}
}