You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:14:01 UTC
[sling-org-apache-sling-servlet-helpers] 01/06: SLING-5428 Move
MockSlingHttpServletRequest+Response to org.apache.sling.servlet-helpers
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.servlet-helpers-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-servlet-helpers.git
commit 43ed44156fb5a29a1948b2661a9fbffd0bc03ddc
Author: Stefan Seifert <ss...@apache.org>
AuthorDate: Wed Jan 13 23:07:09 2016 +0000
SLING-5428 Move MockSlingHttpServletRequest+Response to org.apache.sling.servlet-helpers
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/servlet-helpers@1724523 13f79535-47bb-0310-9956-ffa450edef68
---
README.txt | 29 +
pom.xml | 106 +++
.../apache/sling/servlethelpers/CookieSupport.java | 53 ++
.../apache/sling/servlethelpers/HeaderSupport.java | 175 +++++
.../sling/servlethelpers/MockHttpSession.java | 169 +++++
.../MockRequestDispatcherFactory.java | 51 ++
.../sling/servlethelpers/MockRequestParameter.java | 105 +++
.../servlethelpers/MockRequestParameterMap.java | 101 +++
.../sling/servlethelpers/MockRequestPathInfo.java | 89 +++
.../sling/servlethelpers/MockServletContext.java | 304 ++++++++
.../MockSlingHttpServletRequest.java | 805 +++++++++++++++++++++
.../MockSlingHttpServletResponse.java | 282 ++++++++
.../sling/servlethelpers/ResponseBodySupport.java | 100 +++
.../apache/sling/servlethelpers/package-info.java | 23 +
.../sling/servlethelpers/MockHttpSessionTest.java | 103 +++
.../servlethelpers/MockRequestPathInfoTest.java | 69 ++
.../servlethelpers/MockServletContextTest.java | 43 ++
.../MockSlingHttpServletRequestTest.java | 328 +++++++++
.../MockSlingHttpServletResponseTest.java | 177 +++++
19 files changed, 3112 insertions(+)
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..64e9bb4
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,29 @@
+Apache Sling Servlet Helpers
+
+Mock implementations of SlingHttpServletRequest, SlingHttpServletRepsonse and related classes.
+
+These are used by sling-mock, but can be used standalone and deployed to an OSGi container as well.
+
+
+Getting Started
+===============
+
+This component uses a Maven 2 (http://maven.apache.org/) build
+environment. It requires a Java 5 JDK (or higher) and Maven (http://maven.apache.org/)
+2.0.7 or later. We recommend to use the latest Maven version.
+
+If you have Maven 2 installed, you can compile and
+package the jar using the following command:
+
+ mvn package
+
+See the Maven 2 documentation for other build features.
+
+The latest source code for this component is available in the
+Subversion (http://subversion.tigris.org/) source repository of
+the Apache Software Foundation. If you have Subversion installed,
+you can checkout the latest source using the following command:
+
+ svn checkout http://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/servlet-helpers
+
+See the Subversion documentation for other source control features.
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..56f63db
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>sling</artifactId>
+ <version>26</version>
+ <relativePath/>
+ </parent>
+
+ <artifactId>org.apache.sling.servlet-helpers</artifactId>
+ <packaging>bundle</packaging>
+ <version>1.0.0-SNAPSHOT</version>
+
+ <name>Apache Sling Servlet Helpers</name>
+ <description>Mock implementations of SlingHttpServletRequest, SlingHttpServletRepsonse and related classes.</description>
+
+ <scm>
+ <connection>
+ scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/servlet-helpers
+ </connection>
+ <developerConnection>
+ scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/servlet-helpers
+ </developerConnection>
+ <url>
+ http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/servlet-helpers
+ </url>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>3.0.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.api</artifactId>
+ <version>2.4.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.0.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>3.2.1</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.4</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.9.5</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+</project>
diff --git a/src/main/java/org/apache/sling/servlethelpers/CookieSupport.java b/src/main/java/org/apache/sling/servlethelpers/CookieSupport.java
new file mode 100644
index 0000000..ffdde3c
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/CookieSupport.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.servlet.http.Cookie;
+
+/**
+ * Manages cookies for request and response.
+ */
+class CookieSupport {
+
+ private Map<String, Cookie> cookies = new LinkedHashMap<String, Cookie>();
+
+ public void addCookie(Cookie cookie) {
+ cookies.put(cookie.getName(), cookie);
+ }
+
+ public Cookie getCookie(String name) {
+ return cookies.get(name);
+ }
+
+ public Cookie[] getCookies() {
+ if (cookies.isEmpty()) {
+ return null;
+ } else {
+ return cookies.values().toArray(new Cookie[cookies.size()]);
+ }
+ }
+
+ public void reset() {
+ cookies.clear();
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/servlethelpers/HeaderSupport.java b/src/main/java/org/apache/sling/servlethelpers/HeaderSupport.java
new file mode 100644
index 0000000..48a5f39
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/HeaderSupport.java
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.Vector;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+
+/**
+ * Manage HTTP headers for request and response.
+ */
+class HeaderSupport {
+
+ private static final String RFC_1123_DATE_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z";
+ private static final DateFormat RFC1123_DATE_FORMAT = new SimpleDateFormat(RFC_1123_DATE_PATTERN, Locale.US);
+ private static final TimeZone TIMEZONE_GMT = TimeZone.getTimeZone("GMT");
+ static {
+ RFC1123_DATE_FORMAT.setTimeZone(TIMEZONE_GMT);
+ }
+
+ private List<HeaderValue> headers = new ArrayList<HeaderValue>();
+
+ private static class HeaderValue {
+
+ private String key;
+ private String value;
+
+ public HeaderValue(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return this.key;
+ }
+
+ public String getValue() {
+ return this.value;
+ }
+
+ }
+
+ public void addHeader(String name, String value) {
+ headers.add(new HeaderValue(name, value));
+ }
+
+ public void addIntHeader(String name, int value) {
+ headers.add(new HeaderValue(name, Integer.toString(value)));
+ }
+
+ public void addDateHeader(String name, long date) {
+ Calendar calendar = Calendar.getInstance(TIMEZONE_GMT, Locale.US);
+ calendar.setTimeInMillis(date);
+ headers.add(new HeaderValue(name, formatDate(calendar)));
+ }
+
+ public void setHeader(String name, String value) {
+ removeHeaders(name);
+ addHeader(name, value);
+ }
+
+ public void setIntHeader(String name, int value) {
+ removeHeaders(name);
+ addIntHeader(name, value);
+ }
+
+ public void setDateHeader(String name, long date) {
+ removeHeaders(name);
+ addDateHeader(name, date);
+ }
+
+ private void removeHeaders(String name) {
+ for (int i = this.headers.size() - 1; i >= 0; i--) {
+ if (StringUtils.equals(this.headers.get(i).getKey(), name)) {
+ headers.remove(i);
+ }
+ }
+ }
+
+ public boolean containsHeader(String name) {
+ return !getHeaders(name).isEmpty();
+ }
+
+ public String getHeader(String name) {
+ Collection<String> values = getHeaders(name);
+ if (!values.isEmpty()) {
+ return values.iterator().next();
+ } else {
+ return null;
+ }
+ }
+
+ public int getIntHeader(String name) {
+ String value = getHeader(name);
+ return NumberUtils.toInt(value);
+ }
+
+ public long getDateHeader(String name) {
+ String value = getHeader(name);
+ if (StringUtils.isEmpty(value)) {
+ return 0L;
+ } else {
+ try {
+ return parseDate(value).getTimeInMillis();
+ } catch (ParseException ex) {
+ return 0L;
+ }
+ }
+ }
+
+ public Collection<String> getHeaders(String name) {
+ List<String> values = new ArrayList<String>();
+ for (HeaderValue entry : headers) {
+ if (StringUtils.equals(entry.getKey(), name)) {
+ values.add(entry.getValue());
+ }
+ }
+ return values;
+ }
+
+ public Collection<String> getHeaderNames() {
+ Set<String> values = new HashSet<String>();
+ for (HeaderValue entry : headers) {
+ values.add(entry.getKey());
+ }
+ return values;
+ }
+
+ public void reset() {
+ headers.clear();
+ }
+
+ public static Enumeration<String> toEnumeration(Collection<String> collection) {
+ return new Vector<String>(collection).elements();
+ }
+
+ private static synchronized String formatDate(Calendar date) {
+ return RFC1123_DATE_FORMAT.format(date.getTime());
+ }
+
+ private static synchronized Calendar parseDate(String dateString) throws ParseException {
+ RFC1123_DATE_FORMAT.parse(dateString);
+ return RFC1123_DATE_FORMAT.getCalendar();
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/servlethelpers/MockHttpSession.java b/src/main/java/org/apache/sling/servlethelpers/MockHttpSession.java
new file mode 100644
index 0000000..31d672b
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/MockHttpSession.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.collections.IteratorUtils;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * Mock {@link HttpSession} implementation.
+ */
+@ConsumerType
+public class MockHttpSession implements HttpSession {
+
+ private final ServletContext servletContext;
+ private final Map<String, Object> attributeMap = new HashMap<String, Object>();
+ private final String sessionID = UUID.randomUUID().toString();
+ private final long creationTime = System.currentTimeMillis();
+ private boolean invalidated = false;
+ private boolean isNew = true;
+ private int maxActiveInterval = 1800;
+
+ public MockHttpSession() {
+ this.servletContext = newMockServletContext();
+ }
+
+ protected MockServletContext newMockServletContext() {
+ return new MockServletContext();
+ }
+
+ @Override
+ public ServletContext getServletContext() {
+ return this.servletContext;
+ }
+
+ @Override
+ public Object getAttribute(final String name) {
+ checkInvalidatedState();
+ return this.attributeMap.get(name);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Enumeration<String> getAttributeNames() {
+ checkInvalidatedState();
+ return IteratorUtils.asEnumeration(this.attributeMap.keySet().iterator());
+ }
+
+ @Override
+ public String getId() {
+ return this.sessionID;
+ }
+
+ @Override
+ public long getCreationTime() {
+ checkInvalidatedState();
+ return this.creationTime;
+ }
+
+ @Override
+ public Object getValue(final String name) {
+ checkInvalidatedState();
+ return getAttribute(name);
+ }
+
+ @Override
+ public String[] getValueNames() {
+ checkInvalidatedState();
+ return this.attributeMap.keySet().toArray(new String[this.attributeMap.keySet().size()]);
+ }
+
+ @Override
+ public void putValue(final String name, final Object value) {
+ checkInvalidatedState();
+ setAttribute(name, value);
+ }
+
+ @Override
+ public void removeAttribute(final String name) {
+ checkInvalidatedState();
+ this.attributeMap.remove(name);
+ }
+
+ @Override
+ public void removeValue(final String name) {
+ checkInvalidatedState();
+ this.attributeMap.remove(name);
+ }
+
+ @Override
+ public void setAttribute(final String name, final Object value) {
+ checkInvalidatedState();
+ this.attributeMap.put(name, value);
+ }
+
+ @Override
+ public void invalidate() {
+ checkInvalidatedState();
+ this.invalidated = true;
+ }
+
+ private void checkInvalidatedState() {
+ if (invalidated) {
+ throw new IllegalStateException("Session is already invalidated.");
+ }
+ }
+
+ public boolean isInvalidated() {
+ return invalidated;
+ }
+
+ @Override
+ public boolean isNew() {
+ checkInvalidatedState();
+ return isNew;
+ }
+
+ public void setNew(boolean isNew) {
+ this.isNew = isNew;
+ }
+
+ @Override
+ public long getLastAccessedTime() {
+ checkInvalidatedState();
+ return creationTime;
+ }
+
+ @Override
+ public int getMaxInactiveInterval() {
+ return maxActiveInterval;
+ }
+
+ @Override
+ public void setMaxInactiveInterval(final int interval) {
+ this.maxActiveInterval = interval;
+ }
+
+ // --- unsupported operations ---
+ @Override
+ @SuppressWarnings("deprecation")
+ public javax.servlet.http.HttpSessionContext getSessionContext() {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/servlethelpers/MockRequestDispatcherFactory.java b/src/main/java/org/apache/sling/servlethelpers/MockRequestDispatcherFactory.java
new file mode 100644
index 0000000..5664035
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/MockRequestDispatcherFactory.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import javax.servlet.RequestDispatcher;
+
+import org.apache.sling.api.request.RequestDispatcherOptions;
+import org.apache.sling.api.resource.Resource;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * Interface to create a mock {@link RequestDispatcher} when calling the getRequestDispatcher methods
+ * on {@link MockSlingHttpServletRequest} instances.
+ */
+@ConsumerType
+public interface MockRequestDispatcherFactory {
+
+ /**
+ * Get request dispatcher for given path.
+ * @param path Path
+ * @param options Options. Null if no options are provided.
+ * @return Request dispatcher
+ */
+ RequestDispatcher getRequestDispatcher(String path, RequestDispatcherOptions options);
+
+ /**
+ * Get request dispatcher for given resource.
+ * @param resource Resource
+ * @param options Options. Null if no options are provided.
+ * @return Request dispatcher
+ */
+ RequestDispatcher getRequestDispatcher(Resource resource, RequestDispatcherOptions options);
+
+}
diff --git a/src/main/java/org/apache/sling/servlethelpers/MockRequestParameter.java b/src/main/java/org/apache/sling/servlethelpers/MockRequestParameter.java
new file mode 100644
index 0000000..2c77e3b
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/MockRequestParameter.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.sling.api.request.RequestParameter;
+
+/**
+ * Mock implementation of {@link RequestParameter}.
+ */
+class MockRequestParameter implements RequestParameter {
+
+ private String name;
+ private String encoding = "UTF-8";
+ private String value;
+
+ private byte[] content;
+
+ public MockRequestParameter(String name, String value) {
+ this.value = value;
+ this.content = null;
+ }
+ void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ public String getEncoding() {
+ return this.encoding;
+ }
+
+ public byte[] get() {
+ if (content == null) {
+ try {
+ content = getString().getBytes(getEncoding());
+ } catch (Exception e) {
+ // UnsupportedEncodingException, IllegalArgumentException
+ content = getString().getBytes();
+ }
+ }
+ return content;
+ }
+
+ public String getContentType() {
+ // none known for www-form-encoded parameters
+ return null;
+ }
+
+ public InputStream getInputStream() {
+ return new ByteArrayInputStream(this.get());
+ }
+
+ public String getFileName() {
+ // no original file name
+ return null;
+ }
+
+ public long getSize() {
+ return this.get().length;
+ }
+
+ public String getString() {
+ return value;
+ }
+
+ public String getString(String encoding) throws UnsupportedEncodingException {
+ return new String(this.get(), encoding);
+ }
+
+ public boolean isFormField() {
+ // www-form-encoded are always form fields
+ return true;
+ }
+
+ public String toString() {
+ return this.getString();
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/servlethelpers/MockRequestParameterMap.java b/src/main/java/org/apache/sling/servlethelpers/MockRequestParameterMap.java
new file mode 100644
index 0000000..93e25de
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/MockRequestParameterMap.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.sling.api.request.RequestParameter;
+import org.apache.sling.api.request.RequestParameterMap;
+
+/**
+ * Mock implementation of {@link RequestParameterMap}.
+ */
+class MockRequestParameterMap implements RequestParameterMap {
+
+ private final Map<String,RequestParameter[]> delegate = new HashMap<String, RequestParameter[]>();
+
+ public RequestParameter getValue(String name) {
+ RequestParameter[] params = getValues(name);
+ return (params != null && params.length > 0) ? params[0] : null;
+ }
+
+ public RequestParameter[] getValues(String name) {
+ return delegate.get(name);
+ }
+
+ public int size() {
+ return delegate.size();
+ }
+
+ public boolean isEmpty() {
+ return delegate.isEmpty();
+ }
+
+ public boolean containsKey(Object key) {
+ return delegate.containsKey(key);
+ }
+
+ public boolean containsValue(Object value) {
+ return delegate.containsValue(value);
+ }
+
+ public RequestParameter[] get(Object key) {
+ return delegate.get(key);
+ }
+
+ public RequestParameter[] put(String key, RequestParameter[] value) {
+ return delegate.put(key, value);
+ }
+
+ public RequestParameter[] remove(Object key) {
+ return delegate.remove(key);
+ }
+
+ public void putAll(Map<? extends String, ? extends RequestParameter[]> m) {
+ delegate.putAll(m);
+ }
+
+ public void clear() {
+ delegate.clear();
+ }
+
+ public Set<String> keySet() {
+ return delegate.keySet();
+ }
+
+ public Collection<RequestParameter[]> values() {
+ return delegate.values();
+ }
+
+ public Set<java.util.Map.Entry<String, RequestParameter[]>> entrySet() {
+ return delegate.entrySet();
+ }
+
+ public boolean equals(Object o) {
+ return delegate.equals(o);
+ }
+
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/servlethelpers/MockRequestPathInfo.java b/src/main/java/org/apache/sling/servlethelpers/MockRequestPathInfo.java
new file mode 100644
index 0000000..4c6439d
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/MockRequestPathInfo.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.request.RequestPathInfo;
+import org.apache.sling.api.resource.Resource;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * Mock {@link RequestPathInfo} implementation.
+ */
+@ConsumerType
+public class MockRequestPathInfo implements RequestPathInfo {
+
+ private String extension;
+ private String resourcePath;
+ private String selectorString;
+ private String suffix;
+
+ @Override
+ public String getExtension() {
+ return this.extension;
+ }
+
+ @Override
+ public String getResourcePath() {
+ return this.resourcePath;
+ }
+
+ @Override
+ public String[] getSelectors() {
+ if (StringUtils.isEmpty(this.selectorString)) {
+ return new String[0];
+ } else {
+ return StringUtils.split(this.selectorString, ".");
+ }
+ }
+
+ @Override
+ public String getSelectorString() {
+ return this.selectorString;
+ }
+
+ @Override
+ public String getSuffix() {
+ return this.suffix;
+ }
+
+ public void setExtension(final String extension) {
+ this.extension = extension;
+ }
+
+ public void setResourcePath(final String resourcePath) {
+ this.resourcePath = resourcePath;
+ }
+
+ public void setSelectorString(final String selectorString) {
+ this.selectorString = selectorString;
+ }
+
+ public void setSuffix(final String suffix) {
+ this.suffix = suffix;
+ }
+
+ // --- unsupported operations ---
+ @Override
+ public Resource getSuffixResource() {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/servlethelpers/MockServletContext.java b/src/main/java/org/apache/sling/servlethelpers/MockServletContext.java
new file mode 100644
index 0000000..4741738
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/MockServletContext.java
@@ -0,0 +1,304 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.EventListener;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterRegistration;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRegistration;
+import javax.servlet.ServletRegistration.Dynamic;
+import javax.servlet.SessionCookieConfig;
+import javax.servlet.SessionTrackingMode;
+import javax.servlet.descriptor.JspConfigDescriptor;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * Mock {@link ServletContext} implementation.
+ */
+@ConsumerType
+public class MockServletContext implements ServletContext {
+
+ @Override
+ public String getMimeType(final String file) {
+ return "application/octet-stream";
+ }
+
+ // --- unsupported operations ---
+ @Override
+ public Object getAttribute(final String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Enumeration<String> getAttributeNames() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ServletContext getContext(final String uriPath) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getContextPath() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getInitParameter(final String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Enumeration<String> getInitParameterNames() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getMajorVersion() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getMinorVersion() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public RequestDispatcher getNamedDispatcher(final String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getRealPath(final String pPath) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public RequestDispatcher getRequestDispatcher(final String path) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public URL getResource(final String pPath) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public InputStream getResourceAsStream(final String path) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<String> getResourcePaths(final String path) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getServerInfo() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Servlet getServlet(final String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getServletContextName() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Enumeration<String> getServletNames() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Enumeration<Servlet> getServlets() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void log(final String msg) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void log(final Exception exception, final String msg) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void log(final String msg, final Throwable throwable) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void removeAttribute(final String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setAttribute(final String name, final Object object) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getEffectiveMajorVersion() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getEffectiveMinorVersion() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean setInitParameter(final String name, final String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Dynamic addServlet(final String servletName, final String className) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Dynamic addServlet(final String servletName, final Servlet servlet) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Dynamic addServlet(final String servletName, final Class<? extends Servlet> servletClass) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T extends Servlet> T createServlet(final Class<T> clazz) throws ServletException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ServletRegistration getServletRegistration(final String servletName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, ? extends ServletRegistration> getServletRegistrations() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public FilterRegistration.Dynamic addFilter(final String filterName, final String className) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public FilterRegistration.Dynamic addFilter(final String filterName, final Filter filter) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public FilterRegistration.Dynamic addFilter(final String filterName, final Class<? extends Filter> filterClass) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T extends Filter> T createFilter(final Class<T> clazz) throws ServletException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public FilterRegistration getFilterRegistration(final String filterName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Map<String, ? extends FilterRegistration> getFilterRegistrations() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public SessionCookieConfig getSessionCookieConfig() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setSessionTrackingModes(final Set<SessionTrackingMode> sessionTrackingModes) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addListener(final String pClassName) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T extends EventListener> void addListener(final T listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void addListener(final Class<? extends EventListener> listenerClass) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T extends EventListener> T createListener(final Class<T> clazz) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public JspConfigDescriptor getJspConfigDescriptor() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ClassLoader getClassLoader() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void declareRoles(final String... roleNames) {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/servlethelpers/MockSlingHttpServletRequest.java b/src/main/java/org/apache/sling/servlethelpers/MockSlingHttpServletRequest.java
new file mode 100644
index 0000000..88404fd
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/MockSlingHttpServletRequest.java
@@ -0,0 +1,805 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import static org.apache.sling.servlethelpers.MockSlingHttpServletResponse.CHARSET_SEPARATOR;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.ListResourceBundle;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.Part;
+
+import org.apache.commons.collections.IteratorUtils;
+import org.apache.commons.lang3.CharEncoding;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.adapter.SlingAdaptable;
+import org.apache.sling.api.request.RequestDispatcherOptions;
+import org.apache.sling.api.request.RequestParameter;
+import org.apache.sling.api.request.RequestParameterMap;
+import org.apache.sling.api.request.RequestPathInfo;
+import org.apache.sling.api.request.RequestProgressTracker;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.servlets.HttpConstants;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * Mock {@link SlingHttpServletRequest} implementation.
+ */
+@ConsumerType
+public class MockSlingHttpServletRequest extends SlingAdaptable implements SlingHttpServletRequest {
+
+ private final ResourceResolver resourceResolver;
+ private final RequestPathInfo requestPathInfo;
+ private Map<String, Object> attributeMap = new HashMap<String, Object>();
+ private Map<String, String[]> parameterMap = new LinkedHashMap<String, String[]>();
+ private HttpSession session;
+ private Resource resource;
+ private String contextPath;
+ private String queryString;
+ private String scheme = "http";
+ private String serverName = "localhost";
+ private int serverPort = 80;
+ private String method = HttpConstants.METHOD_GET;
+ private final HeaderSupport headerSupport = new HeaderSupport();
+ private final CookieSupport cookieSupport = new CookieSupport();
+ private String contentType;
+ private String characterEncoding;
+ private byte[] content;
+ private String remoteUser;
+ private String remoteAddr;
+ private String remoteHost;
+ private int remotePort;
+
+ private MockRequestDispatcherFactory requestDispatcherFactory;
+
+ protected static final ResourceBundle EMPTY_RESOURCE_BUNDLE = new ListResourceBundle() {
+ @Override
+ protected Object[][] getContents() {
+ return new Object[0][0];
+ }
+ };
+
+ /**
+ * @param resourceResolver Resource resolver
+ */
+ public MockSlingHttpServletRequest(ResourceResolver resourceResolver) {
+ this.resourceResolver = resourceResolver;
+ this.requestPathInfo = newMockRequestPathInfo();
+ }
+
+ protected MockHttpSession newMockHttpSession() {
+ return new MockHttpSession();
+ }
+
+ protected MockRequestPathInfo newMockRequestPathInfo() {
+ return new MockRequestPathInfo();
+ }
+
+ @Override
+ public ResourceResolver getResourceResolver() {
+ return this.resourceResolver;
+ }
+
+ @Override
+ public HttpSession getSession() {
+ return getSession(true);
+ }
+
+ @Override
+ public HttpSession getSession(boolean create) {
+ if (this.session == null && create) {
+ this.session = newMockHttpSession();
+ }
+ return this.session;
+ }
+
+ @Override
+ public RequestPathInfo getRequestPathInfo() {
+ return this.requestPathInfo;
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return this.attributeMap.get(name);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Enumeration<String> getAttributeNames() {
+ return IteratorUtils.asEnumeration(this.attributeMap.keySet().iterator());
+ }
+
+ @Override
+ public void removeAttribute(String name) {
+ this.attributeMap.remove(name);
+ }
+
+ @Override
+ public void setAttribute(String name, Object object) {
+ this.attributeMap.put(name, object);
+ }
+
+ @Override
+ public Resource getResource() {
+ return this.resource;
+ }
+
+ public void setResource(Resource resource) {
+ this.resource = resource;
+ }
+
+ @Override
+ public String getParameter(String name) {
+ Object object = this.parameterMap.get(name);
+ if (object instanceof String) {
+ return (String) object;
+ } else if (object instanceof String[]) {
+ String[] values = (String[]) object;
+ if (values.length > 0) {
+ return values[0];
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Map<String, String[]> getParameterMap() {
+ return this.parameterMap;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Enumeration<String> getParameterNames() {
+ return IteratorUtils.asEnumeration(this.parameterMap.keySet().iterator());
+ }
+
+ @Override
+ public String[] getParameterValues(String name) { // NOPMD
+ Object object = this.parameterMap.get(name);
+ if (object instanceof String) {
+ return new String[] { (String) object };
+ } else if (object instanceof String[]) {
+ return (String[]) object;
+ }
+ return null; // NOPMD
+ }
+
+ /**
+ * @param parameterMap Map of parameters
+ */
+ public void setParameterMap(Map<String, Object> parameterMap) {
+ this.parameterMap.clear();
+ for (Map.Entry<String, Object> entry : parameterMap.entrySet()) {
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ if (value instanceof String[]) {
+ this.parameterMap.put(key, (String[]) value);
+ } else if (value != null) {
+ this.parameterMap.put(key, new String[] { value.toString() });
+ } else {
+ this.parameterMap.put(key, null);
+ }
+ }
+ try {
+ this.queryString = formatQueryString(this.parameterMap);
+ } catch (UnsupportedEncodingException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private String formatQueryString(Map<String, String[]> map) throws UnsupportedEncodingException {
+ StringBuilder querystring = new StringBuilder();
+ for (Map.Entry<String, String[]> entry : this.parameterMap.entrySet()) {
+ if (entry.getValue() != null) {
+ for (String value : entry.getValue()) {
+ if (querystring.length() != 0) {
+ querystring.append('&');
+ }
+ querystring.append(URLEncoder.encode(entry.getKey(), CharEncoding.UTF_8));
+ querystring.append('=');
+ if (value != null) {
+ querystring.append(URLEncoder.encode(value, CharEncoding.UTF_8));
+ }
+ }
+ }
+ }
+ if (querystring.length() > 0) {
+ return querystring.toString();
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public Locale getLocale() {
+ return Locale.US;
+ }
+
+ @Override
+ public String getContextPath() {
+ return this.contextPath;
+ }
+
+ /**
+ * @param contextPath Webapp context path
+ */
+ public void setContextPath(String contextPath) {
+ this.contextPath = contextPath;
+ }
+
+ /**
+ * @param queryString Query string (with proper URL encoding)
+ */
+ public void setQueryString(String queryString) {
+ this.queryString = queryString;
+ try {
+ parseQueryString(this.parameterMap, this.queryString);
+ } catch (UnsupportedEncodingException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private void parseQueryString(Map<String, String[]> map, String query) throws UnsupportedEncodingException {
+ Map<String, List<String>> queryPairs = new LinkedHashMap<String, List<String>>();
+ String[] pairs = query.split("&");
+ for (String pair : pairs) {
+ int idx = pair.indexOf('=');
+ String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), CharEncoding.UTF_8) : pair;
+ if (!queryPairs.containsKey(key)) {
+ queryPairs.put(key, new ArrayList<String>());
+ }
+ String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1),
+ CharEncoding.UTF_8) : null;
+ queryPairs.get(key).add(value);
+ }
+ map.clear();
+ for (Map.Entry<String, List<String>> entry : queryPairs.entrySet()) {
+ map.put(entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]));
+ }
+ }
+
+ @Override
+ public String getQueryString() {
+ return this.queryString;
+ }
+
+ @Override
+ public String getScheme() {
+ return this.scheme;
+ }
+
+ public void setScheme(String scheme) {
+ this.scheme = scheme;
+ }
+
+ @Override
+ public String getServerName() {
+ return this.serverName;
+ }
+
+ public void setServerName(String serverName) {
+ this.serverName = serverName;
+ }
+
+ @Override
+ public int getServerPort() {
+ return this.serverPort;
+ }
+
+ public void setServerPort(int serverPort) {
+ this.serverPort = serverPort;
+ }
+
+ @Override
+ public boolean isSecure() {
+ return StringUtils.equals("https", getScheme());
+ }
+
+ @Override
+ public String getMethod() {
+ return this.method;
+ }
+
+ public void setMethod(String method) {
+ this.method = method;
+ }
+
+ @Override
+ public long getDateHeader(String name) {
+ return headerSupport.getDateHeader(name);
+ }
+
+ @Override
+ public String getHeader(String name) {
+ return headerSupport.getHeader(name);
+ }
+
+ @Override
+ public Enumeration<String> getHeaderNames() {
+ return HeaderSupport.toEnumeration(headerSupport.getHeaderNames());
+ }
+
+ @Override
+ public Enumeration<String> getHeaders(String name) {
+ return HeaderSupport.toEnumeration(headerSupport.getHeaders(name));
+ }
+
+ @Override
+ public int getIntHeader(String name) {
+ return headerSupport.getIntHeader(name);
+ }
+
+ /**
+ * Add header, keep existing ones with same name.
+ * @param name Header name
+ * @param value Header value
+ */
+ public void addHeader(String name, String value) {
+ headerSupport.addHeader(name, value);
+ }
+
+ /**
+ * Add header, keep existing ones with same name.
+ * @param name Header name
+ * @param value Header value
+ */
+ public void addIntHeader(String name, int value) {
+ headerSupport.addIntHeader(name, value);
+ }
+
+ /**
+ * Add header, keep existing ones with same name.
+ * @param name Header name
+ * @param date Header value
+ */
+ public void addDateHeader(String name, long date) {
+ headerSupport.addDateHeader(name, date);
+ }
+
+ /**
+ * Set header, overwrite existing ones with same name.
+ * @param name Header name
+ * @param value Header value
+ */
+ public void setHeader(String name, String value) {
+ headerSupport.setHeader(name, value);
+ }
+
+ /**
+ * Set header, overwrite existing ones with same name.
+ * @param name Header name
+ * @param value Header value
+ */
+ public void setIntHeader(String name, int value) {
+ headerSupport.setIntHeader(name, value);
+ }
+
+ /**
+ * Set header, overwrite existing ones with same name.
+ * @param name Header name
+ * @param date Header value
+ */
+ public void setDateHeader(String name, long date) {
+ headerSupport.setDateHeader(name, date);
+ }
+
+ @Override
+ public Cookie getCookie(String name) {
+ return cookieSupport.getCookie(name);
+ }
+
+ @Override
+ public Cookie[] getCookies() {
+ return cookieSupport.getCookies();
+ }
+
+ /**
+ * Set cookie
+ * @param cookie Cookie
+ */
+ public void addCookie(Cookie cookie) {
+ cookieSupport.addCookie(cookie);
+ }
+
+ @Override
+ public ResourceBundle getResourceBundle(Locale locale) {
+ return getResourceBundle(null, locale);
+ }
+
+ @Override
+ public ResourceBundle getResourceBundle(String baseName, Locale locale) {
+ return EMPTY_RESOURCE_BUNDLE;
+ }
+
+ @Override
+ public RequestParameter getRequestParameter(String name) {
+ String value = getParameter(name);
+ if (value != null) {
+ return new MockRequestParameter(name, value);
+ }
+ return null;
+ }
+
+ @Override
+ public RequestParameterMap getRequestParameterMap() {
+ MockRequestParameterMap map = new MockRequestParameterMap();
+ for (Map.Entry<String,String[]> entry : getParameterMap().entrySet()) {
+ map.put(entry.getKey(), getRequestParameters(entry.getKey()));
+ }
+ return map;
+ }
+
+ @Override
+ public RequestParameter[] getRequestParameters(String name) {
+ String[] values = getParameterValues(name);
+ if (values == null) {
+ return null;
+ }
+ RequestParameter[] requestParameters = new RequestParameter[values.length];
+ for (int i = 0; i < values.length; i++) {
+ requestParameters[i] = new MockRequestParameter(name, values[i]);
+ }
+ return requestParameters;
+ }
+
+ // part of Sling API 2.7
+ public List<RequestParameter> getRequestParameterList() {
+ List<RequestParameter> params = new ArrayList<RequestParameter>();
+ for (RequestParameter[] requestParameters : getRequestParameterMap().values()) {
+ params.addAll(Arrays.asList(requestParameters));
+ }
+ return params;
+ }
+
+ @Override
+ public String getCharacterEncoding() {
+ return this.characterEncoding;
+ }
+
+ @Override
+ public void setCharacterEncoding(String charset) {
+ this.characterEncoding = charset;
+ }
+
+ @Override
+ public String getContentType() {
+ if (this.contentType == null) {
+ return null;
+ } else {
+ return this.contentType
+ + (StringUtils.isNotBlank(characterEncoding) ? CHARSET_SEPARATOR + characterEncoding : "");
+ }
+ }
+
+ public void setContentType(String type) {
+ this.contentType = type;
+ if (StringUtils.contains(this.contentType, CHARSET_SEPARATOR)) {
+ this.characterEncoding = StringUtils.substringAfter(this.contentType, CHARSET_SEPARATOR);
+ this.contentType = StringUtils.substringBefore(this.contentType, CHARSET_SEPARATOR);
+ }
+ }
+
+ @Override
+ public ServletInputStream getInputStream() {
+ if (content == null) {
+ return null;
+ }
+ return new ServletInputStream() {
+ private final InputStream is = new ByteArrayInputStream(content);
+ @Override
+ public int read() throws IOException {
+ return is.read();
+ }
+ };
+ }
+
+ @Override
+ public int getContentLength() {
+ if (content == null) {
+ return 0;
+ }
+ return content.length;
+ }
+
+ public void setContent(byte[] content) {
+ this.content = content;
+ }
+
+ @Override
+ public RequestDispatcher getRequestDispatcher(String path) {
+ if (requestDispatcherFactory == null) {
+ throw new IllegalStateException("Please provdide a MockRequestDispatcherFactory (setRequestDispatcherFactory).");
+ }
+ return requestDispatcherFactory.getRequestDispatcher(path, null);
+ }
+
+ @Override
+ public RequestDispatcher getRequestDispatcher(String path, RequestDispatcherOptions options) {
+ if (requestDispatcherFactory == null) {
+ throw new IllegalStateException("Please provdide a MockRequestDispatcherFactory (setRequestDispatcherFactory).");
+ }
+ return requestDispatcherFactory.getRequestDispatcher(path, options);
+ }
+
+ @Override
+ public RequestDispatcher getRequestDispatcher(Resource resource) {
+ if (requestDispatcherFactory == null) {
+ throw new IllegalStateException("Please provdide a MockRequestDispatcherFactory (setRequestDispatcherFactory).");
+ }
+ return requestDispatcherFactory.getRequestDispatcher(resource, null);
+ }
+
+ @Override
+ public RequestDispatcher getRequestDispatcher(Resource resource, RequestDispatcherOptions options) {
+ if (requestDispatcherFactory == null) {
+ throw new IllegalStateException("Please provdide a MockRequestDispatcherFactory (setRequestDispatcherFactory).");
+ }
+ return requestDispatcherFactory.getRequestDispatcher(resource, options);
+ }
+
+ public void setRequestDispatcherFactory(MockRequestDispatcherFactory requestDispatcherFactory) {
+ this.requestDispatcherFactory = requestDispatcherFactory;
+ }
+
+ @Override
+ public String getRemoteUser() {
+ return remoteUser;
+ }
+
+ public void setRemoteUser(String remoteUser) {
+ this.remoteUser = remoteUser;
+ }
+
+ @Override
+ public String getRemoteAddr() {
+ return remoteAddr;
+ }
+
+ public void setRemoteAddr(String remoteAddr) {
+ this.remoteAddr = remoteAddr;
+ }
+
+ @Override
+ public String getRemoteHost() {
+ return remoteHost;
+ }
+
+ public void setRemoteHost(String remoteHost) {
+ this.remoteHost = remoteHost;
+ }
+
+ @Override
+ public int getRemotePort() {
+ return remotePort;
+ }
+
+ public void setRemotePort(int remotePort) {
+ this.remotePort = remotePort;
+ }
+
+
+ // --- unsupported operations ---
+
+ @Override
+ public RequestProgressTracker getRequestProgressTracker() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getResponseContentType() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Enumeration<String> getResponseContentTypes() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getAuthType() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getPathInfo() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getPathTranslated() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getRequestURI() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public StringBuffer getRequestURL() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getRequestedSessionId() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getServletPath() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Principal getUserPrincipal() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isRequestedSessionIdFromCookie() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isRequestedSessionIdFromURL() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isRequestedSessionIdFromUrl() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isRequestedSessionIdValid() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isUserInRole(String role) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getLocalAddr() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getLocalName() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getLocalPort() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Enumeration<Locale> getLocales() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getProtocol() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public BufferedReader getReader() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getRealPath(String path) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean authenticate(HttpServletResponse response) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void login(String pUsername, String password) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void logout() throws ServletException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Collection<Part> getParts() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Part getPart(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ServletContext getServletContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public AsyncContext startAsync() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isAsyncStarted() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isAsyncSupported() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public AsyncContext getAsyncContext() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public DispatcherType getDispatcherType() {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/servlethelpers/MockSlingHttpServletResponse.java b/src/main/java/org/apache/sling/servlethelpers/MockSlingHttpServletResponse.java
new file mode 100644
index 0000000..6acfb7c
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/MockSlingHttpServletResponse.java
@@ -0,0 +1,282 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.Locale;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.adapter.SlingAdaptable;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * Mock {@link SlingHttpServletResponse} implementation.
+ */
+@ConsumerType
+public class MockSlingHttpServletResponse extends SlingAdaptable implements SlingHttpServletResponse {
+
+ static final String CHARSET_SEPARATOR = ";charset=";
+
+ private String contentType;
+ private String characterEncoding;
+ private int contentLength;
+ private int status = HttpServletResponse.SC_OK;
+ private int bufferSize = 1024 * 8;
+ private boolean isCommitted;
+ private final HeaderSupport headerSupport = new HeaderSupport();
+ private final ResponseBodySupport bodySupport = new ResponseBodySupport();
+ private final CookieSupport cookieSupport = new CookieSupport();
+
+ @Override
+ public String getContentType() {
+ if (this.contentType == null) {
+ return null;
+ } else {
+ return this.contentType
+ + (StringUtils.isNotBlank(characterEncoding) ? CHARSET_SEPARATOR + characterEncoding : "");
+ }
+ }
+
+ @Override
+ public void setContentType(String type) {
+ this.contentType = type;
+ if (StringUtils.contains(this.contentType, CHARSET_SEPARATOR)) {
+ this.characterEncoding = StringUtils.substringAfter(this.contentType, CHARSET_SEPARATOR);
+ this.contentType = StringUtils.substringBefore(this.contentType, CHARSET_SEPARATOR);
+ }
+ }
+
+ @Override
+ public void setCharacterEncoding(String charset) {
+ this.characterEncoding = charset;
+ }
+
+ @Override
+ public String getCharacterEncoding() {
+ return this.characterEncoding;
+ }
+
+ @Override
+ public void setContentLength(int len) {
+ this.contentLength = len;
+ }
+
+ public int getContentLength() {
+ return this.contentLength;
+ }
+
+ @Override
+ public void setStatus(int sc, String sm) {
+ setStatus(sc);
+ }
+
+ @Override
+ public void setStatus(int sc) {
+ this.status = sc;
+ }
+
+ @Override
+ public int getStatus() {
+ return this.status;
+ }
+
+ @Override
+ public void sendError(int sc, String msg) {
+ setStatus(sc);
+ }
+
+ @Override
+ public void sendError(int sc) {
+ setStatus(sc);
+ }
+
+ @Override
+ public void sendRedirect(String location) {
+ setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ setHeader("Location", location);
+ }
+
+ @Override
+ public void addHeader(String name, String value) {
+ headerSupport.addHeader(name, value);
+ }
+
+ @Override
+ public void addIntHeader(String name, int value) {
+ headerSupport.addIntHeader(name, value);
+ }
+
+ @Override
+ public void addDateHeader(String name, long date) {
+ headerSupport.addDateHeader(name, date);
+ }
+
+ @Override
+ public void setHeader(String name, String value) {
+ headerSupport.setHeader(name, value);
+ }
+
+ @Override
+ public void setIntHeader(String name, int value) {
+ headerSupport.setIntHeader(name, value);
+ }
+
+ @Override
+ public void setDateHeader(String name, long date) {
+ headerSupport.setDateHeader(name, date);
+ }
+
+ @Override
+ public boolean containsHeader(String name) {
+ return headerSupport.containsHeader(name);
+ }
+
+ @Override
+ public String getHeader(String name) {
+ return headerSupport.getHeader(name);
+ }
+
+ @Override
+ public Collection<String> getHeaders(String name) {
+ return headerSupport.getHeaders(name);
+ }
+
+ @Override
+ public Collection<String> getHeaderNames() {
+ return headerSupport.getHeaderNames();
+ }
+
+ @Override
+ public PrintWriter getWriter() {
+ return bodySupport.getWriter(getCharacterEncoding());
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() {
+ return bodySupport.getOutputStream();
+ }
+
+ @Override
+ public void reset() {
+ if (isCommitted()) {
+ throw new IllegalStateException("Response already committed.");
+ }
+ bodySupport.reset();
+ headerSupport.reset();
+ cookieSupport.reset();
+ status = HttpServletResponse.SC_OK;
+ contentLength = 0;
+ }
+
+ @Override
+ public void resetBuffer() {
+ if (isCommitted()) {
+ throw new IllegalStateException("Response already committed.");
+ }
+ bodySupport.reset();
+ }
+
+ @Override
+ public int getBufferSize() {
+ return this.bufferSize;
+ }
+
+ @Override
+ public void setBufferSize(int size) {
+ this.bufferSize = size;
+ }
+
+ @Override
+ public void flushBuffer() {
+ isCommitted = true;
+ }
+
+ @Override
+ public boolean isCommitted() {
+ return isCommitted;
+ }
+
+ public byte[] getOutput() {
+ return bodySupport.getOutput();
+ }
+
+ public String getOutputAsString() {
+ return bodySupport.getOutputAsString(getCharacterEncoding());
+ }
+
+ @Override
+ public void addCookie(Cookie cookie) {
+ cookieSupport.addCookie(cookie);
+ }
+
+ /**
+ * Get cookie
+ * @param name Cookie name
+ * @return Cookie or null
+ */
+ public Cookie getCookie(String name) {
+ return cookieSupport.getCookie(name);
+ }
+
+ /**
+ * Get cookies
+ * @return Cookies array or null if no cookie defined
+ */
+ public Cookie[] getCookies() {
+ return cookieSupport.getCookies();
+ }
+
+ // --- unsupported operations ---
+ @Override
+ public Locale getLocale() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void setLocale(Locale loc) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String encodeRedirectUrl(String url) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String encodeRedirectURL(String url) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String encodeUrl(String url) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String encodeURL(String url) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/src/main/java/org/apache/sling/servlethelpers/ResponseBodySupport.java b/src/main/java/org/apache/sling/servlethelpers/ResponseBodySupport.java
new file mode 100644
index 0000000..c19f2c2
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/ResponseBodySupport.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+
+import javax.servlet.ServletOutputStream;
+
+import org.apache.commons.lang3.CharEncoding;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * Manage response body content.
+ */
+class ResponseBodySupport {
+
+ private ByteArrayOutputStream outputStream;
+ private ServletOutputStream servletOutputStream;
+ private PrintWriter printWriter;
+
+ public ResponseBodySupport() {
+ reset();
+ }
+
+ public void reset() {
+ outputStream = new ByteArrayOutputStream();
+ servletOutputStream = null;
+ printWriter = null;
+ }
+
+ public ServletOutputStream getOutputStream() {
+ if (servletOutputStream == null) {
+ servletOutputStream = new ServletOutputStream() {
+ @Override
+ public void write(int b) throws IOException {
+ outputStream.write(b);
+ }
+ };
+ }
+ return servletOutputStream;
+ }
+
+ public PrintWriter getWriter(String charset) {
+ if (printWriter == null) {
+ try {
+ printWriter = new PrintWriter(new OutputStreamWriter(getOutputStream(), defaultCharset(charset)));
+ } catch (UnsupportedEncodingException ex) {
+ throw new RuntimeException("Unsupported encoding: " + defaultCharset(charset), ex);
+ }
+ }
+ return printWriter;
+ }
+
+ public byte[] getOutput() {
+ if (servletOutputStream != null) {
+ try {
+ servletOutputStream.flush();
+ } catch (IOException ex) {
+ // ignore
+ }
+ }
+ return outputStream.toByteArray();
+ }
+
+ public String getOutputAsString(String charset) {
+ if (printWriter != null) {
+ printWriter.flush();
+ }
+ try {
+ return new String(getOutput(), defaultCharset(charset));
+ } catch (UnsupportedEncodingException ex) {
+ throw new RuntimeException("Unsupported encoding: " + defaultCharset(charset), ex);
+ }
+ }
+
+ private String defaultCharset(String charset) {
+ return StringUtils.defaultString(charset, CharEncoding.UTF_8);
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/servlethelpers/package-info.java b/src/main/java/org/apache/sling/servlethelpers/package-info.java
new file mode 100644
index 0000000..1497ab6
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlethelpers/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+/**
+ * Mock implementation of selected Servlet-related Sling APIs.
+ */
+@aQute.bnd.annotation.Version("1.0")
+package org.apache.sling.servlethelpers;
diff --git a/src/test/java/org/apache/sling/servlethelpers/MockHttpSessionTest.java b/src/test/java/org/apache/sling/servlethelpers/MockHttpSessionTest.java
new file mode 100644
index 0000000..980253c
--- /dev/null
+++ b/src/test/java/org/apache/sling/servlethelpers/MockHttpSessionTest.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.sling.servlethelpers.MockHttpSession;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MockHttpSessionTest {
+
+ private MockHttpSession httpSession;
+
+ @Before
+ public void setUp() throws Exception {
+ httpSession = new MockHttpSession();
+ }
+
+ @Test
+ public void testServletContext() {
+ assertNotNull(httpSession.getServletContext());
+ }
+
+ @Test
+ public void testId() {
+ assertNotNull(httpSession.getId());
+ }
+
+ @Test
+ public void testCreationTime() {
+ assertNotNull(httpSession.getCreationTime());
+ }
+
+ @Test
+ public void testAttributes() {
+ httpSession.setAttribute("attr1", "value1");
+ assertTrue(httpSession.getAttributeNames().hasMoreElements());
+ assertEquals("value1", httpSession.getAttribute("attr1"));
+ httpSession.removeAttribute("attr1");
+ assertFalse(httpSession.getAttributeNames().hasMoreElements());
+ }
+
+ @Test
+ public void testValues() {
+ httpSession.putValue("attr1", "value1");
+ assertEquals(1, httpSession.getValueNames().length);
+ assertEquals("value1", httpSession.getValue("attr1"));
+ httpSession.removeValue("attr1");
+ assertEquals(0, httpSession.getValueNames().length);
+ }
+
+ @Test
+ public void testInvalidate() {
+ httpSession.invalidate();
+ assertTrue(httpSession.isInvalidated());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testInvalidateStateCheck() {
+ httpSession.invalidate();
+ httpSession.getAttribute("attr1");
+ }
+
+ @Test
+ public void testIsNew() {
+ assertTrue(httpSession.isNew());
+ httpSession.setNew(false);
+ assertFalse(httpSession.isNew());
+ }
+
+ @Test
+ public void testGetLastAccessedTime() {
+ assertNotNull(httpSession.getLastAccessedTime());
+ }
+
+ @Test
+ public void testGetMaxInactiveInterval() {
+ assertTrue(httpSession.getMaxInactiveInterval() > 0);
+ httpSession.setMaxInactiveInterval(123);
+ assertEquals(123, httpSession.getMaxInactiveInterval());
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/servlethelpers/MockRequestPathInfoTest.java b/src/test/java/org/apache/sling/servlethelpers/MockRequestPathInfoTest.java
new file mode 100644
index 0000000..f94c380
--- /dev/null
+++ b/src/test/java/org/apache/sling/servlethelpers/MockRequestPathInfoTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.apache.sling.servlethelpers.MockRequestPathInfo;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MockRequestPathInfoTest {
+
+ private MockRequestPathInfo requestPathInfo;
+
+ @Before
+ public void setUp() throws Exception {
+ this.requestPathInfo = new MockRequestPathInfo();
+ }
+
+ @Test
+ public void testExtension() {
+ assertNull(this.requestPathInfo.getExtension());
+ this.requestPathInfo.setExtension("ext");
+ assertEquals("ext", this.requestPathInfo.getExtension());
+ }
+
+ @Test
+ public void testResourcePath() {
+ assertNull(this.requestPathInfo.getResourcePath());
+ this.requestPathInfo.setResourcePath("/path");
+ assertEquals("/path", this.requestPathInfo.getResourcePath());
+ }
+
+ @Test
+ public void testSelector() {
+ assertNull(this.requestPathInfo.getSelectorString());
+ assertEquals(0, this.requestPathInfo.getSelectors().length);
+ this.requestPathInfo.setSelectorString("aa.bb");
+ assertEquals("aa.bb", this.requestPathInfo.getSelectorString());
+ assertEquals(2, this.requestPathInfo.getSelectors().length);
+ assertArrayEquals(new String[] { "aa", "bb" }, this.requestPathInfo.getSelectors());
+ }
+
+ @Test
+ public void testSuffix() {
+ assertNull(this.requestPathInfo.getSuffix());
+ this.requestPathInfo.setSuffix("/suffix");
+ assertEquals("/suffix", this.requestPathInfo.getSuffix());
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/servlethelpers/MockServletContextTest.java b/src/test/java/org/apache/sling/servlethelpers/MockServletContextTest.java
new file mode 100644
index 0000000..131b531
--- /dev/null
+++ b/src/test/java/org/apache/sling/servlethelpers/MockServletContextTest.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import static org.junit.Assert.assertEquals;
+
+import javax.servlet.ServletContext;
+
+import org.apache.sling.servlethelpers.MockServletContext;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MockServletContextTest {
+
+ private ServletContext servletContext;
+
+ @Before
+ public void setUp() throws Exception {
+ this.servletContext = new MockServletContext();
+ }
+
+ @Test
+ public void testGetMimeType() {
+ assertEquals("application/octet-stream", this.servletContext.getMimeType("any"));
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/servlethelpers/MockSlingHttpServletRequestTest.java b/src/test/java/org/apache/sling/servlethelpers/MockSlingHttpServletRequestTest.java
new file mode 100644
index 0000000..28d6b50
--- /dev/null
+++ b/src/test/java/org/apache/sling/servlethelpers/MockSlingHttpServletRequestTest.java
@@ -0,0 +1,328 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Calendar;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.CharEncoding;
+import org.apache.sling.api.request.RequestDispatcherOptions;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.servlets.HttpConstants;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class MockSlingHttpServletRequestTest {
+
+ @Mock
+ private ResourceResolver resourceResolver;
+ @Mock
+ private Resource resource;
+
+ private MockSlingHttpServletRequest request;
+
+ @Before
+ public void setUp() throws Exception {
+ request = new MockSlingHttpServletRequest(resourceResolver);
+ }
+
+ @Test
+ public void testResourceResolver() {
+ assertSame(resourceResolver, request.getResourceResolver());
+ }
+
+ @Test
+ public void testDefaultResourceResolver() {
+ assertNotNull(request.getResourceResolver());
+ }
+
+ @Test
+ public void testSession() {
+ HttpSession session = request.getSession(false);
+ assertNull(session);
+ session = request.getSession();
+ assertNotNull(session);
+ }
+
+ @Test
+ public void testRequestPathInfo() {
+ assertNotNull(request.getRequestPathInfo());
+ }
+
+ @Test
+ public void testAttributes() {
+ request.setAttribute("attr1", "value1");
+ assertTrue(request.getAttributeNames().hasMoreElements());
+ assertEquals("value1", request.getAttribute("attr1"));
+ request.removeAttribute("attr1");
+ assertFalse(request.getAttributeNames().hasMoreElements());
+ }
+
+ @Test
+ public void testResource() {
+ assertNull(request.getResource());
+ request.setResource(resource);
+ assertSame(resource, request.getResource());
+ }
+
+ @Test
+ public void testContextPath() {
+ assertNull(request.getContextPath());
+ request.setContextPath("/ctx");
+ assertEquals("/ctx", request.getContextPath());
+ }
+
+ @Test
+ public void testLocale() {
+ assertEquals(Locale.US, request.getLocale());
+ }
+
+ @Test
+ public void testQueryString() throws UnsupportedEncodingException {
+ assertNull(request.getQueryString());
+ assertEquals(0, request.getParameterMap().size());
+ assertFalse(request.getParameterNames().hasMoreElements());
+
+ request.setQueryString("param1=123¶m2=" + URLEncoder.encode("äöü߀!:!", CharEncoding.UTF_8)
+ + "¶m3=a¶m3=b");
+
+ assertNotNull(request.getQueryString());
+ assertEquals(3, request.getParameterMap().size());
+ assertTrue(request.getParameterNames().hasMoreElements());
+ assertEquals("123", request.getParameter("param1"));
+ assertEquals("äöü߀!:!", request.getParameter("param2"));
+ assertArrayEquals(new String[] { "a", "b" }, request.getParameterValues("param3"));
+
+ Map<String, Object> paramMap = new LinkedHashMap<String, Object>();
+ paramMap.put("p1", "a");
+ paramMap.put("p2", new String[] { "b", "c" });
+ paramMap.put("p3", null);
+ paramMap.put("p4", new String[] { null });
+ paramMap.put("p5", 22);
+ request.setParameterMap(paramMap);
+
+ assertEquals("p1=a&p2=b&p2=c&p4=&p5=22", request.getQueryString());
+ }
+
+ @Test
+ public void testSchemeSecure() {
+ assertEquals("http", request.getScheme());
+ assertFalse(request.isSecure());
+
+ request.setScheme("https");
+ assertEquals("https", request.getScheme());
+ assertTrue(request.isSecure());
+ }
+
+ @Test
+ public void testServerNamePort() {
+ assertEquals("localhost", request.getServerName());
+ assertEquals(80, request.getServerPort());
+
+ request.setServerName("myhost");
+ request.setServerPort(12345);
+ assertEquals("myhost", request.getServerName());
+ assertEquals(12345, request.getServerPort());
+ }
+
+ @Test
+ public void testMethod() {
+ assertEquals(HttpConstants.METHOD_GET, request.getMethod());
+
+ request.setMethod(HttpConstants.METHOD_POST);
+ assertEquals(HttpConstants.METHOD_POST, request.getMethod());
+ }
+
+ @Test
+ public void testHeaders() {
+ assertFalse(request.getHeaderNames().hasMoreElements());
+
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(Calendar.MILLISECOND, 0);
+ long dateValue = calendar.getTimeInMillis();
+
+ request.addHeader("header1", "value1");
+ request.addIntHeader("header2", 5);
+ request.addDateHeader("header3", dateValue);
+
+ assertEquals("value1", request.getHeader("header1"));
+ assertEquals(5, request.getIntHeader("header2"));
+ assertEquals(dateValue, request.getDateHeader("header3"));
+
+ request.setHeader("header1", "value2");
+ request.addIntHeader("header2", 10);
+
+ Enumeration<String> header1Values = request.getHeaders("header1");
+ assertEquals("value2", header1Values.nextElement());
+ assertFalse(header1Values.hasMoreElements());
+
+ Enumeration<String> header2Values = request.getHeaders("header2");
+ assertEquals("5", header2Values.nextElement());
+ assertEquals("10", header2Values.nextElement());
+ assertFalse(header2Values.hasMoreElements());
+ }
+
+ @Test
+ public void testCookies() {
+ assertNull(request.getCookies());
+
+ request.addCookie(new Cookie("cookie1", "value1"));
+ request.addCookie(new Cookie("cookie2", "value2"));
+
+ assertEquals("value1", request.getCookie("cookie1").getValue());
+
+ Cookie[] cookies = request.getCookies();
+ assertEquals(2, cookies.length);
+ assertEquals("value1", cookies[0].getValue());
+ assertEquals("value2", cookies[1].getValue());
+ }
+
+ @Test
+ public void testDefaultResourceBundle() {
+ ResourceBundle bundle = request.getResourceBundle(Locale.US);
+ assertNotNull(bundle);
+ assertFalse(bundle.getKeys().hasMoreElements());
+ }
+
+ @Test
+ public void testRequestParameter() throws Exception {
+ request.setQueryString("param1=123¶m2=" + URLEncoder.encode("äöü߀!:!", CharEncoding.UTF_8)
+ + "¶m3=a¶m3=b");
+
+ assertEquals(3, request.getRequestParameterMap().size());
+ assertEquals(4, request.getRequestParameterList().size());
+ assertEquals("123", request.getRequestParameter("param1").getString());
+ assertEquals("äöü߀!:!", request.getRequestParameter("param2").getString());
+ assertEquals("a",request.getRequestParameters("param3")[0].getString());
+ assertEquals("b",request.getRequestParameters("param3")[1].getString());
+
+ assertNull(request.getRequestParameter("unknown"));
+ assertNull(request.getRequestParameters("unknown"));
+ }
+
+ @Test
+ public void testContentTypeCharset() throws Exception {
+ assertNull(request.getContentType());
+ assertNull(request.getCharacterEncoding());
+
+ request.setContentType("image/gif");
+ assertEquals("image/gif", request.getContentType());
+ assertNull(request.getCharacterEncoding());
+
+ request.setContentType("text/plain;charset=UTF-8");
+ assertEquals("text/plain;charset=UTF-8", request.getContentType());
+ assertEquals(CharEncoding.UTF_8, request.getCharacterEncoding());
+
+ request.setCharacterEncoding(CharEncoding.ISO_8859_1);
+ assertEquals("text/plain;charset=ISO-8859-1", request.getContentType());
+ assertEquals(CharEncoding.ISO_8859_1, request.getCharacterEncoding());
+ }
+
+ @Test
+ public void testContent() throws Exception {
+ assertEquals(0, request.getContentLength());
+ assertNull(request.getInputStream());
+
+ byte[] data = new byte[] { 0x01,0x02,0x03 };
+ request.setContent(data);
+
+ assertEquals(data.length, request.getContentLength());
+ assertArrayEquals(data, IOUtils.toByteArray(request.getInputStream()));
+ }
+
+ @Test
+ public void testGetRequestDispatcher() {
+ MockRequestDispatcherFactory requestDispatcherFactory = mock(MockRequestDispatcherFactory.class);
+ RequestDispatcher requestDispatcher = mock(RequestDispatcher.class);
+ when(requestDispatcherFactory.getRequestDispatcher(any(Resource.class), any(RequestDispatcherOptions.class))).thenReturn(requestDispatcher);
+ when(requestDispatcherFactory.getRequestDispatcher(any(String.class), any(RequestDispatcherOptions.class))).thenReturn(requestDispatcher);
+
+ request.setRequestDispatcherFactory(requestDispatcherFactory);
+
+ assertSame(requestDispatcher, request.getRequestDispatcher("/path"));
+ assertSame(requestDispatcher, request.getRequestDispatcher("/path", new RequestDispatcherOptions()));
+ assertSame(requestDispatcher, request.getRequestDispatcher(resource));
+ assertSame(requestDispatcher, request.getRequestDispatcher(resource, new RequestDispatcherOptions()));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testGetRequestDispatcherWithoutFactory() {
+ request.getRequestDispatcher("/path");
+ }
+
+ @Test
+ public void testGetRemoteUser() {
+ assertNull(null, request.getRemoteUser());
+
+ request.setRemoteUser("admin");
+ assertEquals("admin", request.getRemoteUser());
+ }
+
+ @Test
+ public void testGetRemoteAddr() throws Exception {
+ assertNull(null, request.getRemoteAddr());
+
+ request.setRemoteAddr("1.2.3.4");
+ assertEquals("1.2.3.4", request.getRemoteAddr());
+ }
+
+ @Test
+ public void testGetRemoteHost() throws Exception {
+ assertNull(null, request.getRemoteHost());
+
+ request.setRemoteHost("host1");
+ assertEquals("host1", request.getRemoteHost());
+ }
+
+ @Test
+ public void testGetRemotePort() throws Exception {
+ assertEquals(0, request.getRemotePort());
+
+ request.setRemotePort(1234);
+ assertEquals(1234, request.getRemotePort());
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/servlethelpers/MockSlingHttpServletResponseTest.java b/src/test/java/org/apache/sling/servlethelpers/MockSlingHttpServletResponseTest.java
new file mode 100644
index 0000000..54dae46
--- /dev/null
+++ b/src/test/java/org/apache/sling/servlethelpers/MockSlingHttpServletResponseTest.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.servlethelpers;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.CharEncoding;
+import org.apache.sling.servlethelpers.MockSlingHttpServletResponse;
+import org.junit.Before;
+import org.junit.Test;
+
+public class MockSlingHttpServletResponseTest {
+
+ private MockSlingHttpServletResponse response;
+
+ @Before
+ public void setUp() throws Exception {
+ this.response = new MockSlingHttpServletResponse();
+ }
+
+ @Test
+ public void testContentTypeCharset() throws Exception {
+ assertNull(response.getContentType());
+ assertNull(response.getCharacterEncoding());
+
+ response.setContentType("image/gif");
+ assertEquals("image/gif", response.getContentType());
+ assertNull(response.getCharacterEncoding());
+
+ response.setContentType("text/plain;charset=UTF-8");
+ assertEquals("text/plain;charset=UTF-8", response.getContentType());
+ assertEquals(CharEncoding.UTF_8, response.getCharacterEncoding());
+
+ response.setCharacterEncoding(CharEncoding.ISO_8859_1);
+ assertEquals("text/plain;charset=ISO-8859-1", response.getContentType());
+ assertEquals(CharEncoding.ISO_8859_1, response.getCharacterEncoding());
+ }
+
+ @Test
+ public void testContentLength() throws Exception {
+ assertEquals(0, response.getContentLength());
+
+ response.setContentLength(55);
+ assertEquals(55, response.getContentLength());
+ }
+
+ @Test
+ public void testHeaders() throws Exception {
+ assertEquals(0, response.getHeaderNames().size());
+
+ response.addHeader("header1", "value1");
+ response.addIntHeader("header2", 5);
+ response.addDateHeader("header3", System.currentTimeMillis());
+
+ assertEquals(3, response.getHeaderNames().size());
+ assertTrue(response.containsHeader("header1"));
+ assertEquals("value1", response.getHeader("header1"));
+ assertEquals("5", response.getHeader("header2"));
+ assertNotNull(response.getHeader("header3"));
+
+ response.setHeader("header1", "value2");
+ response.addIntHeader("header2", 10);
+
+ assertEquals(3, response.getHeaderNames().size());
+
+ Collection<String> header1Values = response.getHeaders("header1");
+ assertEquals(1, header1Values.size());
+ assertEquals("value2", header1Values.iterator().next());
+
+ Collection<String> header2Values = response.getHeaders("header2");
+ assertEquals(2, header2Values.size());
+ Iterator<String> header2Iterator = header2Values.iterator();
+ assertEquals("5", header2Iterator.next());
+ assertEquals("10", header2Iterator.next());
+
+ response.reset();
+ assertEquals(0, response.getHeaderNames().size());
+ }
+
+ @Test
+ public void testRedirect() throws Exception {
+ response.sendRedirect("/location.html");
+ assertEquals(HttpServletResponse.SC_MOVED_TEMPORARILY, response.getStatus());
+ assertEquals("/location.html", response.getHeader("Location"));
+ }
+
+ @Test
+ public void testSendError() throws Exception {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ assertEquals(HttpServletResponse.SC_NOT_FOUND, response.getStatus());
+ }
+
+ @Test
+ public void testSetStatus() throws Exception {
+ assertEquals(HttpServletResponse.SC_OK, response.getStatus());
+
+ response.setStatus(HttpServletResponse.SC_BAD_GATEWAY);
+ assertEquals(HttpServletResponse.SC_BAD_GATEWAY, response.getStatus());
+
+ response.reset();
+ assertEquals(HttpServletResponse.SC_OK, response.getStatus());
+ }
+
+ @Test
+ public void testWriteStringContent() throws Exception {
+ final String TEST_CONTENT = "Der Jodelkaiser äöü߀ ᚠᛇᚻ";
+ response.setCharacterEncoding(CharEncoding.UTF_8);
+ response.getWriter().write(TEST_CONTENT);
+ assertEquals(TEST_CONTENT, response.getOutputAsString());
+
+ response.resetBuffer();
+ assertEquals(0, response.getOutputAsString().length());
+ }
+
+ @Test
+ public void testWriteBinaryContent() throws Exception {
+ final byte[] TEST_DATA = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05 };
+ response.getOutputStream().write(TEST_DATA);
+ assertArrayEquals(TEST_DATA, response.getOutput());
+
+ response.resetBuffer();
+ assertEquals(0, response.getOutput().length);
+ }
+
+ @Test
+ public void testIsCommitted() throws Exception {
+ assertFalse(response.isCommitted());
+ response.flushBuffer();
+ assertTrue(response.isCommitted());
+ }
+
+ @Test
+ public void testCookies() {
+ assertNull(response.getCookies());
+
+ response.addCookie(new Cookie("cookie1", "value1"));
+ response.addCookie(new Cookie("cookie2", "value2"));
+
+ assertEquals("value1", response.getCookie("cookie1").getValue());
+
+ Cookie[] cookies = response.getCookies();
+ assertEquals(2, cookies.length);
+ assertEquals("value1", cookies[0].getValue());
+ assertEquals("value2", cookies[1].getValue());
+
+ response.reset();
+ assertNull(response.getCookies());
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.