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.apache.jena.vocabulary.DC_11.title; 021import static org.junit.Assert.assertEquals; 022import static org.junit.Assert.assertTrue; 023import static org.mockito.ArgumentMatchers.any; 024import static org.mockito.ArgumentMatchers.nullable; 025import static org.mockito.Mockito.verify; 026import static org.mockito.Mockito.when; 027import static org.springframework.test.util.ReflectionTestUtils.setField; 028 029import java.time.Instant; 030 031import org.fcrepo.config.FedoraPropsConfig; 032import org.fcrepo.config.ServerManagedPropsMode; 033import org.fcrepo.kernel.api.RdfCollectors; 034import org.fcrepo.kernel.api.RdfLexicon; 035import org.fcrepo.kernel.api.RdfStream; 036import org.fcrepo.kernel.api.Transaction; 037import org.fcrepo.kernel.api.identifiers.FedoraId; 038import org.fcrepo.kernel.api.models.ResourceHeaders; 039import org.fcrepo.kernel.api.observer.EventAccumulator; 040import org.fcrepo.kernel.api.operations.RdfSourceOperationFactory; 041import org.fcrepo.kernel.api.services.MembershipService; 042import org.fcrepo.kernel.api.services.ReferenceService; 043import org.fcrepo.kernel.impl.operations.RdfSourceOperationFactoryImpl; 044import org.fcrepo.kernel.impl.operations.UpdateRdfSourceOperation; 045import org.fcrepo.persistence.api.PersistentStorageSession; 046import org.fcrepo.persistence.api.PersistentStorageSessionManager; 047 048import org.apache.commons.io.IOUtils; 049import org.apache.jena.rdf.model.Model; 050import org.apache.jena.rdf.model.ModelFactory; 051import org.apache.jena.rdf.model.ResourceFactory; 052import org.apache.jena.riot.Lang; 053import org.apache.jena.riot.RDFDataMgr; 054import org.fcrepo.search.api.SearchIndex; 055import org.junit.Before; 056import org.junit.Test; 057import org.junit.runner.RunWith; 058import org.mockito.ArgumentCaptor; 059import org.mockito.Captor; 060import org.mockito.InjectMocks; 061import org.mockito.Mock; 062import org.mockito.junit.MockitoJUnitRunner; 063 064/** 065 * DeleteResourceServiceTest 066 * 067 * @author bseeger 068 */ 069@RunWith(MockitoJUnitRunner.Strict.class) 070public class ReplacePropertiesServiceImplTest { 071 072 private static final String USER_PRINCIPAL = "fedoraUser"; 073 074 @Mock 075 private Transaction tx; 076 077 @Mock 078 private PersistentStorageSession pSession; 079 080 @Mock 081 private PersistentStorageSessionManager psManager; 082 083 @Mock 084 private EventAccumulator eventAccumulator; 085 086 @Mock 087 private ReferenceService referenceService; 088 089 @Mock 090 private MembershipService membershipService; 091 092 @Mock 093 private SearchIndex searchIndex; 094 095 @Mock 096 private ResourceHeaders headers; 097 098 @InjectMocks 099 private UpdateRdfSourceOperation operation; 100 101 @InjectMocks 102 private ReplacePropertiesServiceImpl service; 103 104 private RdfSourceOperationFactory factory; 105 106 @Captor 107 private ArgumentCaptor<UpdateRdfSourceOperation> operationCaptor; 108 109 private FedoraPropsConfig propsConfig; 110 111 private static final FedoraId FEDORA_ID = FedoraId.create("info:fedora/resource1"); 112 private static final String TX_ID = "tx-1234"; 113 private static final String RDF = 114 "<" + FEDORA_ID + "> <" + title + "> 'fancy title' .\n" + 115 "<" + FEDORA_ID + "> <" + title + "> 'another fancy title' ."; 116 117 @Before 118 public void setup() { 119 propsConfig = new FedoraPropsConfig(); 120 factory = new RdfSourceOperationFactoryImpl(); 121 setField(service, "factory", factory); 122 setField(service, "eventAccumulator", eventAccumulator); 123 setField(service, "referenceService", referenceService); 124 setField(service, "membershipService", membershipService); 125 setField(service, "searchIndex", searchIndex); 126 setField(service, "fedoraPropsConfig", propsConfig); 127 propsConfig.setServerManagedPropsMode(ServerManagedPropsMode.STRICT); 128 when(psManager.getSession(any(Transaction.class))).thenReturn(pSession); 129 when(pSession.getHeaders(any(FedoraId.class), nullable(Instant.class))).thenReturn(headers); 130 } 131 132 @Test 133 public void testReplaceProperties() throws Exception { 134 final Model model = ModelFactory.createDefaultModel(); 135 RDFDataMgr.read(model, IOUtils.toInputStream(RDF, "UTF-8"), Lang.NTRIPLES); 136 137 when(headers.getInteractionModel()).thenReturn(RdfLexicon.RDF_SOURCE.toString()); 138 139 service.perform(tx, USER_PRINCIPAL, FEDORA_ID, model); 140 verify(tx).lockResource(FEDORA_ID); 141 verify(pSession).persist(operationCaptor.capture()); 142 assertEquals(FEDORA_ID, operationCaptor.getValue().getResourceId()); 143 final RdfStream stream = operationCaptor.getValue().getTriples(); 144 final Model captureModel = stream.collect(RdfCollectors.toModel()); 145 146 assertTrue(captureModel.contains(ResourceFactory.createResource(FEDORA_ID.getResourceId()), 147 ResourceFactory.createProperty(title.getURI()), 148 "another fancy title")); 149 assertTrue(captureModel.contains(ResourceFactory.createResource(FEDORA_ID.getResourceId()), 150 ResourceFactory.createProperty(title.getURI()), 151 "fancy title")); 152 } 153 154 @Test 155 public void lockRelatedResourcesOnBinaryDescInAg() throws Exception { 156 final Model model = ModelFactory.createDefaultModel(); 157 RDFDataMgr.read(model, IOUtils.toInputStream(RDF, "UTF-8"), Lang.NTRIPLES); 158 159 final var agId = FedoraId.create("ag"); 160 final var binaryId = agId.resolve("bin"); 161 final var descId = binaryId.asDescription(); 162 163 when(headers.getInteractionModel()).thenReturn(RdfLexicon.FEDORA_NON_RDF_SOURCE_DESCRIPTION_URI); 164 when(headers.getArchivalGroupId()).thenReturn(agId); 165 166 service.perform(tx, USER_PRINCIPAL, descId, model); 167 verify(tx).lockResource(agId); 168 verify(tx).lockResource(binaryId); 169 verify(tx).lockResource(descId); 170 verify(pSession).persist(operationCaptor.capture()); 171 assertEquals(descId, operationCaptor.getValue().getResourceId()); 172 } 173 174} 175