/* documentr - Edit, maintain, and present software documentation on the web. Copyright (C) 2012-2013 Maik Schreiber This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package de.blizzy.documentr.web.page; import static de.blizzy.documentr.DocumentrMatchers.*; import static de.blizzy.documentr.TestUtil.*; import static org.junit.Assert.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.io.IOException; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.SortedMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Matchers; import org.mockito.Mock; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.ui.Model; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.BindingResult; import org.springframework.web.context.request.WebRequest; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import de.blizzy.documentr.AbstractDocumentrTest; import de.blizzy.documentr.DocumentrConstants; import de.blizzy.documentr.access.DocumentrPermissionEvaluator; import de.blizzy.documentr.access.Permission; import de.blizzy.documentr.access.User; import de.blizzy.documentr.access.UserStore; import de.blizzy.documentr.markdown.IPageRenderer; import de.blizzy.documentr.markdown.MarkdownProcessor; import de.blizzy.documentr.page.CommitCherryPickConflictResolve; import de.blizzy.documentr.page.CommitCherryPickResult; import de.blizzy.documentr.page.ICherryPicker; import de.blizzy.documentr.page.IPageStore; import de.blizzy.documentr.page.Page; import de.blizzy.documentr.page.PageMetadata; import de.blizzy.documentr.page.PageNotFoundException; import de.blizzy.documentr.page.PageVersion; import de.blizzy.documentr.page.TestPageUtil; import de.blizzy.documentr.repository.IGlobalRepositoryManager; import de.blizzy.documentr.util.Util; public class PageControllerTest extends AbstractDocumentrTest { private static final String PROJECT = "project"; //$NON-NLS-1$ private static final String BRANCH = "branch"; //$NON-NLS-1$ private static final String PAGE_PATH = DocumentrConstants.HOME_PAGE_NAME + "/page"; //$NON-NLS-1$ private static final String PAGE_PATH_URL = DocumentrConstants.HOME_PAGE_NAME + ",page"; //$NON-NLS-1$ private static final String PAGE_NAME = "page"; //$NON-NLS-1$ private static final String PARENT_PAGE = DocumentrConstants.HOME_PAGE_NAME; private static final String CONTEXT = "/context"; //$NON-NLS-1$ private static final User USER = new User("currentUser", "pw", "admin@example.com", false); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ private static final Locale LOCALE = Locale.ENGLISH; @Mock private IPageStore pageStore; @Mock private ICherryPicker cherryPicker; @Mock private IGlobalRepositoryManager repoManager; @Mock private UserStore userStore; @Mock private IPageRenderer pageRenderer; @Mock private MarkdownProcessor markdownProcessor; @Mock private Authentication authenticatedAuthentication; @Mock private Authentication anonymousAuthentication; @Mock private HttpSession session; @Mock private HttpServletRequest request; @Mock private HttpServletResponse response; @Mock private Model model; @Mock private DocumentrPermissionEvaluator permissionEvaluator; @Mock private PageMetadata pageMetadata; @Mock private WebRequest webRequest; @InjectMocks private PageController pageController; @Before public void setUp() throws IOException { when(userStore.getUser(USER.getLoginName())).thenReturn(USER); when(authenticatedAuthentication.isAuthenticated()).thenReturn(true); when(authenticatedAuthentication.getName()).thenReturn(USER.getLoginName()); when(authenticatedAuthentication.isAuthenticated()).thenReturn(false); } @Test public void getPage() throws IOException { when(session.getAttribute("authenticationCreationTime")).thenReturn(System.currentTimeMillis()); //$NON-NLS-1$ when(request.getDateHeader(anyString())).thenReturn(-1L); when(request.getSession()).thenReturn(session); getPage(request); } @Test public void getPageMustReturnNormallyIfModified() throws IOException { when(session.getAttribute("authenticationCreationTime")).thenReturn(System.currentTimeMillis()); //$NON-NLS-1$ when(request.getDateHeader("If-Modified-Since")).thenReturn( //$NON-NLS-1$ new GregorianCalendar(2000, Calendar.JANUARY, 1).getTimeInMillis()); when(request.getSession()).thenReturn(session); getPage(request); } private void getPage(HttpServletRequest request) throws IOException { Date lastModified = new Date(); when(pageStore.getPageMetadata(PROJECT, BRANCH, PAGE_PATH)).thenReturn( new PageMetadata("user", lastModified, 123, "commit")); //$NON-NLS-1$ //$NON-NLS-2$ Page page = Page.fromText("title", "text"); //$NON-NLS-1$ //$NON-NLS-2$ page.setViewRestrictionRole("viewRole"); //$NON-NLS-1$ TestPageUtil.setParentPagePath(page, PARENT_PAGE); when(pageStore.getPage(PROJECT, BRANCH, PAGE_PATH, false)).thenReturn(page); SecurityContextHolder.setContext(createSecurityContext(anonymousAuthentication)); String view = pageController.getPage(PROJECT, BRANCH, PAGE_PATH_URL, model, request, response); SecurityContextHolder.clearContext(); assertEquals("/project/branch/page/view", view); //$NON-NLS-1$ verify(model).addAttribute("path", PAGE_PATH); //$NON-NLS-1$ verify(model).addAttribute("pageName", PAGE_NAME); //$NON-NLS-1$ verify(model).addAttribute("parentPagePath", PARENT_PAGE); //$NON-NLS-1$ verify(model).addAttribute("title", page.getTitle()); //$NON-NLS-1$ verify(model).addAttribute("viewRestrictionRole", page.getViewRestrictionRole()); //$NON-NLS-1$ verify(response).setDateHeader("Last-Modified", lastModified.getTime()); //$NON-NLS-1$ } @Test public void getPageMustReturn404IfNotFound() throws IOException { when(request.getDateHeader(anyString())).thenReturn(-1L); when(pageStore.getPageMetadata(eq(PROJECT), eq(BRANCH), eq("nonexistent"))) //$NON-NLS-1$ .thenThrow(new PageNotFoundException(PROJECT, BRANCH, "nonexistent")); //$NON-NLS-1$ SecurityContextHolder.setContext(createSecurityContext(authenticatedAuthentication)); String view = pageController.getPage(PROJECT, BRANCH, "nonexistent", model, request, response); //$NON-NLS-1$ SecurityContextHolder.clearContext(); assertEquals("/error/" + HttpServletResponse.SC_NOT_FOUND + "/page.notFound", removeViewPrefix(view)); //$NON-NLS-1$ //$NON-NLS-2$ assertForward(view); } @Test public void getPageMustReturn304IfNotModified() throws IOException { when(session.getAttribute("authenticationCreationTime")).thenReturn( //$NON-NLS-1$ new GregorianCalendar(2012, Calendar.JUNE, 2).getTime().getTime()); when(request.getDateHeader("If-Modified-Since")).thenReturn( //$NON-NLS-1$ new GregorianCalendar(2012, Calendar.JUNE, 9).getTimeInMillis()); when(request.getSession()).thenReturn(session); when(pageStore.getPageMetadata(eq(PROJECT), eq(BRANCH), eq("nonexistent"))) //$NON-NLS-1$ .thenReturn(new PageMetadata("user", new GregorianCalendar(2012, Calendar.JUNE, 1).getTime(), 123, "commit")); //$NON-NLS-1$ //$NON-NLS-2$ TestPageUtil.clearProjectEditTimes(); SecurityContextHolder.setContext(createSecurityContext(anonymousAuthentication)); String view = pageController.getPage(PROJECT, BRANCH, "nonexistent", model, request, response); //$NON-NLS-1$ SecurityContextHolder.clearContext(); assertTrue(removeViewPrefix(view).startsWith("/error/" + HttpServletResponse.SC_NOT_MODIFIED + "/")); //$NON-NLS-1$ //$NON-NLS-2$ assertForward(view); } @Test public void createPage() { String view = pageController.createPage(PROJECT, BRANCH, PARENT_PAGE, model); assertEquals("/project/branch/page/edit", view); //$NON-NLS-1$ verify(model).addAttribute(eq("pageForm"), //$NON-NLS-1$ argPageForm(PROJECT, BRANCH, null, PARENT_PAGE, null, null, null)); } @Test public void editPage() throws IOException { Page page = Page.fromText("title", "text"); //$NON-NLS-1$ //$NON-NLS-2$ TestPageUtil.setParentPagePath(page, PARENT_PAGE); when(pageStore.getPage(PROJECT, BRANCH, PAGE_PATH, true)).thenReturn(page); when(pageStore.getPageMetadata(PROJECT, BRANCH, PAGE_PATH)) .thenReturn(new PageMetadata("user", new Date(), 123, "commit")); //$NON-NLS-1$ //$NON-NLS-2$ String view = pageController.editPage(PROJECT, BRANCH, PAGE_PATH_URL, model, session); assertEquals("/project/branch/page/edit", view); //$NON-NLS-1$ verify(model).addAttribute(eq("pageForm"), //$NON-NLS-1$ argPageForm(PROJECT, BRANCH, PAGE_PATH, PARENT_PAGE, "title", "text", "commit")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } @Test public void editPageButNonexistent() throws IOException { when(pageStore.getPage(eq(PROJECT), eq(BRANCH), eq("nonexistent"), anyBoolean())) //$NON-NLS-1$ .thenThrow(new PageNotFoundException(PROJECT, BRANCH, "nonexistent")); //$NON-NLS-1$ String view = pageController.editPage(PROJECT, BRANCH, "nonexistent", model, session); //$NON-NLS-1$ assertEquals("/error/" + HttpServletResponse.SC_NOT_FOUND + "/page.notFound", removeViewPrefix(view)); //$NON-NLS-1$ //$NON-NLS-2$ assertForward(view); } @Test public void savePage() throws IOException { when(repoManager.listProjectBranches(PROJECT)).thenReturn(Collections.singletonList(BRANCH)); PageForm pageForm = new PageForm(PROJECT, BRANCH, PAGE_PATH, PARENT_PAGE, "title", "text", null, null, //$NON-NLS-1$ //$NON-NLS-2$ ArrayUtils.EMPTY_STRING_ARRAY, DocumentrConstants.PAGE_ORDER_INDEX_UNORDERED); BindingResult bindingResult = new BeanPropertyBindingResult(pageForm, "pageForm"); //$NON-NLS-1$ String view = pageController.savePage(pageForm, bindingResult, model, authenticatedAuthentication); assertEquals("/page/" + PROJECT + "/" + BRANCH + "/" + PAGE_PATH_URL, removeViewPrefix(view)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertRedirect(view); assertFalse(bindingResult.hasErrors()); verify(pageStore).savePage(eq(PROJECT), eq(BRANCH), eq(PAGE_PATH), argPage("title", "text"), isNull(String.class), same(USER)); //$NON-NLS-1$ //$NON-NLS-2$ } @Test public void savePageWithViewRestrictionRole() throws IOException { when(repoManager.listProjectBranches(PROJECT)).thenReturn(Collections.singletonList(BRANCH)); PageForm pageForm = new PageForm(PROJECT, BRANCH, PAGE_PATH, PARENT_PAGE, "title", "text", "viewRole", null, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ ArrayUtils.EMPTY_STRING_ARRAY, DocumentrConstants.PAGE_ORDER_INDEX_UNORDERED); BindingResult bindingResult = new BeanPropertyBindingResult(pageForm, "pageForm"); //$NON-NLS-1$ String view = pageController.savePage(pageForm, bindingResult, model, authenticatedAuthentication); assertEquals("/page/" + PROJECT + "/" + BRANCH + "/" + PAGE_PATH_URL, removeViewPrefix(view)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertRedirect(view); assertFalse(bindingResult.hasErrors()); verify(pageStore).savePage(eq(PROJECT), eq(BRANCH), eq(PAGE_PATH), argPage(ANY, "title", "text", "viewRole"), isNull(String.class), same(USER)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } @Test public void savePageMustNotChangeExistingPath() throws IOException { when(repoManager.listProjectBranches(PROJECT)).thenReturn(Collections.singletonList(BRANCH)); PageForm pageForm = new PageForm(PROJECT, BRANCH, PAGE_PATH, PARENT_PAGE, "title", "text", null, null, //$NON-NLS-1$ //$NON-NLS-2$ ArrayUtils.EMPTY_STRING_ARRAY, DocumentrConstants.PAGE_ORDER_INDEX_UNORDERED); BindingResult bindingResult = new BeanPropertyBindingResult(pageForm, "pageForm"); //$NON-NLS-1$ pageController.savePage(pageForm, bindingResult, model, authenticatedAuthentication); Page page = Page.fromText("title", "text"); //$NON-NLS-1$ //$NON-NLS-2$ when(pageStore.getPage(PROJECT, BRANCH, PAGE_PATH, true)).thenReturn(page); pageForm = new PageForm(PROJECT, BRANCH, PAGE_PATH, PARENT_PAGE, "title2", "text2", null, null, //$NON-NLS-1$ //$NON-NLS-2$ ArrayUtils.EMPTY_STRING_ARRAY, DocumentrConstants.PAGE_ORDER_INDEX_UNORDERED); bindingResult = new BeanPropertyBindingResult(pageForm, "pageForm"); //$NON-NLS-1$ String view = pageController.savePage(pageForm, bindingResult, model, authenticatedAuthentication); assertEquals("/page/" + PROJECT + "/" + BRANCH + "/" + PAGE_PATH_URL, removeViewPrefix(view)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertRedirect(view); assertFalse(bindingResult.hasErrors()); verify(pageStore).savePage(eq(PROJECT), eq(BRANCH), eq(PAGE_PATH), argPage("title2", "text2"), isNull(String.class), same(USER)); //$NON-NLS-1$ //$NON-NLS-2$ } @Test public void savePageBlankPath() throws IOException { when(repoManager.listProjectBranches(PROJECT)).thenReturn(Collections.singletonList(BRANCH)); String title = "title"; //$NON-NLS-1$ PageForm pageForm = new PageForm(PROJECT, BRANCH, StringUtils.EMPTY, PARENT_PAGE, title, "text", null, null, //$NON-NLS-1$ ArrayUtils.EMPTY_STRING_ARRAY, DocumentrConstants.PAGE_ORDER_INDEX_UNORDERED); BindingResult bindingResult = new BeanPropertyBindingResult(pageForm, "pageForm"); //$NON-NLS-1$ String view = pageController.savePage(pageForm, bindingResult, model, authenticatedAuthentication); String path = PARENT_PAGE + "/" + Util.simplifyForUrl(title); //$NON-NLS-1$ String pathUrl = Util.toUrlPagePath(path); assertEquals("/page/" + PROJECT + "/" + BRANCH + "/" + pathUrl, removeViewPrefix(view)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertRedirect(view); assertFalse(bindingResult.hasErrors()); verify(pageStore).savePage(eq(PROJECT), eq(BRANCH), eq(path), argPage(title, "text"), isNull(String.class), same(USER)); //$NON-NLS-1$ } @Test public void savePageShouldDoNothingIfNoChanges() throws IOException { when(repoManager.listProjectBranches(PROJECT)).thenReturn(Collections.singletonList(BRANCH)); Page page = Page.fromText("title", "text"); //$NON-NLS-1$ //$NON-NLS-2$ when(pageStore.getPage(PROJECT, BRANCH, PAGE_PATH, true)).thenReturn(page); PageForm pageForm = new PageForm(PROJECT, BRANCH, PAGE_PATH, PARENT_PAGE, "title", "text", null, null, //$NON-NLS-1$ //$NON-NLS-2$ ArrayUtils.EMPTY_STRING_ARRAY, DocumentrConstants.PAGE_ORDER_INDEX_UNORDERED); BindingResult bindingResult = new BeanPropertyBindingResult(pageForm, "pageForm"); //$NON-NLS-1$ pageController.savePage(pageForm, bindingResult, model, authenticatedAuthentication); verify(pageStore, never()).savePage( anyString(), anyString(), anyString(), Matchers.<Page>any(), anyString(), Matchers.<User>any()); } @Test public void savePageButNonexistentBranch() throws IOException { when(repoManager.listProjectBranches(PROJECT)).thenReturn(Collections.singletonList(BRANCH)); PageForm pageForm = new PageForm(PROJECT, "nonexistent", PAGE_PATH, PARENT_PAGE, "title", "text", null, null, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ ArrayUtils.EMPTY_STRING_ARRAY, DocumentrConstants.PAGE_ORDER_INDEX_UNORDERED); BindingResult bindingResult = new BeanPropertyBindingResult(pageForm, "pageForm"); //$NON-NLS-1$ String view = pageController.savePage(pageForm, bindingResult, model, authenticatedAuthentication); assertEquals("/project/branch/page/edit", view); //$NON-NLS-1$ assertTrue(bindingResult.hasErrors()); assertTrue(bindingResult.hasFieldErrors("branchName")); //$NON-NLS-1$ } @Test public void generateName() throws IOException { String title = "simple as 1, 2, 3"; //$NON-NLS-1$ String path = PARENT_PAGE + "/" + Util.simplifyForUrl(title); //$NON-NLS-1$ when(pageStore.getPage(eq(PROJECT), eq(BRANCH), eq(path), anyBoolean())) .thenThrow(new PageNotFoundException(PROJECT, BRANCH, path)); Map<String, Object> result = pageController.generateName(PROJECT, BRANCH, PARENT_PAGE, title); assertEquals(path, result.get("path")); //$NON-NLS-1$ assertEquals(Boolean.FALSE, result.get("exists")); //$NON-NLS-1$ title = "title"; //$NON-NLS-1$ path = PARENT_PAGE + "/" + Util.simplifyForUrl(title); //$NON-NLS-1$ Page page = Page.fromText(title, "text"); //$NON-NLS-1$ when(pageStore.getPage(PROJECT, BRANCH, path, false)).thenReturn(page); result = pageController.generateName(PROJECT, BRANCH, PARENT_PAGE, title); assertEquals(path, result.get("path")); //$NON-NLS-1$ assertEquals(Boolean.TRUE, result.get("exists")); //$NON-NLS-1$ } @Test public void markdownToHtml() { when(markdownProcessor.markdownToHtml("markdown", PROJECT, BRANCH, PAGE_PATH, //$NON-NLS-1$ authenticatedAuthentication, Locale.US, CONTEXT)).thenReturn("html"); //$NON-NLS-1$ when(markdownProcessor.processNonCacheableMacros("html", PROJECT, BRANCH, PAGE_PATH, //$NON-NLS-1$ authenticatedAuthentication, Locale.US, CONTEXT)).thenReturn("htmlWithMacros"); //$NON-NLS-1$ when(request.getContextPath()).thenReturn(CONTEXT); Map<String, String> result = pageController.markdownToHtml( PROJECT, BRANCH, "markdown", PAGE_PATH, authenticatedAuthentication, Locale.US, request); //$NON-NLS-1$ assertEquals("htmlWithMacros", result.get("html")); //$NON-NLS-1$ //$NON-NLS-2$ } @Test public void copyToBranch() throws IOException { Page page = Page.fromText("title", "text"); //$NON-NLS-1$ //$NON-NLS-2$ when(pageStore.getPage(PROJECT, BRANCH, PAGE_PATH, true)).thenReturn(page); String view = pageController.copyToBranch(PROJECT, BRANCH, PAGE_PATH_URL, "targetBranch", //$NON-NLS-1$ authenticatedAuthentication); assertEquals("/page/edit/" + PROJECT + "/targetBranch/" + PAGE_PATH_URL, removeViewPrefix(view)); //$NON-NLS-1$ //$NON-NLS-2$ assertRedirect(view); verify(pageStore).savePage(eq(PROJECT), eq("targetBranch"), eq(PAGE_PATH), //$NON-NLS-1$ argPage("title", "text"), isNull(String.class), same(USER)); //$NON-NLS-1$ //$NON-NLS-2$ } @Test public void deletePage() throws IOException { String view = pageController.deletePage(PROJECT, BRANCH, PAGE_PATH_URL, authenticatedAuthentication); assertEquals("/page/" + PROJECT + "/" + BRANCH + "/" + DocumentrConstants.HOME_PAGE_NAME, removeViewPrefix(view)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertRedirect(view); verify(pageStore).deletePage(PROJECT, BRANCH, PAGE_PATH, USER); } @Test public void relocatePage() throws IOException { String view = pageController.relocatePage(PROJECT, BRANCH, PAGE_PATH_URL, "home,newparent", //$NON-NLS-1$ authenticatedAuthentication); assertEquals("/page/" + PROJECT + "/" + BRANCH + "/home,newparent,page", removeViewPrefix(view)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertRedirect(view); verify(pageStore).relocatePage(PROJECT, BRANCH, PAGE_PATH, "home/newparent", USER); //$NON-NLS-1$ } @Test public void getPageMarkdown() throws IOException { Set<String> versions = Sets.newHashSet("commit1", "commit2", "nonexistent"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ Map<String, String> markdown = Maps.newHashMap(); markdown.put("commit1", "md1"); //$NON-NLS-1$ //$NON-NLS-2$ markdown.put("commit2", "md2"); //$NON-NLS-1$ //$NON-NLS-2$ when(pageStore.getMarkdown(PROJECT, BRANCH, PAGE_PATH, versions)).thenReturn(markdown); Map<String, String> result = pageController.getPageMarkdown(PROJECT, BRANCH, PAGE_PATH_URL, versions); assertEquals(markdown, result); } @Test public void getPageMarkdownInRange() throws IOException { Page page = Page.fromText("title", "x\ny\nz\n"); //$NON-NLS-1$ //$NON-NLS-2$ when(pageStore.getPage(PROJECT, BRANCH, PAGE_PATH, "commit", true)).thenReturn(page); //$NON-NLS-1$ Map<String, String> result = pageController.getPageMarkdownInRange( PROJECT, BRANCH, PAGE_PATH_URL, 2, 4, "commit"); //$NON-NLS-1$ assertEquals("y", result.get("markdown")); //$NON-NLS-1$ //$NON-NLS-2$ } @Test public void savePageRange() throws IOException { Page page = Page.fromText("title", "x\ny\nz\n"); //$NON-NLS-1$ //$NON-NLS-2$ when(pageStore.getPage(PROJECT, BRANCH, PAGE_PATH, "commit", true)).thenReturn(page); //$NON-NLS-1$ when(pageRenderer.getHtml(PROJECT, BRANCH, PAGE_PATH, authenticatedAuthentication, Locale.US, CONTEXT)) .thenReturn("html"); //$NON-NLS-1$ when(markdownProcessor.processNonCacheableMacros("html", PROJECT, BRANCH, PAGE_PATH, //$NON-NLS-1$ authenticatedAuthentication, Locale.US, CONTEXT)).thenReturn("htmlWithMacros"); //$NON-NLS-1$ when(request.getContextPath()).thenReturn(CONTEXT); when(pageMetadata.getCommit()).thenReturn("newCommit"); //$NON-NLS-1$ when(pageStore.getPageMetadata(PROJECT, BRANCH, PAGE_PATH)).thenReturn(pageMetadata); Map<String, Object> result = pageController.savePageRange(PROJECT, BRANCH, PAGE_PATH_URL, "a\nb\nc\n", "2,4", "commit", authenticatedAuthentication, Locale.US, request); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertEquals("htmlWithMacros", result.get("html")); //$NON-NLS-1$ //$NON-NLS-2$ assertEquals("newCommit", result.get("commit")); //$NON-NLS-1$ //$NON-NLS-2$ verify(pageStore).savePage(eq(PROJECT), eq(BRANCH), eq(PAGE_PATH), argPage("title", "x\na\nb\nc\nz\n"), eq("commit"), same(USER)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } @Test public void getPageChanges() { String view = pageController.getPageChanges(PROJECT, BRANCH, PAGE_PATH_URL, model); assertEquals("/project/branch/page/changes", view); //$NON-NLS-1$ verify(model).addAttribute("projectName", PROJECT); //$NON-NLS-1$ verify(model).addAttribute("branchName", BRANCH); //$NON-NLS-1$ verify(model).addAttribute("path", PAGE_PATH); //$NON-NLS-1$ } @Test public void restoreVersion() throws IOException { pageController.restoreVersion(PROJECT, BRANCH, PAGE_PATH_URL, "version", authenticatedAuthentication); //$NON-NLS-1$ verify(pageStore).restorePageVersion(PROJECT, BRANCH, PAGE_PATH, "version", USER); //$NON-NLS-1$ } @Test public void cherryPick() throws IOException { when(permissionEvaluator.hasPagePermission( authenticatedAuthentication, PROJECT, "targetBranch", PAGE_PATH, Permission.EDIT_PAGE)) //$NON-NLS-1$ .thenReturn(true); when(cherryPicker.getCommitsList(PROJECT, BRANCH, PAGE_PATH, "version2", "version4")) //$NON-NLS-1$ //$NON-NLS-2$ .thenReturn(Lists.newArrayList("version3", "version4")); //$NON-NLS-1$ //$NON-NLS-2$ @SuppressWarnings("nls") List<CommitCherryPickResult> branchResults = Lists.newArrayList( new CommitCherryPickResult(new PageVersion("version3", "user", new Date()), CommitCherryPickResult.Status.OK), new CommitCherryPickResult(new PageVersion("version3", "user", new Date()), CommitCherryPickResult.Status.OK)); SortedMap<String, List<CommitCherryPickResult>> results = Maps.newTreeMap(); results.put("targetBranch", branchResults); //$NON-NLS-1$ when(cherryPicker.cherryPick(PROJECT, BRANCH, PAGE_PATH, Lists.newArrayList("version3", "version4"), //$NON-NLS-1$ //$NON-NLS-2$ Sets.newHashSet("targetBranch"), Collections.<CommitCherryPickConflictResolve>emptySet(), false, //$NON-NLS-1$ USER, LOCALE)) .thenReturn(results); String view = pageController.cherryPick(PROJECT, BRANCH, PAGE_PATH, "version2", "version4", //$NON-NLS-1$ //$NON-NLS-2$ Sets.newHashSet("targetBranch"), false, webRequest, model, authenticatedAuthentication, LOCALE); //$NON-NLS-1$ assertEquals("/page/" + PROJECT + "/" + BRANCH + "/" + PAGE_PATH_URL, removeViewPrefix(view)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertRedirect(view); } @Test public void cherryPickWithConflicts() throws IOException { when(permissionEvaluator.hasPagePermission( authenticatedAuthentication, PROJECT, "targetBranch", PAGE_PATH, Permission.EDIT_PAGE)) //$NON-NLS-1$ .thenReturn(true); when(cherryPicker.getCommitsList(PROJECT, BRANCH, PAGE_PATH, "version2", "version4")) //$NON-NLS-1$ //$NON-NLS-2$ .thenReturn(Lists.newArrayList("version3", "version4")); //$NON-NLS-1$ //$NON-NLS-2$ @SuppressWarnings("nls") List<CommitCherryPickResult> branchResults = Lists.newArrayList( new CommitCherryPickResult(new PageVersion("version3", "user", new Date()), CommitCherryPickResult.Status.OK), new CommitCherryPickResult(new PageVersion("version3", "user", new Date()), "conflictText")); SortedMap<String, List<CommitCherryPickResult>> results = Maps.newTreeMap(); results.put("targetBranch", branchResults); //$NON-NLS-1$ when(cherryPicker.cherryPick(PROJECT, BRANCH, PAGE_PATH, Lists.newArrayList("version3", "version4"), //$NON-NLS-1$ //$NON-NLS-2$ Sets.newHashSet("targetBranch"), Collections.<CommitCherryPickConflictResolve>emptySet(), false, //$NON-NLS-1$ USER, LOCALE)) .thenReturn(results); String view = pageController.cherryPick(PROJECT, BRANCH, PAGE_PATH, "version2", "version4", //$NON-NLS-1$ //$NON-NLS-2$ Sets.newHashSet("targetBranch"), false, webRequest, model, authenticatedAuthentication, LOCALE); //$NON-NLS-1$ assertEquals("/project/branch/page/cherryPick", view); //$NON-NLS-1$ verify(model).addAttribute("cherryPickResults", results); //$NON-NLS-1$ verify(model).addAttribute("version1", "version2"); //$NON-NLS-1$ //$NON-NLS-2$ verify(model).addAttribute("version2", "version4"); //$NON-NLS-1$ //$NON-NLS-2$ verify(model).addAttribute("resolves", Collections.emptySet()); //$NON-NLS-1$ } @Test public void cherryPickWithConflictsAndResolveTexts() throws IOException { when(permissionEvaluator.hasPagePermission( authenticatedAuthentication, PROJECT, "targetBranch", PAGE_PATH, Permission.EDIT_PAGE)) //$NON-NLS-1$ .thenReturn(true); when(cherryPicker.getCommitsList(PROJECT, BRANCH, PAGE_PATH, "version2", "version4")) //$NON-NLS-1$ //$NON-NLS-2$ .thenReturn(Lists.newArrayList("version3", "version4")); //$NON-NLS-1$ //$NON-NLS-2$ @SuppressWarnings("nls") Set<CommitCherryPickConflictResolve> resolves = Sets.newHashSet( new CommitCherryPickConflictResolve("targetBranch", "version3", "resolveText")); @SuppressWarnings("nls") List<CommitCherryPickResult> branchResults = Lists.newArrayList( new CommitCherryPickResult(new PageVersion("version3", "user", new Date()), CommitCherryPickResult.Status.OK), new CommitCherryPickResult(new PageVersion("version3", "user", new Date()), CommitCherryPickResult.Status.OK)); SortedMap<String, List<CommitCherryPickResult>> results = Maps.newTreeMap(); results.put("targetBranch", branchResults); //$NON-NLS-1$ when(cherryPicker.cherryPick(PROJECT, BRANCH, PAGE_PATH, Lists.newArrayList("version3", "version4"), //$NON-NLS-1$ //$NON-NLS-2$ Sets.newHashSet("targetBranch"), resolves, false, USER, LOCALE)) //$NON-NLS-1$ .thenReturn(results); Map<String, String[]> params = Maps.newHashMap(); params.put("resolveText_targetBranch/version3", new String[] { "resolveText" }); //$NON-NLS-1$ //$NON-NLS-2$ when(webRequest.getParameterMap()).thenReturn(params); String view = pageController.cherryPick(PROJECT, BRANCH, PAGE_PATH, "version2", "version4", //$NON-NLS-1$ //$NON-NLS-2$ Sets.newHashSet("targetBranch"), false, webRequest, model, authenticatedAuthentication, LOCALE); //$NON-NLS-1$ assertEquals("/page/" + PROJECT + "/" + BRANCH + "/" + PAGE_PATH_URL, removeViewPrefix(view)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ assertRedirect(view); } }