/* * Copyright 2012-2017 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.boot.test.web.reactive; import org.springframework.beans.BeansException; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.test.context.ContextCustomizer; import org.springframework.test.context.MergedContextConfiguration; import org.springframework.test.web.reactive.server.WebTestClient; /** * {@link ContextCustomizer} for {@link WebTestClient}. * * @author Stephane Nicoll */ class WebTestClientContextCustomizer implements ContextCustomizer { @Override public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { SpringBootTest annotation = AnnotatedElementUtils .getMergedAnnotation(mergedConfig.getTestClass(), SpringBootTest.class); if (annotation.webEnvironment().isEmbedded()) { registerWebTestClient(context); } } private void registerWebTestClient(ConfigurableApplicationContext context) { ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); if (beanFactory instanceof BeanDefinitionRegistry) { registerWebTestClient(context, (BeanDefinitionRegistry) context); } } private void registerWebTestClient(ConfigurableApplicationContext context, BeanDefinitionRegistry registry) { registry.registerBeanDefinition(WebTestClient.class.getName(), new RootBeanDefinition(WebTestClientFactory.class)); } @Override public int hashCode() { return getClass().hashCode(); } @Override public boolean equals(Object obj) { if (obj == null || obj.getClass() != getClass()) { return false; } return true; } /** * {@link FactoryBean} used to create and configure a {@link WebTestClient}. */ public static class WebTestClientFactory implements FactoryBean<WebTestClient>, ApplicationContextAware { private ApplicationContext applicationContext; private WebTestClient object; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public boolean isSingleton() { return true; } @Override public Class<?> getObjectType() { return WebTestClient.class; } @Override public WebTestClient getObject() throws Exception { if (this.object == null) { this.object = createWebTestClient(); } return this.object; } private WebTestClient createWebTestClient() { boolean sslEnabled = isSslEnabled(this.applicationContext); String port = this.applicationContext.getEnvironment() .getProperty("local.server.port", "8080"); String baseUrl = (sslEnabled ? "https" : "http") + "://localhost:" + port; return WebTestClient.bindToServer().baseUrl(baseUrl).build(); } private boolean isSslEnabled(ApplicationContext context) { try { AbstractReactiveWebServerFactory webServerFactory = context .getBean(AbstractReactiveWebServerFactory.class); return webServerFactory.getSsl() != null && webServerFactory.getSsl().isEnabled(); } catch (NoSuchBeanDefinitionException ex) { return false; } } } }