package org.bonitasoft.livingapps;
import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import java.io.File;
import java.util.Arrays;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.bonitasoft.console.common.server.page.CustomPageService;
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.session.APISession;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ApplicationRouterTest {
public static final String LAYOUT_PAGE_NAME = "layoutPageName";
@Mock(answer = Answers.RETURNS_MOCKS)
HttpServletRequest hsRequest;
@Mock
HttpServletResponse hsResponse;
@Mock
APISession apiSession;
@Mock
ApplicationModelFactory applicationModelFactory;
@Mock
ApplicationModel applicationModel;
@Mock
PageRenderer pageRenderer;
@Mock
PageResourceProviderImpl pageResourceProvider;
@Mock
CustomPageService customPageService;
@Spy
@InjectMocks
ResourceRenderer resourceRenderer;
@Mock
BonitaHomeFolderAccessor bonitaHomeFolderAccessor;
@InjectMocks
ApplicationRouter applicationRouter;
@Before
public void beforeEach() throws Exception {
given(apiSession.getTenantId()).willReturn(1L);
given(hsRequest.getMethod()).willReturn("GET");
given(hsRequest.getContextPath()).willReturn("/bonita");
}
@Test
public void should_redirect_to_home_page_when_accessing_living_application_root() throws Exception {
given(applicationModel.getApplicationHomePage()).willReturn("home/");
given(applicationModel.getApplicationLayoutName()).willReturn(LAYOUT_PAGE_NAME);
given(applicationModel.hasProfileMapped()).willReturn(true);
given(applicationModelFactory.createApplicationModel("HumanResources")).willReturn(applicationModel);
given(hsRequest.getRequestURI()).willReturn("/bonita/apps/HumanResources");
given(hsRequest.getPathInfo()).willReturn("HumanResources");
given(resourceRenderer.getPathSegments("HumanResources")).willReturn(Arrays.asList("HumanResources"));
applicationRouter.route(hsRequest, hsResponse, apiSession, pageRenderer, resourceRenderer, bonitaHomeFolderAccessor);
verify(hsResponse).sendRedirect("home/");
}
@Test(expected = RuntimeException.class)
public void should_throw_an_error_when_the_uri_is_malformed() throws Exception {
given(hsRequest.getRequestURI()).willReturn("/bonita/apps");
applicationRouter.route(hsRequest, hsResponse, apiSession, pageRenderer, resourceRenderer, bonitaHomeFolderAccessor);
}
@Test
public void should_display_layout_page() throws Exception {
accessAuthorizedPage("HumanResources", "leavingRequests");
applicationRouter.route(hsRequest, hsResponse, apiSession, pageRenderer, resourceRenderer, bonitaHomeFolderAccessor);
verify(pageRenderer).displayCustomPage(hsRequest, hsResponse, apiSession, applicationModel.getApplicationLayoutName());
}
@Test
public void should_access_Layout_resource() throws Exception {
accessAuthorizedPage("HumanResources", "layout/css/file.css");
final File layoutFolder = new File("layout");
final String customPageLayoutName = "custompage_layout";
given(applicationModel.getApplicationLayoutName()).willReturn(customPageLayoutName);
given(pageRenderer.getPageResourceProvider(customPageLayoutName, 1L)).willReturn(pageResourceProvider);
given(pageResourceProvider.getPageDirectory()).willReturn(layoutFolder);
given(bonitaHomeFolderAccessor.isInFolder(any(File.class), any(File.class))).willReturn(true);
applicationRouter.route(hsRequest, hsResponse, apiSession, pageRenderer, resourceRenderer, bonitaHomeFolderAccessor);
verify(pageRenderer).ensurePageFolderIsPresent(apiSession, pageResourceProvider);
verify(resourceRenderer).renderFile(hsRequest, hsResponse, new File("layout/resources/css/file.css"), apiSession);
}
@Test
public void should_access_Theme_resource() throws Exception {
accessAuthorizedPage("HumanResources", "theme/css/file.css");
final File themeFolder = new File("theme");
final String customPageThemeName = "custompage_theme";
given(applicationModel.getApplicationThemeName()).willReturn(customPageThemeName);
given(pageRenderer.getPageResourceProvider(customPageThemeName, 1L)).willReturn(pageResourceProvider);
given(pageResourceProvider.getPageDirectory()).willReturn(themeFolder);
given(bonitaHomeFolderAccessor.isInFolder(any(File.class), any(File.class))).willReturn(true);
applicationRouter.route(hsRequest, hsResponse, apiSession, pageRenderer, resourceRenderer, bonitaHomeFolderAccessor);
verify(pageRenderer).ensurePageFolderIsPresent(apiSession, pageResourceProvider);
verify(resourceRenderer).renderFile(hsRequest, hsResponse, new File("theme/resources/css/file.css"), apiSession);
}
@Test
public void should_not_forward_to_the_application_page_template_when_the_page_is_not_in_the_application() throws Exception {
accessUnknownPage("HumanResources", "leavingRequests");
applicationRouter.route(hsRequest, hsResponse, apiSession, pageRenderer, resourceRenderer, bonitaHomeFolderAccessor);
verify(hsResponse).sendError(HttpServletResponse.SC_FORBIDDEN,
"Unauthorized access for the page " + "leavingRequests" + " of the application " + "HumanResources");
verify(pageRenderer, never()).displayCustomPage(hsRequest, hsResponse, apiSession, LAYOUT_PAGE_NAME);
}
@Test
public void should_not_forward_to_the_application_page_template_when_user_is_not_authorized() throws Exception {
accessUnauthorizedPage("HumanResources", "leavingRequests");
applicationRouter.route(hsRequest, hsResponse, apiSession, pageRenderer, resourceRenderer, bonitaHomeFolderAccessor);
verify(hsResponse).sendError(HttpServletResponse.SC_FORBIDDEN,
"Unauthorized access for the page " + "leavingRequests" + " of the application " + "HumanResources");
verify(pageRenderer, never()).displayCustomPage(hsRequest, hsResponse, apiSession, LAYOUT_PAGE_NAME);
}
@Test
public void should_send_not_found_response_when_no_profile_is_mapped_to_application() throws Exception {
accessAuthorizedPage("HumanResources", "leavingRequests");
given(applicationModel.hasProfileMapped()).willReturn(false);
applicationRouter.route(hsRequest, hsResponse, apiSession, pageRenderer, resourceRenderer, bonitaHomeFolderAccessor);
verify(hsResponse).sendError(HttpServletResponse.SC_NOT_FOUND, "No profile mapped to living application");
verify(pageRenderer, never()).displayCustomPage(hsRequest, hsResponse, apiSession, LAYOUT_PAGE_NAME);
}
private void accessAuthorizedPage(final String applicationToken, final String pageToken) throws Exception {
accessPage(applicationToken, pageToken, true, true);
}
private void accessUnauthorizedPage(final String applicationToken, final String pageToken) throws Exception {
accessPage(applicationToken, pageToken, true, false);
}
private void accessUnknownPage(final String applicationToken, final String pageToken) throws Exception {
accessPage(applicationToken, pageToken, true, false);
}
private void accessPage(final String applicationToken, final String pageToken, final boolean hasPage, final boolean isAuthorized) throws Exception {
given(applicationModel.hasPage(pageToken)).willReturn(hasPage);
given(applicationModel.authorize(apiSession)).willReturn(isAuthorized);
given(applicationModel.hasProfileMapped()).willReturn(true);
given(applicationModelFactory.createApplicationModel(applicationToken)).willReturn(applicationModel);
given(hsRequest.getRequestURI()).willReturn("/bonita/apps/" + applicationToken + "/" + pageToken + "/");
given(hsRequest.getPathInfo()).willReturn("/" + applicationToken + "/" + pageToken + "/");
}
}