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