Merge branch '3.3.x' into 3.4.x
Closes gh-44697
This commit is contained in:
@@ -18,21 +18,26 @@ package org.springframework.boot.testsupport.classpath.resources;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystemNotFoundException;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.util.function.ThrowingConsumer;
|
||||
|
||||
/**
|
||||
* A collection of resources.
|
||||
@@ -50,27 +55,43 @@ class Resources {
|
||||
}
|
||||
|
||||
Resources addPackage(Package root, String[] resourceNames) {
|
||||
String packageName = root.getName();
|
||||
Set<String> unmatchedNames = new HashSet<>(Arrays.asList(resourceNames));
|
||||
withPathsForPackage(packageName, (packagePath) -> {
|
||||
for (String resourceName : resourceNames) {
|
||||
Path resource = packagePath.resolve(resourceName);
|
||||
if (Files.exists(resource) && !Files.isDirectory(resource)) {
|
||||
Path target = this.root.resolve(resourceName);
|
||||
Path targetDirectory = target.getParent();
|
||||
if (!Files.isDirectory(targetDirectory)) {
|
||||
Files.createDirectories(targetDirectory);
|
||||
}
|
||||
Files.copy(resource, target);
|
||||
register(resourceName, target, true);
|
||||
unmatchedNames.remove(resourceName);
|
||||
}
|
||||
}
|
||||
});
|
||||
Assert.isTrue(unmatchedNames.isEmpty(),
|
||||
"Package '" + packageName + "' did not contain resources: " + unmatchedNames);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void withPathsForPackage(String packageName, ThrowingConsumer<Path> consumer) {
|
||||
try {
|
||||
Enumeration<URL> sources = getClass().getClassLoader().getResources(root.getName().replace(".", "/"));
|
||||
for (URL source : Collections.list(sources)) {
|
||||
Path sourceRoot = Paths.get(source.toURI());
|
||||
for (String resourceName : resourceNames) {
|
||||
Path resource = sourceRoot.resolve(resourceName);
|
||||
if (Files.isRegularFile(resource)) {
|
||||
Path target = this.root.resolve(resourceName);
|
||||
Path targetDirectory = target.getParent();
|
||||
if (!Files.isDirectory(targetDirectory)) {
|
||||
Files.createDirectories(targetDirectory);
|
||||
}
|
||||
Files.copy(resource, target);
|
||||
register(resourceName, target, true);
|
||||
unmatchedNames.remove(resourceName);
|
||||
List<URL> sources = Collections
|
||||
.list(getClass().getClassLoader().getResources(packageName.replace(".", "/")));
|
||||
for (URL source : sources) {
|
||||
URI sourceUri = source.toURI();
|
||||
try {
|
||||
consumer.accept(Paths.get(sourceUri));
|
||||
}
|
||||
catch (FileSystemNotFoundException ex) {
|
||||
try (FileSystem fileSystem = FileSystems.newFileSystem(sourceUri, Collections.emptyMap())) {
|
||||
consumer.accept(Paths.get(sourceUri));
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.isTrue(unmatchedNames.isEmpty(),
|
||||
"Package '" + root.getName() + "' did not contain resources: " + unmatchedNames);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new UncheckedIOException(ex);
|
||||
@@ -78,7 +99,6 @@ class Resources {
|
||||
catch (URISyntaxException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
Resources addResource(String name, String content, boolean additional) {
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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
|
||||
*
|
||||
* https://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.testsupport.web.servlet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.servlet.Filter;
|
||||
import jakarta.servlet.FilterRegistration;
|
||||
import jakarta.servlet.Servlet;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.ServletRegistration;
|
||||
import jakarta.servlet.SessionCookieConfig;
|
||||
|
||||
import org.springframework.mock.web.MockSessionCookieConfig;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Base class for Mock {@code ServletWebServer} implementations. Reduces the amount of
|
||||
* code that would otherwise be duplicated in {@code spring-boot},
|
||||
* {@code spring-boot-autoconfigure} and {@code spring-boot-actuator}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public abstract class MockServletWebServer {
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
private final Initializer[] initializers;
|
||||
|
||||
private final List<RegisteredServlet> registeredServlets = new ArrayList<>();
|
||||
|
||||
private final List<RegisteredFilter> registeredFilters = new ArrayList<>();
|
||||
|
||||
private final int port;
|
||||
|
||||
public MockServletWebServer(Initializer[] initializers, int port) {
|
||||
this.initializers = initializers;
|
||||
this.port = port;
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
try {
|
||||
this.servletContext = mock(ServletContext.class);
|
||||
lenient().doAnswer((invocation) -> {
|
||||
RegisteredServlet registeredServlet = new RegisteredServlet(invocation.getArgument(1));
|
||||
MockServletWebServer.this.registeredServlets.add(registeredServlet);
|
||||
return registeredServlet.getRegistration();
|
||||
}).when(this.servletContext).addServlet(anyString(), any(Servlet.class));
|
||||
lenient().doAnswer((invocation) -> {
|
||||
RegisteredFilter registeredFilter = new RegisteredFilter(invocation.getArgument(1));
|
||||
MockServletWebServer.this.registeredFilters.add(registeredFilter);
|
||||
return registeredFilter.getRegistration();
|
||||
}).when(this.servletContext).addFilter(anyString(), any(Filter.class));
|
||||
final SessionCookieConfig sessionCookieConfig = new MockSessionCookieConfig();
|
||||
given(this.servletContext.getSessionCookieConfig()).willReturn(sessionCookieConfig);
|
||||
final Map<String, String> initParameters = new HashMap<>();
|
||||
lenient().doAnswer((invocation) -> {
|
||||
initParameters.put(invocation.getArgument(0), invocation.getArgument(1));
|
||||
return null;
|
||||
}).when(this.servletContext).setInitParameter(anyString(), anyString());
|
||||
given(this.servletContext.getInitParameterNames())
|
||||
.willReturn(Collections.enumeration(initParameters.keySet()));
|
||||
lenient().doAnswer((invocation) -> initParameters.get(invocation.getArgument(0)))
|
||||
.when(this.servletContext)
|
||||
.getInitParameter(anyString());
|
||||
given(this.servletContext.getAttributeNames()).willReturn(Collections.emptyEnumeration());
|
||||
for (Initializer initializer : this.initializers) {
|
||||
initializer.onStartup(this.servletContext);
|
||||
}
|
||||
}
|
||||
catch (ServletException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
this.servletContext = null;
|
||||
this.registeredServlets.clear();
|
||||
}
|
||||
|
||||
public ServletContext getServletContext() {
|
||||
return this.servletContext;
|
||||
}
|
||||
|
||||
public Servlet[] getServlets() {
|
||||
Servlet[] servlets = new Servlet[this.registeredServlets.size()];
|
||||
Arrays.setAll(servlets, (i) -> this.registeredServlets.get(i).getServlet());
|
||||
return servlets;
|
||||
}
|
||||
|
||||
public RegisteredServlet getRegisteredServlet(int index) {
|
||||
return getRegisteredServlets().get(index);
|
||||
}
|
||||
|
||||
public List<RegisteredServlet> getRegisteredServlets() {
|
||||
return this.registeredServlets;
|
||||
}
|
||||
|
||||
public RegisteredFilter getRegisteredFilters(int index) {
|
||||
return getRegisteredFilters().get(index);
|
||||
}
|
||||
|
||||
public List<RegisteredFilter> getRegisteredFilters() {
|
||||
return this.registeredFilters;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return this.port;
|
||||
}
|
||||
|
||||
/**
|
||||
* A registered servlet.
|
||||
*/
|
||||
public static class RegisteredServlet {
|
||||
|
||||
private final Servlet servlet;
|
||||
|
||||
private final ServletRegistration.Dynamic registration;
|
||||
|
||||
public RegisteredServlet(Servlet servlet) {
|
||||
this.servlet = servlet;
|
||||
this.registration = mock(ServletRegistration.Dynamic.class);
|
||||
}
|
||||
|
||||
public ServletRegistration.Dynamic getRegistration() {
|
||||
return this.registration;
|
||||
}
|
||||
|
||||
public Servlet getServlet() {
|
||||
return this.servlet;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A registered filter.
|
||||
*/
|
||||
public static class RegisteredFilter {
|
||||
|
||||
private final Filter filter;
|
||||
|
||||
private final FilterRegistration.Dynamic registration;
|
||||
|
||||
public RegisteredFilter(Filter filter) {
|
||||
this.filter = filter;
|
||||
this.registration = mock(FilterRegistration.Dynamic.class);
|
||||
}
|
||||
|
||||
public FilterRegistration.Dynamic getRegistration() {
|
||||
return this.registration;
|
||||
}
|
||||
|
||||
public Filter getFilter() {
|
||||
return this.filter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializer (usually implement by adapting {@code Initializer}).
|
||||
*/
|
||||
@FunctionalInterface
|
||||
protected interface Initializer {
|
||||
|
||||
void onStartup(ServletContext context) throws ServletException;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2023 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
|
||||
*
|
||||
* https://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.testsupport.web.servlet;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.mock.web.MockSessionCookieConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MockServletWebServer}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class MockServletWebServerTests {
|
||||
|
||||
@Test
|
||||
void servletContextIsConfigured() {
|
||||
MockServletWebServer server = TestMockServletWebServer.create();
|
||||
assertThat(server.getServletContext()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void servletContextHasSessionCookieConfigConfigured() {
|
||||
MockServletWebServer server = TestMockServletWebServer.create();
|
||||
assertThat(server.getServletContext().getSessionCookieConfig()).isInstanceOf(MockSessionCookieConfig.class);
|
||||
}
|
||||
|
||||
private static final class TestMockServletWebServer extends MockServletWebServer {
|
||||
|
||||
private TestMockServletWebServer(Initializer[] initializers, int port) {
|
||||
super(initializers, port);
|
||||
}
|
||||
|
||||
static MockServletWebServer create(Initializer... initializers) {
|
||||
return new TestMockServletWebServer(initializers, 8080);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user