diff options
author | Emmanuel Bourg <ebourg@apache.org> | 2016-08-02 11:13:32 +0200 |
---|---|---|
committer | Emmanuel Bourg <ebourg@apache.org> | 2016-08-02 11:13:32 +0200 |
commit | f69f2a4b8ea697b3a631c0dc7a470e3c9793fee3 (patch) | |
tree | db2f25b29aa3e59c463ab41d3f2856f6265bb1a5 /spring-web/src/test/java/org/springframework/web | |
parent | 5575b60c30c5a0c308c4ba3a2db93956d8c1746c (diff) |
Imported Upstream version 4.2.6
Diffstat (limited to 'spring-web/src/test/java/org/springframework/web')
52 files changed, 2446 insertions, 902 deletions
diff --git a/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderIntegrationTests.java b/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderIntegrationTests.java index e6b0ed64..c12711dc 100644 --- a/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -25,11 +25,13 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; + import org.junit.AfterClass; -import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -39,7 +41,6 @@ import org.springframework.http.MediaType; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.util.SocketUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.context.request.ServletWebRequest; @@ -47,36 +48,30 @@ import static org.junit.Assert.*; /** * @author Brian Clozel + * @author Sam Brannen */ public class WebRequestDataBinderIntegrationTests { - protected static String baseUrl; - - protected static MediaType contentType; - private static Server jettyServer; - private RestTemplate template; + private static final PartsServlet partsServlet = new PartsServlet(); - private static PartsServlet partsServlet; + private static final PartListServlet partListServlet = new PartListServlet(); - private static PartListServlet partListServlet; + private final RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory()); + protected static String baseUrl; + + protected static MediaType contentType; - @Before - public void createTemplate() { - template = new RestTemplate(new HttpComponentsClientHttpRequestFactory()); - } @BeforeClass public static void startJettyServer() throws Exception { - int port = SocketUtils.findAvailableTcpPort(); - jettyServer = new Server(port); - baseUrl = "http://localhost:" + port; - ServletContextHandler handler = new ServletContextHandler(); - partsServlet = new PartsServlet(); - partListServlet = new PartListServlet(); + // Let server pick its own random, available port. + jettyServer = new Server(0); + + ServletContextHandler handler = new ServletContextHandler(); MultipartConfigElement multipartConfig = new MultipartConfigElement(""); @@ -87,8 +82,13 @@ public class WebRequestDataBinderIntegrationTests { holder = new ServletHolder(partListServlet); holder.getRegistration().setMultipartConfig(multipartConfig); handler.addServlet(holder, "/partlist"); + jettyServer.setHandler(handler); jettyServer.start(); + + Connector[] connectors = jettyServer.getConnectors(); + NetworkConnector connector = (NetworkConnector) connectors[0]; + baseUrl = "http://localhost:" + connector.getLocalPort(); } @AfterClass @@ -100,7 +100,7 @@ public class WebRequestDataBinderIntegrationTests { @Test - public void testPartsBinding() { + public void partsBinding() { PartsBean bean = new PartsBean(); partsServlet.setBean(bean); @@ -117,7 +117,7 @@ public class WebRequestDataBinderIntegrationTests { } @Test - public void testPartListBinding() { + public void partListBinding() { PartListBean bean = new PartListBean(); partListServlet.setBean(bean); diff --git a/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderTests.java b/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderTests.java index 6ec3f5b5..32b4c0e1 100644 --- a/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderTests.java +++ b/spring-web/src/test/java/org/springframework/web/bind/support/WebRequestDataBinderTests.java @@ -345,11 +345,11 @@ public class WebRequestDataBinderTests { static class TestBeanWithConcreteSpouse extends TestBean { public void setConcreteSpouse(TestBean spouse) { - this.spouses = new ITestBean[] {spouse}; + setSpouse(spouse); } public TestBean getConcreteSpouse() { - return (spouses != null ? (TestBean) spouses[0] : null); + return (TestBean) getSpouse(); } } diff --git a/spring-web/src/test/java/org/springframework/web/client/AbstractJettyServerTestCase.java b/spring-web/src/test/java/org/springframework/web/client/AbstractJettyServerTestCase.java index 59c82df4..adf5449f 100644 --- a/spring-web/src/test/java/org/springframework/web/client/AbstractJettyServerTestCase.java +++ b/spring-web/src/test/java/org/springframework/web/client/AbstractJettyServerTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -19,6 +19,7 @@ package org.springframework.web.client; import java.io.IOException; import java.util.Collections; import java.util.List; +import java.util.Map; import javax.servlet.GenericServlet; import javax.servlet.ServletException; import javax.servlet.ServletRequest; @@ -32,52 +33,58 @@ import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; + +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.NetworkConnector; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; + import org.junit.AfterClass; import org.junit.BeforeClass; import org.springframework.http.MediaType; import org.springframework.util.FileCopyUtils; -import org.springframework.util.SocketUtils; import static org.junit.Assert.*; /** * @author Arjen Poutsma + * @author Sam Brannen */ public class AbstractJettyServerTestCase { - protected static String helloWorld = "H\u00e9llo W\u00f6rld"; + protected static final String helloWorld = "H\u00e9llo W\u00f6rld"; - protected static int port; - protected static String baseUrl; + protected static final MediaType textContentType = new MediaType("text", "plain", + Collections.singletonMap("charset", "UTF-8")); - protected static MediaType textContentType; - protected static MediaType jsonContentType; + protected static final MediaType jsonContentType = new MediaType("application", + "json", Collections.singletonMap("charset", "utf-8")); private static Server jettyServer; + protected static int port; + + protected static String baseUrl; + + @BeforeClass public static void startJettyServer() throws Exception { - port = SocketUtils.findAvailableTcpPort(); - jettyServer = new Server(port); - baseUrl = "http://localhost:" + port; + + // Let server pick its own random, available port. + jettyServer = new Server(0); + ServletContextHandler handler = new ServletContextHandler(); - byte[] bytes = helloWorld.getBytes("UTF-8"); - textContentType = new MediaType("text", "plain", Collections - .singletonMap("charset", "UTF-8")); - jsonContentType = new MediaType("application", "json", Collections - .singletonMap("charset", "UTF-8")); + byte[] bytes = helloWorld.getBytes("utf-8"); handler.addServlet(new ServletHolder(new GetServlet(bytes, textContentType)), "/get"); handler.addServlet(new ServletHolder(new GetServlet(new byte[0], textContentType)), "/get/nothing"); handler.addServlet(new ServletHolder(new GetServlet(bytes, null)), "/get/nocontenttype"); handler.addServlet( - new ServletHolder(new PostServlet(helloWorld, baseUrl + "/post/1", bytes, textContentType)), + new ServletHolder(new PostServlet(helloWorld, "/post/1", bytes, textContentType)), "/post"); handler.addServlet( - new ServletHolder(new JsonPostServlet(baseUrl + "/jsonpost/1", jsonContentType)), + new ServletHolder(new JsonPostServlet("/jsonpost/1", jsonContentType)), "/jsonpost"); handler.addServlet(new ServletHolder(new StatusCodeServlet(204)), "/status/nocontent"); handler.addServlet(new ServletHolder(new StatusCodeServlet(304)), "/status/notmodified"); @@ -85,12 +92,19 @@ public class AbstractJettyServerTestCase { handler.addServlet(new ServletHolder(new ErrorServlet(500)), "/status/server"); handler.addServlet(new ServletHolder(new UriServlet()), "/uri/*"); handler.addServlet(new ServletHolder(new MultipartServlet()), "/multipart"); + handler.addServlet(new ServletHolder(new FormServlet()), "/form"); handler.addServlet(new ServletHolder(new DeleteServlet()), "/delete"); handler.addServlet( new ServletHolder(new PutServlet(helloWorld, bytes, textContentType)), "/put"); + jettyServer.setHandler(handler); jettyServer.start(); + + Connector[] connectors = jettyServer.getConnectors(); + NetworkConnector connector = (NetworkConnector) connectors[0]; + port = connector.getLocalPort(); + baseUrl = "http://localhost:" + port; } @AfterClass @@ -182,7 +196,7 @@ public class AbstractJettyServerTestCase { String body = FileCopyUtils.copyToString(request.getReader()); assertEquals("Invalid request body", s, body); response.setStatus(HttpServletResponse.SC_CREATED); - response.setHeader("Location", location); + response.setHeader("Location", baseUrl + location); response.setContentLength(buf.length); response.setContentType(contentType.toString()); FileCopyUtils.copy(buf, response.getOutputStream()); @@ -208,9 +222,9 @@ public class AbstractJettyServerTestCase { assertNotNull("No content-type", request.getContentType()); String body = FileCopyUtils.copyToString(request.getReader()); response.setStatus(HttpServletResponse.SC_CREATED); - response.setHeader("Location", location); + response.setHeader("Location", baseUrl +location); response.setContentType(contentType.toString()); - byte[] bytes = body.getBytes("UTF-8"); + byte[] bytes = body.getBytes("utf-8"); response.setContentLength(bytes.length);; FileCopyUtils.copy(bytes, response.getOutputStream()); } @@ -242,7 +256,7 @@ public class AbstractJettyServerTestCase { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/plain"); - resp.setCharacterEncoding("UTF-8"); + resp.setCharacterEncoding("utf-8"); resp.getWriter().write(req.getRequestURI()); } } @@ -287,6 +301,28 @@ public class AbstractJettyServerTestCase { } @SuppressWarnings("serial") + private static class FormServlet extends HttpServlet { + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + assertEquals(MediaType.APPLICATION_FORM_URLENCODED_VALUE, + req.getContentType()); + + Map<String, String[]> parameters = req.getParameterMap(); + assertEquals(2, parameters.size()); + + String[] values = parameters.get("name 1"); + assertEquals(1, values.length); + assertEquals("value 1", values[0]); + + values = parameters.get("name 2"); + assertEquals(2, values.length); + assertEquals("value 2+1", values[0]); + assertEquals("value 2+2", values[1]); + } + } + + @SuppressWarnings("serial") private static class DeleteServlet extends HttpServlet { @Override diff --git a/spring-web/src/test/java/org/springframework/web/client/AsyncRestTemplateIntegrationTests.java b/spring-web/src/test/java/org/springframework/web/client/AsyncRestTemplateIntegrationTests.java index b6127832..6210cec1 100644 --- a/spring-web/src/test/java/org/springframework/web/client/AsyncRestTemplateIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/AsyncRestTemplateIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -20,9 +20,11 @@ import java.net.URI; import java.nio.charset.Charset; import java.util.EnumSet; import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; -import org.junit.Before; import org.junit.Test; import org.springframework.core.io.ClassPathResource; @@ -47,13 +49,7 @@ import static org.junit.Assert.*; */ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCase { - private AsyncRestTemplate template; - - - @Before - public void createTemplate() { - template = new AsyncRestTemplate(new HttpComponentsAsyncClientHttpRequestFactory()); - } + private final AsyncRestTemplate template = new AsyncRestTemplate(new HttpComponentsAsyncClientHttpRequestFactory()); @Test @@ -317,16 +313,50 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa } @Test - public void notFound() throws Exception { + public void identicalExceptionThroughGetAndCallback() throws Exception { + final HttpClientErrorException[] callbackException = new HttpClientErrorException[1]; + + final CountDownLatch latch = new CountDownLatch(1); + ListenableFuture<?> future = template.execute(baseUrl + "/status/notfound", HttpMethod.GET, null, null); + future.addCallback(new ListenableFutureCallback<Object>() { + @Override + public void onSuccess(Object result) { + fail("onSuccess not expected"); + } + @Override + public void onFailure(Throwable ex) { + assertTrue(ex instanceof HttpClientErrorException); + callbackException[0] = (HttpClientErrorException) ex; + latch.countDown(); + } + }); + + try { + future.get(); + fail("Exception expected"); + } + catch (ExecutionException ex) { + Throwable cause = ex.getCause(); + assertTrue(cause instanceof HttpClientErrorException); + latch.await(5, TimeUnit.SECONDS); + assertSame(callbackException[0], cause); + } + } + + @Test + public void notFoundGet() throws Exception { try { Future<?> future = template.execute(baseUrl + "/status/notfound", HttpMethod.GET, null, null); future.get(); fail("HttpClientErrorException expected"); } - catch (HttpClientErrorException ex) { - assertEquals(HttpStatus.NOT_FOUND, ex.getStatusCode()); - assertNotNull(ex.getStatusText()); - assertNotNull(ex.getResponseBodyAsString()); + catch (ExecutionException ex) { + assertTrue(ex.getCause() instanceof HttpClientErrorException); + HttpClientErrorException cause = (HttpClientErrorException)ex.getCause(); + + assertEquals(HttpStatus.NOT_FOUND, cause.getStatusCode()); + assertNotNull(cause.getStatusText()); + assertNotNull(cause.getResponseBodyAsString()); } } @@ -372,10 +402,13 @@ public class AsyncRestTemplateIntegrationTests extends AbstractJettyServerTestCa future.get(); fail("HttpServerErrorException expected"); } - catch (HttpServerErrorException ex) { - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, ex.getStatusCode()); - assertNotNull(ex.getStatusText()); - assertNotNull(ex.getResponseBodyAsString()); + catch (ExecutionException ex) { + assertTrue(ex.getCause() instanceof HttpServerErrorException); + HttpServerErrorException cause = (HttpServerErrorException)ex.getCause(); + + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, cause.getStatusCode()); + assertNotNull(cause.getStatusText()); + assertNotNull(cause.getResponseBodyAsString()); } } diff --git a/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java b/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java index 33139096..3a59757e 100644 --- a/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/HttpMessageConverterExtractorTests.java @@ -157,6 +157,7 @@ public class HttpMessageConverterExtractorTests { } @Test + @SuppressWarnings("unchecked") public void generics() throws IOException { GenericHttpMessageConverter<String> converter = mock(GenericHttpMessageConverter.class); List<HttpMessageConverter<?>> converters = createConverterList(converter); diff --git a/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java b/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java index b5be18bf..149340b6 100644 --- a/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/RestTemplateIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -23,8 +23,6 @@ import java.nio.charset.Charset; import java.util.EnumSet; import java.util.Set; -import com.fasterxml.jackson.annotation.JsonView; -import org.junit.Before; import org.junit.Test; import org.springframework.core.io.ClassPathResource; @@ -40,6 +38,8 @@ import org.springframework.http.converter.json.MappingJacksonValue; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import com.fasterxml.jackson.annotation.JsonView; + import static org.junit.Assert.*; /** @@ -47,12 +47,8 @@ import static org.junit.Assert.*; */ public class RestTemplateIntegrationTests extends AbstractJettyServerTestCase { - private RestTemplate template; + private final RestTemplate template = new RestTemplate(new HttpComponentsClientHttpRequestFactory()); - @Before - public void createTemplate() { - template = new RestTemplate(new HttpComponentsClientHttpRequestFactory()); - } @Test public void getString() { @@ -180,6 +176,16 @@ public class RestTemplateIntegrationTests extends AbstractJettyServerTestCase { } @Test + public void form() throws UnsupportedEncodingException { + MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>(); + form.add("name 1", "value 1"); + form.add("name 2", "value 2+1"); + form.add("name 2", "value 2+2"); + + template.postForLocation(baseUrl + "/form", form); + } + + @Test public void exchangeGet() throws Exception { HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.set("MyHeader", "MyValue"); diff --git a/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java b/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java index 86e55af4..1ecfc48e 100644 --- a/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java @@ -42,6 +42,7 @@ import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.converter.GenericHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.util.DefaultUriTemplateHandler; import static org.junit.Assert.*; import static org.mockito.BDDMockito.*; @@ -259,6 +260,35 @@ public class RestTemplateTests { verify(response).close(); } + @Test + public void getForObjectWithCustomUriTemplateHandler() throws Exception { + + DefaultUriTemplateHandler uriTemplateHandler = new DefaultUriTemplateHandler(); + uriTemplateHandler.setParsePath(true); + template.setUriTemplateHandler(uriTemplateHandler); + + URI expectedUri = new URI("http://example.com/hotels/1/pic/pics%2Flogo.png/size/150x150"); + given(requestFactory.createRequest(expectedUri, HttpMethod.GET)).willReturn(request); + + given(request.getHeaders()).willReturn(new HttpHeaders()); + given(request.execute()).willReturn(response); + given(errorHandler.hasError(response)).willReturn(false); + + given(response.getStatusCode()).willReturn(HttpStatus.OK); + given(response.getHeaders()).willReturn(new HttpHeaders()); + given(response.getBody()).willReturn(null); + + Map<String, String> uriVariables = new HashMap<String, String>(2); + uriVariables.put("hotel", "1"); + uriVariables.put("publicpath", "pics/logo.png"); + uriVariables.put("scale", "150x150"); + + String url = "http://example.com/hotels/{hotel}/pic/{publicpath}/size/{scale}"; + template.getForObject(url, String.class, uriVariables); + + verify(response).close(); + } + @Test public void headForHeaders() throws Exception { diff --git a/spring-web/src/test/java/org/springframework/web/context/request/RequestAndSessionScopedBeanTests.java b/spring-web/src/test/java/org/springframework/web/context/request/RequestAndSessionScopedBeanTests.java index de7e9f7f..353a879f 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/RequestAndSessionScopedBeanTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/RequestAndSessionScopedBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -36,6 +36,7 @@ import static org.junit.Assert.*; public class RequestAndSessionScopedBeanTests { @Test + @SuppressWarnings("resource") public void testPutBeanInRequest() throws Exception { String targetBeanName = "target"; @@ -75,6 +76,7 @@ public class RequestAndSessionScopedBeanTests { } @Test + @SuppressWarnings("resource") public void testPutBeanInSession() throws Exception { String targetBeanName = "target"; HttpServletRequest request = new MockHttpServletRequest(); diff --git a/spring-web/src/test/java/org/springframework/web/context/request/RequestContextListenerTests.java b/spring-web/src/test/java/org/springframework/web/context/request/RequestContextListenerTests.java index 6d9d28e0..550376b8 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/RequestContextListenerTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/RequestContextListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -18,18 +18,21 @@ package org.springframework.web.context.request; import javax.servlet.ServletRequestEvent; -import junit.framework.TestCase; +import org.junit.Test; import org.springframework.core.task.MockRunnable; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockServletContext; +import static org.junit.Assert.*; + /** * @author Juergen Hoeller */ -public class RequestContextListenerTests extends TestCase { +public class RequestContextListenerTests { - public void testRequestContextListenerWithSameThread() { + @Test + public void requestContextListenerWithSameThread() { RequestContextListener listener = new RequestContextListener(); MockServletContext context = new MockServletContext(); MockHttpServletRequest request = new MockHttpServletRequest(context); @@ -49,7 +52,8 @@ public class RequestContextListenerTests extends TestCase { assertTrue(runnable.wasExecuted()); } - public void testRequestContextListenerWithSameThreadAndAttributesGone() { + @Test + public void requestContextListenerWithSameThreadAndAttributesGone() { RequestContextListener listener = new RequestContextListener(); MockServletContext context = new MockServletContext(); MockHttpServletRequest request = new MockHttpServletRequest(context); @@ -70,7 +74,8 @@ public class RequestContextListenerTests extends TestCase { assertTrue(runnable.wasExecuted()); } - public void testRequestContextListenerWithDifferentThread() { + @Test + public void requestContextListenerWithDifferentThread() { final RequestContextListener listener = new RequestContextListener(); final MockServletContext context = new MockServletContext(); final MockHttpServletRequest request = new MockHttpServletRequest(context); diff --git a/spring-web/src/test/java/org/springframework/web/context/request/RequestScopeTests.java b/spring-web/src/test/java/org/springframework/web/context/request/RequestScopeTests.java index b044b8c2..fd01d403 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/RequestScopeTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/RequestScopeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -16,7 +16,9 @@ package org.springframework.web.context.request; -import junit.framework.TestCase; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCurrentlyInCreationException; @@ -29,18 +31,22 @@ import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.tests.sample.beans.DerivedTestBean; import org.springframework.tests.sample.beans.TestBean; +import static org.junit.Assert.*; + /** * @author Rob Harrop * @author Juergen Hoeller * @author Mark Fisher + * @author Sam Brannen + * @see SessionScopeTests */ -public class RequestScopeTests extends TestCase { +public class RequestScopeTests { + + private final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); - private DefaultListableBeanFactory beanFactory; - @Override - protected void setUp() throws Exception { - this.beanFactory = new DefaultListableBeanFactory(); + @Before + public void setUp() throws Exception { this.beanFactory.registerScope("request", new RequestScope()); this.beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.beanFactory); @@ -48,63 +54,57 @@ public class RequestScopeTests extends TestCase { this.beanFactory.preInstantiateSingletons(); } - public void testGetFromScope() throws Exception { + @After + public void resetRequestAttributes() { + RequestContextHolder.setRequestAttributes(null); + } + + @Test + public void getFromScope() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); request.setContextPath("/path"); RequestAttributes requestAttributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes); - try { - String name = "requestScopedObject"; - assertNull(request.getAttribute(name)); - TestBean bean = (TestBean) this.beanFactory.getBean(name); - assertEquals("/path", bean.getName()); - assertSame(bean, request.getAttribute(name)); - assertSame(bean, this.beanFactory.getBean(name)); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } + String name = "requestScopedObject"; + assertNull(request.getAttribute(name)); + TestBean bean = (TestBean) this.beanFactory.getBean(name); + assertEquals("/path", bean.getName()); + assertSame(bean, request.getAttribute(name)); + assertSame(bean, this.beanFactory.getBean(name)); } - public void testDestructionAtRequestCompletion() throws Exception { + @Test + public void destructionAtRequestCompletion() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes); - try { - String name = "requestScopedDisposableObject"; - assertNull(request.getAttribute(name)); - DerivedTestBean bean = (DerivedTestBean) this.beanFactory.getBean(name); - assertSame(bean, request.getAttribute(name)); - assertSame(bean, this.beanFactory.getBean(name)); + String name = "requestScopedDisposableObject"; + assertNull(request.getAttribute(name)); + DerivedTestBean bean = (DerivedTestBean) this.beanFactory.getBean(name); + assertSame(bean, request.getAttribute(name)); + assertSame(bean, this.beanFactory.getBean(name)); - requestAttributes.requestCompleted(); - assertTrue(bean.wasDestroyed()); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } + requestAttributes.requestCompleted(); + assertTrue(bean.wasDestroyed()); } - public void testGetFromFactoryBeanInScope() throws Exception { + @Test + public void getFromFactoryBeanInScope() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); RequestAttributes requestAttributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes); - try { - String name = "requestScopedFactoryBean"; - assertNull(request.getAttribute(name)); - TestBean bean = (TestBean) this.beanFactory.getBean(name); - assertTrue(request.getAttribute(name) instanceof FactoryBean); - assertSame(bean, this.beanFactory.getBean(name)); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } + String name = "requestScopedFactoryBean"; + assertNull(request.getAttribute(name)); + TestBean bean = (TestBean) this.beanFactory.getBean(name); + assertTrue(request.getAttribute(name) instanceof FactoryBean); + assertSame(bean, this.beanFactory.getBean(name)); } - public void testCircleLeadsToException() throws Exception { + @Test + public void circleLeadsToException() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); RequestAttributes requestAttributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes); @@ -112,65 +112,54 @@ public class RequestScopeTests extends TestCase { try { String name = "requestScopedObjectCircle1"; assertNull(request.getAttribute(name)); + this.beanFactory.getBean(name); fail("Should have thrown BeanCreationException"); } catch (BeanCreationException ex) { - // expected assertTrue(ex.contains(BeanCurrentlyInCreationException.class)); } - finally { - RequestContextHolder.setRequestAttributes(null); - } } - public void testInnerBeanInheritsContainingBeanScopeByDefault() { + @Test + public void innerBeanInheritsContainingBeanScopeByDefault() { MockHttpServletRequest request = new MockHttpServletRequest(); ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes); - try { - String outerBeanName = "requestScopedOuterBean"; - assertNull(request.getAttribute(outerBeanName)); - TestBean outer1 = (TestBean) this.beanFactory.getBean(outerBeanName); - assertNotNull(request.getAttribute(outerBeanName)); - TestBean inner1 = (TestBean) outer1.getSpouse(); - assertSame(outer1, this.beanFactory.getBean(outerBeanName)); - requestAttributes.requestCompleted(); - assertTrue(outer1.wasDestroyed()); - assertTrue(inner1.wasDestroyed()); - request = new MockHttpServletRequest(); - requestAttributes = new ServletRequestAttributes(request); - RequestContextHolder.setRequestAttributes(requestAttributes); - TestBean outer2 = (TestBean) this.beanFactory.getBean(outerBeanName); - assertNotSame(outer1, outer2); - assertNotSame(inner1, outer2.getSpouse()); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } + String outerBeanName = "requestScopedOuterBean"; + assertNull(request.getAttribute(outerBeanName)); + TestBean outer1 = (TestBean) this.beanFactory.getBean(outerBeanName); + assertNotNull(request.getAttribute(outerBeanName)); + TestBean inner1 = (TestBean) outer1.getSpouse(); + assertSame(outer1, this.beanFactory.getBean(outerBeanName)); + requestAttributes.requestCompleted(); + assertTrue(outer1.wasDestroyed()); + assertTrue(inner1.wasDestroyed()); + request = new MockHttpServletRequest(); + requestAttributes = new ServletRequestAttributes(request); + RequestContextHolder.setRequestAttributes(requestAttributes); + TestBean outer2 = (TestBean) this.beanFactory.getBean(outerBeanName); + assertNotSame(outer1, outer2); + assertNotSame(inner1, outer2.getSpouse()); } - public void testRequestScopedInnerBeanDestroyedWhileContainedBySingleton() throws Exception { + @Test + public void requestScopedInnerBeanDestroyedWhileContainedBySingleton() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes); - try { - String outerBeanName = "singletonOuterBean"; - TestBean outer1 = (TestBean) this.beanFactory.getBean(outerBeanName); - assertNull(request.getAttribute(outerBeanName)); - TestBean inner1 = (TestBean) outer1.getSpouse(); - TestBean outer2 = (TestBean) this.beanFactory.getBean(outerBeanName); - assertSame(outer1, outer2); - assertSame(inner1, outer2.getSpouse()); - requestAttributes.requestCompleted(); - assertTrue(inner1.wasDestroyed()); - assertFalse(outer1.wasDestroyed()); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } + String outerBeanName = "singletonOuterBean"; + TestBean outer1 = (TestBean) this.beanFactory.getBean(outerBeanName); + assertNull(request.getAttribute(outerBeanName)); + TestBean inner1 = (TestBean) outer1.getSpouse(); + TestBean outer2 = (TestBean) this.beanFactory.getBean(outerBeanName); + assertSame(outer1, outer2); + assertSame(inner1, outer2.getSpouse()); + requestAttributes.requestCompleted(); + assertTrue(inner1.wasDestroyed()); + assertFalse(outer1.wasDestroyed()); } } diff --git a/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestHttpMethodsTests.java b/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestHttpMethodsTests.java new file mode 100644 index 00000000..3832ae3a --- /dev/null +++ b/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestHttpMethodsTests.java @@ -0,0 +1,296 @@ +/* + * Copyright 2002-2015 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.web.context.request; + +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; + +import org.springframework.mock.web.test.MockHttpServletRequest; +import org.springframework.mock.web.test.MockHttpServletResponse; + +import static org.junit.Assert.*; + +/** + * Parameterized tests for ServletWebRequest + * @author Juergen Hoeller + * @author Brian Clozel + * @author Markus Malkusch + */ +@RunWith(Parameterized.class) +public class ServletWebRequestHttpMethodsTests { + + private static final String CURRENT_TIME = "Wed, 09 Apr 2014 09:57:42 GMT"; + + private SimpleDateFormat dateFormat; + + private MockHttpServletRequest servletRequest; + + private MockHttpServletResponse servletResponse; + + private ServletWebRequest request; + + private Date currentDate; + + @Parameter + public String method; + + @Parameters(name = "{0}") + static public Iterable<Object[]> safeMethods() { + return Arrays.asList(new Object[][] { + {"GET"}, + {"HEAD"} + }); + } + + @Before + public void setUp() { + currentDate = new Date(); + dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); + dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); + servletRequest = new MockHttpServletRequest(method, "http://example.org"); + servletResponse = new MockHttpServletResponse(); + request = new ServletWebRequest(servletRequest, servletResponse); + } + + @Test + public void checkNotModifiedNon2xxStatus() { + long epochTime = currentDate.getTime(); + servletRequest.addHeader("If-Modified-Since", epochTime); + servletResponse.setStatus(304); + + assertFalse(request.checkNotModified(epochTime)); + assertEquals(304, servletResponse.getStatus()); + assertNull(servletResponse.getHeader("Last-Modified")); + } + + // SPR-13516 + @Test + public void checkNotModifiedInvalidStatus() { + long epochTime = currentDate.getTime(); + servletRequest.addHeader("If-Modified-Since", epochTime); + servletResponse.setStatus(0); + + assertTrue(request.checkNotModified(epochTime)); + assertEquals(304, servletResponse.getStatus()); + assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified")); + } + + @Test + public void checkNotModifiedHeaderAlreadySet() { + long epochTime = currentDate.getTime(); + servletRequest.addHeader("If-Modified-Since", epochTime); + servletResponse.addHeader("Last-Modified", CURRENT_TIME); + + assertTrue(request.checkNotModified(epochTime)); + assertEquals(304, servletResponse.getStatus()); + assertEquals(1, servletResponse.getHeaders("Last-Modified").size()); + assertEquals(CURRENT_TIME, servletResponse.getHeader("Last-Modified")); + } + + @Test + public void checkNotModifiedTimestamp() throws Exception { + long epochTime = currentDate.getTime(); + servletRequest.addHeader("If-Modified-Since", epochTime); + + assertTrue(request.checkNotModified(epochTime)); + + assertEquals(304, servletResponse.getStatus()); + assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified")); + } + + @Test + public void checkModifiedTimestamp() { + long oneMinuteAgo = currentDate.getTime() - (1000 * 60); + servletRequest.addHeader("If-Modified-Since", oneMinuteAgo); + + assertFalse(request.checkNotModified(currentDate.getTime())); + + assertEquals(200, servletResponse.getStatus()); + assertEquals(dateFormat.format(currentDate.getTime()), servletResponse.getHeader("Last-Modified")); + } + + @Test + public void checkNotModifiedETag() { + String eTag = "\"Foo\""; + servletRequest.addHeader("If-None-Match", eTag); + + assertTrue(request.checkNotModified(eTag)); + + assertEquals(304, servletResponse.getStatus()); + assertEquals(eTag, servletResponse.getHeader("ETag")); + } + + @Test + public void checkModifiedETag() { + String currentETag = "\"Foo\""; + String oldEtag = "Bar"; + servletRequest.addHeader("If-None-Match", oldEtag); + + assertFalse(request.checkNotModified(currentETag)); + + assertEquals(200, servletResponse.getStatus()); + assertEquals(currentETag, servletResponse.getHeader("ETag")); + } + + @Test + public void checkNotModifiedUnpaddedETag() { + String eTag = "Foo"; + String paddedEtag = String.format("\"%s\"", eTag); + servletRequest.addHeader("If-None-Match", paddedEtag); + + assertTrue(request.checkNotModified(eTag)); + + assertEquals(304, servletResponse.getStatus()); + assertEquals(paddedEtag, servletResponse.getHeader("ETag")); + } + + @Test + public void checkModifiedUnpaddedETag() { + String currentETag = "Foo"; + String oldEtag = "Bar"; + servletRequest.addHeader("If-None-Match", oldEtag); + + assertFalse(request.checkNotModified(currentETag)); + + assertEquals(200, servletResponse.getStatus()); + assertEquals(String.format("\"%s\"", currentETag), servletResponse.getHeader("ETag")); + } + + @Test + public void checkNotModifiedWildcardETag() { + String eTag = "\"Foo\""; + servletRequest.addHeader("If-None-Match", "*"); + + assertTrue(request.checkNotModified(eTag)); + + assertEquals(304, servletResponse.getStatus()); + assertEquals(eTag, servletResponse.getHeader("ETag")); + } + + @Test + public void checkNotModifiedETagAndTimestamp() { + String eTag = "\"Foo\""; + servletRequest.addHeader("If-None-Match", eTag); + servletRequest.addHeader("If-Modified-Since", currentDate.getTime()); + + assertTrue(request.checkNotModified(eTag, currentDate.getTime())); + + assertEquals(304, servletResponse.getStatus()); + assertEquals(eTag, servletResponse.getHeader("ETag")); + assertEquals(dateFormat.format(currentDate.getTime()), servletResponse.getHeader("Last-Modified")); + } + + @Test + public void checkNotModifiedETagAndModifiedTimestamp() { + String eTag = "\"Foo\""; + servletRequest.addHeader("If-None-Match", eTag); + long currentEpoch = currentDate.getTime(); + long oneMinuteAgo = currentEpoch - (1000 * 60); + servletRequest.addHeader("If-Modified-Since", oneMinuteAgo); + + assertFalse(request.checkNotModified(eTag, currentEpoch)); + + assertEquals(200, servletResponse.getStatus()); + assertEquals(eTag, servletResponse.getHeader("ETag")); + assertEquals(dateFormat.format(currentEpoch), servletResponse.getHeader("Last-Modified")); + } + + @Test + public void checkModifiedETagAndNotModifiedTimestamp() throws Exception { + String currentETag = "\"Foo\""; + String oldEtag = "\"Bar\""; + servletRequest.addHeader("If-None-Match", oldEtag); + long epochTime = currentDate.getTime(); + servletRequest.addHeader("If-Modified-Since", epochTime); + + assertFalse(request.checkNotModified(currentETag, epochTime)); + + assertEquals(200, servletResponse.getStatus()); + assertEquals(currentETag, servletResponse.getHeader("ETag")); + assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified")); + } + + @Test + public void checkNotModifiedETagWeakStrong() { + String eTag = "\"Foo\""; + String weakEtag = String.format("W/%s", eTag); + servletRequest.addHeader("If-None-Match", eTag); + + assertTrue(request.checkNotModified(weakEtag)); + + assertEquals(304, servletResponse.getStatus()); + assertEquals(weakEtag, servletResponse.getHeader("ETag")); + } + + @Test + public void checkNotModifiedETagStrongWeak() { + String eTag = "\"Foo\""; + servletRequest.addHeader("If-None-Match", String.format("W/%s", eTag)); + + assertTrue(request.checkNotModified(eTag)); + + assertEquals(304, servletResponse.getStatus()); + assertEquals(eTag, servletResponse.getHeader("ETag")); + } + + @Test + public void checkNotModifiedMultipleETags() { + String eTag = "\"Bar\""; + String multipleETags = String.format("\"Foo\", %s", eTag); + servletRequest.addHeader("If-None-Match", multipleETags); + + assertTrue(request.checkNotModified(eTag)); + + assertEquals(304, servletResponse.getStatus()); + assertEquals(eTag, servletResponse.getHeader("ETag")); + } + + @Test + public void checkNotModifiedTimestampWithLengthPart() throws Exception { + long epochTime = dateFormat.parse(CURRENT_TIME).getTime(); + servletRequest.setMethod("GET"); + servletRequest.addHeader("If-Modified-Since", "Wed, 09 Apr 2014 09:57:42 GMT; length=13774"); + + assertTrue(request.checkNotModified(epochTime)); + + assertEquals(304, servletResponse.getStatus()); + assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified")); + } + + @Test + public void checkModifiedTimestampWithLengthPart() throws Exception { + long epochTime = dateFormat.parse(CURRENT_TIME).getTime(); + servletRequest.setMethod("GET"); + servletRequest.addHeader("If-Modified-Since", "Wed, 08 Apr 2014 09:57:42 GMT; length=13774"); + + assertFalse(request.checkNotModified(epochTime)); + + assertEquals(200, servletResponse.getStatus()); + assertEquals(dateFormat.format(epochTime), servletResponse.getHeader("Last-Modified")); + } + +} diff --git a/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestTests.java b/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestTests.java index dc3ad4b0..75fed80b 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/ServletWebRequestTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -16,9 +16,11 @@ package org.springframework.web.context.request; -import java.util.Date; +import static org.junit.Assert.*; + import java.util.Locale; import java.util.Map; + import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; @@ -33,12 +35,8 @@ import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; import org.springframework.web.multipart.MultipartRequest; -import static org.junit.Assert.*; - /** * @author Juergen Hoeller - * @author Markus Malkusch - * @since 26.07.2006 */ public class ServletWebRequestTests { @@ -116,113 +114,4 @@ public class ServletWebRequestTests { assertNull(request.getNativeResponse(MultipartRequest.class)); } - @Test - public void checkNotModifiedTimestampForGET() { - long currentTime = new Date().getTime(); - servletRequest.setMethod("GET"); - servletRequest.addHeader("If-Modified-Since", currentTime); - - assertTrue(request.checkNotModified(currentTime)); - assertEquals(304, servletResponse.getStatus()); - } - - @Test - public void checkModifiedTimestampForGET() { - long currentTime = new Date().getTime(); - long oneMinuteAgo = currentTime - (1000 * 60); - servletRequest.setMethod("GET"); - servletRequest.addHeader("If-Modified-Since", oneMinuteAgo); - - assertFalse(request.checkNotModified(currentTime)); - assertEquals(200, servletResponse.getStatus()); - assertEquals("" + currentTime, servletResponse.getHeader("Last-Modified")); - } - - @Test - public void checkNotModifiedTimestampForHEAD() { - long currentTime = new Date().getTime(); - servletRequest.setMethod("HEAD"); - servletRequest.addHeader("If-Modified-Since", currentTime); - - assertTrue(request.checkNotModified(currentTime)); - assertEquals(304, servletResponse.getStatus()); - } - - @Test - public void checkModifiedTimestampForHEAD() { - long currentTime = new Date().getTime(); - long oneMinuteAgo = currentTime - (1000 * 60); - servletRequest.setMethod("HEAD"); - servletRequest.addHeader("If-Modified-Since", oneMinuteAgo); - - assertFalse(request.checkNotModified(currentTime)); - assertEquals(200, servletResponse.getStatus()); - assertEquals(""+currentTime, servletResponse.getHeader("Last-Modified")); - } - - @Test - public void checkNotModifiedTimestampWithLengthPart() { - long currentTime = Date.parse("Wed, 09 Apr 2014 09:57:42 GMT"); - servletRequest.setMethod("GET"); - servletRequest.addHeader("If-Modified-Since", "Wed, 09 Apr 2014 09:57:42 GMT; length=13774"); - - assertTrue(request.checkNotModified(currentTime)); - assertEquals(304, servletResponse.getStatus()); - } - - @Test - public void checkModifiedTimestampWithLengthPart() { - long currentTime = Date.parse("Wed, 09 Apr 2014 09:57:42 GMT"); - servletRequest.setMethod("GET"); - servletRequest.addHeader("If-Modified-Since", "Wed, 08 Apr 2014 09:57:42 GMT; length=13774"); - - assertFalse(request.checkNotModified(currentTime)); - assertEquals(200, servletResponse.getStatus()); - assertEquals("" + currentTime, servletResponse.getHeader("Last-Modified")); - } - - @Test - public void checkNotModifiedETagForGET() { - String eTag = "\"Foo\""; - servletRequest.setMethod("GET"); - servletRequest.addHeader("If-None-Match", eTag ); - - assertTrue(request.checkNotModified(eTag)); - assertEquals(304, servletResponse.getStatus()); - } - - @Test - public void checkModifiedETagForGET() { - String currentETag = "\"Foo\""; - String oldEtag = "Bar"; - servletRequest.setMethod("GET"); - servletRequest.addHeader("If-None-Match", oldEtag); - - assertFalse(request.checkNotModified(currentETag)); - assertEquals(200, servletResponse.getStatus()); - assertEquals(currentETag, servletResponse.getHeader("ETag")); - } - - @Test - public void checkNotModifiedETagForHEAD() { - String eTag = "\"Foo\""; - servletRequest.setMethod("HEAD"); - servletRequest.addHeader("If-None-Match", eTag ); - - assertTrue(request.checkNotModified(eTag)); - assertEquals(304, servletResponse.getStatus()); - } - - @Test - public void checkModifiedETagForHEAD() { - String currentETag = "\"Foo\""; - String oldEtag = "Bar"; - servletRequest.setMethod("HEAD"); - servletRequest.addHeader("If-None-Match", oldEtag); - - assertFalse(request.checkNotModified(currentETag)); - assertEquals(200, servletResponse.getStatus()); - assertEquals(currentETag, servletResponse.getHeader("ETag")); - } - -} +}
\ No newline at end of file diff --git a/spring-web/src/test/java/org/springframework/web/context/request/SessionScopeTests.java b/spring-web/src/test/java/org/springframework/web/context/request/SessionScopeTests.java index ead787e9..ab198238 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/SessionScopeTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/SessionScopeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -18,7 +18,9 @@ package org.springframework.web.context.request; import java.io.Serializable; -import junit.framework.TestCase; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanNameAware; @@ -32,74 +34,78 @@ import org.springframework.tests.sample.beans.DerivedTestBean; import org.springframework.tests.sample.beans.TestBean; import org.springframework.util.SerializationTestUtils; +import static org.junit.Assert.*; + /** * @author Rob Harrop * @author Juergen Hoeller + * @author Sam Brannen + * @see RequestScopeTests */ -public class SessionScopeTests extends TestCase { +public class SessionScopeTests { + + private final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); - private DefaultListableBeanFactory beanFactory; - @Override - protected void setUp() throws Exception { - this.beanFactory = new DefaultListableBeanFactory(); + @Before + public void setUp() throws Exception { this.beanFactory.registerScope("session", new SessionScope()); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.beanFactory); reader.loadBeanDefinitions(new ClassPathResource("sessionScopeTests.xml", getClass())); } - public void testGetFromScope() throws Exception { + @After + public void resetRequestAttributes() { + RequestContextHolder.setRequestAttributes(null); + } + + @Test + public void getFromScope() throws Exception { MockHttpSession session = new MockHttpSession(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setSession(session); ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes); - try { - String name = "sessionScopedObject"; - assertNull(session.getAttribute(name)); - TestBean bean = (TestBean) this.beanFactory.getBean(name); - assertEquals(session.getAttribute(name), bean); - assertSame(bean, this.beanFactory.getBean(name)); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } + String name = "sessionScopedObject"; + assertNull(session.getAttribute(name)); + TestBean bean = (TestBean) this.beanFactory.getBean(name); + assertEquals(session.getAttribute(name), bean); + assertSame(bean, this.beanFactory.getBean(name)); } - public void testDestructionAtSessionTermination() throws Exception { + @Test + public void destructionAtSessionTermination() throws Exception { MockHttpSession session = new MockHttpSession(); MockHttpServletRequest request = new MockHttpServletRequest(); request.setSession(session); ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes); - try { - String name = "sessionScopedDisposableObject"; - assertNull(session.getAttribute(name)); - DerivedTestBean bean = (DerivedTestBean) this.beanFactory.getBean(name); - assertEquals(session.getAttribute(name), bean); - assertSame(bean, this.beanFactory.getBean(name)); - - requestAttributes.requestCompleted(); - session.invalidate(); - assertTrue(bean.wasDestroyed()); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } + String name = "sessionScopedDisposableObject"; + assertNull(session.getAttribute(name)); + DerivedTestBean bean = (DerivedTestBean) this.beanFactory.getBean(name); + assertEquals(session.getAttribute(name), bean); + assertSame(bean, this.beanFactory.getBean(name)); + + requestAttributes.requestCompleted(); + session.invalidate(); + assertTrue(bean.wasDestroyed()); } - public void testDestructionWithSessionSerialization() throws Exception { + @Test + public void destructionWithSessionSerialization() throws Exception { doTestDestructionWithSessionSerialization(false); } - public void testDestructionWithSessionSerializationAndBeanPostProcessor() throws Exception { + @Test + public void destructionWithSessionSerializationAndBeanPostProcessor() throws Exception { this.beanFactory.addBeanPostProcessor(new CustomDestructionAwareBeanPostProcessor()); doTestDestructionWithSessionSerialization(false); } - public void testDestructionWithSessionSerializationAndSerializableBeanPostProcessor() throws Exception { + @Test + public void destructionWithSessionSerializationAndSerializableBeanPostProcessor() throws Exception { this.beanFactory.addBeanPostProcessor(new CustomSerializableDestructionAwareBeanPostProcessor()); doTestDestructionWithSessionSerialization(true); } @@ -113,20 +119,15 @@ public class SessionScopeTests extends TestCase { ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes); - try { - String name = "sessionScopedDisposableObject"; - assertNull(session.getAttribute(name)); - DerivedTestBean bean = (DerivedTestBean) this.beanFactory.getBean(name); - assertEquals(session.getAttribute(name), bean); - assertSame(bean, this.beanFactory.getBean(name)); - - requestAttributes.requestCompleted(); - serializedState = session.serializeState(); - assertFalse(bean.wasDestroyed()); - } - finally { - RequestContextHolder.setRequestAttributes(null); - } + String name = "sessionScopedDisposableObject"; + assertNull(session.getAttribute(name)); + DerivedTestBean bean = (DerivedTestBean) this.beanFactory.getBean(name); + assertEquals(session.getAttribute(name), bean); + assertSame(bean, this.beanFactory.getBean(name)); + + requestAttributes.requestCompleted(); + serializedState = session.serializeState(); + assertFalse(bean.wasDestroyed()); serializedState = (Serializable) SerializationTestUtils.serializeAndDeserialize(serializedState); @@ -137,26 +138,21 @@ public class SessionScopeTests extends TestCase { requestAttributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes); - try { - String name = "sessionScopedDisposableObject"; - assertNotNull(session.getAttribute(name)); - DerivedTestBean bean = (DerivedTestBean) this.beanFactory.getBean(name); - assertEquals(session.getAttribute(name), bean); - assertSame(bean, this.beanFactory.getBean(name)); - - requestAttributes.requestCompleted(); - session.invalidate(); - assertTrue(bean.wasDestroyed()); - - if (beanNameReset) { - assertNull(bean.getBeanName()); - } - else { - assertNotNull(bean.getBeanName()); - } + name = "sessionScopedDisposableObject"; + assertNotNull(session.getAttribute(name)); + bean = (DerivedTestBean) this.beanFactory.getBean(name); + assertEquals(session.getAttribute(name), bean); + assertSame(bean, this.beanFactory.getBean(name)); + + requestAttributes.requestCompleted(); + session.invalidate(); + assertTrue(bean.wasDestroyed()); + + if (beanNameReset) { + assertNull(bean.getBeanName()); } - finally { - RequestContextHolder.setRequestAttributes(null); + else { + assertNotNull(bean.getBeanName()); } } diff --git a/spring-web/src/test/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequestTests.java b/spring-web/src/test/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequestTests.java index 16355085..50d84230 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequestTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/async/StandardServletAsyncWebRequestTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -26,13 +26,19 @@ import org.springframework.mock.web.test.MockAsyncContext; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.BDDMockito.mock; +import static org.mockito.BDDMockito.verify; /** * A test fixture with a {@link StandardServletAsyncWebRequest}. - * * @author Rossen Stoyanchev */ public class StandardServletAsyncWebRequestTests { @@ -43,6 +49,7 @@ public class StandardServletAsyncWebRequestTests { private MockHttpServletResponse response; + @Before public void setup() { this.request = new MockHttpServletRequest(); @@ -52,10 +59,10 @@ public class StandardServletAsyncWebRequestTests { this.asyncRequest.setTimeout(44*1000L); } + @Test public void isAsyncStarted() throws Exception { assertFalse(this.asyncRequest.isAsyncStarted()); - this.asyncRequest.startAsync(); assertTrue(this.asyncRequest.isAsyncStarted()); } @@ -64,12 +71,11 @@ public class StandardServletAsyncWebRequestTests { public void startAsync() throws Exception { this.asyncRequest.startAsync(); - MockAsyncContext asyncContext = (MockAsyncContext) this.request.getAsyncContext(); - - assertNotNull(asyncContext); - assertEquals("Timeout value not set", 44 * 1000, asyncContext.getTimeout()); - assertEquals(1, asyncContext.getListeners().size()); - assertSame(this.asyncRequest, asyncContext.getListeners().get(0)); + MockAsyncContext context = (MockAsyncContext) this.request.getAsyncContext(); + assertNotNull(context); + assertEquals("Timeout value not set", 44 * 1000, context.getTimeout()); + assertEquals(1, context.getListeners().size()); + assertSame(this.asyncRequest, context.getListeners().get(0)); } @Test @@ -79,10 +85,9 @@ public class StandardServletAsyncWebRequestTests { this.asyncRequest.startAsync(); this.asyncRequest.startAsync(); // idempotent - MockAsyncContext asyncContext = (MockAsyncContext) this.request.getAsyncContext(); - - assertNotNull(asyncContext); - assertEquals(1, asyncContext.getListeners().size()); + MockAsyncContext context = (MockAsyncContext) this.request.getAsyncContext(); + assertNotNull(context); + assertEquals(1, context.getListeners().size()); } @Test @@ -116,12 +121,10 @@ public class StandardServletAsyncWebRequestTests { } @Test - public void onTimeoutTimeoutHandler() throws Exception { + public void onTimeoutHandler() throws Exception { Runnable timeoutHandler = mock(Runnable.class); - this.asyncRequest.addTimeoutHandler(timeoutHandler); this.asyncRequest.onTimeout(new AsyncEvent(null)); - verify(timeoutHandler).run(); } @@ -131,4 +134,29 @@ public class StandardServletAsyncWebRequestTests { this.asyncRequest.setTimeout(25L); } + @Test + public void onCompletionHandler() throws Exception { + Runnable handler = mock(Runnable.class); + this.asyncRequest.addCompletionHandler(handler); + + this.asyncRequest.startAsync(); + this.asyncRequest.onComplete(new AsyncEvent(null)); + + verify(handler).run(); + assertTrue(this.asyncRequest.isAsyncComplete()); + } + + // SPR-13292 + + @Test + public void onCompletionHandlerAfterOnErrorEvent() throws Exception { + Runnable handler = mock(Runnable.class); + this.asyncRequest.addCompletionHandler(handler); + + this.asyncRequest.startAsync(); + this.asyncRequest.onError(new AsyncEvent(null)); + + verify(handler).run(); + assertTrue(this.asyncRequest.isAsyncComplete()); + } } diff --git a/spring-web/src/test/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContextTests.java b/spring-web/src/test/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContextTests.java index 93e647e8..be74d092 100644 --- a/spring-web/src/test/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContextTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/support/AnnotationConfigWebApplicationContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -34,6 +34,7 @@ import static org.junit.Assert.*; public class AnnotationConfigWebApplicationContextTests { @Test + @SuppressWarnings("resource") public void registerSingleClass() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(Config.class); @@ -44,6 +45,7 @@ public class AnnotationConfigWebApplicationContextTests { } @Test + @SuppressWarnings("resource") public void configLocationWithSingleClass() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.setConfigLocation(Config.class.getName()); @@ -54,6 +56,7 @@ public class AnnotationConfigWebApplicationContextTests { } @Test + @SuppressWarnings("resource") public void configLocationWithBasePackage() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.setConfigLocation("org.springframework.web.context.support"); @@ -64,6 +67,7 @@ public class AnnotationConfigWebApplicationContextTests { } @Test + @SuppressWarnings("resource") public void withBeanNameGenerator() { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.setBeanNameGenerator(new AnnotationBeanNameGenerator() { diff --git a/spring-web/src/test/java/org/springframework/web/cors/CorsConfigurationTests.java b/spring-web/src/test/java/org/springframework/web/cors/CorsConfigurationTests.java new file mode 100644 index 00000000..8d3651c5 --- /dev/null +++ b/spring-web/src/test/java/org/springframework/web/cors/CorsConfigurationTests.java @@ -0,0 +1,219 @@ +/* + * Copyright 2002-2015 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.web.cors; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +import org.junit.Test; + +import org.springframework.http.HttpMethod; + +import static org.junit.Assert.*; + +/** + * Unit tests for {@link CorsConfiguration}. + * + * @author Sebastien Deleuze + * @author Sam Brannen + */ +public class CorsConfigurationTests { + + private CorsConfiguration config = new CorsConfiguration(); + + @Test + public void setNullValues() { + config.setAllowedOrigins(null); + assertNull(config.getAllowedOrigins()); + config.setAllowedHeaders(null); + assertNull(config.getAllowedHeaders()); + config.setAllowedMethods(null); + assertNull(config.getAllowedMethods()); + config.setExposedHeaders(null); + assertNull(config.getExposedHeaders()); + config.setAllowCredentials(null); + assertNull(config.getAllowCredentials()); + config.setMaxAge(null); + assertNull(config.getMaxAge()); + } + + @Test + public void setValues() { + config.addAllowedOrigin("*"); + assertEquals(Arrays.asList("*"), config.getAllowedOrigins()); + config.addAllowedHeader("*"); + assertEquals(Arrays.asList("*"), config.getAllowedHeaders()); + config.addAllowedMethod("*"); + assertEquals(Arrays.asList("*"), config.getAllowedMethods()); + config.addExposedHeader("header1"); + config.addExposedHeader("header2"); + assertEquals(Arrays.asList("header1", "header2"), config.getExposedHeaders()); + config.setAllowCredentials(true); + assertTrue(config.getAllowCredentials()); + config.setMaxAge(123L); + assertEquals(new Long(123), config.getMaxAge()); + } + + @Test(expected = IllegalArgumentException.class) + public void asteriskWildCardOnAddExposedHeader() { + config.addExposedHeader("*"); + } + + @Test(expected = IllegalArgumentException.class) + public void asteriskWildCardOnSetExposedHeaders() { + config.setExposedHeaders(Arrays.asList("*")); + } + + @Test + public void combineWithNull() { + config.setAllowedOrigins(Arrays.asList("*")); + config.combine(null); + assertEquals(Arrays.asList("*"), config.getAllowedOrigins()); + } + + @Test + public void combineWithNullProperties() { + config.addAllowedOrigin("*"); + config.addAllowedHeader("header1"); + config.addExposedHeader("header3"); + config.addAllowedMethod(HttpMethod.GET.name()); + config.setMaxAge(123L); + config.setAllowCredentials(true); + CorsConfiguration other = new CorsConfiguration(); + config = config.combine(other); + assertEquals(Arrays.asList("*"), config.getAllowedOrigins()); + assertEquals(Arrays.asList("header1"), config.getAllowedHeaders()); + assertEquals(Arrays.asList("header3"), config.getExposedHeaders()); + assertEquals(Arrays.asList(HttpMethod.GET.name()), config.getAllowedMethods()); + assertEquals(new Long(123), config.getMaxAge()); + assertTrue(config.getAllowCredentials()); + } + + @Test + public void combineWithAsteriskWildCard() { + config.addAllowedOrigin("*"); + config.addAllowedHeader("*"); + config.addAllowedMethod("*"); + CorsConfiguration other = new CorsConfiguration(); + other.addAllowedOrigin("http://domain.com"); + other.addAllowedHeader("header1"); + other.addExposedHeader("header2"); + other.addAllowedMethod(HttpMethod.PUT.name()); + CorsConfiguration combinedConfig = config.combine(other); + assertEquals(Arrays.asList("http://domain.com"), combinedConfig.getAllowedOrigins()); + assertEquals(Arrays.asList("header1"), combinedConfig.getAllowedHeaders()); + assertEquals(Arrays.asList("header2"), combinedConfig.getExposedHeaders()); + assertEquals(Arrays.asList(HttpMethod.PUT.name()), combinedConfig.getAllowedMethods()); + combinedConfig = other.combine(config); + assertEquals(Arrays.asList("http://domain.com"), combinedConfig.getAllowedOrigins()); + assertEquals(Arrays.asList("header1"), combinedConfig.getAllowedHeaders()); + assertEquals(Arrays.asList("header2"), combinedConfig.getExposedHeaders()); + assertEquals(Arrays.asList(HttpMethod.PUT.name()), combinedConfig.getAllowedMethods()); + } + + @Test + public void combine() { + config.addAllowedOrigin("http://domain1.com"); + config.addAllowedHeader("header1"); + config.addExposedHeader("header3"); + config.addAllowedMethod(HttpMethod.GET.name()); + config.setMaxAge(123L); + config.setAllowCredentials(true); + CorsConfiguration other = new CorsConfiguration(); + other.addAllowedOrigin("http://domain2.com"); + other.addAllowedHeader("header2"); + other.addExposedHeader("header4"); + other.addAllowedMethod(HttpMethod.PUT.name()); + other.setMaxAge(456L); + other.setAllowCredentials(false); + config = config.combine(other); + assertEquals(Arrays.asList("http://domain1.com", "http://domain2.com"), config.getAllowedOrigins()); + assertEquals(Arrays.asList("header1", "header2"), config.getAllowedHeaders()); + assertEquals(Arrays.asList("header3", "header4"), config.getExposedHeaders()); + assertEquals(Arrays.asList(HttpMethod.GET.name(), HttpMethod.PUT.name()), config.getAllowedMethods()); + assertEquals(new Long(456), config.getMaxAge()); + assertFalse(config.getAllowCredentials()); + } + + @Test + public void checkOriginAllowed() { + config.setAllowedOrigins(Arrays.asList("*")); + assertEquals("*", config.checkOrigin("http://domain.com")); + config.setAllowCredentials(true); + assertEquals("http://domain.com", config.checkOrigin("http://domain.com")); + config.setAllowedOrigins(Arrays.asList("http://domain.com")); + assertEquals("http://domain.com", config.checkOrigin("http://domain.com")); + config.setAllowCredentials(false); + assertEquals("http://domain.com", config.checkOrigin("http://domain.com")); + } + + @Test + public void checkOriginNotAllowed() { + assertNull(config.checkOrigin(null)); + assertNull(config.checkOrigin("http://domain.com")); + config.addAllowedOrigin("*"); + assertNull(config.checkOrigin(null)); + config.setAllowedOrigins(Arrays.asList("http://domain1.com")); + assertNull(config.checkOrigin("http://domain2.com")); + config.setAllowedOrigins(new ArrayList<>()); + assertNull(config.checkOrigin("http://domain.com")); + } + + @Test + public void checkMethodAllowed() { + assertEquals(Arrays.asList(HttpMethod.GET), config.checkHttpMethod(HttpMethod.GET)); + config.addAllowedMethod("GET"); + assertEquals(Arrays.asList(HttpMethod.GET), config.checkHttpMethod(HttpMethod.GET)); + config.addAllowedMethod("POST"); + assertEquals(Arrays.asList(HttpMethod.GET, HttpMethod.POST), config.checkHttpMethod(HttpMethod.GET)); + assertEquals(Arrays.asList(HttpMethod.GET, HttpMethod.POST), config.checkHttpMethod(HttpMethod.POST)); + } + + @Test + public void checkMethodNotAllowed() { + assertNull(config.checkHttpMethod(null)); + assertNull(config.checkHttpMethod(HttpMethod.DELETE)); + config.setAllowedMethods(new ArrayList<>()); + assertNull(config.checkHttpMethod(HttpMethod.HEAD)); + } + + @Test + public void checkHeadersAllowed() { + assertEquals(Collections.emptyList(), config.checkHeaders(Collections.emptyList())); + config.addAllowedHeader("header1"); + config.addAllowedHeader("header2"); + assertEquals(Arrays.asList("header1"), config.checkHeaders(Arrays.asList("header1"))); + assertEquals(Arrays.asList("header1", "header2"), config.checkHeaders(Arrays.asList("header1", "header2"))); + assertEquals(Arrays.asList("header1", "header2"), config.checkHeaders(Arrays.asList("header1", "header2", "header3"))); + } + + @Test + public void checkHeadersNotAllowed() { + assertNull(config.checkHeaders(null)); + + assertNull(config.checkHeaders(Arrays.asList("header1"))); + + config.setAllowedHeaders(Collections.emptyList()); + assertNull(config.checkHeaders(Arrays.asList("header1"))); + + config.addAllowedHeader("header2"); + config.addAllowedHeader("header3"); + assertNull(config.checkHeaders(Arrays.asList("header1"))); + } + +} diff --git a/spring-web/src/test/java/org/springframework/web/cors/CorsUtilsTests.java b/spring-web/src/test/java/org/springframework/web/cors/CorsUtilsTests.java new file mode 100644 index 00000000..4174cb2a --- /dev/null +++ b/spring-web/src/test/java/org/springframework/web/cors/CorsUtilsTests.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002-2015 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.web.cors; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.mock.web.test.MockHttpServletRequest; + +/** + * Test case for {@link CorsUtils}. + * + * @author Sebastien Deleuze + */ +public class CorsUtilsTests { + + @Test + public void isCorsRequest() { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader(HttpHeaders.ORIGIN, "http://domain.com"); + assertTrue(CorsUtils.isCorsRequest(request)); + } + + @Test + public void isNotCorsRequest() { + MockHttpServletRequest request = new MockHttpServletRequest(); + assertFalse(CorsUtils.isCorsRequest(request)); + } + + @Test + public void isPreFlightRequest() { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod(HttpMethod.OPTIONS.name()); + request.addHeader(HttpHeaders.ORIGIN, "http://domain.com"); + request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + assertTrue(CorsUtils.isPreFlightRequest(request)); + } + + @Test + public void isNotPreFlightRequest() { + MockHttpServletRequest request = new MockHttpServletRequest(); + assertFalse(CorsUtils.isPreFlightRequest(request)); + + request = new MockHttpServletRequest(); + request.setMethod(HttpMethod.OPTIONS.name()); + request.addHeader(HttpHeaders.ORIGIN, "http://domain.com"); + assertFalse(CorsUtils.isPreFlightRequest(request)); + + request = new MockHttpServletRequest(); + request.setMethod(HttpMethod.OPTIONS.name()); + request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + assertFalse(CorsUtils.isPreFlightRequest(request)); + } + +} diff --git a/spring-web/src/test/java/org/springframework/web/cors/DefaultCorsProcessorTests.java b/spring-web/src/test/java/org/springframework/web/cors/DefaultCorsProcessorTests.java new file mode 100644 index 00000000..56ab6166 --- /dev/null +++ b/spring-web/src/test/java/org/springframework/web/cors/DefaultCorsProcessorTests.java @@ -0,0 +1,310 @@ +/* + * Copyright 2002-2015 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.web.cors; + +import org.junit.Before; +import org.junit.Test; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.mock.web.test.MockHttpServletRequest; +import org.springframework.mock.web.test.MockHttpServletResponse; + +import javax.servlet.http.HttpServletResponse; + +import static org.junit.Assert.*; + +/** + * Test {@link DefaultCorsProcessor} with simple or preflight CORS request. + * + * @author Sebastien Deleuze + * @author Rossen Stoyanchev + */ +public class DefaultCorsProcessorTests { + + private MockHttpServletRequest request; + + private MockHttpServletResponse response; + + private DefaultCorsProcessor processor; + + private CorsConfiguration conf; + + + @Before + public void setup() { + this.request = new MockHttpServletRequest(); + this.request.setRequestURI("/test.html"); + this.request.setRemoteHost("domain1.com"); + this.conf = new CorsConfiguration(); + this.response = new MockHttpServletResponse(); + this.response.setStatus(HttpServletResponse.SC_OK); + this.processor = new DefaultCorsProcessor(); + } + + @Test + public void actualRequestWithOriginHeader() throws Exception { + this.request.setMethod(HttpMethod.GET.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.processor.processRequest(this.conf, request, response); + assertFalse(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); + } + + @Test + public void actualRequestWithOriginHeaderAndNullConfig() throws Exception { + this.request.setMethod(HttpMethod.GET.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.processor.processRequest(null, request, response); + assertFalse(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void actualRequestWithOriginHeaderAndAllowedOrigin() throws Exception { + this.request.setMethod(HttpMethod.GET.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.conf.addAllowedOrigin("*"); + this.processor.processRequest(this.conf, request, response); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals("*", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertFalse(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE)); + assertFalse(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS)); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void actualRequestCredentials() throws Exception { + this.request.setMethod(HttpMethod.GET.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.conf.addAllowedOrigin("http://domain1.com"); + this.conf.addAllowedOrigin("http://domain2.com"); + this.conf.addAllowedOrigin("http://domain3.com"); + this.conf.setAllowCredentials(true); + this.processor.processRequest(this.conf, request, response); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals("http://domain2.com", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)); + assertEquals("true", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void actualRequestCredentialsWithOriginWildcard() throws Exception { + this.request.setMethod(HttpMethod.GET.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.conf.addAllowedOrigin("*"); + this.conf.setAllowCredentials(true); + this.processor.processRequest(this.conf, request, response); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals("http://domain2.com", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)); + assertEquals("true", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void actualRequestCaseInsensitiveOriginMatch() throws Exception { + this.request.setMethod(HttpMethod.GET.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.conf.addAllowedOrigin("http://DOMAIN2.com"); + this.processor.processRequest(this.conf, request, response); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void actualRequestExposedHeaders() throws Exception { + this.request.setMethod(HttpMethod.GET.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.conf.addExposedHeader("header1"); + this.conf.addExposedHeader("header2"); + this.conf.addAllowedOrigin("http://domain2.com"); + this.processor.processRequest(this.conf, request, response); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals("http://domain2.com", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS)); + assertTrue(this.response.getHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS).contains("header1")); + assertTrue(this.response.getHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS).contains("header2")); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void preflightRequestAllOriginsAllowed() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + this.conf.addAllowedOrigin("*"); + this.processor.processRequest(this.conf, request, response); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void preflightRequestWrongAllowedMethod() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "DELETE"); + this.conf.addAllowedOrigin("*"); + this.processor.processRequest(this.conf, request, response); + assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); + } + + @Test + public void preflightRequestMatchedAllowedMethod() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + this.conf.addAllowedOrigin("*"); + this.processor.processRequest(this.conf, request, response); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + assertEquals("GET", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS)); + } + + @Test + public void preflightRequestTestWithOriginButWithoutOtherHeaders() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.processor.processRequest(this.conf, request, response); + assertFalse(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); + } + + @Test + public void preflightRequestWithoutRequestMethod() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Header1"); + this.processor.processRequest(this.conf, request, response); + assertFalse(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); + } + + @Test + public void preflightRequestWithRequestAndMethodHeaderButNoConfig() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Header1"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + this.processor.processRequest(this.conf, request, response); + assertFalse(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); + } + + @Test + public void preflightRequestValidRequestAndConfig() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Header1"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + this.conf.addAllowedOrigin("*"); + this.conf.addAllowedMethod("GET"); + this.conf.addAllowedMethod("PUT"); + this.conf.addAllowedHeader("header1"); + this.conf.addAllowedHeader("header2"); + this.processor.processRequest(this.conf, request, response); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals("*", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS)); + assertEquals("GET,PUT", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS)); + assertFalse(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE)); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void preflightRequestCredentials() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Header1"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + this.conf.addAllowedOrigin("http://domain1.com"); + this.conf.addAllowedOrigin("http://domain2.com"); + this.conf.addAllowedOrigin("http://domain3.com"); + this.conf.addAllowedHeader("Header1"); + this.conf.setAllowCredentials(true); + this.processor.processRequest(this.conf, request, response); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals("http://domain2.com", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)); + assertEquals("true", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void preflightRequestCredentialsWithOriginWildcard() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Header1"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + this.conf.addAllowedOrigin("http://domain1.com"); + this.conf.addAllowedOrigin("*"); + this.conf.addAllowedOrigin("http://domain3.com"); + this.conf.addAllowedHeader("Header1"); + this.conf.setAllowCredentials(true); + this.processor.processRequest(this.conf, request, response); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals("http://domain2.com", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void preflightRequestAllowedHeaders() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Header1, Header2"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + this.conf.addAllowedHeader("Header1"); + this.conf.addAllowedHeader("Header2"); + this.conf.addAllowedHeader("Header3"); + this.conf.addAllowedOrigin("http://domain2.com"); + this.processor.processRequest(this.conf, request, response); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS)); + assertTrue(this.response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS).contains("Header1")); + assertTrue(this.response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS).contains("Header2")); + assertFalse(this.response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS).contains("Header3")); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void preflightRequestAllowsAllHeaders() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "Header1, Header2"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + this.conf.addAllowedHeader("*"); + this.conf.addAllowedOrigin("http://domain2.com"); + this.processor.processRequest(this.conf, request, response); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertTrue(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS)); + assertTrue(this.response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS).contains("Header1")); + assertTrue(this.response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS).contains("Header2")); + assertFalse(this.response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS).contains("*")); + assertEquals(HttpServletResponse.SC_OK, response.getStatus()); + } + + @Test + public void preflightRequestWithNullConfig() throws Exception { + this.request.setMethod(HttpMethod.OPTIONS.name()); + this.request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + this.request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, "GET"); + this.conf.addAllowedOrigin("*"); + this.processor.processRequest(null, request, response); + assertFalse(this.response.containsHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); + } + +}
\ No newline at end of file diff --git a/spring-web/src/test/java/org/springframework/web/cors/UrlBasedCorsConfigurationSourceTests.java b/spring-web/src/test/java/org/springframework/web/cors/UrlBasedCorsConfigurationSourceTests.java new file mode 100644 index 00000000..2d6aaa49 --- /dev/null +++ b/spring-web/src/test/java/org/springframework/web/cors/UrlBasedCorsConfigurationSourceTests.java @@ -0,0 +1,51 @@ +/* + * Copyright 2002-2015 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.web.cors; + +import static org.junit.Assert.*; +import org.junit.Test; + +import org.springframework.http.HttpMethod; +import org.springframework.mock.web.test.MockHttpServletRequest; + +/** + * Unit tests for {@link UrlBasedCorsConfigurationSource}. + * @author Sebastien Deleuze + */ +public class UrlBasedCorsConfigurationSourceTests { + + private final UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); + + @Test + public void empty() { + assertNull(this.configSource.getCorsConfiguration(new MockHttpServletRequest(HttpMethod.GET.name(), "/bar/test.html"))); + } + + @Test + public void registerAndMatch() { + CorsConfiguration config = new CorsConfiguration(); + this.configSource.registerCorsConfiguration("/bar/**", config); + assertNull(this.configSource.getCorsConfiguration(new MockHttpServletRequest(HttpMethod.GET.name(), "/foo/test.html"))); + assertEquals(config, this.configSource.getCorsConfiguration(new MockHttpServletRequest(HttpMethod.GET.name(), "/bar/test.html"))); + } + + @Test(expected = UnsupportedOperationException.class) + public void unmodifiableConfigurationsMap() { + this.configSource.getCorsConfigurations().put("/**", new CorsConfiguration()); + } + +} diff --git a/spring-web/src/test/java/org/springframework/web/filter/CharacterEncodingFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/CharacterEncodingFilterTests.java index 6091fa6a..64392f91 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/CharacterEncodingFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/CharacterEncodingFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -20,7 +20,7 @@ import javax.servlet.FilterChain; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import junit.framework.TestCase; +import org.junit.Test; import org.springframework.mock.web.test.MockFilterConfig; import org.springframework.mock.web.test.MockHttpServletResponse; @@ -32,15 +32,17 @@ import static org.mockito.BDDMockito.*; /** * @author Rick Evans * @author Juergen Hoeller + * @author Vedran Pavic */ -public class CharacterEncodingFilterTests extends TestCase { +public class CharacterEncodingFilterTests { private static final String FILTER_NAME = "boot"; private static final String ENCODING = "UTF-8"; - public void testForceAlwaysSetsEncoding() throws Exception { + @Test + public void forceEncodingAlwaysSetsEncoding() throws Exception { HttpServletRequest request = mock(HttpServletRequest.class); request.setCharacterEncoding(ENCODING); given(request.getAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE)).willReturn(null); @@ -49,9 +51,7 @@ public class CharacterEncodingFilterTests extends TestCase { HttpServletResponse response = mock(HttpServletResponse.class); FilterChain filterChain = mock(FilterChain.class); - CharacterEncodingFilter filter = new CharacterEncodingFilter(); - filter.setForceEncoding(true); - filter.setEncoding(ENCODING); + CharacterEncodingFilter filter = new CharacterEncodingFilter(ENCODING, true); filter.init(new MockFilterConfig(FILTER_NAME)); filter.doFilter(request, response, filterChain); @@ -61,7 +61,8 @@ public class CharacterEncodingFilterTests extends TestCase { verify(filterChain).doFilter(request, response); } - public void testEncodingIfEmptyAndNotForced() throws Exception { + @Test + public void encodingIfEmptyAndNotForced() throws Exception { HttpServletRequest request = mock(HttpServletRequest.class); given(request.getCharacterEncoding()).willReturn(null); given(request.getAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE)).willReturn(null); @@ -71,9 +72,7 @@ public class CharacterEncodingFilterTests extends TestCase { FilterChain filterChain = mock(FilterChain.class); - CharacterEncodingFilter filter = new CharacterEncodingFilter(); - filter.setForceEncoding(false); - filter.setEncoding(ENCODING); + CharacterEncodingFilter filter = new CharacterEncodingFilter(ENCODING); filter.init(new MockFilterConfig(FILTER_NAME)); filter.doFilter(request, response, filterChain); @@ -83,7 +82,8 @@ public class CharacterEncodingFilterTests extends TestCase { verify(filterChain).doFilter(request, response); } - public void testDoesNowtIfEncodingIsNotEmptyAndNotForced() throws Exception { + @Test + public void doesNotIfEncodingIsNotEmptyAndNotForced() throws Exception { HttpServletRequest request = mock(HttpServletRequest.class); given(request.getCharacterEncoding()).willReturn(ENCODING); given(request.getAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE)).willReturn(null); @@ -93,8 +93,7 @@ public class CharacterEncodingFilterTests extends TestCase { FilterChain filterChain = mock(FilterChain.class); - CharacterEncodingFilter filter = new CharacterEncodingFilter(); - filter.setEncoding(ENCODING); + CharacterEncodingFilter filter = new CharacterEncodingFilter(ENCODING); filter.init(new MockFilterConfig(FILTER_NAME)); filter.doFilter(request, response, filterChain); @@ -103,7 +102,8 @@ public class CharacterEncodingFilterTests extends TestCase { verify(filterChain).doFilter(request, response); } - public void testWithBeanInitialization() throws Exception { + @Test + public void withBeanInitialization() throws Exception { HttpServletRequest request = mock(HttpServletRequest.class); given(request.getCharacterEncoding()).willReturn(null); given(request.getAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE)).willReturn(null); @@ -125,7 +125,8 @@ public class CharacterEncodingFilterTests extends TestCase { verify(filterChain).doFilter(request, response); } - public void testWithIncompleteInitialization() throws Exception { + @Test + public void withIncompleteInitialization() throws Exception { HttpServletRequest request = mock(HttpServletRequest.class); given(request.getCharacterEncoding()).willReturn(null); given(request.getAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE)).willReturn(null); @@ -135,8 +136,7 @@ public class CharacterEncodingFilterTests extends TestCase { FilterChain filterChain = mock(FilterChain.class); - CharacterEncodingFilter filter = new CharacterEncodingFilter(); - filter.setEncoding(ENCODING); + CharacterEncodingFilter filter = new CharacterEncodingFilter(ENCODING); filter.doFilter(request, response, filterChain); verify(request).setCharacterEncoding(ENCODING); @@ -144,4 +144,5 @@ public class CharacterEncodingFilterTests extends TestCase { verify(request).removeAttribute(CharacterEncodingFilter.class.getName() + OncePerRequestFilter.ALREADY_FILTERED_SUFFIX); verify(filterChain).doFilter(request, response); } + } diff --git a/spring-web/src/test/java/org/springframework/web/filter/CompositeFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/CompositeFilterTests.java index 75a2eae1..fc1d3e5f 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/CompositeFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/CompositeFilterTests.java @@ -1,6 +1,5 @@ /* - * Copyright 2004, 2005 Acegi Technology Pty Limited - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -44,9 +43,7 @@ public class CompositeFilterTests { @Test public void testCompositeFilter() throws ServletException, IOException { ServletContext sc = new MockServletContext(); - MockFilter targetFilter = new MockFilter(); - MockFilterConfig proxyConfig = new MockFilterConfig(sc); CompositeFilter filterProxy = new CompositeFilter(); @@ -75,7 +72,7 @@ public class CompositeFilterTests { } @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) { request.setAttribute("called", Boolean.TRUE); } diff --git a/spring-web/src/test/java/org/springframework/web/filter/CorsFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/CorsFilterTests.java new file mode 100644 index 00000000..59450108 --- /dev/null +++ b/spring-web/src/test/java/org/springframework/web/filter/CorsFilterTests.java @@ -0,0 +1,120 @@ +/* + * Copyright 2002-2015 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.web.filter; + +import java.io.IOException; +import java.util.Arrays; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; + +import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.mock.web.test.MockHttpServletRequest; +import org.springframework.mock.web.test.MockHttpServletResponse; +import org.springframework.web.cors.CorsConfiguration; + +/** + * Unit tests for {@link CorsFilter}. + * @author Sebastien Deleuze + */ +public class CorsFilterTests { + + private CorsFilter filter; + + private final CorsConfiguration config = new CorsConfiguration(); + + @Before + public void setup() throws Exception { + config.setAllowedOrigins(Arrays.asList("http://domain1.com", "http://domain2.com")); + config.setAllowedMethods(Arrays.asList("GET", "POST")); + config.setAllowedHeaders(Arrays.asList("header1", "header2")); + config.setExposedHeaders(Arrays.asList("header3", "header4")); + config.setMaxAge(123L); + config.setAllowCredentials(false); + filter = new CorsFilter(r -> config); + } + + @Test + public void validActualRequest() throws ServletException, IOException { + + MockHttpServletRequest request = new MockHttpServletRequest(HttpMethod.GET.name(), "/test.html"); + request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + request.addHeader("header2", "foo"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + FilterChain filterChain = (filterRequest, filterResponse) -> { + assertEquals("http://domain2.com", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals("header3, header4", response.getHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS)); + }; + filter.doFilter(request, response, filterChain); + } + + @Test + public void invalidActualRequest() throws ServletException, IOException { + + MockHttpServletRequest request = new MockHttpServletRequest(HttpMethod.DELETE.name(), "/test.html"); + request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + request.addHeader("header2", "foo"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + FilterChain filterChain = (filterRequest, filterResponse) -> { + fail("Invalid requests must not be forwarded to the filter chain"); + }; + filter.doFilter(request, response, filterChain); + assertNull(response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + } + + @Test + public void validPreFlightRequest() throws ServletException, IOException { + + MockHttpServletRequest request = new MockHttpServletRequest(HttpMethod.OPTIONS.name(), "/test.html"); + request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.GET.name()); + request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "header1, header2"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + FilterChain filterChain = (filterRequest, filterResponse) -> + fail("Preflight requests must not be forwarded to the filter chain"); + filter.doFilter(request, response, filterChain); + + assertEquals("http://domain2.com", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + assertEquals("header1, header2", response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS)); + assertEquals("header3, header4", response.getHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS)); + assertEquals(123L, Long.parseLong(response.getHeader(HttpHeaders.ACCESS_CONTROL_MAX_AGE))); + } + + @Test + public void invalidPreFlightRequest() throws ServletException, IOException { + + MockHttpServletRequest request = new MockHttpServletRequest(HttpMethod.OPTIONS.name(), "/test.html"); + request.addHeader(HttpHeaders.ORIGIN, "http://domain2.com"); + request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.DELETE.name()); + request.addHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "header1, header2"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + FilterChain filterChain = (filterRequest, filterResponse) -> + fail("Preflight requests must not be forwarded to the filter chain"); + filter.doFilter(request, response, filterChain); + + assertNull(response.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)); + } + +} diff --git a/spring-web/src/test/java/org/springframework/web/filter/DelegatingFilterProxyTests.java b/spring-web/src/test/java/org/springframework/web/filter/DelegatingFilterProxyTests.java index e68581d0..8dc67241 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/DelegatingFilterProxyTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/DelegatingFilterProxyTests.java @@ -1,6 +1,5 @@ /* - * Copyright 2004, 2005 Acegi Technology Pty Limited - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -40,6 +39,7 @@ import static org.junit.Assert.*; /** * @author Juergen Hoeller * @author Chris Beams + * @author Rob Winch * @since 08.05.2005 */ public class DelegatingFilterProxyTests { @@ -268,6 +268,128 @@ public class DelegatingFilterProxyTests { assertNull(targetFilter.filterConfig); } + @Test + public void testDelegatingFilterProxyWithFrameworkServletContext() throws ServletException, IOException { + ServletContext sc = new MockServletContext(); + StaticWebApplicationContext wac = new StaticWebApplicationContext(); + wac.setServletContext(sc); + wac.registerSingleton("targetFilter", MockFilter.class); + wac.refresh(); + sc.setAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher", wac); + + MockFilter targetFilter = (MockFilter) wac.getBean("targetFilter"); + + MockFilterConfig proxyConfig = new MockFilterConfig(sc); + proxyConfig.addInitParameter("targetBeanName", "targetFilter"); + DelegatingFilterProxy filterProxy = new DelegatingFilterProxy(); + filterProxy.init(proxyConfig); + + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + filterProxy.doFilter(request, response, null); + + assertNull(targetFilter.filterConfig); + assertEquals(Boolean.TRUE, request.getAttribute("called")); + + filterProxy.destroy(); + assertNull(targetFilter.filterConfig); + } + + @Test + public void testDelegatingFilterProxyInjectedPreferred() throws ServletException, IOException { + ServletContext sc = new MockServletContext(); + StaticWebApplicationContext wac = new StaticWebApplicationContext(); + wac.setServletContext(sc); + wac.refresh(); + sc.setAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher", wac); + + StaticWebApplicationContext injectedWac = new StaticWebApplicationContext(); + injectedWac.setServletContext(sc); + String beanName = "targetFilter"; + injectedWac.registerSingleton(beanName, MockFilter.class); + injectedWac.refresh(); + + MockFilter targetFilter = (MockFilter) injectedWac.getBean(beanName); + + DelegatingFilterProxy filterProxy = new DelegatingFilterProxy(beanName, injectedWac); + + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + filterProxy.doFilter(request, response, null); + + assertNull(targetFilter.filterConfig); + assertEquals(Boolean.TRUE, request.getAttribute("called")); + + filterProxy.destroy(); + assertNull(targetFilter.filterConfig); + } + + @Test + public void testDelegatingFilterProxyNotInjectedWacServletAttrPreferred() throws ServletException, IOException { + ServletContext sc = new MockServletContext(); + StaticWebApplicationContext wac = new StaticWebApplicationContext(); + wac.setServletContext(sc); + wac.refresh(); + sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac); + sc.setAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher", wac); + + StaticWebApplicationContext wacToUse = new StaticWebApplicationContext(); + wacToUse.setServletContext(sc); + String beanName = "targetFilter"; + String attrName = "customAttrName"; + wacToUse.registerSingleton(beanName, MockFilter.class); + wacToUse.refresh(); + sc.setAttribute(attrName, wacToUse); + + MockFilter targetFilter = (MockFilter) wacToUse.getBean(beanName); + + DelegatingFilterProxy filterProxy = new DelegatingFilterProxy(beanName); + filterProxy.setContextAttribute(attrName); + filterProxy.setServletContext(sc); + + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + filterProxy.doFilter(request, response, null); + + assertNull(targetFilter.filterConfig); + assertEquals(Boolean.TRUE, request.getAttribute("called")); + + filterProxy.destroy(); + assertNull(targetFilter.filterConfig); + } + + @Test + public void testDelegatingFilterProxyNotInjectedWithRootPreferred() throws ServletException, IOException { + ServletContext sc = new MockServletContext(); + StaticWebApplicationContext wac = new StaticWebApplicationContext(); + wac.setServletContext(sc); + wac.refresh(); + sc.setAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher", wac); + sc.setAttribute("another", wac); + + StaticWebApplicationContext wacToUse = new StaticWebApplicationContext(); + wacToUse.setServletContext(sc); + String beanName = "targetFilter"; + wacToUse.registerSingleton(beanName, MockFilter.class); + wacToUse.refresh(); + sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wacToUse); + + MockFilter targetFilter = (MockFilter) wacToUse.getBean(beanName); + + DelegatingFilterProxy filterProxy = new DelegatingFilterProxy(beanName); + filterProxy.setServletContext(sc); + + MockHttpServletRequest request = new MockHttpServletRequest(); + MockHttpServletResponse response = new MockHttpServletResponse(); + filterProxy.doFilter(request, response, null); + + assertNull(targetFilter.filterConfig); + assertEquals(Boolean.TRUE, request.getAttribute("called")); + + filterProxy.destroy(); + assertNull(targetFilter.filterConfig); + } + public static class MockFilter implements Filter { diff --git a/spring-web/src/test/java/org/springframework/web/filter/RequestContextFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/RequestContextFilterTests.java index 5e303c7e..677a7e79 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/RequestContextFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/RequestContextFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -17,12 +17,13 @@ package org.springframework.web.filter; import java.io.IOException; + import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import junit.framework.TestCase; +import org.junit.Test; import org.springframework.mock.web.test.MockFilterConfig; import org.springframework.mock.web.test.MockHttpServletRequest; @@ -31,21 +32,25 @@ import org.springframework.mock.web.test.MockServletContext; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; +import static org.junit.Assert.*; + /** * @author Rod Johnson * @author Juergen Hoeller */ -public class RequestContextFilterTests extends TestCase { +public class RequestContextFilterTests { - public void testHappyPath() throws Exception { + @Test + public void happyPath() throws Exception { testFilterInvocation(null); } - public void testWithException() throws Exception { + @Test + public void withException() throws Exception { testFilterInvocation(new ServletException()); } - public void testFilterInvocation(final ServletException sex) throws Exception { + private void testFilterInvocation(final ServletException sex) throws Exception { final MockHttpServletRequest req = new MockHttpServletRequest(); req.setAttribute("myAttr", "myValue"); final MockHttpServletResponse resp = new MockHttpServletResponse(); diff --git a/spring-web/src/test/java/org/springframework/web/filter/RequestLoggingFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/RequestLoggingFilterTests.java index ea9a3344..5a179e72 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/RequestLoggingFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/RequestLoggingFilterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * 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. @@ -24,7 +24,6 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.test.MockHttpServletRequest; @@ -34,19 +33,14 @@ import org.springframework.util.FileCopyUtils; import static org.junit.Assert.*; /** - * Test for {@link AbstractRequestLoggingFilter} and sub classes. + * Test for {@link AbstractRequestLoggingFilter} and subclasses. * * @author Arjen Poutsma + * @author Juergen Hoeller */ public class RequestLoggingFilterTests { - private MyRequestLoggingFilter filter; - - - @Before - public void createFilter() throws Exception { - filter = new MyRequestLoggingFilter(); - } + private final MyRequestLoggingFilter filter = new MyRequestLoggingFilter(); @Test @@ -70,23 +64,39 @@ public class RequestLoggingFilterTests { } @Test - public void queryString() throws Exception { + public void queryStringIncluded() throws Exception { filter.setIncludeQueryString(true); - final MockHttpServletRequest request = new MockHttpServletRequest("POST", "/hotels"); + MockHttpServletRequest request = new MockHttpServletRequest("POST", "/hotels"); MockHttpServletResponse response = new MockHttpServletResponse(); request.setQueryString("booking=42"); FilterChain filterChain = new NoOpFilterChain(); + filter.doFilter(request, response, filterChain); + + assertNotNull(filter.beforeRequestMessage); + assertTrue(filter.beforeRequestMessage.contains("[uri=/hotels?booking=42]")); + + assertNotNull(filter.afterRequestMessage); + assertTrue(filter.afterRequestMessage.contains("[uri=/hotels?booking=42]")); + } + + @Test + public void noQueryStringAvailable() throws Exception { + filter.setIncludeQueryString(true); + + MockHttpServletRequest request = new MockHttpServletRequest("POST", "/hotels"); + MockHttpServletResponse response = new MockHttpServletResponse(); + FilterChain filterChain = new NoOpFilterChain(); filter.doFilter(request, response, filterChain); assertNotNull(filter.beforeRequestMessage); - assertTrue(filter.beforeRequestMessage.contains("uri=/hotels?booking=42")); + assertTrue(filter.beforeRequestMessage.contains("[uri=/hotels]")); assertNotNull(filter.afterRequestMessage); - assertTrue(filter.afterRequestMessage.contains("uri=/hotels?booking=42")); + assertTrue(filter.afterRequestMessage.contains("[uri=/hotels]")); } @Test @@ -98,8 +108,8 @@ public class RequestLoggingFilterTests { final byte[] requestBody = "Hello World".getBytes("UTF-8"); request.setContent(requestBody); - FilterChain filterChain = new FilterChain() { + FilterChain filterChain = new FilterChain() { @Override public void doFilter(ServletRequest filterRequest, ServletResponse filterResponse) throws IOException, ServletException { @@ -124,8 +134,8 @@ public class RequestLoggingFilterTests { final String requestBody = "Hello World"; request.setContent(requestBody.getBytes("UTF-8")); - FilterChain filterChain = new FilterChain() { + FilterChain filterChain = new FilterChain() { @Override public void doFilter(ServletRequest filterRequest, ServletResponse filterResponse) throws IOException, ServletException { @@ -151,8 +161,8 @@ public class RequestLoggingFilterTests { final byte[] requestBody = "Hello World".getBytes("UTF-8"); request.setContent(requestBody); - FilterChain filterChain = new FilterChain() { + FilterChain filterChain = new FilterChain() { @Override public void doFilter(ServletRequest filterRequest, ServletResponse filterResponse) throws IOException, ServletException { diff --git a/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java index b573a06d..0c5af485 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java @@ -16,19 +16,15 @@ package org.springframework.web.filter; -import java.io.IOException; import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; -import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; import org.springframework.util.FileCopyUtils; +import org.springframework.util.StreamUtils; import static org.junit.Assert.*; @@ -39,27 +35,23 @@ import static org.junit.Assert.*; */ public class ShallowEtagHeaderFilterTests { - private ShallowEtagHeaderFilter filter; + private final ShallowEtagHeaderFilter filter = new ShallowEtagHeaderFilter(); - @Before - public void createFilter() throws Exception { - filter = new ShallowEtagHeaderFilter(); - } @Test public void isEligibleForEtag() { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels"); MockHttpServletResponse response = new MockHttpServletResponse(); - assertTrue(filter.isEligibleForEtag(request, response, 200, new byte[0])); - assertFalse(filter.isEligibleForEtag(request, response, 300, new byte[0])); + assertTrue(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput())); + assertFalse(filter.isEligibleForEtag(request, response, 300, StreamUtils.emptyInput())); request = new MockHttpServletRequest("POST", "/hotels"); - assertFalse(filter.isEligibleForEtag(request, response, 200, new byte[0])); + assertFalse(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput())); request = new MockHttpServletRequest("POST", "/hotels"); - request.addHeader("Cache-Control", "must-revalidate, no-store"); - assertFalse(filter.isEligibleForEtag(request, response, 200, new byte[0])); + request.addHeader("Cache-Control","must-revalidate, no-store"); + assertFalse(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput())); } @Test @@ -68,14 +60,10 @@ public class ShallowEtagHeaderFilterTests { MockHttpServletResponse response = new MockHttpServletResponse(); final byte[] responseBody = "Hello World".getBytes("UTF-8"); - FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest filterRequest, ServletResponse filterResponse) - throws IOException, ServletException { - assertEquals("Invalid request passed", request, filterRequest); - ((HttpServletResponse) filterResponse).setStatus(HttpServletResponse.SC_OK); - FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); - } + FilterChain filterChain = (filterRequest, filterResponse) -> { + assertEquals("Invalid request passed", request, filterRequest); + ((HttpServletResponse) filterResponse).setStatus(HttpServletResponse.SC_OK); + FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); }; filter.doFilter(request, response, filterChain); @@ -92,15 +80,11 @@ public class ShallowEtagHeaderFilterTests { request.addHeader("If-None-Match", etag); MockHttpServletResponse response = new MockHttpServletResponse(); - FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest filterRequest, ServletResponse filterResponse) - throws IOException, ServletException { - assertEquals("Invalid request passed", request, filterRequest); - byte[] responseBody = "Hello World".getBytes("UTF-8"); - FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); - filterResponse.setContentLength(responseBody.length); - } + FilterChain filterChain = (filterRequest, filterResponse) -> { + assertEquals("Invalid request passed", request, filterRequest); + byte[] responseBody = "Hello World".getBytes("UTF-8"); + FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); + filterResponse.setContentLength(responseBody.length); }; filter.doFilter(request, response, filterChain); @@ -117,15 +101,11 @@ public class ShallowEtagHeaderFilterTests { request.addHeader("If-None-Match", etag); MockHttpServletResponse response = new MockHttpServletResponse(); - FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest filterRequest, ServletResponse filterResponse) - throws IOException, ServletException { - assertEquals("Invalid request passed", request, filterRequest); - ((HttpServletResponse) filterResponse).setStatus(HttpServletResponse.SC_OK); - String responseBody = "Hello World"; - FileCopyUtils.copy(responseBody, filterResponse.getWriter()); - } + FilterChain filterChain = (filterRequest, filterResponse) -> { + assertEquals("Invalid request passed", request, filterRequest); + ((HttpServletResponse) filterResponse).setStatus(HttpServletResponse.SC_OK); + String responseBody = "Hello World"; + FileCopyUtils.copy(responseBody, filterResponse.getWriter()); }; filter.doFilter(request, response, filterChain); @@ -135,21 +115,37 @@ public class ShallowEtagHeaderFilterTests { assertArrayEquals("Invalid content", new byte[0], response.getContentAsByteArray()); } + @Test // SPR-12960 + public void filterWriterWithDisabledCaching() throws Exception { + final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + final byte[] responseBody = "Hello World".getBytes("UTF-8"); + FilterChain filterChain = (filterRequest, filterResponse) -> { + assertEquals("Invalid request passed", request, filterRequest); + ((HttpServletResponse) filterResponse).setStatus(HttpServletResponse.SC_OK); + FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); + }; + + ShallowEtagHeaderFilter.disableContentCaching(request); + this.filter.doFilter(request, response, filterChain); + + assertEquals(200, response.getStatus()); + assertNull(response.getHeader("ETag")); + assertArrayEquals(responseBody, response.getContentAsByteArray()); + } + @Test public void filterSendError() throws Exception { final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels"); MockHttpServletResponse response = new MockHttpServletResponse(); final byte[] responseBody = "Hello World".getBytes("UTF-8"); - FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest filterRequest, ServletResponse filterResponse) - throws IOException, ServletException { - assertEquals("Invalid request passed", request, filterRequest); - response.setContentLength(100); - FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); - ((HttpServletResponse) filterResponse).sendError(HttpServletResponse.SC_FORBIDDEN); - } + FilterChain filterChain = (filterRequest, filterResponse) -> { + assertEquals("Invalid request passed", request, filterRequest); + response.setContentLength(100); + FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); + ((HttpServletResponse) filterResponse).sendError(HttpServletResponse.SC_FORBIDDEN); }; filter.doFilter(request, response, filterChain); @@ -165,15 +161,11 @@ public class ShallowEtagHeaderFilterTests { MockHttpServletResponse response = new MockHttpServletResponse(); final byte[] responseBody = "Hello World".getBytes("UTF-8"); - FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest filterRequest, ServletResponse filterResponse) - throws IOException, ServletException { - assertEquals("Invalid request passed", request, filterRequest); - response.setContentLength(100); - FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); - ((HttpServletResponse) filterResponse).sendError(HttpServletResponse.SC_FORBIDDEN, "ERROR"); - } + FilterChain filterChain = (filterRequest, filterResponse) -> { + assertEquals("Invalid request passed", request, filterRequest); + response.setContentLength(100); + FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); + ((HttpServletResponse) filterResponse).sendError(HttpServletResponse.SC_FORBIDDEN, "ERROR"); }; filter.doFilter(request, response, filterChain); @@ -190,15 +182,11 @@ public class ShallowEtagHeaderFilterTests { MockHttpServletResponse response = new MockHttpServletResponse(); final byte[] responseBody = "Hello World".getBytes("UTF-8"); - FilterChain filterChain = new FilterChain() { - @Override - public void doFilter(ServletRequest filterRequest, ServletResponse filterResponse) - throws IOException, ServletException { - assertEquals("Invalid request passed", request, filterRequest); - response.setContentLength(100); - FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); - ((HttpServletResponse) filterResponse).sendRedirect("http://www.google.com"); - } + FilterChain filterChain = (filterRequest, filterResponse) -> { + assertEquals("Invalid request passed", request, filterRequest); + response.setContentLength(100); + FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); + ((HttpServletResponse) filterResponse).sendRedirect("http://www.google.com"); }; filter.doFilter(request, response, filterChain); @@ -209,4 +197,25 @@ public class ShallowEtagHeaderFilterTests { assertEquals("Invalid redirect URL", "http://www.google.com", response.getRedirectedUrl()); } + // SPR-13717 + @Test + public void filterFlushResponse() throws Exception { + final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels"); + MockHttpServletResponse response = new MockHttpServletResponse(); + + final byte[] responseBody = "Hello World".getBytes("UTF-8"); + FilterChain filterChain = (filterRequest, filterResponse) -> { + assertEquals("Invalid request passed", request, filterRequest); + ((HttpServletResponse) filterResponse).setStatus(HttpServletResponse.SC_OK); + FileCopyUtils.copy(responseBody, filterResponse.getOutputStream()); + filterResponse.flushBuffer(); + }; + filter.doFilter(request, response, filterChain); + + assertEquals("Invalid status", 200, response.getStatus()); + assertEquals("Invalid ETag header", "\"0b10a8db164e0754105b7a99be72e3fe5\"", response.getHeader("ETag")); + assertTrue("Invalid Content-Length header", response.getContentLength() > 0); + assertArrayEquals("Invalid content", responseBody, response.getContentAsByteArray()); + } + } diff --git a/spring-web/src/test/java/org/springframework/web/jsf/DelegatingNavigationHandlerTests.java b/spring-web/src/test/java/org/springframework/web/jsf/DelegatingNavigationHandlerTests.java index 864fdb1b..e7f111f2 100644 --- a/spring-web/src/test/java/org/springframework/web/jsf/DelegatingNavigationHandlerTests.java +++ b/spring-web/src/test/java/org/springframework/web/jsf/DelegatingNavigationHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006 the original author or authors. + * Copyright 2002-2015 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. @@ -19,37 +19,35 @@ package org.springframework.web.jsf; import javax.faces.application.NavigationHandler; import javax.faces.context.FacesContext; -import junit.framework.TestCase; +import org.junit.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.support.StaticListableBeanFactory; +import static org.junit.Assert.*; + /** * @author Colin Sampaleanu * @author Juergen Hoeller */ -public class DelegatingNavigationHandlerTests extends TestCase { - - private MockFacesContext facesContext; - private StaticListableBeanFactory beanFactory; - private TestNavigationHandler origNavHandler; - private DelegatingNavigationHandlerProxy delNavHandler; - - @Override - protected void setUp() { - facesContext = new MockFacesContext(); - beanFactory = new StaticListableBeanFactory(); - origNavHandler = new TestNavigationHandler(); - - delNavHandler = new DelegatingNavigationHandlerProxy(origNavHandler) { - @Override - protected BeanFactory getBeanFactory(FacesContext facesContext) { - return beanFactory; - } - }; - } +public class DelegatingNavigationHandlerTests { + + private final MockFacesContext facesContext = new MockFacesContext(); + + private final StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); + + private final TestNavigationHandler origNavHandler = new TestNavigationHandler(); + + private final DelegatingNavigationHandlerProxy delNavHandler = new DelegatingNavigationHandlerProxy(origNavHandler) { + @Override + protected BeanFactory getBeanFactory(FacesContext facesContext) { + return beanFactory; + } + }; + - public void testHandleNavigationWithoutDecoration() { + @Test + public void handleNavigationWithoutDecoration() { TestNavigationHandler targetHandler = new TestNavigationHandler(); beanFactory.addBean("jsfNavigationHandler", targetHandler); @@ -58,7 +56,8 @@ public class DelegatingNavigationHandlerTests extends TestCase { assertEquals("myViewId", targetHandler.lastOutcome); } - public void testHandleNavigationWithDecoration() { + @Test + public void handleNavigationWithDecoration() { TestDecoratingNavigationHandler targetHandler = new TestDecoratingNavigationHandler(); beanFactory.addBean("jsfNavigationHandler", targetHandler); @@ -72,7 +71,7 @@ public class DelegatingNavigationHandlerTests extends TestCase { } - public static class TestNavigationHandler extends NavigationHandler { + static class TestNavigationHandler extends NavigationHandler { private String lastFromAction; private String lastOutcome; @@ -85,7 +84,7 @@ public class DelegatingNavigationHandlerTests extends TestCase { } - public static class TestDecoratingNavigationHandler extends DecoratingNavigationHandler { + static class TestDecoratingNavigationHandler extends DecoratingNavigationHandler { private String lastFromAction; private String lastOutcome; diff --git a/spring-web/src/test/java/org/springframework/web/jsf/DelegatingPhaseListenerTests.java b/spring-web/src/test/java/org/springframework/web/jsf/DelegatingPhaseListenerTests.java index d74bf8a6..230b2c3f 100644 --- a/spring-web/src/test/java/org/springframework/web/jsf/DelegatingPhaseListenerTests.java +++ b/spring-web/src/test/java/org/springframework/web/jsf/DelegatingPhaseListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -21,36 +21,33 @@ import javax.faces.event.PhaseEvent; import javax.faces.event.PhaseId; import javax.faces.event.PhaseListener; -import junit.framework.TestCase; +import org.junit.Test; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.support.StaticListableBeanFactory; +import static org.junit.Assert.*; + /** * @author Colin Sampaleanu * @author Juergen Hoeller */ -public class DelegatingPhaseListenerTests extends TestCase { +public class DelegatingPhaseListenerTests { + + private final MockFacesContext facesContext = new MockFacesContext(); - private MockFacesContext facesContext; - private StaticListableBeanFactory beanFactory; - private DelegatingPhaseListenerMulticaster delPhaseListener; + private final StaticListableBeanFactory beanFactory = new StaticListableBeanFactory(); - @Override @SuppressWarnings("serial") - protected void setUp() { - facesContext = new MockFacesContext(); - beanFactory = new StaticListableBeanFactory(); - - delPhaseListener = new DelegatingPhaseListenerMulticaster() { - @Override - protected ListableBeanFactory getBeanFactory(FacesContext facesContext) { - return beanFactory; - } - }; - } + private final DelegatingPhaseListenerMulticaster delPhaseListener = new DelegatingPhaseListenerMulticaster() { + @Override + protected ListableBeanFactory getBeanFactory(FacesContext facesContext) { + return beanFactory; + } + }; - public void testBeforeAndAfterPhaseWithSingleTarget() { + @Test + public void beforeAndAfterPhaseWithSingleTarget() { TestListener target = new TestListener(); beanFactory.addBean("testListener", target); @@ -64,7 +61,8 @@ public class DelegatingPhaseListenerTests extends TestCase { assertTrue(target.afterCalled); } - public void testBeforeAndAfterPhaseWithMultipleTargets() { + @Test + public void beforeAndAfterPhaseWithMultipleTargets() { TestListener target1 = new TestListener(); TestListener target2 = new TestListener(); beanFactory.addBean("testListener1", target1); diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/CookieValueMethodArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/CookieValueMethodArgumentResolverTests.java index 0d730965..e1f9929a 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/CookieValueMethodArgumentResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/CookieValueMethodArgumentResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.core.MethodParameter; +import org.springframework.core.annotation.SynthesizingMethodParameter; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; import org.springframework.web.bind.ServletRequestBindingException; @@ -52,19 +53,21 @@ public class CookieValueMethodArgumentResolverTests { private MockHttpServletRequest request; + @Before public void setUp() throws Exception { resolver = new TestCookieValueMethodArgumentResolver(); Method method = getClass().getMethod("params", Cookie.class, String.class, String.class); - paramNamedCookie = new MethodParameter(method, 0); - paramNamedDefaultValueString = new MethodParameter(method, 1); - paramString = new MethodParameter(method, 2); + paramNamedCookie = new SynthesizingMethodParameter(method, 0); + paramNamedDefaultValueString = new SynthesizingMethodParameter(method, 1); + paramString = new SynthesizingMethodParameter(method, 2); request = new MockHttpServletRequest(); webRequest = new ServletWebRequest(request, new MockHttpServletResponse()); } + @Test public void supportsParameter() { assertTrue("Cookie parameter not supported", resolver.supportsParameter(paramNamedCookie)); @@ -98,9 +101,10 @@ public class CookieValueMethodArgumentResolverTests { } } + public void params(@CookieValue("name") Cookie param1, - @CookieValue(value = "name", defaultValue = "bar") String param2, + @CookieValue(name = "name", defaultValue = "bar") String param2, String param3) { } -}
\ No newline at end of file +} diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/ExpressionValueMethodArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/ExpressionValueMethodArgumentResolverTests.java index cbc2ae7d..5606eece 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/ExpressionValueMethodArgumentResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/ExpressionValueMethodArgumentResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -51,6 +51,7 @@ public class ExpressionValueMethodArgumentResolverTests { private NativeWebRequest webRequest; @Before + @SuppressWarnings("resource") public void setUp() throws Exception { GenericWebApplicationContext context = new GenericWebApplicationContext(); context.refresh(); diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessorTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessorTests.java index 31f64b9d..21fc00e8 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessorTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/ModelAttributeMethodProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -172,7 +172,7 @@ public class ModelAttributeMethodProcessorTests { } @Test - public void resovleArgumentValidation() throws Exception { + public void resolveArgumentValidation() throws Exception { String name = "attrName"; Object target = new TestBean(); mavContainer.addAttribute(name, target); @@ -187,7 +187,7 @@ public class ModelAttributeMethodProcessorTests { assertTrue(dataBinder.isValidateInvoked()); } - @Test(expected=BindException.class) + @Test(expected = BindException.class) public void resovleArgumentBindException() throws Exception { String name = "testBean"; Object target = new TestBean(); @@ -203,9 +203,7 @@ public class ModelAttributeMethodProcessorTests { verify(binderFactory).createBinder(webRequest, target, name); } - // SPR-9378 - - @Test + @Test // SPR-9378 public void resolveArgumentOrdering() throws Exception { String name = "testBean"; Object testBean = new TestBean(name); @@ -241,6 +239,7 @@ public class ModelAttributeMethodProcessorTests { assertSame(testBean, mavContainer.getModel().get("testBean")); } + private static class StubRequestDataBinder extends WebRequestDataBinder { private boolean bindInvoked; @@ -273,31 +272,31 @@ public class ModelAttributeMethodProcessorTests { public void validate(Object... validationHints) { validateInvoked = true; } - - } - @Target({ METHOD, FIELD, CONSTRUCTOR, PARAMETER }) + + @Target({METHOD, FIELD, CONSTRUCTOR, PARAMETER}) @Retention(RUNTIME) public @interface Valid { } + @SessionAttributes(types=TestBean.class) private static class ModelAttributeHandler { + @SuppressWarnings("unused") - public void modelAttribute(@ModelAttribute("attrName") @Valid TestBean annotatedAttr, - Errors errors, - int intArg, - @ModelAttribute TestBean defaultNameAttr, - TestBean notAnnotatedAttr) { + public void modelAttribute(@ModelAttribute("attrName") @Valid TestBean annotatedAttr, Errors errors, + int intArg, @ModelAttribute TestBean defaultNameAttr, TestBean notAnnotatedAttr) { } } + @ModelAttribute("modelAttrName") private String annotatedReturnValue() { return null; } + @SuppressWarnings("unused") private TestBean notAnnotatedReturnValue() { return null; diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/ModelFactoryOrderingTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/ModelFactoryOrderingTests.java index a177b7e8..8d5c7aed 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/ModelFactoryOrderingTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/ModelFactoryOrderingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -28,6 +28,7 @@ import org.apache.commons.logging.LogFactory; import org.junit.Before; import org.junit.Test; +import org.springframework.core.MethodIntrospector; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; @@ -42,7 +43,6 @@ import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.method.HandlerMethod; -import org.springframework.web.method.HandlerMethodSelector; import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite; import org.springframework.web.method.support.InvocableHandlerMethod; import org.springframework.web.method.support.ModelAndViewContainer; @@ -119,7 +119,7 @@ public class ModelFactoryOrderingTests { WebDataBinderFactory dataBinderFactory = new DefaultDataBinderFactory(null); Class<?> type = controller.getClass(); - Set<Method> methods = HandlerMethodSelector.selectMethods(type, METHOD_FILTER); + Set<Method> methods = MethodIntrospector.selectMethods(type, METHOD_FILTER); List<InvocableHandlerMethod> modelMethods = new ArrayList<InvocableHandlerMethod>(); for (Method method : methods) { InvocableHandlerMethod modelMethod = new InvocableHandlerMethod(controller, method); @@ -168,7 +168,6 @@ public class ModelFactoryOrderingTests { } } - @SuppressWarnings("unused") private static class StraightLineDependencyController extends AbstractController { @ModelAttribute @@ -208,7 +207,6 @@ public class ModelFactoryOrderingTests { } } - @SuppressWarnings("unused") private static class TreeDependencyController extends AbstractController { @ModelAttribute @@ -247,7 +245,6 @@ public class ModelFactoryOrderingTests { } } - @SuppressWarnings("unused") private static class InvertedTreeDependencyController extends AbstractController { @ModelAttribute @@ -287,7 +284,6 @@ public class ModelFactoryOrderingTests { } - @SuppressWarnings("unused") private static class UnresolvedDependencyController extends AbstractController { @ModelAttribute diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestHeaderMapMethodArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestHeaderMapMethodArgumentResolverTests.java index e86446dd..ef2a3f01 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestHeaderMapMethodArgumentResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestHeaderMapMethodArgumentResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -24,6 +24,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.core.MethodParameter; +import org.springframework.core.annotation.SynthesizingMethodParameter; import org.springframework.http.HttpHeaders; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; @@ -57,20 +58,22 @@ public class RequestHeaderMapMethodArgumentResolverTests { private MockHttpServletRequest request; + @Before public void setUp() throws Exception { resolver = new RequestHeaderMapMethodArgumentResolver(); Method method = getClass().getMethod("params", Map.class, MultiValueMap.class, HttpHeaders.class, Map.class); - paramMap = new MethodParameter(method, 0); - paramMultiValueMap = new MethodParameter(method, 1); - paramHttpHeaders = new MethodParameter(method, 2); - paramUnsupported = new MethodParameter(method, 3); + paramMap = new SynthesizingMethodParameter(method, 0); + paramMultiValueMap = new SynthesizingMethodParameter(method, 1); + paramHttpHeaders = new SynthesizingMethodParameter(method, 2); + paramUnsupported = new SynthesizingMethodParameter(method, 3); request = new MockHttpServletRequest(); webRequest = new ServletWebRequest(request, new MockHttpServletResponse()); } + @Test public void supportsParameter() { assertTrue("Map parameter not supported", resolver.supportsParameter(paramMap)); @@ -130,10 +133,11 @@ public class RequestHeaderMapMethodArgumentResolverTests { assertEquals("Invalid result", expected, result); } + public void params(@RequestHeader Map<?, ?> param1, @RequestHeader MultiValueMap<?, ?> param2, @RequestHeader HttpHeaders param3, Map<?,?> unsupported) { } -}
\ No newline at end of file +} diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestHeaderMethodArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestHeaderMethodArgumentResolverTests.java index 0806e60e..b484e2ff 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestHeaderMethodArgumentResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestHeaderMethodArgumentResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -24,6 +24,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.core.MethodParameter; +import org.springframework.core.annotation.SynthesizingMethodParameter; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; import org.springframework.web.bind.ServletRequestBindingException; @@ -55,18 +56,20 @@ public class RequestHeaderMethodArgumentResolverTests { private NativeWebRequest webRequest; + @Before + @SuppressWarnings("resource") public void setUp() throws Exception { GenericWebApplicationContext context = new GenericWebApplicationContext(); context.refresh(); resolver = new RequestHeaderMethodArgumentResolver(context.getBeanFactory()); Method method = getClass().getMethod("params", String.class, String[].class, String.class, String.class, Map.class); - paramNamedDefaultValueStringHeader = new MethodParameter(method, 0); - paramNamedValueStringArray = new MethodParameter(method, 1); - paramSystemProperty = new MethodParameter(method, 2); - paramContextPath = new MethodParameter(method, 3); - paramNamedValueMap = new MethodParameter(method, 4); + paramNamedDefaultValueStringHeader = new SynthesizingMethodParameter(method, 0); + paramNamedValueStringArray = new SynthesizingMethodParameter(method, 1); + paramSystemProperty = new SynthesizingMethodParameter(method, 2); + paramContextPath = new SynthesizingMethodParameter(method, 3); + paramNamedValueMap = new SynthesizingMethodParameter(method, 4); servletRequest = new MockHttpServletRequest(); webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse()); @@ -80,6 +83,7 @@ public class RequestHeaderMethodArgumentResolverTests { RequestContextHolder.resetRequestAttributes(); } + @Test public void supportsParameter() { assertTrue("String parameter not supported", resolver.supportsParameter(paramNamedDefaultValueStringHeader)); @@ -141,11 +145,12 @@ public class RequestHeaderMethodArgumentResolverTests { resolver.resolveArgument(paramNamedValueStringArray, null, webRequest, null); } - public void params(@RequestHeader(value = "name", defaultValue = "bar") String param1, + + public void params(@RequestHeader(name = "name", defaultValue = "bar") String param1, @RequestHeader("name") String[] param2, - @RequestHeader(value = "name", defaultValue="#{systemProperties.systemProperty}") String param3, - @RequestHeader(value = "name", defaultValue="#{request.contextPath}") String param4, + @RequestHeader(name = "name", defaultValue="#{systemProperties.systemProperty}") String param3, + @RequestHeader(name = "name", defaultValue="#{request.contextPath}") String param4, @RequestHeader("name") Map<?, ?> unsupported) { } -}
\ No newline at end of file +} diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolverTests.java index 1aa9d371..cae73f46 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -24,6 +24,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.core.MethodParameter; +import org.springframework.core.annotation.SynthesizingMethodParameter; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; import org.springframework.util.LinkedMultiValueMap; @@ -56,20 +57,22 @@ public class RequestParamMapMethodArgumentResolverTests { private MockHttpServletRequest request; + @Before public void setUp() throws Exception { resolver = new RequestParamMapMethodArgumentResolver(); Method method = getClass().getMethod("params", Map.class, MultiValueMap.class, Map.class, Map.class); - paramMap = new MethodParameter(method, 0); - paramMultiValueMap = new MethodParameter(method, 1); - paramNamedMap = new MethodParameter(method, 2); - paramMapWithoutAnnot = new MethodParameter(method, 3); + paramMap = new SynthesizingMethodParameter(method, 0); + paramMultiValueMap = new SynthesizingMethodParameter(method, 1); + paramNamedMap = new SynthesizingMethodParameter(method, 2); + paramMapWithoutAnnot = new SynthesizingMethodParameter(method, 3); request = new MockHttpServletRequest(); webRequest = new ServletWebRequest(request, new MockHttpServletResponse()); } + @Test public void supportsParameter() { assertTrue("Map parameter not supported", resolver.supportsParameter(paramMap)); @@ -108,10 +111,11 @@ public class RequestParamMapMethodArgumentResolverTests { assertEquals("Invalid result", expected, result); } + public void params(@RequestParam Map<?, ?> param1, @RequestParam MultiValueMap<?, ?> param2, @RequestParam("name") Map<?, ?> param3, Map<?, ?> param4) { } -}
\ No newline at end of file +} diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java index 23e6fbcc..00b61b5f 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * 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. @@ -30,6 +30,7 @@ import org.springframework.beans.propertyeditors.StringTrimmerEditor; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.core.MethodParameter; import org.springframework.core.ParameterNameDiscoverer; +import org.springframework.core.annotation.SynthesizingMethodParameter; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; @@ -86,10 +87,10 @@ public class RequestParamMethodArgumentResolverTests { private MockHttpServletRequest request; + @Before public void setUp() throws Exception { resolver = new RequestParamMethodArgumentResolver(null, true); - ParameterNameDiscoverer paramNameDiscoverer = new LocalVariableTableParameterNameDiscoverer(); Method method = getClass().getMethod("params", String.class, String[].class, @@ -98,33 +99,34 @@ public class RequestParamMethodArgumentResolverTests { String.class, MultipartFile.class, List.class, Part.class, MultipartFile.class, String.class, String.class, Optional.class); - paramNamedDefaultValueString = new MethodParameter(method, 0); - paramNamedStringArray = new MethodParameter(method, 1); - paramNamedMap = new MethodParameter(method, 2); - paramMultipartFile = new MethodParameter(method, 3); - paramMultipartFileList = new MethodParameter(method, 4); - paramMultipartFileArray = new MethodParameter(method, 5); - paramPart = new MethodParameter(method, 6); - paramPartList = new MethodParameter(method, 7); - paramPartArray = new MethodParameter(method, 8); - paramMap = new MethodParameter(method, 9); - paramStringNotAnnot = new MethodParameter(method, 10); + paramNamedDefaultValueString = new SynthesizingMethodParameter(method, 0); + paramNamedStringArray = new SynthesizingMethodParameter(method, 1); + paramNamedMap = new SynthesizingMethodParameter(method, 2); + paramMultipartFile = new SynthesizingMethodParameter(method, 3); + paramMultipartFileList = new SynthesizingMethodParameter(method, 4); + paramMultipartFileArray = new SynthesizingMethodParameter(method, 5); + paramPart = new SynthesizingMethodParameter(method, 6); + paramPartList = new SynthesizingMethodParameter(method, 7); + paramPartArray = new SynthesizingMethodParameter(method, 8); + paramMap = new SynthesizingMethodParameter(method, 9); + paramStringNotAnnot = new SynthesizingMethodParameter(method, 10); paramStringNotAnnot.initParameterNameDiscovery(paramNameDiscoverer); - paramMultipartFileNotAnnot = new MethodParameter(method, 11); + paramMultipartFileNotAnnot = new SynthesizingMethodParameter(method, 11); paramMultipartFileNotAnnot.initParameterNameDiscovery(paramNameDiscoverer); - paramMultipartFileListNotAnnot = new MethodParameter(method, 12); + paramMultipartFileListNotAnnot = new SynthesizingMethodParameter(method, 12); paramMultipartFileListNotAnnot.initParameterNameDiscovery(paramNameDiscoverer); - paramPartNotAnnot = new MethodParameter(method, 13); + paramPartNotAnnot = new SynthesizingMethodParameter(method, 13); paramPartNotAnnot.initParameterNameDiscovery(paramNameDiscoverer); - paramRequestPartAnnot = new MethodParameter(method, 14); - paramRequired = new MethodParameter(method, 15); - paramNotRequired = new MethodParameter(method, 16); - paramOptional = new MethodParameter(method, 17); + paramRequestPartAnnot = new SynthesizingMethodParameter(method, 14); + paramRequired = new SynthesizingMethodParameter(method, 15); + paramNotRequired = new SynthesizingMethodParameter(method, 16); + paramOptional = new SynthesizingMethodParameter(method, 17); request = new MockHttpServletRequest(); webRequest = new ServletWebRequest(request, new MockHttpServletResponse()); } + @Test public void supportsParameter() { resolver = new RequestParamMethodArgumentResolver(null, true); @@ -153,18 +155,16 @@ public class RequestParamMethodArgumentResolverTests { request.addParameter("name", expected); Object result = resolver.resolveArgument(paramNamedDefaultValueString, null, webRequest, null); - assertTrue(result instanceof String); assertEquals("Invalid result", expected, result); } @Test public void resolveStringArray() throws Exception { - String[] expected = new String[]{"foo", "bar"}; + String[] expected = new String[] {"foo", "bar"}; request.addParameter("name", expected); Object result = resolver.resolveArgument(paramNamedStringArray, null, webRequest, null); - assertTrue(result instanceof String[]); assertArrayEquals("Invalid result", expected, (String[]) result); } @@ -177,7 +177,6 @@ public class RequestParamMethodArgumentResolverTests { webRequest = new ServletWebRequest(request); Object result = resolver.resolveArgument(paramMultipartFile, null, webRequest, null); - assertTrue(result instanceof MultipartFile); assertEquals("Invalid result", expected, result); } @@ -192,7 +191,6 @@ public class RequestParamMethodArgumentResolverTests { webRequest = new ServletWebRequest(request); Object result = resolver.resolveArgument(paramMultipartFileList, null, webRequest, null); - assertTrue(result instanceof List); assertEquals(Arrays.asList(expected1, expected2), result); } @@ -207,9 +205,9 @@ public class RequestParamMethodArgumentResolverTests { webRequest = new ServletWebRequest(request); Object result = resolver.resolveArgument(paramMultipartFileArray, null, webRequest, null); - assertTrue(result instanceof MultipartFile[]); MultipartFile[] parts = (MultipartFile[]) result; + assertEquals(2, parts.length); assertEquals(parts[0], expected1); assertEquals(parts[1], expected2); } @@ -241,7 +239,6 @@ public class RequestParamMethodArgumentResolverTests { webRequest = new ServletWebRequest(request); Object result = resolver.resolveArgument(paramPartList, null, webRequest, null); - assertTrue(result instanceof List); assertEquals(Arrays.asList(expected1, expected2), result); } @@ -258,9 +255,9 @@ public class RequestParamMethodArgumentResolverTests { webRequest = new ServletWebRequest(request); Object result = resolver.resolveArgument(paramPartArray, null, webRequest, null); - assertTrue(result instanceof Part[]); Part[] parts = (Part[]) result; + assertEquals(2, parts.length); assertEquals(parts[0], expected1); assertEquals(parts[1], expected2); } @@ -273,7 +270,6 @@ public class RequestParamMethodArgumentResolverTests { webRequest = new ServletWebRequest(request); Object result = resolver.resolveArgument(paramMultipartFileNotAnnot, null, webRequest, null); - assertTrue(result instanceof MultipartFile); assertEquals("Invalid result", expected, result); } @@ -288,7 +284,6 @@ public class RequestParamMethodArgumentResolverTests { webRequest = new ServletWebRequest(request); Object result = resolver.resolveArgument(paramMultipartFileListNotAnnot, null, webRequest, null); - assertTrue(result instanceof List); assertEquals(Arrays.asList(expected1, expected2), result); } @@ -299,9 +294,7 @@ public class RequestParamMethodArgumentResolverTests { fail("Expected exception: request is not a multipart request"); } - // SPR-9079 - - @Test + @Test // SPR-9079 public void isMultipartRequestHttpPut() throws Exception { MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(); MultipartFile expected = new MockMultipartFile("multipartFileList", "Hello World".getBytes()); @@ -310,7 +303,6 @@ public class RequestParamMethodArgumentResolverTests { webRequest = new ServletWebRequest(request); Object actual = resolver.resolveArgument(paramMultipartFileListNotAnnot, null, webRequest, null); - assertTrue(actual instanceof List); assertEquals(expected, ((List<?>) actual).get(0)); } @@ -333,7 +325,6 @@ public class RequestParamMethodArgumentResolverTests { webRequest = new ServletWebRequest(request); Object result = resolver.resolveArgument(paramPartNotAnnot, null, webRequest, null); - assertTrue(result instanceof Part); assertEquals("Invalid result", expected, result); } @@ -341,7 +332,6 @@ public class RequestParamMethodArgumentResolverTests { @Test public void resolveDefaultValue() throws Exception { Object result = resolver.resolveArgument(paramNamedDefaultValueString, null, webRequest, null); - assertTrue(result instanceof String); assertEquals("Invalid result", "bar", result); } @@ -352,11 +342,8 @@ public class RequestParamMethodArgumentResolverTests { fail("Expected exception"); } - // SPR-10578 - - @Test + @Test // SPR-10578 public void missingRequestParamEmptyValueConvertedToNull() throws Exception { - WebDataBinder binder = new WebRequestDataBinder(null); binder.registerCustomEditor(String.class, new StringTrimmerEditor(true)); @@ -366,13 +353,11 @@ public class RequestParamMethodArgumentResolverTests { this.request.addParameter("stringNotAnnot", ""); Object arg = resolver.resolveArgument(paramStringNotAnnot, null, webRequest, binderFactory); - assertNull(arg); } @Test public void missingRequestParamEmptyValueNotRequired() throws Exception { - WebDataBinder binder = new WebRequestDataBinder(null); binder.registerCustomEditor(String.class, new StringTrimmerEditor(true)); @@ -382,7 +367,6 @@ public class RequestParamMethodArgumentResolverTests { this.request.addParameter("name", ""); Object arg = resolver.resolveArgument(paramNotRequired, null, webRequest, binderFactory); - assertNull(arg); } @@ -395,17 +379,13 @@ public class RequestParamMethodArgumentResolverTests { assertEquals("plainValue", result); } - // SPR-8561 - - @Test + @Test // SPR-8561 public void resolveSimpleTypeParamToNull() throws Exception { Object result = resolver.resolveArgument(paramStringNotAnnot, null, webRequest, null); assertNull(result); } - // SPR-10180 - - @Test + @Test // SPR-10180 public void resolveEmptyValueToDefault() throws Exception { this.request.addParameter("name", ""); Object result = resolver.resolveArgument(paramNamedDefaultValueString, null, webRequest, null); @@ -427,13 +407,13 @@ public class RequestParamMethodArgumentResolverTests { } @Test - public void resolveOptional() throws Exception { + @SuppressWarnings("rawtypes") + public void resolveOptionalParamValue() throws Exception { ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); initializer.setConversionService(new DefaultConversionService()); WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer); Object result = resolver.resolveArgument(paramOptional, null, webRequest, binderFactory); - assertEquals(Optional.class, result.getClass()); assertEquals(Optional.empty(), result); this.request.addParameter("name", "123"); @@ -443,24 +423,24 @@ public class RequestParamMethodArgumentResolverTests { } - public void params(@RequestParam(value = "name", defaultValue = "bar") String param1, + public void params(@RequestParam(name = "name", defaultValue = "bar") String param1, @RequestParam("name") String[] param2, @RequestParam("name") Map<?, ?> param3, - @RequestParam(value = "mfile") MultipartFile param4, - @RequestParam(value = "mfilelist") List<MultipartFile> param5, - @RequestParam(value = "mfilearray") MultipartFile[] param6, - @RequestParam(value = "pfile") Part param7, - @RequestParam(value = "pfilelist") List<Part> param8, - @RequestParam(value = "pfilearray") Part[] param9, + @RequestParam("mfile") MultipartFile param4, + @RequestParam("mfilelist") List<MultipartFile> param5, + @RequestParam("mfilearray") MultipartFile[] param6, + @RequestParam("pfile") Part param7, + @RequestParam("pfilelist") List<Part> param8, + @RequestParam("pfilearray") Part[] param9, @RequestParam Map<?, ?> param10, String stringNotAnnot, MultipartFile multipartFileNotAnnot, List<MultipartFile> multipartFileList, Part part, @RequestPart MultipartFile requestPartAnnot, - @RequestParam(value = "name") String paramRequired, - @RequestParam(value = "name", required=false) String paramNotRequired, - @RequestParam(value = "name") Optional<Integer> paramOptional) { + @RequestParam("name") String paramRequired, + @RequestParam(name = "name", required = false) String paramNotRequired, + @RequestParam("name") Optional<Integer> paramOptional) { } } diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/SessionAttributesHandlerTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/SessionAttributesHandlerTests.java index 85f2a752..51d791eb 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/SessionAttributesHandlerTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/SessionAttributesHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -16,9 +16,9 @@ package org.springframework.web.method.annotation; + import java.util.HashSet; -import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.test.MockHttpServletRequest; @@ -40,20 +40,13 @@ import static org.junit.Assert.*; */ public class SessionAttributesHandlerTests { - private Class<?> handlerType = SessionAttributeHandler.class; - - private SessionAttributesHandler sessionAttributesHandler; + private final SessionAttributeStore sessionAttributeStore = new DefaultSessionAttributeStore(); - private SessionAttributeStore sessionAttributeStore; + private final SessionAttributesHandler sessionAttributesHandler = new SessionAttributesHandler( + SessionAttributeHandler.class, sessionAttributeStore); - private NativeWebRequest request; + private final NativeWebRequest request = new ServletWebRequest(new MockHttpServletRequest()); - @Before - public void setUp() { - this.sessionAttributeStore = new DefaultSessionAttributeStore(); - this.sessionAttributesHandler = new SessionAttributesHandler(handlerType, sessionAttributeStore); - this.request = new ServletWebRequest(new MockHttpServletRequest()); - } @Test public void isSessionAttribute() throws Exception { @@ -115,7 +108,8 @@ public class SessionAttributesHandlerTests { assertTrue(sessionAttributeStore.retrieveAttribute(request, "attr3") instanceof TestBean); } - @SessionAttributes(value = { "attr1", "attr2" }, types = { TestBean.class }) + + @SessionAttributes(names = { "attr1", "attr2" }, types = { TestBean.class }) private static class SessionAttributeHandler { } diff --git a/spring-web/src/test/java/org/springframework/web/method/support/CompositeUriComponentsContributorTests.java b/spring-web/src/test/java/org/springframework/web/method/support/CompositeUriComponentsContributorTests.java index 55aa9d9f..7a7b3abc 100644 --- a/spring-web/src/test/java/org/springframework/web/method/support/CompositeUriComponentsContributorTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/support/CompositeUriComponentsContributorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -57,7 +57,6 @@ public class CompositeUriComponentsContributorTests { } - @SuppressWarnings("unused") public void handleRequest(@RequestParam String p1, String p2, @RequestHeader String h) { } diff --git a/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerCompositeTests.java b/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerCompositeTests.java index 5fe5eaef..06f46b22 100644 --- a/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerCompositeTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/support/HandlerMethodReturnValueHandlerCompositeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -22,76 +22,114 @@ import org.junit.Test; import org.springframework.core.MethodParameter; import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * Test fixture with {@link HandlerMethodReturnValueHandlerComposite}. - * * @author Rossen Stoyanchev */ +@SuppressWarnings("unused") public class HandlerMethodReturnValueHandlerCompositeTests { private HandlerMethodReturnValueHandlerComposite handlers; + private HandlerMethodReturnValueHandler integerHandler; + ModelAndViewContainer mavContainer; - private MethodParameter paramInt; + private MethodParameter integerType; + + private MethodParameter stringType; - private MethodParameter paramStr; @Before public void setUp() throws Exception { - handlers = new HandlerMethodReturnValueHandlerComposite(); + + this.integerType = new MethodParameter(getClass().getDeclaredMethod("handleInteger"), -1); + this.stringType = new MethodParameter(getClass().getDeclaredMethod("handleString"), -1); + + this.integerHandler = mock(HandlerMethodReturnValueHandler.class); + when(this.integerHandler.supportsReturnType(this.integerType)).thenReturn(true); + + this.handlers = new HandlerMethodReturnValueHandlerComposite(); + this.handlers.addHandler(this.integerHandler); + mavContainer = new ModelAndViewContainer(); - paramInt = new MethodParameter(getClass().getDeclaredMethod("handleInteger"), -1); - paramStr = new MethodParameter(getClass().getDeclaredMethod("handleString"), -1); } @Test public void supportsReturnType() throws Exception { - registerHandler(Integer.class); - - assertTrue(this.handlers.supportsReturnType(paramInt)); - assertFalse(this.handlers.supportsReturnType(paramStr)); + assertTrue(this.handlers.supportsReturnType(this.integerType)); + assertFalse(this.handlers.supportsReturnType(this.stringType)); } @Test public void handleReturnValue() throws Exception { - StubReturnValueHandler handler = registerHandler(Integer.class); - this.handlers.handleReturnValue(Integer.valueOf(55), paramInt, mavContainer, null); + this.handlers.handleReturnValue(55, this.integerType, this.mavContainer, null); + verify(this.integerHandler).handleReturnValue(55, this.integerType, this.mavContainer, null); + } + + @Test + public void handleReturnValueWithMultipleHandlers() throws Exception { + HandlerMethodReturnValueHandler anotherIntegerHandler = mock(HandlerMethodReturnValueHandler.class); + when(anotherIntegerHandler.supportsReturnType(this.integerType)).thenReturn(true); - assertEquals(Integer.valueOf(55), handler.getReturnValue()); + this.handlers.handleReturnValue(55, this.integerType, this.mavContainer, null); + + verify(this.integerHandler).handleReturnValue(55, this.integerType, this.mavContainer, null); + verifyNoMoreInteractions(anotherIntegerHandler); } + // SPR-13083 + @Test - public void handleReturnValueMultipleHandlers() throws Exception { - StubReturnValueHandler h1 = registerHandler(Integer.class); - StubReturnValueHandler h2 = registerHandler(Integer.class); - this.handlers.handleReturnValue(Integer.valueOf(55), paramInt, mavContainer, null); + public void handleReturnValueWithAsyncHandler() throws Exception { + + Promise<Integer> promise = new Promise<>(); + MethodParameter promiseType = new MethodParameter(getClass().getDeclaredMethod("handlePromise"), -1); + + HandlerMethodReturnValueHandler responseBodyHandler = mock(HandlerMethodReturnValueHandler.class); + when(responseBodyHandler.supportsReturnType(promiseType)).thenReturn(true); + this.handlers.addHandler(responseBodyHandler); + + AsyncHandlerMethodReturnValueHandler promiseHandler = mock(AsyncHandlerMethodReturnValueHandler.class); + when(promiseHandler.supportsReturnType(promiseType)).thenReturn(true); + when(promiseHandler.isAsyncReturnValue(promise, promiseType)).thenReturn(true); + this.handlers.addHandler(promiseHandler); + + this.handlers.handleReturnValue(promise, promiseType, this.mavContainer, null); - assertEquals("Didn't use the 1st registered handler", Integer.valueOf(55), h1.getReturnValue()); - assertNull("Shouldn't have use the 2nd registered handler", h2.getReturnValue()); + verify(promiseHandler).isAsyncReturnValue(promise, promiseType); + verify(promiseHandler).supportsReturnType(promiseType); + verify(promiseHandler).handleReturnValue(promise, promiseType, this.mavContainer, null); + verifyNoMoreInteractions(promiseHandler); + verifyNoMoreInteractions(responseBodyHandler); } @Test(expected=IllegalArgumentException.class) public void noSuitableReturnValueHandler() throws Exception { - registerHandler(Integer.class); - this.handlers.handleReturnValue("value", paramStr, null, null); + this.handlers.handleReturnValue("value", this.stringType, null, null); } - private StubReturnValueHandler registerHandler(Class<?> returnType) { - StubReturnValueHandler handler = new StubReturnValueHandler(returnType); - handlers.addHandler(handler); - return handler; - } - @SuppressWarnings("unused") private Integer handleInteger() { return null; } - @SuppressWarnings("unused") private String handleString() { return null; } + private Promise<Integer> handlePromise() { + return null; + } + + private static class Promise<T> {} + }
\ No newline at end of file diff --git a/spring-web/src/test/java/org/springframework/web/method/support/InvocableHandlerMethodTests.java b/spring-web/src/test/java/org/springframework/web/method/support/InvocableHandlerMethodTests.java index 4bd60cd5..b044b257 100644 --- a/spring-web/src/test/java/org/springframework/web/method/support/InvocableHandlerMethodTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/support/InvocableHandlerMethodTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * 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. @@ -29,6 +29,7 @@ import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.ServletWebRequest; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; /** @@ -195,6 +196,26 @@ public class InvocableHandlerMethodTests { } } + @Test // SPR-13917 + public void invocationErrorMessage() throws Exception { + HandlerMethodArgumentResolverComposite composite = new HandlerMethodArgumentResolverComposite(); + composite.addResolver(new StubArgumentResolver(double.class, null)); + + Method method = Handler.class.getDeclaredMethod("handle", double.class); + Object handler = new Handler(); + InvocableHandlerMethod hm = new InvocableHandlerMethod(handler, method); + hm.setHandlerMethodArgumentResolvers(composite); + + try { + hm.invokeForRequest(this.webRequest, new ModelAndViewContainer()); + fail(); + } + catch (IllegalStateException ex) { + assertThat(ex.getMessage(), containsString("Illegal argument")); + } + } + + private void invokeExceptionRaisingHandler(Throwable expected) throws Exception { Method method = ExceptionRaisingHandler.class.getDeclaredMethod("raiseException"); Object handler = new ExceptionRaisingHandler(expected); @@ -209,6 +230,9 @@ public class InvocableHandlerMethodTests { public String handle(Integer intArg, String stringArg) { return intArg + "-" + stringArg; } + + public void handle(double amount) { + } } diff --git a/spring-web/src/test/java/org/springframework/web/method/support/ModelAndViewContainerTests.java b/spring-web/src/test/java/org/springframework/web/method/support/ModelAndViewContainerTests.java index 114c6712..8e292394 100644 --- a/spring-web/src/test/java/org/springframework/web/method/support/ModelAndViewContainerTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/support/ModelAndViewContainerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * 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. @@ -16,13 +16,12 @@ package org.springframework.web.method.support; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - import org.junit.Before; import org.junit.Test; + import org.springframework.ui.ModelMap; +import static org.junit.Assert.*; /** * Test fixture for {@link ModelAndViewContainer}. @@ -76,4 +75,15 @@ public class ModelAndViewContainerTests { assertTrue(this.mavContainer.getModel().isEmpty()); } + @Test // SPR-14045 + public void ignoreDefaultModelAndWithoutRedirectModel() { + this.mavContainer.setIgnoreDefaultModelOnRedirect(true); + this.mavContainer.setRedirectModelScenario(true); + this.mavContainer.addAttribute("name", "value"); + + assertEquals(1, this.mavContainer.getModel().size()); + assertEquals("value", this.mavContainer.getModel().get("name")); + } + + } diff --git a/spring-web/src/test/java/org/springframework/web/method/support/StubReturnValueHandler.java b/spring-web/src/test/java/org/springframework/web/method/support/StubReturnValueHandler.java deleted file mode 100644 index ca63af02..00000000 --- a/spring-web/src/test/java/org/springframework/web/method/support/StubReturnValueHandler.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2002-2012 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.web.method.support; - -import org.springframework.core.MethodParameter; -import org.springframework.web.context.request.NativeWebRequest; - -/** - * Supports a fixed return value type. Records the last handled return value. - * - * @author Rossen Stoyanchev - */ -public class StubReturnValueHandler implements HandlerMethodReturnValueHandler { - - private final Class<?> returnType; - - private Object returnValue; - - public StubReturnValueHandler(Class<?> returnType) { - this.returnType = returnType; - } - - public Object getReturnValue() { - return this.returnValue; - } - - @Override - public boolean supportsReturnType(MethodParameter returnType) { - return returnType.getParameterType().equals(this.returnType); - } - - @Override - public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, - NativeWebRequest webRequest) throws Exception { - this.returnValue = returnValue; - } - -} diff --git a/spring-web/src/test/java/org/springframework/web/multipart/support/ByteArrayMultipartFileEditorTests.java b/spring-web/src/test/java/org/springframework/web/multipart/support/ByteArrayMultipartFileEditorTests.java index a3de4860..fdca3abc 100644 --- a/spring-web/src/test/java/org/springframework/web/multipart/support/ByteArrayMultipartFileEditorTests.java +++ b/spring-web/src/test/java/org/springframework/web/multipart/support/ByteArrayMultipartFileEditorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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. @@ -18,33 +18,37 @@ package org.springframework.web.multipart.support; import java.io.IOException; -import junit.framework.TestCase; +import org.junit.Test; import org.springframework.web.multipart.MultipartFile; +import static org.junit.Assert.*; import static org.mockito.BDDMockito.*; /** * @author Rick Evans + * @author Sam Brannen */ -public final class ByteArrayMultipartFileEditorTests extends TestCase { +public final class ByteArrayMultipartFileEditorTests { - public void testSetValueAsByteArray() throws Exception { - ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor(); + private final ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor(); + + @Test + public void setValueAsByteArray() throws Exception { String expectedValue = "Shumwere, shumhow, a shuck ish washing you. - Drunken Far Side"; editor.setValue(expectedValue.getBytes()); assertEquals(expectedValue, editor.getAsText()); } - public void testSetValueAsString() throws Exception { - ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor(); + @Test + public void setValueAsString() throws Exception { String expectedValue = "'Green Wing' - classic British comedy"; editor.setValue(expectedValue); assertEquals(expectedValue, editor.getAsText()); } - public void testSetValueAsCustomObjectInvokesToString() throws Exception { - ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor(); + @Test + public void setValueAsCustomObjectInvokesToString() throws Exception { final String expectedValue = "'Green Wing' - classic British comedy"; Object object = new Object() { @Override @@ -52,35 +56,31 @@ public final class ByteArrayMultipartFileEditorTests extends TestCase { return expectedValue; } }; + editor.setValue(object); assertEquals(expectedValue, editor.getAsText()); } - public void testSetValueAsNullGetsBackEmptyString() throws Exception { - ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor(); + @Test + public void setValueAsNullGetsBackEmptyString() throws Exception { editor.setValue(null); assertEquals("", editor.getAsText()); } - public void testSetValueAsMultipartFile() throws Exception { + @Test + public void setValueAsMultipartFile() throws Exception { String expectedValue = "That is comforting to know"; - ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor(); MultipartFile file = mock(MultipartFile.class); given(file.getBytes()).willReturn(expectedValue.getBytes()); editor.setValue(file); assertEquals(expectedValue, editor.getAsText()); } - public void testSetValueAsMultipartFileWithBadBytes() throws Exception { - ByteArrayMultipartFileEditor editor = new ByteArrayMultipartFileEditor(); + @Test(expected = IllegalArgumentException.class) + public void setValueAsMultipartFileWithBadBytes() throws Exception { MultipartFile file = mock(MultipartFile.class); given(file.getBytes()).willThrow(new IOException()); - try { - editor.setValue(file); - fail("Must have thrown an IllegalArgumentException: IOException thrown when reading MultipartFile bytes"); - } - catch (IllegalArgumentException expected) { - } + editor.setValue(file); } } diff --git a/spring-web/src/test/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequestTests.java b/spring-web/src/test/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequestTests.java index 60776274..f821dab4 100644 --- a/spring-web/src/test/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequestTests.java +++ b/spring-web/src/test/java/org/springframework/web/multipart/support/RequestPartServletServerHttpRequestTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -17,68 +17,131 @@ package org.springframework.web.multipart.support; import java.net.URI; +import java.nio.charset.Charset; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; -import org.junit.Before; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; +import org.springframework.http.server.ServerHttpRequest; import org.springframework.mock.web.test.MockMultipartFile; import org.springframework.mock.web.test.MockMultipartHttpServletRequest; import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; /** * @author Rossen Stoyanchev */ public class RequestPartServletServerHttpRequestTests { - private RequestPartServletServerHttpRequest request; - - private MockMultipartHttpServletRequest mockRequest; + private final MockMultipartHttpServletRequest mockRequest = new MockMultipartHttpServletRequest(); - private MockMultipartFile mockFile; - - @Before - public void create() throws Exception { - mockFile = new MockMultipartFile("part", "", "application/json" ,"Part Content".getBytes("UTF-8")); - mockRequest = new MockMultipartHttpServletRequest(); - mockRequest.addFile(mockFile); - request = new RequestPartServletServerHttpRequest(mockRequest, "part"); - } @Test public void getMethod() throws Exception { - mockRequest.setMethod("POST"); - assertEquals("Invalid method", HttpMethod.POST, request.getMethod()); + this.mockRequest.addFile(new MockMultipartFile("part", "", "", "content".getBytes("UTF-8"))); + ServerHttpRequest request = new RequestPartServletServerHttpRequest(this.mockRequest, "part"); + this.mockRequest.setMethod("POST"); + + assertEquals(HttpMethod.POST, request.getMethod()); } @Test public void getURI() throws Exception { + this.mockRequest.addFile(new MockMultipartFile("part", "", "application/json", "content".getBytes("UTF-8"))); + ServerHttpRequest request = new RequestPartServletServerHttpRequest(this.mockRequest, "part"); + URI uri = new URI("http://example.com/path?query"); - mockRequest.setServerName(uri.getHost()); - mockRequest.setServerPort(uri.getPort()); - mockRequest.setRequestURI(uri.getPath()); - mockRequest.setQueryString(uri.getQuery()); - assertEquals("Invalid uri", uri, request.getURI()); + this.mockRequest.setServerName(uri.getHost()); + this.mockRequest.setServerPort(uri.getPort()); + this.mockRequest.setRequestURI(uri.getPath()); + this.mockRequest.setQueryString(uri.getQuery()); + assertEquals(uri, request.getURI()); } @Test public void getContentType() throws Exception { - HttpHeaders headers = request.getHeaders(); - assertNotNull("No HttpHeaders returned", headers); + MultipartFile part = new MockMultipartFile("part", "", "application/json", "content".getBytes("UTF-8")); + this.mockRequest.addFile(part); + ServerHttpRequest request = new RequestPartServletServerHttpRequest(this.mockRequest, "part"); - MediaType expected = MediaType.parseMediaType(mockFile.getContentType()); - MediaType actual = headers.getContentType(); - assertEquals("Invalid content type returned", expected, actual); + HttpHeaders headers = request.getHeaders(); + assertNotNull(headers); + assertEquals(MediaType.APPLICATION_JSON, headers.getContentType()); } @Test public void getBody() throws Exception { + byte[] bytes = "content".getBytes("UTF-8"); + MultipartFile part = new MockMultipartFile("part", "", "application/json", bytes); + this.mockRequest.addFile(part); + ServerHttpRequest request = new RequestPartServletServerHttpRequest(this.mockRequest, "part"); + + byte[] result = FileCopyUtils.copyToByteArray(request.getBody()); + assertArrayEquals(bytes, result); + } + + // SPR-13317 + + @Test + public void getBodyWithWrappedRequest() throws Exception { + byte[] bytes = "content".getBytes("UTF-8"); + MultipartFile part = new MockMultipartFile("part", "", "application/json", bytes); + this.mockRequest.addFile(part); + HttpServletRequest wrapped = new HttpServletRequestWrapper(this.mockRequest); + ServerHttpRequest request = new RequestPartServletServerHttpRequest(wrapped, "part"); + + byte[] result = FileCopyUtils.copyToByteArray(request.getBody()); + assertArrayEquals(bytes, result); + } + + // SPR-13096 + + @Test + public void getBodyViaRequestParameter() throws Exception { + MockMultipartHttpServletRequest mockRequest = new MockMultipartHttpServletRequest() { + + @Override + public HttpHeaders getMultipartHeaders(String paramOrFileName) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(new MediaType("application", "octet-stream", Charset.forName("iso-8859-1"))); + return headers; + } + }; + byte[] bytes = {(byte) 0xC4}; + mockRequest.setParameter("part", new String(bytes, Charset.forName("iso-8859-1"))); + ServerHttpRequest request = new RequestPartServletServerHttpRequest(mockRequest, "part"); + + byte[] result = FileCopyUtils.copyToByteArray(request.getBody()); + assertArrayEquals(bytes, result); + } + + @Test + public void getBodyViaRequestParameterWithRequestEncoding() throws Exception { + MockMultipartHttpServletRequest mockRequest = new MockMultipartHttpServletRequest() { + + @Override + public HttpHeaders getMultipartHeaders(String paramOrFileName) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + return headers; + } + }; + byte[] bytes = {(byte) 0xC4}; + mockRequest.setParameter("part", new String(bytes, Charset.forName("iso-8859-1"))); + mockRequest.setCharacterEncoding("iso-8859-1"); + ServerHttpRequest request = new RequestPartServletServerHttpRequest(mockRequest, "part"); + byte[] result = FileCopyUtils.copyToByteArray(request.getBody()); - assertArrayEquals("Invalid content returned", mockFile.getBytes(), result); + assertArrayEquals(bytes, result); } } diff --git a/spring-web/src/test/java/org/springframework/web/util/DefaultUriTemplateHandlerTests.java b/spring-web/src/test/java/org/springframework/web/util/DefaultUriTemplateHandlerTests.java new file mode 100644 index 00000000..1642351e --- /dev/null +++ b/spring-web/src/test/java/org/springframework/web/util/DefaultUriTemplateHandlerTests.java @@ -0,0 +1,88 @@ +/* + * Copyright 2002-2015 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.web.util; + +import static org.junit.Assert.assertEquals; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +/** + * Unit tests for {@link DefaultUriTemplateHandler}. + * @author Rossen Stoyanchev + */ +public class DefaultUriTemplateHandlerTests { + + private DefaultUriTemplateHandler handler; + + + @Before + public void setUp() throws Exception { + this.handler = new DefaultUriTemplateHandler(); + } + + + @Test + public void baseUrl() throws Exception { + this.handler.setBaseUrl("http://localhost:8080"); + URI actual = this.handler.expand("/myapiresource"); + + URI expected = new URI("http://localhost:8080/myapiresource"); + assertEquals(expected, actual); + } + + @Test + public void baseUrlWithPartialPath() throws Exception { + this.handler.setBaseUrl("http://localhost:8080/context"); + URI actual = this.handler.expand("/myapiresource"); + + URI expected = new URI("http://localhost:8080/context/myapiresource"); + assertEquals(expected, actual); + } + + @Test + public void expandWithFullPath() throws Exception { + Map<String, String> vars = new HashMap<String, String>(2); + vars.put("hotel", "1"); + vars.put("publicpath", "pics/logo.png"); + String template = "http://example.com/hotels/{hotel}/pic/{publicpath}"; + + URI actual = this.handler.expand(template, vars); + + URI expected = new URI("http://example.com/hotels/1/pic/pics/logo.png"); + assertEquals(expected, actual); + } + + @Test + public void expandWithFullPathAndParsePathEnabled() throws Exception { + Map<String, String> vars = new HashMap<String, String>(2); + vars.put("hotel", "1"); + vars.put("publicpath", "pics/logo.png"); + vars.put("scale", "150x150"); + String template = "http://example.com/hotels/{hotel}/pic/{publicpath}/size/{scale}"; + + this.handler.setParsePath(true); + URI actual = this.handler.expand(template, vars); + + URI expected = new URI("http://example.com/hotels/1/pic/pics%2Flogo.png/size/150x150"); + assertEquals(expected, actual); + } + +} diff --git a/spring-web/src/test/java/org/springframework/web/util/Log4jWebConfigurerTests.java b/spring-web/src/test/java/org/springframework/web/util/Log4jWebConfigurerTests.java index 78b587ef..5001f9fb 100644 --- a/spring-web/src/test/java/org/springframework/web/util/Log4jWebConfigurerTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/Log4jWebConfigurerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -17,23 +17,27 @@ package org.springframework.web.util; import java.net.URL; + import javax.servlet.ServletContextEvent; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.junit.Ignore; + import org.junit.Test; import org.springframework.core.io.FileSystemResourceLoader; import org.springframework.mock.web.test.MockServletContext; +import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; +import static org.junit.Assume.*; /** * @author Juergen Hoeller * @author Sam Brannen * @since 21.02.2005 */ +@SuppressWarnings("deprecation") public class Log4jWebConfigurerTests { private static final String TESTLOG4J_PROPERTIES = "testlog4j.properties"; @@ -78,9 +82,11 @@ public class Log4jWebConfigurerTests { initLogging(url.toString(), true); } - @Ignore("Only works on MS Windows") @Test public void initLoggingWithAbsoluteFilePathAndRefreshInterval() { + // Only works on MS Windows + assumeThat(System.getProperty("os.name"), containsString("Windows")); + URL url = Log4jWebConfigurerTests.class.getResource(TESTLOG4J_PROPERTIES); initLogging(url.getFile(), true); } diff --git a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java index e7677936..6b5e40e8 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java @@ -16,17 +16,10 @@ package org.springframework.web.util; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -39,12 +32,17 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + /** * Unit tests for {@link org.springframework.web.util.UriComponentsBuilder}. * * @author Arjen Poutsma * @author Phillip Webb * @author Oliver Gierke + * @author David Eckel + * @author Sam Brannen */ public class UriComponentsBuilderTests { @@ -436,6 +434,15 @@ public class UriComponentsBuilderTests { assertEquals("https://a.example.org/mvc-showcase", result.toString()); } + // SPR-12742 + + @Test + public void fromHttpRequestWithTrailingSlash() throws Exception { + UriComponents before = UriComponentsBuilder.fromPath("/foo/").build(); + UriComponents after = UriComponentsBuilder.newInstance().uriComponents(before).build(); + assertEquals("/foo/", after.getPath()); + } + @Test public void path() throws URISyntaxException { UriComponentsBuilder builder = UriComponentsBuilder.fromPath("/foo/bar"); @@ -487,7 +494,7 @@ public class UriComponentsBuilderTests { UriComponents result = builder.build(); assertEquals("/foo/", result.getPath()); - assertEquals(Arrays.asList("foo"), result.getPathSegments()); + assertEquals(Collections.singletonList("foo"), result.getPathSegments()); } @Test @@ -603,18 +610,23 @@ public class UriComponentsBuilderTests { public void queryParamWithValueWithEquals() throws Exception { UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/foo?bar=baz").build(); assertThat(uriComponents.toUriString(), equalTo("http://example.com/foo?bar=baz")); + assertThat(uriComponents.getQueryParams().get("bar").get(0), equalTo("baz")); } @Test public void queryParamWithoutValueWithEquals() throws Exception { UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/foo?bar=").build(); assertThat(uriComponents.toUriString(), equalTo("http://example.com/foo?bar=")); + assertThat(uriComponents.getQueryParams().get("bar").get(0), equalTo("")); } @Test public void queryParamWithoutValueWithoutEquals() throws Exception { UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://example.com/foo?bar").build(); assertThat(uriComponents.toUriString(), equalTo("http://example.com/foo?bar")); + + // TODO [SPR-13537] Change equalTo(null) to equalTo(""). + assertThat(uriComponents.getQueryParams().get("bar").get(0), equalTo(null)); } @Test @@ -645,6 +657,12 @@ public class UriComponentsBuilderTests { assertThat(components.toString(), equalTo("/example")); } + @Test // SPR-13257 + public void parsesEmptyUri() { + UriComponents components = UriComponentsBuilder.fromUriString("").build(); + assertThat(components.toString(), equalTo("")); + } + @Test public void testClone() throws URISyntaxException { UriComponentsBuilder builder1 = UriComponentsBuilder.newInstance(); @@ -668,4 +686,71 @@ public class UriComponentsBuilderTests { assertEquals("f2", result2.getFragment()); } + // SPR-11856 + + @Test + public void fromHttpRequestForwardedHeader() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader("Forwarded", "proto=https; host=84.198.58.199"); + request.setScheme("http"); + request.setServerName("example.com"); + request.setRequestURI("/rest/mobile/users/1"); + + HttpRequest httpRequest = new ServletServerHttpRequest(request); + UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build(); + + assertEquals("https", result.getScheme()); + assertEquals("84.198.58.199", result.getHost()); + assertEquals("/rest/mobile/users/1", result.getPath()); + } + + @Test + public void fromHttpRequestForwardedHeaderQuoted() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader("Forwarded", "proto=\"https\"; host=\"84.198.58.199\""); + request.setScheme("http"); + request.setServerName("example.com"); + request.setRequestURI("/rest/mobile/users/1"); + + HttpRequest httpRequest = new ServletServerHttpRequest(request); + UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build(); + + assertEquals("https", result.getScheme()); + assertEquals("84.198.58.199", result.getHost()); + assertEquals("/rest/mobile/users/1", result.getPath()); + } + + @Test + public void fromHttpRequestMultipleForwardedHeader() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader("Forwarded", "host=84.198.58.199;proto=https"); + request.addHeader("Forwarded", "proto=ftp; host=1.2.3.4"); + request.setScheme("http"); + request.setServerName("example.com"); + request.setRequestURI("/rest/mobile/users/1"); + + HttpRequest httpRequest = new ServletServerHttpRequest(request); + UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build(); + + assertEquals("https", result.getScheme()); + assertEquals("84.198.58.199", result.getHost()); + assertEquals("/rest/mobile/users/1", result.getPath()); + } + + @Test + public void fromHttpRequestMultipleForwardedHeaderComma() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.addHeader("Forwarded", "host=84.198.58.199 ;proto=https, proto=ftp; host=1.2.3.4"); + request.setScheme("http"); + request.setServerName("example.com"); + request.setRequestURI("/rest/mobile/users/1"); + + HttpRequest httpRequest = new ServletServerHttpRequest(request); + UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build(); + + assertEquals("https", result.getScheme()); + assertEquals("84.198.58.199", result.getHost()); + assertEquals("/rest/mobile/users/1", result.getPath()); + } + } diff --git a/spring-web/src/test/java/org/springframework/web/util/UriComponentsTests.java b/spring-web/src/test/java/org/springframework/web/util/UriComponentsTests.java index 54406188..7a43337c 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriComponentsTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriComponentsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -22,12 +22,17 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.URI; import java.net.URISyntaxException; +import java.util.Arrays; +import java.util.Collections; import org.junit.Test; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; -import static org.springframework.web.util.UriComponentsBuilder.*; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.springframework.web.util.UriComponentsBuilder.fromUriString; /** * @author Arjen Poutsma @@ -81,6 +86,16 @@ public class UriComponentsTests { assertEquals("http://example.com/1 2 3 4", uriComponents.toUriString()); } + // SPR-13311 + + @Test + public void expandWithRegexVar() { + String template = "/myurl/{name:[a-z]{1,5}}/show"; + UriComponents uriComponents = UriComponentsBuilder.fromUriString(template).build(); + uriComponents = uriComponents.expand(Collections.singletonMap("name", "test")); + assertEquals("/myurl/test/show", uriComponents.getPath()); + } + // SPR-12123 @Test @@ -133,6 +148,16 @@ public class UriComponentsTests { } @Test + public void copyToUriComponentsBuilder() { + UriComponents source = UriComponentsBuilder.fromPath("/foo/bar").pathSegment("ba/z").build(); + UriComponentsBuilder targetBuilder = UriComponentsBuilder.newInstance(); + source.copyToUriComponentsBuilder(targetBuilder); + UriComponents result = targetBuilder.build().encode(); + assertEquals("/foo/bar/ba%2Fz", result.getPath()); + assertEquals(Arrays.asList("foo", "bar", "ba%2Fz"), result.getPathSegments()); + } + + @Test public void equalsHierarchicalUriComponents() throws Exception { UriComponents uriComponents1 = UriComponentsBuilder.fromUriString("http://example.com").path("/{foo}").query("bar={baz}").build(); UriComponents uriComponents2 = UriComponentsBuilder.fromUriString("http://example.com").path("/{foo}").query("bar={baz}").build(); diff --git a/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java b/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java index ebd3cea2..a047af03 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -143,6 +143,15 @@ public class UriTemplateTests { assertEquals("Invalid match", expected, result); } + // SPR-13627 + + @Test + public void matchCustomRegexWithNestedCurlyBraces() throws Exception { + UriTemplate template = new UriTemplate("/site.{domain:co.[a-z]{2}}"); + Map<String, String> result = template.match("/site.co.eu"); + assertEquals("Invalid match", Collections.singletonMap("domain", "co.eu"), result); + } + @Test public void matchDuplicate() throws Exception { UriTemplate template = new UriTemplate("/order/{c}/{c}/{c}"); @@ -176,6 +185,14 @@ public class UriTemplateTests { assertTrue(template.matches("/search?query=foo#bar")); } + // SPR-13705 + + @Test + public void matchesWithSlashAtTheEnd() { + UriTemplate uriTemplate = new UriTemplate("/test/"); + assertTrue(uriTemplate.matches("/test/")); + } + @Test public void expandWithDollar() { UriTemplate template = new UriTemplate("/{a}"); diff --git a/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java index 81dbcd12..6480c5fa 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java @@ -104,62 +104,4 @@ public class UriUtilsTests { UriUtils.decode("foo%2", ENC); } - @Test - @Deprecated - public void encodeUri() throws UnsupportedEncodingException { - assertEquals("Invalid encoded URI", "http://www.ietf.org/rfc/rfc3986.txt", - UriUtils.encodeUri("http://www.ietf.org/rfc/rfc3986.txt", ENC)); - assertEquals("Invalid encoded URI", "https://www.ietf.org/rfc/rfc3986.txt", - UriUtils.encodeUri("https://www.ietf.org/rfc/rfc3986.txt", ENC)); - assertEquals("Invalid encoded URI", "http://www.google.com/?q=Z%C3%BCrich", - UriUtils.encodeUri("http://www.google.com/?q=Z\u00fcrich", ENC)); - assertEquals("Invalid encoded URI", - "http://arjen:foobar@java.sun.com:80/javase/6/docs/api/java/util/BitSet.html?foo=bar#and(java.util.BitSet)", - UriUtils.encodeUri( - "http://arjen:foobar@java.sun.com:80/javase/6/docs/api/java/util/BitSet.html?foo=bar#and(java.util.BitSet)", - ENC)); - assertEquals("Invalid encoded URI", "http://java.sun.com/j2se/1.3/", - UriUtils.encodeUri("http://java.sun.com/j2se/1.3/", ENC)); - assertEquals("Invalid encoded URI", "docs/guide/collections/designfaq.html#28", - UriUtils.encodeUri("docs/guide/collections/designfaq.html#28", ENC)); - assertEquals("Invalid encoded URI", "../../../demo/jfc/SwingSet2/src/SwingSet2.java", - UriUtils.encodeUri("../../../demo/jfc/SwingSet2/src/SwingSet2.java", ENC)); - assertEquals("Invalid encoded URI", "file:///~/calendar", UriUtils.encodeUri("file:///~/calendar", ENC)); - assertEquals("Invalid encoded URI", "http://example.com/query=foo@bar", - UriUtils.encodeUri("http://example.com/query=foo@bar", ENC)); - - // SPR-8974 - assertEquals("http://example.org?format=json&url=http://another.com?foo=bar", - UriUtils.encodeUri("http://example.org?format=json&url=http://another.com?foo=bar", ENC)); - } - - @Test - @Deprecated - public void encodeHttpUrl() throws UnsupportedEncodingException { - assertEquals("Invalid encoded HTTP URL", "http://www.ietf.org/rfc/rfc3986.txt", - UriUtils.encodeHttpUrl("http://www.ietf.org/rfc/rfc3986.txt", ENC)); - assertEquals("Invalid encoded URI", "https://www.ietf.org/rfc/rfc3986.txt", - UriUtils.encodeHttpUrl("https://www.ietf.org/rfc/rfc3986.txt", ENC)); - assertEquals("Invalid encoded HTTP URL", "http://www.google.com/?q=Z%C3%BCrich", - UriUtils.encodeHttpUrl("http://www.google.com/?q=Z\u00fcrich", ENC)); - assertEquals("Invalid encoded HTTP URL", "http://ws.geonames.org/searchJSON?q=T%C5%8Dky%C5%8D&style=FULL&maxRows=300", - UriUtils.encodeHttpUrl("http://ws.geonames.org/searchJSON?q=T\u014dky\u014d&style=FULL&maxRows=300", ENC)); - assertEquals("Invalid encoded HTTP URL", - "http://arjen:foobar@java.sun.com:80/javase/6/docs/api/java/util/BitSet.html?foo=bar", - UriUtils.encodeHttpUrl( - "http://arjen:foobar@java.sun.com:80/javase/6/docs/api/java/util/BitSet.html?foo=bar", ENC)); - assertEquals("Invalid encoded HTTP URL", "http://search.twitter.com/search.atom?q=%23avatar", - UriUtils.encodeHttpUrl("http://search.twitter.com/search.atom?q=#avatar", ENC)); - assertEquals("Invalid encoded HTTP URL", "http://java.sun.com/j2se/1.3/", - UriUtils.encodeHttpUrl("http://java.sun.com/j2se/1.3/", ENC)); - assertEquals("Invalid encoded HTTP URL", "http://example.com/query=foo@bar", - UriUtils.encodeHttpUrl("http://example.com/query=foo@bar", ENC)); - } - - @Test(expected = IllegalArgumentException.class) - @Deprecated - public void encodeHttpUrlMail() throws UnsupportedEncodingException { - UriUtils.encodeHttpUrl("mailto:java-net@java.sun.com", ENC); - } - } diff --git a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java index 7ef44076..9c75abf6 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -18,7 +18,6 @@ package org.springframework.web.util; import java.io.UnsupportedEncodingException; -import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -27,23 +26,20 @@ import org.springframework.mock.web.test.MockHttpServletRequest; import static org.junit.Assert.*; /** + * Unit tests for {@link UrlPathHelper}. + * * @author Rob Harrop * @author Juergen Hoeller * @author Costin Leau */ public class UrlPathHelperTests { - private UrlPathHelper helper; + private static final String WEBSPHERE_URI_ATTRIBUTE = "com.ibm.websphere.servlet.uri_non_decoded"; - private MockHttpServletRequest request; + private final UrlPathHelper helper = new UrlPathHelper(); - private static final String WEBSPHERE_URI_ATTRIBUTE = "com.ibm.websphere.servlet.uri_non_decoded"; + private final MockHttpServletRequest request = new MockHttpServletRequest(); - @Before - public void setUp() { - helper = new UrlPathHelper(); - request = new MockHttpServletRequest(); - } @Test public void getPathWithinApplication() { @@ -78,6 +74,16 @@ public class UrlPathHelperTests { assertEquals("Incorrect path returned", "/welcome.html", helper.getPathWithinServletMapping(request)); } + @Test + public void alwaysUseFullPath() { + helper.setAlwaysUseFullPath(true); + request.setContextPath("/petclinic"); + request.setServletPath("/main"); + request.setRequestURI("/petclinic/main/welcome.html"); + + assertEquals("Incorrect path returned", "/main/welcome.html", helper.getLookupPathForRequest(request)); + } + // SPR-11101 @Test @@ -102,7 +108,6 @@ public class UrlPathHelperTests { request.setRequestURI("/foo+bar"); assertEquals("Incorrect path returned", "/foo+bar", helper.getRequestUri(request)); - } @Test @@ -111,6 +116,13 @@ public class UrlPathHelperTests { request.setRequestURI("/foo;f=F;o=O;o=O/bar;b=B;a=A;r=R"); assertEquals("/foo/bar", helper.getRequestUri(request)); + + // SPR-13455 + + request.setServletPath("/foo/1"); + request.setRequestURI("/foo/;test/1"); + + assertEquals("/foo/1", helper.getRequestUri(request)); } @Test @@ -194,6 +206,28 @@ public class UrlPathHelperTests { assertEquals("/foo/", helper.getLookupPathForRequest(request)); } + //SPR-12372 & SPR-13455 + @Test + public void removeDuplicateSlashesInPath() throws Exception { + request.setContextPath("/SPR-12372"); + request.setPathInfo(null); + request.setServletPath("/foo/bar/"); + request.setRequestURI("/SPR-12372/foo//bar/"); + + assertEquals("/foo/bar/", helper.getLookupPathForRequest(request)); + + request.setServletPath("/foo/bar/"); + request.setRequestURI("/SPR-12372/foo/bar//"); + + assertEquals("/foo/bar/", helper.getLookupPathForRequest(request)); + + // "normal" case + request.setServletPath("/foo/bar//"); + request.setRequestURI("/SPR-12372/foo/bar//"); + + assertEquals("/foo/bar//", helper.getLookupPathForRequest(request)); + } + @Test public void wasDefaultServletRoot() throws Exception { request.setContextPath("/test"); @@ -315,7 +349,8 @@ public class UrlPathHelperTests { } // test the root mapping for /foo/* w/o a trailing slash - <host>/<context>/foo - @Test @Ignore + @Ignore + @Test public void wasCasualServletRootWithMissingSlash() throws Exception { request.setContextPath("/test"); request.setPathInfo(null); @@ -326,7 +361,8 @@ public class UrlPathHelperTests { assertEquals("/", helper.getLookupPathForRequest(request)); } - @Test @Ignore + @Ignore + @Test public void wasCasualServletRootWithMissingSlashWithCompliantSetting() throws Exception { request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo"); tomcatCasualServletRootWithMissingSlash(); @@ -367,6 +403,26 @@ public class UrlPathHelperTests { } @Test + public void getOriginatingRequestUri() { + request.setAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE, "/path"); + request.setRequestURI("/forwarded"); + assertEquals("/path", helper.getOriginatingRequestUri(request)); + } + + @Test + public void getOriginatingRequestUriWebsphere() { + request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/path"); + request.setRequestURI("/forwarded"); + assertEquals("/path", helper.getOriginatingRequestUri(request)); + } + + @Test + public void getOriginatingRequestUriDefault() { + request.setRequestURI("/forwarded"); + assertEquals("/forwarded", helper.getOriginatingRequestUri(request)); + } + + @Test public void getOriginatingQueryString() { request.setQueryString("forward=on"); request.setAttribute(WebUtils.FORWARD_REQUEST_URI_ATTRIBUTE, "/path"); diff --git a/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java index ea662533..1ad98fd2 100644 --- a/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/WebUtilsTests.java @@ -16,8 +16,6 @@ package org.springframework.web.util; -import static org.junit.Assert.*; - import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -32,6 +30,8 @@ import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.util.MultiValueMap; +import static org.junit.Assert.*; + /** * @author Juergen Hoeller * @author Arjen Poutsma @@ -114,37 +114,65 @@ public class WebUtilsTests { } @Test - public void isValidOriginSuccess() { - + public void isValidOrigin() { List<String> allowed = Collections.emptyList(); - assertTrue(checkOrigin("mydomain1.com", -1, "http://mydomain1.com", allowed)); - assertTrue(checkOrigin("mydomain1.com", -1, "http://mydomain1.com:80", allowed)); - assertTrue(checkOrigin("mydomain1.com", 443, "https://mydomain1.com", allowed)); - assertTrue(checkOrigin("mydomain1.com", 443, "https://mydomain1.com:443", allowed)); - assertTrue(checkOrigin("mydomain1.com", 123, "http://mydomain1.com:123", allowed)); - assertTrue(checkOrigin("mydomain1.com", -1, "ws://mydomain1.com", allowed)); - assertTrue(checkOrigin("mydomain1.com", 443, "wss://mydomain1.com", allowed)); + assertTrue(checkValidOrigin("mydomain1.com", -1, "http://mydomain1.com", allowed)); + assertFalse(checkValidOrigin("mydomain1.com", -1, "http://mydomain2.com", allowed)); allowed = Collections.singletonList("*"); - assertTrue(checkOrigin("mydomain1.com", -1, "http://mydomain2.com", allowed)); + assertTrue(checkValidOrigin("mydomain1.com", -1, "http://mydomain2.com", allowed)); allowed = Collections.singletonList("http://mydomain1.com"); - assertTrue(checkOrigin("mydomain2.com", -1, "http://mydomain1.com", allowed)); + assertTrue(checkValidOrigin("mydomain2.com", -1, "http://mydomain1.com", allowed)); + assertFalse(checkValidOrigin("mydomain2.com", -1, "http://mydomain3.com", allowed)); } @Test - public void isValidOriginFailure() { + public void isSameOrigin() { + assertTrue(checkSameOrigin("mydomain1.com", -1, "http://mydomain1.com")); + assertTrue(checkSameOrigin("mydomain1.com", -1, "http://mydomain1.com:80")); + assertTrue(checkSameOrigin("mydomain1.com", 443, "https://mydomain1.com")); + assertTrue(checkSameOrigin("mydomain1.com", 443, "https://mydomain1.com:443")); + assertTrue(checkSameOrigin("mydomain1.com", 123, "http://mydomain1.com:123")); + assertTrue(checkSameOrigin("mydomain1.com", -1, "ws://mydomain1.com")); + assertTrue(checkSameOrigin("mydomain1.com", 443, "wss://mydomain1.com")); + + assertFalse(checkSameOrigin("mydomain1.com", -1, "http://mydomain2.com")); + assertFalse(checkSameOrigin("mydomain1.com", -1, "https://mydomain1.com")); + assertFalse(checkSameOrigin("mydomain1.com", -1, "invalid-origin")); + + // Handling of invalid origins as described in SPR-13478 + assertTrue(checkSameOrigin("mydomain1.com", -1, "http://mydomain1.com/")); + assertTrue(checkSameOrigin("mydomain1.com", -1, "http://mydomain1.com:80/")); + assertTrue(checkSameOrigin("mydomain1.com", -1, "http://mydomain1.com/path")); + assertTrue(checkSameOrigin("mydomain1.com", -1, "http://mydomain1.com:80/path")); + assertFalse(checkSameOrigin("mydomain2.com", -1, "http://mydomain1.com/")); + assertFalse(checkSameOrigin("mydomain2.com", -1, "http://mydomain1.com:80/")); + assertFalse(checkSameOrigin("mydomain2.com", -1, "http://mydomain1.com/path")); + assertFalse(checkSameOrigin("mydomain2.com", -1, "http://mydomain1.com:80/path")); + + // Handling of IPv6 hosts as described in SPR-13525 + assertTrue(checkSameOrigin("[::1]", -1, "http://[::1]")); + assertTrue(checkSameOrigin("[::1]", 8080, "http://[::1]:8080")); + assertTrue(checkSameOrigin("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]", -1, "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]")); + assertTrue(checkSameOrigin("[2001:0db8:0000:85a3:0000:0000:ac1f:8001]", 8080, "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8080")); + assertFalse(checkSameOrigin("[::1]", -1, "http://[::1]:8080")); + assertFalse(checkSameOrigin("[::1]", 8080, "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8080")); + } - List<String> allowed = Collections.emptyList(); - assertFalse(checkOrigin("mydomain1.com", -1, "http://mydomain2.com", allowed)); - assertFalse(checkOrigin("mydomain1.com", -1, "https://mydomain1.com", allowed)); - assertFalse(checkOrigin("mydomain1.com", -1, "invalid-origin", allowed)); - allowed = Collections.singletonList("http://mydomain1.com"); - assertFalse(checkOrigin("mydomain2.com", -1, "http://mydomain3.com", allowed)); + private boolean checkValidOrigin(String serverName, int port, String originHeader, List<String> allowed) { + MockHttpServletRequest servletRequest = new MockHttpServletRequest(); + ServerHttpRequest request = new ServletServerHttpRequest(servletRequest); + servletRequest.setServerName(serverName); + if (port != -1) { + servletRequest.setServerPort(port); + } + request.getHeaders().set(HttpHeaders.ORIGIN, originHeader); + return WebUtils.isValidOrigin(request, allowed); } - private boolean checkOrigin(String serverName, int port, String originHeader, List<String> allowed) { + private boolean checkSameOrigin(String serverName, int port, String originHeader) { MockHttpServletRequest servletRequest = new MockHttpServletRequest(); ServerHttpRequest request = new ServletServerHttpRequest(servletRequest); servletRequest.setServerName(serverName); @@ -152,7 +180,7 @@ public class WebUtilsTests { servletRequest.setServerPort(port); } request.getHeaders().set(HttpHeaders.ORIGIN, originHeader); - return WebUtils.isValidOrigin(request, allowed); + return WebUtils.isSameOrigin(request); } } |