001/* 002 * Copyright 2015 DuraSpace, Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.fcrepo.http.commons.responses; 017 018import static com.google.common.collect.ImmutableMap.of; 019import static com.hp.hpl.jena.graph.NodeFactory.createAnon; 020import static com.hp.hpl.jena.graph.NodeFactory.createLiteral; 021import static com.hp.hpl.jena.graph.NodeFactory.createURI; 022import static com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel; 023import static com.hp.hpl.jena.rdf.model.ResourceFactory.createResource; 024import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty; 025import static com.hp.hpl.jena.rdf.model.ResourceFactory.createTypedLiteral; 026import static org.fcrepo.http.commons.test.util.TestHelpers.getUriInfoImpl; 027import static org.fcrepo.kernel.api.RdfLexicon.CREATED_DATE; 028import static org.fcrepo.kernel.api.RdfLexicon.DC_TITLE; 029import static org.fcrepo.kernel.api.RdfLexicon.DCTERMS_TITLE; 030import static org.fcrepo.kernel.api.RdfLexicon.HAS_CHILD_COUNT; 031import static org.fcrepo.kernel.api.RdfLexicon.HAS_PRIMARY_TYPE; 032import static org.fcrepo.kernel.api.RdfLexicon.HAS_VERSION_LABEL; 033import static org.fcrepo.kernel.api.RdfLexicon.DC_NAMESPACE; 034import static org.fcrepo.kernel.api.RdfLexicon.HAS_VERSION; 035import static org.fcrepo.kernel.api.RdfLexicon.DESCRIBES; 036import static org.fcrepo.kernel.api.RdfLexicon.RDFS_LABEL; 037import static org.fcrepo.kernel.api.RdfLexicon.REPOSITORY_NAMESPACE; 038import static org.fcrepo.kernel.api.RdfLexicon.SKOS_PREFLABEL; 039import static org.fcrepo.kernel.api.RdfLexicon.WRITABLE; 040import static org.fcrepo.kernel.api.RdfLexicon.RDF_NAMESPACE; 041import static org.junit.Assert.assertEquals; 042import static org.junit.Assert.assertFalse; 043import static org.junit.Assert.assertTrue; 044 045import java.util.Date; 046import java.util.Iterator; 047import java.util.List; 048import java.util.Map; 049 050import javax.ws.rs.core.UriInfo; 051 052import com.hp.hpl.jena.graph.Graph; 053import com.hp.hpl.jena.graph.Triple; 054import org.junit.Before; 055import org.junit.Test; 056 057import com.hp.hpl.jena.graph.Node; 058import com.hp.hpl.jena.graph.NodeFactory; 059import com.hp.hpl.jena.rdf.model.Literal; 060import com.hp.hpl.jena.rdf.model.Model; 061import com.hp.hpl.jena.rdf.model.Property; 062import com.hp.hpl.jena.rdf.model.Resource; 063import com.hp.hpl.jena.rdf.model.ResourceFactory; 064import com.hp.hpl.jena.vocabulary.RDF; 065 066/** 067 * <p>ViewHelpersTest class.</p> 068 * 069 * @author awoods 070 */ 071public class ViewHelpersTest { 072 073 private ViewHelpers testObj; 074 075 @Before 076 public void setUp() { 077 testObj = ViewHelpers.getInstance(); 078 } 079 080 @Test 081 public void testGetVersions() { 082 final Graph mem = createDefaultModel().getGraph(); 083 final Node version = createURI("http://localhost/fcrepo/abc/fcr:version/adcd"); 084 final String date = new Date().toString(); 085 mem.add(new Triple(createURI("http://localhost/fcrepo/abc"), HAS_VERSION.asNode(), 086 version)); 087 mem.add(new Triple(version, CREATED_DATE.asNode(), createLiteral(date))); 088 assertEquals("Version should be available.", 089 version, testObj.getVersions(mem, createURI("http://localhost/fcrepo/abc")).next()); 090 } 091 092 @Test 093 public void testGetOrderedVersions() { 094 final Node resource = createURI("http://localhost/fcrepo/abc"); 095 final Node v1 = createURI("http://localhost/fcrepo/abc/fcr:version/1"); 096 final Node v2 = createURI("http://localhost/fcrepo/abc/fcr:version/2"); 097 final Node v3 = createURI("http://localhost/fcrepo/abc/fcr:version/3"); 098 final Date now = new Date(); 099 final Date later = new Date(); 100 later.setTime(later.getTime() + 10000l); 101 102 final Graph mem = createDefaultModel().getGraph(); 103 mem.add(new Triple(resource, HAS_VERSION.asNode(), v1)); 104 mem.add(new Triple(v1, CREATED_DATE.asNode(), 105 createLiteral(now.toString()))); 106 mem.add(new Triple(resource, HAS_VERSION.asNode(), v2)); 107 mem.add(new Triple(v2, CREATED_DATE.asNode(), 108 createLiteral(now.toString()))); 109 mem.add(new Triple(resource, HAS_VERSION.asNode(), v3)); 110 mem.add(new Triple(v3, CREATED_DATE.asNode(), 111 createLiteral(later.toString()))); 112 113 final Iterator<Node> versions = testObj.getOrderedVersions(mem, resource, HAS_VERSION); 114 versions.next(); 115 versions.next(); 116 final Node r3 = versions.next(); 117 assertEquals("Latest version should be last.", v3, r3); 118 } 119 120 @Test 121 public void shouldConvertAUriToNodeBreadcrumbs() { 122 123 final UriInfo mockUriInfo = getUriInfoImpl(); 124 125 final Map<String, String> nodeBreadcrumbs = 126 testObj.getNodeBreadcrumbs(mockUriInfo, createResource( 127 "http://localhost/fcrepo/a/b/c").asNode()); 128 129 assertEquals(of("http://localhost/fcrepo/a", "a", 130 "http://localhost/fcrepo/a/b", "b", 131 "http://localhost/fcrepo/a/b/c", "c"), nodeBreadcrumbs); 132 } 133 134 @Test 135 public void shouldRefuseToConvertAForeignUriToNodeBreadcrumbs() { 136 137 final UriInfo mockUriInfo = getUriInfoImpl(); 138 139 final Map<String, String> nodeBreadcrumbs = 140 testObj.getNodeBreadcrumbs(mockUriInfo, createResource( 141 "http://somewhere/else/a/b/c").asNode()); 142 143 assertTrue(nodeBreadcrumbs.isEmpty()); 144 } 145 146 @Test 147 public void testIsWritable() { 148 final Graph mem = createDefaultModel().getGraph(); 149 mem.add(new Triple(createURI("a/b/c"), WRITABLE.asNode(), createLiteral(Boolean.TRUE.toString()))); 150 assertTrue("Node is should be writable.", testObj.isWritable(mem, createURI("a/b/c"))); 151 } 152 153 @Test 154 public void testIsWritableFalse() { 155 final Graph mem = createDefaultModel().getGraph(); 156 mem.add(new Triple(createURI("a/b/c"), WRITABLE.asNode(), createLiteral(Boolean.FALSE.toString()))); 157 assertFalse("Node should not be writable.", testObj.isWritable(mem, createURI("a/b/c"))); 158 } 159 160 @Test 161 public void testIsWritableFalseJunk() { 162 final Graph mem = createDefaultModel().getGraph(); 163 mem.add(new Triple(createURI("a/b/c"), DESCRIBES.asNode(), createLiteral("junk"))); 164 assertFalse("Node should not be writable.", testObj.isWritable(mem, createURI("a/b/c"))); 165 } 166 167 @Test 168 public void testIsVersionedNode() { 169 final Graph mem = createDefaultModel().getGraph(); 170 mem.add(new Triple(createURI("a/b/c"), RDF.type.asNode(), createURI(REPOSITORY_NAMESPACE + "Version"))); 171 assertTrue("Node is a versioned node.", testObj.isVersionedNode(mem, createURI("a/b/c"))); 172 } 173 174 @Test 175 public void testIsNotVersionedNode() { 176 final Graph mem = createDefaultModel().getGraph(); 177 mem.add(new Triple(createURI("a/b/c"), HAS_PRIMARY_TYPE.asNode(), createLiteral("nt:file"))); 178 assertFalse("Node is not a versioned node.", testObj.isVersionedNode(mem, createURI("a/b/c"))); 179 } 180 181 @Test 182 public void testRdfResource() { 183 final String ns = "http://any/namespace#"; 184 final String type = "anyType"; 185 final Graph mem = createDefaultModel().getGraph(); 186 mem.add(new Triple(createURI("a/b"), 187 createResource(RDF_NAMESPACE + "type").asNode(), 188 createResource(ns + type).asNode())); 189 190 assertTrue("Node is a " + type + " node.", 191 testObj.isRdfResource(mem, createURI("a/b"), ns, type)); 192 assertFalse("Node is not a " + type + " node.", 193 testObj.isRdfResource(mem, createURI("a/b"), ns, "otherType")); 194 } 195 196 @Test 197 public void shouldFindVersionRoot() { 198 199 final UriInfo mockUriInfo = getUriInfoImpl(); 200 201 final String nodeUri = testObj.getVersionSubjectUrl(mockUriInfo, createResource( 202 "http://localhost/fcrepo/a/b/fcr:versions/c").asNode()); 203 assertEquals("http://localhost/fcrepo/a/b", nodeUri); 204 } 205 206 @Test 207 public void testGetLabeledVersion() { 208 final Graph mem = createDefaultModel().getGraph(); 209 final String label = "testLabel"; 210 mem.add(new Triple(createURI("a/b/c"), HAS_VERSION_LABEL.asNode(), 211 createLiteral(label))); 212 assertEquals("Version label should be available.", label, testObj.getVersionLabel(mem, createURI("a/b/c")) 213 .orElse("")); 214 } 215 216 @Test 217 public void testGetUnlabeledVersion() { 218 final Graph mem = createDefaultModel().getGraph(); 219 assertEquals("Default version label should be used.", 220 "d", testObj.getVersionLabel(mem, createURI("a/b/c")).orElse("d")); 221 } 222 223 @Test 224 public void testGetVersionDate() { 225 final Graph mem = createDefaultModel().getGraph(); 226 final String date = new Date().toString(); 227 mem.add(new Triple(createURI("a/b/c"), CREATED_DATE.asNode(), 228 createLiteral(date))); 229 assertEquals("Date should be available.", date, testObj.getVersionDate(mem, createURI("a/b/c")).get()); 230 } 231 232 @Test 233 public void testGetMissingVersionDate() { 234 final Graph mem = createDefaultModel().getGraph(); 235 assertFalse("Date should not be available.", testObj.getVersionDate(mem, createURI("a/b/c")).isPresent()); 236 } 237 238 @Test 239 public void shouldExtractTitleFromNode() { 240 shouldExtractTitleFromNode(DC_TITLE); 241 shouldExtractTitleFromNode(DCTERMS_TITLE); 242 shouldExtractTitleFromNode(RDFS_LABEL); 243 shouldExtractTitleFromNode(SKOS_PREFLABEL); 244 } 245 246 private void shouldExtractTitleFromNode( final Property property ) { 247 final Graph mem = createDefaultModel().getGraph(); 248 mem.add(new Triple(createURI("a/b/c"), property.asNode(), createLiteral("abc"))); 249 assertEquals("abc", testObj.getObjectTitle(mem, createURI("a/b/c"))); 250 } 251 252 @Test 253 public void shouldUseTheObjectUriIfATitleIsNotAvailable() { 254 final Graph mem = createDefaultModel().getGraph(); 255 mem.add(new Triple(createURI("a/b/c"), DC_TITLE.asNode(), createURI("d/e/f"))); 256 257 assertEquals("a/b/c", testObj.getObjectTitle(mem, createURI("a/b/c"))); 258 259 } 260 261 @Test 262 public void shouldUsetheBNodeIdIfItIsABNode() { 263 final Graph mem = createDefaultModel().getGraph(); 264 final Node anon = createAnon(); 265 assertEquals(anon.getBlankNodeLabel(), testObj 266 .getObjectTitle(mem, anon)); 267 } 268 269 @Test 270 public void shouldJustUseTheStringIfItIsALiteral() { 271 final Graph mem = createDefaultModel().getGraph(); 272 final Node lit = createLiteral("xyz"); 273 assertEquals("\"xyz\"", testObj.getObjectTitle(mem, lit)); 274 } 275 276 @Test 277 public void shouldGetSerializationFormat() { 278 final String serialKey = "jcr/xml"; 279 final Node formatRDF = createLiteral(REPOSITORY_NAMESPACE + serialKey); 280 final Node subject = createLiteral("xyz"); 281 final Graph mem = createDefaultModel().getGraph(); 282 final Property dcFormat = createProperty(DC_NAMESPACE + "format"); 283 284 mem.add(new Triple(formatRDF, RDFS_LABEL.asNode(), createLiteral(serialKey))); 285 mem.add(new Triple(subject, dcFormat.asNode(), formatRDF)); 286 287 assertEquals("jcr/xml", testObj.getSerializationTitle(mem, subject).get()); 288 } 289 290 @Test 291 public void shouldConvertRdfObjectsToStrings() { 292 293 final Graph mem = createDefaultModel().getGraph(); 294 mem.add(new Triple(createURI("subject"), createURI("a/b/c"), 295 NodeFactory.createLiteral("abc"))); 296 mem.add(new Triple(createURI("subject"), 297 createURI("a-numeric-type"), createTypedLiteral(0).asNode())); 298 mem.add(new Triple(createURI("subject"), 299 createURI("an-empty-string"), createLiteral(""))); 300 mem.add(new Triple( createURI("subject"), createURI("a-uri"), 301 createURI("some-uri"))); 302 303 assertEquals("abc", testObj.getObjectsAsString(mem, 304 createURI("subject"), createResource("a/b/c"), true)); 305 assertEquals("0", testObj.getObjectsAsString(mem, createURI("subject"), 306 createResource("a-numeric-type"), true)); 307 assertEquals("<empty>", testObj.getObjectsAsString(mem, 308 createURI("subject"), createResource("an-empty-string"), true)); 309 assertEquals("<<a href=\"some-uri\">some-uri</a>>", testObj 310 .getObjectsAsString(mem, createURI("subject"), 311 createResource("a-uri"), true)); 312 313 assertEquals("some-uri", testObj 314 .getObjectsAsString(mem, createURI("subject"), 315 createResource("a-uri"), false)); 316 assertEquals("", testObj.getObjectsAsString(mem, createURI("subject"), 317 createResource("a-nonexistent-uri"), true)); 318 319 } 320 321 @Test 322 public void shouldExtractNamespaceAndPrefix() { 323 final Model model = createDefaultModel(); 324 model.setNsPrefix("prefix", "namespace"); 325 326 assertEquals("prefix:", testObj.getNamespacePrefix(model, "namespace", false)); 327 assertEquals("some-other-namespace", testObj.getNamespacePrefix(model, 328 "some-other-namespace", false)); 329 } 330 331 @Test 332 public void shouldSortTriplesForDisplay() { 333 final Model model = createDefaultModel(); 334 335 model.setNsPrefix("prefix", "namespace"); 336 final Property propertyA = model.createProperty("namespace", "a"); 337 final Property propertyB = model.createProperty("namespace", "b"); 338 final Property propertyC = model.createProperty("c"); 339 final Literal literalA = model.createLiteral("a"); 340 final Literal literalB = model.createLiteral("b"); 341 final Resource resourceB = model.createResource("b"); 342 model.add(resourceB, propertyA, literalA); 343 344 final Resource a = model.createResource("a"); 345 model.add(a, propertyC, literalA); 346 347 model.add(a, propertyB, literalA); 348 349 model.add(a, propertyA, literalA); 350 model.add(a, propertyA, literalB); 351 352 final Iterator<Triple> iterator = model.getGraph().find(null, null, null); 353 354 final List<Triple> sortedTriples = 355 testObj.getSortedTriples(model, iterator); 356 357 sortedTriples.get(0).matches(a.asNode(), propertyA.asNode(), 358 literalA.asNode()); 359 sortedTriples.get(1).matches(a.asNode(), propertyA.asNode(), 360 literalB.asNode()); 361 sortedTriples.get(2).matches(a.asNode(), propertyB.asNode(), 362 literalA.asNode()); 363 sortedTriples.get(3).matches(a.asNode(), propertyC.asNode(), 364 literalA.asNode()); 365 sortedTriples.get(4).matches(resourceB.asNode(), 366 propertyC.asNode(), literalA.asNode()); 367 368 } 369 370 @Test 371 public void shouldConvertPrefixMappingToSparqlUpdatePrefixPreamble() { 372 373 final Model model = createDefaultModel(); 374 375 model.setNsPrefix("prefix", "namespace"); 376 377 final String prefixPreamble = testObj.getPrefixPreamble(model); 378 379 assertEquals("PREFIX prefix: <namespace>\n\n", prefixPreamble); 380 } 381 382 @Test 383 public void shouldConvertStringLiteralsToNodes() { 384 final String uri = "fedora:resource"; 385 final Literal URIRES = ResourceFactory.createPlainLiteral(uri); 386 assertEquals(URIRES.asNode(), testObj.asLiteralStringNode(uri)); 387 } 388 389 @Test 390 public void testGetNumChildren() { 391 final Graph mem = createDefaultModel().getGraph(); 392 mem.add(new Triple(createURI("a/b/c"), HAS_CHILD_COUNT.asNode(), createTypedLiteral(4).asNode())); 393 assertEquals(4, testObj.getNumChildren(mem, createURI("a/b/c"))); 394 } 395 396 @Test 397 public void testGetNumChildrenEmpty() { 398 final Graph mem = createDefaultModel().getGraph(); 399 mem.add(new Triple(createURI("a/b/c"), HAS_CHILD_COUNT.asNode(), createLiteral(""))); 400 assertEquals(0, testObj.getNumChildren(mem, createURI("a/b/c"))); 401 } 402 403 @Test 404 public void testGetNumChildrenNone() { 405 final Graph mem = createDefaultModel().getGraph(); 406 assertEquals(0, testObj.getNumChildren(mem, createURI("a/b/c"))); 407 } 408 409}