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