blob: 61b886f8505a75107e348ba5cd07e0878a2459ea [file] [log] [blame]
/*
* 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.sling.servlets.resolver.internal.console;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.servlets.resolver.internal.ResolverConfig;
import org.apache.sling.servlets.resolver.internal.resolution.ResolutionCache;
import org.hamcrest.CoreMatchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import javax.json.Json;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
public class WebConsolePluginTest {
@Mock
private HttpServletRequest request;
@Mock
private HttpServletResponse response;
@Mock
private ResourceResolverFactory resourceResolverFactory;
@Mock
private ResolutionCache resolutionCache;
@InjectMocks
private WebConsolePlugin webConsolePlugin;
private StringWriter stringWriter;
private PrintWriter writer;
@Before
public void setUp() throws Exception {
MockitoAnnotations.openMocks(this);
ResolverConfig resolverConfig = Mockito.mock(ResolverConfig.class);
Mockito.when(resolverConfig.servletresolver_defaultExtensions()).thenReturn(new String[]{"html"});
Mockito.when(resolverConfig.servletresolver_paths()).thenReturn(new String[]{"/path"});
webConsolePlugin.activate(resolverConfig);
// mock http responses
stringWriter = new StringWriter();
writer = new PrintWriter(stringWriter);
Mockito.when(response.getWriter()).thenReturn(writer);
}
@After
public void closeUp() throws Exception {
MockitoAnnotations.openMocks(this).close();
}
@Test
public void printJsonFormatFull() throws Exception {
// Mock resource resolver
ResourceResolver resourceResolver = Mockito.mock(ResourceResolver.class);
Resource resource = Mockito.mock(Resource.class);
Servlet servlet = Mockito.mock(Servlet.class);
Mockito.when(resource.adaptTo(Servlet.class)).thenReturn(servlet);
Mockito.when(resource.getPath()).thenReturn("/path");
Mockito.when(resourceResolver.resolve(Mockito.anyString())).thenReturn(resource);
Mockito.when(resourceResolverFactory.getServiceResourceResolver(Mockito.anyMap())).thenReturn(resourceResolver);
// Mock request calls
Mockito.when(request.getParameter("url")).thenReturn("/test.1.json");
Mockito.when(request.getParameter("method")).thenReturn("GET");
// JSON output
Mockito.when(request.getRequestURI()).thenReturn("/path/servletresolver.json");
webConsolePlugin.service(request, response);
Mockito.verify(response).setContentType("application/json");
String jsonString = stringWriter.toString();
String json = Json.createReader(new StringReader(jsonString)).readObject().toString();
Map<String, Object> expectedJsonPaths = new HashMap(){{
put("$.candidates", null);
put("$.candidates.allowedServlets.length()", 1);
put("$.candidates.deniedServlets.length()", 0);
put("$.decomposedURL", null);
put("$.decomposedURL.path", "/test");
put("$.decomposedURL.extension", "json");
put("$.decomposedURL.selectors", Arrays.asList("1"));
put("$.decomposedURL.suffix", "");
put("$.method", "GET");
}};
expectedJsonPaths.forEach((k, v) -> {
if (v != null) {
assertThat(json, hasJsonPath(k, equalTo(v)));
} else {
assertThat(json, hasJsonPath(k));
}
});
}
@Test
public void printJsonFormatEmptyURL() throws Exception {
// Mock resource resolver
ResourceResolver resourceResolver = Mockito.mock(ResourceResolver.class);
Resource resource = Mockito.mock(Resource.class);
Mockito.when(resource.adaptTo(Servlet.class)).thenReturn(null);
Mockito.when(resourceResolver.resolve(Mockito.anyString())).thenReturn(resource);
Mockito.when(resourceResolverFactory.getServiceResourceResolver(Mockito.anyMap())).thenReturn(resourceResolver);
// Mock request calls
Mockito.when(request.getParameter("url")).thenReturn("");
Mockito.when(request.getParameter("method")).thenReturn("GET");
// JSON output
Mockito.when(request.getRequestURI()).thenReturn("/path/servletresolver.json");
webConsolePlugin.service(request, response);
Mockito.verify(response).setContentType("application/json");
String jsonString = stringWriter.toString();
String json = Json.createReader(new StringReader(jsonString)).readObject().toString();
Map<String, Object> expectedJsonPaths = new HashMap(){{
put("$.method", "GET");
}};
expectedJsonPaths.forEach((k, v) -> {
if (v != null) {
assertThat(json, hasJsonPath(k, equalTo(v)));
} else {
assertThat(json, hasJsonPath(k));
}
});
}
@Test
public void printJsonFormatDenyPaths() throws Exception {
// Mock resource resolver
ResourceResolver resourceResolver = Mockito.mock(ResourceResolver.class);
Resource resource = Mockito.mock(Resource.class);
Servlet servlet = Mockito.mock(Servlet.class);
Mockito.when(resource.adaptTo(Servlet.class)).thenReturn(servlet);
Mockito.when(resource.getPath()).thenReturn("/denied");
Mockito.when(resourceResolver.resolve(Mockito.anyString())).thenReturn(resource);
Mockito.when(resourceResolverFactory.getServiceResourceResolver(Mockito.anyMap())).thenReturn(resourceResolver);
// Mock request calls
Mockito.when(request.getParameter("url")).thenReturn("/denied");
Mockito.when(request.getParameter("method")).thenReturn("GET");
// JSON output
Mockito.when(request.getRequestURI()).thenReturn("/path/servletresolver.json");
webConsolePlugin.service(request, response);
Mockito.verify(response).setContentType("application/json");
String jsonString = stringWriter.toString();
String json = Json.createReader(new StringReader(jsonString)).readObject().toString();
Map<String, Object> expectedJsonPaths = new HashMap(){{
put("$.candidates", null);
put("$.candidates.allowedServlets.length()", 0);
put("$.candidates.deniedServlets.length()", 1);
}};
expectedJsonPaths.forEach((k, v) -> {
if (v != null) {
assertThat(json, hasJsonPath(k, equalTo(v)));
} else {
assertThat(json, hasJsonPath(k));
}
});
}
@Test
public void printHTMLFormatFull() throws Exception {
// Mock resource resolver
ResourceResolver resourceResolver = Mockito.mock(ResourceResolver.class);
Resource resource = Mockito.mock(Resource.class);
Servlet servlet = Mockito.mock(Servlet.class);
Mockito.when(resource.adaptTo(Servlet.class)).thenReturn(servlet);
Mockito.when(resourceResolver.resolve(Mockito.anyString())).thenReturn(resource);
Mockito.when(resourceResolverFactory.getServiceResourceResolver(Mockito.anyMap())).thenReturn(resourceResolver);
// Mock request calls
Mockito.when(request.getParameter("url")).thenReturn("/test.1.json");
Mockito.when(request.getParameter("method")).thenReturn("GET");
// HTML output
Mockito.when(request.getRequestURI()).thenReturn("/path/servletresolver");
webConsolePlugin.service(request, response);
String htmlString = stringWriter.toString();
final String expectedInputHTML = "<tr class='content'>\n" +
"<td class='content'>URL</td>\n" +
"<td class='content' colspan='2'><input type='text' name='url' value='/test.1.json' class='input' " +
"size='50'>\n" +
"</td></tr>\n" +
"</tr>\n" +
"<tr class='content'>\n" +
"<td class='content'>Method</td>\n" +
"<td class='content' colspan='2'><select name='method'>\n" +
"<option value='GET'>GET</option>\n" +
"<option value='POST'>POST</option>\n" +
"</select>\n" +
"&nbsp;&nbsp;<input type='submit' value='Resolve' class='submit'>\n" +
"</td></tr>";
assertThat(htmlString, CoreMatchers.containsString(expectedInputHTML));
final String expectedDecomposedURLHTML = "<tr class='content'>\n" +
"<td class='content'>Decomposed URL</td>\n" +
"<td class='content' colspan='2'><dl>\n" +
"<dt>Path</dt>\n" +
"<dd>\n" +
"/test<br/><em>Note that in a real Sling request, the path might vary depending on the existence of " +
"resources that partially match it. <br/>This utility does not take this into account and uses the " +
"first dot to split between path and selectors/extension. <br/>As a workaround, you can replace dots " +
"with underline characters, for example, when testing such a URL.</em></dd><dt>Selectors</dt>\n" +
"<dd>\n" +
"[1]</dd><dt>Extension</dt>\n" +
"<dd>\n" +
"json</dd></dl>\n" +
"</dd><dt>Suffix</dt>\n" +
"<dd>\n" +
"null</dd></dl>\n" +
"</td></tr>";
assertThat(htmlString, CoreMatchers.containsString(expectedDecomposedURLHTML));
final String expectedCandidatesHTML = "<tr class='content'>\n" +
"<td class='content'>Candidates</td>\n" +
"<td class='content' colspan='2'>Candidate servlets and scripts in order of preference for method " +
"GET:<br/>\n" +
"<ol class='servlets'>\n";
assertThat(htmlString, CoreMatchers.containsString(expectedCandidatesHTML));
}
@Test
public void printHTMLFormatEmptyURL() throws Exception {
// Mock resource resolver
ResourceResolver resourceResolver = Mockito.mock(ResourceResolver.class);
Resource resource = Mockito.mock(Resource.class);
Mockito.when(resource.adaptTo(Servlet.class)).thenReturn(null);
Mockito.when(resourceResolver.resolve(Mockito.anyString())).thenReturn(resource);
Mockito.when(resourceResolverFactory.getServiceResourceResolver(Mockito.anyMap())).thenReturn(resourceResolver);
// Mock request calls
Mockito.when(request.getParameter("url")).thenReturn("");
Mockito.when(request.getParameter("method")).thenReturn("GET");
// HTML output
Mockito.when(request.getRequestURI()).thenReturn("/path/servletresolver");
webConsolePlugin.service(request, response);
String htmlString = stringWriter.toString();
assertEquals("<form method='get'><table class='content' cellpadding='0' cellspacing='0' width='100%'>\n" +
"<tr class='content'>\n" +
"<th colspan='3' class='content container'>Servlet Resolver Test</th>\n" +
"</tr>\n" +
"<tr class='content'>\n" +
"<td colspan='3' class='content'>To check which servlet is responsible for rendering a response, " +
"enter a request path into the field and click &apos;Resolve&apos; to resolve it.</th>\n" +
"</tr>\n" +
"<tr class='content'>\n" +
"<td class='content'>URL</td>\n" +
"<td class='content' colspan='2'><input type='text' name='url' value='' class='input' size='50'>\n" +
"</td></tr>\n" +
"</tr>\n" +
"<tr class='content'>\n" +
"<td class='content'>Method</td>\n" +
"<td class='content' colspan='2'><select name='method'>\n" +
"<option value='GET'>GET</option>\n" +
"<option value='POST'>POST</option>\n" +
"</select>\n" +
"&nbsp;&nbsp;<input type='submit' value='Resolve' class='submit'>\n" +
"</td></tr>\n" +
"</table>\n" +
"</form>", htmlString);
}
@Test
public void printHTMLFormatDenyPaths() throws Exception {
// Mock resource resolver
ResourceResolver resourceResolver = Mockito.mock(ResourceResolver.class);
Resource resource = Mockito.mock(Resource.class);
Servlet servlet = Mockito.mock(Servlet.class);
Mockito.when(resource.adaptTo(Servlet.class)).thenReturn(servlet);
Mockito.when(resource.getPath()).thenReturn("/denied");
Mockito.when(resourceResolver.resolve(Mockito.anyString())).thenReturn(resource);
Mockito.when(resourceResolverFactory.getServiceResourceResolver(Mockito.anyMap())).thenReturn(resourceResolver);
// Mock request calls
Mockito.when(request.getParameter("url")).thenReturn("/denied");
Mockito.when(request.getParameter("method")).thenReturn("GET");
// HTML output
Mockito.when(request.getRequestURI()).thenReturn("/path/servletresolver");
webConsolePlugin.service(request, response);
String htmlString = stringWriter.toString();
final String expectedDeniedElement = "<ol class='servlets'>\n" +
"<li><del>";
assertThat(htmlString, CoreMatchers.containsString(expectedDeniedElement));
}
}