1
2
3
4
5
6
7
8
9
10
11 package psiprobe.controllers.sql;
12
13 import static org.junit.jupiter.api.Assertions.assertEquals;
14 import static org.junit.jupiter.api.Assertions.assertTrue;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.when;
17
18 import java.sql.Connection;
19 import java.sql.DatabaseMetaData;
20 import java.sql.SQLException;
21 import java.util.List;
22 import java.util.Locale;
23 import java.util.Map;
24
25 import javax.naming.NamingException;
26 import javax.sql.DataSource;
27
28 import org.apache.catalina.Context;
29 import org.junit.jupiter.api.BeforeEach;
30 import org.junit.jupiter.api.Test;
31 import org.springframework.context.support.StaticApplicationContext;
32 import org.springframework.mock.web.MockHttpServletRequest;
33 import org.springframework.mock.web.MockHttpServletResponse;
34 import org.springframework.test.util.ReflectionTestUtils;
35 import org.springframework.web.servlet.ModelAndView;
36
37 import psiprobe.TomcatContainer;
38 import psiprobe.beans.ContainerWrapperBean;
39 import psiprobe.beans.ResourceResolver;
40
41 class ConnectionTestControllerTest {
42
43 private ConnectionTestController controller;
44 private ContainerWrapperBean containerWrapper;
45 private ResourceResolver resourceResolver;
46 private TomcatContainer tomcatContainer;
47
48 @BeforeEach
49 void setUp() throws Exception {
50 controller = new ConnectionTestController();
51 controller.setViewName("ajax/sql/connection");
52
53 StaticApplicationContext applicationContext = new StaticApplicationContext();
54 applicationContext.addMessage("probe.src.dataSourceTest.resource.lookup.failure",
55 Locale.getDefault(), "lookup {0}");
56 applicationContext.addMessage("probe.src.dataSourceTest.connection.failure",
57 Locale.getDefault(), "connection {0}");
58 applicationContext.addMessage("probe.jsp.dataSourceTest.dbMetaData.dbProdName",
59 Locale.getDefault(), "db product");
60 applicationContext.addMessage("probe.jsp.dataSourceTest.dbMetaData.dbProdVersion",
61 Locale.getDefault(), "db version");
62 applicationContext.addMessage("probe.jsp.dataSourceTest.dbMetaData.jdbcDriverName",
63 Locale.getDefault(), "driver name");
64 applicationContext.addMessage("probe.jsp.dataSourceTest.dbMetaData.jdbcDriverVersion",
65 Locale.getDefault(), "driver version");
66 applicationContext.addMessage("probe.jsp.dataSourceTest.dbMetaData.jdbcVersion",
67 Locale.getDefault(), "jdbc version");
68 applicationContext.refresh();
69 controller.setApplicationContext(applicationContext);
70
71 containerWrapper = mock(ContainerWrapperBean.class);
72 resourceResolver = mock(ResourceResolver.class);
73 tomcatContainer = mock(TomcatContainer.class);
74
75 when(containerWrapper.getResourceResolver()).thenReturn(resourceResolver);
76 when(containerWrapper.getTomcatContainer()).thenReturn(tomcatContainer);
77 when(tomcatContainer.formatContextName("app")).thenReturn("/app");
78
79 ReflectionTestUtils.setField(controller, "containerWrapper", containerWrapper);
80 }
81
82 @Test
83 void handleRequestReturnsDatabaseMetadataWhenLookupSucceeds() throws Exception {
84 Context context = mock(Context.class);
85 DataSource dataSource = mock(DataSource.class);
86 Connection connection = mock(Connection.class);
87 DatabaseMetaData metaData = mock(DatabaseMetaData.class);
88
89 when(tomcatContainer.findContext("/app")).thenReturn(context);
90 when(resourceResolver.lookupDataSource(context, "jdbc/test", containerWrapper))
91 .thenReturn(dataSource);
92 when(dataSource.getConnection()).thenReturn(connection);
93 when(connection.getMetaData()).thenReturn(metaData);
94 when(metaData.getDatabaseProductName()).thenReturn("PostgreSQL");
95 when(metaData.getDatabaseProductVersion()).thenReturn("16");
96 when(metaData.getDriverName()).thenReturn("Driver");
97 when(metaData.getDriverVersion()).thenReturn("1.0");
98 when(metaData.getJDBCMajorVersion()).thenReturn(4);
99
100 MockHttpServletRequest request = new MockHttpServletRequest("GET", "/sql/connection.ajax");
101 request.addParameter("webapp", "app");
102 request.addParameter("resource", "jdbc/test");
103
104 ModelAndView modelAndView = controller.handleRequest(request, new MockHttpServletResponse());
105
106 assertEquals("ajax/sql/connection", modelAndView.getViewName());
107 @SuppressWarnings("unchecked")
108 List<Map<String, String>> dbMetaData =
109 (List<Map<String, String>>) modelAndView.getModel().get("dbMetaData");
110 assertEquals(5, dbMetaData.size());
111 assertEquals("db product", dbMetaData.get(0).get("propertyName"));
112 assertEquals("PostgreSQL", dbMetaData.get(0).get("propertyValue"));
113 }
114
115 @Test
116 void handleRequestSetsLookupErrorWhenDatasourceLookupFails() throws Exception {
117 Context context = mock(Context.class);
118 when(tomcatContainer.findContext("/app")).thenReturn(context);
119 when(resourceResolver.lookupDataSource(context, "jdbc/missing", containerWrapper))
120 .thenThrow(new NamingException("boom"));
121
122 MockHttpServletRequest request = new MockHttpServletRequest("GET", "/sql/connection.ajax");
123 request.addParameter("webapp", "app");
124 request.addParameter("resource", "jdbc/missing");
125
126 ModelAndView modelAndView = controller.handleRequest(request, new MockHttpServletResponse());
127
128 assertEquals("ajax/sql/connection", modelAndView.getViewName());
129 assertEquals("lookup jdbc/missing", request.getAttribute("errorMessage"));
130 }
131
132 @Test
133 void handleRequestSetsConnectionErrorWhenConnectionFails() throws Exception {
134 Context context = mock(Context.class);
135 DataSource dataSource = mock(DataSource.class);
136 when(tomcatContainer.findContext("/app")).thenReturn(context);
137 when(resourceResolver.lookupDataSource(context, "jdbc/test", containerWrapper))
138 .thenReturn(dataSource);
139 when(dataSource.getConnection()).thenThrow(new SQLException("down"));
140
141 MockHttpServletRequest request = new MockHttpServletRequest("GET", "/sql/connection.ajax");
142 request.addParameter("webapp", "app");
143 request.addParameter("resource", "jdbc/test");
144
145 ModelAndView modelAndView = controller.handleRequest(request, new MockHttpServletResponse());
146
147 assertEquals("ajax/sql/connection", modelAndView.getViewName());
148 assertEquals("connection down", request.getAttribute("errorMessage"));
149 assertTrue(modelAndView.getModel().isEmpty());
150 }
151 }