/* * #%L * ACS AEM Commons Bundle * %% * Copyright (C) 2015 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.oak.impl; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.jcr.RepositoryException; import javax.jcr.Session; import com.adobe.acs.commons.analysis.jcrchecksum.ChecksumGenerator; import com.adobe.acs.commons.analysis.jcrchecksum.impl.options.CustomChecksumGeneratorOptions; import org.apache.commons.collections.IteratorUtils; import org.apache.sling.api.resource.ModifiableValueMap; import org.apache.sling.api.wrappers.ModifiableValueMapDecorator; import org.junit.Assert; import org.apache.sling.api.resource.PersistenceException; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ValueMap; import org.apache.sling.testing.resourceresolver.MockValueMap; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Spy; import static org.mockito.Mockito.*; import static org.mockito.Mockito.eq; import org.mockito.runners.MockitoJUnitRunner; import com.adobe.acs.commons.oak.impl.EnsureOakIndex.OakIndexDefinitionException; /** * * Test the algorithm within the JobHandler, but do not validate the inner working of the * performing methods * * */ @RunWith(MockitoJUnitRunner.class) public class EnsureOakIndexJobHandlerTest { // Create a job handler, where we mock the execution of the index actions @Spy private EnsureOakIndexJobHandler handler = new EnsureOakIndexJobHandler(null, OAK_INDEX, DEFINITION_PATH); private static final String OAK_INDEX = "/oak:index"; private static final String INDEX_NAME = "testIndex"; private static final String DEFINITION_PATH = "/apps/mydefinitions/index/" + INDEX_NAME; private Resource oakIndexResource; @Before public void init() throws RepositoryException, IOException, OakIndexDefinitionException { oakIndexResource = mock(Resource.class); doNothing().when(handler).disableIndex(any(Resource.class)); doNothing().when(handler).delete(any(Resource.class)); doNothing().when(handler).forceRefresh(any(Resource.class)); doNothing().when(handler).validateEnsureDefinition(any(Resource.class)); doReturn(null).when(handler).update(any(Resource.class), any(Resource.class), anyBoolean()); doReturn(null).when(handler).create(any(Resource.class), any(Resource.class)); } Resource getEnsureOakDefinition(Map<String, Object> properties) { Resource r = mock(Resource.class); ValueMap vm = new MockValueMap(r, properties); when(r.getValueMap()).thenReturn(vm); when(r.adaptTo(ModifiableValueMap.class)).thenReturn(new ModifiableValueMapDecorator(properties)); when(r.getName()).thenReturn(INDEX_NAME); when(r.getPath()).thenReturn(DEFINITION_PATH); when(r.listChildren()).thenReturn(IteratorUtils.EMPTY_LIST_ITERATOR); return r; } Resource getOakDefinition(Map<String, Object> properties) { Resource r = mock(Resource.class); ValueMap vm = new MockValueMap(r, properties); when(r.adaptTo(ModifiableValueMap.class)).thenReturn(new ModifiableValueMapDecorator(properties)); when(r.getValueMap()).thenReturn(vm); when(r.getName()).thenReturn(INDEX_NAME); when(r.getPath()).thenReturn(OAK_INDEX + "/" + INDEX_NAME); when(r.listChildren()).thenReturn(IteratorUtils.EMPTY_LIST_ITERATOR); return r; } @Test public void testIgnoreProperty() throws PersistenceException, RepositoryException { Map<String, Object> props = new HashMap<String, Object>(); props.put(EnsureOakIndexJobHandler.PN_IGNORE, "true"); props.put(EnsureOakIndexJobHandler.PN_DISABLE, "true"); props.put(EnsureOakIndexJobHandler.PN_DELETE, "true"); Resource def = getEnsureOakDefinition(props); Assert.assertTrue(handler.handleLightWeightIndexOperations(def, null)); verify(handler, never()).disableIndex(any(Resource.class)); verify(handler, never()).delete(any(Resource.class)); } @Test public void testDisableProperty() throws PersistenceException, RepositoryException { Map<String, Object> props = new HashMap<String, Object>(); props.put(EnsureOakIndexJobHandler.PN_DISABLE, "true"); Resource def = getEnsureOakDefinition(props); Resource r = mock(Resource.class); Assert.assertTrue(handler.handleLightWeightIndexOperations(def, r)); verify(handler, times(1)).disableIndex(any(Resource.class)); verify(handler, never()).delete(any(Resource.class)); } @Test public void testDisablePropertyWithoutExistingIndex() throws PersistenceException, RepositoryException { Map<String, Object> props = new HashMap<String, Object>(); props.put(EnsureOakIndexJobHandler.PN_DISABLE, "true"); Resource def = getEnsureOakDefinition(props); Resource r = null; Assert.assertTrue(handler.handleLightWeightIndexOperations(def, r)); verify(handler, never()).disableIndex(any(Resource.class)); verify(handler, never()).delete(any(Resource.class)); } @Test public void testDeleteProperty() throws PersistenceException, RepositoryException { Map<String, Object> props = new HashMap<String, Object>(); props.put(EnsureOakIndexJobHandler.PN_DELETE, "true"); props.put(EnsureOakIndexJobHandler.PN_DISABLE, "true"); Resource def = getEnsureOakDefinition(props); Resource r = mock(Resource.class); Assert.assertTrue(handler.handleLightWeightIndexOperations(def, r)); verify(handler, never()).disableIndex(any(Resource.class)); verify(handler, times(1)).delete(any(Resource.class)); } @Test public void testDeletePropertyWithoutExistingIndex() throws PersistenceException, RepositoryException { Map<String, Object> props = new HashMap<String, Object>(); props.put(EnsureOakIndexJobHandler.PN_DELETE, "true"); props.put(EnsureOakIndexJobHandler.PN_DISABLE, "true"); Resource def = getEnsureOakDefinition(props); Resource r = null; Assert.assertTrue(handler.handleLightWeightIndexOperations(def, r)); verify(handler, never()).disableIndex(any(Resource.class)); verify(handler, never()).delete(any(Resource.class)); } @Test public void testCreate() throws RepositoryException, IOException { Map<String, Object> props = new HashMap<String, Object>(); Resource def = getEnsureOakDefinition(props); Resource index = null; Assert.assertFalse(handler.handleLightWeightIndexOperations(def, index)); handler.handleHeavyWeightIndexOperations(oakIndexResource, def, index); verify(handler, never()).disableIndex(any(Resource.class)); verify(handler, never()).delete(any(Resource.class)); verify(handler, times(1)).create(eq(def), eq(oakIndexResource)); verify(handler, never()).forceRefresh(any(Resource.class)); } @Test public void testCreateWithForcedReindex() throws RepositoryException, IOException { Map<String, Object> props = new HashMap<String, Object>(); props.put(EnsureOakIndexJobHandler.PN_FORCE_REINDEX, "true"); Resource def = getEnsureOakDefinition(props); Resource index = null; Assert.assertFalse(handler.handleLightWeightIndexOperations(def, index)); handler.handleHeavyWeightIndexOperations(oakIndexResource, def, index); verify(handler, never()).disableIndex(any(Resource.class)); verify(handler, never()).delete(any(Resource.class)); verify(handler, times(1)).create(eq(def), eq(oakIndexResource)); verify(handler, times(1)).forceRefresh(any(Resource.class)); } @Test public void testUpdate() throws RepositoryException, IOException { Map<String, Object> props = new HashMap<String, Object>(); props.put(EnsureOakIndexJobHandler.PN_FORCE_REINDEX, "true"); Resource def = getEnsureOakDefinition(props); Resource index = mock(Resource.class); Assert.assertFalse(handler.handleLightWeightIndexOperations(def, index)); handler.handleHeavyWeightIndexOperations(oakIndexResource, def, index); verify(handler, never()).disableIndex(any(Resource.class)); verify(handler, never()).delete(any(Resource.class)); verify(handler, never()).create(any(Resource.class), any(Resource.class)); verify(handler, times(1)).update(eq(def), eq(oakIndexResource), eq(true)); verify(handler, never()).forceRefresh(any(Resource.class)); } @Ignore("This test passes locally but fails on TravisCI; Figure out how to make this test pass on TravisCI") public void testUpdateOperation() throws RepositoryException, IOException { String PN_IGNORE_ME = "ignoreMe"; ChecksumGenerator checksumGenerator = mock(ChecksumGenerator.class); List<String> ignoreProperties = new ArrayList<String>(); ignoreProperties.add(PN_IGNORE_ME); EnsureOakIndex eoi = mock(EnsureOakIndex.class); when(eoi.getIgnoreProperties()).thenReturn(ignoreProperties); when(eoi.getChecksumGenerator()).thenReturn(checksumGenerator); Map<String, Object> ensureProps = spy(new HashMap<String, Object>()); ensureProps.put(EnsureOakIndexJobHandler.PN_RECREATE_ON_UPDATE, true); Resource def = getEnsureOakDefinition(ensureProps); Map<String, Object> oakProps = spy(new HashMap<String, Object>()); oakProps.put(EnsureOakIndexJobHandler.PN_RECREATE_ON_UPDATE, true); oakProps.put(PN_IGNORE_ME, "true"); Resource oak = getOakDefinition(oakProps); Map<String,String> defChecksum = new HashMap<String, String>(); defChecksum.put(def.getPath(), "123"); when(checksumGenerator.generateChecksums(any(Session.class), any(String.class), any(CustomChecksumGeneratorOptions.class))).thenReturn(defChecksum); Map<String,String> oakChecksum = new HashMap<String, String>(); oakChecksum.put(oak.getPath(), "456"); when(checksumGenerator.generateChecksums(any(Session.class), any(String.class), any(CustomChecksumGeneratorOptions.class))).thenReturn(oakChecksum); when(oakIndexResource.getChild(INDEX_NAME)).thenReturn(oak); handler.update(def, oakIndexResource, false); verify(oakProps, never()).remove(PN_IGNORE_ME); } }