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.http.commons.api.rdf; 019 020import org.apache.jena.rdf.model.Resource; 021import org.fcrepo.http.commons.session.HttpSession; 022import org.fcrepo.kernel.api.FedoraSession; 023import org.fcrepo.kernel.api.exception.InvalidResourceIdentifierException; 024import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 025import org.fcrepo.kernel.api.models.FedoraBinary; 026import org.fcrepo.kernel.api.models.FedoraResource; 027import org.fcrepo.kernel.api.models.NonRdfSourceDescription; 028import org.fcrepo.kernel.modeshape.FedoraBinaryImpl; 029import org.fcrepo.kernel.modeshape.FedoraResourceImpl; 030import org.fcrepo.kernel.modeshape.FedoraSessionImpl; 031import org.fcrepo.kernel.modeshape.NonRdfSourceDescriptionImpl; 032import org.junit.Before; 033import org.junit.Ignore; 034import org.junit.Test; 035import org.junit.runner.RunWith; 036import org.mockito.Mock; 037import org.mockito.runners.MockitoJUnitRunner; 038 039import javax.jcr.ItemNotFoundException; 040import javax.jcr.Node; 041import javax.jcr.Property; 042import javax.jcr.RepositoryException; 043import javax.jcr.Session; 044import javax.jcr.Workspace; 045import javax.jcr.version.Version; 046import javax.jcr.version.VersionHistory; 047import javax.jcr.version.VersionManager; 048import javax.ws.rs.core.UriBuilder; 049 050import static org.apache.jena.rdf.model.ResourceFactory.createResource; 051import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_NON_RDF_SOURCE_DESCRIPTION; 052import static org.fcrepo.kernel.modeshape.FedoraJcrConstants.FROZEN_NODE; 053import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getJcrNode; 054import static org.fcrepo.http.commons.test.util.TestHelpers.setField; 055import static org.junit.Assert.assertEquals; 056import static org.junit.Assert.assertTrue; 057import static org.mockito.Mockito.when; 058import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT; 059 060/** 061 * @author cabeer 062 */ 063@RunWith(MockitoJUnitRunner.class) 064public class HttpResourceConverterTest { 065 066 @Mock 067 private Session session, txSession; 068 069 @Mock 070 private Node node, versionedNode, contentNode; 071 072 @Mock 073 private Property mockProperty; 074 075 private FedoraSession testSession, testTxSession; 076 077 private HttpSession testHttpSession, testHttpBatchSession; 078 079 private HttpResourceConverter converter; 080 private final String uriTemplate = "http://localhost:8080/some/{path: .*}"; 081 private final String path = "arbitrary/path"; 082 private final Resource resource = createResource("http://localhost:8080/some/" + path); 083 private final Resource versionedResource = createResource("http://localhost:8080/some/" + path + "/fcr:versions/x"); 084 private final Resource metadataResource = createResource(resource.toString() + "/fcr:metadata"); 085 086 @Mock 087 private Workspace mockWorkspace; 088 089 @Mock 090 private VersionManager mockVersionManager; 091 092 @Mock 093 private VersionHistory mockVersionHistory; 094 095 @Mock 096 private Version mockVersion; 097 098 @Before 099 public void setUp() throws RepositoryException { 100 final UriBuilder uriBuilder = UriBuilder.fromUri(uriTemplate); 101 testSession = new FedoraSessionImpl(session); 102 testTxSession = new FedoraSessionImpl(txSession); 103 testHttpSession = new HttpSession(testSession); 104 testHttpBatchSession = new HttpSession(testTxSession); 105 testHttpBatchSession.makeBatchSession(); 106 converter = new HttpResourceConverter(testHttpSession, uriBuilder); 107 108 when(session.getNode("/" + path)).thenReturn(node); 109 when(session.getNode("/")).thenReturn(node); 110 when(node.getPath()).thenReturn("/" + path); 111 when(node.isNodeType(FROZEN_NODE)).thenReturn(false); 112 when(node.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(false); 113 when(contentNode.getPath()).thenReturn("/" + path + "/jcr:content"); 114 when(session.getWorkspace()).thenReturn(mockWorkspace); 115 when(mockWorkspace.getName()).thenReturn("default"); 116 when(mockWorkspace.getVersionManager()).thenReturn(mockVersionManager); 117 when(versionedNode.isNodeType("nt:frozenNode")).thenReturn(true); 118 } 119 120 @Test 121 public void testDoForward() { 122 final FedoraResource converted = converter.convert(resource); 123 assertEquals(node, getJcrNode(converted)); 124 } 125 126 @Test 127 public void testDoForwardWithDatastreamContent() throws Exception { 128 when(node.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(true); 129 when(node.getNode(JCR_CONTENT)).thenReturn(contentNode); 130 final FedoraResource converted = converter.convert(resource); 131 assertTrue(converted instanceof FedoraBinary); 132 assertEquals(contentNode, getJcrNode(converted)); 133 } 134 135 @Test 136 public void testDoForwardWithDatastreamMetadata() throws Exception { 137 when(node.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(true); 138 final FedoraResource converted = converter.convert(metadataResource); 139 assertTrue(converted instanceof NonRdfSourceDescription); 140 assertEquals(node, getJcrNode(converted)); 141 } 142 143 @Test 144 public void testDoForwardWithAHash() throws Exception { 145 when(session.getNode("/" + path + "/#/with-a-hash")).thenReturn(node); 146 final FedoraResource converted = 147 converter.convert(createResource("http://localhost:8080/some/" + path + "#with-a-hash")); 148 assertEquals(node, getJcrNode(converted)); 149 } 150 151 @Test 152 public void testDoForwardWithTransaction() throws Exception { 153 setField(testTxSession, "id", "xyz"); 154 final HttpResourceConverter converter = new HttpResourceConverter(testHttpBatchSession, 155 UriBuilder.fromUri(uriTemplate)); 156 when(txSession.getNode("/" + path)).thenReturn(node); 157 when(txSession.getWorkspace()).thenReturn(mockWorkspace); 158 final Resource resource = createResource("http://localhost:8080/some/tx:xyz/" + path); 159 final FedoraResource converted = converter.convert(resource); 160 assertEquals(node, getJcrNode(converted)); 161 } 162 163 @Test 164 public void testDoForwardWithUuid() throws Exception { 165 final Resource resource = createResource("http://localhost:8080/some/[xyz]"); 166 when(session.getNode("/[xyz]")).thenReturn(node); 167 final FedoraResource converted = converter.convert(resource); 168 assertEquals(node, getJcrNode(converted)); 169 } 170 171 @Test 172 public void testDoForwardRoot() { 173 final Resource resource = createResource("http://localhost:8080/some/"); 174 final FedoraResource converted = converter.convert(resource); 175 assertEquals(node, getJcrNode(converted)); 176 assertTrue(converter.inDomain(resource)); 177 } 178 179 @Test 180 public void testDoForwardRootWithoutSlash() { 181 final Resource resource = createResource("http://localhost:8080/some"); 182 final FedoraResource converted = converter.convert(resource); 183 assertEquals(node, getJcrNode(converted)); 184 assertTrue(converter.inDomain(resource)); 185 } 186 187 @Test 188 public void testDoBackward() { 189 final Resource converted = converter.reverse().convert(new FedoraResourceImpl(node)); 190 assertEquals(resource, converted); 191 } 192 193 @Test 194 public void testDoBackwardWithDatastreamContent() { 195 final Resource converted = converter.reverse().convert(new FedoraBinaryImpl(contentNode)); 196 assertEquals(resource, converted); 197 } 198 199 @Test 200 public void testDoBackwardWithDatastreamMetadata() { 201 final Resource converted = converter.reverse().convert(new NonRdfSourceDescriptionImpl(node)); 202 assertEquals(metadataResource, converted); 203 } 204 205 @Test 206 public void testDoBackwardWithHash() throws Exception { 207 when(node.getPath()).thenReturn(path + "/#/with-a-hash"); 208 final Resource converted = converter.reverse().convert(new FedoraResourceImpl(node)); 209 assertEquals(createResource("http://localhost:8080/some/" + path + "#with-a-hash"), converted); 210 } 211 212 @Test 213 public void testDoForwardWithImplicitVersionedDatastream() throws Exception { 214 when(session.getNodeByIdentifier("x")).thenReturn(versionedNode); 215 when(versionedNode.getProperty("jcr:frozenUuid")).thenReturn(mockProperty); 216 when(mockProperty.getString()).thenReturn("some-identifier"); 217 when(node.getIdentifier()).thenReturn("some-identifier"); 218 when(mockVersionManager.getVersionHistory("/" + path)).thenReturn(mockVersionHistory); 219 when(mockVersionHistory.hasVersionLabel("x")).thenReturn(true); 220 when(mockVersionHistory.getVersionByLabel("x")).thenReturn(mockVersion); 221 final FedoraResource converted = converter.convert(versionedResource); 222 assertEquals(versionedNode, getJcrNode(converted)); 223 } 224 225 @Test 226 public void testDoForwardWithExplicitVersionedDatastream() throws Exception { 227 when(session.getNodeByIdentifier("x")).thenThrow(new ItemNotFoundException()); 228 when(mockVersionManager.getVersionHistory("/" + path)).thenReturn(mockVersionHistory); 229 when(mockVersionHistory.hasVersionLabel("x")).thenReturn(true); 230 when(mockVersionHistory.getVersionByLabel("x")).thenReturn(mockVersion); 231 when(mockVersion.getFrozenNode()).thenReturn(versionedNode); 232 final FedoraResource converted = converter.convert(versionedResource); 233 assertEquals(versionedNode, getJcrNode(converted)); 234 } 235 236 @Test(expected = RepositoryRuntimeException.class) 237 public void testDoForwardWithMissingVersionedDatastream() throws Exception { 238 when(session.getNodeByIdentifier("x")).thenThrow(new ItemNotFoundException()); 239 when(mockVersionManager.getVersionHistory("/" + path)).thenReturn(mockVersionHistory); 240 when(mockVersionHistory.hasVersionLabel("x")).thenReturn(false); 241 converter.convert(versionedResource); 242 } 243 244 @Test 245 @Ignore 246 public void testDoBackwardWithVersionedNode() throws Exception { 247 248 when(versionedNode.getProperty("jcr:frozenUuid")).thenReturn(mockProperty); 249 when(versionedNode.getIdentifier()).thenReturn("x"); 250 when(mockProperty.getString()).thenReturn("some-identifier"); 251 when(node.getIdentifier()).thenReturn("some-identifier"); 252 when(session.getNodeByIdentifier("some-identifier")).thenReturn(node); 253 when(node.isNodeType("mix:versionable")).thenReturn(true); 254 255 final Resource converted = converter.reverse().convert(new FedoraResourceImpl(versionedNode)); 256 assertEquals(versionedResource, converted); 257 } 258 259 @Test 260 public void testDoBackwardWithTransaction() throws Exception { 261 setField(testTxSession, "id", "xyz"); 262 final HttpResourceConverter converter = new HttpResourceConverter(testHttpBatchSession, 263 UriBuilder.fromUri(uriTemplate)); 264 when(txSession.getNode("/" + path)).thenReturn(node); 265 when(txSession.getWorkspace()).thenReturn(mockWorkspace); 266 when(node.getSession()).thenReturn(txSession); 267 final Resource resource = createResource("http://localhost:8080/some/tx:xyz/" + path); 268 final Resource converted = converter.reverse().convert(new FedoraResourceImpl(node)); 269 assertEquals(resource, converted); 270 } 271 272 @Test 273 public void testToStringWithRoot() { 274 assertEquals("/", converter.asString(createResource("http://localhost:8080/some/"))); 275 } 276 277 @Test (expected = InvalidResourceIdentifierException.class) 278 public void testToStringWithEmptPathSegment() { 279 converter.asString(createResource("http://localhost:8080/some/test/a//b/c/d")); 280 } 281}