You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2020/04/05 05:46:05 UTC
[struts] branch action-context-boost updated (8a68c62 -> 78ed6c8)
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a change to branch action-context-boost
in repository https://gitbox.apache.org/repos/asf/struts.git.
from 8a68c62 WW-4789 WW-3788 Adds instance bind() to simplify bind operation
new 2e7a6b9 Proposed implementation to address WW-5030. Introduce new junit-portlet plugin. - Utilizes a copy of org.springframework.mock.web.portlet package from Spring 4.3.x, refactored to org.apache.struts2.mock.web.portlet. Also copies one interface from org.apache.struts2.mock.web.portlet. The package-info.java files identify the package renaming. - Provides test cases for the mock objects. - Modifies the portlet plugin to use the junit-portlet plugin as a dependency. [...]
new b0197f3 Fix for test running on JDK 9+. If using Spring 4.x mock objects the MockServletContext has a dependency on javax.activation that causes a java.lang.NoClassDefFoundError. - Test updated to allow the single call that triggers this in JDK9+ to continue as long as the class not found is FileTypeMap (expected).
new b7520d2 Correction for previous commit message. There was a typo which should have read: "copies one interface from org.springframework.mock.web.portlet.multipart" (not "org.apache.struts2.mock.web.portlet" which was incorrect).
new 0ea08d1 Drops duplicated dependency
new 7d988c9 Install SNAPSHOTs to allow reuse them
new 78ed6c8 WW-4789 WW-3788 Adjusts after rebase
The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
Jenkinsfile | 6 +-
plugins/junit/pom.xml | 15 +-
.../org/apache/struts2/StrutsPortletTestCase.java | 26 +-
plugins/pom.xml | 1 +
plugins/{testng => portlet-mocks}/pom.xml | 19 +-
.../mock/web/portlet/MockActionRequest.java | 86 ++
.../mock/web/portlet/MockActionResponse.java | 132 ++
.../struts2/mock/web/portlet/MockBaseURL.java | 161 ++
.../struts2/mock/web/portlet/MockCacheControl.java | 78 +
.../mock/web/portlet/MockClientDataRequest.java | 135 ++
.../apache/struts2/mock/web/portlet/MockEvent.java | 91 ++
.../struts2/mock/web/portlet/MockEventRequest.java | 90 ++
.../mock/web/portlet/MockEventResponse.java | 35 +
.../struts2/mock/web/portlet/MockMimeResponse.java | 259 ++++
.../web/portlet/MockMultipartActionRequest.java | 101 ++
.../mock/web/portlet/MockPortalContext.java | 106 ++
.../mock/web/portlet/MockPortletConfig.java | 194 +++
.../mock/web/portlet/MockPortletContext.java | 285 ++++
.../mock/web/portlet/MockPortletPreferences.java | 123 ++
.../mock/web/portlet/MockPortletRequest.java | 565 +++++++
.../web/portlet/MockPortletRequestDispatcher.java | 87 ++
.../mock/web/portlet/MockPortletResponse.java | 202 +++
.../mock/web/portlet/MockPortletSession.java | 249 +++
.../struts2/mock/web/portlet/MockPortletURL.java | 121 ++
.../mock/web/portlet/MockRenderRequest.java | 94 ++
.../mock/web/portlet/MockRenderResponse.java | 90 ++
.../mock/web/portlet/MockResourceRequest.java | 132 ++
.../mock/web/portlet/MockResourceResponse.java | 41 +
.../struts2/mock/web/portlet/MockResourceURL.java | 73 +
.../mock/web/portlet/MockStateAwareResponse.java | 165 ++
.../web/portlet/ServletWrappingPortletContext.java | 161 ++
.../portlet/multipart/MultipartActionRequest.java | 41 +
.../mock/web/portlet/multipart/package-info.java | 38 +
.../struts2/mock/web/portlet/package-info.java | 35 +
plugins/{tiles => portlet-mocks}/src/site/site.xml | 0
.../StrutsSpringPortletMockObjectsTest.java | 1597 ++++++++++++++++++++
.../src/test/resources/applicationContext.xml | 72 +-
plugins/portlet/pom.xml | 5 +-
.../apache/struts2/portlet/PortletRequestMap.java | 10 +-
.../struts2/StrutsTestCasePortletTests.java} | 32 +-
.../struts2/components/PortletUrlRendererTest.java | 10 +-
.../struts2/portlet/PortletRequestMapTest.java | 2 +-
.../struts2/portlet/PortletSessionMapTest.java | 2 +-
.../portlet/dispatcher/Jsr168DispatcherTest.java | 4 +-
.../portlet/dispatcher/Jsr286DispatcherTest.java | 4 +-
.../interceptor/PortletStateInterceptorTest.java | 4 +-
pom.xml | 5 +
47 files changed, 5696 insertions(+), 88 deletions(-)
rename plugins/{portlet => junit}/src/main/java/org/apache/struts2/StrutsPortletTestCase.java (79%)
copy plugins/{testng => portlet-mocks}/pom.xml (81%)
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockActionRequest.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockActionResponse.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockBaseURL.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockCacheControl.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockClientDataRequest.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockEvent.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockEventRequest.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockEventResponse.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockMimeResponse.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockMultipartActionRequest.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortalContext.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletConfig.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletContext.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletPreferences.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequest.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequestDispatcher.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletResponse.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletSession.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletURL.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderRequest.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderResponse.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceRequest.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceResponse.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceURL.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockStateAwareResponse.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/ServletWrappingPortletContext.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/multipart/MultipartActionRequest.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/multipart/package-info.java
create mode 100644 plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/package-info.java
copy plugins/{tiles => portlet-mocks}/src/site/site.xml (100%)
create mode 100644 plugins/portlet-mocks/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java
copy plugins/{junit => portlet-mocks}/src/test/resources/applicationContext.xml (87%)
copy plugins/{junit/src/main/java/org/apache/struts2/StrutsTestCase.java => portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java} (87%)
[struts] 02/06: Fix for test running on JDK 9+. If using Spring 4.x
mock objects the MockServletContext has a dependency on javax.activation
that causes a java.lang.NoClassDefFoundError. - Test updated to allow the
single call that triggers this in JDK9+ to continue as long as the class
not found is FileTypeMap (expected).
Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch action-context-boost
in repository https://gitbox.apache.org/repos/asf/struts.git
commit b0197f370e15286675481517f7eb284b43a818b9
Author: JCgH4164838Gh792C124B5 <43...@users.noreply.github.com>
AuthorDate: Sun Mar 22 15:37:20 2020 -0400
Fix for test running on JDK 9+. If using Spring 4.x mock objects the
MockServletContext has a dependency on javax.activation that causes a
java.lang.NoClassDefFoundError.
- Test updated to allow the single call that triggers this in JDK9+
to continue as long as the class not found is FileTypeMap (expected).
---
.../org/apache/struts2/StrutsSpringPortletMockObjectsTest.java | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/plugins/junit-portlet/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java b/plugins/junit-portlet/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java
index 6ba60f3..e802dc6 100644
--- a/plugins/junit-portlet/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java
+++ b/plugins/junit-portlet/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java
@@ -1465,7 +1465,15 @@ public class StrutsSpringPortletMockObjectsTest extends StrutsSpringTestCase {
assertNull("ServletWrappingPortletContext resource stream for /ThisDoesNotExist not null ?", servletWrappingPortletContext.getResourceAsStream("/ThisDoesNotExist"));
assertTrue("ServletWrappingPortletContext major version not >= 2 ?", servletWrappingPortletContext.getMajorVersion() >= 2);
assertTrue("ServletWrappingPortletContext minor version not >= 0 ?", servletWrappingPortletContext.getMajorVersion() >= 0);
- assertNull("ServletWrappingPortletContext MIME type for / not null ?", servletWrappingPortletContext.getMimeType("/"));
+ try {
+ assertNull("ServletWrappingPortletContext MIME type for / not null ?", servletWrappingPortletContext.getMimeType("/"));
+ } catch (NoClassDefFoundError ncdfe) {
+ // If compiled with Spring 4.x the MockServletContext has a dependency on javax.activation. This will cause a runtime failure running under JDK 9+ due to removal
+ // of the javax.activation module. For that reason we will ignore the NoClassDefFoundError failure provided it is for the known FileTypeMap dependency.
+ if (!ncdfe.getMessage().contains("javax/activation/FileTypeMap")) {
+ fail("Unexpected exception: " + ncdfe);
+ }
+ }
assertNotNull("ServletWrappingPortletContext real path for / null ?", servletWrappingPortletContext.getRealPath("/"));
assertNull("ServletWrappingPortletContext real path for /ThisDoesNotExist not null ? ?", servletWrappingPortletContext.getRealPath("/ThisDoesNotExist"));
assertNull("ServletWrappingPortletContext resource paths for / not null ?", servletWrappingPortletContext.getResourcePaths("/"));
[struts] 05/06: Install SNAPSHOTs to allow reuse them
Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch action-context-boost
in repository https://gitbox.apache.org/repos/asf/struts.git
commit 7d988c9dbce4257ea8a627b07e0fdec0e2568c41
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Sat Apr 4 17:43:41 2020 +0200
Install SNAPSHOTs to allow reuse them
---
Jenkinsfile | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Jenkinsfile b/Jenkinsfile
index a6812c3..5bff27e 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -39,7 +39,7 @@ pipeline {
stages {
stage('Build') {
steps {
- sh 'mvn -B package -DskipTests -DskipAssembly'
+ sh 'mvn -B clean install -DskipTests -DskipAssembly'
}
}
stage('Test') {
@@ -75,7 +75,7 @@ pipeline {
stages {
stage('Build') {
steps {
- sh 'mvn -B clean package -DskipTests -DskipAssembly'
+ sh 'mvn -B clean install -DskipTests -DskipAssembly'
}
}
stage('Test') {
@@ -111,7 +111,7 @@ pipeline {
stages {
stage('Build') {
steps {
- sh 'mvn -B clean package -DskipTests -DskipAssembly'
+ sh 'mvn -B clean install -DskipTests -DskipAssembly'
}
}
stage('Test') {
[struts] 06/06: WW-4789 WW-3788 Adjusts after rebase
Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch action-context-boost
in repository https://gitbox.apache.org/repos/asf/struts.git
commit 78ed6c881d2933c427c2892159910b92fc22cead
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Sun Apr 5 07:45:55 2020 +0200
WW-4789 WW-3788 Adjusts after rebase
---
.../src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/plugins/portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java b/plugins/portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java
index 1e7ea61..56d7cb0 100644
--- a/plugins/portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java
+++ b/plugins/portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java
@@ -134,12 +134,12 @@ public abstract class StrutsTestCasePortletTests extends XWorkTestCase {
initSession(actionContext);
applyAdditionalParams(actionContext);
// set the action context to the one used by the proxy
- ActionContext.setContext(actionContext);
+ ActionContext.bind(actionContext);
}
protected void initSession(ActionContext actionContext) {
if (actionContext.getSession() == null) {
- actionContext.setSession(new HashMap<String, Object>());
+ actionContext.setSession(new HashMap<>());
request.setSession(new MockHttpSession(servletContext));
}
}
[struts] 03/06: Correction for previous commit message. There was a
typo which should have read: "copies one interface from
org.springframework.mock.web.portlet.multipart" (not
"org.apache.struts2.mock.web.portlet" which was incorrect).
Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch action-context-boost
in repository https://gitbox.apache.org/repos/asf/struts.git
commit b7520d2ea011b4d90742f99348562df653ed71bd
Author: JCgH4164838Gh792C124B5 <43...@users.noreply.github.com>
AuthorDate: Sat Mar 28 11:48:06 2020 -0400
Correction for previous commit message. There was a typo which should have
read: "copies one interface from
org.springframework.mock.web.portlet.multipart" (not
"org.apache.struts2.mock.web.portlet" which was incorrect).
Refactor (rename) junit-portlet plugin to portlet-mocks plugin.
- Moved StrutsPortletTestCase from the portlet plugin into the junit plugin
(same package name).
- Added optional dependencies to the junit plugin for the portlet plugin
and mocks plugin.
- Duplicated StrutsTestCase from the junit plugin with a new name
StrutsTestCasePortletTests that exists within a test scope only.
This was done to eliminate a dendency cycle between junit and portlet
plugins during refactoring.
- Updated the portlet plugin unit tests to use StrutsTestCasePortletTests
internally instead of StrutsTestCase from the junit plugin.
- Removed junit plugin dependency for portlets plugin, added test scope
dependency for portlet-mocks plugin.
- Made StrutsSpringPortletMockObjectsTest depend only on TestCase.
- Removed unneeded dependencies from portlet-mocks pom.
Amended commit multiple times: Missed plugins pom.xml change, forgot to
drop StrutsPortletTestCase from portlet plugin (local repository).
---
plugins/junit/pom.xml | 15 +-
.../org/apache/struts2/StrutsPortletTestCase.java | 20 +-
plugins/pom.xml | 2 +-
plugins/{junit-portlet => portlet-mocks}/pom.xml | 27 +--
.../mock/web/portlet/MockActionRequest.java | 0
.../mock/web/portlet/MockActionResponse.java | 0
.../struts2/mock/web/portlet/MockBaseURL.java | 0
.../struts2/mock/web/portlet/MockCacheControl.java | 0
.../mock/web/portlet/MockClientDataRequest.java | 0
.../apache/struts2/mock/web/portlet/MockEvent.java | 0
.../struts2/mock/web/portlet/MockEventRequest.java | 0
.../mock/web/portlet/MockEventResponse.java | 0
.../struts2/mock/web/portlet/MockMimeResponse.java | 0
.../web/portlet/MockMultipartActionRequest.java | 0
.../mock/web/portlet/MockPortalContext.java | 0
.../mock/web/portlet/MockPortletConfig.java | 0
.../mock/web/portlet/MockPortletContext.java | 0
.../mock/web/portlet/MockPortletPreferences.java | 0
.../mock/web/portlet/MockPortletRequest.java | 0
.../web/portlet/MockPortletRequestDispatcher.java | 0
.../mock/web/portlet/MockPortletResponse.java | 0
.../mock/web/portlet/MockPortletSession.java | 0
.../struts2/mock/web/portlet/MockPortletURL.java | 0
.../mock/web/portlet/MockRenderRequest.java | 0
.../mock/web/portlet/MockRenderResponse.java | 0
.../mock/web/portlet/MockResourceRequest.java | 0
.../mock/web/portlet/MockResourceResponse.java | 0
.../struts2/mock/web/portlet/MockResourceURL.java | 0
.../mock/web/portlet/MockStateAwareResponse.java | 0
.../web/portlet/ServletWrappingPortletContext.java | 0
.../portlet/multipart/MultipartActionRequest.java | 0
.../mock/web/portlet/multipart/package-info.java | 0
.../struts2/mock/web/portlet/package-info.java | 0
.../src/site/site.xml | 0
.../StrutsSpringPortletMockObjectsTest.java | 11 +-
.../src/test/resources/applicationContext.xml | 0
plugins/portlet/pom.xml | 9 +-
.../apache/struts2/StrutsTestCasePortletTests.java | 224 +++++++++++++++++++++
.../struts2/components/PortletUrlRendererTest.java | 4 +-
.../interceptor/PortletStateInterceptorTest.java | 4 +-
pom.xml | 4 +-
41 files changed, 267 insertions(+), 53 deletions(-)
diff --git a/plugins/junit/pom.xml b/plugins/junit/pom.xml
index f41e243..b978c8d 100644
--- a/plugins/junit/pom.xml
+++ b/plugins/junit/pom.xml
@@ -70,7 +70,20 @@
<dependency>
<groupId>javax.portlet</groupId>
<artifactId>portlet-api</artifactId>
- <scope>test</scope>
+ <scope>compile</scope>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-portlet-plugin</artifactId>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-portlet-mocks-plugin</artifactId>
+ <optional>true</optional>
</dependency>
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
diff --git a/plugins/portlet/src/main/java/org/apache/struts2/StrutsPortletTestCase.java b/plugins/junit/src/main/java/org/apache/struts2/StrutsPortletTestCase.java
similarity index 86%
rename from plugins/portlet/src/main/java/org/apache/struts2/StrutsPortletTestCase.java
rename to plugins/junit/src/main/java/org/apache/struts2/StrutsPortletTestCase.java
index 0f07ea9..624a186 100644
--- a/plugins/portlet/src/main/java/org/apache/struts2/StrutsPortletTestCase.java
+++ b/plugins/junit/src/main/java/org/apache/struts2/StrutsPortletTestCase.java
@@ -18,20 +18,30 @@
*/
package org.apache.struts2;
+
import com.opensymphony.xwork2.ActionContext;
+import java.util.HashMap;
+import java.util.Map;
+import javax.portlet.PortletMode;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
-import org.apache.struts2.portlet.PortletConstants;
-import org.apache.struts2.portlet.PortletPhase;
import org.apache.struts2.mock.web.portlet.MockPortletContext;
import org.apache.struts2.mock.web.portlet.MockPortletRequest;
import org.apache.struts2.mock.web.portlet.MockPortletResponse;
import org.apache.struts2.mock.web.portlet.MockPortletSession;
import org.apache.struts2.mock.web.portlet.MockStateAwareResponse;
+import org.apache.struts2.portlet.PortletConstants;
+import org.apache.struts2.portlet.PortletPhase;
-import javax.portlet.PortletMode;
-import java.util.HashMap;
-import java.util.Map;
+/*
+ * Changes: This is a copy of org.apache.struts2.StrutsPortletTestCase from the Struts 2 portlet-plugin, moved
+ * into the junit-plugin (same package org.apache.struts2).
+ * The import order above was changed to alphabetical.
+ *
+ * Note: The assumption is that anyone utilizing StrutsPortletTestCase currently from the portlet-plugin will almost
+ * certainly be using the junit-plugin. Under that assumption, the refactored-move of StrutsPortletTestCase
+ * should not cause issues for pre-existing usage of StrutsPortletTestCase.
+ */
/**
* Base class used to test action in portlet environment
diff --git a/plugins/pom.xml b/plugins/pom.xml
index fdee6ed..b9f6254 100644
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -45,12 +45,12 @@
<module>jfreechart</module>
<module>json</module>
<module>junit</module>
- <module>junit-portlet</module>
<module>osgi</module>
<module>oval</module>
<module>pell-multipart</module>
<module>plexus</module>
<module>portlet</module>
+ <module>portlet-mocks</module>
<module>portlet-tiles</module>
<module>rest</module>
<module>sitemesh</module>
diff --git a/plugins/junit-portlet/pom.xml b/plugins/portlet-mocks/pom.xml
similarity index 72%
rename from plugins/junit-portlet/pom.xml
rename to plugins/portlet-mocks/pom.xml
index adfab00..afc9a8f 100644
--- a/plugins/junit-portlet/pom.xml
+++ b/plugins/portlet-mocks/pom.xml
@@ -27,9 +27,9 @@
<version>2.6-SNAPSHOT</version>
</parent>
- <artifactId>struts2-junit-portlet-plugin</artifactId>
+ <artifactId>struts2-portlet-mocks-plugin</artifactId>
<packaging>jar</packaging>
- <name>Struts 2 JUnit Portlet Plugin</name>
+ <name>Struts 2 Portlet Mocks Plugin</name>
<dependencies>
<dependency>
@@ -38,33 +38,12 @@
</dependency>
<dependency>
<groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.struts</groupId>
- <artifactId>struts2-junit-plugin</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.struts</groupId>
- <artifactId>struts2-spring-plugin</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>javax.servlet.jsp</groupId>
- <artifactId>jsp-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+ <scope>test</scope>
</dependency>
<!-- Portlet -->
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockActionRequest.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockActionRequest.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockActionRequest.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockActionRequest.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockActionResponse.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockActionResponse.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockActionResponse.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockActionResponse.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockBaseURL.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockBaseURL.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockBaseURL.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockBaseURL.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockCacheControl.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockCacheControl.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockCacheControl.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockCacheControl.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockClientDataRequest.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockClientDataRequest.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockClientDataRequest.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockClientDataRequest.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEvent.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockEvent.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEvent.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockEvent.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEventRequest.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockEventRequest.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEventRequest.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockEventRequest.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEventResponse.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockEventResponse.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEventResponse.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockEventResponse.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockMimeResponse.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockMimeResponse.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockMimeResponse.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockMimeResponse.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockMultipartActionRequest.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockMultipartActionRequest.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockMultipartActionRequest.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockMultipartActionRequest.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortalContext.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortalContext.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortalContext.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortalContext.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletConfig.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletConfig.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletConfig.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletConfig.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletContext.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletContext.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletContext.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletContext.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletPreferences.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletPreferences.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletPreferences.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletPreferences.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequest.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequest.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequest.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequest.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequestDispatcher.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequestDispatcher.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequestDispatcher.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequestDispatcher.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletResponse.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletResponse.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletResponse.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletResponse.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletSession.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletSession.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletSession.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletSession.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletURL.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletURL.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletURL.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletURL.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderRequest.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderRequest.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderRequest.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderRequest.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderResponse.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderResponse.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderResponse.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderResponse.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceRequest.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceRequest.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceRequest.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceRequest.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceResponse.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceResponse.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceResponse.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceResponse.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceURL.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceURL.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceURL.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceURL.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockStateAwareResponse.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockStateAwareResponse.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockStateAwareResponse.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/MockStateAwareResponse.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/ServletWrappingPortletContext.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/ServletWrappingPortletContext.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/ServletWrappingPortletContext.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/ServletWrappingPortletContext.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/multipart/MultipartActionRequest.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/multipart/MultipartActionRequest.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/multipart/MultipartActionRequest.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/multipart/MultipartActionRequest.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/multipart/package-info.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/multipart/package-info.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/multipart/package-info.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/multipart/package-info.java
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/package-info.java b/plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/package-info.java
similarity index 100%
rename from plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/package-info.java
rename to plugins/portlet-mocks/src/main/java/org/apache/struts2/mock/web/portlet/package-info.java
diff --git a/plugins/junit-portlet/src/site/site.xml b/plugins/portlet-mocks/src/site/site.xml
similarity index 100%
rename from plugins/junit-portlet/src/site/site.xml
rename to plugins/portlet-mocks/src/site/site.xml
diff --git a/plugins/junit-portlet/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java b/plugins/portlet-mocks/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java
similarity index 99%
rename from plugins/junit-portlet/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java
rename to plugins/portlet-mocks/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java
index e802dc6..821868f 100644
--- a/plugins/junit-portlet/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java
+++ b/plugins/portlet-mocks/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java
@@ -49,6 +49,7 @@ import javax.portlet.WindowState;
import javax.security.auth.Subject;
import javax.servlet.http.Cookie;
import javax.xml.namespace.QName;
+import junit.framework.TestCase;
import org.apache.struts2.mock.web.portlet.MockActionRequest;
import org.apache.struts2.mock.web.portlet.MockActionResponse;
import org.apache.struts2.mock.web.portlet.MockCacheControl;
@@ -84,7 +85,7 @@ import org.w3c.dom.Element;
* Basic test class for Portlet Mock Object testing
*
*/
-public class StrutsSpringPortletMockObjectsTest extends StrutsSpringTestCase {
+public class StrutsSpringPortletMockObjectsTest extends TestCase {
/**
* An empty preferences validator for code coverage only
@@ -98,14 +99,6 @@ public class StrutsSpringPortletMockObjectsTest extends StrutsSpringTestCase {
}
- public void testApplicationContext() {
- assertNotNull(applicationContext);
- }
-
- public void testContextLocations() {
- assertNotNull(getContextLocations());
- }
-
public void testMockActionRequest() {
final String TEST_ACTIONNAME = "TEST_ACTIONNAME";
diff --git a/plugins/junit-portlet/src/test/resources/applicationContext.xml b/plugins/portlet-mocks/src/test/resources/applicationContext.xml
similarity index 100%
rename from plugins/junit-portlet/src/test/resources/applicationContext.xml
rename to plugins/portlet-mocks/src/test/resources/applicationContext.xml
diff --git a/plugins/portlet/pom.xml b/plugins/portlet/pom.xml
index 5fc6480..31d35c5 100644
--- a/plugins/portlet/pom.xml
+++ b/plugins/portlet/pom.xml
@@ -33,16 +33,11 @@
<dependencies>
<!-- junit and related JARs are needed for 'compile'! -->
- <!-- Due to StrutsPortletTestCase shall be distributed to applications. -->
- <dependency>
- <groupId>org.apache.struts</groupId>
- <artifactId>struts2-junit-plugin</artifactId>
- <optional>true</optional>
- </dependency>
<dependency>
<groupId>org.apache.struts</groupId>
- <artifactId>struts2-junit-portlet-plugin</artifactId>
+ <artifactId>struts2-portlet-mocks-plugin</artifactId>
+ <scope>test</scope>
<optional>true</optional>
</dependency>
diff --git a/plugins/portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java b/plugins/portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java
new file mode 100644
index 0000000..1e7ea61
--- /dev/null
+++ b/plugins/portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java
@@ -0,0 +1,224 @@
+/*
+ * 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.struts2;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionProxy;
+import com.opensymphony.xwork2.ActionProxyFactory;
+import com.opensymphony.xwork2.XWorkTestCase;
+import com.opensymphony.xwork2.config.Configuration;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.struts2.dispatcher.Dispatcher;
+import org.apache.struts2.dispatcher.HttpParameters;
+import org.apache.struts2.dispatcher.mapper.ActionMapper;
+import org.apache.struts2.dispatcher.mapper.ActionMapping;
+import org.apache.struts2.util.StrutsTestCaseHelper;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.mock.web.MockHttpSession;
+import org.springframework.mock.web.MockPageContext;
+import org.springframework.mock.web.MockServletContext;
+
+/*
+ * Changes: This is a copy of org.apache.struts2.StrutsTestCase from the Struts 2 junit-plugin, kept in
+ * in the same package org.apache.struts2 and renamed. Removed some unused imports, made
+ * imports alphabetical and made some whitespace changes and modified a comment.
+ * The StrutsTestCasePortletTests is needed in order to break a dependency-cycle between the
+ * portlet-plugin and junit-plugin with respect to StrutsTestCase.
+ *
+ * Note: If the junit-plugin StrutsTestCase is updated/modified, it may be appropriate to update
+ * this version as well, for consistency (but they may diverge in the future).
+ * The StrutsTestCasePortletTests is intentionally kept at the test scope of the portlet-plugin
+ * as it only exists due to the dependency-cycle issue. The junit-plugin StrutsTestCase should
+ * be used elswehere.
+ */
+
+/**
+ * Base test case for JUnit testing Struts within the portlet-plugin unit tests.
+ */
+public abstract class StrutsTestCasePortletTests extends XWorkTestCase {
+ protected MockHttpServletResponse response;
+ protected MockHttpServletRequest request;
+ protected MockPageContext pageContext;
+ protected MockServletContext servletContext;
+ protected Map<String, String> dispatcherInitParams;
+ protected Dispatcher dispatcher;
+ protected DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
+
+ /**
+ * gets an object from the stack after an action is executed
+ */
+ protected Object findValueAfterExecute(String key) {
+ return ServletActionContext.getValueStack(request).findValue(key);
+ }
+
+ /**
+ * Executes an action and returns it's output (not the result returned from
+ * execute()), but the actual output that would be written to the response.
+ * For this to work the configured result for the action needs to be
+ * FreeMarker, or Velocity (JSPs can be used with the Embedded JSP plugin)
+ */
+ protected String executeAction(String uri) throws ServletException, UnsupportedEncodingException {
+ request.setRequestURI(uri);
+ ActionMapping mapping = getActionMapping(request);
+
+ assertNotNull(mapping);
+ Dispatcher.getInstance().serviceAction(request, response, mapping);
+
+ if (response.getStatus() != HttpServletResponse.SC_OK) {
+ throw new ServletException("Error code [" + response.getStatus() + "], Error: [" + response.getErrorMessage() + "]");
+ }
+ return response.getContentAsString();
+ }
+
+ /**
+ * Creates an action proxy for a request, and sets parameters of the ActionInvocation to the passed
+ * parameters. Make sure to set the request parameters in the protected "request" object before calling this method.
+ */
+ protected ActionProxy getActionProxy(String uri) {
+ request.setRequestURI(uri);
+ ActionMapping mapping = getActionMapping(request);
+ String namespace = mapping.getNamespace();
+ String name = mapping.getName();
+ String method = mapping.getMethod();
+
+ Configuration config = configurationManager.getConfiguration();
+ ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
+ namespace, name, method, new HashMap<String, Object>(), true, false);
+
+ initActionContext(proxy.getInvocation().getInvocationContext());
+
+ // this is normally done in onSetUp(), but we are using Struts internal
+ // objects (proxy and action invocation)
+ // so we have to hack around so it works
+ ServletActionContext.setServletContext(servletContext);
+ ServletActionContext.setRequest(request);
+ ServletActionContext.setResponse(response);
+
+ return proxy;
+ }
+
+ /**
+ * A helper method which allows instantiate an action if this action extends
+ * {@link com.opensymphony.xwork2.ActionSupport} or any other action class
+ * that requires framework's dependencies injection.
+ */
+ protected <T> T createAction(Class<T> clazz) {
+ return container.inject(clazz);
+ }
+
+ protected void initActionContext(ActionContext actionContext) {
+ actionContext.setParameters(HttpParameters.create(request.getParameterMap()).build());
+ initSession(actionContext);
+ applyAdditionalParams(actionContext);
+ // set the action context to the one used by the proxy
+ ActionContext.setContext(actionContext);
+ }
+
+ protected void initSession(ActionContext actionContext) {
+ if (actionContext.getSession() == null) {
+ actionContext.setSession(new HashMap<String, Object>());
+ request.setSession(new MockHttpSession(servletContext));
+ }
+ }
+
+ /**
+ * Can be overwritten in subclass to provide additional context's params and settings used during action invocation
+ *
+ * @param context current {@link ActionContext}
+ */
+ protected void applyAdditionalParams(ActionContext context) {
+ // empty be default
+ }
+
+ /**
+ * Finds an ActionMapping for a given request
+ */
+ protected ActionMapping getActionMapping(HttpServletRequest request) {
+ return container.getInstance(ActionMapper.class).getMapping(request, configurationManager);
+ }
+
+ /**
+ * Finds an ActionMapping for a given url
+ */
+ protected ActionMapping getActionMapping(String url) {
+ MockHttpServletRequest req = new MockHttpServletRequest();
+ req.setRequestURI(url);
+ return getActionMapping(req);
+ }
+
+ /**
+ * Injects dependencies on an Object using Struts internal IoC container
+ */
+ protected void injectStrutsDependencies(Object object) {
+ container.inject(object);
+ }
+
+ /**
+ * Sets up the configuration settings, XWork configuration, and
+ * message resources
+ */
+ protected void setUp() throws Exception {
+ super.setUp();
+ initServletMockObjects();
+ setupBeforeInitDispatcher();
+ dispatcher = initDispatcher(dispatcherInitParams);
+ setupAfterInitDispatcher(dispatcher);
+ }
+
+ protected void setupBeforeInitDispatcher() throws Exception {
+ // empty by default
+ }
+
+ protected void setupAfterInitDispatcher(Dispatcher dispatcher) {
+ // empty by default
+ }
+
+ protected void initServletMockObjects() {
+ servletContext = new MockServletContext(resourceLoader);
+ response = new MockHttpServletResponse();
+ request = new MockHttpServletRequest();
+ pageContext = new MockPageContext(servletContext, request, response);
+ }
+
+ protected Dispatcher initDispatcher(Map<String, String> params) {
+ Dispatcher du = StrutsTestCaseHelper.initDispatcher(servletContext, params);
+ configurationManager = du.getConfigurationManager();
+ configuration = configurationManager.getConfiguration();
+ container = configuration.getContainer();
+ return du;
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ // maybe someone else already destroyed Dispatcher
+ if (dispatcher != null && dispatcher.getConfigurationManager() != null) {
+ dispatcher.cleanup();
+ dispatcher = null;
+ }
+ StrutsTestCaseHelper.tearDown();
+ }
+
+}
diff --git a/plugins/portlet/src/test/java/org/apache/struts2/components/PortletUrlRendererTest.java b/plugins/portlet/src/test/java/org/apache/struts2/components/PortletUrlRendererTest.java
index 0272043..fbc87db 100644
--- a/plugins/portlet/src/test/java/org/apache/struts2/components/PortletUrlRendererTest.java
+++ b/plugins/portlet/src/test/java/org/apache/struts2/components/PortletUrlRendererTest.java
@@ -22,7 +22,7 @@ import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.struts2.StrutsStatics;
-import org.apache.struts2.StrutsTestCase;
+import org.apache.struts2.StrutsTestCasePortletTests;
import org.apache.struts2.portlet.PortletConstants;
import org.apache.struts2.mock.web.portlet.MockMimeResponse;
import org.apache.struts2.mock.web.portlet.MockPortletContext;
@@ -35,7 +35,7 @@ import java.io.StringWriter;
import java.io.Writer;
import java.util.Collections;
-public class PortletUrlRendererTest extends StrutsTestCase {
+public class PortletUrlRendererTest extends StrutsTestCasePortletTests {
private ValueStack stack;
diff --git a/plugins/portlet/src/test/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptorTest.java b/plugins/portlet/src/test/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptorTest.java
index 533b2ea..f324cf2 100644
--- a/plugins/portlet/src/test/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptorTest.java
+++ b/plugins/portlet/src/test/java/org/apache/struts2/portlet/interceptor/PortletStateInterceptorTest.java
@@ -22,7 +22,7 @@ import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.ValueStackFactory;
-import org.apache.struts2.StrutsTestCase;
+import org.apache.struts2.StrutsTestCasePortletTests;
import org.apache.struts2.dispatcher.DefaultActionSupport;
import org.apache.struts2.portlet.PortletPhase;
import org.apache.struts2.portlet.dispatcher.DirectRenderFromEventAction;
@@ -39,7 +39,7 @@ import static org.apache.struts2.portlet.PortletConstants.REQUEST;
import static org.apache.struts2.portlet.PortletConstants.RESPONSE;
import static org.apache.struts2.portlet.PortletConstants.STACK_FROM_EVENT_PHASE;
-public class PortletStateInterceptorTest extends StrutsTestCase {
+public class PortletStateInterceptorTest extends StrutsTestCasePortletTests {
private PortletStateInterceptor interceptor;
diff --git a/pom.xml b/pom.xml
index 2c83f31..bfbb5d4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -566,12 +566,12 @@
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
- <artifactId>struts2-junit-plugin</artifactId>
+ <artifactId>struts2-portlet-mocks-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
- <artifactId>struts2-junit-portlet-plugin</artifactId>
+ <artifactId>struts2-junit-plugin</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
[struts] 01/06: Proposed implementation to address WW-5030.
Introduce new junit-portlet plugin. - Utilizes a copy of
org.springframework.mock.web.portlet package from Spring 4.3.x,
refactored to org.apache.struts2.mock.web.portlet. Also copies one interface
from org.apache.struts2.mock.web.portlet. The package-info.java files
identify the package renaming. - Provides test cases for the mock objects.
- Modifies the portlet plugin to use the junit-portlet plugin as a
dependency. Adds a small boun [...]
Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch action-context-boost
in repository https://gitbox.apache.org/repos/asf/struts.git
commit 2e7a6b967e0b95576107073faa8c98caf7c2a428
Author: JCgH4164838Gh792C124B5 <43...@users.noreply.github.com>
AuthorDate: Sun Mar 22 13:31:54 2020 -0400
Proposed implementation to address WW-5030.
Introduce new junit-portlet plugin.
- Utilizes a copy of org.springframework.mock.web.portlet package from
Spring 4.3.x, refactored to org.apache.struts2.mock.web.portlet. Also
copies one interface from org.apache.struts2.mock.web.portlet. The
package-info.java files identify the package renaming.
- Provides test cases for the mock objects.
- Modifies the portlet plugin to use the junit-portlet plugin as a
dependency. Adds a small boundary case fix for PortletRequestMap.
---
plugins/{portlet => junit-portlet}/pom.xml | 96 +-
.../mock/web/portlet/MockActionRequest.java | 86 ++
.../mock/web/portlet/MockActionResponse.java | 132 ++
.../struts2/mock/web/portlet/MockBaseURL.java | 161 ++
.../struts2/mock/web/portlet/MockCacheControl.java | 78 +
.../mock/web/portlet/MockClientDataRequest.java | 135 ++
.../apache/struts2/mock/web/portlet/MockEvent.java | 91 ++
.../struts2/mock/web/portlet/MockEventRequest.java | 90 ++
.../mock/web/portlet/MockEventResponse.java | 35 +
.../struts2/mock/web/portlet/MockMimeResponse.java | 259 ++++
.../web/portlet/MockMultipartActionRequest.java | 101 ++
.../mock/web/portlet/MockPortalContext.java | 106 ++
.../mock/web/portlet/MockPortletConfig.java | 194 +++
.../mock/web/portlet/MockPortletContext.java | 285 ++++
.../mock/web/portlet/MockPortletPreferences.java | 123 ++
.../mock/web/portlet/MockPortletRequest.java | 565 +++++++
.../web/portlet/MockPortletRequestDispatcher.java | 87 ++
.../mock/web/portlet/MockPortletResponse.java | 202 +++
.../mock/web/portlet/MockPortletSession.java | 249 +++
.../struts2/mock/web/portlet/MockPortletURL.java | 121 ++
.../mock/web/portlet/MockRenderRequest.java | 94 ++
.../mock/web/portlet/MockRenderResponse.java | 90 ++
.../mock/web/portlet/MockResourceRequest.java | 132 ++
.../mock/web/portlet/MockResourceResponse.java | 41 +
.../struts2/mock/web/portlet/MockResourceURL.java | 73 +
.../mock/web/portlet/MockStateAwareResponse.java | 165 ++
.../web/portlet/ServletWrappingPortletContext.java | 161 ++
.../portlet/multipart/MultipartActionRequest.java | 41 +
.../mock/web/portlet/multipart/package-info.java | 38 +
.../struts2/mock/web/portlet/package-info.java | 35 +
plugins/junit-portlet/src/site/site.xml | 56 +
.../StrutsSpringPortletMockObjectsTest.java | 1596 ++++++++++++++++++++
.../src/test/resources/applicationContext.xml | 36 +
plugins/pom.xml | 1 +
plugins/portlet/pom.xml | 6 +
.../org/apache/struts2/StrutsPortletTestCase.java | 10 +-
.../apache/struts2/portlet/PortletRequestMap.java | 10 +-
.../struts2/components/PortletUrlRendererTest.java | 6 +-
.../struts2/portlet/PortletRequestMapTest.java | 2 +-
.../struts2/portlet/PortletSessionMapTest.java | 2 +-
.../portlet/dispatcher/Jsr168DispatcherTest.java | 4 +-
.../portlet/dispatcher/Jsr286DispatcherTest.java | 4 +-
pom.xml | 5 +
43 files changed, 5712 insertions(+), 92 deletions(-)
diff --git a/plugins/portlet/pom.xml b/plugins/junit-portlet/pom.xml
similarity index 57%
copy from plugins/portlet/pom.xml
copy to plugins/junit-portlet/pom.xml
index c5198b8..adfab00 100644
--- a/plugins/portlet/pom.xml
+++ b/plugins/junit-portlet/pom.xml
@@ -27,47 +27,44 @@
<version>2.6-SNAPSHOT</version>
</parent>
- <artifactId>struts2-portlet-plugin</artifactId>
+ <artifactId>struts2-junit-portlet-plugin</artifactId>
<packaging>jar</packaging>
- <name>Struts 2 Portlet Plugin</name>
+ <name>Struts 2 JUnit Portlet Plugin</name>
<dependencies>
- <!-- junit and related JARs are needed for 'compile'! -->
- <!-- Due to StrutsPortletTestCase shall be distributed to applications. -->
<dependency>
- <groupId>org.apache.struts</groupId>
- <artifactId>struts2-junit-plugin</artifactId>
- <optional>true</optional>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
</dependency>
-
<dependency>
- <groupId>org.apache.struts</groupId>
- <artifactId>struts2-velocity-plugin</artifactId>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-core</artifactId>
</dependency>
-
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <optional>true</optional>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
</dependency>
-
- <!-- spring-core is required for javadoc of jdk8 -->
- <!-- It is indirectly referenced by struts2-junit-plugin. -->
<dependency>
<groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
+ <artifactId>spring-web</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-junit-plugin</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-spring-plugin</artifactId>
<optional>true</optional>
</dependency>
-
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
</dependency>
-
<dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-lang3</artifactId>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
</dependency>
<!-- Portlet -->
@@ -77,59 +74,6 @@
<scope>provided</scope>
</dependency>
- <dependency>
- <groupId>mockobjects</groupId>
- <artifactId>mockobjects-jdk1.3-j2ee1.3</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymock</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>jmock</groupId>
- <artifactId>jmock</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>jmock</groupId>
- <artifactId>jmock-cglib</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>mockobjects</groupId>
- <artifactId>mockobjects-core</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.logging.log4j</groupId>
- <artifactId>log4j-core</artifactId>
- <version>${log4j2.version}</version>
- <scope>test</scope>
- </dependency>
-
- <!-- Mocks for unit testing (by Spring) -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-test</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc-portlet</artifactId>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>commons-fileupload</groupId>
- <artifactId>commons-fileupload</artifactId>
- <scope>test</scope>
- </dependency>
-
<!-- The Servlet API mocks in Spring Framework 4.x only supports Servlet 3.0 and higher.
This is only necessary in tests-->
<dependency>
@@ -140,6 +84,6 @@
</dependency>
</dependencies>
<properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockActionRequest.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockActionRequest.java
new file mode 100644
index 0000000..390df5c
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockActionRequest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2002-2009 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletMode;
+
+/**
+ * Mock implementation of the {@link javax.portlet.ActionRequest} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockActionRequest extends MockClientDataRequest implements ActionRequest {
+
+ /**
+ * Create a new MockActionRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @see org.springframework.mock.web.portlet.MockPortalContext
+ * @see org.springframework.mock.web.portlet.MockPortletContext
+ */
+ public MockActionRequest() {
+ super();
+ }
+
+ /**
+ * Create a new MockActionRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @param actionName the name of the action to trigger
+ */
+ public MockActionRequest(String actionName) {
+ super();
+ setParameter(ActionRequest.ACTION_NAME, actionName);
+ }
+
+ /**
+ * Create a new MockActionRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @param portletMode the mode that the portlet runs in
+ */
+ public MockActionRequest(PortletMode portletMode) {
+ super();
+ setPortletMode(portletMode);
+ }
+
+ /**
+ * Create a new MockActionRequest with a default {@link MockPortalContext}.
+ * @param portletContext the PortletContext that the request runs in
+ */
+ public MockActionRequest(PortletContext portletContext) {
+ super(portletContext);
+ }
+
+ /**
+ * Create a new MockActionRequest.
+ * @param portalContext the PortalContext that the request runs in
+ * @param portletContext the PortletContext that the request runs in
+ */
+ public MockActionRequest(PortalContext portalContext, PortletContext portletContext) {
+ super(portalContext, portletContext);
+ }
+
+
+ @Override
+ protected String getLifecyclePhase() {
+ return ACTION_PHASE;
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockActionResponse.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockActionResponse.java
new file mode 100644
index 0000000..b120ffd
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockActionResponse.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.io.IOException;
+import java.util.Map;
+import javax.portlet.ActionResponse;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletModeException;
+import javax.portlet.WindowState;
+import javax.portlet.WindowStateException;
+
+import org.springframework.util.Assert;
+
+/**
+ * Mock implementation of the {@link javax.portlet.ActionResponse} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockActionResponse extends MockStateAwareResponse implements ActionResponse {
+
+ private boolean redirectAllowed = true;
+
+ private String redirectedUrl;
+
+
+ /**
+ * Create a new MockActionResponse with a default {@link MockPortalContext}.
+ * @see MockPortalContext
+ */
+ public MockActionResponse() {
+ super();
+ }
+
+ /**
+ * Create a new MockActionResponse.
+ * @param portalContext the PortalContext defining the supported
+ * PortletModes and WindowStates
+ */
+ public MockActionResponse(PortalContext portalContext) {
+ super(portalContext);
+ }
+
+
+ @Override
+ public void setWindowState(WindowState windowState) throws WindowStateException {
+ if (this.redirectedUrl != null) {
+ throw new IllegalStateException("Cannot set WindowState after sendRedirect has been called");
+ }
+ super.setWindowState(windowState);
+ this.redirectAllowed = false;
+ }
+
+ @Override
+ public void setPortletMode(PortletMode portletMode) throws PortletModeException {
+ if (this.redirectedUrl != null) {
+ throw new IllegalStateException("Cannot set PortletMode after sendRedirect has been called");
+ }
+ super.setPortletMode(portletMode);
+ this.redirectAllowed = false;
+ }
+
+ @Override
+ public void setRenderParameters(Map<String, String[]> parameters) {
+ if (this.redirectedUrl != null) {
+ throw new IllegalStateException("Cannot set render parameters after sendRedirect has been called");
+ }
+ super.setRenderParameters(parameters);
+ this.redirectAllowed = false;
+ }
+
+ @Override
+ public void setRenderParameter(String key, String value) {
+ if (this.redirectedUrl != null) {
+ throw new IllegalStateException("Cannot set render parameters after sendRedirect has been called");
+ }
+ super.setRenderParameter(key, value);
+ this.redirectAllowed = false;
+ }
+
+ @Override
+ public void setRenderParameter(String key, String[] values) {
+ if (this.redirectedUrl != null) {
+ throw new IllegalStateException("Cannot set render parameters after sendRedirect has been called");
+ }
+ super.setRenderParameter(key, values);
+ this.redirectAllowed = false;
+ }
+
+ @Override
+ public void sendRedirect(String location) throws IOException {
+ if (!this.redirectAllowed) {
+ throw new IllegalStateException(
+ "Cannot call sendRedirect after windowState, portletMode, or renderParameters have been set");
+ }
+ Assert.notNull(location, "Redirect URL must not be null");
+ this.redirectedUrl = location;
+ }
+
+ @Override
+ public void sendRedirect(String location, String renderUrlParamName) throws IOException {
+ sendRedirect(location);
+ if (renderUrlParamName != null) {
+ // NOTE: Changed since original Spring 4.3.x version.
+ // Cannot call setRenderParameter(renderUrlParamName, location) here as it always results in an IllegalStateException - since a redirect has been called.
+ // Due to this, we call super.setRenderParameter() directly, otherwise this method can never successfully be called.
+ super.setRenderParameter(renderUrlParamName, location);
+ }
+ }
+
+ public String getRedirectedUrl() {
+ return this.redirectedUrl;
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockBaseURL.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockBaseURL.java
new file mode 100644
index 0000000..c0a1995
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockBaseURL.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.net.URLEncoder;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.portlet.BaseURL;
+import javax.portlet.PortletSecurityException;
+
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * Mock implementation of the {@link javax.portlet.BaseURL} interface.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ */
+public abstract class MockBaseURL implements BaseURL {
+
+ public static final String URL_TYPE_RENDER = "render";
+
+ public static final String URL_TYPE_ACTION = "action";
+
+ private static final String ENCODING = "UTF-8";
+
+
+ protected final Map<String, String[]> parameters = new LinkedHashMap<String, String[]>();
+
+ private boolean secure = false;
+
+ private final Map<String, String[]> properties = new LinkedHashMap<String, String[]>();
+
+
+ //---------------------------------------------------------------------
+ // BaseURL methods
+ //---------------------------------------------------------------------
+
+ @Override
+ public void setParameter(String key, String value) {
+ Assert.notNull(key, "Parameter key must be null");
+ Assert.notNull(value, "Parameter value must not be null");
+ this.parameters.put(key, new String[] {value});
+ }
+
+ @Override
+ public void setParameter(String key, String[] values) {
+ Assert.notNull(key, "Parameter key must be null");
+ Assert.notNull(values, "Parameter values must not be null");
+ this.parameters.put(key, values);
+ }
+
+ @Override
+ public void setParameters(Map<String, String[]> parameters) {
+ Assert.notNull(parameters, "Parameters Map must not be null");
+ this.parameters.clear();
+ this.parameters.putAll(parameters);
+ }
+
+ public Set<String> getParameterNames() {
+ return this.parameters.keySet();
+ }
+
+ public String getParameter(String name) {
+ String[] arr = this.parameters.get(name);
+ return (arr != null && arr.length > 0 ? arr[0] : null);
+ }
+
+ public String[] getParameterValues(String name) {
+ return this.parameters.get(name);
+ }
+
+ @Override
+ public Map<String, String[]> getParameterMap() {
+ return Collections.unmodifiableMap(this.parameters);
+ }
+
+ @Override
+ public void setSecure(boolean secure) throws PortletSecurityException {
+ this.secure = secure;
+ }
+
+ public boolean isSecure() {
+ return this.secure;
+ }
+
+ @Override
+ public void write(Writer out) throws IOException {
+ out.write(toString());
+ }
+
+ @Override
+ public void write(Writer out, boolean escapeXML) throws IOException {
+ out.write(toString());
+ }
+
+ @Override
+ public void addProperty(String key, String value) {
+ String[] values = this.properties.get(key);
+ if (values != null) {
+ this.properties.put(key, StringUtils.addStringToArray(values, value));
+ }
+ else {
+ this.properties.put(key, new String[] {value});
+ }
+ }
+
+ @Override
+ public void setProperty(String key, String value) {
+ this.properties.put(key, new String[] {value});
+ }
+
+ public Map<String, String[]> getProperties() {
+ return Collections.unmodifiableMap(this.properties);
+ }
+
+
+ protected String encodeParameter(String name, String value) {
+ try {
+ return URLEncoder.encode(name, ENCODING) + "=" + URLEncoder.encode(value, ENCODING);
+ }
+ catch (UnsupportedEncodingException ex) {
+ return null;
+ }
+ }
+
+ protected String encodeParameter(String name, String[] values) {
+ try {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0, n = values.length; i < n; i++) {
+ sb.append(i > 0 ? ";" : "").append(URLEncoder.encode(name, ENCODING)).append("=")
+ .append(URLEncoder.encode(values[i], ENCODING));
+ }
+ return sb.toString();
+ }
+ catch (UnsupportedEncodingException ex) {
+ return null;
+ }
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockCacheControl.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockCacheControl.java
new file mode 100644
index 0000000..f0ae50a
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockCacheControl.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import javax.portlet.CacheControl;
+
+/**
+ * Mock implementation of the {@link javax.portlet.CacheControl} interface.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ */
+public class MockCacheControl implements CacheControl {
+
+ private int expirationTime = 0;
+
+ private boolean publicScope = false;
+
+ private String etag;
+
+ private boolean useCachedContent = false;
+
+
+ @Override
+ public int getExpirationTime() {
+ return this.expirationTime;
+ }
+
+ @Override
+ public void setExpirationTime(int time) {
+ this.expirationTime = time;
+ }
+
+ @Override
+ public boolean isPublicScope() {
+ return this.publicScope;
+ }
+
+ @Override
+ public void setPublicScope(boolean publicScope) {
+ this.publicScope = publicScope;
+ }
+
+ @Override
+ public String getETag() {
+ return this.etag;
+ }
+
+ @Override
+ public void setETag(String token) {
+ this.etag = token;
+ }
+
+ @Override
+ public boolean useCachedContent() {
+ return this.useCachedContent;
+ }
+
+ @Override
+ public void setUseCachedContent(boolean useCachedContent) {
+ this.useCachedContent = useCachedContent;
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockClientDataRequest.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockClientDataRequest.java
new file mode 100644
index 0000000..44792d1
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockClientDataRequest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import javax.portlet.ClientDataRequest;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletContext;
+
+/**
+ * Mock implementation of the {@link javax.portlet.ClientDataRequest} interface.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ */
+public class MockClientDataRequest extends MockPortletRequest implements ClientDataRequest {
+
+ private String characterEncoding;
+
+ private byte[] content;
+
+ private String contentType;
+
+ private String method;
+
+
+ /**
+ * Create a new MockClientDataRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @see org.springframework.mock.web.portlet.MockPortalContext
+ * @see org.springframework.mock.web.portlet.MockPortletContext
+ */
+ public MockClientDataRequest() {
+ super();
+ }
+
+ /**
+ * Create a new MockClientDataRequest with a default {@link MockPortalContext}.
+ * @param portletContext the PortletContext that the request runs in
+ */
+ public MockClientDataRequest(PortletContext portletContext) {
+ super(portletContext);
+ }
+
+ /**
+ * Create a new MockClientDataRequest.
+ * @param portalContext the PortalContext that the request runs in
+ * @param portletContext the PortletContext that the request runs in
+ */
+ public MockClientDataRequest(PortalContext portalContext, PortletContext portletContext) {
+ super(portalContext, portletContext);
+ }
+
+
+ public void setContent(byte[] content) {
+ this.content = content;
+ }
+
+ @Override
+ public InputStream getPortletInputStream() throws IOException {
+ if (this.content != null) {
+ return new ByteArrayInputStream(this.content);
+ }
+ else {
+ return null;
+ }
+ }
+
+ @Override
+ public void setCharacterEncoding(String characterEncoding) {
+ this.characterEncoding = characterEncoding;
+ }
+
+ @Override
+ public BufferedReader getReader() throws UnsupportedEncodingException {
+ if (this.content != null) {
+ InputStream sourceStream = new ByteArrayInputStream(this.content);
+ Reader sourceReader = (this.characterEncoding != null) ?
+ new InputStreamReader(sourceStream, this.characterEncoding) : new InputStreamReader(sourceStream);
+ return new BufferedReader(sourceReader);
+ }
+ else {
+ return null;
+ }
+ }
+
+ @Override
+ public String getCharacterEncoding() {
+ return this.characterEncoding;
+ }
+
+ public void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ @Override
+ public String getContentType() {
+ return this.contentType;
+ }
+
+ @Override
+ public int getContentLength() {
+ return (this.content != null ? content.length : -1);
+ }
+
+ public void setMethod(String method) {
+ this.method = method;
+ }
+
+ @Override
+ public String getMethod() {
+ return this.method;
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEvent.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEvent.java
new file mode 100644
index 0000000..2e9a411
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEvent.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.io.Serializable;
+import javax.portlet.Event;
+import javax.xml.namespace.QName;
+
+/**
+ * Mock implementation of the {@link javax.portlet.Event} interface.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ * @see MockEventRequest
+ */
+public class MockEvent implements Event {
+
+ private final QName name;
+
+ private final Serializable value;
+
+
+ /**
+ * Create a new MockEvent with the given name.
+ * @param name the name of the event
+ */
+ public MockEvent(QName name) {
+ this.name = name;
+ this.value = null;
+ }
+
+ /**
+ * Create a new MockEvent with the given name and value.
+ * @param name the name of the event
+ * @param value the associated payload of the event
+ */
+ public MockEvent(QName name, Serializable value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ /**
+ * Create a new MockEvent with the given name.
+ * @param name the name of the event
+ */
+ public MockEvent(String name) {
+ this.name = new QName(name);
+ this.value = null;
+ }
+
+ /**
+ * Create a new MockEvent with the given name and value.
+ * @param name the name of the event
+ * @param value the associated payload of the event
+ */
+ public MockEvent(String name, Serializable value) {
+ this.name = new QName(name);
+ this.value = value;
+ }
+
+
+ @Override
+ public QName getQName() {
+ return this.name;
+ }
+
+ @Override
+ public String getName() {
+ return this.name.getLocalPart();
+ }
+
+ @Override
+ public Serializable getValue() {
+ return this.value;
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEventRequest.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEventRequest.java
new file mode 100644
index 0000000..c055511
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEventRequest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import javax.portlet.Event;
+import javax.portlet.EventRequest;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletContext;
+
+/**
+ * Mock implementation of the {@link javax.portlet.EventRequest} interface.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ */
+public class MockEventRequest extends MockPortletRequest implements EventRequest {
+
+ private final Event event;
+
+ private String method;
+
+
+ /**
+ * Create a new MockEventRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @param event the event that this request wraps
+ * @see MockEvent
+ */
+ public MockEventRequest(Event event) {
+ super();
+ this.event = event;
+ }
+
+ /**
+ * Create a new MockEventRequest with a default {@link MockPortalContext}.
+ * @param event the event that this request wraps
+ * @param portletContext the PortletContext that the request runs in
+ * @see MockEvent
+ */
+ public MockEventRequest(Event event, PortletContext portletContext) {
+ super(portletContext);
+ this.event = event;
+ }
+
+ /**
+ * Create a new MockEventRequest.
+ * @param event the event that this request wraps
+ * @param portalContext the PortletContext that the request runs in
+ * @param portletContext the PortletContext that the request runs in
+ */
+ public MockEventRequest(Event event, PortalContext portalContext, PortletContext portletContext) {
+ super(portalContext, portletContext);
+ this.event = event;
+ }
+
+
+ @Override
+ protected String getLifecyclePhase() {
+ return EVENT_PHASE;
+ }
+
+ @Override
+ public Event getEvent() {
+ return this.event;
+ }
+
+ public void setMethod(String method) {
+ this.method = method;
+ }
+
+ @Override
+ public String getMethod() {
+ return this.method;
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEventResponse.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEventResponse.java
new file mode 100644
index 0000000..9bda32e
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockEventResponse.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import javax.portlet.EventRequest;
+import javax.portlet.EventResponse;
+
+/**
+ * Mock implementation of the {@link javax.portlet.EventResponse} interface.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ */
+public class MockEventResponse extends MockStateAwareResponse implements EventResponse {
+
+ @Override
+ public void setRenderParameters(EventRequest request) {
+ setRenderParameters(request.getParameterMap());
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockMimeResponse.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockMimeResponse.java
new file mode 100644
index 0000000..cb654cb
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockMimeResponse.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Locale;
+import javax.portlet.CacheControl;
+import javax.portlet.MimeResponse;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletURL;
+import javax.portlet.ResourceURL;
+
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.util.WebUtils;
+
+/**
+ * Mock implementation of the {@link javax.portlet.MimeResponse} interface.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ */
+public class MockMimeResponse extends MockPortletResponse implements MimeResponse {
+
+ private PortletRequest request;
+
+ private String contentType;
+
+ private String characterEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING;
+
+ private PrintWriter writer;
+
+ private Locale locale = Locale.getDefault();
+
+ private int bufferSize = 4096;
+
+ private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+ private final CacheControl cacheControl = new MockCacheControl();
+
+ private boolean committed;
+
+ private String includedUrl;
+
+ private String forwardedUrl;
+
+
+ /**
+ * Create a new MockMimeResponse with a default {@link MockPortalContext}.
+ * @see org.springframework.mock.web.portlet.MockPortalContext
+ */
+ public MockMimeResponse() {
+ super();
+ }
+
+ /**
+ * Create a new MockMimeResponse.
+ * @param portalContext the PortalContext defining the supported
+ * PortletModes and WindowStates
+ */
+ public MockMimeResponse(PortalContext portalContext) {
+ super(portalContext);
+ }
+
+ /**
+ * Create a new MockMimeResponse.
+ * @param portalContext the PortalContext defining the supported
+ * PortletModes and WindowStates
+ * @param request the corresponding render/resource request that this response
+ * is being generated for
+ */
+ public MockMimeResponse(PortalContext portalContext, PortletRequest request) {
+ super(portalContext);
+ this.request = request;
+ }
+
+
+ //---------------------------------------------------------------------
+ // RenderResponse methods
+ //---------------------------------------------------------------------
+
+ @Override
+ public void setContentType(String contentType) {
+ if (this.request != null) {
+ Enumeration<String> supportedTypes = this.request.getResponseContentTypes();
+ if (!CollectionUtils.contains(supportedTypes, contentType)) {
+ throw new IllegalArgumentException("Content type [" + contentType + "] not in supported list: " +
+ Collections.list(supportedTypes));
+ }
+ }
+ this.contentType = contentType;
+ }
+
+ @Override
+ public String getContentType() {
+ return this.contentType;
+ }
+
+ public void setCharacterEncoding(String characterEncoding) {
+ this.characterEncoding = characterEncoding;
+ }
+
+ @Override
+ public String getCharacterEncoding() {
+ return this.characterEncoding;
+ }
+
+ @Override
+ public PrintWriter getWriter() throws UnsupportedEncodingException {
+ if (this.writer == null) {
+ Writer targetWriter = (this.characterEncoding != null
+ ? new OutputStreamWriter(this.outputStream, this.characterEncoding)
+ : new OutputStreamWriter(this.outputStream));
+ this.writer = new PrintWriter(targetWriter);
+ }
+ return this.writer;
+ }
+
+ public byte[] getContentAsByteArray() {
+ flushBuffer();
+ return this.outputStream.toByteArray();
+ }
+
+ public String getContentAsString() throws UnsupportedEncodingException {
+ flushBuffer();
+ return (this.characterEncoding != null)
+ ? this.outputStream.toString(this.characterEncoding)
+ : this.outputStream.toString();
+ }
+
+ public void setLocale(Locale locale) {
+ this.locale = locale;
+ }
+
+ @Override
+ public Locale getLocale() {
+ return this.locale;
+ }
+
+ @Override
+ public void setBufferSize(int bufferSize) {
+ this.bufferSize = bufferSize;
+ }
+
+ @Override
+ public int getBufferSize() {
+ return this.bufferSize;
+ }
+
+ @Override
+ public void flushBuffer() {
+ if (this.writer != null) {
+ this.writer.flush();
+ }
+ if (this.outputStream != null) {
+ try {
+ this.outputStream.flush();
+ }
+ catch (IOException ex) {
+ throw new IllegalStateException("Could not flush OutputStream: " + ex.getMessage());
+ }
+ }
+ this.committed = true;
+ }
+
+ @Override
+ public void resetBuffer() {
+ if (this.committed) {
+ throw new IllegalStateException("Cannot reset buffer - response is already committed");
+ }
+ this.outputStream.reset();
+ }
+
+ public void setCommitted(boolean committed) {
+ this.committed = committed;
+ }
+
+ @Override
+ public boolean isCommitted() {
+ return this.committed;
+ }
+
+ @Override
+ public void reset() {
+ resetBuffer();
+ this.characterEncoding = null;
+ this.contentType = null;
+ this.locale = null;
+ }
+
+ @Override
+ public OutputStream getPortletOutputStream() throws IOException {
+ return this.outputStream;
+ }
+
+ @Override
+ public PortletURL createRenderURL() {
+ return new MockPortletURL(getPortalContext(), MockPortletURL.URL_TYPE_RENDER);
+ }
+
+ @Override
+ public PortletURL createActionURL() {
+ return new MockPortletURL(getPortalContext(), MockPortletURL.URL_TYPE_ACTION);
+ }
+
+ @Override
+ public ResourceURL createResourceURL() {
+ return new MockResourceURL();
+ }
+
+ @Override
+ public CacheControl getCacheControl() {
+ return this.cacheControl;
+ }
+
+
+ //---------------------------------------------------------------------
+ // Methods for MockPortletRequestDispatcher
+ //---------------------------------------------------------------------
+
+ public void setIncludedUrl(String includedUrl) {
+ this.includedUrl = includedUrl;
+ }
+
+ public String getIncludedUrl() {
+ return this.includedUrl;
+ }
+
+ public void setForwardedUrl(String forwardedUrl) {
+ this.forwardedUrl = forwardedUrl;
+ }
+
+ public String getForwardedUrl() {
+ return this.forwardedUrl;
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockMultipartActionRequest.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockMultipartActionRequest.java
new file mode 100644
index 0000000..396e8cf
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockMultipartActionRequest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.util.Assert;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.multipart.MultipartFile;
+import org.apache.struts2.mock.web.portlet.multipart.MultipartActionRequest;
+
+/**
+ * Mock implementation of the
+ * {@link org.springframework.web.portlet.multipart.MultipartActionRequest} interface.
+ *
+ * <p>Useful for testing application controllers that access multipart uploads.
+ * The {@link org.springframework.mock.web.MockMultipartFile} can be used to
+ * populate these mock requests with files.
+ *
+ * @author Juergen Hoeller
+ * @author Arjen Poutsma
+ * @since 2.0
+ * @see org.springframework.mock.web.MockMultipartFile
+ */
+public class MockMultipartActionRequest extends MockActionRequest implements MultipartActionRequest {
+
+ private final MultiValueMap<String, MultipartFile> multipartFiles =
+ new LinkedMultiValueMap<String, MultipartFile>();
+
+
+ /**
+ * Add a file to this request. The parameter name from the multipart
+ * form is taken from the {@link org.springframework.web.multipart.MultipartFile#getName()}.
+ * @param file multipart file to be added
+ */
+ public void addFile(MultipartFile file) {
+ Assert.notNull(file, "MultipartFile must not be null");
+ this.multipartFiles.add(file.getName(), file);
+ }
+
+ @Override
+ public Iterator<String> getFileNames() {
+ return this.multipartFiles.keySet().iterator();
+ }
+
+ @Override
+ public MultipartFile getFile(String name) {
+ return this.multipartFiles.getFirst(name);
+ }
+
+ @Override
+ public List<MultipartFile> getFiles(String name) {
+ List<MultipartFile> multipartFiles = this.multipartFiles.get(name);
+ if (multipartFiles != null) {
+ return multipartFiles;
+ }
+ else {
+ return Collections.emptyList();
+ }
+ }
+
+ @Override
+ public Map<String, MultipartFile> getFileMap() {
+ return this.multipartFiles.toSingleValueMap();
+ }
+
+ @Override
+ public MultiValueMap<String, MultipartFile> getMultiFileMap() {
+ return new LinkedMultiValueMap<String, MultipartFile>(this.multipartFiles);
+ }
+
+ @Override
+ public String getMultipartContentType(String paramOrFileName) {
+ MultipartFile file = getFile(paramOrFileName);
+ if (file != null) {
+ return file.getContentType();
+ }
+ else {
+ return null;
+ }
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortalContext.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortalContext.java
new file mode 100644
index 0000000..0c7eccf
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortalContext.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletMode;
+import javax.portlet.WindowState;
+
+/**
+ * Mock implementation of the {@link javax.portlet.PortalContext} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockPortalContext implements PortalContext {
+
+ private final Map<String, String> properties = new HashMap<String, String>();
+
+ private final List<PortletMode> portletModes;
+
+ private final List<WindowState> windowStates;
+
+
+ /**
+ * Create a new MockPortalContext
+ * with default PortletModes (VIEW, EDIT, HELP)
+ * and default WindowStates (NORMAL, MAXIMIZED, MINIMIZED).
+ * @see javax.portlet.PortletMode
+ * @see javax.portlet.WindowState
+ */
+ public MockPortalContext() {
+ this.portletModes = new ArrayList<PortletMode>(3);
+ this.portletModes.add(PortletMode.VIEW);
+ this.portletModes.add(PortletMode.EDIT);
+ this.portletModes.add(PortletMode.HELP);
+
+ this.windowStates = new ArrayList<WindowState>(3);
+ this.windowStates.add(WindowState.NORMAL);
+ this.windowStates.add(WindowState.MAXIMIZED);
+ this.windowStates.add(WindowState.MINIMIZED);
+ }
+
+ /**
+ * Create a new MockPortalContext with the given PortletModes and WindowStates.
+ * @param supportedPortletModes the List of supported PortletMode instances
+ * @param supportedWindowStates the List of supported WindowState instances
+ * @see javax.portlet.PortletMode
+ * @see javax.portlet.WindowState
+ */
+ public MockPortalContext(List<PortletMode> supportedPortletModes, List<WindowState> supportedWindowStates) {
+ this.portletModes = new ArrayList<PortletMode>(supportedPortletModes);
+ this.windowStates = new ArrayList<WindowState>(supportedWindowStates);
+ }
+
+
+ @Override
+ public String getPortalInfo() {
+ return "MockPortal/1.0";
+ }
+
+ public void setProperty(String name, String value) {
+ this.properties.put(name, value);
+ }
+
+ @Override
+ public String getProperty(String name) {
+ return this.properties.get(name);
+ }
+
+ @Override
+ public Enumeration<String> getPropertyNames() {
+ return Collections.enumeration(this.properties.keySet());
+ }
+
+ @Override
+ public Enumeration<PortletMode> getSupportedPortletModes() {
+ return Collections.enumeration(this.portletModes);
+ }
+
+ @Override
+ public Enumeration<WindowState> getSupportedWindowStates() {
+ return Collections.enumeration(this.windowStates);
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletConfig.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletConfig.java
new file mode 100644
index 0000000..33d7e90
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletConfig.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
+import javax.portlet.PortletConfig;
+import javax.portlet.PortletContext;
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+
+import org.springframework.util.Assert;
+
+/**
+ * Mock implementation of the {@link javax.portlet.PortletConfig} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockPortletConfig implements PortletConfig {
+
+ private final PortletContext portletContext;
+
+ private final String portletName;
+
+ private final Map<Locale, ResourceBundle> resourceBundles = new HashMap<Locale, ResourceBundle>();
+
+ private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
+
+ private final Set<String> publicRenderParameterNames = new LinkedHashSet<String>();
+
+ private String defaultNamespace = XMLConstants.NULL_NS_URI;
+
+ private final Set<QName> publishingEventQNames = new LinkedHashSet<QName>();
+
+ private final Set<QName> processingEventQNames = new LinkedHashSet<QName>();
+
+ private final Set<Locale> supportedLocales = new LinkedHashSet<Locale>();
+
+ private final Map<String, String[]> containerRuntimeOptions = new LinkedHashMap<String, String[]>();
+
+
+ /**
+ * Create a new MockPortletConfig with a default {@link MockPortletContext}.
+ */
+ public MockPortletConfig() {
+ this(null, "");
+ }
+
+ /**
+ * Create a new MockPortletConfig with a default {@link MockPortletContext}.
+ * @param portletName the name of the portlet
+ */
+ public MockPortletConfig(String portletName) {
+ this(null, portletName);
+ }
+
+ /**
+ * Create a new MockPortletConfig.
+ * @param portletContext the PortletContext that the portlet runs in
+ */
+ public MockPortletConfig(PortletContext portletContext) {
+ this(portletContext, "");
+ }
+
+ /**
+ * Create a new MockPortletConfig.
+ * @param portletContext the PortletContext that the portlet runs in
+ * @param portletName the name of the portlet
+ */
+ public MockPortletConfig(PortletContext portletContext, String portletName) {
+ this.portletContext = (portletContext != null ? portletContext : new MockPortletContext());
+ this.portletName = portletName;
+ }
+
+
+ @Override
+ public String getPortletName() {
+ return this.portletName;
+ }
+
+ @Override
+ public PortletContext getPortletContext() {
+ return this.portletContext;
+ }
+
+ public void setResourceBundle(Locale locale, ResourceBundle resourceBundle) {
+ Assert.notNull(locale, "Locale must not be null");
+ this.resourceBundles.put(locale, resourceBundle);
+ }
+
+ @Override
+ public ResourceBundle getResourceBundle(Locale locale) {
+ Assert.notNull(locale, "Locale must not be null");
+ return this.resourceBundles.get(locale);
+ }
+
+ public void addInitParameter(String name, String value) {
+ Assert.notNull(name, "Parameter name must not be null");
+ this.initParameters.put(name, value);
+ }
+
+ @Override
+ public String getInitParameter(String name) {
+ Assert.notNull(name, "Parameter name must not be null");
+ return this.initParameters.get(name);
+ }
+
+ @Override
+ public Enumeration<String> getInitParameterNames() {
+ return Collections.enumeration(this.initParameters.keySet());
+ }
+
+ public void addPublicRenderParameterName(String name) {
+ this.publicRenderParameterNames.add(name);
+ }
+
+ @Override
+ public Enumeration<String> getPublicRenderParameterNames() {
+ return Collections.enumeration(this.publicRenderParameterNames);
+ }
+
+ public void setDefaultNamespace(String defaultNamespace) {
+ this.defaultNamespace = defaultNamespace;
+ }
+
+ @Override
+ public String getDefaultNamespace() {
+ return this.defaultNamespace;
+ }
+
+ public void addPublishingEventQName(QName name) {
+ this.publishingEventQNames.add(name);
+ }
+
+ @Override
+ public Enumeration<QName> getPublishingEventQNames() {
+ return Collections.enumeration(this.publishingEventQNames);
+ }
+
+ public void addProcessingEventQName(QName name) {
+ this.processingEventQNames.add(name);
+ }
+
+ @Override
+ public Enumeration<QName> getProcessingEventQNames() {
+ return Collections.enumeration(this.processingEventQNames);
+ }
+
+ public void addSupportedLocale(Locale locale) {
+ this.supportedLocales.add(locale);
+ }
+
+ @Override
+ public Enumeration<Locale> getSupportedLocales() {
+ return Collections.enumeration(this.supportedLocales);
+ }
+
+ public void addContainerRuntimeOption(String key, String value) {
+ this.containerRuntimeOptions.put(key, new String[] {value});
+ }
+
+ public void addContainerRuntimeOption(String key, String[] values) {
+ this.containerRuntimeOptions.put(key, values);
+ }
+
+ @Override
+ public Map<String, String[]> getContainerRuntimeOptions() {
+ return Collections.unmodifiableMap(this.containerRuntimeOptions);
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletContext.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletContext.java
new file mode 100644
index 0000000..3cf0a5d
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletContext.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletRequestDispatcher;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.util.Assert;
+import org.springframework.web.util.WebUtils;
+
+/**
+ * Mock implementation of the {@link javax.portlet.PortletContext} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockPortletContext implements PortletContext {
+
+ private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
+
+
+ private final Log logger = LogFactory.getLog(getClass());
+
+ private final String resourceBasePath;
+
+ private final ResourceLoader resourceLoader;
+
+ private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
+
+ private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
+
+ private String portletContextName = "MockPortletContext";
+
+ private Set<String> containerRuntimeOptions = new LinkedHashSet<String>();
+
+
+ /**
+ * Create a new MockPortletContext with no base path and a
+ * DefaultResourceLoader (i.e. the classpath root as WAR root).
+ * @see org.springframework.core.io.DefaultResourceLoader
+ */
+ public MockPortletContext() {
+ this("", null);
+ }
+
+ /**
+ * Create a new MockPortletContext using a DefaultResourceLoader.
+ * @param resourceBasePath the WAR root directory (should not end with a slash)
+ * @see org.springframework.core.io.DefaultResourceLoader
+ */
+ public MockPortletContext(String resourceBasePath) {
+ this(resourceBasePath, null);
+ }
+
+ /**
+ * Create a new MockPortletContext, using the specified ResourceLoader
+ * and no base path.
+ * @param resourceLoader the ResourceLoader to use (or null for the default)
+ */
+ public MockPortletContext(ResourceLoader resourceLoader) {
+ this("", resourceLoader);
+ }
+
+ /**
+ * Create a new MockPortletContext.
+ * @param resourceBasePath the WAR root directory (should not end with a slash)
+ * @param resourceLoader the ResourceLoader to use (or null for the default)
+ */
+ public MockPortletContext(String resourceBasePath, ResourceLoader resourceLoader) {
+ this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : "");
+ this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
+
+ // Use JVM temp dir as PortletContext temp dir.
+ String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY);
+ if (tempDir != null) {
+ this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir));
+ }
+ }
+
+ /**
+ * Build a full resource location for the given path,
+ * prepending the resource base path of this MockPortletContext.
+ * @param path the path as specified
+ * @return the full resource path
+ */
+ protected String getResourceLocation(String path) {
+ if (!path.startsWith("/")) {
+ path = "/" + path;
+ }
+ return this.resourceBasePath + path;
+ }
+
+
+ @Override
+ public String getServerInfo() {
+ return "MockPortal/1.0";
+ }
+
+ @Override
+ public PortletRequestDispatcher getRequestDispatcher(String path) {
+ if (!path.startsWith("/")) {
+ throw new IllegalArgumentException(
+ "PortletRequestDispatcher path at PortletContext level must start with '/'");
+ }
+ return new MockPortletRequestDispatcher(path);
+ }
+
+ @Override
+ public PortletRequestDispatcher getNamedDispatcher(String path) {
+ return null;
+ }
+
+ @Override
+ public InputStream getResourceAsStream(String path) {
+ Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
+ try {
+ return resource.getInputStream();
+ }
+ catch (IOException ex) {
+ logger.info("Couldn't open InputStream for " + resource, ex);
+ return null;
+ }
+ }
+
+ @Override
+ public int getMajorVersion() {
+ return 2;
+ }
+
+ @Override
+ public int getMinorVersion() {
+ return 0;
+ }
+
+ @Override
+ public String getMimeType(String filePath) {
+ return null;
+ }
+
+ @Override
+ public String getRealPath(String path) {
+ Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
+ try {
+ return resource.getFile().getAbsolutePath();
+ }
+ catch (IOException ex) {
+ logger.info("Couldn't determine real path of resource " + resource, ex);
+ return null;
+ }
+ }
+
+ @Override
+ public Set<String> getResourcePaths(String path) {
+ Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
+ try {
+ File file = resource.getFile();
+ String[] fileList = file.list();
+ String prefix = (path.endsWith("/") ? path : path + "/");
+ Set<String> resourcePaths = new HashSet<String>(fileList.length);
+ for (String fileEntry : fileList) {
+ resourcePaths.add(prefix + fileEntry);
+ }
+ return resourcePaths;
+ }
+ catch (IOException ex) {
+ logger.info("Couldn't get resource paths for " + resource, ex);
+ return null;
+ }
+ }
+
+ @Override
+ public URL getResource(String path) throws MalformedURLException {
+ Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
+ try {
+ return resource.getURL();
+ }
+ catch (IOException ex) {
+ logger.info("Couldn't get URL for " + resource, ex);
+ return null;
+ }
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return this.attributes.get(name);
+ }
+
+ @Override
+ public Enumeration<String> getAttributeNames() {
+ return Collections.enumeration(this.attributes.keySet());
+ }
+
+ @Override
+ public void setAttribute(String name, Object value) {
+ if (value != null) {
+ this.attributes.put(name, value);
+ }
+ else {
+ this.attributes.remove(name);
+ }
+ }
+
+ @Override
+ public void removeAttribute(String name) {
+ this.attributes.remove(name);
+ }
+
+ public void addInitParameter(String name, String value) {
+ Assert.notNull(name, "Parameter name must not be null");
+ this.initParameters.put(name, value);
+ }
+
+ @Override
+ public String getInitParameter(String name) {
+ Assert.notNull(name, "Parameter name must not be null");
+ return this.initParameters.get(name);
+ }
+
+ @Override
+ public Enumeration<String> getInitParameterNames() {
+ return Collections.enumeration(this.initParameters.keySet());
+ }
+
+ @Override
+ public void log(String message) {
+ logger.info(message);
+ }
+
+ @Override
+ public void log(String message, Throwable t) {
+ logger.info(message, t);
+ }
+
+ public void setPortletContextName(String portletContextName) {
+ this.portletContextName = portletContextName;
+ }
+
+ @Override
+ public String getPortletContextName() {
+ return this.portletContextName;
+ }
+
+ public void addContainerRuntimeOption(String key) {
+ this.containerRuntimeOptions.add(key);
+ }
+
+ @Override
+ public Enumeration<String> getContainerRuntimeOptions() {
+ return Collections.enumeration(this.containerRuntimeOptions);
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletPreferences.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletPreferences.java
new file mode 100644
index 0000000..60ceca2
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletPreferences.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2002-2009 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.portlet.PortletPreferences;
+import javax.portlet.PreferencesValidator;
+import javax.portlet.ReadOnlyException;
+import javax.portlet.ValidatorException;
+
+import org.springframework.util.Assert;
+
+/**
+ * Mock implementation of the {@link javax.portlet.PortletPreferences} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockPortletPreferences implements PortletPreferences {
+
+ private PreferencesValidator preferencesValidator;
+
+ private final Map<String, String[]> preferences = new LinkedHashMap<String, String[]>();
+
+ private final Set<String> readOnly = new HashSet<String>();
+
+
+ public void setReadOnly(String key, boolean readOnly) {
+ Assert.notNull(key, "Key must not be null");
+ if (readOnly) {
+ this.readOnly.add(key);
+ }
+ else {
+ this.readOnly.remove(key);
+ }
+ }
+
+ @Override
+ public boolean isReadOnly(String key) {
+ Assert.notNull(key, "Key must not be null");
+ return this.readOnly.contains(key);
+ }
+
+ @Override
+ public String getValue(String key, String def) {
+ Assert.notNull(key, "Key must not be null");
+ String[] values = this.preferences.get(key);
+ return (values != null && values.length > 0 ? values[0] : def);
+ }
+
+ @Override
+ public String[] getValues(String key, String[] def) {
+ Assert.notNull(key, "Key must not be null");
+ String[] values = this.preferences.get(key);
+ return (values != null && values.length > 0 ? values : def);
+ }
+
+ @Override
+ public void setValue(String key, String value) throws ReadOnlyException {
+ setValues(key, new String[] {value});
+ }
+
+ @Override
+ public void setValues(String key, String[] values) throws ReadOnlyException {
+ Assert.notNull(key, "Key must not be null");
+ if (isReadOnly(key)) {
+ throw new ReadOnlyException("Preference '" + key + "' is read-only");
+ }
+ this.preferences.put(key, values);
+ }
+
+ @Override
+ public Enumeration<String> getNames() {
+ return Collections.enumeration(this.preferences.keySet());
+ }
+
+ @Override
+ public Map<String, String[]> getMap() {
+ return Collections.unmodifiableMap(this.preferences);
+ }
+
+ @Override
+ public void reset(String key) throws ReadOnlyException {
+ Assert.notNull(key, "Key must not be null");
+ if (isReadOnly(key)) {
+ throw new ReadOnlyException("Preference '" + key + "' is read-only");
+ }
+ this.preferences.remove(key);
+ }
+
+ public void setPreferencesValidator(PreferencesValidator preferencesValidator) {
+ this.preferencesValidator = preferencesValidator;
+ }
+
+ @Override
+ public void store() throws IOException, ValidatorException {
+ if (this.preferencesValidator != null) {
+ this.preferencesValidator.validate(this);
+ }
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequest.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequest.java
new file mode 100644
index 0000000..02ac4a3
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequest.java
@@ -0,0 +1,565 @@
+/*
+ * Copyright 2002-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletPreferences;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletSession;
+import javax.portlet.WindowState;
+import javax.servlet.http.Cookie;
+
+import org.springframework.util.Assert;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * Mock implementation of the {@link javax.portlet.PortletRequest} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockPortletRequest implements PortletRequest {
+
+ private boolean active = true;
+
+ private final PortalContext portalContext;
+
+ private final PortletContext portletContext;
+
+ private PortletSession session;
+
+ private WindowState windowState = WindowState.NORMAL;
+
+ private PortletMode portletMode = PortletMode.VIEW;
+
+ private PortletPreferences portletPreferences = new MockPortletPreferences();
+
+ private final Map<String, List<String>> properties = new LinkedHashMap<String, List<String>>();
+
+ private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
+
+ private final Map<String, String[]> parameters = new LinkedHashMap<String, String[]>();
+
+ private String authType = null;
+
+ private String contextPath = "";
+
+ private String remoteUser = null;
+
+ private Principal userPrincipal = null;
+
+ private final Set<String> userRoles = new HashSet<String>();
+
+ private boolean secure = false;
+
+ private boolean requestedSessionIdValid = true;
+
+ private final List<String> responseContentTypes = new LinkedList<String>();
+
+ private final List<Locale> locales = new LinkedList<Locale>();
+
+ private String scheme = "http";
+
+ private String serverName = "localhost";
+
+ private int serverPort = 80;
+
+ private String windowID;
+
+ private Cookie[] cookies;
+
+ private final Set<String> publicParameterNames = new HashSet<String>();
+
+
+ /**
+ * Create a new MockPortletRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @see MockPortalContext
+ * @see MockPortletContext
+ */
+ public MockPortletRequest() {
+ this(null, null);
+ }
+
+ /**
+ * Create a new MockPortletRequest with a default {@link MockPortalContext}.
+ * @param portletContext the PortletContext that the request runs in
+ * @see MockPortalContext
+ */
+ public MockPortletRequest(PortletContext portletContext) {
+ this(null, portletContext);
+ }
+
+ /**
+ * Create a new MockPortletRequest.
+ * @param portalContext the PortalContext that the request runs in
+ * @param portletContext the PortletContext that the request runs in
+ */
+ public MockPortletRequest(PortalContext portalContext, PortletContext portletContext) {
+ this.portalContext = (portalContext != null ? portalContext : new MockPortalContext());
+ this.portletContext = (portletContext != null ? portletContext : new MockPortletContext());
+ this.responseContentTypes.add("text/html");
+ this.locales.add(Locale.ENGLISH);
+ this.attributes.put(LIFECYCLE_PHASE, getLifecyclePhase());
+ }
+
+
+ //---------------------------------------------------------------------
+ // Lifecycle methods
+ //---------------------------------------------------------------------
+
+ /**
+ * Return the Portlet 2.0 lifecycle id for the current phase.
+ */
+ protected String getLifecyclePhase() {
+ return null;
+ }
+
+ /**
+ * Return whether this request is still active (that is, not completed yet).
+ */
+ public boolean isActive() {
+ return this.active;
+ }
+
+ /**
+ * Mark this request as completed.
+ */
+ public void close() {
+ this.active = false;
+ }
+
+ /**
+ * Check whether this request is still active (that is, not completed yet),
+ * throwing an IllegalStateException if not active anymore.
+ */
+ protected void checkActive() throws IllegalStateException {
+ if (!this.active) {
+ throw new IllegalStateException("Request is not active anymore");
+ }
+ }
+
+
+ //---------------------------------------------------------------------
+ // PortletRequest methods
+ //---------------------------------------------------------------------
+
+ @Override
+ public boolean isWindowStateAllowed(WindowState windowState) {
+ return CollectionUtils.contains(this.portalContext.getSupportedWindowStates(), windowState);
+ }
+
+ @Override
+ public boolean isPortletModeAllowed(PortletMode portletMode) {
+ return CollectionUtils.contains(this.portalContext.getSupportedPortletModes(), portletMode);
+ }
+
+ public void setPortletMode(PortletMode portletMode) {
+ Assert.notNull(portletMode, "PortletMode must not be null");
+ this.portletMode = portletMode;
+ }
+
+ @Override
+ public PortletMode getPortletMode() {
+ return this.portletMode;
+ }
+
+ public void setWindowState(WindowState windowState) {
+ Assert.notNull(windowState, "WindowState must not be null");
+ this.windowState = windowState;
+ }
+
+ @Override
+ public WindowState getWindowState() {
+ return this.windowState;
+ }
+
+ public void setPreferences(PortletPreferences preferences) {
+ Assert.notNull(preferences, "PortletPreferences must not be null");
+ this.portletPreferences = preferences;
+ }
+
+ @Override
+ public PortletPreferences getPreferences() {
+ return this.portletPreferences;
+ }
+
+ public void setSession(PortletSession session) {
+ this.session = session;
+ if (session instanceof MockPortletSession) {
+ MockPortletSession mockSession = ((MockPortletSession) session);
+ mockSession.access();
+ }
+ }
+
+ @Override
+ public PortletSession getPortletSession() {
+ return getPortletSession(true);
+ }
+
+ @Override
+ public PortletSession getPortletSession(boolean create) {
+ checkActive();
+ // Reset session if invalidated.
+ if (this.session instanceof MockPortletSession && ((MockPortletSession) this.session).isInvalid()) {
+ this.session = null;
+ }
+ // Create new session if necessary.
+ if (this.session == null && create) {
+ this.session = new MockPortletSession(this.portletContext);
+ }
+ return this.session;
+ }
+
+ /**
+ * Set a single value for the specified property.
+ * <p>If there are already one or more values registered for the given
+ * property key, they will be replaced.
+ */
+ public void setProperty(String key, String value) {
+ Assert.notNull(key, "Property key must not be null");
+ List<String> list = new LinkedList<String>();
+ list.add(value);
+ this.properties.put(key, list);
+ }
+
+ /**
+ * Add a single value for the specified property.
+ * <p>If there are already one or more values registered for the given
+ * property key, the given value will be added to the end of the list.
+ */
+ public void addProperty(String key, String value) {
+ Assert.notNull(key, "Property key must not be null");
+ List<String> oldList = this.properties.get(key);
+ if (oldList != null) {
+ oldList.add(value);
+ }
+ else {
+ List<String> list = new LinkedList<String>();
+ list.add(value);
+ this.properties.put(key, list);
+ }
+ }
+
+ @Override
+ public String getProperty(String key) {
+ Assert.notNull(key, "Property key must not be null");
+ List<String> list = this.properties.get(key);
+ return (list != null && list.size() > 0 ? list.get(0) : null);
+ }
+
+ @Override
+ public Enumeration<String> getProperties(String key) {
+ Assert.notNull(key, "property key must not be null");
+ return Collections.enumeration(this.properties.get(key));
+ }
+
+ @Override
+ public Enumeration<String> getPropertyNames() {
+ return Collections.enumeration(this.properties.keySet());
+ }
+
+ @Override
+ public PortalContext getPortalContext() {
+ return this.portalContext;
+ }
+
+ public void setAuthType(String authType) {
+ this.authType = authType;
+ }
+
+ @Override
+ public String getAuthType() {
+ return this.authType;
+ }
+
+ public void setContextPath(String contextPath) {
+ this.contextPath = contextPath;
+ }
+
+ @Override
+ public String getContextPath() {
+ return this.contextPath;
+ }
+
+ public void setRemoteUser(String remoteUser) {
+ this.remoteUser = remoteUser;
+ }
+
+ @Override
+ public String getRemoteUser() {
+ return this.remoteUser;
+ }
+
+ public void setUserPrincipal(Principal userPrincipal) {
+ this.userPrincipal = userPrincipal;
+ }
+
+ @Override
+ public Principal getUserPrincipal() {
+ return this.userPrincipal;
+ }
+
+ public void addUserRole(String role) {
+ this.userRoles.add(role);
+ }
+
+ @Override
+ public boolean isUserInRole(String role) {
+ return this.userRoles.contains(role);
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ checkActive();
+ return this.attributes.get(name);
+ }
+
+ @Override
+ public Enumeration<String> getAttributeNames() {
+ checkActive();
+ return Collections.enumeration(this.attributes.keySet());
+ }
+
+ public void setParameters(Map<String, String[]> parameters) {
+ Assert.notNull(parameters, "Parameters Map must not be null");
+ this.parameters.clear();
+ this.parameters.putAll(parameters);
+ }
+
+ public void setParameter(String key, String value) {
+ Assert.notNull(key, "Parameter key must be null");
+ Assert.notNull(value, "Parameter value must not be null");
+ this.parameters.put(key, new String[] {value});
+ }
+
+ public void setParameter(String key, String[] values) {
+ Assert.notNull(key, "Parameter key must be null");
+ Assert.notNull(values, "Parameter values must not be null");
+ this.parameters.put(key, values);
+ }
+
+ public void addParameter(String name, String value) {
+ addParameter(name, new String[] {value});
+ }
+
+ public void addParameter(String name, String[] values) {
+ String[] oldArr = this.parameters.get(name);
+ if (oldArr != null) {
+ String[] newArr = new String[oldArr.length + values.length];
+ System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
+ System.arraycopy(values, 0, newArr, oldArr.length, values.length);
+ this.parameters.put(name, newArr);
+ }
+ else {
+ this.parameters.put(name, values);
+ }
+ }
+
+ @Override
+ public String getParameter(String name) {
+ String[] arr = this.parameters.get(name);
+ return (arr != null && arr.length > 0 ? arr[0] : null);
+ }
+
+ @Override
+ public Enumeration<String> getParameterNames() {
+ return Collections.enumeration(this.parameters.keySet());
+ }
+
+ @Override
+ public String[] getParameterValues(String name) {
+ return this.parameters.get(name);
+ }
+
+ @Override
+ public Map<String, String[]> getParameterMap() {
+ return Collections.unmodifiableMap(this.parameters);
+ }
+
+ public void setSecure(boolean secure) {
+ this.secure = secure;
+ }
+
+ @Override
+ public boolean isSecure() {
+ return this.secure;
+ }
+
+ @Override
+ public void setAttribute(String name, Object value) {
+ checkActive();
+ if (value != null) {
+ this.attributes.put(name, value);
+ }
+ else {
+ this.attributes.remove(name);
+ }
+ }
+
+ @Override
+ public void removeAttribute(String name) {
+ checkActive();
+ this.attributes.remove(name);
+ }
+
+ @Override
+ public String getRequestedSessionId() {
+ PortletSession session = this.getPortletSession();
+ return (session != null ? session.getId() : null);
+ }
+
+ public void setRequestedSessionIdValid(boolean requestedSessionIdValid) {
+ this.requestedSessionIdValid = requestedSessionIdValid;
+ }
+
+ @Override
+ public boolean isRequestedSessionIdValid() {
+ return this.requestedSessionIdValid;
+ }
+
+ public void addResponseContentType(String responseContentType) {
+ this.responseContentTypes.add(responseContentType);
+ }
+
+ public void addPreferredResponseContentType(String responseContentType) {
+ this.responseContentTypes.add(0, responseContentType);
+ }
+
+ @Override
+ public String getResponseContentType() {
+ return this.responseContentTypes.get(0);
+ }
+
+ @Override
+ public Enumeration<String> getResponseContentTypes() {
+ return Collections.enumeration(this.responseContentTypes);
+ }
+
+ public void addLocale(Locale locale) {
+ this.locales.add(locale);
+ }
+
+ public void addPreferredLocale(Locale locale) {
+ this.locales.add(0, locale);
+ }
+
+ @Override
+ public Locale getLocale() {
+ return this.locales.get(0);
+ }
+
+ @Override
+ public Enumeration<Locale> getLocales() {
+ return Collections.enumeration(this.locales);
+ }
+
+ public void setScheme(String scheme) {
+ this.scheme = scheme;
+ }
+
+ @Override
+ public String getScheme() {
+ return this.scheme;
+ }
+
+ public void setServerName(String serverName) {
+ this.serverName = serverName;
+ }
+
+ @Override
+ public String getServerName() {
+ return this.serverName;
+ }
+
+ public void setServerPort(int serverPort) {
+ this.serverPort = serverPort;
+ }
+
+ @Override
+ public int getServerPort() {
+ return this.serverPort;
+ }
+
+ public void setWindowID(String windowID) {
+ this.windowID = windowID;
+ }
+
+ @Override
+ public String getWindowID() {
+ return this.windowID;
+ }
+
+ public void setCookies(Cookie... cookies) {
+ this.cookies = cookies;
+ }
+
+ @Override
+ public Cookie[] getCookies() {
+ return this.cookies;
+ }
+
+ @Override
+ public Map<String, String[]> getPrivateParameterMap() {
+ if (!this.publicParameterNames.isEmpty()) {
+ Map<String, String[]> filtered = new LinkedHashMap<String, String[]>();
+ for (String key : this.parameters.keySet()) {
+ if (!this.publicParameterNames.contains(key)) {
+ filtered.put(key, this.parameters.get(key));
+ }
+ }
+ return filtered;
+ }
+ else {
+ return Collections.unmodifiableMap(this.parameters);
+ }
+ }
+
+ @Override
+ public Map<String, String[]> getPublicParameterMap() {
+ if (!this.publicParameterNames.isEmpty()) {
+ Map<String, String[]> filtered = new LinkedHashMap<String, String[]>();
+ for (String key : this.parameters.keySet()) {
+ if (this.publicParameterNames.contains(key)) {
+ filtered.put(key, this.parameters.get(key));
+ }
+ }
+ return filtered;
+ }
+ else {
+ return Collections.emptyMap();
+ }
+ }
+
+ public void registerPublicParameter(String name) {
+ this.publicParameterNames.add(name);
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequestDispatcher.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequestDispatcher.java
new file mode 100644
index 0000000..e80f774
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletRequestDispatcher.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.io.IOException;
+import javax.portlet.PortletException;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletRequestDispatcher;
+import javax.portlet.PortletResponse;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.springframework.util.Assert;
+
+/**
+ * Mock implementation of the {@link javax.portlet.PortletRequestDispatcher} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockPortletRequestDispatcher implements PortletRequestDispatcher {
+
+ private final Log logger = LogFactory.getLog(getClass());
+
+ private final String url;
+
+
+ /**
+ * Create a new MockPortletRequestDispatcher for the given URL.
+ * @param url the URL to dispatch to.
+ */
+ public MockPortletRequestDispatcher(String url) {
+ Assert.notNull(url, "URL must not be null");
+ this.url = url;
+ }
+
+
+ @Override
+ public void include(RenderRequest request, RenderResponse response) throws PortletException, IOException {
+ include((PortletRequest) request, (PortletResponse) response);
+ }
+
+ @Override
+ public void include(PortletRequest request, PortletResponse response) throws PortletException, IOException {
+ Assert.notNull(request, "Request must not be null");
+ Assert.notNull(response, "Response must not be null");
+ if (!(response instanceof MockMimeResponse)) {
+ throw new IllegalArgumentException("MockPortletRequestDispatcher requires MockMimeResponse");
+ }
+ ((MockMimeResponse) response).setIncludedUrl(this.url);
+ if (logger.isDebugEnabled()) {
+ logger.debug("MockPortletRequestDispatcher: including URL [" + this.url + "]");
+ }
+ }
+
+ @Override
+ public void forward(PortletRequest request, PortletResponse response) throws PortletException, IOException {
+ Assert.notNull(request, "Request must not be null");
+ Assert.notNull(response, "Response must not be null");
+ if (!(response instanceof MockMimeResponse)) {
+ throw new IllegalArgumentException("MockPortletRequestDispatcher requires MockMimeResponse");
+ }
+ ((MockMimeResponse) response).setForwardedUrl(this.url);
+ if (logger.isDebugEnabled()) {
+ logger.debug("MockPortletRequestDispatcher: forwarding to URL [" + this.url + "]");
+ }
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletResponse.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletResponse.java
new file mode 100644
index 0000000..1e69a53
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletResponse.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletResponse;
+import javax.servlet.http.Cookie;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.springframework.util.Assert;
+
+/**
+ * Mock implementation of the {@link javax.portlet.PortletResponse} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockPortletResponse implements PortletResponse {
+
+ private final PortalContext portalContext;
+
+ private final Map<String, String[]> properties = new LinkedHashMap<String, String[]>();
+
+ private String namespace = "";
+
+ private final Set<Cookie> cookies = new LinkedHashSet<Cookie>();
+
+ private final Map<String, Element[]> xmlProperties = new LinkedHashMap<String, Element[]>();
+
+ private Document xmlDocument;
+
+
+ /**
+ * Create a new MockPortletResponse with a default {@link MockPortalContext}.
+ * @see MockPortalContext
+ */
+ public MockPortletResponse() {
+ this(null);
+ }
+
+ /**
+ * Create a new MockPortletResponse.
+ * @param portalContext the PortalContext defining the supported
+ * PortletModes and WindowStates
+ */
+ public MockPortletResponse(PortalContext portalContext) {
+ this.portalContext = (portalContext != null ? portalContext : new MockPortalContext());
+ }
+
+ /**
+ * Return the PortalContext that this MockPortletResponse runs in,
+ * defining the supported PortletModes and WindowStates.
+ */
+ public PortalContext getPortalContext() {
+ return this.portalContext;
+ }
+
+
+ //---------------------------------------------------------------------
+ // PortletResponse methods
+ //---------------------------------------------------------------------
+
+ @Override
+ public void addProperty(String key, String value) {
+ Assert.notNull(key, "Property key must not be null");
+ String[] oldArr = this.properties.get(key);
+ if (oldArr != null) {
+ String[] newArr = new String[oldArr.length + 1];
+ System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
+ newArr[oldArr.length] = value;
+ this.properties.put(key, newArr);
+ }
+ else {
+ this.properties.put(key, new String[] {value});
+ }
+ }
+
+ @Override
+ public void setProperty(String key, String value) {
+ Assert.notNull(key, "Property key must not be null");
+ this.properties.put(key, new String[] {value});
+ }
+
+ public Set<String> getPropertyNames() {
+ return Collections.unmodifiableSet(this.properties.keySet());
+ }
+
+ public String getProperty(String key) {
+ Assert.notNull(key, "Property key must not be null");
+ String[] arr = this.properties.get(key);
+ return (arr != null && arr.length > 0 ? arr[0] : null);
+ }
+
+ public String[] getProperties(String key) {
+ Assert.notNull(key, "Property key must not be null");
+ return this.properties.get(key);
+ }
+
+ @Override
+ public String encodeURL(String path) {
+ return path;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ @Override
+ public String getNamespace() {
+ return this.namespace;
+ }
+
+ @Override
+ public void addProperty(Cookie cookie) {
+ Assert.notNull(cookie, "Cookie must not be null");
+ this.cookies.add(cookie);
+ }
+
+ public Cookie[] getCookies() {
+ return this.cookies.toArray(new Cookie[this.cookies.size()]);
+ }
+
+ public Cookie getCookie(String name) {
+ Assert.notNull(name, "Cookie name must not be null");
+ for (Cookie cookie : this.cookies) {
+ if (name.equals(cookie.getName())) {
+ return cookie;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void addProperty(String key, Element value) {
+ Assert.notNull(key, "Property key must not be null");
+ Element[] oldArr = this.xmlProperties.get(key);
+ if (oldArr != null) {
+ Element[] newArr = new Element[oldArr.length + 1];
+ System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
+ newArr[oldArr.length] = value;
+ this.xmlProperties.put(key, newArr);
+ }
+ else {
+ this.xmlProperties.put(key, new Element[] {value});
+ }
+ }
+
+
+ public Set<String> getXmlPropertyNames() {
+ return Collections.unmodifiableSet(this.xmlProperties.keySet());
+ }
+
+ public Element getXmlProperty(String key) {
+ Assert.notNull(key, "Property key must not be null");
+ Element[] arr = this.xmlProperties.get(key);
+ return (arr != null && arr.length > 0 ? arr[0] : null);
+ }
+
+ public Element[] getXmlProperties(String key) {
+ Assert.notNull(key, "Property key must not be null");
+ return this.xmlProperties.get(key);
+ }
+
+ @Override
+ public Element createElement(String tagName) throws DOMException {
+ if (this.xmlDocument == null) {
+ try {
+ this.xmlDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
+ }
+ catch (ParserConfigurationException ex) {
+ throw new DOMException(DOMException.INVALID_STATE_ERR, ex.toString());
+ }
+ }
+ return this.xmlDocument.createElement(tagName);
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletSession.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletSession.java
new file mode 100644
index 0000000..ca1a44a
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletSession.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletSession;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
+
+import org.springframework.mock.web.MockHttpSession;
+
+/**
+ * Mock implementation of the {@link javax.portlet.PortletSession} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockPortletSession implements PortletSession {
+
+ private static int nextId = 1;
+
+
+ private final String id = Integer.toString(nextId++);
+
+ private final long creationTime = System.currentTimeMillis();
+
+ private int maxInactiveInterval;
+
+ private long lastAccessedTime = System.currentTimeMillis();
+
+ private final PortletContext portletContext;
+
+ private final Map<String, Object> portletAttributes = new HashMap<String, Object>();
+
+ private final Map<String, Object> applicationAttributes = new HashMap<String, Object>();
+
+ private boolean invalid = false;
+
+ private boolean isNew = true;
+
+
+ /**
+ * Create a new MockPortletSession with a default {@link MockPortletContext}.
+ * @see MockPortletContext
+ */
+ public MockPortletSession() {
+ this(null);
+ }
+
+ /**
+ * Create a new MockPortletSession.
+ * @param portletContext the PortletContext that the session runs in
+ */
+ public MockPortletSession(PortletContext portletContext) {
+ this.portletContext = (portletContext != null ? portletContext : new MockPortletContext());
+ }
+
+
+ @Override
+ public Object getAttribute(String name) {
+ return this.portletAttributes.get(name);
+ }
+
+ @Override
+ public Object getAttribute(String name, int scope) {
+ if (scope == PortletSession.PORTLET_SCOPE) {
+ return this.portletAttributes.get(name);
+ }
+ else if (scope == PortletSession.APPLICATION_SCOPE) {
+ return this.applicationAttributes.get(name);
+ }
+ return null;
+ }
+
+ @Override
+ public Enumeration<String> getAttributeNames() {
+ return Collections.enumeration(this.portletAttributes.keySet());
+ }
+
+ @Override
+ public Enumeration<String> getAttributeNames(int scope) {
+ if (scope == PortletSession.PORTLET_SCOPE) {
+ return Collections.enumeration(this.portletAttributes.keySet());
+ }
+ else if (scope == PortletSession.APPLICATION_SCOPE) {
+ return Collections.enumeration(this.applicationAttributes.keySet());
+ }
+ return null;
+ }
+
+ @Override
+ public long getCreationTime() {
+ return this.creationTime;
+ }
+
+ @Override
+ public String getId() {
+ return this.id;
+ }
+
+ public void access() {
+ this.lastAccessedTime = System.currentTimeMillis();
+ setNew(false);
+ }
+
+ @Override
+ public long getLastAccessedTime() {
+ return this.lastAccessedTime;
+ }
+
+ @Override
+ public int getMaxInactiveInterval() {
+ return this.maxInactiveInterval;
+ }
+
+ /**
+ * Clear all of this session's attributes.
+ */
+ public void clearAttributes() {
+ doClearAttributes(this.portletAttributes);
+ doClearAttributes(this.applicationAttributes);
+ }
+
+ protected void doClearAttributes(Map<String, Object> attributes) {
+ for (Iterator<Map.Entry<String, Object>> it = attributes.entrySet().iterator(); it.hasNext();) {
+ Map.Entry<String, Object> entry = it.next();
+ String name = entry.getKey();
+ Object value = entry.getValue();
+ it.remove();
+ if (value instanceof HttpSessionBindingListener) {
+ ((HttpSessionBindingListener) value).valueUnbound(
+ new HttpSessionBindingEvent(new MockHttpSession(), name, value));
+ }
+ }
+ }
+
+ @Override
+ public void invalidate() {
+ this.invalid = true;
+ clearAttributes();
+ }
+
+ public boolean isInvalid() {
+ return this.invalid;
+ }
+
+ public void setNew(boolean value) {
+ this.isNew = value;
+ }
+
+ @Override
+ public boolean isNew() {
+ return this.isNew;
+ }
+
+ @Override
+ public void removeAttribute(String name) {
+ this.portletAttributes.remove(name);
+ }
+
+ @Override
+ public void removeAttribute(String name, int scope) {
+ if (scope == PortletSession.PORTLET_SCOPE) {
+ this.portletAttributes.remove(name);
+ }
+ else if (scope == PortletSession.APPLICATION_SCOPE) {
+ this.applicationAttributes.remove(name);
+ }
+ }
+
+ @Override
+ public void setAttribute(String name, Object value) {
+ if (value != null) {
+ this.portletAttributes.put(name, value);
+ }
+ else {
+ this.portletAttributes.remove(name);
+ }
+ }
+
+ @Override
+ public void setAttribute(String name, Object value, int scope) {
+ if (scope == PortletSession.PORTLET_SCOPE) {
+ if (value != null) {
+ this.portletAttributes.put(name, value);
+ }
+ else {
+ this.portletAttributes.remove(name);
+ }
+ }
+ else if (scope == PortletSession.APPLICATION_SCOPE) {
+ if (value != null) {
+ this.applicationAttributes.put(name, value);
+ }
+ else {
+ this.applicationAttributes.remove(name);
+ }
+ }
+ }
+
+ @Override
+ public void setMaxInactiveInterval(int interval) {
+ this.maxInactiveInterval = interval;
+ }
+
+ @Override
+ public PortletContext getPortletContext() {
+ return this.portletContext;
+ }
+
+ @Override
+ public Map<String, Object> getAttributeMap() {
+ return Collections.unmodifiableMap(this.portletAttributes);
+ }
+
+ @Override
+ public Map<String, Object> getAttributeMap(int scope) {
+ if (scope == PortletSession.PORTLET_SCOPE) {
+ return Collections.unmodifiableMap(this.portletAttributes);
+ }
+ else if (scope == PortletSession.APPLICATION_SCOPE) {
+ return Collections.unmodifiableMap(this.applicationAttributes);
+ }
+ else {
+ return Collections.emptyMap();
+ }
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletURL.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletURL.java
new file mode 100644
index 0000000..503807e
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockPortletURL.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.util.Map;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletModeException;
+import javax.portlet.PortletURL;
+import javax.portlet.WindowState;
+import javax.portlet.WindowStateException;
+
+import org.springframework.util.Assert;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * Mock implementation of the {@link javax.portlet.PortletURL} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockPortletURL extends MockBaseURL implements PortletURL {
+
+ public static final String URL_TYPE_RENDER = "render";
+
+ public static final String URL_TYPE_ACTION = "action";
+
+
+ private final PortalContext portalContext;
+
+ private final String urlType;
+
+ private WindowState windowState;
+
+ private PortletMode portletMode;
+
+
+ /**
+ * Create a new MockPortletURL for the given URL type.
+ * @param portalContext the PortalContext defining the supported
+ * PortletModes and WindowStates
+ * @param urlType the URL type, for example "render" or "action"
+ * @see #URL_TYPE_RENDER
+ * @see #URL_TYPE_ACTION
+ */
+ public MockPortletURL(PortalContext portalContext, String urlType) {
+ Assert.notNull(portalContext, "PortalContext is required");
+ this.portalContext = portalContext;
+ this.urlType = urlType;
+ }
+
+
+ //---------------------------------------------------------------------
+ // PortletURL methods
+ //---------------------------------------------------------------------
+
+ @Override
+ public void setWindowState(WindowState windowState) throws WindowStateException {
+ if (!CollectionUtils.contains(this.portalContext.getSupportedWindowStates(), windowState)) {
+ throw new WindowStateException("WindowState not supported", windowState);
+ }
+ this.windowState = windowState;
+ }
+
+ @Override
+ public WindowState getWindowState() {
+ return this.windowState;
+ }
+
+ @Override
+ public void setPortletMode(PortletMode portletMode) throws PortletModeException {
+ if (!CollectionUtils.contains(this.portalContext.getSupportedPortletModes(), portletMode)) {
+ throw new PortletModeException("PortletMode not supported", portletMode);
+ }
+ this.portletMode = portletMode;
+ }
+
+ @Override
+ public PortletMode getPortletMode() {
+ return this.portletMode;
+ }
+
+ @Override
+ public void removePublicRenderParameter(String name) {
+ this.parameters.remove(name);
+ }
+
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(encodeParameter("urlType", this.urlType));
+ if (this.windowState != null) {
+ sb.append(";").append(encodeParameter("windowState", this.windowState.toString()));
+ }
+ if (this.portletMode != null) {
+ sb.append(";").append(encodeParameter("portletMode", this.portletMode.toString()));
+ }
+ for (Map.Entry<String, String[]> entry : this.parameters.entrySet()) {
+ sb.append(";").append(encodeParameter("param_" + entry.getKey(), entry.getValue()));
+ }
+ return (isSecure() ? "https:" : "http:") +
+ "//localhost/mockportlet?" + sb.toString();
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderRequest.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderRequest.java
new file mode 100644
index 0000000..fe5c11a
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderRequest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import javax.portlet.PortalContext;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletMode;
+import javax.portlet.RenderRequest;
+import javax.portlet.WindowState;
+
+/**
+ * Mock implementation of the {@link javax.portlet.RenderRequest} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockRenderRequest extends MockPortletRequest implements RenderRequest {
+
+ /**
+ * Create a new MockRenderRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @see MockPortalContext
+ * @see MockPortletContext
+ */
+ public MockRenderRequest() {
+ super();
+ }
+
+ /**
+ * Create a new MockRenderRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @param portletMode the mode that the portlet runs in
+ */
+ public MockRenderRequest(PortletMode portletMode) {
+ super();
+ setPortletMode(portletMode);
+ }
+
+ /**
+ * Create a new MockRenderRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @param portletMode the mode that the portlet runs in
+ * @param windowState the window state to run the portlet in
+ */
+ public MockRenderRequest(PortletMode portletMode, WindowState windowState) {
+ super();
+ setPortletMode(portletMode);
+ setWindowState(windowState);
+ }
+
+ /**
+ * Create a new MockRenderRequest with a default {@link MockPortalContext}.
+ * @param portletContext the PortletContext that the request runs in
+ */
+ public MockRenderRequest(PortletContext portletContext) {
+ super(portletContext);
+ }
+
+ /**
+ * Create a new MockRenderRequest.
+ * @param portalContext the PortletContext that the request runs in
+ * @param portletContext the PortletContext that the request runs in
+ */
+ public MockRenderRequest(PortalContext portalContext, PortletContext portletContext) {
+ super(portalContext, portletContext);
+ }
+
+
+ @Override
+ protected String getLifecyclePhase() {
+ return RENDER_PHASE;
+ }
+
+ @Override
+ public String getETag() {
+ return getProperty(RenderRequest.ETAG);
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderResponse.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderResponse.java
new file mode 100644
index 0000000..defa5e9
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockRenderResponse.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.util.Collection;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletMode;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+/**
+ * Mock implementation of the {@link javax.portlet.RenderResponse} interface.
+ *
+ * @author John A. Lewis
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+public class MockRenderResponse extends MockMimeResponse implements RenderResponse {
+
+ private String title;
+
+ private Collection<PortletMode> nextPossiblePortletModes;
+
+
+ /**
+ * Create a new MockRenderResponse with a default {@link MockPortalContext}.
+ * @see MockPortalContext
+ */
+ public MockRenderResponse() {
+ super();
+ }
+
+ /**
+ * Create a new MockRenderResponse.
+ * @param portalContext the PortalContext defining the supported
+ * PortletModes and WindowStates
+ */
+ public MockRenderResponse(PortalContext portalContext) {
+ super(portalContext);
+ }
+
+ /**
+ * Create a new MockRenderResponse.
+ * @param portalContext the PortalContext defining the supported
+ * PortletModes and WindowStates
+ * @param request the corresponding render request that this response
+ * is generated for
+ */
+ public MockRenderResponse(PortalContext portalContext, RenderRequest request) {
+ super(portalContext, request);
+ }
+
+
+ //---------------------------------------------------------------------
+ // RenderResponse methods
+ //---------------------------------------------------------------------
+
+ @Override
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getTitle() {
+ return this.title;
+ }
+
+ @Override
+ public void setNextPossiblePortletModes(Collection<PortletMode> portletModes) {
+ this.nextPossiblePortletModes = portletModes;
+ }
+
+ public Collection<PortletMode> getNextPossiblePortletModes() {
+ return this.nextPossiblePortletModes;
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceRequest.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceRequest.java
new file mode 100644
index 0000000..4212170
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceRequest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletContext;
+import javax.portlet.RenderRequest;
+import javax.portlet.ResourceRequest;
+
+/**
+ * Mock implementation of the {@link javax.portlet.ResourceRequest} interface.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ */
+public class MockResourceRequest extends MockClientDataRequest implements ResourceRequest {
+
+ private String resourceID;
+
+ private String cacheability;
+
+ private final Map<String, String[]> privateRenderParameterMap = new LinkedHashMap<String, String[]>();
+
+
+ /**
+ * Create a new MockResourceRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @see org.springframework.mock.web.portlet.MockPortalContext
+ * @see org.springframework.mock.web.portlet.MockPortletContext
+ */
+ public MockResourceRequest() {
+ super();
+ }
+
+ /**
+ * Create a new MockResourceRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @param resourceID the resource id for this request
+ */
+ public MockResourceRequest(String resourceID) {
+ super();
+ this.resourceID = resourceID;
+ }
+
+ /**
+ * Create a new MockResourceRequest with a default {@link MockPortalContext}
+ * and a default {@link MockPortletContext}.
+ * @param url the resource URL for this request
+ */
+ public MockResourceRequest(MockResourceURL url) {
+ super();
+ this.resourceID = url.getResourceID();
+ this.cacheability = url.getCacheability();
+ }
+
+ /**
+ * Create a new MockResourceRequest with a default {@link MockPortalContext}.
+ * @param portletContext the PortletContext that the request runs in
+ */
+ public MockResourceRequest(PortletContext portletContext) {
+ super(portletContext);
+ }
+
+ /**
+ * Create a new MockResourceRequest.
+ * @param portalContext the PortalContext that the request runs in
+ * @param portletContext the PortletContext that the request runs in
+ */
+ public MockResourceRequest(PortalContext portalContext, PortletContext portletContext) {
+ super(portalContext, portletContext);
+ }
+
+
+ @Override
+ protected String getLifecyclePhase() {
+ return RESOURCE_PHASE;
+ }
+
+ public void setResourceID(String resourceID) {
+ this.resourceID = resourceID;
+ }
+
+ @Override
+ public String getResourceID() {
+ return this.resourceID;
+ }
+
+ public void setCacheability(String cacheLevel) {
+ this.cacheability = cacheLevel;
+ }
+
+ @Override
+ public String getCacheability() {
+ return this.cacheability;
+ }
+
+ @Override
+ public String getETag() {
+ return getProperty(RenderRequest.ETAG);
+ }
+
+ public void addPrivateRenderParameter(String key, String value) {
+ this.privateRenderParameterMap.put(key, new String[] {value});
+ }
+
+ public void addPrivateRenderParameter(String key, String[] values) {
+ this.privateRenderParameterMap.put(key, values);
+ }
+
+ @Override
+ public Map<String, String[]> getPrivateRenderParameterMap() {
+ return Collections.unmodifiableMap(this.privateRenderParameterMap);
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceResponse.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceResponse.java
new file mode 100644
index 0000000..06bba7a
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceResponse.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import javax.portlet.ResourceResponse;
+
+/**
+ * Mock implementation of the {@link javax.portlet.ResourceResponse} interface.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ */
+public class MockResourceResponse extends MockMimeResponse implements ResourceResponse {
+
+ private int contentLength = 0;
+
+
+ @Override
+ public void setContentLength(int len) {
+ this.contentLength = len;
+ }
+
+ public int getContentLength() {
+ return this.contentLength;
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceURL.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceURL.java
new file mode 100644
index 0000000..e38e089
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockResourceURL.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.util.Map;
+import javax.portlet.ResourceURL;
+
+/**
+ * Mock implementation of the {@link javax.portlet.ResourceURL} interface.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ */
+public class MockResourceURL extends MockBaseURL implements ResourceURL {
+
+ private String resourceID;
+
+ private String cacheability;
+
+
+ //---------------------------------------------------------------------
+ // ResourceURL methods
+ //---------------------------------------------------------------------
+
+ @Override
+ public void setResourceID(String resourceID) {
+ this.resourceID = resourceID;
+ }
+
+ public String getResourceID() {
+ return this.resourceID;
+ }
+
+ @Override
+ public void setCacheability(String cacheLevel) {
+ this.cacheability = cacheLevel;
+ }
+
+ @Override
+ public String getCacheability() {
+ return this.cacheability;
+ }
+
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(encodeParameter("resourceID", this.resourceID));
+ if (this.cacheability != null) {
+ sb.append(";").append(encodeParameter("cacheability", this.cacheability));
+ }
+ for (Map.Entry<String, String[]> entry : this.parameters.entrySet()) {
+ sb.append(";").append(encodeParameter("param_" + entry.getKey(), entry.getValue()));
+ }
+ return (isSecure() ? "https:" : "http:") +
+ "//localhost/mockportlet?" + sb.toString();
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockStateAwareResponse.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockStateAwareResponse.java
new file mode 100644
index 0000000..bb085ba
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/MockStateAwareResponse.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2002-2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.portlet.PortalContext;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletModeException;
+import javax.portlet.StateAwareResponse;
+import javax.portlet.WindowState;
+import javax.portlet.WindowStateException;
+import javax.xml.namespace.QName;
+
+import org.springframework.util.Assert;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * Mock implementation of the {@link javax.portlet.StateAwareResponse} interface.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ */
+public class MockStateAwareResponse extends MockPortletResponse implements StateAwareResponse {
+
+ private WindowState windowState;
+
+ private PortletMode portletMode;
+
+ private final Map<String, String[]> renderParameters = new LinkedHashMap<String, String[]>();
+
+ private final Map<QName, Serializable> events = new HashMap<QName, Serializable>();
+
+
+ /**
+ * Create a new MockActionResponse with a default {@link MockPortalContext}.
+ * @see org.springframework.mock.web.portlet.MockPortalContext
+ */
+ public MockStateAwareResponse() {
+ super();
+ }
+
+ /**
+ * Create a new MockActionResponse.
+ * @param portalContext the PortalContext defining the supported
+ * PortletModes and WindowStates
+ */
+ public MockStateAwareResponse(PortalContext portalContext) {
+ super(portalContext);
+ }
+
+
+ @Override
+ public void setWindowState(WindowState windowState) throws WindowStateException {
+ if (!CollectionUtils.contains(getPortalContext().getSupportedWindowStates(), windowState)) {
+ throw new WindowStateException("WindowState not supported", windowState);
+ }
+ this.windowState = windowState;
+ }
+
+ @Override
+ public WindowState getWindowState() {
+ return this.windowState;
+ }
+
+ @Override
+ public void setPortletMode(PortletMode portletMode) throws PortletModeException {
+ if (!CollectionUtils.contains(getPortalContext().getSupportedPortletModes(), portletMode)) {
+ throw new PortletModeException("PortletMode not supported", portletMode);
+ }
+ this.portletMode = portletMode;
+ }
+
+ @Override
+ public PortletMode getPortletMode() {
+ return this.portletMode;
+ }
+
+ @Override
+ public void setRenderParameters(Map<String, String[]> parameters) {
+ Assert.notNull(parameters, "Parameters Map must not be null");
+ this.renderParameters.clear();
+ this.renderParameters.putAll(parameters);
+ }
+
+ @Override
+ public void setRenderParameter(String key, String value) {
+ Assert.notNull(key, "Parameter key must not be null");
+ Assert.notNull(value, "Parameter value must not be null");
+ this.renderParameters.put(key, new String[] {value});
+ }
+
+ @Override
+ public void setRenderParameter(String key, String[] values) {
+ Assert.notNull(key, "Parameter key must not be null");
+ Assert.notNull(values, "Parameter values must not be null");
+ this.renderParameters.put(key, values);
+ }
+
+ public String getRenderParameter(String key) {
+ Assert.notNull(key, "Parameter key must not be null");
+ String[] arr = this.renderParameters.get(key);
+ return (arr != null && arr.length > 0 ? arr[0] : null);
+ }
+
+ public String[] getRenderParameterValues(String key) {
+ Assert.notNull(key, "Parameter key must not be null");
+ return this.renderParameters.get(key);
+ }
+
+ public Iterator<String> getRenderParameterNames() {
+ return this.renderParameters.keySet().iterator();
+ }
+
+ @Override
+ public Map<String, String[]> getRenderParameterMap() {
+ return Collections.unmodifiableMap(this.renderParameters);
+ }
+
+ @Override
+ public void removePublicRenderParameter(String name) {
+ this.renderParameters.remove(name);
+ }
+
+ @Override
+ public void setEvent(QName name, Serializable value) {
+ this.events.put(name, value);
+ }
+
+ @Override
+ public void setEvent(String name, Serializable value) {
+ this.events.put(new QName(name), value);
+ }
+
+ public Iterator<QName> getEventNames() {
+ return this.events.keySet().iterator();
+ }
+
+ public Serializable getEvent(QName name) {
+ return this.events.get(name);
+ }
+
+ public Serializable getEvent(String name) {
+ return this.events.get(new QName(name));
+ }
+
+}
\ No newline at end of file
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/ServletWrappingPortletContext.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/ServletWrappingPortletContext.java
new file mode 100644
index 0000000..70f8b86
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/ServletWrappingPortletContext.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2002-2016 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Set;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletRequestDispatcher;
+import javax.servlet.ServletContext;
+
+import org.springframework.util.Assert;
+
+/**
+ * Mock implementation of the {@link javax.portlet.PortletContext} interface,
+ * wrapping an underlying {@link javax.servlet.ServletContext}.
+ *
+ * @author Juergen Hoeller
+ * @since 3.0
+ * @see MockPortletContext
+ */
+public class ServletWrappingPortletContext implements PortletContext {
+
+ private final ServletContext servletContext;
+
+
+ /**
+ * Create a new PortletContext wrapping the given ServletContext.
+ * @param servletContext the ServletContext to wrap
+ */
+ public ServletWrappingPortletContext(ServletContext servletContext) {
+ Assert.notNull(servletContext, "ServletContext must not be null");
+ this.servletContext = servletContext;
+ }
+
+ /**
+ * Return the underlying ServletContext that this PortletContext wraps.
+ */
+ public final ServletContext getServletContext() {
+ return this.servletContext;
+ }
+
+
+ @Override
+ public String getServerInfo() {
+ return this.servletContext.getServerInfo();
+ }
+
+ @Override
+ public PortletRequestDispatcher getRequestDispatcher(String path) {
+ return null;
+ }
+
+ @Override
+ public PortletRequestDispatcher getNamedDispatcher(String name) {
+ return null;
+ }
+
+ @Override
+ public InputStream getResourceAsStream(String path) {
+ return this.servletContext.getResourceAsStream(path);
+ }
+
+ @Override
+ public int getMajorVersion() {
+ return 2;
+ }
+
+ @Override
+ public int getMinorVersion() {
+ return 0;
+ }
+
+ @Override
+ public String getMimeType(String file) {
+ return this.servletContext.getMimeType(file);
+ }
+
+ @Override
+ public String getRealPath(String path) {
+ return this.servletContext.getRealPath(path);
+ }
+
+ @Override
+ public Set<String> getResourcePaths(String path) {
+ return this.servletContext.getResourcePaths(path);
+ }
+
+ @Override
+ public URL getResource(String path) throws MalformedURLException {
+ return this.servletContext.getResource(path);
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return this.servletContext.getAttribute(name);
+ }
+
+ @Override
+ public Enumeration<String> getAttributeNames() {
+ return this.servletContext.getAttributeNames();
+ }
+
+ @Override
+ public String getInitParameter(String name) {
+ return this.servletContext.getInitParameter(name);
+ }
+
+ @Override
+ public Enumeration<String> getInitParameterNames() {
+ return this.servletContext.getInitParameterNames();
+ }
+
+ @Override
+ public void log(String msg) {
+ this.servletContext.log(msg);
+ }
+
+ @Override
+ public void log(String message, Throwable throwable) {
+ this.servletContext.log(message, throwable);
+ }
+
+ @Override
+ public void removeAttribute(String name) {
+ this.servletContext.removeAttribute(name);
+ }
+
+ @Override
+ public void setAttribute(String name, Object object) {
+ this.servletContext.setAttribute(name, object);
+ }
+
+ @Override
+ public String getPortletContextName() {
+ return this.servletContext.getServletContextName();
+ }
+
+ @Override
+ public Enumeration<String> getContainerRuntimeOptions() {
+ return Collections.enumeration(Collections.<String>emptySet());
+ }
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/multipart/MultipartActionRequest.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/multipart/MultipartActionRequest.java
new file mode 100644
index 0000000..6df611f
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/multipart/MultipartActionRequest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2002-2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.mock.web.portlet.multipart;
+
+import javax.portlet.ActionRequest;
+
+import org.springframework.web.multipart.MultipartRequest;
+
+/**
+ * Interface which provides additional methods for dealing with multipart
+ * content within a portlet request, allowing to access uploaded files.
+ * Implementations also need to override the standard ActionRequest
+ * methods for parameter access, making multipart parameters available.
+ *
+ * <p>A concrete implementation is {@link DefaultMultipartActionRequest}.
+ *
+ * @author Juergen Hoeller
+ * @since 2.0
+ * @see PortletMultipartResolver
+ * @see org.springframework.web.multipart.MultipartFile
+ * @see javax.portlet.ActionRequest#getParameter
+ * @see javax.portlet.ActionRequest#getParameterNames
+ * @see javax.portlet.ActionRequest#getParameterMap
+ */
+public interface MultipartActionRequest extends ActionRequest, MultipartRequest {
+
+}
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/multipart/package-info.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/multipart/package-info.java
new file mode 100644
index 0000000..0ed9b60
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/multipart/package-info.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2002-2016 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * This package is a copy of the org.springframework.web.portlet.multipart package from Spring 4.3.x
+ * (org.springframework, spring-webmvc-portlet, <a href="https://github.com/spring-projects/spring-framework/tree/4.3.x</a>)
+ * which changes the package name to: org.apache.struts2.mock.web.portlet.multipart.
+ *
+ * The copyright and license notice above is reproduced from the original package's CommonsPortletMultipartResolver.java,
+ * since it contained the widest year-range.
+ *
+ * The mock objects only have a dependency on one file from the package, MultipartActionRequest.java, so
+ * it was required. The other files in the package were not retained in this copy (CommonsPortletMultipartResolver.java
+ * in particular created additional dependencies that would require copying additional packages).
+ *
+ * With Spring 5 dropping Portlet MVC support completely [SPR-14129], copying this package should allow
+ * individuals to continue using JUnit unit tests for their Struts 2 Portlet Plugin applications with
+ * Spring 5.x.
+ */
+/**
+ * Multipart resolution framework for handling file uploads.
+ * Provides a PortletMultipartResolver strategy interface,
+ * and a generic extension of the ActionRequest interface
+ * for accessing multipart files in web application code.
+ */
+package org.apache.struts2.mock.web.portlet.multipart;
diff --git a/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/package-info.java b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/package-info.java
new file mode 100644
index 0000000..982821e
--- /dev/null
+++ b/plugins/junit-portlet/src/main/java/org/apache/struts2/mock/web/portlet/package-info.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2016 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * This package is a copy of the org.springframework.mock.web.portlet package from Spring 4.3.x
+ * (org.springframework, spring-test, <a href="https://github.com/spring-projects/spring-framework/tree/4.3.x</a>)
+ * which changes the package name to: org.apache.struts2.mock.web.portlet.
+ *
+ * The copyright and license notice above is reproduced from the original package's ServletWrappingPortletContext.java,
+ * since it contained the widest year-range.
+ *
+ * With Spring 5 dropping Portlet MVC support completely [SPR-14129], copying this package should allow
+ * individuals to continue using JUnit unit tests for their Struts 2 Portlet Plugin applications with
+ * Spring 5.x.
+ */
+/**
+ * A comprehensive set of Portlet API mock objects, targeted at usage with Spring's web MVC framework.
+ * Useful for testing web contexts and controllers.
+ *
+ * <p>More convenient to use than dynamic mock objects (<a href="http://easymock.org/">EasyMock</a>) or
+ * existing Portlet API mock objects.
+ */
+package org.apache.struts2.mock.web.portlet;
\ No newline at end of file
diff --git a/plugins/junit-portlet/src/site/site.xml b/plugins/junit-portlet/src/site/site.xml
new file mode 100644
index 0000000..54fdcf4
--- /dev/null
+++ b/plugins/junit-portlet/src/site/site.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * 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 name="Apache Struts">
+ <skin>
+ <groupId>org.apache.maven.skins</groupId>
+ <artifactId>maven-fluido-skin</artifactId>
+ <version>${fluido-skin.version}</version>
+ </skin>
+ <bannerLeft>
+ <name>Apache Software Foundation</name>
+ <src>http://www.apache.org/images/asf-logo.gif</src>
+ <href>http://www.apache.org/</href>
+ </bannerLeft>
+ <bannerRight>
+ <name>Apache Struts</name>
+ <src>http://struts.apache.org/img/struts-logo.svg</src>
+ <href>http://struts.apache.org/</href>
+ </bannerRight>
+ <publishDate position="left"/>
+ <version position="right"/>
+ <body>
+ <links>
+ <item name="Apache" href="http://www.apache.org/"/>
+ <item name="Struts" href="http://struts.apache.org/"/>
+ </links>
+
+ <menu ref="parent"/>
+ <menu ref="reports"/>
+
+ <footer>
+ <![CDATA[<div class="row span12">
+ Apache Struts, Struts, Apache, the Apache feather logo, and the Apache Struts project
+ logos are trademarks of The Apache Software Foundation.
+ </div>]]>
+ </footer>
+ </body>
+</project>
diff --git a/plugins/junit-portlet/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java b/plugins/junit-portlet/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java
new file mode 100644
index 0000000..6ba60f3
--- /dev/null
+++ b/plugins/junit-portlet/src/test/java/org/apache/struts2/StrutsSpringPortletMockObjectsTest.java
@@ -0,0 +1,1596 @@
+/*
+ * Copyright 2020 Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.MalformedURLException;
+import java.nio.charset.StandardCharsets;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.ResourceBundle;
+import java.util.Set;
+import javax.portlet.ActionRequest;
+import javax.portlet.PortletMode;
+import javax.portlet.PortletPreferences;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletSession;
+import javax.portlet.PortletURL;
+import javax.portlet.PreferencesValidator;
+import javax.portlet.ReadOnlyException;
+import javax.portlet.ResourceURL;
+import javax.portlet.ValidatorException;
+import javax.portlet.WindowState;
+import javax.security.auth.Subject;
+import javax.servlet.http.Cookie;
+import javax.xml.namespace.QName;
+import org.apache.struts2.mock.web.portlet.MockActionRequest;
+import org.apache.struts2.mock.web.portlet.MockActionResponse;
+import org.apache.struts2.mock.web.portlet.MockCacheControl;
+import org.apache.struts2.mock.web.portlet.MockClientDataRequest;
+import org.apache.struts2.mock.web.portlet.MockEvent;
+import org.apache.struts2.mock.web.portlet.MockEventRequest;
+import org.apache.struts2.mock.web.portlet.MockEventResponse;
+import org.apache.struts2.mock.web.portlet.MockMimeResponse;
+import org.apache.struts2.mock.web.portlet.MockMultipartActionRequest;
+import org.apache.struts2.mock.web.portlet.MockPortalContext;
+import org.apache.struts2.mock.web.portlet.MockPortletConfig;
+import org.apache.struts2.mock.web.portlet.MockPortletContext;
+import org.apache.struts2.mock.web.portlet.MockPortletPreferences;
+import org.apache.struts2.mock.web.portlet.MockPortletRequest;
+import org.apache.struts2.mock.web.portlet.MockPortletRequestDispatcher;
+import org.apache.struts2.mock.web.portlet.MockPortletResponse;
+import org.apache.struts2.mock.web.portlet.MockPortletSession;
+import org.apache.struts2.mock.web.portlet.MockPortletURL;
+import org.apache.struts2.mock.web.portlet.MockRenderRequest;
+import org.apache.struts2.mock.web.portlet.MockRenderResponse;
+import org.apache.struts2.mock.web.portlet.MockResourceRequest;
+import org.apache.struts2.mock.web.portlet.MockResourceResponse;
+import org.apache.struts2.mock.web.portlet.MockResourceURL;
+import org.apache.struts2.mock.web.portlet.MockStateAwareResponse;
+import org.apache.struts2.mock.web.portlet.ServletWrappingPortletContext;
+import org.springframework.mock.web.MockServletContext;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.util.WebUtils;
+import org.w3c.dom.Element;
+
+/**
+ * Basic test class for Portlet Mock Object testing
+ *
+ */
+public class StrutsSpringPortletMockObjectsTest extends StrutsSpringTestCase {
+
+ /**
+ * An empty preferences validator for code coverage only
+ */
+ private static class BasicPreferencesValidator implements PreferencesValidator {
+
+ @Override
+ public void validate(PortletPreferences preferences) throws ValidatorException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ }
+
+ public void testApplicationContext() {
+ assertNotNull(applicationContext);
+ }
+
+ public void testContextLocations() {
+ assertNotNull(getContextLocations());
+ }
+
+ public void testMockActionRequest() {
+ final String TEST_ACTIONNAME = "TEST_ACTIONNAME";
+
+ // Call each constructor in sequence, do some basic checks
+ MockActionRequest mockActionRequest = new MockActionRequest(); // Only test is to confirm constructor completes without exception
+ mockActionRequest = new MockActionRequest(TEST_ACTIONNAME);
+ assertEquals("Action name (ActionRequest.ACTION_NAME) " + TEST_ACTIONNAME + " not set ?", TEST_ACTIONNAME, mockActionRequest.getParameter(ActionRequest.ACTION_NAME));
+ mockActionRequest = new MockActionRequest(PortletMode.VIEW);
+ assertEquals("PortletMode.VIEW not set ?", PortletMode.VIEW, mockActionRequest.getPortletMode());
+
+ final MockPortletContext mockPortletContext = new MockPortletContext();
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ mockActionRequest = new MockActionRequest(mockPortletContext); // Only test is to confirm constructor completes without exception
+ mockActionRequest = new MockActionRequest(mockPortalContext, mockPortletContext);
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockActionRequest.getPortalContext());
+ }
+
+ public void testMockActionResponse() {
+ final String TEST_PARAM = "TEST_PARAM";
+ final String TEST_PARAM2 = "TEST_PARAM2";
+ final String TEST_PARAM3 = "TEST_PARAM3";
+ final String TEST_PARAM_VALUE = "NORMALVALUE";
+ final String[] TEST_PARAM_ARRAYVALUE = { "ARRAYVALUE1", "ARRAYVALUE2" };
+ final String[] TEST_PARAM_ARRAYVALUE2 = { "ARRAYVALUE3", "ARRAYVALUE4" };
+ final String TEST_REDIRECT_URL = "localhost:8080/fakeurl";
+ final String TEST_RENDER_URLPARAM_NAME = "fake_render_url_param_name";
+
+ // Call each constructor in sequence, do some basic checks
+ MockActionResponse mockActionResponse = new MockActionResponse();
+ try {
+ mockActionResponse.setPortletMode(PortletMode.VIEW);
+ } catch (Exception ex) {
+ fail("MockActionResponse portlet mode set failed. Exception: " + ex);
+ }
+ assertEquals("PortletMode.VIEW not set ?", PortletMode.VIEW, mockActionResponse.getPortletMode());
+
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ mockActionResponse = new MockActionResponse(mockPortalContext); // Only test is to confirm constructor completes without exception
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockActionResponse.getPortalContext());
+ mockActionResponse.setRenderParameter(TEST_PARAM, TEST_PARAM_VALUE);
+ mockActionResponse.setRenderParameter(TEST_PARAM2, TEST_PARAM_ARRAYVALUE);
+ assertEquals("Portal test render parameter value not as expected ?", TEST_PARAM_VALUE, mockActionResponse.getRenderParameter(TEST_PARAM));
+ assertEquals("Portal test render parameter value not as expected ?", TEST_PARAM_ARRAYVALUE[0], mockActionResponse.getRenderParameter(TEST_PARAM2));
+ final Map<String, String[]> renderParametersMap = new LinkedHashMap<>();
+ renderParametersMap.put(TEST_PARAM3, TEST_PARAM_ARRAYVALUE2);
+ mockActionResponse.setRenderParameters(renderParametersMap);
+ assertEquals("Portal test render parameter value not cleared as expected ?", null, mockActionResponse.getRenderParameter(TEST_PARAM));
+ assertEquals("Portal test render parameter value not cleared as expected ?", null, mockActionResponse.getRenderParameter(TEST_PARAM2));
+ assertEquals("Portal test render parameter map value not as expected ?", renderParametersMap, mockActionResponse.getRenderParameterMap());
+
+ try {
+ mockActionResponse.sendRedirect(TEST_REDIRECT_URL);
+ fail("Able to redirect after windowState/portletMode/renderParameters set ?");
+ } catch (IllegalStateException ise) {
+ // Expected failure
+ } catch (Exception ex) {
+ fail("MockActionResponse sendredirect failed. Exception: " + ex);
+ }
+ mockActionResponse = new MockActionResponse(); // Clean mock response
+ try {
+ mockActionResponse.sendRedirect(TEST_REDIRECT_URL);
+ } catch (Exception ex) {
+ fail("MockActionResponse sendredirect failed. Exception: " + ex);
+ }
+ assertEquals("Redirect url not as expected ?", TEST_REDIRECT_URL, mockActionResponse.getRedirectedUrl());
+ mockActionResponse = new MockActionResponse(); // Clean mock response
+ try {
+ // Note: The original Spring 4.3.x mock implementation always threw an IllegalStateException when calling the method below.
+ mockActionResponse.sendRedirect(TEST_REDIRECT_URL, TEST_RENDER_URLPARAM_NAME);
+ } catch (Exception ex) {
+ fail("MockActionResponse sendredirect failed. Exception: " + ex);
+ }
+ assertEquals("Redirect url not as expected ?", TEST_REDIRECT_URL, mockActionResponse.getRedirectedUrl());
+ assertEquals("Redirect url render parameter not as expected ?", TEST_REDIRECT_URL, mockActionResponse.getRenderParameter(TEST_RENDER_URLPARAM_NAME));
+ }
+
+ public void testMockCacheControl() {
+ final int TEST_EXPIRATION_TIME = 30;
+ final String TEST_ETAG = "TEST_ETAG";
+
+ // Call each constructor in sequence, do some basic checks
+ MockCacheControl mockCacheControl = new MockCacheControl();
+ assertEquals("Initial expiry not as expected ?", 0, mockCacheControl.getExpirationTime());
+ assertFalse("Initial scope public ?", mockCacheControl.isPublicScope());
+ assertFalse("Initial use cache true ?", mockCacheControl.useCachedContent());
+ mockCacheControl.setExpirationTime(TEST_EXPIRATION_TIME);
+ assertEquals("Initial expiry not as expected ?", TEST_EXPIRATION_TIME, mockCacheControl.getExpirationTime());
+ mockCacheControl.setPublicScope(true);
+ assertTrue("Updated scope not public ?", mockCacheControl.isPublicScope());
+ mockCacheControl.setPublicScope(false);
+ assertFalse("Updated scope still public ?", mockCacheControl.isPublicScope());
+ mockCacheControl.setETag(TEST_ETAG);
+ assertEquals("ETag not not as expected ?", TEST_ETAG, mockCacheControl.getETag());
+ mockCacheControl.setUseCachedContent(true);
+ assertTrue("Updated use cache not true ?", mockCacheControl.useCachedContent());
+ mockCacheControl.setUseCachedContent(false);
+ assertFalse("Updated use cache still true ?", mockCacheControl.useCachedContent());
+ }
+
+ public void testMockClientDataRequest() {
+ final String TEST_FAKECONTENT = "Some fake content for the test.";
+ final byte[] TEST_FAKECONTENT_ASBYTES = TEST_FAKECONTENT.getBytes(StandardCharsets.UTF_8);
+ final String TEST_CONTENT_TYPE = "text/html";
+ final String TEST_METHOD = "POST";
+
+ // Call each constructor in sequence, do some basic checks
+ MockClientDataRequest mockClientDataRequest = new MockClientDataRequest(); // Only test is to confirm constructor completes without exception
+ final MockPortletContext mockPortletContext = new MockPortletContext();
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ mockClientDataRequest = new MockClientDataRequest(mockPortletContext); // Only test is to confirm constructor completes without exception
+ mockClientDataRequest = new MockClientDataRequest(mockPortalContext, mockPortletContext);
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockClientDataRequest.getPortalContext());
+ mockClientDataRequest.setContent(TEST_FAKECONTENT_ASBYTES);
+ assertEquals("Content length not as expected ?", TEST_FAKECONTENT_ASBYTES.length, mockClientDataRequest.getContentLength());
+ mockClientDataRequest.setCharacterEncoding(StandardCharsets.UTF_8.name());
+ assertEquals("Charset not as expected ?", StandardCharsets.UTF_8.name(), mockClientDataRequest.getCharacterEncoding());
+ mockClientDataRequest.setContentType(TEST_CONTENT_TYPE);
+ assertEquals("Content-type not as expected ?", TEST_CONTENT_TYPE, mockClientDataRequest.getContentType());
+ mockClientDataRequest.setMethod(TEST_METHOD);
+ assertEquals("Method not as expected ?", TEST_METHOD, mockClientDataRequest.getMethod());
+ try ( InputStream inputStream = mockClientDataRequest.getPortletInputStream() ) {
+ final byte[] readContent = new byte[mockClientDataRequest.getContentLength()];
+ inputStream.read(readContent, 0, readContent.length);
+ assertTrue("Read byte array does not match original ?", Arrays.equals(TEST_FAKECONTENT_ASBYTES, readContent));
+ } catch (Exception ex) {
+ fail("MockClientDataRequest read inputstream failed. Exception: " + ex);
+ }
+ try ( BufferedReader bufferedReader = mockClientDataRequest.getReader() ) {
+ final String theOnlyLine = bufferedReader.readLine();
+ assertEquals("Read line does not match original ?", TEST_FAKECONTENT, theOnlyLine);
+ } catch (Exception ex) {
+ fail("MockClientDataRequest read inputstream failed. Exception: " + ex);
+ }
+ }
+
+ public void testMockEvent() {
+ final String TEST_EVENT = "TEST_EVENT";
+ final String TEST_EVENT_VALUE = "TEST_EVENT_VALUE";
+ final QName TEST_QNAME = new QName(TEST_EVENT);
+
+ // Call each constructor in sequence, do some basic checks
+ MockEvent mockClientDataRequest = new MockEvent(TEST_EVENT);
+ assertEquals("Initial value not null ?", null, mockClientDataRequest.getValue());
+ assertEquals("Event name does not match ?", TEST_EVENT, mockClientDataRequest.getName());
+ assertEquals("Event QName does not match ?", new QName(TEST_EVENT), mockClientDataRequest.getQName());
+ mockClientDataRequest = new MockEvent(TEST_EVENT, TEST_EVENT_VALUE);
+ assertEquals("Initial value not as expected ?", TEST_EVENT_VALUE, mockClientDataRequest.getValue());
+ assertEquals("Event name does not match ?", TEST_EVENT, mockClientDataRequest.getName());
+ assertEquals("Event QName does not match ?", new QName(TEST_EVENT), mockClientDataRequest.getQName());
+ mockClientDataRequest = new MockEvent(TEST_QNAME);
+ assertEquals("Initial value not null ?", null, mockClientDataRequest.getValue());
+ assertEquals("Event name does not match ?", TEST_EVENT, mockClientDataRequest.getName());
+ assertEquals("Event QName does not match ?", TEST_QNAME, mockClientDataRequest.getQName());
+ mockClientDataRequest = new MockEvent(TEST_QNAME, TEST_EVENT_VALUE);
+ assertEquals("Initial value not as expected ?", TEST_EVENT_VALUE, mockClientDataRequest.getValue());
+ assertEquals("Event name does not match ?", TEST_EVENT, mockClientDataRequest.getName());
+ assertEquals("Event QName does not match ?", TEST_QNAME, mockClientDataRequest.getQName());
+ }
+
+ public void testMockEventRequest() {
+ final MockEvent TEST_MOCKEVENT = new MockEvent("MockEventName", "MockEventValue");
+ final String TEST_METHOD = "POST";
+
+ // Call each constructor in sequence, do some basic checks
+ MockEventRequest mockEventRequest = new MockEventRequest(TEST_MOCKEVENT);
+ assertEquals("Event not the event set ?", TEST_MOCKEVENT, mockEventRequest.getEvent());
+ mockEventRequest.setMethod(TEST_METHOD);
+ assertEquals("Method not the method set ?", TEST_METHOD, mockEventRequest.getMethod());
+ final MockPortletContext mockPortletContext = new MockPortletContext();
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ mockEventRequest = new MockEventRequest(TEST_MOCKEVENT, mockPortletContext); // Only test is to confirm constructor completes without exception
+ mockEventRequest = new MockEventRequest(TEST_MOCKEVENT, mockPortalContext, mockPortletContext); // Only test is to confirm constructor completes without exception
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockEventRequest.getPortalContext());
+ }
+
+ public void testMockEventResponse() {
+ // Call each constructor in sequence, do some basic checks
+ MockEventResponse mockEventResponse = new MockEventResponse(); // Only test is to confirm constructor completes without exception
+ }
+
+ public void testMockMimeResponse() {;
+ final String TEST_CONTENT_TYPE = "text/html";
+ final int TEST_BUFFERSIZE = 8192;
+ final String TEST_INCLUDED_URL = "localhost:8080/fakeincludedurl";
+ final String TEST_FORWARDED_URL = "localhost:8080/fakeforwardedurl";
+ final String TEST_FAKECONTENT = "Some fake content for the test.";
+ final byte[] TEST_FAKECONTENT_ASBYTES = TEST_FAKECONTENT.getBytes(StandardCharsets.UTF_8);
+
+ // Call each constructor in sequence, do some basic checks
+ MockMimeResponse mockMimeResponse = new MockMimeResponse();
+ assertEquals("Default character encoding not as expected ?", WebUtils.DEFAULT_CHARACTER_ENCODING, mockMimeResponse.getCharacterEncoding());
+ assertEquals("Default locale not as expected ?", Locale.getDefault(), mockMimeResponse.getLocale());
+ assertTrue("Default buffersize not as expected ?", mockMimeResponse.getBufferSize() >= 4096);
+ assertFalse("Mock response already committed ?", mockMimeResponse.isCommitted());
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ final MockPortletContext mockPortletContext = new MockPortletContext();
+ final MockPortletRequest mockPortletRequest = new MockPortletRequest(mockPortalContext, mockPortletContext);
+ mockMimeResponse = new MockMimeResponse(mockPortalContext);
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockMimeResponse.getPortalContext());
+ mockMimeResponse = new MockMimeResponse(mockPortalContext, mockPortletRequest);
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockMimeResponse.getPortalContext());
+ mockMimeResponse.setContentType(TEST_CONTENT_TYPE);
+ assertEquals("Content-type not as expected ?", TEST_CONTENT_TYPE, mockMimeResponse.getContentType());
+ mockMimeResponse.setCharacterEncoding(StandardCharsets.UTF_8.name());
+ assertEquals("Charset not as expected ?", StandardCharsets.UTF_8.name(), mockMimeResponse.getCharacterEncoding());
+ mockMimeResponse.setBufferSize(TEST_BUFFERSIZE);
+ assertEquals("Buffersize not as expected ?", TEST_BUFFERSIZE, mockMimeResponse.getBufferSize());
+ mockMimeResponse.setCommitted(true);
+ assertTrue("Response not committed ?", mockMimeResponse.isCommitted());
+ mockMimeResponse.setCommitted(false);
+ assertFalse("Response still committed ?", mockMimeResponse.isCommitted());
+ mockMimeResponse.setIncludedUrl(TEST_INCLUDED_URL);
+ assertEquals("Included URL not as expected ?", TEST_INCLUDED_URL, mockMimeResponse.getIncludedUrl());
+ mockMimeResponse.setForwardedUrl(TEST_FORWARDED_URL);
+ assertEquals("Forwarded URL not as expected ?", TEST_FORWARDED_URL, mockMimeResponse.getForwardedUrl());
+ try {
+ assertNotNull("OutputStream null ?", mockMimeResponse.getPortletOutputStream());
+ } catch (Exception ex) {
+ fail("MockMimeResponse get outputstream failed. Exception: " + ex);
+ }
+ PortletURL portletUrl = mockMimeResponse.createRenderURL();
+ assertNotNull("RenderURL null ?", portletUrl);
+ portletUrl = mockMimeResponse.createActionURL();
+ assertNotNull("ActionURL null ?", portletUrl);
+ ResourceURL resourceURL = mockMimeResponse.createResourceURL();
+ assertNotNull("ResourceURL null ?", resourceURL);
+ assertNotNull("CacheControl null ?", mockMimeResponse.getCacheControl());
+
+ try {
+ OutputStream outputStream = mockMimeResponse.getPortletOutputStream();
+ assertNotNull("OutputStream null ?", outputStream);
+ outputStream.write(TEST_FAKECONTENT_ASBYTES);
+ final byte[] writeResult = mockMimeResponse.getContentAsByteArray();
+ assertTrue("Written byte array does not match original ?", Arrays.equals(TEST_FAKECONTENT_ASBYTES, writeResult));
+ assertTrue("Buffer not committed after processing ?", mockMimeResponse.isCommitted());
+ } catch (Exception ex) {
+ fail("MockMimeResponse get/process outputstream failed. Exception: " + ex);
+ }
+ try {
+ mockMimeResponse.resetBuffer();
+ } catch (IllegalStateException ise) {
+ // Expected failure
+ }
+
+ mockMimeResponse.setCommitted(false);
+ mockMimeResponse.resetBuffer();
+ try {
+ PrintWriter printWriter = mockMimeResponse.getWriter();
+ assertNotNull("PrintWriter null ?", printWriter);
+ printWriter.print(TEST_FAKECONTENT);
+ mockMimeResponse.flushBuffer();
+ final byte[] writeResult = mockMimeResponse.getContentAsByteArray();
+ assertTrue("Written byte array does not match original ?", Arrays.equals(TEST_FAKECONTENT_ASBYTES, writeResult));
+ assertTrue("Buffer not committed after processing ?", mockMimeResponse.isCommitted());
+ final String writeResultAsString = mockMimeResponse.getContentAsString();
+ assertEquals("Written result does not match original ?", TEST_FAKECONTENT, writeResultAsString);
+ } catch (Exception ex) {
+ fail("MockMimeResponse get/process printwriter failed. Exception: " + ex);
+ }
+ try {
+ mockMimeResponse.reset();
+ } catch (IllegalStateException ise) {
+ // Expected failure
+ }
+
+ mockMimeResponse.setCommitted(false);
+ mockMimeResponse.reset();
+ assertNull("After reset, character encoding not null ?", mockMimeResponse.getCharacterEncoding());
+ assertNull("After reset, content-type not null ?", mockMimeResponse.getContentType());
+ assertNull("After reset, locale not null ?", mockMimeResponse.getLocale());
+ }
+
+ public void testMockMultipartActionRequest() {
+ final String TEST_FILENAME = "TEST_TEMPFILE";
+ final String TEST_FILENAME2 = "TEST_TEMPFILE2";
+ final String TEST_CONTENT_TYPE = "text/html";
+ final String TEST_FAKECONTENT = "Some fake content for the test.";
+ final byte[] TEST_FAKECONTENT_ASBYTES = TEST_FAKECONTENT.getBytes(StandardCharsets.UTF_8);
+
+ // Call each constructor in sequence, do some basic checks
+ MockMultipartActionRequest mockMultipartActionRequest = new MockMultipartActionRequest();
+ assertFalse("Initial multipartrequest has file names ?", mockMultipartActionRequest.getFileNames().hasNext());
+ assertTrue("Initial multipartrequest has nonempty map ?", mockMultipartActionRequest.getFileMap().isEmpty());
+ assertTrue("Initial multipartrequest has nonempty multivalue map ?", mockMultipartActionRequest.getMultiFileMap().isEmpty());
+ final MultipartFile multipartFile = new TestMockMultipartFile(TEST_FILENAME, TEST_FILENAME, TEST_CONTENT_TYPE, TEST_FAKECONTENT_ASBYTES);
+ final MultipartFile multipartFile2 = new TestMockMultipartFile(TEST_FILENAME2, TEST_FILENAME2, TEST_CONTENT_TYPE, TEST_FAKECONTENT_ASBYTES);
+ mockMultipartActionRequest.addFile(multipartFile);
+ assertTrue("Multipartrequest does not have file names ?", mockMultipartActionRequest.getFileNames().hasNext());
+ assertFalse("Multipartrequest does not have nonempty map ?", mockMultipartActionRequest.getFileMap().isEmpty());
+ assertFalse("Multipartrequest does not have nonempty multivalue map ?", mockMultipartActionRequest.getMultiFileMap().isEmpty());
+ mockMultipartActionRequest.addFile(multipartFile2);
+ assertTrue("Multipartrequest does not have file names ?", mockMultipartActionRequest.getFileNames().hasNext());
+ assertFalse("Multipartrequest does not have nonempty map ?", mockMultipartActionRequest.getFileMap().isEmpty());
+ assertFalse("Multipartrequest does not have nonempty multivalue map ?", mockMultipartActionRequest.getMultiFileMap().isEmpty());
+ assertEquals("Retrieved file 1 not as expected ?", multipartFile, mockMultipartActionRequest.getFile(TEST_FILENAME));
+ assertEquals("Retrieved file 1 content-type not as expected ?", TEST_CONTENT_TYPE, mockMultipartActionRequest.getMultipartContentType(TEST_FILENAME));
+ assertEquals("Retrieved file 2 not as expected ?", multipartFile2, mockMultipartActionRequest.getFile(TEST_FILENAME2));
+ assertEquals("Retrieved file 2 content-type not as expected ?", TEST_CONTENT_TYPE, mockMultipartActionRequest.getMultipartContentType(TEST_FILENAME2));
+ final Map<String, MultipartFile> fileMap = mockMultipartActionRequest.getFileMap();
+ assertNotNull("File map is null ?", fileMap);
+ assertTrue("File 1 name not in map ?", fileMap.containsKey(TEST_FILENAME));
+ assertTrue("File 2 name not in map ?", fileMap.containsKey(TEST_FILENAME2));
+ assertTrue("File 1 not in map ?", fileMap.containsValue(multipartFile));
+ assertTrue("File 2 not in map ?", fileMap.containsValue(multipartFile2));
+ MultiValueMap<String, MultipartFile> fileMultiValueMap = mockMultipartActionRequest.getMultiFileMap();
+ assertNotNull("MultiValue file map is null ?", fileMultiValueMap);
+ MultipartFile retrievedFile = fileMultiValueMap.getFirst(TEST_FILENAME);
+ assertNotNull("File 1 1st value is null ?", retrievedFile);
+ assertEquals("File 1 not in multivalue map ?", multipartFile, retrievedFile);
+ retrievedFile = fileMultiValueMap.getFirst(TEST_FILENAME2);
+ assertNotNull("File 2 1st value is null ?", retrievedFile);
+ assertEquals("File 2 not in multivalue map ?", multipartFile2, retrievedFile);
+ }
+
+ public void testMockPortalContext() {
+ final String TEST_PROPERTY = "TEST_PROPERTY";
+ final String TEST_PROPERTY_VALUE = "Property_Value_1";
+ final String TEST_PROPERTY2 = "TEST_PROPERTY2";
+ final String TEST_PROPERTY2_VALUE = "Property_Value_2";
+
+ // Call each constructor in sequence, do some basic checks
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ assertNotNull("MockPortalContext portalInfo null ?", mockPortalContext.getPortalInfo());
+ assertNotNull("MockPortalContext property names null ?", mockPortalContext.getPropertyNames());
+ assertFalse("MockPortalConext initial propertyNames not empty ?", mockPortalContext.getPropertyNames().hasMoreElements());
+ final Enumeration<PortletMode> supportedPortletModes = mockPortalContext.getSupportedPortletModes();
+ assertNotNull("MockPortalContext supported portlet modes null ?", supportedPortletModes);
+ final ArrayList<PortletMode> portletModeList = new ArrayList<>();
+ while (supportedPortletModes.hasMoreElements()) {
+ portletModeList.add(supportedPortletModes.nextElement());
+ }
+ assertEquals("MockPortalContext does not support three modes ?", 3, portletModeList.size());
+ assertTrue("MockPortalContext does not contain PortletMode.VIEW ?", portletModeList.contains(PortletMode.VIEW));
+ assertTrue("MockPortalContext does not contain PortletMode.EDIT ?", portletModeList.contains(PortletMode.EDIT));
+ assertTrue("MockPortalContext does not contain PortletMode.HELP ?", portletModeList.contains(PortletMode.HELP));
+
+ final Enumeration<WindowState> supportedWindowStates = mockPortalContext.getSupportedWindowStates();
+ assertNotNull("MockPortalContext supported window modes null ?", supportedWindowStates);
+ final ArrayList<WindowState> windowStateList = new ArrayList<>();
+ while (supportedWindowStates.hasMoreElements()) {
+ windowStateList.add(supportedWindowStates.nextElement());
+ }
+ assertEquals("MockPortalContext does not support three states ?", 3, windowStateList.size());
+ assertTrue("MockPortalContext does not contain WindowState.NORMAL ?", windowStateList.contains(WindowState.NORMAL));
+ assertTrue("MockPortalContext does not contain WindowState.MAXIMIZED ?", windowStateList.contains(WindowState.MAXIMIZED));
+ assertTrue("MockPortalContext does not contain WindowState.MINIMIZED ?", windowStateList.contains(WindowState.MINIMIZED));
+
+ mockPortalContext.setProperty(TEST_PROPERTY, TEST_PROPERTY_VALUE);
+ mockPortalContext.setProperty(TEST_PROPERTY2, TEST_PROPERTY2_VALUE);
+ final Enumeration<String> propertyNames = mockPortalContext.getPropertyNames();
+ assertNotNull("MockPortalContext property names null ?", propertyNames);
+ final ArrayList<String> propertyNamesList = new ArrayList<>();
+ while (propertyNames.hasMoreElements()) {
+ propertyNamesList.add(propertyNames.nextElement());
+ }
+ assertEquals("MockPortalContext does not contain two properties ?", 2, propertyNamesList.size());
+ assertTrue("MockPortalContext does not contain property name " + TEST_PROPERTY + " ?", propertyNamesList.contains(TEST_PROPERTY));
+ assertTrue("MockPortalContext does not contain property name " + TEST_PROPERTY2 + " ?", propertyNamesList.contains(TEST_PROPERTY2));
+ assertEquals("MockPortalContext value of property name " + TEST_PROPERTY + " not as expected ?", TEST_PROPERTY_VALUE, mockPortalContext.getProperty(TEST_PROPERTY));
+ assertEquals("MockPortalContext value of property name " + TEST_PROPERTY2 + " not as expected ?", TEST_PROPERTY2_VALUE, mockPortalContext.getProperty(TEST_PROPERTY2));
+ }
+
+ public void testMockPortletConfig() {
+ final String TEST_PORTLETNAME = "TestPortletName";
+ final String TEST_INITPARAM = "TEST_INITPARAM";
+ final String TEST_INITPARAM_VALUE = "Init_Value_1";
+ final String TEST_INITPARAM2= "TEST_INITPARAM2";
+ final String TEST_INITPARAM_VALUE2 = "Init_Value_2";
+ final String TEST_RENDERPARAM_NAME = "Test_RenderParam_1";
+ final String TEST_RENDERPARAM_NAME2 = "Test_RenderParam_2";
+ final String TEST_DEFAULTNAMESPACE = "Test_Default_Namespace";
+ final QName TEST_QNAME = new QName(TEST_PORTLETNAME);
+ final QName TEST_QNAME2 = new QName(TEST_DEFAULTNAMESPACE);
+ final String TEST_RUNTIME_OPTION = "TEST_RUNTIME_OPTION";
+ final String TEST_RUNTIME_OPTION2 = "TEST_RUNTIME_OPTION2";
+ final String TEST_RUNTIME_VALUE1 = "Test_Runtime_Option1";
+ final String TEST_RUNTIME_VALUE2 = "Test_Runtime_Option2";
+
+ // Call each constructor in sequence, do some basic checks
+ MockPortletConfig mockPortletConfig = new MockPortletConfig();
+ assertNotNull("MockPortletConfig default PortletContext is null ?", mockPortletConfig.getPortletContext());
+ assertEquals("MockPortletConfig default name not empty string ?", "", mockPortletConfig.getPortletName());
+ mockPortletConfig = new MockPortletConfig(TEST_PORTLETNAME);
+ assertNotNull("MockPortletConfig default PortletContext is null ?", mockPortletConfig.getPortletContext());
+ assertEquals("MockPortletConfig name not constructor set value ?", TEST_PORTLETNAME, mockPortletConfig.getPortletName());
+ final MockPortletContext mockPortletContext = new MockPortletContext();
+ mockPortletConfig = new MockPortletConfig(mockPortletContext, TEST_PORTLETNAME);
+ assertEquals("MockPortletConfig PortletContext constructor set value ?", mockPortletContext, mockPortletConfig.getPortletContext());
+ assertEquals("MockPortletConfig name not constructor set value ?", TEST_PORTLETNAME, mockPortletConfig.getPortletName());
+ assertNull("MockPortletConfig default locale resource bundle not null ?", mockPortletConfig.getResourceBundle(Locale.getDefault()));
+ final ResourceBundle resourceBundle = new TetMockResourceBundle();
+ mockPortletConfig.setResourceBundle(Locale.getDefault(), resourceBundle);
+ assertEquals("Default locale resource bundle not set value ?", resourceBundle, mockPortletConfig.getResourceBundle(Locale.getDefault()));
+
+ assertNull(TEST_INITPARAM + " present before set ?", mockPortletConfig.getInitParameter(TEST_INITPARAM));
+ assertNull(TEST_INITPARAM2 + " present before set ?", mockPortletConfig.getInitParameter(TEST_INITPARAM));
+ mockPortletConfig.addInitParameter(TEST_INITPARAM, TEST_INITPARAM_VALUE);
+ mockPortletConfig.addInitParameter(TEST_INITPARAM2, TEST_INITPARAM_VALUE2);
+ assertEquals("Retrieved init parameter 1 does not match set value ?", TEST_INITPARAM_VALUE, mockPortletConfig.getInitParameter(TEST_INITPARAM));
+ assertEquals("Retrieved init parameter 2 does not match set value ?", TEST_INITPARAM_VALUE2, mockPortletConfig.getInitParameter(TEST_INITPARAM2));
+ final Enumeration<String> initParameterNames = mockPortletConfig.getInitParameterNames();
+ int initParameterNameCount = 0;
+ assertNotNull("InitParameter names null after additions ?", initParameterNames);
+ assertTrue("InitParameter names empty after additions ?", initParameterNames.hasMoreElements());
+ while (initParameterNames.hasMoreElements()) {
+ initParameterNameCount++;
+ String currentInitParameterName = initParameterNames.nextElement();
+ assertTrue("Initparam name not one of two expected matches ?", TEST_INITPARAM.equals(currentInitParameterName) ||
+ TEST_INITPARAM2.equals(currentInitParameterName));
+ }
+ assertEquals("InitParameter names size not 2 ?", 2, initParameterNameCount);
+
+ assertFalse("Initial renderparam names not empty ?", mockPortletConfig.getPublicRenderParameterNames().hasMoreElements());
+ mockPortletConfig.addPublicRenderParameterName(TEST_RENDERPARAM_NAME);
+ mockPortletConfig.addPublicRenderParameterName(TEST_RENDERPARAM_NAME2);
+ final Enumeration<String> publicRenderParameterNames = mockPortletConfig.getPublicRenderParameterNames();
+ int publicRenderParameterNameCount = 0;
+ assertNotNull("PublicRenderParameter names null after additions ?", publicRenderParameterNames);
+ assertTrue("PublicRenderParameter names empty after additions ?", publicRenderParameterNames.hasMoreElements());
+ while (publicRenderParameterNames.hasMoreElements()) {
+ publicRenderParameterNameCount++;
+ String currentPublicRenderParameterName = publicRenderParameterNames.nextElement();
+ assertTrue("PublicRenderParameter name not one of two expected matches ?", TEST_RENDERPARAM_NAME.equals(currentPublicRenderParameterName) ||
+ TEST_RENDERPARAM_NAME2.equals(currentPublicRenderParameterName));
+ }
+ assertEquals("PublicRenderParameter names size not 2 ?", 2, publicRenderParameterNameCount);
+ mockPortletConfig.setDefaultNamespace(TEST_DEFAULTNAMESPACE);
+ assertEquals("Default namespace not set value ?", TEST_DEFAULTNAMESPACE, mockPortletConfig.getDefaultNamespace());
+
+ assertFalse("Initial publishing event QNames not empty ?", mockPortletConfig.getPublishingEventQNames().hasMoreElements());
+ assertFalse("Initial processing event QNames not empty ?", mockPortletConfig.getProcessingEventQNames().hasMoreElements());
+ mockPortletConfig.addPublishingEventQName(TEST_QNAME);
+ mockPortletConfig.addProcessingEventQName(TEST_QNAME2);
+ final Enumeration<QName> publishingEventQNames = mockPortletConfig.getPublishingEventQNames();
+ assertNotNull("PublishingEventQNames names null after additions ?", publishingEventQNames);
+ assertTrue("PublishingEventQNames names empty after additions ?", publishingEventQNames.hasMoreElements());
+ final QName firstPublishingEventQName = publishingEventQNames.nextElement();
+ assertEquals("First publishing event QName not set value ?", TEST_QNAME, firstPublishingEventQName);
+ final Enumeration<QName> processingEventQNames = mockPortletConfig.getProcessingEventQNames();
+ assertNotNull("ProcessingEventQNames names null after additions ?", processingEventQNames);
+ assertTrue("ProcessingEventQNames names empty after additions ?", processingEventQNames.hasMoreElements());
+ final QName firstProcessingEventQName = processingEventQNames.nextElement();
+ assertEquals("First processing event QName not set value ?", TEST_QNAME2, firstProcessingEventQName);
+
+ assertFalse("Initial supported locales not empty ?", mockPortletConfig.getSupportedLocales().hasMoreElements());
+ mockPortletConfig.addSupportedLocale(Locale.getDefault());
+ final Enumeration<Locale> supportedLocales = mockPortletConfig.getSupportedLocales();
+ assertNotNull("Supported locales null after additions ?", supportedLocales);
+ assertTrue("Supported locales names empty after additions ?", supportedLocales.hasMoreElements());
+ final Locale firstSupportedLocale = supportedLocales.nextElement();
+ assertEquals("First supported locale not set value ?", Locale.getDefault(), firstSupportedLocale);
+
+ assertTrue("Portlet runtime options not empty before set ?", mockPortletConfig.getContainerRuntimeOptions().isEmpty());
+ mockPortletConfig.addContainerRuntimeOption(TEST_RUNTIME_OPTION, TEST_RUNTIME_VALUE1);
+ mockPortletConfig.addContainerRuntimeOption(TEST_RUNTIME_OPTION2, TEST_RUNTIME_VALUE2);
+ final Map<String, String[]> containerRuntimeOptions = mockPortletConfig.getContainerRuntimeOptions();
+ assertNotNull("Runtime options null after additions ?", containerRuntimeOptions);
+ assertFalse("Runtime options empty after additions ?", containerRuntimeOptions.isEmpty());
+ assertTrue("Runtime option 1 not present after setting ?", containerRuntimeOptions.containsKey(TEST_RUNTIME_OPTION));
+ assertTrue("Runtime option 2 not present after setting ?", containerRuntimeOptions.containsKey(TEST_RUNTIME_OPTION2));
+ assertEquals("Runtime option 1 not equal to set value ?", TEST_RUNTIME_VALUE1, containerRuntimeOptions.get(TEST_RUNTIME_OPTION)[0]);
+ assertEquals("Runtime option 2 not equal to set value ?", TEST_RUNTIME_VALUE2, containerRuntimeOptions.get(TEST_RUNTIME_OPTION2)[0]);
+ }
+
+ public void testMockPortletContext() {
+ final String TEST_ATTRIBUTE = "TEST_ATTRIBUTE";
+ final String TEST_ATTRIBUTE_VALUE = "Attribute_Value_1";
+ final String TEST_ATTRIBUTE2 = "TEST_ATTRIBUTE2";
+ final String TEST_ATTRIBUTE_VALUE2 = "Attribute_Value_2";
+ final String TEST_INITPARAM = "TEST_INITPARAM";
+ final String TEST_INITPARAM_VALUE = "Init_Value_1";
+ final String TEST_INITPARAM2 = "TEST_INITPARAM2";
+ final String TEST_INITPARAM_VALUE2 = "Init_Value_2";
+ final String TEST_CONTEXT_NAME = "TEST_CONTEXT_NAME";
+ final String TEST_RUNTIME_OPTION = "TEST_RUNTIME_OPTION";
+ final String TEST_RUNTIME_OPTION2 = "TEST_RUNTIME_OPTION2";
+
+ // Call each constructor in sequence, do some basic checks
+ final MockPortletContext mockPortletContext = new MockPortletContext();
+ assertNotNull("MockPortletContext serverInfo null ?", mockPortletContext.getServerInfo());
+ try {
+ assertNotNull("MockPortletContext PortletRequestDispatcher null ?", mockPortletContext.getRequestDispatcher("IllegalPrefix"));
+ fail("PortletRequestDispatcher path must start with /");
+ } catch (IllegalArgumentException iae) {
+ // Expected exception
+ }
+ assertNotNull("MockPortletContext PortletRequestDispatcher for / null ?", mockPortletContext.getRequestDispatcher("/"));
+ assertNull("MockPortletContext named PortletRequestDispatcher not null ?", mockPortletContext.getNamedDispatcher("SomeName"));
+ assertNotNull("MockPortletContext resource stream for / null ?", mockPortletContext.getResourceAsStream("/"));
+ assertNull("MockPortletContext resource stream for /ThisDoesNotExist not null ?", mockPortletContext.getResourceAsStream("/ThisDoesNotExist"));
+ assertTrue("MockPortletContext major version not >= 2 ?", mockPortletContext.getMajorVersion() >= 2);
+ assertTrue("MockPortletContext minor version not >= 0 ?", mockPortletContext.getMajorVersion() >= 0);
+ assertNull("MockPortletContext MIME type for / not null ?", mockPortletContext.getMimeType("/"));
+ assertNotNull("MockPortletContext real path for / null ?", mockPortletContext.getRealPath("/"));
+ assertNull("MockPortletContext real path for /ThisDoesNotExist not null ? ?", mockPortletContext.getRealPath("/ThisDoesNotExist"));
+ assertNotNull("MockPortletContext resource paths for / null ?", mockPortletContext.getResourcePaths("/"));
+ assertNull("MockPortletContext resource paths for / null ?", mockPortletContext.getResourcePaths("/ThisDoesNotExist"));
+ try {
+ assertNotNull("MockPortletContext resource URL for / null ?", mockPortletContext.getResource("/"));
+ } catch (MalformedURLException mue) {
+ fail("MockPortletContext resource URL for / failed. Exception: " + mue);
+ }
+ try {
+ assertNull("MockPortletContext resource URL for /ThisDoesNotExist not null ?", mockPortletContext.getResource("/ThisDoesNotExist"));
+ } catch (MalformedURLException mue) {
+ fail("MockPortletContext resource URL for /ThisDoesNotExist failed. Exception: " + mue);
+ }
+
+ assertNull(TEST_ATTRIBUTE + " present before set ?", mockPortletContext.getAttribute(TEST_ATTRIBUTE));
+ assertNull(TEST_ATTRIBUTE2 + " present before set ?", mockPortletContext.getAttribute(TEST_ATTRIBUTE2));
+ mockPortletContext.setAttribute(TEST_ATTRIBUTE, TEST_ATTRIBUTE_VALUE);
+ mockPortletContext.setAttribute(TEST_ATTRIBUTE2, TEST_ATTRIBUTE_VALUE2);
+ assertEquals("Retrieved atribute 1 does not match set value ?", TEST_ATTRIBUTE_VALUE, mockPortletContext.getAttribute(TEST_ATTRIBUTE));
+ assertEquals("Retrieved atribute 2 does not match set value ?", TEST_ATTRIBUTE_VALUE2, mockPortletContext.getAttribute(TEST_ATTRIBUTE2));
+ final Enumeration<String> attributeNames = mockPortletContext.getAttributeNames();
+ int attributeNameCount = 0;
+ assertNotNull("Attribute names null after additions ?", attributeNames);
+ assertTrue("Attribute names empty after additions ?", attributeNames.hasMoreElements());
+ while (attributeNames.hasMoreElements()) {
+ attributeNameCount++;
+ String currentAttibuteName = attributeNames.nextElement();
+ assertTrue("Attribute name not one of two or three expected matches ?", TEST_ATTRIBUTE.equals(currentAttibuteName) ||
+ TEST_ATTRIBUTE2.equals(currentAttibuteName) ||
+ WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE.equals(currentAttibuteName));
+ }
+ assertTrue("Atribute names size not 2 or 3 ?", attributeNameCount >= 2 && attributeNameCount <= 3);
+
+ assertNull(TEST_INITPARAM + " present before set ?", mockPortletContext.getInitParameter(TEST_INITPARAM));
+ assertNull(TEST_INITPARAM2 + " present before set ?", mockPortletContext.getInitParameter(TEST_INITPARAM));
+ mockPortletContext.addInitParameter(TEST_INITPARAM, TEST_INITPARAM_VALUE);
+ mockPortletContext.addInitParameter(TEST_INITPARAM2, TEST_INITPARAM_VALUE2);
+ assertEquals("Retrieved init parameter 1 does not match set value ?", TEST_INITPARAM_VALUE, mockPortletContext.getInitParameter(TEST_INITPARAM));
+ assertEquals("Retrieved init parameter 2 does not match set value ?", TEST_INITPARAM_VALUE2, mockPortletContext.getInitParameter(TEST_INITPARAM2));
+ final Enumeration<String> initParameterNames = mockPortletContext.getInitParameterNames();
+ int initParameterNameCount = 0;
+ assertNotNull("InitParameter names null after additions ?", initParameterNames);
+ assertTrue("InitParameter names empty after additions ?", initParameterNames.hasMoreElements());
+ while (initParameterNames.hasMoreElements()) {
+ initParameterNameCount++;
+ String currentInitParameterName = initParameterNames.nextElement();
+ assertTrue("Initparam name not one of two expected matches ?", TEST_INITPARAM.equals(currentInitParameterName) ||
+ TEST_INITPARAM2.equals(currentInitParameterName));
+ }
+ assertEquals("InitParameter names size not 2 ?", 2, initParameterNameCount);
+
+ mockPortletContext.log("Test logging call");
+ mockPortletContext.log("Test logging call", new Exception("Fake Exception"));
+
+ assertEquals("Default portlet context name not as expected ?", "MockPortletContext", mockPortletContext.getPortletContextName());
+ mockPortletContext.setPortletContextName(TEST_CONTEXT_NAME);
+ assertEquals("Portlet context name not equal to set value ?", TEST_CONTEXT_NAME, mockPortletContext.getPortletContextName());
+
+ assertFalse("Portlet runtime options not empty before set ?", mockPortletContext.getContainerRuntimeOptions().hasMoreElements());
+ mockPortletContext.addContainerRuntimeOption(TEST_RUNTIME_OPTION);
+ mockPortletContext.addContainerRuntimeOption(TEST_RUNTIME_OPTION2);
+ final Enumeration<String> containerRuntimeOptions = mockPortletContext.getContainerRuntimeOptions();
+ int containerRuntimeOptionsCount = 0;
+ assertNotNull("Runtime options null after additions ?", containerRuntimeOptions);
+ assertTrue("Runtime options empty after additions ?", containerRuntimeOptions.hasMoreElements());
+ while (containerRuntimeOptions.hasMoreElements()) {
+ containerRuntimeOptionsCount++;
+ String currentRuntimeOption = containerRuntimeOptions.nextElement();
+ assertTrue("Runtime option not one of two expected matches ?", TEST_RUNTIME_OPTION.equals(currentRuntimeOption) ||
+ TEST_RUNTIME_OPTION2.equals(currentRuntimeOption));
+ }
+ assertEquals("Runtime options size not 2 ?", 2, containerRuntimeOptionsCount);
+ }
+
+ public void testMockPortletPreferences() {
+ final String PORTLET_READONLY = "PORTLET_READONLY";
+ final String PORTLET_READONLY_VALUE = "Readonly_Value_1";
+ final String PORTLET_READONLY2 = "PORTLET_READONLY2";
+ final String PORTLET_READONLY2_VALUE = "Readonly_Value_2";
+ final String PORTLET_WRITEABLE = "PORTLET_WRITEABLE";
+ final String PORTLET_WRITEABLE_VALUE = "Writeable_Value_1";
+ final String PORTLET_WRITEABLE2 = "PORTLET_WRITEABLE2";
+ final String PORTLET_WRITEABLE2_VALUE = "Writeable_Value_2";
+ final String PORTLET_WRITEABLE_ARRAY = "PORTLET_WRITEABLE_ARRAY";
+ final String[] PORTLET_WRITEABLE_ARRAY_VALUE = { "Writeable_Array_Value_1", "Writeable_Array_Value" };
+
+ // Call each constructor in sequence, do some basic checks
+ final MockPortletPreferences mockPortletPreferences = new MockPortletPreferences();
+ assertFalse("MockPortletPreferences initial preferences names non-empty ?", mockPortletPreferences.getNames().hasMoreElements());
+ assertTrue("MockPortletPreferences initial preferences non-empty ?", mockPortletPreferences.getMap().isEmpty());
+
+ // Test set readonly permitted before key exists
+ assertFalse(PORTLET_READONLY + " readonly before set ?", mockPortletPreferences.isReadOnly(PORTLET_READONLY));
+ assertFalse(PORTLET_READONLY2 + " readonly before set ?", mockPortletPreferences.isReadOnly(PORTLET_READONLY2));
+ mockPortletPreferences.setReadOnly(PORTLET_READONLY, true);
+ mockPortletPreferences.setReadOnly(PORTLET_READONLY2, true);
+ assertTrue(PORTLET_READONLY + " not readonly after set ?", mockPortletPreferences.isReadOnly(PORTLET_READONLY));
+ assertTrue(PORTLET_READONLY2 + " not readonly after set ?", mockPortletPreferences.isReadOnly(PORTLET_READONLY2));
+ mockPortletPreferences.setReadOnly(PORTLET_READONLY, false);
+ mockPortletPreferences.setReadOnly(PORTLET_READONLY2, false);
+ assertFalse(PORTLET_READONLY + " readonly after clear ?", mockPortletPreferences.isReadOnly(PORTLET_READONLY));
+ assertFalse(PORTLET_READONLY2 + " readonly after clear ?", mockPortletPreferences.isReadOnly(PORTLET_READONLY2));
+
+ try {
+ // Test initial set and replace
+ mockPortletPreferences.setValue(PORTLET_READONLY, PORTLET_READONLY_VALUE);
+ assertEquals("Set value mismatch ?", PORTLET_READONLY_VALUE, mockPortletPreferences.getValue(PORTLET_READONLY, null));
+ mockPortletPreferences.setValue(PORTLET_READONLY, PORTLET_READONLY_VALUE);
+ assertEquals("Set value mismatch ?", PORTLET_READONLY_VALUE, mockPortletPreferences.getValue(PORTLET_READONLY, null));
+ } catch (Exception ex) {
+ fail("Setvalue failed unexpectedly: " + ex);
+ }
+ try {
+ // Test initial set and replace
+ mockPortletPreferences.setValue(PORTLET_READONLY2, PORTLET_READONLY2_VALUE);
+ assertEquals("Set value mismatch ?", PORTLET_READONLY2_VALUE, mockPortletPreferences.getValue(PORTLET_READONLY2, null));
+ mockPortletPreferences.setValue(PORTLET_READONLY2, PORTLET_READONLY2_VALUE);
+ assertEquals("Set value mismatch ?", PORTLET_READONLY2_VALUE, mockPortletPreferences.getValue(PORTLET_READONLY2, null));
+ } catch (Exception ex) {
+ fail("Setvalue failed unexpectedly: " + ex);
+ }
+
+ mockPortletPreferences.setReadOnly(PORTLET_READONLY, true);
+ mockPortletPreferences.setReadOnly(PORTLET_READONLY2, true);
+ try {
+ // Test set of readonly value fails
+ mockPortletPreferences.setValue(PORTLET_READONLY, PORTLET_READONLY_VALUE);
+ fail("Setvalue worked unexpectedly for readonly value");
+ } catch (Exception ex) {
+ assertTrue("Unexpected exception type failure ? Ex: " + ex, ex instanceof ReadOnlyException);
+ assertTrue(PORTLET_READONLY + " is not readonly ?", mockPortletPreferences.isReadOnly(PORTLET_READONLY));
+ }
+ try {
+ // Test reset of readonly value fails
+ mockPortletPreferences.reset(PORTLET_READONLY);
+ fail("Reset worked unexpectedly for readonly value");
+ } catch (Exception ex) {
+ assertTrue("Unexpected exception type failure ? Ex: " + ex, ex instanceof ReadOnlyException);
+ assertTrue(PORTLET_READONLY + " is not readonly ?", mockPortletPreferences.isReadOnly(PORTLET_READONLY));
+ }
+ try {
+ // Test set of readonly value fails
+ mockPortletPreferences.setValue(PORTLET_READONLY2, PORTLET_READONLY2_VALUE);
+ fail("Setvalue worked unexpectedly for readonly value");
+ } catch (Exception ex) {
+ assertTrue("Unexpected exception type failure ? Ex: " + ex, ex instanceof ReadOnlyException);
+ assertTrue(PORTLET_READONLY2 + " is not readonly ?", mockPortletPreferences.isReadOnly(PORTLET_READONLY2));
+ }
+ try {
+ // Test reset of readonly value fails
+ mockPortletPreferences.reset(PORTLET_READONLY2);
+ fail("Reset worked unexpectedly for readonly value");
+ } catch (Exception ex) {
+ assertTrue("Unexpected exception type failure ? Ex: " + ex, ex instanceof ReadOnlyException);
+ assertTrue(PORTLET_READONLY2 + " is not readonly ?", mockPortletPreferences.isReadOnly(PORTLET_READONLY2));
+ }
+
+ try {
+ // Test initial set, get and reset
+ mockPortletPreferences.setValue(PORTLET_WRITEABLE, PORTLET_WRITEABLE_VALUE);
+ mockPortletPreferences.setValue(PORTLET_WRITEABLE2, PORTLET_WRITEABLE2_VALUE);
+ assertEquals("Set value mismatch ?", PORTLET_WRITEABLE_VALUE, mockPortletPreferences.getValue(PORTLET_WRITEABLE, null));
+ assertEquals("Set value mismatch ?", PORTLET_WRITEABLE2_VALUE, mockPortletPreferences.getValue(PORTLET_WRITEABLE2, null));
+ assertFalse(PORTLET_WRITEABLE + " is readonly ?", mockPortletPreferences.isReadOnly(PORTLET_WRITEABLE));
+ assertFalse(PORTLET_WRITEABLE2 + " is readonly ?", mockPortletPreferences.isReadOnly(PORTLET_WRITEABLE2));
+ mockPortletPreferences.reset(PORTLET_WRITEABLE);
+ mockPortletPreferences.reset(PORTLET_WRITEABLE2);
+ assertEquals("After reset getValue with null not null ?", null, mockPortletPreferences.getValue(PORTLET_WRITEABLE, null));
+ assertEquals("After reset getValue with null not null ?", null, mockPortletPreferences.getValue(PORTLET_WRITEABLE2, null));
+ } catch (Exception ex) {
+ fail("Set/Get/Reset failed unexpectedly: " + ex);
+ }
+
+ try {
+ // Test initial array set, get, names and map
+ mockPortletPreferences.setValues(PORTLET_WRITEABLE_ARRAY, PORTLET_WRITEABLE_ARRAY_VALUE);
+
+ assertEquals("Set values mismatch ?", PORTLET_WRITEABLE_ARRAY_VALUE, mockPortletPreferences.getValues(PORTLET_WRITEABLE_ARRAY, null));
+ assertFalse(PORTLET_WRITEABLE_ARRAY + " is readonly ?", mockPortletPreferences.isReadOnly(PORTLET_WRITEABLE_ARRAY));
+
+ // There should be two readonly attributes plus the array attribute present at this point
+ final Enumeration<String> preferencesNames = mockPortletPreferences.getNames();
+ assertNotNull("Preferences names null after additions ?", preferencesNames);
+ assertTrue("Preferences names empty after additions ?", preferencesNames.hasMoreElements());
+ int preferencesNameCount = 0;
+ while (preferencesNames.hasMoreElements()) {
+ preferencesNameCount++;
+ String currentPreferencesName = preferencesNames.nextElement();
+ assertTrue("Preferences name not one of three expected matches ?", PORTLET_WRITEABLE_ARRAY.equals(currentPreferencesName) ||
+ PORTLET_READONLY.equals(currentPreferencesName) ||
+ PORTLET_READONLY2.equals(currentPreferencesName));
+ }
+ assertEquals("Preferences names size not 3 ?", 3, preferencesNameCount);
+
+ final Map<String, String[]> preferencesMap = mockPortletPreferences.getMap();
+ assertNotNull("Preferences map null ?", preferencesMap);
+ assertEquals("Preferences map size not 3 ?", 3, preferencesMap.size());
+ assertTrue("Map does not contain expected key ?", preferencesMap.containsKey(PORTLET_WRITEABLE_ARRAY));
+ assertTrue("Map does not contain expected key ?", preferencesMap.containsKey(PORTLET_READONLY));
+ assertTrue("Map does not contain expected key ?", preferencesMap.containsKey(PORTLET_READONLY2));
+ assertTrue("Map does not contain expected value ?", preferencesMap.containsValue(PORTLET_WRITEABLE_ARRAY_VALUE));
+ assertTrue("Map does not contain expected value ?", preferencesMap.containsValue(mockPortletPreferences.getValues(PORTLET_READONLY, null)));
+ assertTrue("Map does not contain expected value ?", preferencesMap.containsValue(mockPortletPreferences.getValues(PORTLET_READONLY2, null)));
+ } catch (Exception ex) {
+ fail("Set/Get/Names/Map failed unexpectedly: " + ex);
+ }
+
+ // Verify store behaviour without validator present
+ try {
+ mockPortletPreferences.store();
+ } catch (Exception ex) {
+ fail("Store without validator failed ? Exception: " + ex);
+ }
+ // Verify store behaviour with validator present
+ try {
+ mockPortletPreferences.setPreferencesValidator(new BasicPreferencesValidator());
+ mockPortletPreferences.store();
+ fail("Basic validator did not prevent store as expected ?");
+ } catch (Exception ex) {
+ assertTrue("Basic validator did not produce UnsupportedOperationException ?", ex instanceof UnsupportedOperationException);
+ }
+ // Verify store behaviour after validator cleared
+ try {
+ mockPortletPreferences.setPreferencesValidator(null);
+ mockPortletPreferences.store();
+ } catch (Exception ex) {
+ fail("Store after clearing validator failed ? Exception: " + ex);
+ }
+ }
+
+ public void testMockPortletRequest() {
+ final String TEST_DEFAULT_CONTENT_TYPE = "text/html";
+ final String TEST_CONTENT_TYPE = "text/plain";
+ final String TEST_CONTENT_TYPE2 = "text/csv";
+ final String TEST_PROPERTY = "TEST_PROPERTY";
+ final String TEST_PROPERTY_VALUE = "Property_Value_1";
+ final String TEST_PROPERTY2 = "TEST_PROPERTY2";
+ final String TEST_PROPERTY2_VALUE = "Property_Value_2";
+ final String TEST_AUTHTYPE = "Test_Auth_Type";
+ final String TEST_FAKECONTEXTPATH = "/fakeContextPath";
+ final String TEST_FAKEREMOTEUSER = "fakeRemoteUser";
+ final String TEST_FAKEUSERROLE = "fakeUserRole";
+ final String TEST_ATTRIBUTE = "TEST_ATTRIBUTE";
+ final String TEST_ATTRIBUTE_VALUE = "Attribute_Value_1";
+ final String TEST_ATTRIBUTE2 = "TEST_ATTRIBUTE2";
+ final String TEST_ATTRIBUTE_VALUE2 = "Attribute_Value_2";
+ final String TEST_PARAM = "TEST_PARAM";
+ final String TEST_PARAM_VALUE = "Param_Value_1";
+ final String TEST_PARAM2 = "TEST_PARAM2";
+ final String TEST_PARAM_VALUE2 = "PARAM_Value_2";
+ final String TEST_ARRAYPARAM = "TEST_ARRAYPARAM";
+ final String[] TEST_PARAM_ARRAYVALUE = { "ARRAYVALUE1", "ARRAYVALUE2" };
+ final String TEST_SCHEME = "file";
+ final String TEST_HOST = "localhost2";
+ final int TEST_PORT = 8080;
+ final String TEST_WINDOWID = "TEST_WINDOWID";
+ final String TEST_COOKIE_ID = "TEST_COOKIE_ID";
+ final String TEST_COOKIE_ID2 = "TEST_COOKIE_ID2";
+ final String TEST_COOKIE_VALUE = "Cookie_Value";
+ final String TEST_COOKIE_VALUE2 = "Cookie_Value2";
+ final Cookie PORLET_TEST_COOKIE = new Cookie(TEST_COOKIE_ID, TEST_COOKIE_VALUE);
+ final Cookie PORLET_TEST_COOKIE2 = new Cookie(TEST_COOKIE_ID2, TEST_COOKIE_VALUE2);
+
+ // Call each constructor in sequence, do some basic checks
+ MockPortletRequest mockPortletRequest = new MockPortletRequest();
+ assertTrue("Default active state not true ?", mockPortletRequest.isActive());
+ assertEquals("Default portlet mode not as expected ?", PortletMode.VIEW, mockPortletRequest.getPortletMode());
+ assertEquals("Default window state not as expected ?", WindowState.NORMAL, mockPortletRequest.getWindowState());
+ assertNotNull("Default preferences is null ?", mockPortletRequest.getPreferences());
+ assertNotNull("Default portlet session is null ?", mockPortletRequest.getPortletSession());
+ assertNotNull("Default portal context is null ?", mockPortletRequest.getPortalContext());
+ assertEquals("Default context path not empty string ?", "", mockPortletRequest.getContextPath());
+ assertNull("Default remote user not null ?", mockPortletRequest.getRemoteUser());
+ assertNull("Default user principal not null ?", mockPortletRequest.getUserPrincipal());
+ assertFalse("Default secure state not false ?", mockPortletRequest.isSecure());
+ assertTrue("Default request sessionid not valid ?", mockPortletRequest.isRequestedSessionIdValid());
+ assertEquals("Default locale not as expected ?", Locale.ENGLISH, mockPortletRequest.getLocale());
+ assertEquals("Default response content-type not as expected ?", TEST_DEFAULT_CONTENT_TYPE, mockPortletRequest.getResponseContentType());
+ assertNull("Default lifecycle phase attribute not null ?", mockPortletRequest.getAttribute(PortletRequest.LIFECYCLE_PHASE));
+ assertEquals("Default scheme not as expected ?", "http", mockPortletRequest.getScheme());
+ assertEquals("Default server name not as expected ?", "localhost", mockPortletRequest.getServerName());
+ assertEquals("Default server port not as expected ?", 80, mockPortletRequest.getServerPort());
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ final MockPortletContext mockPortletContext = new MockPortletContext();
+ mockPortletRequest = new MockPortletRequest(mockPortletContext); // Only test is to confirm constructor completes without exception
+ mockPortletRequest = new MockPortletRequest(mockPortalContext, mockPortletContext);
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockPortletRequest.getPortalContext());
+ mockPortletRequest.addResponseContentType(TEST_CONTENT_TYPE);
+ mockPortletRequest.addResponseContentType(TEST_CONTENT_TYPE2);
+ Enumeration<String> contentTypes = mockPortletRequest.getResponseContentTypes();
+ assertNotNull("MockPortletRequest content-types null ?", contentTypes);
+ final ArrayList<String> contentTypesList = new ArrayList<>();
+ while (contentTypes.hasMoreElements()) {
+ contentTypesList.add(contentTypes.nextElement());
+ }
+ assertEquals("MockPortletRequest does not contain three content-types ?", 3, contentTypesList.size());
+ assertTrue("MockPortletRequest does not contain content-type " + TEST_CONTENT_TYPE + " ?", contentTypesList.contains(TEST_CONTENT_TYPE));
+ assertTrue("MockPortletRequest does not contain content-type " + TEST_CONTENT_TYPE2 + " ?", contentTypesList.contains(TEST_CONTENT_TYPE2));
+ assertTrue("MockPortletRequest does not contain default content-type + " + TEST_DEFAULT_CONTENT_TYPE + " ?", contentTypesList.contains(TEST_DEFAULT_CONTENT_TYPE));
+ assertTrue("View portlet mode not allowed ?", mockPortletRequest.isPortletModeAllowed(PortletMode.VIEW));
+ assertTrue("Edit portlet mode not allowed ?", mockPortletRequest.isPortletModeAllowed(PortletMode.EDIT));
+ assertTrue("Help portlet mode not allowed ?", mockPortletRequest.isPortletModeAllowed(PortletMode.HELP));
+ assertTrue("Normal window state not allowed ?", mockPortletRequest.isWindowStateAllowed(WindowState.NORMAL));
+ assertTrue("Maximized window state not allowed ?", mockPortletRequest.isWindowStateAllowed(WindowState.MAXIMIZED));
+ assertTrue("Minimized window state not allowed ?", mockPortletRequest.isWindowStateAllowed(WindowState.MINIMIZED));
+ mockPortletRequest.setPortletMode(PortletMode.EDIT);
+ assertEquals("Portlet mode does not match set value ?", PortletMode.EDIT, mockPortletRequest.getPortletMode());
+ mockPortletRequest.setWindowState(WindowState.MAXIMIZED);
+ assertEquals("Window state does not match set value ?", WindowState.MAXIMIZED, mockPortletRequest.getWindowState());
+ final MockPortletPreferences mockPortletPreferences = new MockPortletPreferences();
+ mockPortletRequest.setPreferences(mockPortletPreferences);
+ assertEquals("Portlet preferences does not match set value ?", mockPortletPreferences, mockPortletRequest.getPreferences());
+ final MockPortletSession mockPortletSession = new MockPortletSession(mockPortletContext);
+ mockPortletRequest.setSession(mockPortletSession);
+ assertEquals("Portlet session does not match set value ?", mockPortletSession, mockPortletRequest.getPortletSession());
+ assertTrue("Set request sessionid not valid ?", mockPortletRequest.isRequestedSessionIdValid());
+ mockPortletRequest.setRequestedSessionIdValid(false);
+ assertFalse("Set request sessionid still valid after set invalid ?", mockPortletRequest.isRequestedSessionIdValid());
+ mockPortletRequest.setRequestedSessionIdValid(true);
+ assertTrue("Set request sessionid not valid after set valid ?", mockPortletRequest.isRequestedSessionIdValid());
+
+ mockPortletRequest.setProperty(TEST_PROPERTY, TEST_PROPERTY_VALUE);
+ mockPortletRequest.setProperty(TEST_PROPERTY2, TEST_PROPERTY2_VALUE);
+ final Enumeration<String> propertyNames = mockPortletRequest.getPropertyNames();
+ assertNotNull("MockPortalContext property names null ?", propertyNames);
+ final ArrayList<String> propertyNamesList = new ArrayList<>();
+ while (propertyNames.hasMoreElements()) {
+ propertyNamesList.add(propertyNames.nextElement());
+ }
+ assertEquals("MockPortletRequest does not contain two properties ?", 2, propertyNamesList.size());
+ assertTrue("MockPortletRequest does not contain property name " + TEST_PROPERTY + " ?", propertyNamesList.contains(TEST_PROPERTY));
+ assertTrue("MockPortletRequest does not contain property name " + TEST_PROPERTY2 + " ?", propertyNamesList.contains(TEST_PROPERTY2));
+ assertEquals("MockPortletRequest value of property name " + TEST_PROPERTY + " not as expected ?", TEST_PROPERTY_VALUE, mockPortletRequest.getProperty(TEST_PROPERTY));
+ assertEquals("MockPortletRequest value of property name " + TEST_PROPERTY2 + " not as expected ?", TEST_PROPERTY2_VALUE, mockPortletRequest.getProperty(TEST_PROPERTY2));
+ mockPortletRequest.addProperty(TEST_PROPERTY, TEST_PROPERTY2_VALUE);
+ final Enumeration<String> propertiesForName = mockPortletRequest.getProperties(TEST_PROPERTY);
+ assertNotNull("MockPortletRequest properties for " + TEST_PROPERTY + " is null ?", propertiesForName);
+ final ArrayList<String> propertiesForNameList = new ArrayList<>();
+ while (propertiesForName.hasMoreElements()) {
+ propertiesForNameList.add(propertiesForName.nextElement());
+ }
+ assertEquals("MockPortletRequest does not contain two values for " + TEST_PROPERTY + " ?", 2, propertiesForNameList.size());
+ assertTrue("MockPortletRequest does not contain expected value for property name " + TEST_PROPERTY + " ?", propertiesForNameList.contains(TEST_PROPERTY_VALUE));
+ assertTrue("MockPortletRequest does not contain expected value for propety name " + TEST_PROPERTY + " ?", propertiesForNameList.contains(TEST_PROPERTY2_VALUE));
+
+ mockPortletRequest.setAuthType(TEST_AUTHTYPE);
+ assertEquals("Authtype not equal to set value ?", TEST_AUTHTYPE, mockPortletRequest.getAuthType());
+ mockPortletRequest.setContextPath(TEST_FAKECONTEXTPATH);
+ assertEquals("Context path not equal to set value ?", TEST_FAKECONTEXTPATH, mockPortletRequest.getContextPath());
+ mockPortletRequest.setRemoteUser(TEST_FAKEREMOTEUSER);
+ assertEquals("Remote user not equal to set value ?", TEST_FAKEREMOTEUSER, mockPortletRequest.getRemoteUser());
+ final TestMockPrincipal testMockPrincipal = new TestMockPrincipal();
+ mockPortletRequest.setUserPrincipal(testMockPrincipal);
+ assertEquals("User principal not equal to set value ?", testMockPrincipal, mockPortletRequest.getUserPrincipal());
+ mockPortletRequest.addUserRole(TEST_FAKEUSERROLE);
+ assertTrue("Usser not in added role ?", mockPortletRequest.isUserInRole(TEST_FAKEUSERROLE));
+
+ assertNull(TEST_PARAM + " present before set ?", mockPortletRequest.getParameter(TEST_PARAM));
+ assertNull(TEST_PARAM2 + " present before set ?", mockPortletRequest.getParameter(TEST_PARAM));
+ mockPortletRequest.addParameter(TEST_PARAM, TEST_PARAM_VALUE);
+ mockPortletRequest.addParameter(TEST_PARAM2, TEST_PARAM_VALUE2);
+ assertEquals("Retrieved parameter 1 does not match set value ?", TEST_PARAM_VALUE, mockPortletRequest.getParameter(TEST_PARAM));
+ assertEquals("Retrieved parameter 2 does not match set value ?", TEST_PARAM_VALUE2, mockPortletRequest.getParameter(TEST_PARAM2));
+ final Enumeration<String> parameterNames = mockPortletRequest.getParameterNames();
+ int parameterNameCount = 0;
+ assertNotNull("Parameter names null after additions ?", parameterNames);
+ assertTrue("Parameter names empty after additions ?", parameterNames.hasMoreElements());
+ while (parameterNames.hasMoreElements()) {
+ parameterNameCount++;
+ String currentParameterName = parameterNames.nextElement();
+ assertTrue("Param name not one of two expected matches ?", TEST_PARAM.equals(currentParameterName) ||
+ TEST_PARAM2.equals(currentParameterName));
+ }
+ assertEquals("Parameter names size not 2 ?", 2, parameterNameCount);
+ mockPortletRequest.addParameter(TEST_ARRAYPARAM, TEST_PARAM_ARRAYVALUE);
+ assertTrue("Array parameter value not set as expected ?", Arrays.equals(TEST_PARAM_ARRAYVALUE, mockPortletRequest.getParameterValues(TEST_ARRAYPARAM)));
+ final Map<String, String[]> parameterMap = mockPortletRequest.getParameterMap();
+ assertNotNull("Parameter map is null ?", parameterMap);
+ assertTrue("Expected parameter not present ?", parameterMap.containsKey(TEST_PARAM));
+ assertTrue("Expected parameter not present ?", parameterMap.containsKey(TEST_PARAM2));
+ assertTrue("Expected parameter not present ?", parameterMap.containsKey(TEST_ARRAYPARAM));
+
+ assertNull(TEST_ATTRIBUTE + " present before set ?", mockPortletRequest.getAttribute(TEST_ATTRIBUTE));
+ assertNull(TEST_ATTRIBUTE2 + " present before set ?", mockPortletRequest.getAttribute(TEST_ATTRIBUTE2));
+ mockPortletRequest.setAttribute(TEST_ATTRIBUTE, TEST_ATTRIBUTE_VALUE);
+ mockPortletRequest.setAttribute(TEST_ATTRIBUTE2, TEST_ATTRIBUTE_VALUE2);
+ assertEquals("Retrieved atribute 1 does not match set value ?", TEST_ATTRIBUTE_VALUE, mockPortletRequest.getAttribute(TEST_ATTRIBUTE));
+ assertEquals("Retrieved atribute 2 does not match set value ?", TEST_ATTRIBUTE_VALUE2, mockPortletRequest.getAttribute(TEST_ATTRIBUTE2));
+ final Enumeration<String> attributeNames = mockPortletRequest.getAttributeNames();
+ int attributeNameCount = 0;
+ assertNotNull("Attribute names null after additions ?", attributeNames);
+ assertTrue("Attribute names empty after additions ?", attributeNames.hasMoreElements());
+ while (attributeNames.hasMoreElements()) {
+ attributeNameCount++;
+ String currentAttibuteName = attributeNames.nextElement();
+ assertTrue("Attribute name not one of two or three expected matches ?", TEST_ATTRIBUTE.equals(currentAttibuteName) ||
+ TEST_ATTRIBUTE2.equals(currentAttibuteName) ||
+ PortletRequest.LIFECYCLE_PHASE.equals(currentAttibuteName));
+ }
+ assertTrue("Atribute names size not 2 or 3 ?", attributeNameCount >= 2 && attributeNameCount <= 3);
+
+ mockPortletRequest.addPreferredLocale(Locale.FRENCH);
+ assertEquals("Preferred locale not as expected ?", Locale.FRENCH, mockPortletRequest.getLocale());
+ final Enumeration<Locale> locales = mockPortletRequest.getLocales();
+ assertNotNull("Locales null after additions ?", locales);
+ assertTrue("Locales names empty after additions ?", locales.hasMoreElements());
+ final Locale firstLocale = locales.nextElement();
+ assertEquals("First locale not set value ?", Locale.FRENCH, firstLocale);
+ final Locale secondLocale = locales.nextElement();
+ assertEquals("Second locale not default value ?", Locale.ENGLISH, secondLocale);
+ mockPortletRequest.setScheme(TEST_SCHEME);
+ assertEquals("Scheme not equal to set value ?", TEST_SCHEME, mockPortletRequest.getScheme());
+ mockPortletRequest.setServerName(TEST_HOST);
+ assertEquals("Server name not equal to set value ?", TEST_HOST, mockPortletRequest.getServerName());
+ mockPortletRequest.setServerPort(TEST_PORT);
+ assertEquals("Server port not equal to set value ?", TEST_PORT, mockPortletRequest.getServerPort());
+ mockPortletRequest.setWindowID(TEST_WINDOWID);
+ assertEquals("Window id not equal to set value ?", TEST_WINDOWID, mockPortletRequest.getWindowID());
+
+ mockPortletRequest.setCookies(PORLET_TEST_COOKIE, PORLET_TEST_COOKIE2);
+ final Cookie[] cookies = mockPortletRequest.getCookies();
+ assertNotNull("Cookies array null ?", cookies);
+ assertEquals("Cookies array length not 2 ?", 2, cookies.length);
+ for (Cookie cookie : cookies) {
+ assertTrue("Cookie not one of set cookies ?", PORLET_TEST_COOKIE.equals(cookie) || PORLET_TEST_COOKIE2.equals(cookie));
+ }
+
+ final Map<String, String[]> originalPrivateParameters = mockPortletRequest.getPrivateParameterMap();
+ final Map<String, String[]> originalPublicParameters = mockPortletRequest.getPublicParameterMap();
+ assertNotNull("Original private parameters map is null ?", originalPrivateParameters);
+ assertFalse("Original private parameters map is empty ?", originalPrivateParameters.isEmpty());
+ assertTrue("Original private parameters map does not contain " + TEST_PARAM + " ?", originalPrivateParameters.containsKey(TEST_PARAM));
+ assertTrue("Original private parameters map does not contain " + TEST_PARAM2 + " ?", originalPrivateParameters.containsKey(TEST_PARAM2));
+ assertNotNull("Original public parameters map is null ?", originalPublicParameters);
+ assertTrue("Original public parameters map is not empty ?", originalPublicParameters.isEmpty());
+ mockPortletRequest.registerPublicParameter(TEST_PARAM2);
+ final Map<String, String[]> updatedPrivateParameters = mockPortletRequest.getPrivateParameterMap();
+ final Map<String, String[]> updatedPublicParameters = mockPortletRequest.getPublicParameterMap();
+ assertNotNull("Updated private parameters map is null ?", updatedPrivateParameters);
+ assertFalse("Updated private parameters map is empty ?", updatedPrivateParameters.isEmpty());
+ assertFalse("Updated private parameters map contains " + TEST_PARAM2 + " ?", updatedPrivateParameters.containsKey(TEST_PARAM2));
+ assertTrue("Updated private parameters map does not contain " + TEST_PARAM + " ?", updatedPrivateParameters.containsKey(TEST_PARAM));
+ assertNotNull("Updated public parameters map is null ?", updatedPublicParameters);
+ assertFalse("Updated public parameters map is empty ?", updatedPublicParameters.isEmpty());
+ assertFalse("Updated public parameters map contains " + TEST_PARAM + " ?", updatedPublicParameters.containsKey(TEST_PARAM));
+ assertTrue("Updated public parameters map does not contain " + TEST_PARAM2 + " ?", updatedPublicParameters.containsKey(TEST_PARAM2));
+ }
+
+ public void testMockPortletRequestDispatcher() {
+ final String TEST_DISPATCH_URL = "localhost:8080/fakeurl";
+
+ // Call each constructor in sequence, do some basic checks
+ MockPortletRequestDispatcher mockPortletRequestDispatcher = new MockPortletRequestDispatcher(TEST_DISPATCH_URL);
+ final MockRenderRequest mockRenderRequest = new MockRenderRequest();
+ final MockRenderResponse mockRenderResponse = new MockRenderResponse();
+ try {
+ mockPortletRequestDispatcher.include(mockRenderRequest, mockRenderResponse);
+ } catch (Exception ex) {
+ fail("MockPortletRequestDispatcher include (render) failed. Exception: " + ex);
+ }
+ final MockPortletRequest mockPortletRequest = new MockPortletRequest();
+ final MockPortletResponse mockPortletResponse = new MockPortletResponse();
+ final MockMimeResponse mockMimeResponse = new MockMimeResponse();
+ try {
+ mockPortletRequestDispatcher.include(mockPortletRequest, mockPortletResponse);
+ fail("Include of non-MockMimeResponse did not throw an exception ?");
+ } catch (IllegalArgumentException iae) {
+ // Expected failure
+ } catch (Exception ex) {
+ fail("MockPortletRequestDispatcher include (portlet) failed. Exception: " + ex);
+ }
+ try {
+ mockPortletRequestDispatcher.include(mockPortletRequest, mockMimeResponse);
+ } catch (Exception ex) {
+ fail("MockPortletRequestDispatcher include (portlet) failed. Exception: " + ex);
+ }
+ try {
+ mockPortletRequestDispatcher.forward(mockPortletRequest, mockPortletResponse);
+ fail("Forward of non-MockMimeResponse did not throw an exception ?");
+ } catch (IllegalArgumentException iae) {
+ // Expected failure
+ } catch (Exception ex) {
+ fail("MockPortletRequestDispatcher forward failed. Exception: " + ex);
+ }
+ try {
+ mockPortletRequestDispatcher.forward(mockPortletRequest, mockMimeResponse);
+ } catch (Exception ex) {
+ fail("MockPortletRequestDispatcher forward failed. Exception: " + ex);
+ }
+ }
+
+ public void testMockPortletResponse() {
+ final String TEST_ENCODE_URL = "localhost:8080/fakeforwardedurl?param1=param with spaces";
+ final String TEST_NAMESPACE = "Test_Namespace";
+ final String TEST_PROPERTY = "TEST_PROPERTY";
+ final String TEST_PROPERTY_VALUE = "Property_Value_1";
+ final String TEST_PROPERTY2 = "TEST_PROPERTY2";
+ final String TEST_PROPERTY2_VALUE = "Property_Value_2";
+ final String TEST_XMLPROPERTY = "TEST_XMLPROPERTY";
+ final String TEST_XML_TAGNAME = "TEST_XML_TAGNAME";
+ final String TEST_COOKIE_ID = "TEST_COOKIE_ID";
+
+ // Call each constructor in sequence, do some basic checks
+ MockPortletResponse mockPortletResponse = new MockPortletResponse();
+ assertEquals("Default namespace not as expected ?", "", mockPortletResponse.getNamespace());
+ assertNotNull("Default portal context null ?", mockPortletResponse.getPortalContext());
+ assertEquals("Encoded URL not as expected ?", TEST_ENCODE_URL, mockPortletResponse.encodeURL(TEST_ENCODE_URL)); // Mock URL encode does nothing
+ mockPortletResponse.setNamespace(TEST_NAMESPACE);
+ assertEquals("Set namespace not as expected ?", TEST_NAMESPACE, mockPortletResponse.getNamespace());
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ mockPortletResponse = new MockPortletResponse(mockPortalContext);
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockPortletResponse.getPortalContext());
+
+ mockPortletResponse.setProperty(TEST_PROPERTY, TEST_PROPERTY_VALUE);
+ mockPortletResponse.setProperty(TEST_PROPERTY2, TEST_PROPERTY2_VALUE);
+ final Set<String> propertyNames = mockPortletResponse.getPropertyNames();
+ assertNotNull("MockPortletResponse property names null ?", propertyNames);
+ assertEquals("MockPortletResponse does not contain two properties ?", 2, propertyNames.size());
+ assertTrue("MockPortletResponse does not contain property name " + TEST_PROPERTY + " ?", propertyNames.contains(TEST_PROPERTY));
+ assertTrue("MockPortletResponse does not contain property name " + TEST_PROPERTY2 + " ?", propertyNames.contains(TEST_PROPERTY2));
+ assertEquals("MockPortletResponse value of property name " + TEST_PROPERTY + " not as expected ?", TEST_PROPERTY_VALUE, mockPortletResponse.getProperty(TEST_PROPERTY));
+ assertEquals("MockPortletResponse value of property name " + TEST_PROPERTY2 + " not as expected ?", TEST_PROPERTY2_VALUE, mockPortletResponse.getProperty(TEST_PROPERTY2));
+ mockPortletResponse.addProperty(TEST_PROPERTY, TEST_PROPERTY2_VALUE);
+ final String[] propertiesForName = mockPortletResponse.getProperties(TEST_PROPERTY);
+ assertNotNull("MockPortletResponse properties for " + TEST_PROPERTY + " is null ?", propertiesForName);
+ final ArrayList<String> propertiesForNameList = new ArrayList<>();
+ propertiesForNameList.addAll(Arrays.asList(propertiesForName));
+ assertEquals("MockPortletResponse does not contain two values for " + TEST_PROPERTY + " ?", 2, propertiesForNameList.size());
+ assertTrue("MockPortletResponse does not contain expected value for property name " + TEST_PROPERTY + " ?", propertiesForNameList.contains(TEST_PROPERTY_VALUE));
+ assertTrue("MockPortletResponse does not contain expected value for propety name " + TEST_PROPERTY + " ?", propertiesForNameList.contains(TEST_PROPERTY2_VALUE));
+
+ final Cookie[] cookies = mockPortletResponse.getCookies();
+ assertNotNull("Cookies array null ?", cookies);
+ assertEquals("Cookies array length not 0 ?", 0, cookies.length);
+ assertNull("Cookie found ?", mockPortletResponse.getCookie(TEST_COOKIE_ID));
+
+ Set<String> xmlPropertyNames = mockPortletResponse.getXmlPropertyNames();
+ assertNotNull("MockPortletResponse XML property names null ?", xmlPropertyNames);
+ assertTrue("XML properites set not empty ?", xmlPropertyNames.isEmpty());
+ assertNull("XML property found ?", mockPortletResponse.getXmlProperty(TEST_XMLPROPERTY));
+ Element[] xmlProperties = mockPortletResponse.getXmlProperties(TEST_XMLPROPERTY);
+ assertNull("XML properties found ?", xmlProperties);
+ Element element = mockPortletResponse.createElement(TEST_XML_TAGNAME);
+ assertNotNull("MockPortletResponse XML element null ?", element);
+ mockPortletResponse.addProperty(TEST_XMLPROPERTY, element);
+ xmlPropertyNames = mockPortletResponse.getXmlPropertyNames();
+ assertNotNull("MockPortletResponse XML property names null ?", xmlPropertyNames);
+ assertFalse("XML properites set empty ?", xmlPropertyNames.isEmpty());
+ assertNotNull("XML property not found ?", mockPortletResponse.getXmlProperty(TEST_XMLPROPERTY));
+ xmlProperties = mockPortletResponse.getXmlProperties(TEST_XMLPROPERTY);
+ assertNotNull("XML properties not found ?", xmlProperties);
+ assertEquals("XML properties not expected size ?", 1, xmlProperties.length);
+ assertEquals("XML property at index 0 not element value ?", element, xmlProperties[0]);
+ }
+
+ public void testMockPortletSession() {
+ final String TEST_ATTRIBUTE = "TEST_ATTRIBUTE";
+ final String TEST_ATTRIBUTE_VALUE = "Attribute_Value_1";
+ final String TEST_ATTRIBUTE2 = "TEST_ATTRIBUTE2";
+ final String TEST_ATTRIBUTE_VALUE2 = "Attribute_Value_2";
+ final long TEST_START_TIME = System.currentTimeMillis();
+ final int TEST_MAXINACTIVE_INTERVAL = 300;
+
+ // Call each constructor in sequence, do some basic checks
+ MockPortletSession mockPortletSession = new MockPortletSession();
+ final String INITIAL_SESSION_ID = mockPortletSession.getId();
+ assertNotNull("MockPortletSession session id null ?", INITIAL_SESSION_ID);
+ assertFalse("MockPortletSession session is invalid ?", mockPortletSession.isInvalid());
+ assertTrue("MockPortletSession session is not new ?", mockPortletSession.isNew());
+ mockPortletSession.setNew(false);
+ assertFalse("MockPortletSession session is still new ?", mockPortletSession.isNew());
+ mockPortletSession.setNew(true);
+ assertTrue("MockPortletSession session is not new after set ?", mockPortletSession.isNew());
+ assertEquals("MockPortletSession max inactive interval not 0 ?", 0, mockPortletSession.getMaxInactiveInterval());
+ assertNotNull("Default portlet context null ?", mockPortletSession.getPortletContext());
+ assertTrue("MockPortletSession session creation time in past ?", mockPortletSession.getCreationTime() >= TEST_START_TIME);
+ assertTrue("MockPortletSession session last accessed time in past ?", mockPortletSession.getLastAccessedTime() >= TEST_START_TIME);
+ assertTrue("MockPortletSession session last accessed time older than creation time ?", mockPortletSession.getLastAccessedTime() >= mockPortletSession.getCreationTime());
+ assertNotNull("Default portlet attribute map null ?", mockPortletSession.getAttributeMap());
+ assertNotNull("Default portlet portletscope attribute map null ?", mockPortletSession.getAttributeMap(PortletSession.PORTLET_SCOPE));
+ assertNotNull("Default portlet applicationscope attribute map null ?", mockPortletSession.getAttributeMap(PortletSession.APPLICATION_SCOPE));
+ final MockPortletContext mockPortletContext = new MockPortletContext();
+ mockPortletSession = new MockPortletSession(mockPortletContext);
+ assertEquals("MockPortletSession portletcontext not equal to set value ?", mockPortletContext, mockPortletSession.getPortletContext());
+ final String NEW_SESSION_ID = mockPortletSession.getId();
+ assertNotNull("MockPortletSession session id null ?", NEW_SESSION_ID);
+ assertFalse("Original and new session id match ?", NEW_SESSION_ID.equals(INITIAL_SESSION_ID));
+
+ assertNull(TEST_ATTRIBUTE + " present before set ?", mockPortletSession.getAttribute(TEST_ATTRIBUTE));
+ assertNull(TEST_ATTRIBUTE2 + " present before set ?", mockPortletSession.getAttribute(TEST_ATTRIBUTE2));
+ mockPortletSession.setAttribute(TEST_ATTRIBUTE, TEST_ATTRIBUTE_VALUE);
+ mockPortletSession.setAttribute(TEST_ATTRIBUTE2, TEST_ATTRIBUTE_VALUE2);
+ assertEquals("Retrieved atribute 1 does not match set value ?", TEST_ATTRIBUTE_VALUE, mockPortletSession.getAttribute(TEST_ATTRIBUTE));
+ assertEquals("Retrieved atribute 2 does not match set value ?", TEST_ATTRIBUTE_VALUE2, mockPortletSession.getAttribute(TEST_ATTRIBUTE2));
+ final Enumeration<String> attributeNames = mockPortletSession.getAttributeNames();
+ int attributeNameCount = 0;
+ assertNotNull("Attribute names null after additions ?", attributeNames);
+ assertTrue("Attribute names empty after additions ?", attributeNames.hasMoreElements());
+ while (attributeNames.hasMoreElements()) {
+ attributeNameCount++;
+ String currentAttibuteName = attributeNames.nextElement();
+ assertTrue("Attribute name not one of two expected matches ?", TEST_ATTRIBUTE.equals(currentAttibuteName) ||
+ TEST_ATTRIBUTE2.equals(currentAttibuteName));
+ }
+ assertEquals("Atribute names size not expected value ?", 2, attributeNameCount);
+ assertNull(TEST_ATTRIBUTE + " present before set (application scope) ?", mockPortletSession.getAttribute(TEST_ATTRIBUTE, PortletSession.APPLICATION_SCOPE));
+ assertNull(TEST_ATTRIBUTE2 + " present before set (application scope) ?", mockPortletSession.getAttribute(TEST_ATTRIBUTE2, PortletSession.APPLICATION_SCOPE));
+ mockPortletSession.setAttribute(TEST_ATTRIBUTE, TEST_ATTRIBUTE_VALUE, PortletSession.APPLICATION_SCOPE);
+ mockPortletSession.setAttribute(TEST_ATTRIBUTE2, TEST_ATTRIBUTE_VALUE2, PortletSession.APPLICATION_SCOPE);
+ assertEquals("Retrieved atribute 1 does not match set value (application scope) ?", TEST_ATTRIBUTE_VALUE, mockPortletSession.getAttribute(TEST_ATTRIBUTE, PortletSession.APPLICATION_SCOPE));
+ assertEquals("Retrieved atribute 2 does not match set value (application scope) ?", TEST_ATTRIBUTE_VALUE2, mockPortletSession.getAttribute(TEST_ATTRIBUTE2, PortletSession.APPLICATION_SCOPE));
+ final Enumeration<String> attributeNamesApplication = mockPortletSession.getAttributeNames(PortletSession.APPLICATION_SCOPE);
+ int attributeNameCountApplication = 0;
+ assertNotNull("Attribute names null after additions (application scope) ?", attributeNamesApplication);
+ assertTrue("Attribute names empty after additions (application scope) ?", attributeNamesApplication.hasMoreElements());
+ while (attributeNamesApplication.hasMoreElements()) {
+ attributeNameCountApplication++;
+ String currentAttibuteName = attributeNamesApplication.nextElement();
+ assertTrue("Attribute name not one of two expected matches (application scope) ?", TEST_ATTRIBUTE.equals(currentAttibuteName) ||
+ TEST_ATTRIBUTE2.equals(currentAttibuteName));
+ }
+ assertEquals("Atribute names size not expected value (application scope) ?", 2, attributeNameCount);
+
+ assertTrue("MockPortletSession session is not new ?", mockPortletSession.isNew());
+ mockPortletSession.access();
+ assertFalse("MockPortletSession session is still new after access ?", mockPortletSession.isNew());
+ mockPortletSession.setMaxInactiveInterval(TEST_MAXINACTIVE_INTERVAL);
+ assertEquals("MockPortletSession max inactive interval not set value ?", TEST_MAXINACTIVE_INTERVAL, mockPortletSession.getMaxInactiveInterval());
+ mockPortletSession.removeAttribute(TEST_ATTRIBUTE2);
+ assertNull(TEST_ATTRIBUTE2 + " still present after removal ?", mockPortletSession.getAttribute(TEST_ATTRIBUTE2));
+ mockPortletSession.removeAttribute(TEST_ATTRIBUTE, PortletSession.APPLICATION_SCOPE);
+ assertNull(TEST_ATTRIBUTE + " still present after removal (application scope) ?", mockPortletSession.getAttribute(TEST_ATTRIBUTE, PortletSession.APPLICATION_SCOPE));
+ final long BEFORE_INVALIDATE_TIME = System.currentTimeMillis();
+ mockPortletSession.invalidate();
+ assertTrue("MockPortletSession session is still valid after invalidate ?", mockPortletSession.isInvalid());
+ assertNull(TEST_ATTRIBUTE + " still present after invalidate ?", mockPortletSession.getAttribute(TEST_ATTRIBUTE));
+ assertNull(TEST_ATTRIBUTE2 + " still present after removal (application scope) ?", mockPortletSession.getAttribute(TEST_ATTRIBUTE2, PortletSession.APPLICATION_SCOPE));
+ assertTrue("MockPortletSession session last accessed time older than creation time ?", mockPortletSession.getLastAccessedTime() >= mockPortletSession.getCreationTime());
+ assertTrue("MockPortletSession session last accessed time older than time before invalidation ?", mockPortletSession.getLastAccessedTime() >= BEFORE_INVALIDATE_TIME);
+ }
+
+ public void testMockPortletURL() {
+ final String TEST_PARAMETER = "TEST_PARAMETER";
+
+ // Call each constructor in sequence, do some basic checks
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ final MockPortletURL mockPortletURL = new MockPortletURL(mockPortalContext, MockPortletURL.URL_TYPE_RENDER);
+ assertNull("MockPortletURL default portlet mode not null ?", mockPortletURL.getPortletMode());
+ assertNull("MockPortletURL default window state not null ?", mockPortletURL.getWindowState());
+ try {
+ mockPortletURL.setWindowState(WindowState.MAXIMIZED);
+ } catch (Exception ex) {
+ fail("MockPortletURL window state set failed. Exception: " + ex);
+ }
+ assertEquals("Window state does not match set value ?", WindowState.MAXIMIZED, mockPortletURL.getWindowState());
+ try {
+ mockPortletURL.setPortletMode(PortletMode.VIEW);
+ } catch (Exception ex) {
+ fail("MockPortletURL portlet mode set failed. Exception: " + ex);
+ }
+ assertEquals("PortletMode.VIEW not set ?", PortletMode.VIEW, mockPortletURL.getPortletMode());
+ final String portletURLAsString = mockPortletURL.toString();
+ assertNotNull("MockPortletURL toString() result null ?", portletURLAsString);
+ assertTrue("MockPortletURL toString() result is empty ?", portletURLAsString.length() > 0);
+ mockPortletURL.removePublicRenderParameter(TEST_PARAMETER); // Just confirm no exception
+ }
+
+ public void testMockRenderRequest() {
+ final MockPortletContext mockPortletContext = new MockPortletContext();
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+
+ // Call each constructor in sequence, do some basic checks
+ MockRenderRequest mockRenderRequest = new MockRenderRequest();
+ assertNull("MockRenderRequest ETag not null ?", mockRenderRequest.getETag());
+ mockRenderRequest = new MockRenderRequest(PortletMode.HELP);
+ assertEquals("MockRenderRequest portlet mode does not match constructor-set value ?", PortletMode.HELP, mockRenderRequest.getPortletMode());
+ mockRenderRequest = new MockRenderRequest(PortletMode.HELP, WindowState.MAXIMIZED);
+ assertEquals("MockRenderRequest portlet mode does not match constructor-set value ?", PortletMode.HELP, mockRenderRequest.getPortletMode());
+ assertEquals("MockRenderRequest window state does not match constructor-set value ?", WindowState.MAXIMIZED, mockRenderRequest.getWindowState());
+ mockRenderRequest = new MockRenderRequest(mockPortletContext); // Only test is to confirm constructor completes without exception
+ mockRenderRequest = new MockRenderRequest(mockPortalContext, mockPortletContext);
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockRenderRequest.getPortalContext());
+ }
+
+ public void testMockRenderResponse() {
+ final String TEST_TITLE = "TEST_TITLE";
+
+ // Call each constructor in sequence, do some basic checks
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ final MockRenderRequest mockRenderRequest = new MockRenderRequest();
+ MockRenderResponse mockRenderResponse = new MockRenderResponse();
+ assertNull("MockRenderResponse title not null ?", mockRenderResponse.getTitle());
+ mockRenderResponse = new MockRenderResponse(mockPortalContext); // Only test is to confirm constructor completes without exception
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockRenderResponse.getPortalContext());
+ mockRenderResponse = new MockRenderResponse(mockPortalContext, mockRenderRequest);
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockRenderResponse.getPortalContext());
+ mockRenderResponse.setTitle(TEST_TITLE);
+ assertEquals("Title does not match set value ?", TEST_TITLE, mockRenderResponse.getTitle());
+ final Collection<PortletMode> portletModes = new ArrayList<>();
+ portletModes.add(PortletMode.EDIT);
+ portletModes.add(PortletMode.VIEW);
+ mockRenderResponse.setNextPossiblePortletModes(portletModes);
+ assertEquals("Next possible portlet modes not equal to set value ?", portletModes, mockRenderResponse.getNextPossiblePortletModes());
+ }
+
+ public void testMockResourceRequest() {
+ final String TEST_RESOURCEID = "TEST_RESOURCEID";
+ final String TEST_CACHEABILITY = "TEST_CACHEABILITY";
+ final String TEST_PARAM = "TEST_PARAM";
+ final String TEST_PARAM2 = "TEST_PARAM2";
+ final String TEST_PARAM_VALUE = "NORMALVALUE";
+ final String[] TEST_PARAM_ARRAYVALUE = { "ARRAYVALUE1", "ARRAYVALUE2" };
+
+ // Call each constructor in sequence, do some basic checks
+ MockResourceRequest mockResourceRequest = new MockResourceRequest();
+ assertNull("Default resource id not null ?", mockResourceRequest.getResourceID());
+ assertNull("Default cacheability not null ?", mockResourceRequest.getCacheability());
+ assertNull("Default ETag not null ?", mockResourceRequest.getETag());
+ mockResourceRequest = new MockResourceRequest(TEST_RESOURCEID);
+ assertEquals("Resource id not set value ?", TEST_RESOURCEID, mockResourceRequest.getResourceID());
+ final MockPortletContext mockPortletContext = new MockPortletContext();
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ final MockResourceURL mockResourceURL = new MockResourceURL();
+ mockResourceRequest = new MockResourceRequest(mockResourceURL); // Only test is to confirm constructor completes without exception
+ mockResourceRequest = new MockResourceRequest(mockPortletContext); // Only test is to confirm constructor completes without exception
+ mockResourceRequest = new MockResourceRequest(mockPortalContext, mockPortletContext);
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockResourceRequest.getPortalContext());
+ mockResourceRequest.setCacheability(TEST_CACHEABILITY);
+ assertEquals("Cacheability does not match set value ?", TEST_CACHEABILITY, mockResourceRequest.getCacheability());
+ mockResourceRequest.addPrivateRenderParameter(TEST_PARAM, TEST_PARAM_VALUE);
+ mockResourceRequest.addPrivateRenderParameter(TEST_PARAM2, TEST_PARAM_ARRAYVALUE);
+ final Map<String, String[]> privateRenderParameterMap = mockResourceRequest.getPrivateRenderParameterMap();
+ assertNotNull("Parameter map is null ?", privateRenderParameterMap);
+ assertTrue("Expected parameter not present ?", privateRenderParameterMap.containsKey(TEST_PARAM));
+ assertTrue("Expected parameter not present ?", privateRenderParameterMap.containsKey(TEST_PARAM2));
+ }
+
+ public void testMockResourceResponse() {
+ final int TEST_CONTENT_LENGTH = 4096;
+
+ // Call each constructor in sequence, do some basic checks
+ MockResourceResponse mockResourceRequest = new MockResourceResponse();
+ assertEquals("MockResourceResponse initial content length not 0 ?", 0, mockResourceRequest.getContentLength());
+ mockResourceRequest.setContentLength(TEST_CONTENT_LENGTH);
+ assertEquals("Content length not equal to set value ?", TEST_CONTENT_LENGTH, mockResourceRequest.getContentLength());
+ }
+
+ public void testMockResourceURL() {
+ final String TEST_RESOURCEID = "TEST_RESOURCEID";
+ final String TEST_CACHEABILITY = "TEST_CACHEABILITY";
+
+ // Call each constructor in sequence, do some basic checks
+ MockResourceURL mockResourceURL = new MockResourceURL();
+ assertNull("Default resource id not null ?", mockResourceURL.getResourceID());
+ assertNull("Default cacheability not null ?", mockResourceURL.getCacheability());
+ mockResourceURL.setResourceID(TEST_RESOURCEID);
+ assertEquals("Resource id not set value ?", TEST_RESOURCEID, mockResourceURL.getResourceID());
+ mockResourceURL.setCacheability(TEST_CACHEABILITY);
+ assertEquals("Cacheability does not match set value ?", TEST_CACHEABILITY, mockResourceURL.getCacheability());
+ final String resourceURLAsString = mockResourceURL.toString();
+ assertNotNull("MockResourceURL toString() result null ?", resourceURLAsString);
+ assertTrue("MockResourceURL toString() result is empty ?", resourceURLAsString.length() > 0);
+ }
+
+ public void testMockStateAwareResponse() {
+ final String TEST_PORTLETNAME = "TestPortletName";
+ final String TEST_DEFAULTNAMESPACE = "Test_Default_Namespace";
+ final String TEST_QNAME3_STRING = "TestQname3String";
+ final QName TEST_QNAME = new QName(TEST_PORTLETNAME);
+ final QName TEST_QNAME2 = new QName(TEST_DEFAULTNAMESPACE);
+ final String TEST_QNAME_VALUE = "Test_Qname_Value";
+ final String TEST_QNAME2_VALUE = "Test_Qname2_Value";
+ final String TEST_QNAME3_VALUE = "Test_Qname3_Value";
+ final String TEST_PARAM = "TEST_PARAM";
+ final String TEST_PARAM2 = "TEST_PARAM2";
+ final String TEST_PARAM3 = "TEST_PARAM3";
+ final String TEST_PARAM_VALUE = "NORMALVALUE";
+ final String[] TEST_PARAM_ARRAYVALUE = { "ARRAYVALUE1", "ARRAYVALUE2" };
+ final String[] TEST_PARAM_ARRAYVALUE2 = { "ARRAYVALUE3", "ARRAYVALUE4" };
+
+ // Call each constructor in sequence, do some basic checks
+ MockStateAwareResponse mockStateAwareResponse = new MockStateAwareResponse();
+ try {
+ mockStateAwareResponse.setPortletMode(PortletMode.VIEW);
+ } catch (Exception ex) {
+ fail("MockStateAwareResponse portlet mode set failed. Exception: " + ex);
+ }
+ assertEquals("PortletMode.VIEW not set ?", PortletMode.VIEW, mockStateAwareResponse.getPortletMode());
+ try {
+ mockStateAwareResponse.setPortletMode(PortletMode.EDIT);
+ } catch (Exception ex) {
+ fail("MockStateAwareResponse portlet mode set failed. Exception: " + ex);
+ }
+ assertEquals("Portlet mode does not match set value ?", PortletMode.EDIT, mockStateAwareResponse.getPortletMode());
+ try {
+ mockStateAwareResponse.setWindowState(WindowState.MAXIMIZED);
+ } catch (Exception ex) {
+ fail("MockStateAwareResponse portlet mode set failed. Exception: " + ex);
+ }
+ assertEquals("Window state does not match set value ?", WindowState.MAXIMIZED, mockStateAwareResponse.getWindowState());
+ final MockPortalContext mockPortalContext = new MockPortalContext();
+ mockStateAwareResponse = new MockStateAwareResponse(mockPortalContext);
+ assertEquals("Portal context does not match constructor-set value ?", mockPortalContext, mockStateAwareResponse.getPortalContext());
+
+ assertNull("Initial event already present ?", mockStateAwareResponse.getEvent(TEST_PORTLETNAME));
+ assertNull("Initial event already present ?", mockStateAwareResponse.getEvent(TEST_QNAME));
+ assertNull("Initial event already present ?", mockStateAwareResponse.getEvent(TEST_DEFAULTNAMESPACE));
+ assertNull("Initial event already present ?", mockStateAwareResponse.getEvent(TEST_QNAME2));
+ mockStateAwareResponse.setEvent(TEST_QNAME, TEST_QNAME_VALUE);
+ mockStateAwareResponse.setEvent(TEST_QNAME2, TEST_QNAME2_VALUE);
+ mockStateAwareResponse.setEvent(TEST_QNAME3_STRING, TEST_QNAME3_VALUE);
+ assertEquals("First event QName not set value ?", TEST_QNAME_VALUE, mockStateAwareResponse.getEvent(TEST_QNAME));
+ assertEquals("Second event QName not set value ?", TEST_QNAME2_VALUE, mockStateAwareResponse.getEvent(TEST_QNAME2));
+ assertEquals("Third event QName not set value ?", TEST_QNAME3_VALUE, mockStateAwareResponse.getEvent(TEST_QNAME3_STRING));
+ final Iterator<QName> eventQNames = mockStateAwareResponse.getEventNames();
+ assertNotNull("Event names iterator null ?", eventQNames);
+ while (eventQNames.hasNext()) {
+ QName currentQName = eventQNames.next();
+ assertNotNull("Iterator QName entry null ?", currentQName);
+ assertTrue("Iterator QName name not one of two or three expected matches ?", currentQName.getLocalPart().equals(TEST_QNAME.getLocalPart()) ||
+ currentQName.getLocalPart().equals(TEST_QNAME2.getLocalPart()) ||
+ currentQName.getLocalPart().equals(TEST_QNAME3_STRING));
+ }
+
+ mockStateAwareResponse.setRenderParameter(TEST_PARAM, TEST_PARAM_VALUE);
+ mockStateAwareResponse.setRenderParameter(TEST_PARAM2, TEST_PARAM_ARRAYVALUE);
+ assertEquals("Portal test render parameter value not as expected ?", TEST_PARAM_VALUE, mockStateAwareResponse.getRenderParameter(TEST_PARAM));
+ assertEquals("Portal test render parameter value not as expected ?", TEST_PARAM_ARRAYVALUE[0], mockStateAwareResponse.getRenderParameter(TEST_PARAM2));
+ final Iterator<String> renderParameterNames = mockStateAwareResponse.getRenderParameterNames();
+ assertNotNull("Render parameter names iterator null ?", renderParameterNames);
+ while (renderParameterNames.hasNext()) {
+ String currentParameter = renderParameterNames.next();
+ assertNotNull("Iterator parameter entry null ?", currentParameter);
+ assertTrue("Iterator parameter name not one of two or three expected matches ?", currentParameter.equals(TEST_PARAM) ||
+ currentParameter.equals(TEST_PARAM2) ||
+ currentParameter.equals(TEST_PARAM3));
+ }
+ final String[] renderParameterValuesParam2 = mockStateAwareResponse.getRenderParameterValues(TEST_PARAM2);
+ assertTrue("Render parameter value2 not as expected ?", Arrays.equals(TEST_PARAM_ARRAYVALUE, renderParameterValuesParam2));
+ final Map<String, String[]> renderParametersMap = new LinkedHashMap<>();
+ renderParametersMap.put(TEST_PARAM3, TEST_PARAM_ARRAYVALUE2);
+ mockStateAwareResponse.setRenderParameters(renderParametersMap);
+ assertEquals("Portal test render parameter value not cleared as expected ?", null, mockStateAwareResponse.getRenderParameter(TEST_PARAM));
+ assertEquals("Portal test render parameter value not cleared as expected ?", null, mockStateAwareResponse.getRenderParameter(TEST_PARAM2));
+ assertEquals("Portal test render parameter map value not as expected ?", renderParametersMap, mockStateAwareResponse.getRenderParameterMap());
+ }
+
+ public void testServletWrappingPortletContext() {
+ final String TEST_ATTRIBUTE = "TEST_ATTRIBUTE";
+ final String TEST_ATTRIBUTE_VALUE = "Attribute_Value_1";
+ final String TEST_ATTRIBUTE2 = "TEST_ATTRIBUTE2";
+ final String TEST_ATTRIBUTE_VALUE2 = "Attribute_Value_2";
+ final String TEST_INITPARAM = "TEST_INITPARAM";
+ final String TEST_INITPARAM2 = "TEST_INITPARAM2";
+
+ // Call each constructor in sequence, do some basic checks
+ final MockServletContext mockServletContext = new MockServletContext();
+ final ServletWrappingPortletContext servletWrappingPortletContext = new ServletWrappingPortletContext(mockServletContext);
+ assertNotNull("ServletWrappingPortletContext serverInfo null ?", servletWrappingPortletContext.getServerInfo());
+ assertNull("ServletWrappingPortletContext PortletRequestDispatcher not null (illegal prefix) ?", servletWrappingPortletContext.getRequestDispatcher("IllegalPrefix"));
+ assertNull("ServletWrappingPortletContext PortletRequestDispatcher not null ?", servletWrappingPortletContext.getRequestDispatcher("/"));
+ assertNotNull("ServletWrappingPortletContext resource stream for / null ?", servletWrappingPortletContext.getResourceAsStream("/"));
+ assertNull("ServletWrappingPortletContext resource stream for /ThisDoesNotExist not null ?", servletWrappingPortletContext.getResourceAsStream("/ThisDoesNotExist"));
+ assertTrue("ServletWrappingPortletContext major version not >= 2 ?", servletWrappingPortletContext.getMajorVersion() >= 2);
+ assertTrue("ServletWrappingPortletContext minor version not >= 0 ?", servletWrappingPortletContext.getMajorVersion() >= 0);
+ assertNull("ServletWrappingPortletContext MIME type for / not null ?", servletWrappingPortletContext.getMimeType("/"));
+ assertNotNull("ServletWrappingPortletContext real path for / null ?", servletWrappingPortletContext.getRealPath("/"));
+ assertNull("ServletWrappingPortletContext real path for /ThisDoesNotExist not null ? ?", servletWrappingPortletContext.getRealPath("/ThisDoesNotExist"));
+ assertNull("ServletWrappingPortletContext resource paths for / not null ?", servletWrappingPortletContext.getResourcePaths("/"));
+ assertNull("ServletWrappingPortletContext resource paths for / null ?", servletWrappingPortletContext.getResourcePaths("/ThisDoesNotExist"));
+ try {
+ assertNotNull("ServletWrappingPortletContext resource URL for / null ?", servletWrappingPortletContext.getResource("/"));
+ } catch (MalformedURLException mue) {
+ fail("ServletWrappingPortletContext resource URL for / failed. Exception: " + mue);
+ }
+ try {
+ assertNull("ServletWrappingPortletContext resource URL for /ThisDoesNotExist not null ?", servletWrappingPortletContext.getResource("/ThisDoesNotExist"));
+ } catch (MalformedURLException mue) {
+ fail("ServletWrappingPortletContext resource URL for /ThisDoesNotExist failed. Exception: " + mue);
+ }
+
+ assertNull(TEST_ATTRIBUTE + " present before set ?", servletWrappingPortletContext.getAttribute(TEST_ATTRIBUTE));
+ assertNull(TEST_ATTRIBUTE2 + " present before set ?", servletWrappingPortletContext.getAttribute(TEST_ATTRIBUTE2));
+ servletWrappingPortletContext.setAttribute(TEST_ATTRIBUTE, TEST_ATTRIBUTE_VALUE);
+ servletWrappingPortletContext.setAttribute(TEST_ATTRIBUTE2, TEST_ATTRIBUTE_VALUE2);
+ assertEquals("Retrieved atribute 1 does not match set value ?", TEST_ATTRIBUTE_VALUE, servletWrappingPortletContext.getAttribute(TEST_ATTRIBUTE));
+ assertEquals("Retrieved atribute 2 does not match set value ?", TEST_ATTRIBUTE_VALUE2, servletWrappingPortletContext.getAttribute(TEST_ATTRIBUTE2));
+ final Enumeration<String> attributeNames = servletWrappingPortletContext.getAttributeNames();
+ int attributeNameCount = 0;
+ assertNotNull("Attribute names null after additions ?", attributeNames);
+ assertTrue("Attribute names empty after additions ?", attributeNames.hasMoreElements());
+ while (attributeNames.hasMoreElements()) {
+ attributeNameCount++;
+ String currentAttibuteName = attributeNames.nextElement();
+ assertTrue("Attribute name not one of two or three expected matches ?", TEST_ATTRIBUTE.equals(currentAttibuteName) ||
+ TEST_ATTRIBUTE2.equals(currentAttibuteName) ||
+ WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE.equals(currentAttibuteName));
+ }
+ assertTrue("Atribute names size not 2 or 3 ?", attributeNameCount >= 2 && attributeNameCount <= 3);
+
+ assertNull(TEST_INITPARAM + " present before set ?", servletWrappingPortletContext.getInitParameter(TEST_INITPARAM));
+ assertNull(TEST_INITPARAM2 + " present before set ?", servletWrappingPortletContext.getInitParameter(TEST_INITPARAM));
+ servletWrappingPortletContext.log("Test logging call");
+ servletWrappingPortletContext.log("Test logging call", new Exception("Fake Exception"));
+ assertEquals("Default portlet context name not as expected ?", "MockServletContext", servletWrappingPortletContext.getPortletContextName());
+ assertFalse("Portlet runtime options not empty before set ?", servletWrappingPortletContext.getContainerRuntimeOptions().hasMoreElements());
+ }
+ // -------- Continue writing tests here --------------
+
+ class TestMockMultipartFile implements MultipartFile {
+ private String name;
+ private String originalFilename;
+ private String contentType;
+ private int size;
+ private byte[] bytes;
+
+ public TestMockMultipartFile(String name, String originalFilename, String contentType, byte[] bytes) {
+ this.name = name;
+ this.originalFilename = originalFilename;
+ this.contentType = contentType;
+ if (bytes != null) {
+ this.bytes = Arrays.copyOf(bytes, bytes.length);
+ } else {
+ bytes = null;
+ }
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String getOriginalFilename() {
+ return this.originalFilename;
+ }
+
+ @Override
+ public String getContentType() {
+ return contentType;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return (bytes != null ? bytes.length > 0 : true);
+ }
+
+ @Override
+ public long getSize() {
+ return (bytes != null ? bytes.length : 0);
+ }
+
+ @Override
+ public byte[] getBytes() throws IOException {
+ return bytes;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return new ByteArrayInputStream(bytes);
+ }
+
+ @Override
+ public void transferTo(File file) throws IOException, IllegalStateException {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ }
+
+ class TetMockResourceBundle extends ResourceBundle {
+
+ @Override
+ protected Object handleGetObject(String key) {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public Enumeration<String> getKeys() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ }
+
+ class TestMockPrincipal implements Principal {
+
+ @Override
+ public String getName() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ @Override
+ public boolean implies(Subject subject) {
+ return Principal.super.implies(subject);
+ }
+ }
+}
diff --git a/plugins/junit-portlet/src/test/resources/applicationContext.xml b/plugins/junit-portlet/src/test/resources/applicationContext.xml
new file mode 100644
index 0000000..106fd6c
--- /dev/null
+++ b/plugins/junit-portlet/src/test/resources/applicationContext.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * 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.
+ */
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
+ <property name="scopes">
+ <map>
+ <entry key="session">
+ <bean class="org.springframework.context.support.SimpleThreadScope"/>
+ </entry>
+ </map>
+ </property>
+ </bean>
+
+</beans>
\ No newline at end of file
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 66bb555..fdee6ed 100644
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -45,6 +45,7 @@
<module>jfreechart</module>
<module>json</module>
<module>junit</module>
+ <module>junit-portlet</module>
<module>osgi</module>
<module>oval</module>
<module>pell-multipart</module>
diff --git a/plugins/portlet/pom.xml b/plugins/portlet/pom.xml
index c5198b8..5fc6480 100644
--- a/plugins/portlet/pom.xml
+++ b/plugins/portlet/pom.xml
@@ -42,6 +42,12 @@
<dependency>
<groupId>org.apache.struts</groupId>
+ <artifactId>struts2-junit-portlet-plugin</artifactId>
+ <optional>true</optional>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.struts</groupId>
<artifactId>struts2-velocity-plugin</artifactId>
</dependency>
diff --git a/plugins/portlet/src/main/java/org/apache/struts2/StrutsPortletTestCase.java b/plugins/portlet/src/main/java/org/apache/struts2/StrutsPortletTestCase.java
index 0c9801d..0f07ea9 100644
--- a/plugins/portlet/src/main/java/org/apache/struts2/StrutsPortletTestCase.java
+++ b/plugins/portlet/src/main/java/org/apache/struts2/StrutsPortletTestCase.java
@@ -23,11 +23,11 @@ import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import org.apache.struts2.portlet.PortletConstants;
import org.apache.struts2.portlet.PortletPhase;
-import org.springframework.mock.web.portlet.MockPortletContext;
-import org.springframework.mock.web.portlet.MockPortletRequest;
-import org.springframework.mock.web.portlet.MockPortletResponse;
-import org.springframework.mock.web.portlet.MockPortletSession;
-import org.springframework.mock.web.portlet.MockStateAwareResponse;
+import org.apache.struts2.mock.web.portlet.MockPortletContext;
+import org.apache.struts2.mock.web.portlet.MockPortletRequest;
+import org.apache.struts2.mock.web.portlet.MockPortletResponse;
+import org.apache.struts2.mock.web.portlet.MockPortletSession;
+import org.apache.struts2.mock.web.portlet.MockStateAwareResponse;
import javax.portlet.PortletMode;
import java.util.HashMap;
diff --git a/plugins/portlet/src/main/java/org/apache/struts2/portlet/PortletRequestMap.java b/plugins/portlet/src/main/java/org/apache/struts2/portlet/PortletRequestMap.java
index df9dc10..ec13f12 100644
--- a/plugins/portlet/src/main/java/org/apache/struts2/portlet/PortletRequestMap.java
+++ b/plugins/portlet/src/main/java/org/apache/struts2/portlet/PortletRequestMap.java
@@ -20,6 +20,7 @@ package org.apache.struts2.portlet;
import javax.portlet.PortletRequest;
import java.util.AbstractMap;
+import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
@@ -49,9 +50,14 @@ public class PortletRequestMap extends AbstractMap<String, Object> {
public void clear() {
entries = null;
Enumeration keys = request.getAttributeNames();
-
+ ArrayList<String> keyStrings = new ArrayList<>();
+ // Depending on the underlying collection, a ConcurrentModificationException may occur if we attempt
+ // to remove attributes while iterating over the keys Enumeration. Instead use an interim collection to
+ // gather all the keys and then remove them.
while (keys.hasMoreElements()) {
- String key = (String) keys.nextElement();
+ keyStrings.add((String) keys.nextElement());
+ }
+ for (String key : keyStrings){
request.removeAttribute(key);
}
}
diff --git a/plugins/portlet/src/test/java/org/apache/struts2/components/PortletUrlRendererTest.java b/plugins/portlet/src/test/java/org/apache/struts2/components/PortletUrlRendererTest.java
index 39c5125..0272043 100644
--- a/plugins/portlet/src/test/java/org/apache/struts2/components/PortletUrlRendererTest.java
+++ b/plugins/portlet/src/test/java/org/apache/struts2/components/PortletUrlRendererTest.java
@@ -24,9 +24,9 @@ import com.opensymphony.xwork2.util.ValueStack;
import org.apache.struts2.StrutsStatics;
import org.apache.struts2.StrutsTestCase;
import org.apache.struts2.portlet.PortletConstants;
-import org.springframework.mock.web.portlet.MockMimeResponse;
-import org.springframework.mock.web.portlet.MockPortletContext;
-import org.springframework.mock.web.portlet.MockPortletRequest;
+import org.apache.struts2.mock.web.portlet.MockMimeResponse;
+import org.apache.struts2.mock.web.portlet.MockPortletContext;
+import org.apache.struts2.mock.web.portlet.MockPortletRequest;
import javax.portlet.PortletContext;
import javax.portlet.PortletMode;
diff --git a/plugins/portlet/src/test/java/org/apache/struts2/portlet/PortletRequestMapTest.java b/plugins/portlet/src/test/java/org/apache/struts2/portlet/PortletRequestMapTest.java
index 19d4c67..a282f2e 100644
--- a/plugins/portlet/src/test/java/org/apache/struts2/portlet/PortletRequestMapTest.java
+++ b/plugins/portlet/src/test/java/org/apache/struts2/portlet/PortletRequestMapTest.java
@@ -25,7 +25,7 @@ import java.util.Set;
import javax.portlet.PortletRequest;
import org.jmock.MockObjectTestCase;
-import org.springframework.mock.web.portlet.MockPortletRequest;
+import org.apache.struts2.mock.web.portlet.MockPortletRequest;
/**
diff --git a/plugins/portlet/src/test/java/org/apache/struts2/portlet/PortletSessionMapTest.java b/plugins/portlet/src/test/java/org/apache/struts2/portlet/PortletSessionMapTest.java
index d666cc6..a92c521 100644
--- a/plugins/portlet/src/test/java/org/apache/struts2/portlet/PortletSessionMapTest.java
+++ b/plugins/portlet/src/test/java/org/apache/struts2/portlet/PortletSessionMapTest.java
@@ -26,7 +26,7 @@ import javax.portlet.PortletSession;
import junit.framework.TestCase;
-import org.springframework.mock.web.portlet.MockPortletRequest;
+import org.apache.struts2.mock.web.portlet.MockPortletRequest;
/**
diff --git a/plugins/portlet/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr168DispatcherTest.java b/plugins/portlet/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr168DispatcherTest.java
index be2ea35..0c54cf2 100644
--- a/plugins/portlet/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr168DispatcherTest.java
+++ b/plugins/portlet/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr168DispatcherTest.java
@@ -30,8 +30,8 @@ import org.easymock.EasyMock;
import org.jmock.Mock;
import org.jmock.cglib.MockObjectTestCase;
import org.jmock.core.Constraint;
-import org.springframework.mock.web.portlet.MockPortletConfig;
-import org.springframework.mock.web.portlet.MockPortletContext;
+import org.apache.struts2.mock.web.portlet.MockPortletConfig;
+import org.apache.struts2.mock.web.portlet.MockPortletContext;
import javax.portlet.*;
import java.util.*;
diff --git a/plugins/portlet/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr286DispatcherTest.java b/plugins/portlet/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr286DispatcherTest.java
index c5f4346..843f4ce 100644
--- a/plugins/portlet/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr286DispatcherTest.java
+++ b/plugins/portlet/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr286DispatcherTest.java
@@ -30,8 +30,8 @@ import org.easymock.EasyMock;
import org.jmock.Mock;
import org.jmock.cglib.MockObjectTestCase;
import org.jmock.core.Constraint;
-import org.springframework.mock.web.portlet.MockPortletConfig;
-import org.springframework.mock.web.portlet.MockPortletContext;
+import org.apache.struts2.mock.web.portlet.MockPortletConfig;
+import org.apache.struts2.mock.web.portlet.MockPortletContext;
import javax.portlet.*;
import java.util.*;
diff --git a/pom.xml b/pom.xml
index b5786b7..2c83f31 100644
--- a/pom.xml
+++ b/pom.xml
@@ -571,6 +571,11 @@
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
+ <artifactId>struts2-junit-portlet-plugin</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>${project.version}</version>
</dependency>
[struts] 04/06: Drops duplicated dependency
Posted by lu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch action-context-boost
in repository https://gitbox.apache.org/repos/asf/struts.git
commit 0ea08d1b1c0c9b7cbc9e9f40f02d3435178abd18
Author: Lukasz Lenart <lu...@apache.org>
AuthorDate: Sat Apr 4 10:00:14 2020 +0200
Drops duplicated dependency
---
plugins/portlet-mocks/pom.xml | 5 -----
1 file changed, 5 deletions(-)
diff --git a/plugins/portlet-mocks/pom.xml b/plugins/portlet-mocks/pom.xml
index afc9a8f..8f7357d 100644
--- a/plugins/portlet-mocks/pom.xml
+++ b/plugins/portlet-mocks/pom.xml
@@ -40,11 +40,6 @@
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
<!-- Portlet -->
<dependency>