/*
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.markdown.macro.impl;
import static de.blizzy.documentr.DocumentrMatchers.*;
import static org.junit.Assert.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.springframework.security.core.Authentication;
import com.google.common.collect.Lists;
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.markdown.HtmlSerializerContext;
import de.blizzy.documentr.markdown.macro.IMacroContext;
import de.blizzy.documentr.page.IPageStore;
import de.blizzy.documentr.page.Page;
import de.blizzy.documentr.page.TestPageUtil;
public class NeighborsMacroTest extends AbstractDocumentrTest {
private static final String PROJECT = "project"; //$NON-NLS-1$
private static final String BRANCH = "branch"; //$NON-NLS-1$
private static final String INACCESSIBLE_PAGE_PATH = DocumentrConstants.HOME_PAGE_NAME + "/foo/inaccessible"; //$NON-NLS-1$
@SuppressWarnings("nls")
private static final String[] PAGES = {
DocumentrConstants.HOME_PAGE_NAME,
DocumentrConstants.HOME_PAGE_NAME + "/foo",
DocumentrConstants.HOME_PAGE_NAME + "/foo/aaa",
DocumentrConstants.HOME_PAGE_NAME + "/foo/aaa/a1",
DocumentrConstants.HOME_PAGE_NAME + "/foo/aaa/a2",
DocumentrConstants.HOME_PAGE_NAME + "/foo/bar", // <-- page under test
DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x",
DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x/x1",
DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x/x2",
DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y",
DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y/y1",
DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y/y2",
DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z",
DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z/z1",
DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z/z2",
DocumentrConstants.HOME_PAGE_NAME + "/foo/bbb",
DocumentrConstants.HOME_PAGE_NAME + "/foo/bbb/b1",
INACCESSIBLE_PAGE_PATH
};
@Mock
private IPageStore pageStore;
@Mock
private HtmlSerializerContext htmlSerializerContext;
@Mock
private DocumentrPermissionEvaluator permissionEvaluator;
@Mock
private IMacroContext context;
private List<Page> pages = Lists.newArrayList();
private NeighborsMacro runnable;
@Before
public void setUp() throws IOException {
when(htmlSerializerContext.getPageUri(anyString())).then(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) {
return "/" + invocation.getArguments()[0]; //$NON-NLS-1$
}
});
setupPages();
setupPagePermissions();
when(context.getPageStore()).thenReturn(pageStore);
when(context.getPermissionEvaluator()).thenReturn(permissionEvaluator);
when(context.getLocale()).thenReturn(Locale.US);
runnable = new NeighborsMacro();
}
@Test
public void getHtmlWithDefaultChildren() {
String childrenHtml =
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x</a></li>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y</a></li>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z</a></li>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertHtml(childrenHtml, null);
}
@Test
public void getHtmlWith1Child() {
String childrenHtml =
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x</a></li>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y</a></li>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z</a></li>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
assertHtml(childrenHtml, "children=1"); //$NON-NLS-1$
}
@Test
public void getHtmlWith2Children() {
String childrenHtml =
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x</a>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"<ul class=\"nav nav-list\">" + //$NON-NLS-1$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x/x1\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x/x1\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x/x1</a></li>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x/x2\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x/x2\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/x/x2</a></li>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"</ul>" + //$NON-NLS-1$
"</li>" + //$NON-NLS-1$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y</a>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"<ul class=\"nav nav-list\">" + //$NON-NLS-1$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y/y1\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y/y1\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y/y1</a></li>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y/y2\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y/y2\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/y/y2</a></li>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"</ul>" + //$NON-NLS-1$
"</li>" + //$NON-NLS-1$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z</a>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"<ul class=\"nav nav-list\">" + //$NON-NLS-1$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z/z1\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z/z1\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z/z1</a></li>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z/z2\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z/z2\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar/z/z2</a></li>" + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"</ul>" + //$NON-NLS-1$
"</li>"; //$NON-NLS-1$
assertHtml(childrenHtml, "children=2"); //$NON-NLS-1$
}
private void assertHtml(String childrenHtml, String childrenParam) {
when(htmlSerializerContext.getProjectName()).thenReturn(PROJECT);
when(htmlSerializerContext.getBranchName()).thenReturn(BRANCH);
when(htmlSerializerContext.getPagePath()).thenReturn(DocumentrConstants.HOME_PAGE_NAME + "/foo/bar"); //$NON-NLS-1$
when(context.getHtmlSerializerContext()).thenReturn(htmlSerializerContext);
when(context.getParameters()).thenReturn(childrenParam);
// this is the HTML for home/foo/bar
@SuppressWarnings("nls")
String html =
"<span class=\"well well-small neighbors pull-right\"><ul class=\"nav nav-list\">" +
"<li>" +
"<a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "\">" + DocumentrConstants.HOME_PAGE_NAME + "</a>" +
"<ul class=\"nav nav-list\">" +
"<li>" +
"<a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo</a>" +
"<ul class=\"nav nav-list\">" +
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/aaa\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/aaa\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/aaa</a></li>" +
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar\" class=\"active\">" +
"<a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bar</a>" +
"<ul class=\"nav nav-list\">" +
childrenHtml +
"</ul>" +
"</li>" +
"<li data-path=\"" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bbb\"><a href=\"/" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bbb\">" + DocumentrConstants.HOME_PAGE_NAME + "/foo/bbb</a></li>" +
"</ul>" +
"</li>" +
"</ul>" +
"</li>" +
"</ul></span>";
assertEquals(html, runnable.getHtml(context));
}
private void setupPages() throws IOException {
setupPages(PAGES);
for (Page page : pages) {
List<Page> childPages = Lists.newArrayList();
String childPagePrefix = page.getPath() + "/"; //$NON-NLS-1$
for (Page childPage : pages) {
if (childPage.getPath().startsWith(childPagePrefix)) {
String rest = StringUtils.substringAfter(childPage.getPath(), childPagePrefix);
if (!rest.contains("/")) { //$NON-NLS-1$
childPages.add(childPage);
}
}
}
when(pageStore.listChildPagesOrdered(PROJECT, BRANCH, page.getPath(), Locale.US)).thenReturn(childPages);
}
}
private void setupPagePermissions() {
when(permissionEvaluator.hasPagePermission(Matchers.<Authentication>any(),
eq(PROJECT), eq(BRANCH), notEq(INACCESSIBLE_PAGE_PATH), same(Permission.VIEW)))
.thenReturn(true);
when(permissionEvaluator.hasPagePermission(Matchers.<Authentication>any(),
eq(PROJECT), eq(BRANCH), eq(INACCESSIBLE_PAGE_PATH), same(Permission.VIEW)))
.thenReturn(false);
}
private void setupPages(String... pagePaths) throws IOException {
for (String pagePath : pagePaths) {
setupPage(pagePath);
}
}
private void setupPage(String pagePath) throws IOException {
String parentPagePath = pagePath.contains("/") ? //$NON-NLS-1$
StringUtils.substringBeforeLast(pagePath, "/") : //$NON-NLS-1$
null;
Page page = Page.fromText(pagePath, "text"); //$NON-NLS-1$
TestPageUtil.setParentPagePath(page, parentPagePath);
TestPageUtil.setPath(page, pagePath);
when(pageStore.getPage(PROJECT, BRANCH, pagePath, false)).thenReturn(page);
pages.add(page);
}
}