From 1b8844705bf6c2fd9d4a10023260fe704c5d6ec3 Mon Sep 17 00:00:00 2001 From: Alexei Date: Tue, 19 Nov 2024 00:28:38 +0300 Subject: [PATCH 1/4] feat (JENKINS-70464) added test from CLIAction https://issues.jenkins.io/browse/JENKINS-70464 --- .../test/java/hudson/cli/CLIActionTest.java | 228 ++++++++++++++++++ 1 file changed, 228 insertions(+) create mode 100644 core/src/test/java/hudson/cli/CLIActionTest.java diff --git a/core/src/test/java/hudson/cli/CLIActionTest.java b/core/src/test/java/hudson/cli/CLIActionTest.java new file mode 100644 index 000000000000..946427149ce2 --- /dev/null +++ b/core/src/test/java/hudson/cli/CLIActionTest.java @@ -0,0 +1,228 @@ +package hudson.cli; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import jakarta.servlet.RequestDispatcher; +import jakarta.servlet.ServletException; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.Optional; +import javax.servlet.http.HttpServletResponse; +import jenkins.model.Jenkins; +import jenkins.websocket.WebSocketSession; +import jenkins.websocket.WebSockets; +import org.junit.Rule; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; +import org.jvnet.hudson.test.MockAuthorizationStrategy; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.StaplerRequest2; +import org.kohsuke.stapler.StaplerResponse2; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.stubbing.Answer; + +public class CLIActionTest { + + @Rule + public JenkinsRule jenkinsRule = new JenkinsRule(); + + private final CLIAction cliAction = new CLIAction(); + + @Test + public void testDoCommand() throws ServletException, IOException { + Jenkins jenkins = jenkinsRule.getInstance(); + jenkins.setSecurityRealm(jenkinsRule.createDummySecurityRealm()); + jenkinsRule.jenkins.setAuthorizationStrategy( + new org.jvnet.hudson.test.MockAuthorizationStrategy() + .grant(Jenkins.READ) + .everywhere() + .to("user")); + + StaplerRequest2 req = mock(StaplerRequest2.class); + StaplerResponse2 rsp = mock(StaplerResponse2.class); + + when(req.getRestOfPath()).thenReturn("/testCommand"); + + doAnswer( + (Answer) invocation -> { + int statusCode = invocation.getArgument(0); + String message = invocation.getArgument(1); + assertEquals("Expected 404 error", HttpServletResponse.SC_NOT_FOUND, statusCode); + assertTrue("Expected 'No such command' message", message.contains("No such command")); + return null; + }) + .when(rsp) + .sendError(eq(HttpServletResponse.SC_NOT_FOUND), anyString()); + + // Вызов тестируемого метода + cliAction.doCommand(req, rsp); + + // Проверка, что sendError был вызван + verify(rsp).sendError(HttpServletResponse.SC_NOT_FOUND, "No such command"); + } + + @Test + public void testDoCommandWithParameter() throws ServletException, IOException { + Jenkins jenkins = jenkinsRule.getInstance(); + + jenkins.setSecurityRealm(jenkinsRule.createDummySecurityRealm()); + jenkinsRule.jenkins.setAuthorizationStrategy( + new MockAuthorizationStrategy() + .grant(Jenkins.READ) + .everywhere() + .to("user")); + + StaplerRequest2 req = mock(StaplerRequest2.class); + StaplerResponse2 rsp = mock(StaplerResponse2.class); + RequestDispatcher dispatcher = mock(RequestDispatcher.class); + + when(req.getRestOfPath()).thenReturn("/add-job-to-view"); + when(req.getView(Optional.ofNullable(any()), anyString())).thenReturn(dispatcher); + + doNothing().when(dispatcher).forward(any(), any()); + + cliAction.doCommand(req, rsp); + + verify(req).getRestOfPath(); + verify(req).getView(Optional.ofNullable(any()), anyString()); + verify(dispatcher).forward(any(), any()); + } + + @Test + public void getIconFileName() { + assertNull(cliAction.getIconFileName()); + } + + @Test + public void getDisplayName() { + assertEquals("Jenkins CLI", cliAction.getDisplayName()); + } + + @Test + public void getUrlName() { + assertEquals("cli", cliAction.getUrlName()); + } + + @Test + public void isWebSocketSupported() { + assertFalse(cliAction.isWebSocketSupported()); + } + + @Test + public void testWebSocketNotSupported() throws Exception { + try (MockedStatic webSocketsMock = Mockito.mockStatic(WebSockets.class)) { + StaplerRequest2 req = mock(StaplerRequest2.class);// Используем обычный StaplerRequest + + webSocketsMock.when(WebSockets::isSupported).thenReturn(false); + + HttpResponse response = cliAction.doWs(req); + + assertNotNull("Response should not be null", response); + + StaplerResponse2 resp = mock(StaplerResponse2.class); + response.generateResponse(req, resp, null); + + verify(resp).setStatus(HttpServletResponse.SC_NOT_FOUND); + } + } + + @Test + public void testInvalidOrigin() throws Exception { + try (MockedStatic webSocketsMock = Mockito.mockStatic(WebSockets.class); + MockedStatic jenkinsMock = Mockito.mockStatic(Jenkins.class)) { + + StaplerRequest2 req = mock(StaplerRequest2.class); + StaplerResponse2 resp = mock(StaplerResponse2.class); + + webSocketsMock.when(WebSockets::isSupported).thenReturn(true); + + when(req.getHeader("Origin")).thenReturn("http://invalid-origin.com"); + + Jenkins jenkins = mock(Jenkins.class); + jenkinsMock.when(Jenkins::get).thenReturn(jenkins); + when(jenkins.getRootUrlFromRequest()).thenReturn("http://correct-origin.com/"); + when(req.getContextPath()).thenReturn(""); + + Field allowWebSocketField = CLIAction.class.getDeclaredField("ALLOW_WEBSOCKET"); + allowWebSocketField.setAccessible(true); + allowWebSocketField.set(cliAction, null); + + HttpResponse response = cliAction.doWs(req); + + assertNotNull("Response should not be null", response); + + response.generateResponse(req, resp, null); + + verify(resp).setStatus(HttpServletResponse.SC_FORBIDDEN); + } + } + + @Test + public void testWebSocketSupportedAndAllowed() throws Exception { + try (MockedStatic webSocketsMock = Mockito.mockStatic(WebSockets.class); + MockedStatic jenkinsMock = Mockito.mockStatic(Jenkins.class)) { + + webSocketsMock.when(() -> WebSockets.upgrade(any(WebSocketSession.class))) + .thenReturn(mock(HttpResponse.class)); + + StaplerRequest2 req = mock(StaplerRequest2.class); + + webSocketsMock.when(WebSockets::isSupported).thenReturn(true); + + when(req.getHeader("Origin")).thenReturn("http://correct-origin.com"); + + Jenkins jenkins = mock(Jenkins.class); + jenkinsMock.when(Jenkins::get).thenReturn(jenkins); + when(jenkins.getRootUrlFromRequest()).thenReturn("http://correct-origin.com/"); + when(req.getContextPath()).thenReturn(""); + + Field allowWebSocketField = CLIAction.class.getDeclaredField("ALLOW_WEBSOCKET"); + allowWebSocketField.setAccessible(true); + allowWebSocketField.set(cliAction, true); + + HttpResponse response = cliAction.doWs(req); + + assertNotNull("Response should not be null", response); + } + } + + @Test + public void testWebSocketDisabled() throws Exception { + try (MockedStatic webSocketsMock = Mockito.mockStatic(WebSockets.class)) { + StaplerRequest2 req = mock(StaplerRequest2.class); + StaplerResponse2 resp = mock(StaplerResponse2.class); + + webSocketsMock.when(WebSockets::isSupported).thenReturn(true); + + // Отключен WebSocket через флаг ALLOW_WEBSOCKET + Field allowWebSocketField = CLIAction.class.getDeclaredField("ALLOW_WEBSOCKET"); + allowWebSocketField.setAccessible(true); + allowWebSocketField.set(cliAction, false); + + HttpResponse response = cliAction.doWs(req); + + assertNotNull("Response should not be null", response); + + response.generateResponse(req, resp, null); + + verify(resp).setStatus(HttpServletResponse.SC_FORBIDDEN); + } + } + + @Test + public void getTarget() { + } +} From f1731398b0e0c7fd8409623c94b8b721d4dcb832 Mon Sep 17 00:00:00 2001 From: Alexei Date: Tue, 19 Nov 2024 00:30:53 +0300 Subject: [PATCH 2/4] refactor (JENKINS-70464) delete comment and added secure from http https://issues.jenkins.io/browse/JENKINS-70464 --- core/src/test/java/hudson/cli/CLIActionTest.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/core/src/test/java/hudson/cli/CLIActionTest.java b/core/src/test/java/hudson/cli/CLIActionTest.java index 946427149ce2..69121ad069fa 100644 --- a/core/src/test/java/hudson/cli/CLIActionTest.java +++ b/core/src/test/java/hudson/cli/CLIActionTest.java @@ -67,10 +67,8 @@ public void testDoCommand() throws ServletException, IOException { .when(rsp) .sendError(eq(HttpServletResponse.SC_NOT_FOUND), anyString()); - // Вызов тестируемого метода cliAction.doCommand(req, rsp); - // Проверка, что sendError был вызван verify(rsp).sendError(HttpServletResponse.SC_NOT_FOUND, "No such command"); } @@ -124,7 +122,7 @@ public void isWebSocketSupported() { @Test public void testWebSocketNotSupported() throws Exception { try (MockedStatic webSocketsMock = Mockito.mockStatic(WebSockets.class)) { - StaplerRequest2 req = mock(StaplerRequest2.class);// Используем обычный StaplerRequest + StaplerRequest2 req = mock(StaplerRequest2.class); webSocketsMock.when(WebSockets::isSupported).thenReturn(false); @@ -149,11 +147,11 @@ public void testInvalidOrigin() throws Exception { webSocketsMock.when(WebSockets::isSupported).thenReturn(true); - when(req.getHeader("Origin")).thenReturn("http://invalid-origin.com"); + when(req.getHeader("Origin")).thenReturn("https://invalid-origin.com"); Jenkins jenkins = mock(Jenkins.class); jenkinsMock.when(Jenkins::get).thenReturn(jenkins); - when(jenkins.getRootUrlFromRequest()).thenReturn("http://correct-origin.com/"); + when(jenkins.getRootUrlFromRequest()).thenReturn("https://correct-origin.com/"); when(req.getContextPath()).thenReturn(""); Field allowWebSocketField = CLIAction.class.getDeclaredField("ALLOW_WEBSOCKET"); @@ -182,11 +180,11 @@ public void testWebSocketSupportedAndAllowed() throws Exception { webSocketsMock.when(WebSockets::isSupported).thenReturn(true); - when(req.getHeader("Origin")).thenReturn("http://correct-origin.com"); + when(req.getHeader("Origin")).thenReturn("https://correct-origin.com"); Jenkins jenkins = mock(Jenkins.class); jenkinsMock.when(Jenkins::get).thenReturn(jenkins); - when(jenkins.getRootUrlFromRequest()).thenReturn("http://correct-origin.com/"); + when(jenkins.getRootUrlFromRequest()).thenReturn("https://correct-origin.com/"); when(req.getContextPath()).thenReturn(""); Field allowWebSocketField = CLIAction.class.getDeclaredField("ALLOW_WEBSOCKET"); @@ -207,7 +205,6 @@ public void testWebSocketDisabled() throws Exception { webSocketsMock.when(WebSockets::isSupported).thenReturn(true); - // Отключен WebSocket через флаг ALLOW_WEBSOCKET Field allowWebSocketField = CLIAction.class.getDeclaredField("ALLOW_WEBSOCKET"); allowWebSocketField.setAccessible(true); allowWebSocketField.set(cliAction, false); From 7960a2baf64d92a8e4bd41c812b98440e78a4e02 Mon Sep 17 00:00:00 2001 From: Alexei Date: Tue, 19 Nov 2024 00:31:33 +0300 Subject: [PATCH 3/4] refactor (JENKINS-70464) delete comment and added secure from http https://issues.jenkins.io/browse/JENKINS-70464 --- core/src/test/java/hudson/cli/CLIActionTest.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/test/java/hudson/cli/CLIActionTest.java b/core/src/test/java/hudson/cli/CLIActionTest.java index 69121ad069fa..a8065dcbe954 100644 --- a/core/src/test/java/hudson/cli/CLIActionTest.java +++ b/core/src/test/java/hudson/cli/CLIActionTest.java @@ -218,8 +218,4 @@ public void testWebSocketDisabled() throws Exception { verify(resp).setStatus(HttpServletResponse.SC_FORBIDDEN); } } - - @Test - public void getTarget() { - } } From 503654c70a1f20b1cbc34dcc1c8675841e23aec4 Mon Sep 17 00:00:00 2001 From: Alexei Date: Tue, 19 Nov 2024 01:04:44 +0300 Subject: [PATCH 4/4] feat (JENKINS-70464) added lib https://issues.jenkins.io/browse/JENKINS-70464 --- core/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/pom.xml b/core/pom.xml index 9bff5e5ad0b2..06e645e44f0a 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -491,6 +491,12 @@ THE SOFTWARE. test-annotations test + + org.jenkins-ci.main + jenkins-test-harness + 2353.ve3f890c6eea_f + test + org.junit.jupiter junit-jupiter