Skip to content

Commit

Permalink
unit tests for BrokenLinksReport and GenericReportExcelServlet
Browse files Browse the repository at this point in the history
  • Loading branch information
Yegor Kozlov committed Sep 30, 2017
1 parent 978e322 commit 6f5a2c5
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 102 deletions.
6 changes: 6 additions & 0 deletions bundle/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,12 @@
<artifactId>mockserver-netty</artifactId>
<version>3.10.4</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,86 @@
/*
* #%L
* ACS AEM Commons Bundle
* %%
* Copyright (C) 2017 Adobe
* %%
* Licensed 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.
* #L%
*/
package com.adobe.acs.commons.mcp.impl;

import com.adobe.acs.commons.mcp.model.GenericReport;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.sling.resourcebuilder.api.ResourceBuilder;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletRequest;
import org.apache.sling.testing.mock.sling.servlet.MockSlingHttpServletResponse;
import org.junit.Rule;
import org.junit.Test;

import java.io.ByteArrayInputStream;

import static org.junit.Assert.assertEquals;

/**
* @author Yegor Kozlov
*/
public class TestGenericReportExcelServlet {
@Rule
public final SlingContext slingContext = new SlingContext(ResourceResolverType.RESOURCERESOLVER_MOCK);


@Test
public void testReport() throws Exception {
int numRows = 10;
String reportPath = "/var/acs-commons/mcp/instances/junit/jcr:content/report";
ResourceBuilder rb = slingContext.build()
.resource(reportPath,
"columns", new String[]{"ColumnA", "ColumnB"},
"name", "report",
"sling:resourceType", "acs-commons/components/utilities/process-instance/process-generic-report")
.resource("rows");
rb.siblingsMode();
for (int i = 1; i <= numRows; i++) {
rb.resource("row-" + i,
"ColumnA", "abcdef-" + i, "ColumnB", "qwerty-" + i);
}
MockSlingHttpServletRequest request = slingContext.request();
request.setResource(slingContext.resourceResolver().getResource(reportPath));
MockSlingHttpServletResponse response = slingContext.response();

slingContext.addModelsForClasses(GenericReport.class);

GenericReportExcelServlet servlet = new GenericReportExcelServlet();
servlet.doGet(request, response);

assertEquals("application/vnd.ms-excel", response.getContentType());

Workbook wb = WorkbookFactory.create(new ByteArrayInputStream(response.getOutput()));
Sheet sh = wb.getSheetAt(0);
assertEquals(numRows, sh.getLastRowNum());
Row header = sh.getRow(0);
assertEquals("Column A", header.getCell(0).getStringCellValue());
assertEquals("Column B", header.getCell(1).getStringCellValue());
for (int i = 1; i <= numRows; i++) {
Row row = sh.getRow(i);
assertEquals("abcdef-" + i, row.getCell(0).getStringCellValue());
assertEquals("qwerty-" + i, row.getCell(1).getStringCellValue());
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,148 +18,114 @@
import com.adobe.acs.commons.fam.ActionManager;
import com.adobe.acs.commons.fam.ActionManagerFactory;
import com.adobe.acs.commons.fam.impl.ActionManagerFactoryImpl;
import static com.adobe.acs.commons.fam.impl.ActionManagerTest.*;
import com.adobe.acs.commons.mcp.ControlledProcessManager;
import com.adobe.acs.commons.mcp.ProcessInstance;
import com.adobe.acs.commons.mcp.impl.AbstractResourceImpl;
import com.adobe.acs.commons.mcp.impl.ProcessInstanceImpl;
import com.adobe.acs.commons.mcp.util.DeserializeException;
import com.day.cq.replication.Replicator;
import com.day.cq.wcm.api.PageManagerFactory;

import java.util.HashMap;
import java.util.Map;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.Privilege;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.NonExistingResource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.testing.mock.sling.ResourceResolverType;
import org.apache.sling.testing.mock.sling.junit.SlingContext;
import static org.junit.Assert.*;

import static com.adobe.acs.commons.mcp.impl.processes.BrokenLinksReport.REPORT;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.Privilege;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;

import static com.adobe.acs.commons.fam.impl.ActionManagerTest.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
*
*/
public class PageRelocatorTest {
public class BrokenLinksTest {
@Rule
public final SlingContext slingContext = new SlingContext(ResourceResolverType.RESOURCERESOLVER_MOCK);

PageRelocator tool;
BrokenLinksReport tool;

@Before
public void setup() {
tool = getPageRelocatorTool();
tool = getBrokenLinksReport();
}

@Test
public void barebonesRun() throws LoginException, DeserializeException, RepositoryException, PersistenceException {
ResourceResolver rr = getEnhancedMockResolver(true);
ProcessInstance instance = new ProcessInstanceImpl(getControlledProcessManager(), tool, "relocator test");
public void reportBrokenReferences() throws Exception {
ResourceResolver rr = getEnhancedMockResolver();

assertEquals("Page Relocator: relocator test", instance.getName());
initInstance(instance, rr);
assertEquals(0.0, instance.updateProgress(), 0.00001);
instance.run(rr);
assertEquals(1.0, instance.updateProgress(), 0.00001);
verify(rr, atLeast(3)).commit();
}
AbstractResourceImpl content = new AbstractResourceImpl("/content", "cq:Page", "cq:Page", new ResourceMetadata());

@Test
public void aclFail() throws LoginException, DeserializeException, RepositoryException, PersistenceException {
ResourceResolver rr = getEnhancedMockResolver(false);
ProcessInstance instance = new ProcessInstanceImpl(getControlledProcessManager(), tool, "relocator test");
AbstractResourceImpl pageA = new AbstractResourceImpl("/content/pageA", "cq:Page", "cq:Page", new ResourceMetadata());
content.addChild(pageA);
AbstractResourceImpl pageAcontent = new AbstractResourceImpl("/content/pageA/jcr:content", "cq:PageContent", "cq:PageContent", new ResourceMetadata() {{
put("ref1", "/content/pageA");
put("ref2", "/content/pageB");
put("ref3", "/content/pageC");
}});
pageA.addChild(pageAcontent);
AbstractResourceImpl pageB = new AbstractResourceImpl("/content/pageB", "cq:Page", "cq:Page", new ResourceMetadata());
content.addChild(pageB);
AbstractResourceImpl pageBcontent = new AbstractResourceImpl("/content/pageB/jcr:content", "cq:PageContent", "cq:PageContent", new ResourceMetadata() {{
put("ignoredRef", "/content/pageC");
put("ref2", "/content/pageD");
put("ref3", "/content/pageE");
}});
pageB.addChild(pageBcontent);
when(rr.getResource("/content")).thenReturn(content);

pageA.setResourceResolver(rr);
pageAcontent.setResourceResolver(rr);
pageB.setResourceResolver(rr);
pageBcontent.setResourceResolver(rr);

when(rr.resolve("/content/pageA")).thenReturn(pageA);
when(rr.resolve("/content/pageB")).thenReturn(pageB);
when(rr.resolve("/content/pageC")).thenReturn(new NonExistingResource(rr, "/content/pageC"));
when(rr.resolve("/content/pageD")).thenReturn(new NonExistingResource(rr, "/content/pageD"));
when(rr.resolve("/content/pageE")).thenReturn(new NonExistingResource(rr, "/content/pageE"));

Map<String, Object> values = new HashMap<>();
values.put("sourcePath", "/content");
values.put("propertyRegex", "^/(etc|content)/.+");
values.put("excludeProperties", "ignoredRef");

assertEquals("Page Relocator: relocator test", instance.getName());
initInstance(instance, rr);
ProcessInstanceImpl instance = new ProcessInstanceImpl(getControlledProcessManager(), tool, "broken references");
instance.init(rr, values);
instance.run(rr);
assertFalse("ACL issues should have been tracked", instance.getInfo().getReportedErrors().isEmpty());
assertEquals("Aborted", instance.getInfo().getStatus());
}

@Test
public void validateMoveOperation() throws RepositoryException, LoginException, DeserializeException, PersistenceException {
ResourceResolver rr = getEnhancedMockResolver(true);
ProcessInstance instance = new ProcessInstanceImpl(getControlledProcessManager(), tool, "relocator test");
initInstance(instance, rr);

ActionManager manager = getActionManager();
tool.movePages(manager);
assertTrue("Should be no reported errors", manager.getErrorCount() == 0);
assertFalse("Should have captured activate requests", tool.replicatorQueue.activateOperations.isEmpty());
assertFalse("Should have captured deactivate requests", tool.replicatorQueue.deactivateOperations.isEmpty());

// Our mock doesn't pretend to create target pages at the moment...
// Resource pageB = rr.getResource("/content/pageB");
// verify(rr, times(1)).create(eq(pageB), eq("pageA"), any());
verify(rr, atLeastOnce()).commit();
Map<String, EnumMap<REPORT, Object>> reportData = tool.getReportData();
assertEquals(3, reportData.size());
assertEquals("/content/pageC", reportData.get("/content/pageA/jcr:content/ref3").get(REPORT.reference));
assertEquals("/content/pageD", reportData.get("/content/pageB/jcr:content/ref2").get(REPORT.reference));
assertEquals("/content/pageE", reportData.get("/content/pageB/jcr:content/ref3").get(REPORT.reference));

assertFalse("ignoredRef is in the exclude list", reportData.containsKey("/content/pageB/jcr:content/ignoredRef"));
}

private PageRelocator getPageRelocatorTool() {
PageManagerFactory mockPageManagerFactory = mock(PageManagerFactory.class);
when(mockPageManagerFactory.getPageManager(any())).then(invocation->new MockPageManager(getMockResolver()));
slingContext.registerService(PageManagerFactory.class, mockPageManagerFactory);

Replicator replicator = mock(Replicator.class);
slingContext.registerService(Replicator.class, replicator);
private BrokenLinksReport getBrokenLinksReport() {

PageRelocatorFactory t = new PageRelocatorFactory();
BrokenLinksReportFactory t = new BrokenLinksReportFactory();
slingContext.registerInjectActivateService(t);

return t.createProcessDefinition();
}

private void initInstance(ProcessInstance instance, ResourceResolver rr) throws RepositoryException, DeserializeException {
Map<String, Object> values = new HashMap<>();
values.put("sourcePath", "/content/pageA");
values.put("destinationPath", "/content/pageB");
values.put("maxReferences", "0");
values.put("mode", PageRelocator.Mode.MOVE.toString());
values.put("publishMethod", PageRelocator.PUBLISH_METHOD.SELF_MANAGED.toString());
values.put("createVerionsOnReplicate", "false");
values.put("updateStatus", "true");
values.put("dryRun", "false");
instance.init(rr, values);

AbstractResourceImpl processNode = new AbstractResourceImpl(instance.getPath(), null, null, new ResourceMetadata());
when(rr.getResource(instance.getPath())).thenReturn(processNode);
AbstractResourceImpl processContentNode = new AbstractResourceImpl(instance.getPath() + "/jcr:content", null, null, new ResourceMetadata());
when(rr.getResource(instance.getPath() + "/jcr:content")).thenReturn(processContentNode);
AbstractResourceImpl processResultNode = new AbstractResourceImpl(instance.getPath() + "/jcr:content/result", null, null, new ResourceMetadata());
when(rr.getResource(instance.getPath() + "/jcr:content/result")).thenReturn(processResultNode);
AbstractResourceImpl failuresNode = new AbstractResourceImpl(instance.getPath() + "/jcr:content/failures", null, null, new ResourceMetadata());
when(rr.getResource(instance.getPath() + "/jcr:content/failures")).thenReturn(processResultNode);
when(rr.getResource(instance.getPath() + "/jcr:content/failures/step1")).thenReturn(processResultNode);
}

private ResourceResolver getEnhancedMockResolver(final boolean aclChecksPass) throws RepositoryException, LoginException {
private ResourceResolver getEnhancedMockResolver() throws RepositoryException, LoginException {
ResourceResolver rr = getFreshMockResolver();

when(rr.hasChanges()).thenReturn(true);

AbstractResourceImpl pageA = new AbstractResourceImpl("/content/pageA", "cq:Page", "cq:Page", new ResourceMetadata());
when(rr.getResource("/content/pageA")).thenReturn(pageA);
AbstractResourceImpl pageAcontent = new AbstractResourceImpl("/content/pageA/jcr:content", "cq:PageContent", "cq:PageContent", new ResourceMetadata());
when(rr.getResource("/content/pageA/jcr:content")).thenReturn(pageAcontent);
AbstractResourceImpl pageB = new AbstractResourceImpl("/content/pageB", "cq:Page", "cq:Page", new ResourceMetadata());
when(rr.getResource("/content/pageB")).thenReturn(pageB);
AbstractResourceImpl content = new AbstractResourceImpl("/content", "cq:Page", "cq:Page", new ResourceMetadata());
AbstractResourceImpl pageBcontent = new AbstractResourceImpl("/content/pageB/jcr:content", "cq:PageContent", "cq:PageContent", new ResourceMetadata());
when(rr.getResource("/content/pageB/jcr:content")).thenReturn(pageBcontent);
when(rr.getResource("/content")).thenReturn(content);
content.addChild(pageA);
content.addChild(pageB);

AbstractResourceImpl processes = new AbstractResourceImpl(ProcessInstanceImpl.BASE_PATH, null, null, new ResourceMetadata());
when(rr.getResource(ProcessInstanceImpl.BASE_PATH)).thenReturn(processes);

Expand All @@ -168,11 +134,12 @@ private ResourceResolver getEnhancedMockResolver(final boolean aclChecksPass) th
AccessControlManager acm = mock(AccessControlManager.class);
when(ses.getAccessControlManager()).thenReturn(acm);
when(acm.privilegeFromName(any())).thenReturn(mock(Privilege.class));
when(acm.hasPrivileges(any(), any())).thenReturn(aclChecksPass);
when(acm.hasPrivileges(any(), any())).thenReturn(true);

return rr;
}


private ControlledProcessManager getControlledProcessManager() throws LoginException {
ActionManager am = getActionManager();

Expand Down

0 comments on commit 6f5a2c5

Please sign in to comment.