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.models.Container; 025import org.fcrepo.kernel.api.models.FedoraBinary; 026import org.fcrepo.kernel.api.models.FedoraResource; 027import org.fcrepo.kernel.api.models.FedoraTimeMap; 028import org.fcrepo.kernel.api.models.FedoraWebacAcl; 029import org.fcrepo.kernel.api.models.NonRdfSourceDescription; 030import org.fcrepo.kernel.modeshape.ContainerImpl; 031import org.fcrepo.kernel.modeshape.FedoraBinaryImpl; 032import org.fcrepo.kernel.modeshape.FedoraResourceImpl; 033import org.fcrepo.kernel.modeshape.FedoraSessionImpl; 034import org.fcrepo.kernel.modeshape.FedoraTimeMapImpl; 035import org.fcrepo.kernel.modeshape.FedoraWebacAclImpl; 036import org.fcrepo.kernel.modeshape.NonRdfSourceDescriptionImpl; 037import org.junit.Before; 038import org.junit.Test; 039import org.junit.runner.RunWith; 040import org.mockito.Mock; 041import org.mockito.junit.MockitoJUnitRunner; 042 043import javax.jcr.Node; 044import javax.jcr.Property; 045import javax.jcr.RepositoryException; 046import javax.jcr.Session; 047import javax.jcr.Workspace; 048import javax.jcr.version.VersionManager; 049import javax.ws.rs.core.UriBuilder; 050 051import static org.apache.jena.rdf.model.ResourceFactory.createResource; 052import static org.fcrepo.http.commons.test.util.TestHelpers.setField; 053import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_BINARY; 054import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_NON_RDF_SOURCE_DESCRIPTION; 055import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_TIME_MAP; 056import static org.fcrepo.kernel.api.FedoraTypes.FEDORA_WEBAC_ACL; 057import static org.fcrepo.kernel.api.FedoraTypes.MEMENTO; 058import static org.fcrepo.kernel.api.FedoraTypes.MEMENTO_ORIGINAL; 059import static org.fcrepo.kernel.api.RdfLexicon.FEDORA_DESCRIPTION; 060import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.getJcrNode; 061import static org.junit.Assert.assertEquals; 062import static org.junit.Assert.assertTrue; 063import static org.mockito.Mockito.when; 064 065/** 066 * @author cabeer 067 */ 068@RunWith(MockitoJUnitRunner.Silent.class) 069public class HttpResourceConverterTest { 070 071 @Mock 072 private Session session, txSession; 073 074 @Mock 075 private Node node, mementoNode, timeMapNode, descriptionNode, webacAclNode; 076 077 @Mock 078 private Property mockOriginal; 079 080 private FedoraSession testSession, testTxSession; 081 082 private HttpSession testHttpSession, testHttpBatchSession; 083 084 private HttpResourceConverter converter; 085 private final String uriTemplate = "http://localhost:8080/some/{path: .*}"; 086 private final String path = "arbitrary/path"; 087 088 private final String resourceUri = "http://localhost:8080/some/" + path; 089 090 private final Resource resource = createResource(resourceUri); 091 private final Resource metadataResource = createResource(resource.toString() + "/fcr:metadata"); 092 093 @Mock 094 private Workspace mockWorkspace; 095 096 @Mock 097 private VersionManager mockVersionManager; 098 099 @Before 100 public void setUp() throws RepositoryException { 101 final UriBuilder uriBuilder = UriBuilder.fromUri(uriTemplate); 102 testSession = new FedoraSessionImpl(session); 103 testTxSession = new FedoraSessionImpl(txSession); 104 testHttpSession = new HttpSession(testSession); 105 testHttpBatchSession = new HttpSession(testTxSession); 106 testHttpBatchSession.makeBatchSession(); 107 converter = new HttpResourceConverter(testHttpSession, uriBuilder); 108 109 when(session.getNode("/" + path)).thenReturn(node); 110 when(session.getNode("/")).thenReturn(node); 111 when(node.getPath()).thenReturn("/" + path); 112 when(node.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(false); 113 when(descriptionNode.getPath()).thenReturn("/" + path + "/" + FEDORA_DESCRIPTION); 114 when(descriptionNode.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(true); 115 when(session.getWorkspace()).thenReturn(mockWorkspace); 116 when(mockWorkspace.getName()).thenReturn("default"); 117 when(mockWorkspace.getVersionManager()).thenReturn(mockVersionManager); 118 119 when(mockOriginal.getNode()).thenReturn(node); 120 when(timeMapNode.getProperty(MEMENTO_ORIGINAL)).thenReturn(mockOriginal); 121 when(timeMapNode.isNodeType(FEDORA_TIME_MAP)).thenReturn(true); 122 when(webacAclNode.isNodeType(FEDORA_WEBAC_ACL)).thenReturn(true); 123 } 124 125 @Test 126 public void testDoForward() { 127 final FedoraResource converted = converter.convert(resource); 128 assertEquals(node, getJcrNode(converted)); 129 } 130 131 @Test 132 public void testDoForwardWithDatastreamContent() throws Exception { 133 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 134 final FedoraResource converted = converter.convert(resource); 135 assertTrue(converted instanceof FedoraBinary); 136 assertEquals(node, getJcrNode(converted)); 137 } 138 139 @Test 140 public void testDoForwardWithDatastreamMetadata() throws Exception { 141 when(session.getNode("/" + path + "/" + FEDORA_DESCRIPTION)).thenReturn(node); 142 when(node.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(true); 143 final FedoraResource converted = converter.convert(metadataResource); 144 assertTrue(converted instanceof NonRdfSourceDescription); 145 assertEquals(node, getJcrNode(converted)); 146 } 147 148 @Test 149 public void testDoForwardWithAHash() throws Exception { 150 when(session.getNode("/" + path + "/#/with-a-hash")).thenReturn(node); 151 final FedoraResource converted = 152 converter.convert(createResource("http://localhost:8080/some/" + path + "#with-a-hash")); 153 assertEquals(node, getJcrNode(converted)); 154 } 155 156 @Test 157 public void testDoForwardWithTransaction() throws Exception { 158 setField(testTxSession, "id", "xyz"); 159 final HttpResourceConverter converter = new HttpResourceConverter(testHttpBatchSession, 160 UriBuilder.fromUri(uriTemplate)); 161 when(txSession.getNode("/" + path)).thenReturn(node); 162 when(txSession.getWorkspace()).thenReturn(mockWorkspace); 163 final Resource resource = createResource("http://localhost:8080/some/tx:xyz/" + path); 164 final FedoraResource converted = converter.convert(resource); 165 assertEquals(node, getJcrNode(converted)); 166 } 167 168 @Test 169 public void testDoForwardWithUuid() throws Exception { 170 final Resource resource = createResource("http://localhost:8080/some/[xyz]"); 171 when(session.getNode("/[xyz]")).thenReturn(node); 172 final FedoraResource converted = converter.convert(resource); 173 assertEquals(node, getJcrNode(converted)); 174 } 175 176 @Test 177 public void testDoForwardRoot() { 178 final Resource resource = createResource("http://localhost:8080/some/"); 179 final FedoraResource converted = converter.convert(resource); 180 assertEquals(node, getJcrNode(converted)); 181 assertTrue(converter.inDomain(resource)); 182 } 183 184 @Test 185 public void testDoForwardRootWithoutSlash() { 186 final Resource resource = createResource("http://localhost:8080/some"); 187 final FedoraResource converted = converter.convert(resource); 188 assertEquals(node, getJcrNode(converted)); 189 assertTrue(converter.inDomain(resource)); 190 } 191 192 @Test 193 public void testDoBackward() { 194 final Resource converted = converter.reverse().convert(new FedoraResourceImpl(node)); 195 assertEquals(resource, converted); 196 } 197 198 @Test 199 public void testDoBackwardWithDatastreamContent() throws Exception { 200 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 201 final Resource converted = converter.reverse().convert(new FedoraBinaryImpl(node)); 202 assertEquals(resource, converted); 203 } 204 205 @Test 206 public void testDoBackwardWithDatastreamMetadata() { 207 final Resource converted = converter.reverse().convert(new NonRdfSourceDescriptionImpl(descriptionNode)); 208 assertEquals(metadataResource, converted); 209 } 210 211 @Test 212 public void testDoBackwardWithHash() throws Exception { 213 when(node.getPath()).thenReturn(path + "/#/with-a-hash"); 214 final Resource converted = converter.reverse().convert(new FedoraResourceImpl(node)); 215 assertEquals(createResource("http://localhost:8080/some/" + path + "#with-a-hash"), converted); 216 } 217 218 @Test 219 public void testDoBackwardWithTransaction() throws Exception { 220 setField(testTxSession, "id", "xyz"); 221 final HttpResourceConverter converter = new HttpResourceConverter(testHttpBatchSession, 222 UriBuilder.fromUri(uriTemplate)); 223 when(txSession.getNode("/" + path)).thenReturn(node); 224 when(txSession.getWorkspace()).thenReturn(mockWorkspace); 225 when(node.getSession()).thenReturn(txSession); 226 final Resource resource = createResource("http://localhost:8080/some/tx:xyz/" + path); 227 final Resource converted = converter.reverse().convert(new FedoraResourceImpl(node)); 228 assertEquals(resource, converted); 229 } 230 231 @Test 232 public void testToStringWithRoot() { 233 assertEquals("/", converter.asString(createResource("http://localhost:8080/some/"))); 234 } 235 236 @Test (expected = InvalidResourceIdentifierException.class) 237 public void testToStringWithEmptPathSegment() { 238 converter.asString(createResource("http://localhost:8080/some/test/a//b/c/d")); 239 } 240 241 @Test 242 public void testDoForwardWithTimemap() throws Exception { 243 final Resource resource = createResource("http://localhost:8080/some/container/fcr:versions"); 244 when(session.getNode("/container")).thenReturn(node); 245 246 when(session.getNode("/container/fedora:timemap")).thenReturn(timeMapNode); 247 248 final FedoraResource converted = converter.convert(resource); 249 assertTrue("Converted resource must be a timemap", converted instanceof FedoraTimeMap); 250 251 final Node resultNode = getJcrNode(converted); 252 assertEquals(timeMapNode, resultNode); 253 } 254 255 @Test 256 public void testDoForwardWithBinaryTimemap() throws Exception { 257 final Resource resource = createResource("http://localhost:8080/some/binary/fcr:versions"); 258 when(session.getNode("/binary")).thenReturn(node); 259 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 260 261 when(session.getNode("/binary/fedora:timemap")).thenReturn(timeMapNode); 262 263 final FedoraResource converted = converter.convert(resource); 264 assertTrue("Converted resource must be a timemap", converted instanceof FedoraTimeMap); 265 266 final Node resultNode = getJcrNode(converted); 267 assertEquals(timeMapNode, resultNode); 268 } 269 270 @Test 271 public void testDoForwardWithBinaryDescriptionTimemap() throws Exception { 272 final Resource resource = createResource("http://localhost:8080/some/binary/fcr:metadata/fcr:versions"); 273 when(node.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(true); 274 when(session.getNode("/binary/fedora:description")).thenReturn(node); 275 276 when(session.getNode("/binary/fedora:description/fedora:timemap")).thenReturn(timeMapNode); 277 278 final FedoraResource converted = converter.convert(resource); 279 assertTrue("Converted resource must be a timemap", converted instanceof FedoraTimeMap); 280 281 final Node resultNode = getJcrNode(converted); 282 assertEquals(timeMapNode, resultNode); 283 } 284 285 @Test 286 public void testDoBackWithTimemap() throws Exception { 287 final FedoraTimeMap timemap = new FedoraTimeMapImpl(timeMapNode); 288 when(timeMapNode.getPath()).thenReturn(path + "/fedora:timemap"); 289 290 final Resource converted = converter.reverse().convert(timemap); 291 final Resource expectedResource = createResource("http://localhost:8080/some/" + path + "/fcr:versions"); 292 assertEquals(expectedResource, converted); 293 } 294 295 @Test 296 public void testDoBackWithBinaryTimemap() throws Exception { 297 final FedoraTimeMap timemap = new FedoraTimeMapImpl(timeMapNode); 298 when(timeMapNode.getPath()).thenReturn(path + "/fedora:timemap"); 299 300 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 301 302 final Resource converted = converter.reverse().convert(timemap); 303 final Resource expectedResource = createResource( 304 "http://localhost:8080/some/" + path + "/fcr:versions"); 305 assertEquals(expectedResource, converted); 306 } 307 308 @Test 309 public void testDoBackWithBinaryDescriptionTimemap() throws Exception { 310 final FedoraTimeMap timemap = new FedoraTimeMapImpl(timeMapNode); 311 when(timeMapNode.getPath()).thenReturn(path + "/fedora:description/fedora:timemap"); 312 313 when(node.isNodeType(FEDORA_NON_RDF_SOURCE_DESCRIPTION)).thenReturn(true); 314 315 final Resource converted = converter.reverse().convert(timemap); 316 final Resource expectedResource = createResource( 317 "http://localhost:8080/some/" + path + "/fcr:metadata/fcr:versions"); 318 assertEquals(expectedResource, converted); 319 } 320 321 @Test 322 public void testDoForwardWithMemento() throws Exception { 323 final Resource resource = createResource( 324 "http://localhost:8080/some/container/fcr:versions/20180315180915"); 325 when(mementoNode.isNodeType(MEMENTO)).thenReturn(true); 326 when(session.getNode("/container/fedora:timemap/20180315180915")).thenReturn(mementoNode); 327 328 when(session.getNode("/container")).thenReturn(node); 329 330 final FedoraResource converted = converter.convert(resource); 331 assertTrue("Converted resource must be a container", converted instanceof Container); 332 333 final Node resultNode = getJcrNode(converted); 334 assertEquals(mementoNode, resultNode); 335 } 336 337 @Test 338 public void testDoForwardWithMementoWithHash() throws Exception { 339 final Resource resource = createResource( 340 "http://localhost:8080/some/container/fcr:versions/20180315180915#test"); 341 when(session.getNode("/container/fedora:timemap/20180315180915/#/test")).thenReturn(node); 342 343 final FedoraResource converted = converter.convert(resource); 344 final Node resultNode = getJcrNode(converted); 345 assertEquals(node, resultNode); 346 } 347 348 @Test 349 public void testDoForwardWithBinaryMemento() throws Exception { 350 final Resource resource = createResource( 351 "http://localhost:8080/some/binary/fcr:versions/20180315180915"); 352 when(mementoNode.isNodeType(MEMENTO)).thenReturn(true); 353 when(mementoNode.isNodeType(FEDORA_BINARY)).thenReturn(true); 354 when(session.getNode("/binary/fedora:timemap/20180315180915")).thenReturn(mementoNode); 355 356 when(session.getNode("/binary")).thenReturn(node); 357 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 358 359 final FedoraResource converted = converter.convert(resource); 360 assertTrue("Converted resource must be a binary", converted instanceof FedoraBinary); 361 362 final Node resultNode = getJcrNode(converted); 363 assertEquals(mementoNode, resultNode); 364 } 365 366 @Test 367 public void testDoForwardWithBinaryDescriptionMemento() throws Exception { 368 final Resource resource = createResource( 369 "http://localhost:8080/some/binary/fcr:metadata/fcr:versions/20180315180915"); 370 when(mementoNode.isNodeType(MEMENTO)).thenReturn(true); 371 // Timemap for binary description uses fedora:timemap name 372 when(session.getNode("/binary/fedora:description/fedora:timemap/20180315180915")).thenReturn(mementoNode); 373 374 when(session.getNode("/binary/fedora:description")).thenReturn(node); 375 376 final FedoraResource converted = converter.convert(resource); 377 assertTrue("Converted resource must be a container", converted instanceof Container); 378 379 final Node resultNode = getJcrNode(converted); 380 assertEquals(mementoNode, resultNode); 381 } 382 383 @Test 384 public void testDoBackWithMemento() throws Exception { 385 when(node.getPath()).thenReturn("/" + path + "/fedora:timemap/20180315180915"); 386 when(node.isNodeType(MEMENTO)).thenReturn(true); 387 388 final Container memento = new ContainerImpl(node); 389 390 final Resource converted = converter.reverse().convert(memento); 391 final Resource expectedResource = createResource(resourceUri + "/fcr:versions/20180315180915"); 392 assertEquals(expectedResource, converted); 393 } 394 395 @Test 396 public void testDoBackWithBinaryMemento() throws Exception { 397 when(node.getPath()).thenReturn("/" + path + "/fedora:timemap/20180315180915"); 398 when(node.isNodeType(FEDORA_BINARY)).thenReturn(true); 399 400 when(node.isNodeType(MEMENTO)).thenReturn(true); 401 402 final FedoraBinary memento = new FedoraBinaryImpl(node); 403 404 final Resource converted = converter.reverse().convert(memento); 405 final Resource expectedResource = createResource(resourceUri + "/fcr:versions/20180315180915"); 406 assertEquals(expectedResource, converted); 407 } 408 409 @Test 410 public void testDoBackWithBinaryDescriptionMemento() throws Exception { 411 when(descriptionNode.getPath()).thenReturn("/" + path + "/fedora:description/fedora:timemap/20180315180915"); 412 when(descriptionNode.isNodeType(MEMENTO)).thenReturn(true); 413 414 final NonRdfSourceDescription memento = new NonRdfSourceDescriptionImpl(descriptionNode); 415 416 final Resource converted = converter.reverse().convert(memento); 417 final Resource expectedResource = createResource(resourceUri + "/fcr:metadata/fcr:versions/20180315180915"); 418 assertEquals(expectedResource, converted); 419 } 420 421 @Test 422 public void testDoForwardWithWebacAcl() throws Exception { 423 final Resource resource = createResource("http://localhost:8080/some/container/fcr:acl"); 424 when(session.getNode("/container")).thenReturn(node); 425 426 when(session.getNode("/container/fedora:acl")).thenReturn(webacAclNode); 427 428 final FedoraResource converted = converter.convert(resource); 429 assertTrue("Converted resource must be a FedoraWebacAcl", converted instanceof FedoraWebacAcl); 430 431 final Node resultNode = getJcrNode(converted); 432 assertEquals(webacAclNode, resultNode); 433 } 434 435 @Test 436 public void testDoBackWithWebacAcl() throws Exception { 437 final FedoraWebacAcl webacAcl = new FedoraWebacAclImpl(webacAclNode); 438 when(webacAclNode.getPath()).thenReturn(path + "/fedora:acl"); 439 440 final Resource converted = converter.reverse().convert(webacAcl); 441 final Resource expectedResource = createResource("http://localhost:8080/some/" + path + "/fcr:acl"); 442 assertEquals(expectedResource, converted); 443 } 444 445 @Test 446 public void testDoForwardWithWebacAclWithHash() throws Exception { 447 final Resource resource = createResource("http://localhost:8080/some/container/fcr:acl#hash_resource"); 448 when(session.getNode("/container")).thenReturn(node); 449 450 when(session.getNode("/container/fedora:acl/#/hash_resource")).thenReturn(webacAclNode); 451 452 final FedoraResource converted = converter.convert(resource); 453 assertTrue("Converted resource must be a FedoraWebacAcl", converted instanceof FedoraWebacAcl); 454 455 final Node resultNode = getJcrNode(converted); 456 assertEquals(webacAclNode, resultNode); 457 } 458 459 @Test 460 public void testDoBackWithWebacAclHash() throws Exception { 461 final FedoraWebacAcl webacAcl = new FedoraWebacAclImpl(webacAclNode); 462 when(webacAclNode.getPath()).thenReturn(path + "/fedora:acl/#/hash_resource"); 463 464 final Resource converted = converter.reverse().convert(webacAcl); 465 final Resource expectedResource = 466 createResource("http://localhost:8080/some/" + path + "/fcr:acl#hash_resource"); 467 assertEquals(expectedResource, converted); 468 } 469}