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