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