/*******************************************************************************
* Copyright (C) 2015 BonitaSoft S.A.
* BonitaSoft, 32 rue Gustave Eiffel - 38000 Grenoble
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation
* version 2.1 of the License.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301, USA.
******************************************************************************/
package org.bonitasoft.livingapps;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpSession;
import org.bonitasoft.console.common.server.page.CustomPageAuthorizationsHelper;
import org.bonitasoft.console.common.server.page.CustomPageRequestModifier;
import org.bonitasoft.console.common.server.page.PageRenderer;
import org.bonitasoft.console.common.server.page.ResourceRenderer;
import org.bonitasoft.console.common.server.page.extension.PageResourceProviderImpl;
import org.bonitasoft.console.common.server.utils.BonitaHomeFolderAccessor;
import org.bonitasoft.engine.api.ApplicationAPI;
import org.bonitasoft.engine.api.PageAPI;
import org.bonitasoft.engine.business.application.ApplicationPage;
import org.bonitasoft.engine.page.Page;
import org.bonitasoft.engine.session.APISession;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@RunWith(MockitoJUnitRunner.class)
public class LivingApplicationPageServletTest {
MockHttpServletRequest hsRequest = new MockHttpServletRequest();
@Mock
MockHttpServletResponse hsResponse = new MockHttpServletResponse();
@Mock
HttpSession httpSession;
@Mock
APISession apiSession;
@Mock
CustomPageAuthorizationsHelper customPageAuthorizationsHelper;
@Mock
PageRenderer pageRenderer;
@Mock
ResourceRenderer resourceRenderer;
@Mock
PageResourceProviderImpl pageResourceProvider;
@Mock
BonitaHomeFolderAccessor bonitaHomeFolderAccessor;
@Mock
CustomPageRequestModifier customPageRequestModifier;
@Mock
ApplicationAPI applicationAPI;
@Mock
Page page;
@Mock
ApplicationPage applicationPage;
@Mock
PageAPI pageAPI;
@Spy
@InjectMocks
LivingApplicationPageServlet servlet;
@Before
public void beforeEach() throws Exception {
hsRequest.setSession(httpSession);
hsRequest.setMethod("GET");
doReturn(apiSession).when(httpSession).getAttribute("apiSession");
doReturn(applicationAPI).when(servlet).getApplicationApi(apiSession);
doReturn(pageAPI).when(servlet).getPageApi(apiSession);
doReturn(1L).when(apiSession).getTenantId();
doReturn(customPageAuthorizationsHelper).when(servlet).getCustomPageAuthorizationsHelper(apiSession);
}
@Test
public void should_get_Forbidden_Status_when_page_unAuthorize() throws Exception {
hsRequest.setPathInfo("/AppToken/pageToken/content/");
given(resourceRenderer.getPathSegments("/AppToken/pageToken/content/")).willReturn(Arrays.asList("AppToken", "pageToken", "content"));
given(customPageAuthorizationsHelper.isPageAuthorized("AppToken", "customPageName")).willReturn(false);
doReturn(applicationPage).when(applicationAPI).getApplicationPage("AppToken","pageToken");
doReturn(2L).when(applicationPage).getPageId();
doReturn(page).when(pageAPI).getPage(2L);
doReturn("customPageName").when(page).getName();
servlet.service(hsRequest, hsResponse);
verify(hsResponse).sendError(403 ,"User not Authorized");
}
@Test
public void should_get_badRequest_Status_when_page_name_is_not_set() throws Exception {
hsRequest.setPathInfo("/AppToken/content/");
servlet.service(hsRequest, hsResponse);
verify(hsResponse).sendError(400, "The info path is suppose to contain the application token, the page token and one of the separator '/content', '/theme' or '/API'.");
}
@Test
public void should_redirect_to_valide_url_on_missing_slash() throws Exception {
hsRequest.setPathInfo("/AppToken/pageToken/content");
servlet.service(hsRequest, hsResponse);
verify(customPageRequestModifier).redirectToValidPageUrl(hsRequest, hsResponse);
}
@Test
public void getPage_should_call_the_page_renderer() throws Exception {
testPageIsWellCalled("AppToken", "htmlexample1", "/AppToken/htmlexample1/content/", Arrays.asList("AppToken","htmlexample1","content"));
testPageIsWellCalled("AppToken", "htmlexample2", "/AppToken/htmlexample2/content/index", Arrays.asList("AppToken","htmlexample2","content","index"));
testPageIsWellCalled("AppToken", "htmlexample4", "/AppToken/htmlexample4/content/index.html", Arrays.asList("AppToken","htmlexample4","content","index.html"));
testPageIsWellCalled("AppToken", "htmlexample5", "/AppToken/htmlexample5/content/Index.groovy", Arrays.asList("AppToken","htmlexample5","content","Index.groovy"));
}
private void testPageIsWellCalled(final String appToken, final String pageToken, final String path, final List<String> pathSegment) throws Exception {
hsRequest.setPathInfo(path);
given(resourceRenderer.getPathSegments(path)).willReturn(pathSegment);
given(customPageAuthorizationsHelper.isPageAuthorized(appToken, "customPage_"+pageToken)).willReturn(true);
doReturn(applicationPage).when(applicationAPI).getApplicationPage(appToken,pageToken);
doReturn(2L).when(applicationPage).getPageId();
doReturn(page).when(pageAPI).getPage(2L);
doReturn("customPage_"+pageToken).when(page).getName();
servlet.service(hsRequest, hsResponse);
verify(pageRenderer, times(1)).displayCustomPage(hsRequest, hsResponse, apiSession, "customPage_"+pageToken);
}
@Test
public void getResource_should_call_the_resource_renderer() throws Exception {
hsRequest.setPathInfo("/AppToken/htmlexample/content/css/file.css");
final File pageDir = new File("/pageDir");
given(resourceRenderer.getPathSegments("/AppToken/htmlexample/content/css/file.css")).willReturn(Arrays.asList("AppToken", "htmlexample", "content", "css", "file.css"));
final String pageName = "customPage_htmlexample";
doReturn(pageResourceProvider).when(pageRenderer).getPageResourceProvider(pageName, 1L);
doReturn(pageDir).when(pageResourceProvider).getPageDirectory();
doReturn(true).when(bonitaHomeFolderAccessor).isInFolder(any(File.class), any(File.class));
doReturn(applicationPage).when(applicationAPI).getApplicationPage("AppToken","htmlexample");
doReturn(2L).when(applicationPage).getPageId();
doReturn(page).when(pageAPI).getPage(2L);
doReturn(pageName).when(page).getName();
servlet.service(hsRequest, hsResponse);
verify(pageRenderer, times(1)).ensurePageFolderIsPresent(apiSession, pageResourceProvider);
verify(resourceRenderer, times(1)).renderFile(hsRequest, hsResponse,
new File(pageDir, File.separator + "resources" + File.separator + "css" + File.separator + "file.css"), apiSession);
}
@Test(expected=ServletException.class)
public void getResource_should_throw_exception_if_unauthorised() throws Exception {
hsRequest.setPathInfo("/AppToken/htmlexample/content/css/../../../file.css");
final File pageDir = new File(".");
given(resourceRenderer.getPathSegments("/AppToken/htmlexample/content/css/../../../file.css")).willReturn(
Arrays.asList("AppToken","htmlexample","content", "css", "..", "..", "..", "file.css"));
doReturn(pageResourceProvider).when(pageRenderer).getPageResourceProvider("htmlexample", 1L);
given(pageResourceProvider.getPageDirectory()).willReturn(pageDir);
doReturn(false).when(bonitaHomeFolderAccessor).isInFolder(any(File.class), any(File.class));
doReturn(applicationPage).when(applicationAPI).getApplicationPage("AppToken","htmlexample");
doReturn(2L).when(applicationPage).getPageId();
doReturn(page).when(pageAPI).getPage(2L);
doReturn("customPage_"+"htmlexample").when(page).getName();
servlet.service(hsRequest, hsResponse);
}
@Test
public void should_forward_when_API_call() throws Exception {
hsRequest.setPathInfo("/AppToken/htmlexample/API/bpm/process/1");
given(resourceRenderer.getPathSegments("/AppToken/htmlexample/API/bpm/process/1")).willReturn(
Arrays.asList("AppToken", "htmlexample", "API", "bpm", "process", "1"));
servlet.service(hsRequest, hsResponse);
verify(servlet, never()).doGet(hsRequest, hsResponse);
}
}