This is an automated email from the ASF dual-hosted git repository. lukaszlenart pushed a commit to branch WW-5631-chaining-require-annotations in repository https://gitbox.apache.org/repos/asf/struts.git
commit 7db36c9b46aabbfcda844896371e63121fb80bc2 Author: Lukasz Lenart <[email protected]> AuthorDate: Wed May 27 08:25:35 2026 +0200 WW-5631 test(chaining): cover includes interaction and proxied target Co-Authored-By: Claude Opus 4.7 <[email protected]> --- .../interceptor/ChainingInterceptorTest.java | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/core/src/test/java/org/apache/struts2/interceptor/ChainingInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/ChainingInterceptorTest.java index e59780a93..ab9305bce 100644 --- a/core/src/test/java/org/apache/struts2/interceptor/ChainingInterceptorTest.java +++ b/core/src/test/java/org/apache/struts2/interceptor/ChainingInterceptorTest.java @@ -30,6 +30,8 @@ import org.apache.struts2.util.ValueStack; import org.apache.struts2.interceptor.parameter.StrutsParameterAuthorizer; import org.apache.struts2.ognl.OgnlUtil; import org.apache.struts2.util.ProxyService; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; import java.util.*; @@ -240,6 +242,42 @@ public class ChainingInterceptorTest extends XWorkTestCase { target.getManagerApproved()); } + public void testEnforcementStillFiltersWithIncludesConfigured() throws Exception { + AnnotatedChainingAction source = new AnnotatedChainingAction(); + source.setManagerApproved(true); + UnannotatedChainingAction target = new UnannotatedChainingAction(); + mockInvocation.matchAndReturn("getAction", target); + stack.push(source); + stack.push(target); + + interceptor.setIncludes("managerApproved"); + enableChainingEnforcement(true, false); + interceptor.intercept(invocation); + + assertFalse("unauthorized property must be excluded even when listed in includes", + target.getManagerApproved()); + } + + public void testEnforcementResolvesProxiedTargetClass() throws Exception { + AnnotatedChainingAction source = new AnnotatedChainingAction(); + source.setManagerApproved(true); + UnannotatedChainingAction target = new UnannotatedChainingAction(); + mockInvocation.matchAndReturn("getAction", target); + stack.push(source); + stack.push(target); + + ProxyService proxyService = Mockito.mock(ProxyService.class); + Mockito.when(proxyService.isProxy(ArgumentMatchers.any())).thenReturn(true); + Mockito.when(proxyService.ultimateTargetClass(ArgumentMatchers.any())) + .thenReturn((Class) UnannotatedChainingAction.class); + interceptor.setProxyService(proxyService); + + enableChainingEnforcement(true, false); + interceptor.intercept(invocation); + + assertFalse("proxied unannotated target property must NOT be copied", target.getManagerApproved()); + } + @Override protected void setUp() throws Exception { super.setUp();
