001/* 002 * The contents of this file are subject to the license and copyright 003 * detailed in the LICENSE and NOTICE files at the root of the source 004 * tree. 005 */ 006package org.fcrepo.kernel.impl.services; 007 008import static org.junit.Assert.assertEquals; 009import static org.mockito.ArgumentMatchers.any; 010import static org.mockito.Mockito.times; 011import static org.mockito.Mockito.verify; 012import static org.mockito.Mockito.when; 013import static org.springframework.test.util.ReflectionTestUtils.setField; 014 015import java.util.List; 016import java.util.Optional; 017 018import javax.inject.Inject; 019 020import org.fcrepo.kernel.api.ContainmentIndex; 021import org.fcrepo.kernel.api.Transaction; 022import org.fcrepo.kernel.api.auth.ACLHandle; 023import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 024import org.fcrepo.kernel.api.identifiers.FedoraId; 025import org.fcrepo.kernel.api.models.Binary; 026import org.fcrepo.kernel.api.models.Container; 027import org.fcrepo.kernel.api.models.NonRdfSourceDescription; 028import org.fcrepo.kernel.api.models.ResourceFactory; 029import org.fcrepo.kernel.api.models.ResourceHeaders; 030import org.fcrepo.kernel.api.models.WebacAcl; 031import org.fcrepo.kernel.api.observer.EventAccumulator; 032import org.fcrepo.kernel.impl.TestTransactionHelper; 033import org.fcrepo.kernel.impl.operations.DeleteResourceOperationFactoryImpl; 034import org.fcrepo.kernel.impl.operations.PurgeResourceOperation; 035import org.fcrepo.persistence.api.PersistentStorageSession; 036import org.fcrepo.persistence.api.PersistentStorageSessionManager; 037 038import org.junit.Before; 039import org.junit.Test; 040import org.junit.runner.RunWith; 041import org.mockito.ArgumentCaptor; 042import org.mockito.Captor; 043import org.mockito.InjectMocks; 044import org.mockito.Mock; 045import org.mockito.MockitoAnnotations; 046import org.springframework.test.context.ContextConfiguration; 047import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 048 049import com.github.benmanes.caffeine.cache.Cache; 050 051/** 052 * PurgeResourceServiceTest 053 * 054 * Copy of DeleteResourceServiceTest 055 * 056 * @author dbernstein 057 * @author whikloj 058 */ 059@RunWith(SpringJUnit4ClassRunner.class) 060@ContextConfiguration("/containmentIndexTest.xml") 061public class PurgeResourceServiceImplTest { 062 063 private static final String USER = "fedoraAdmin"; 064 065 private Transaction tx; 066 067 @Mock 068 private EventAccumulator eventAccumulator; 069 070 @Mock 071 private PersistentStorageSession pSession; 072 073 @Inject 074 private ContainmentIndex containmentIndex; 075 076 @Mock 077 private PersistentStorageSessionManager psManager; 078 079 @Mock 080 private ResourceFactory resourceFactory; 081 082 @Mock 083 private Container container; 084 085 @Mock 086 private Container childContainer; 087 088 @Mock 089 private Binary binary; 090 091 @Mock 092 private WebacAcl acl; 093 094 @Mock 095 private NonRdfSourceDescription binaryDesc; 096 097 @Mock 098 private ResourceHeaders resourceHeaders; 099 @Mock 100 private ResourceHeaders childHeaders; 101 @Mock 102 private ResourceHeaders descHeaders; 103 @Mock 104 private ResourceHeaders aclHeaders; 105 @Mock 106 private Cache<String, Optional<ACLHandle>> authHandleCache; 107 108 @Captor 109 private ArgumentCaptor<PurgeResourceOperation> operationCaptor; 110 111 @InjectMocks 112 private PurgeResourceServiceImpl service; 113 114 private static final FedoraId RESOURCE_ID = FedoraId.create("test-resource"); 115 private static final FedoraId CHILD_RESOURCE_ID = RESOURCE_ID.resolve("test-resource-child"); 116 private static final FedoraId RESOURCE_DESCRIPTION_ID = RESOURCE_ID.resolve("fcr:metadata"); 117 private static final FedoraId RESOURCE_ACL_ID = RESOURCE_ID.resolve("fcr:acl"); 118 private static final String TX_ID = "tx-1234"; 119 120 @Before 121 public void setup() { 122 MockitoAnnotations.openMocks(this); 123 tx = TestTransactionHelper.mockTransaction(TX_ID, false); 124 when(psManager.getSession(any(Transaction.class))).thenReturn(pSession); 125 final DeleteResourceOperationFactoryImpl factoryImpl = new DeleteResourceOperationFactoryImpl(); 126 setField(service, "deleteResourceFactory", factoryImpl); 127 setField(service, "containmentIndex", containmentIndex); 128 setField(service, "eventAccumulator", eventAccumulator); 129 when(container.getFedoraId()).thenReturn(RESOURCE_ID); 130 131 when(pSession.getHeaders(RESOURCE_ID, null)).thenReturn(resourceHeaders); 132 when(pSession.getHeaders(CHILD_RESOURCE_ID, null)).thenReturn(childHeaders); 133 when(pSession.getHeaders(RESOURCE_DESCRIPTION_ID, null)).thenReturn(descHeaders); 134 when(pSession.getHeaders(RESOURCE_ACL_ID, null)).thenReturn(aclHeaders); 135 } 136 137 @Test 138 public void testContainerPurge() throws Exception { 139 when(container.isAcl()).thenReturn(false); 140 when(container.getAcl()).thenReturn(null); 141 142 service.perform(tx, container, USER); 143 verifyResourceOperation(RESOURCE_ID, operationCaptor, pSession); 144 } 145 146 @Test 147 public void testRecursivePurge() throws Exception { 148 when(container.isAcl()).thenReturn(false); 149 when(container.getAcl()).thenReturn(null); 150 when(childContainer.getFedoraId()).thenReturn(CHILD_RESOURCE_ID); 151 when(childContainer.isAcl()).thenReturn(false); 152 when(childContainer.getAcl()).thenReturn(null); 153 154 when(resourceFactory.getResource(tx, CHILD_RESOURCE_ID)).thenReturn(childContainer); 155 containmentIndex.addContainedBy(tx, container.getFedoraId(), childContainer.getFedoraId()); 156 containmentIndex.commitTransaction(tx); 157 containmentIndex.removeContainedBy(tx, container.getFedoraId(), childContainer.getFedoraId()); 158 159 service.perform(tx, container, USER); 160 161 verify(pSession, times(2)).persist(operationCaptor.capture()); 162 final List<PurgeResourceOperation> operations = operationCaptor.getAllValues(); 163 assertEquals(2, operations.size()); 164 165 assertEquals(CHILD_RESOURCE_ID, operations.get(0).getResourceId()); 166 assertEquals(RESOURCE_ID, operations.get(1).getResourceId()); 167 168 assertEquals(0, containmentIndex.getContains(tx, RESOURCE_ID).count()); 169 170 verify(tx).lockResource(RESOURCE_ID); 171 verify(tx).lockResource(CHILD_RESOURCE_ID); 172 } 173 174 private void verifyResourceOperation(final FedoraId fedoraID, 175 final ArgumentCaptor<PurgeResourceOperation> captor, 176 final PersistentStorageSession pSession) throws Exception { 177 verify(pSession).persist(captor.capture()); 178 final PurgeResourceOperation containerOperation = captor.getValue(); 179 assertEquals(fedoraID, containerOperation.getResourceId()); 180 } 181 182 @Test 183 public void testAclPurge() throws Exception { 184 when(acl.getFedoraId()).thenReturn(RESOURCE_ACL_ID); 185 when(acl.isAcl()).thenReturn(true); 186 service.perform(tx, acl, USER); 187 verifyResourceOperation(RESOURCE_ACL_ID, operationCaptor, pSession); 188 } 189 190 @Test(expected = RepositoryRuntimeException.class) 191 public void testBinaryDescriptionPurge() throws Exception { 192 when(binaryDesc.getFedoraId()).thenReturn(RESOURCE_DESCRIPTION_ID); 193 service.perform(tx, binaryDesc, USER); 194 } 195 196 @Test 197 public void testBinaryPurgeWithAcl() throws Exception { 198 when(binary.getFedoraId()).thenReturn(RESOURCE_ID); 199 when(binary.isAcl()).thenReturn(false); 200 when(binary.getDescription()).thenReturn(binaryDesc); 201 when(binaryDesc.getFedoraId()).thenReturn(RESOURCE_DESCRIPTION_ID); 202 when(binary.getAcl()).thenReturn(acl); 203 when(acl.getFedoraId()).thenReturn(RESOURCE_ACL_ID); 204 205 service.perform(tx, binary, USER); 206 207 verify(pSession, times(3)).persist(operationCaptor.capture()); 208 final List<PurgeResourceOperation> operations = operationCaptor.getAllValues(); 209 assertEquals(3, operations.size()); 210 211 assertEquals(RESOURCE_DESCRIPTION_ID, operations.get(0).getResourceId()); 212 assertEquals(RESOURCE_ACL_ID, operations.get(1).getResourceId()); 213 assertEquals(RESOURCE_ID, operations.get(2).getResourceId()); 214 215 verify(tx).lockResource(RESOURCE_ID); 216 verify(tx).lockResource(RESOURCE_DESCRIPTION_ID); 217 verify(tx).lockResource(RESOURCE_ACL_ID); 218 } 219 220}