[
https://issues.apache.org/jira/browse/WW-5517?focusedWorklogId=953088&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-953088
]
ASF GitHub Bot logged work on WW-5517:
--------------------------------------
Author: ASF GitHub Bot
Created on: 20/Jan/25 02:20
Start Date: 20/Jan/25 02:20
Worklog Time Spent: 10m
Work Description: kusalk commented on code in PR #1187:
URL: https://github.com/apache/struts/pull/1187#discussion_r1921711368
##########
core/src/test/java/org/apache/struts2/views/jsp/ui/DebugTagTest.java:
##########
@@ -198,14 +197,14 @@ public void
testTagAttributeOverrideDevModeFalse_clearTagStateSet() throws Excep
freshTag.setPerformClearTagStateForTagPoolingServers(true);
freshTag.setPageContext(pageContext);
assertTrue("Tag state after doEndTag() and explicit tag state clearing
is inequal to new Tag with pageContext/parent set. " +
- "May indicate that clearTagStateForTagPoolingServers() calls
are not working properly.",
+ "May indicate that clearTagStateForTagPoolingServers()
calls are not working properly.",
strutsBodyTagsAreReflectionEqual(tag, freshTag));
PrepareOperations.clearDevModeOverride(); // Clear DevMode override.
Avoid ThreadLocal side-effects if test thread re-used.
}
private void setDevMode(final boolean devMode) {
- setStrutsConstant(new HashMap<String, String>() {{
+ setStrutsConstant(new HashMap<>() {{
Review Comment:
Nit: `Map#of` or `Collections#singletonMap`
##########
core/src/test/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptorTest.java:
##########
@@ -0,0 +1,552 @@
+/*
+ * 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.interceptor.debugging;
+
+import org.apache.struts2.ActionContext;
+import org.apache.struts2.StrutsJUnit4InternalTestCase;
+import org.apache.struts2.TestAction;
+import org.apache.struts2.dispatcher.DispatcherConstants;
+import org.apache.struts2.dispatcher.HttpParameters;
+import org.apache.struts2.dispatcher.RequestMap;
+import org.apache.struts2.dispatcher.SessionMap;
+import org.apache.struts2.mock.MockActionInvocation;
+import org.apache.struts2.util.ValueStack;
+import org.assertj.core.util.Maps;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.mock.web.MockHttpServletResponse;
+import org.springframework.mock.web.MockHttpSession;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+public class DebuggingInterceptorTest extends StrutsJUnit4InternalTestCase {
+
+ private DebuggingInterceptor interceptor;
+ private MockActionInvocation invocation;
+ private MockHttpServletRequest request;
+ private MockHttpServletResponse response;
+ private ActionContext context;
+
+ @Test
+ public void noDevMode() throws Exception {
+ interceptor.intercept(invocation);
+ assertThat(invocation.getResultCode()).isEqualTo("mock");
+ assertThat(response.getContentAsString()).isEmpty();
+ }
+
+ @Test
+ public void debugXml() throws Exception {
+ interceptor.setDevMode("true");
+ context.withParameters(HttpParameters.create(Maps.newHashMap("debug",
"xml")).build());
+
+ interceptor.intercept(invocation);
+
+
assertThat(response.getContentAsString()).isEqualToIgnoringWhitespace("""
+ <debug>
+ <parameters/>
+ <context/>
+ <request/>
+ <session/>
+ <valueStack>
+ <value>
+ <action>
+ <actionErrors/>
+ <actionMessages/>
+ <class>class org.apache.struts2.TestAction</class>
+ <fieldErrors/>
+ <locale>
+ <ISO3Country>USA</ISO3Country>
+ <ISO3Language>eng</ISO3Language>
+ <class>class java.util.Locale</class>
+ <country>US</country>
+ <displayCountry>United States</displayCountry>
+ <displayLanguage>English</displayLanguage>
+ <displayName>English (United States)</displayName>
+ <displayScript></displayScript>
+ <displayVariant></displayVariant>
+ <extensionKeys/>
+ <language>en</language>
+ <script></script>
+ <unicodeLocaleAttributes/>
+ <unicodeLocaleKeys/>
+ <variant></variant>
+ </locale>
+ <status>
+ <class>class org.apache.struts2.SomeEnum</class>
+ <declaringClass>class
org.apache.struts2.SomeEnum</declaringClass>
+ <displayName>completed</displayName>
+ <name>COMPLETED</name>
+ </status>
+ <statusList>
+ <value>
+ <class>class org.apache.struts2.SomeEnum</class>
+ <declaringClass>class
org.apache.struts2.SomeEnum</declaringClass>
+ <displayName>init</displayName>
+ <name>INIT</name>
+ </value>
+ <value>
+ <class>class org.apache.struts2.SomeEnum</class>
+ <declaringClass>class
org.apache.struts2.SomeEnum</declaringClass>
+ <displayName>completed</displayName>
+ <name>COMPLETED</name>
+ </value>
+ </statusList>
+ <texts>
+
<baseBundleName>org.apache.struts2.TestAction</baseBundleName>
+ <class>class java.util.PropertyResourceBundle</class>
+ <keys>
+ <class>class
sun.util.ResourceBundleEnumeration</class>
+ </keys>
+ <locale>
+ <ISO3Country></ISO3Country>
+ <ISO3Language></ISO3Language>
+ <class>class java.util.Locale</class>
+ <country></country>
+ <displayCountry></displayCountry>
+ <displayLanguage></displayLanguage>
+ <displayName></displayName>
+ <displayScript></displayScript>
+ <displayVariant></displayVariant>
+ <extensionKeys/>
+ <language></language>
+ <script></script>
+ <unicodeLocaleAttributes/>
+ <unicodeLocaleKeys/>
+ <variant></variant>
+ </locale>
+ </texts>
+ </action>
+
<org.apache.struts2.util.OgnlValueStack.MAP_IDENTIFIER_KEY></org.apache.struts2.util.OgnlValueStack.MAP_IDENTIFIER_KEY>
+ </value>
+ <value>
+ <class>class
org.apache.struts2.text.DefaultTextProvider</class>
+ </value>
+ </valueStack>
+ </debug>
+ """);
+ }
+
+ @Test
+ public void debugXmlWithConsole() throws Exception {
+ interceptor.setDevMode("true");
+ context.withParameters(HttpParameters.create(Maps.newHashMap("debug",
"console")).build());
+ interceptor.setEnableXmlWithConsole(true);
+
+ interceptor.intercept(invocation);
+
+
assertThat(response.getContentAsString()).isEqualToIgnoringWhitespace("""
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <script>
+ var baseUrl = "/static";
+ window.open(baseUrl+"/webconsole.html", 'OGNL
Console','width=500,height=450,status=no,toolbar=no,menubar=no');
+ </script>
+ </head>
+ <body>
+ <pre>
+ &lt;debug&gt;
+ &lt;parameters/&gt;
+ &lt;context/&gt;
+ &lt;request/&gt;
+ &lt;session/&gt;
+ &lt;valueStack&gt;
+ &lt;value&gt;
+ &lt;action&gt;
+ &lt;actionErrors/&gt;
+ &lt;actionMessages/&gt;
+ &lt;class&gt;class
org.apache.struts2.TestAction&lt;/class&gt;
+ &lt;fieldErrors/&gt;
+ &lt;locale&gt;
+
&lt;ISO3Country&gt;USA&lt;/ISO3Country&gt;
+
&lt;ISO3Language&gt;eng&lt;/ISO3Language&gt;
+ &lt;class&gt;class
java.util.Locale&lt;/class&gt;
+ &lt;country&gt;US&lt;/country&gt;
+ &lt;displayCountry&gt;United
States&lt;/displayCountry&gt;
+
&lt;displayLanguage&gt;English&lt;/displayLanguage&gt;
+ &lt;displayName&gt;English (United
States)&lt;/displayName&gt;
+
&lt;displayScript&gt;&lt;/displayScript&gt;
+
&lt;displayVariant&gt;&lt;/displayVariant&gt;
+ &lt;extensionKeys/&gt;
+ &lt;language&gt;en&lt;/language&gt;
+ &lt;script&gt;&lt;/script&gt;
+ &lt;unicodeLocaleAttributes/&gt;
+ &lt;unicodeLocaleKeys/&gt;
+ &lt;variant&gt;&lt;/variant&gt;
+ &lt;/locale&gt;
+ &lt;status&gt;
+ &lt;class&gt;class
org.apache.struts2.SomeEnum&lt;/class&gt;
+ &lt;declaringClass&gt;class
org.apache.struts2.SomeEnum&lt;/declaringClass&gt;
+
&lt;displayName&gt;completed&lt;/displayName&gt;
+ &lt;name&gt;COMPLETED&lt;/name&gt;
+ &lt;/status&gt;
+ &lt;statusList&gt;
+ &lt;value&gt;
+ &lt;class&gt;class
org.apache.struts2.SomeEnum&lt;/class&gt;
+ &lt;declaringClass&gt;class
org.apache.struts2.SomeEnum&lt;/declaringClass&gt;
+
&lt;displayName&gt;init&lt;/displayName&gt;
+ &lt;name&gt;INIT&lt;/name&gt;
+ &lt;/value&gt;
+ &lt;value&gt;
+ &lt;class&gt;class
org.apache.struts2.SomeEnum&lt;/class&gt;
+ &lt;declaringClass&gt;class
org.apache.struts2.SomeEnum&lt;/declaringClass&gt;
+
&lt;displayName&gt;completed&lt;/displayName&gt;
+ &lt;name&gt;COMPLETED&lt;/name&gt;
+ &lt;/value&gt;
+ &lt;/statusList&gt;
+ &lt;texts&gt;
+
&lt;baseBundleName&gt;org.apache.struts2.TestAction&lt;/baseBundleName&gt;
+ &lt;class&gt;class
java.util.PropertyResourceBundle&lt;/class&gt;
+ &lt;keys&gt;
+ &lt;class&gt;class
sun.util.ResourceBundleEnumeration&lt;/class&gt;
+ &lt;/keys&gt;
+ &lt;locale&gt;
+
&lt;ISO3Country&gt;&lt;/ISO3Country&gt;
+
&lt;ISO3Language&gt;&lt;/ISO3Language&gt;
+ &lt;class&gt;class
java.util.Locale&lt;/class&gt;
+ &lt;country&gt;&lt;/country&gt;
+
&lt;displayCountry&gt;&lt;/displayCountry&gt;
+
&lt;displayLanguage&gt;&lt;/displayLanguage&gt;
+
&lt;displayName&gt;&lt;/displayName&gt;
+
&lt;displayScript&gt;&lt;/displayScript&gt;
+
&lt;displayVariant&gt;&lt;/displayVariant&gt;
+ &lt;extensionKeys/&gt;
+ &lt;language&gt;&lt;/language&gt;
+ &lt;script&gt;&lt;/script&gt;
+ &lt;unicodeLocaleAttributes/&gt;
+ &lt;unicodeLocaleKeys/&gt;
+ &lt;variant&gt;&lt;/variant&gt;
+ &lt;/locale&gt;
+ &lt;/texts&gt;
+ &lt;/action&gt;
+
&lt;org.apache.struts2.util.OgnlValueStack.MAP_IDENTIFIER_KEY&gt;&lt;/org.apache.struts2.util.OgnlValueStack.MAP_IDENTIFIER_KEY&gt;
+ &lt;/value&gt;
+ &lt;value&gt;
+ &lt;class&gt;class
org.apache.struts2.text.DefaultTextProvider&lt;/class&gt;
+ &lt;/value&gt;
+ &lt;/valueStack&gt;
+ &lt;/debug&gt;
+ </pre>
+ </body>
+ </html>
+ """);
+ }
+
+ @Test
+ public void debugConsole() throws Exception {
+ interceptor.setDevMode("true");
+ context.withParameters(HttpParameters.create(Maps.newHashMap("debug",
"console")).build());
+
+ interceptor.intercept(invocation);
+
+
assertThat(response.getContentAsString()).isEqualToIgnoringWhitespace("""
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <script>
+ var baseUrl = "/static";
+ window.open(baseUrl+"/webconsole.html", 'OGNL
Console','width=500,height=450,status=no,toolbar=no,menubar=no');
+ </script>
+ </head>
+ <body>
+ <pre>
+
+ </pre>
+ </body>
+ </html>
+ """);
+ }
+
+ @Test
+ public void debugCommand() throws Exception {
+ interceptor.setDevMode("true");
+ Map<String, Object> params = new HashMap<>() {{
+ put("debug", "command");
+ put("expression", "1+1");
+ }};
+ context.withParameters(HttpParameters.create(params).build());
+
+ interceptor.intercept(invocation);
+
+
assertThat(response.getContentAsString()).isEqualToIgnoringWhitespace("2");
+ }
+
+ @Test
+ public void debugBrowser() throws Exception {
+ interceptor.setDevMode("true");
+ context.withParameters(HttpParameters.create(Maps.newHashMap("debug",
"browser")).build());
+
+ interceptor.intercept(invocation);
+ invocation.invoke();
+
+
assertThat(response.getContentAsString()).isEqualToIgnoringWhitespace("""
+ <!DOCTYPE html>
+ <html lang="en">
+ <style>
+ .debugTable {
+ border-style: solid;
+ border-width: 1px;
+ }
+
+ .debugTable td {
+ border-style: solid;
+ border-width: 1px;
+ }
+
+ .nameColumn {
+ background-color:#CCDDFF;
+ }
+
+ .valueColumn {
+ background-color: #CCFFCC;
+ }
+
+ .nullValue {
+ background-color: #FF0000;
+ }
+
+ .typeColumn {
+ background-color: white;
+ }
+
+ .emptyCollection {
+ background-color: #EEEEEE;
+ }
+ </style>
+
+ <script>
+ function expand(src, path) {
+ let baseUrl = location.href;
+ const i = baseUrl.indexOf('&object=');
+ baseUrl = (i > 0 ? baseUrl.substring(0, i) :
baseUrl) + "&object=" + path;
+ if (baseUrl.indexOf("decorate") < 0) {
+ baseUrl += "&decorate=false";
+ }
+
+ const request = new XMLHttpRequest();
+ request.open('GET', baseUrl, true);
+ request.onreadystatechange = function() {
+ if (this.readyState === 4) {
+ if (this.status >= 200 && this.status < 400) {
+ const div = document.createElement('div');
+ console.log(this.responseText);
+ div.innerHTML = this.responseText;
+ src.parentNode.appendChild(div);
+
+ src.innerHTML = "Collapse";
+ const oldOnclick = src.onclick;
+ src.onclick = function() {
+ src.innerHTML = "Expand";
+ src.parentNode.removeChild(div);
+ src.onclick = oldOnclick;
+ };
+ }
+ }
+ };
+ request.send();
+ }
+ </script>
+
+ <body>
+ <table class="debugTable">
+ <tr>
+ <td class="nameColumn">container</td>
+ <td class="valueColumn">There is no read method for
container</td>
+ <td class="typeColumn">java.lang.String</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">foo</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">intList</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">locale</td>
+ <td class="valueColumn">
+ <a onclick="expand(this, 'action["locale"]')"
href="javascript://nop/">Expand</a>
+ </td>
+ <td class="typeColumn">java.util.Locale</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">result</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">collection2</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">someBool</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">array</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">fooInt</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">id</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">map</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">actionErrors</td>
+ <td class="emptyCollection">empty</td>
+ <td class="typeColumn">java.util.LinkedList</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">objectArray</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">fieldErrors</td>
+ <td class="emptyCollection">empty</td>
+ <td class="typeColumn">java.util.LinkedHashMap</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">collection</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">floatNumber</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">list</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">enumList</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">actionMessages</td>
+ <td class="emptyCollection">empty</td>
+ <td class="typeColumn">java.util.LinkedList</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">statusList</td>
+ <td class="valueColumn">
+ <a onclick="expand(this,
'action["statusList"]')" href="javascript://nop/">Expand</a>
+ </td>
+ <td class="typeColumn">java.util.Arrays$ArrayList</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">texts</td>
+ <td class="valueColumn">
+ <a onclick="expand(this, 'action["texts"]')"
href="javascript://nop/">Expand</a>
+ </td>
+ <td
class="typeColumn">java.util.PropertyResourceBundle</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">list3</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">list2</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">user</td>
+ <td class="nullValue">null</td>
+ <td class="nullValue">unknown</td>
+ </tr>
+ <tr>
+ <td class="nameColumn">status</td>
+ <td class="valueColumn">
+ <a onclick="expand(this, 'action["status"]')"
href="javascript://nop/">Expand</a>
+ </td>
+ <td class="typeColumn">org.apache.struts2.SomeEnum</td>
+ </tr>
+ </table>
+ </body>
+ </html>
+ """);
+ }
+
+ @Before
+ public void before() {
+ request = new MockHttpServletRequest();
+ request.setSession(new MockHttpSession());
+ response = new MockHttpServletResponse();
+
+ ValueStack valueStack =
dispatcher.getValueStackFactory().createValueStack();
+
+ context = valueStack.getActionContext()
+ .withServletContext(servletContext)
+ .withServletRequest(request)
+ .withServletResponse(response)
+ .withSession(new SessionMap(request))
+ .with(DispatcherConstants.REQUEST, new RequestMap(request));
+
+ interceptor = container.inject(DebuggingInterceptor.class);
+ interceptor.init();
+
+ invocation = new MockActionInvocation();
+ invocation.setResultCode("mock");
+ invocation.setInvocationContext(context);
+ invocation.setAction(new TestAction());
+ invocation.setStack(valueStack);
+
+ valueStack.set("action", invocation.getAction());
+
+ context = context.withActionInvocation(invocation).bind();
+ }
+
+ @After
+ public void after() {
Review Comment:
Nit: looks redundant
Issue Time Tracking
-------------------
Worklog Id: (was: 953088)
Remaining Estimate: 0h
Time Spent: 10m
> The debug Struts tag throws an error.
> -------------------------------------
>
> Key: WW-5517
> URL: https://issues.apache.org/jira/browse/WW-5517
> Project: Struts 2
> Issue Type: Bug
> Affects Versions: 7.0.0
> Reporter: Boris Kole
> Assignee: Lukasz Lenart
> Priority: Major
> Fix For: 7.0.1
>
> Time Spent: 10m
> Remaining Estimate: 0h
>
> When using the debug Struts tag it throws the following errors.
> |{*}Messages{*}:| # org.apache.struts2.text.DefaultTextProvider.texts
> # Caught an exception while getting the property values of
> org.apache.struts2.text.DefaultTextProvider@61995fff
> # An exception occurred processing [/home.jsp] at line [3] 1: <%@ taglib
> prefix="s" uri="/struts-tags" %> 2: 3: <s:debug/> Stacktrace:|
> |{*}File{*}:|org/apache/jasper/servlet/JspServletWrapper.java|
> |{*}Line number{*}:|599|
> The JSP I used:
> {code:java}
> <%@ taglib prefix="s" uri="/struts-tags" %>
> <s:debug/> {code}
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)