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.apache.jena.rdf.model.ResourceFactory.createResource; 009import static org.fcrepo.kernel.api.RdfCollectors.toModel; 010import static org.fcrepo.kernel.api.RdfLexicon.CONTAINS; 011import static org.junit.Assert.assertEquals; 012import static org.junit.Assert.assertTrue; 013import static org.mockito.Mockito.when; 014import static org.springframework.test.util.ReflectionTestUtils.setField; 015 016import java.util.UUID; 017 018import javax.inject.Inject; 019 020import org.fcrepo.kernel.api.ContainmentIndex; 021import org.fcrepo.kernel.api.ReadOnlyTransaction; 022import org.fcrepo.kernel.api.Transaction; 023import org.fcrepo.kernel.api.identifiers.FedoraId; 024import org.fcrepo.kernel.api.models.FedoraResource; 025import org.fcrepo.kernel.impl.TestTransactionHelper; 026 027import org.apache.jena.rdf.model.Model; 028import org.apache.jena.rdf.model.ModelFactory; 029import org.apache.jena.rdf.model.Statement; 030import org.apache.jena.rdf.model.StmtIterator; 031import org.junit.After; 032import org.junit.Before; 033import org.junit.Test; 034import org.junit.runner.RunWith; 035import org.mockito.InjectMocks; 036import org.mockito.Mock; 037import org.mockito.MockitoAnnotations; 038import org.springframework.test.context.ContextConfiguration; 039import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 040 041/** 042 * @author whikloj 043 */ 044@RunWith(SpringJUnit4ClassRunner.class) 045@ContextConfiguration("/containmentIndexTest.xml") 046public class ContainmentTriplesServiceImplTest { 047 048 @Mock 049 private FedoraResource parentResource; 050 051 private Transaction transaction; 052 053 private Transaction transaction2; 054 055 @Inject 056 private ContainmentIndex containmentIndex; 057 058 @InjectMocks 059 private ContainmentTriplesServiceImpl containmentTriplesService; 060 061 private Transaction readOnlyTx; 062 063 @Before 064 public void setup() { 065 MockitoAnnotations.openMocks(this); 066 final FedoraId parentId = FedoraId.create(UUID.randomUUID().toString()); 067 final String txId = UUID.randomUUID().toString(); 068 transaction = TestTransactionHelper.mockTransaction(txId, false); 069 when(parentResource.getFedoraId()).thenReturn(parentId); 070 setField(containmentTriplesService, "containmentIndex", containmentIndex); 071 readOnlyTx = ReadOnlyTransaction.INSTANCE; 072 } 073 074 @After 075 public void cleanUp() { 076 containmentIndex.reset(); 077 } 078 079 @Test 080 public void testNoContains() { 081 assertEquals(0, containmentTriplesService.get(transaction, parentResource).count()); 082 } 083 084 @Test 085 public void testOneChild() { 086 final FedoraId child = FedoraId.create(UUID.randomUUID().toString()); 087 containmentIndex.addContainedBy(transaction, parentResource.getFedoraId(), child); 088 assertEquals(1, containmentTriplesService.get(transaction, parentResource).count()); 089 final Model expectedModel = ModelFactory.createDefaultModel(); 090 expectedModel.add(createResource(parentResource.getFedoraId().getFullId()), CONTAINS, 091 createResource(child.getFullId())); 092 final Model received = containmentTriplesService.get(transaction, parentResource).collect(toModel()); 093 matchModels(expectedModel, received); 094 } 095 096 @Test 097 public void testTwoChildren() { 098 final FedoraId child1 = FedoraId.create(UUID.randomUUID().toString()); 099 final FedoraId child2 = FedoraId.create(UUID.randomUUID().toString()); 100 containmentIndex.addContainedBy(transaction, parentResource.getFedoraId(), child1); 101 containmentIndex.addContainedBy(transaction, parentResource.getFedoraId(), child2); 102 assertEquals(2, containmentTriplesService.get(transaction, parentResource).count()); 103 final Model expectedModel = ModelFactory.createDefaultModel(); 104 expectedModel.add(createResource(parentResource.getFedoraId().getFullId()), CONTAINS, 105 createResource(child1.getFullId())); 106 expectedModel.add(createResource(parentResource.getFedoraId().getFullId()), CONTAINS, 107 createResource(child2.getFullId())); 108 final Model received = containmentTriplesService.get(transaction, parentResource).collect(toModel()); 109 matchModels(expectedModel, received); 110 } 111 112 @Test 113 public void testTenChildren() { 114 final Model expectedModel = ModelFactory.createDefaultModel(); 115 for (var foo = 0; foo < 10; foo += 1) { 116 final FedoraId child = FedoraId.create(UUID.randomUUID().toString()); 117 containmentIndex.addContainedBy(transaction, parentResource.getFedoraId(), child); 118 expectedModel.add(createResource(parentResource.getFedoraId().getFullId()), CONTAINS, 119 createResource(child.getFullId())); 120 } 121 assertEquals(10, containmentTriplesService.get(transaction, parentResource).count()); 122 final Model received = containmentTriplesService.get(transaction, parentResource).collect(toModel()); 123 matchModels(expectedModel, received); 124 } 125 126 @Test 127 public void testAddAndRemove() { 128 final FedoraId child = FedoraId.create(UUID.randomUUID().toString()); 129 final String otherTransactionId = UUID.randomUUID().toString(); 130 131 transaction2 = TestTransactionHelper.mockTransaction(otherTransactionId, false); 132 containmentIndex.addContainedBy(transaction, parentResource.getFedoraId(), child); 133 assertEquals(1, containmentTriplesService.get(transaction, parentResource).count()); 134 final Model expectedModel = ModelFactory.createDefaultModel(); 135 expectedModel.add(createResource(parentResource.getFedoraId().getFullId()), CONTAINS, 136 createResource(child.getFullId())); 137 final Model received = containmentTriplesService.get(transaction, parentResource).collect(toModel()); 138 matchModels(expectedModel, received); 139 // Commit and ensure we can see the child. 140 containmentIndex.commitTransaction(transaction); 141 final Model received2 = containmentTriplesService.get(readOnlyTx, parentResource).collect(toModel()); 142 matchModels(expectedModel, received2); 143 // Now remove the child in a transaction, but verify we can still see it outside the transaction. 144 containmentIndex.removeResource(transaction2, child); 145 final Model received3 = containmentTriplesService.get(readOnlyTx, parentResource).collect(toModel()); 146 matchModels(expectedModel, received3); 147 // Now commit the transaction and ensure it disappears. 148 containmentIndex.commitTransaction(transaction2); 149 assertEquals(0, containmentTriplesService.get(readOnlyTx, parentResource).count()); 150 } 151 152 /** 153 * Ensure the test model contains all the expected statements from the expected model. 154 * @param expected The expected model. 155 * @param test The model to be tested. 156 */ 157 private void matchModels(final Model expected, final Model test) { 158 for (final StmtIterator it = expected.listStatements(); it.hasNext(); ) { 159 final Statement t = it.next(); 160 assertTrue(test.contains(t)); 161 } 162 } 163}