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.client.integration; 019 020import static javax.ws.rs.core.Response.Status.BAD_REQUEST; 021import static javax.ws.rs.core.Response.Status.CONFLICT; 022import static javax.ws.rs.core.Response.Status.CREATED; 023import static javax.ws.rs.core.Response.Status.GONE; 024import static javax.ws.rs.core.Response.Status.NOT_FOUND; 025import static javax.ws.rs.core.Response.Status.NOT_MODIFIED; 026import static javax.ws.rs.core.Response.Status.NO_CONTENT; 027import static javax.ws.rs.core.Response.Status.OK; 028import static javax.ws.rs.core.Response.Status.PARTIAL_CONTENT; 029import static javax.ws.rs.core.Response.Status.PRECONDITION_FAILED; 030import static javax.ws.rs.core.Response.Status.TEMPORARY_REDIRECT; 031import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_DISPOSITION_FILENAME; 032import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_TYPE; 033import static org.fcrepo.client.FedoraHeaderConstants.DIGEST; 034import static org.fcrepo.client.FedoraHeaderConstants.ETAG; 035import static org.fcrepo.client.FedoraHeaderConstants.LAST_MODIFIED; 036import static org.fcrepo.client.FedoraHeaderConstants.STATE_TOKEN; 037import static org.fcrepo.client.FedoraTypes.LDP_DIRECT_CONTAINER; 038import static org.fcrepo.client.TestUtils.TEXT_TURTLE; 039import static org.fcrepo.client.TestUtils.sparqlUpdate; 040import static org.junit.Assert.assertEquals; 041import static org.junit.Assert.assertNotEquals; 042import static org.junit.Assert.assertNotNull; 043import static org.junit.Assert.assertNull; 044import static org.junit.Assert.assertTrue; 045 046import java.io.ByteArrayInputStream; 047import java.io.InputStream; 048import java.net.URI; 049import java.nio.file.Files; 050import java.nio.file.Path; 051import java.util.Arrays; 052import java.util.Calendar; 053import java.util.Date; 054import java.util.HashMap; 055import java.util.Map; 056import java.util.UUID; 057 058import javax.ws.rs.core.EntityTag; 059 060import org.apache.commons.io.FileUtils; 061import org.apache.commons.io.IOUtils; 062import org.apache.http.client.utils.DateUtils; 063import org.fcrepo.client.ExternalContentHandling; 064import org.fcrepo.client.FcrepoClient; 065import org.fcrepo.client.FcrepoOperationFailedException; 066import org.fcrepo.client.FcrepoResponse; 067import org.fcrepo.client.HeaderHelpers; 068import org.junit.Before; 069import org.junit.Test; 070 071/** 072 * @author bbpennel 073 */ 074public class FcrepoClientIT extends AbstractResourceIT { 075 076 protected URI url; 077 078 final private String UNMODIFIED_DATE = "Mon, 1 Jan 2001 00:00:00 GMT"; 079 080 public FcrepoClientIT() throws Exception { 081 super(); 082 083 client = FcrepoClient.client() 084 .credentials("fedoraAdmin", "fedoraAdmin") 085 .authScope("localhost") 086 .build(); 087 } 088 089 @Before 090 public void before() { 091 url = URI.create(serverAddress + UUID.randomUUID().toString()); 092 } 093 094 @Test 095 public void testPost() throws Exception { 096 final FcrepoResponse response = client.post(new URI(serverAddress)) 097 .perform(); 098 099 assertEquals(CREATED.getStatusCode(), response.getStatusCode()); 100 } 101 102 @Test 103 public void testPostBinary() throws Exception { 104 final String slug = UUID.randomUUID().toString(); 105 final String filename = "hello.txt"; 106 final String mimetype = "text/plain"; 107 final String bodyContent = "Hello world"; 108 final FcrepoResponse response = client.post(new URI(serverAddress)) 109 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 110 .filename(filename) 111 .slug(slug) 112 .perform(); 113 114 final String content = IOUtils.toString(response.getBody(), "UTF-8"); 115 final int status = response.getStatusCode(); 116 117 assertEquals("Didn't get a CREATED response! Got content:\n" + content, 118 CREATED.getStatusCode(), status); 119 assertEquals("Location did not match slug", serverAddress + slug, response.getLocation().toString()); 120 121 assertNotNull("Didn't find linked description!", response.getLinkHeaders("describedby").get(0)); 122 123 final FcrepoResponse getResponse = client.get(response.getLocation()).perform(); 124 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 125 assertEquals(filename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 126 127 assertEquals(mimetype, getResponse.getContentType()); 128 129 final String getContent = IOUtils.toString(getResponse.getBody(), "UTF-8"); 130 assertEquals(bodyContent, getContent); 131 } 132 133 @Test 134 public void testPostExternalContent() throws Exception { 135 final String filename = "hello.txt"; 136 final String mimetype = "text/plain"; 137 final String fileContent = "Hello post world"; 138 139 final Path contentPath = Files.createTempFile(null, ".txt"); 140 FileUtils.write(contentPath.toFile(), fileContent, "UTF-8"); 141 142 final FcrepoResponse response = client.post(new URI(serverAddress)) 143 .externalContent(contentPath.toUri(), mimetype, ExternalContentHandling.PROXY) 144 .filename(filename) 145 .perform(); 146 147 final String content = IOUtils.toString(response.getBody(), "UTF-8"); 148 final int status = response.getStatusCode(); 149 150 assertEquals("Didn't get a CREATED response! Got content:\n" + content, 151 CREATED.getStatusCode(), status); 152 153 final FcrepoResponse getResponse = client.get(response.getLocation()).perform(); 154 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 155 assertEquals(filename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 156 157 assertEquals(mimetype, getResponse.getContentType()); 158 159 final String getContent = IOUtils.toString(getResponse.getBody(), "UTF-8"); 160 assertEquals(fileContent, getContent); 161 } 162 163 @Test 164 public void testPostDigestMismatch() throws Exception { 165 final String bodyContent = "Hello world"; 166 final String invalidDigest = "adc83b19e793491b1c6ea0fd8b46cd9f32e592fc"; 167 168 final FcrepoResponse response = client.post(new URI(serverAddress)) 169 .body(new ByteArrayInputStream(bodyContent.getBytes()), "text/plain") 170 .digestSha1(invalidDigest) 171 .perform(); 172 173 assertEquals("Invalid checksum was not rejected", CONFLICT.getStatusCode(), response.getStatusCode()); 174 } 175 176 @Test 177 public void testPostDigestMultipleChecksums() throws Exception { 178 final String bodyContent = "Hello world"; 179 180 final FcrepoResponse response = client.post(new URI(serverAddress)) 181 .body(new ByteArrayInputStream(bodyContent.getBytes()), "text/plain") 182 .digestMd5("3e25960a79dbc69b674cd4ec67a72c62") 183 .digestSha1("7b502c3a1f48c8609ae212cdfb639dee39673f5e") 184 .digestSha256("64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c") 185 .perform(); 186 187 assertEquals("Checksums rejected", CREATED.getStatusCode(), response.getStatusCode()); 188 } 189 190 @Test 191 public void testPostDigestMultipleChecksumsOneMismatch() throws Exception { 192 final String bodyContent = "Hello world"; 193 194 final FcrepoResponse response = client.post(new URI(serverAddress)) 195 .body(new ByteArrayInputStream(bodyContent.getBytes()), "text/plain") 196 .digestMd5("3e25960a79dbc69b674cd4ec67a72c62") 197 .digestSha1("7b502c3a1f48c8609ae212cdfb639dee39673f5e") 198 // Incorrect sha256 199 .digestSha256("123488ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c") 200 .perform(); 201 202 assertEquals("Invalid checksum was not rejected", CONFLICT.getStatusCode(), response.getStatusCode()); 203 } 204 205 @Test 206 public void testPostBinaryNullFilename() throws Exception { 207 final String bodyContent = "Hello world"; 208 209 final FcrepoResponse response = client.post(new URI(serverAddress)) 210 .body(new ByteArrayInputStream(bodyContent.getBytes()), "text/plain") 211 .filename(null) 212 .perform(); 213 214 assertEquals("Empty filename rejected", CREATED.getStatusCode(), response.getStatusCode()); 215 } 216 217 @Test 218 public void testPostDirectContainer() throws Exception { 219 final FcrepoResponse response = client.post(new URI(serverAddress)) 220 .addInteractionModel(LDP_DIRECT_CONTAINER) 221 .perform(); 222 223 final int status = response.getStatusCode(); 224 225 assertEquals("Didn't get a CREATED response!", CREATED.getStatusCode(), status); 226 227 final FcrepoResponse getResponse = client.get(response.getLocation()).perform(); 228 assertTrue("Did not have ldp:DirectContainer type", getResponse.hasType(LDP_DIRECT_CONTAINER)); 229 } 230 231 @Test 232 public void testPostBinaryFilenameSpecialCharacters() throws Exception { 233 final String slug = UUID.randomUUID().toString(); 234 final String filename = "hello world\nof_weird:+\tchar/acters.tx\rt"; 235 final String expectedFilename = "hello world of_weird:+\tchar/acters.tx t"; 236 final String mimetype = "text/plain"; 237 final String bodyContent = "Hello world"; 238 final FcrepoResponse response = client.post(new URI(serverAddress)) 239 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 240 .filename(filename) 241 .slug(slug) 242 .perform(); 243 244 final String content = IOUtils.toString(response.getBody(), "UTF-8"); 245 final int status = response.getStatusCode(); 246 247 assertEquals("Didn't get a CREATED response! Got content:\n" + content, 248 CREATED.getStatusCode(), status); 249 assertEquals("Location did not match slug", serverAddress + slug, response.getLocation().toString()); 250 251 assertNotNull("Didn't find linked description!", response.getLinkHeaders("describedby").get(0)); 252 253 final FcrepoResponse getResponse = client.get(response.getLocation()).perform(); 254 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 255 assertEquals(expectedFilename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 256 257 assertEquals(mimetype, getResponse.getContentType()); 258 259 final String getContent = IOUtils.toString(getResponse.getBody(), "UTF-8"); 260 assertEquals(bodyContent, getContent); 261 } 262 263 @Test 264 public void testPutBinaryFilenameSpecialCharacters() throws Exception { 265 final String id = UUID.randomUUID().toString(); 266 final String filename = "hello world\nof_weird:+\tchar/acters.tx\rt"; 267 final String expectedFilename = "hello world of_weird:+\tchar/acters.tx t"; 268 final String mimetype = "text/plain"; 269 final String bodyContent = "Hello world"; 270 final FcrepoResponse response = client.put(new URI(serverAddress + id)) 271 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 272 .filename(filename) 273 .perform(); 274 275 final String content = IOUtils.toString(response.getBody(), "UTF-8"); 276 final int status = response.getStatusCode(); 277 278 assertEquals("Didn't get a CREATED response! Got content:\n" + content, 279 CREATED.getStatusCode(), status); 280 assertEquals("Location did not match slug", serverAddress + id, response.getLocation().toString()); 281 282 assertNotNull("Didn't find linked description!", response.getLinkHeaders("describedby").get(0)); 283 284 final FcrepoResponse getResponse = client.get(response.getLocation()).perform(); 285 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 286 assertEquals(expectedFilename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 287 288 assertEquals(mimetype, getResponse.getContentType()); 289 290 final String getContent = IOUtils.toString(getResponse.getBody(), "UTF-8"); 291 assertEquals(bodyContent, getContent); 292 } 293 294 @Test 295 public void testPut() throws Exception { 296 final FcrepoResponse response = create(); 297 298 assertEquals(CREATED.getStatusCode(), response.getStatusCode()); 299 assertEquals(url, response.getLocation()); 300 } 301 302 @Test 303 public void testPutEtag() throws Exception { 304 // Create object 305 final FcrepoResponse response = create(); 306 307 // Get the etag of the nearly created object 308 final EntityTag etag = EntityTag.valueOf(response.getHeaderValue(ETAG)); 309 310 // Retrieve the body of the resource so we can modify it 311 String body = getTurtle(url); 312 body += "\n<> <http://purl.org/dc/elements/1.1/title> \"some-title\""; 313 314 // Check that etag is making it through and being rejected 315 final FcrepoResponse updateResp = client.put(url) 316 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 317 .ifMatch("\"bad-etag\"") 318 .perform(); 319 320 assertEquals(PRECONDITION_FAILED.getStatusCode(), updateResp.getStatusCode()); 321 322 // Verify that etag is retrieved and resubmitted correctly 323 final FcrepoResponse validResp = client.put(url) 324 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 325 .ifMatch("\"" + etag.getValue() + "\"") 326 .perform(); 327 assertEquals(NO_CONTENT.getStatusCode(), validResp.getStatusCode()); 328 } 329 330 @Test 331 public void testPutUnmodifiedSince() throws Exception { 332 // Create object 333 final FcrepoResponse response = create(); 334 335 // Retrieve the body of the resource so we can modify it 336 String body = getTurtle(url); 337 body += "\n<> <http://purl.org/dc/elements/1.1/title> \"some-title\""; 338 339 // Update the body the first time, which should succeed 340 final String originalModified = response.getHeaderValue(LAST_MODIFIED); 341 final FcrepoResponse matchResponse = client.put(url) 342 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 343 .ifUnmodifiedSince(originalModified) 344 .perform(); 345 346 assertEquals(NO_CONTENT.getStatusCode(), matchResponse.getStatusCode()); 347 348 // Update the triples a second time with old timestamp 349 final FcrepoResponse mismatchResponse = client.put(url) 350 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 351 .ifUnmodifiedSince(UNMODIFIED_DATE) 352 .perform(); 353 354 assertEquals(PRECONDITION_FAILED.getStatusCode(), mismatchResponse.getStatusCode()); 355 } 356 357 @Test 358 public void testPutLenient() throws Exception { 359 // Create object 360 create(); 361 final String body = "<> <http://purl.org/dc/elements/1.1/title> \"some-title\""; 362 363 // try to update without lenient header 364 final FcrepoResponse strictResponse = client.put(url) 365 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 366 .perform(); 367 assertEquals(NO_CONTENT.getStatusCode(), strictResponse.getStatusCode()); 368 369 // try again with lenient header 370 final FcrepoResponse lenientResponse = client.put(url) 371 .body(new ByteArrayInputStream(body.getBytes()), TEXT_TURTLE) 372 .preferLenient() 373 .perform(); 374 assertEquals(NO_CONTENT.getStatusCode(), lenientResponse.getStatusCode()); 375 } 376 377 @Test 378 public void testPutExternalContent() throws Exception { 379 final String filename = "put.txt"; 380 final String mimetype = "text/plain"; 381 final String fileContent = "Hello put world"; 382 383 final Path contentPath = Files.createTempFile(null, ".txt"); 384 FileUtils.write(contentPath.toFile(), fileContent, "UTF-8"); 385 386 final FcrepoResponse response = client.put(url) 387 .externalContent(contentPath.toUri(), mimetype, ExternalContentHandling.PROXY) 388 .filename(filename) 389 .perform(); 390 391 final String content = IOUtils.toString(response.getBody(), "UTF-8"); 392 final int status = response.getStatusCode(); 393 394 assertEquals("Didn't get a CREATED response! Got content:\n" + content, 395 CREATED.getStatusCode(), status); 396 397 final FcrepoResponse getResponse = client.get(response.getLocation()).perform(); 398 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 399 assertEquals(filename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 400 401 assertEquals(mimetype, getResponse.getContentType()); 402 403 final String getContent = IOUtils.toString(getResponse.getBody(), "UTF-8"); 404 assertEquals(fileContent, getContent); 405 } 406 407 @Test 408 public void testPutBinaryNullFilename() throws Exception { 409 final String bodyContent = "Hello world"; 410 411 final FcrepoResponse response = client.put(url) 412 .body(new ByteArrayInputStream(bodyContent.getBytes()), "text/plain") 413 .filename(null) 414 .perform(); 415 416 assertEquals("Empty filename rejected", CREATED.getStatusCode(), response.getStatusCode()); 417 } 418 419 @Test 420 public void testPatch() throws Exception { 421 // Create object 422 create(); 423 424 final InputStream body = new ByteArrayInputStream(sparqlUpdate.getBytes()); 425 426 // Update triples with sparql update 427 final FcrepoResponse response = client.patch(url) 428 .body(body) 429 .perform(); 430 431 assertEquals(NO_CONTENT.getStatusCode(), response.getStatusCode()); 432 } 433 434 @Test 435 public void testPatchEtagUpdated() throws Exception { 436 // Create object 437 final FcrepoResponse createResp = create(); 438 final EntityTag createdEtag = EntityTag.valueOf(createResp.getHeaderValue(ETAG)); 439 440 final InputStream body = new ByteArrayInputStream(sparqlUpdate.getBytes()); 441 442 // Update triples with sparql update 443 final FcrepoResponse response = client.patch(url) 444 .body(body) 445 .ifMatch("\"" + createdEtag.getValue() + "\"") 446 .perform(); 447 448 final EntityTag updateEtag = EntityTag.valueOf(response.getHeaderValue(ETAG)); 449 450 assertEquals(NO_CONTENT.getStatusCode(), response.getStatusCode()); 451 assertNotEquals("Etag did not change after patch", createdEtag, updateEtag); 452 } 453 454 @Test 455 public void testPatchNoBody() throws Exception { 456 create(); 457 458 final FcrepoResponse response = client.patch(url) 459 .perform(); 460 461 assertEquals(BAD_REQUEST.getStatusCode(), response.getStatusCode()); 462 } 463 464 @Test 465 public void testDelete() throws Exception { 466 create(); 467 468 final FcrepoResponse response = client.delete(url).perform(); 469 470 assertEquals(NO_CONTENT.getStatusCode(), response.getStatusCode()); 471 472 assertEquals(GONE.getStatusCode(), client.get(url).perform().getStatusCode()); 473 } 474 475 @Test 476 public void testGet() throws Exception { 477 create(); 478 final FcrepoResponse response = client.get(url).perform(); 479 480 assertEquals(OK.getStatusCode(), response.getStatusCode()); 481 } 482 483 @Test 484 public void testGetNotFound() throws Exception { 485 final FcrepoResponse response = client.get(url).perform(); 486 487 assertEquals(NOT_FOUND.getStatusCode(), response.getStatusCode()); 488 } 489 490 @Test 491 public void testGetUnmodified() throws Exception { 492 // Check that get returns a 304 if the item hasn't changed according to last-modified 493 final FcrepoResponse response = create(); 494 495 // Get tomorrows date to provide as the modified-since date 496 final String lastModified = response.getHeaderValue(LAST_MODIFIED); 497 final Date modDate = DateUtils.parseDate(lastModified); 498 final Calendar cal = Calendar.getInstance(); 499 cal.setTime(modDate); 500 cal.add(Calendar.DATE, 1); 501 502 final FcrepoResponse modResp = client.get(url) 503 .ifModifiedSince(DateUtils.formatDate(cal.getTime())) 504 .perform(); 505 506 assertEquals(NOT_MODIFIED.getStatusCode(), modResp.getStatusCode()); 507 assertNull("Response body should not be returned when unmodified", modResp.getBody()); 508 } 509 510 @Test 511 public void testGetModified() throws Exception { 512 // Check that get returns a 200 if the item has changed according to last-modified 513 final FcrepoResponse response = create(); 514 515 // Get yesterdays date to provide as the modified-since date 516 final String lastModified = response.getHeaderValue(LAST_MODIFIED); 517 final Date modDate = DateUtils.parseDate(lastModified); 518 final Calendar cal = Calendar.getInstance(); 519 cal.setTime(modDate); 520 cal.add(Calendar.DATE, -1); 521 522 final FcrepoResponse modResp = client.get(url) 523 .ifModifiedSince(DateUtils.formatDate(cal.getTime())) 524 .perform(); 525 526 assertEquals(OK.getStatusCode(), modResp.getStatusCode()); 527 assertNotNull("GET response body should be normal when modified", modResp.getBody()); 528 } 529 530 @Test 531 public void testGetAccept() throws Exception { 532 // Check that get returns a 304 if the item hasn't changed according to last-modified/etag 533 create(); 534 535 final FcrepoResponse response = client.get(url) 536 .accept("application/n-triples") 537 .perform(); 538 539 assertEquals("application/n-triples", response.getHeaderValue(CONTENT_TYPE)); 540 assertEquals(OK.getStatusCode(), response.getStatusCode()); 541 } 542 543 @Test 544 public void testGetPrefer() throws Exception { 545 // Check that get returns a 304 if the item hasn't changed according to last-modified/etag 546 create(); 547 548 final FcrepoResponse response = client.get(url) 549 .preferRepresentation(Arrays.asList(URI.create("http://www.w3.org/ns/ldp#PreferMinimalContainer")), 550 Arrays.asList(URI.create("http://fedora.info/definitions/fcrepo#ServerManaged"))).perform(); 551 552 assertEquals(OK.getStatusCode(), response.getStatusCode()); 553 assertEquals("return=representation; include=\"http://www.w3.org/ns/ldp#PreferMinimalContainer\"; " + 554 "omit=\"http://fedora.info/definitions/fcrepo#ServerManaged\"", 555 response.getHeaderValue("Preference-Applied")); 556 } 557 558 @Test 559 public void testGetRange() throws Exception { 560 // Creating a binary for retrieval 561 final String mimetype = "text/plain"; 562 final String bodyContent = "Hello world"; 563 final FcrepoResponse response = client.post(new URI(serverAddress)) 564 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 565 .perform(); 566 567 final URI url = response.getLocation(); 568 569 // Get the content of the object after the first 6 bytes 570 final FcrepoResponse rangeResp = client.get(url) 571 .range(6L, null) 572 .perform(); 573 574 final String content = IOUtils.toString(rangeResp.getBody(), "UTF-8"); 575 assertEquals("Body did not contain correct range of original content", "world", content); 576 assertEquals(PARTIAL_CONTENT.getStatusCode(), rangeResp.getStatusCode()); 577 } 578 579 @Test 580 public void testGetDisableRedirects() throws Exception { 581 final String filename = "example.html"; 582 final String mimetype = "text/plain"; 583 584 final URI externalURI = URI.create("http://example.com/"); 585 586 final FcrepoResponse response = client.post(new URI(serverAddress)) 587 .externalContent(externalURI, mimetype, ExternalContentHandling.REDIRECT) 588 .filename(filename) 589 .perform(); 590 591 final FcrepoResponse getResponse = client.get(response.getLocation()) 592 .disableRedirects() 593 .perform(); 594 assertEquals("Didn't get a REDIRECT response!", 595 TEMPORARY_REDIRECT.getStatusCode(), getResponse.getStatusCode()); 596 assertEquals(mimetype, getResponse.getContentType()); 597 598 final Map<String, String> contentDisp = getResponse.getContentDisposition(); 599 assertEquals(filename, contentDisp.get(CONTENT_DISPOSITION_FILENAME)); 600 601 assertEquals(externalURI, getResponse.getLocation()); 602 } 603 604 @Test 605 public void testGetWantDigest() throws Exception { 606 // Creating a binary for retrieval 607 final String mimetype = "text/plain"; 608 final String bodyContent = "Hello world"; 609 final FcrepoResponse response = client.post(new URI(serverAddress)) 610 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 611 .perform(); 612 613 final URI url = response.getLocation(); 614 615 // Request md5 digest with caching disabled 616 final FcrepoResponse getResp = client.get(url) 617 .wantDigest("md5") 618 .noCache() 619 .perform(); 620 assertEquals(OK.getStatusCode(), getResp.getStatusCode()); 621 622 final String digest = getResp.getHeaderValue(DIGEST); 623 assertTrue("Did not contain md5", digest.contains("md5=3e25960a79dbc69b674cd4ec67a72c62")); 624 } 625 626 @Test 627 public void testHead() throws Exception { 628 final FcrepoResponse response = create(); 629 final FcrepoResponse headResp = client.head(url).perform(); 630 631 assertEquals(OK.getStatusCode(), headResp.getStatusCode()); 632 assertEquals(response.getHeaderValue(ETAG), headResp.getHeaderValue(ETAG)); 633 assertNotNull(headResp.getHeaderValue("Allow")); 634 } 635 636 @Test 637 public void testHeadWantDigest() throws Exception { 638 // Creating a binary for retrieval 639 final String mimetype = "text/plain"; 640 final String bodyContent = "Hello world"; 641 final FcrepoResponse response = client.post(new URI(serverAddress)) 642 .body(new ByteArrayInputStream(bodyContent.getBytes()), mimetype) 643 .perform(); 644 645 final URI url = response.getLocation(); 646 647 final Map<String, Double> qualityMap = new HashMap<>(); 648 qualityMap.put("md5", 1.0); 649 qualityMap.put("sha", 1.0); 650 qualityMap.put("sha-256", 0.4); 651 652 final String wantDigest = HeaderHelpers.formatQualityValues(qualityMap); 653 // Request multiple digests 654 final FcrepoResponse getResp = client.head(url) 655 .wantDigest(wantDigest) 656 .perform(); 657 assertEquals(OK.getStatusCode(), getResp.getStatusCode()); 658 659 final String digest = getResp.getHeaderValue(DIGEST); 660 assertTrue("Did not contain md5", digest.contains("md5=3e25960a79dbc69b674cd4ec67a72c62")); 661 assertTrue("Did not contain sha1", digest.contains("sha=7b502c3a1f48c8609ae212cdfb639dee39673f5e")); 662 assertTrue("Did not contain sha256", digest 663 .contains("sha-256=64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c")); 664 } 665 666 @Test 667 public void testOptions() throws Exception { 668 create(); 669 final FcrepoResponse headResp = client.options(url).perform(); 670 671 assertEquals(OK.getStatusCode(), headResp.getStatusCode()); 672 assertNotNull(headResp.getHeaderValue("Allow")); 673 assertNotNull(headResp.getHeaderValue("Accept-Post")); 674 assertNotNull(headResp.getHeaderValue("Accept-Patch")); 675 } 676 677 @Test 678 public void testStateTokens() throws Exception { 679 create(); 680 681 final FcrepoResponse getResp = client.get(url).perform(); 682 final String stateToken = getResp.getHeaderValue(STATE_TOKEN); 683 684 // Attempt to update triples with an incorrect state token 685 final InputStream body = new ByteArrayInputStream(sparqlUpdate.getBytes()); 686 final FcrepoResponse badTokenResp = client.patch(url) 687 .body(body) 688 .ifStateToken("bad_state_token") 689 .perform(); 690 assertEquals(PRECONDITION_FAILED.getStatusCode(), badTokenResp.getStatusCode()); 691 692 // Update triples with the correct state token 693 body.reset(); 694 final FcrepoResponse goodTokenResp = client.patch(url) 695 .body(body) 696 .ifStateToken(stateToken) 697 .perform(); 698 assertEquals(NO_CONTENT.getStatusCode(), goodTokenResp.getStatusCode()); 699 } 700 701 private FcrepoResponse create() throws FcrepoOperationFailedException { 702 return client.put(url).perform(); 703 } 704 705 private String getTurtle(final URI url) throws Exception { 706 final FcrepoResponse getResponse = client.get(url) 707 .accept("text/turtle") 708 .preferRepresentation(Arrays.asList(URI.create("http://www.w3.org/ns/ldp#PreferMinimalContainer")), 709 Arrays.asList(URI.create("http://fedora.info/definitions/fcrepo#ServerManaged"))).perform(); 710 return IOUtils.toString(getResponse.getBody(), "UTF-8"); 711 } 712}