001/* 002 * The contents of this file are subject to the license and copyright 003 * detailed in the LICENSE and NOTICE files at the root of the source 004 * tree. 005 */ 006package org.fcrepo.http.commons.exceptionhandlers; 007 008import org.fcrepo.http.commons.api.rdf.HttpIdentifierConverter; 009import org.fcrepo.kernel.api.exception.TombstoneException; 010import org.fcrepo.kernel.api.identifiers.FedoraId; 011import org.fcrepo.kernel.api.models.FedoraResource; 012import org.junit.Before; 013import org.junit.Test; 014import org.mockito.Mock; 015 016import javax.ws.rs.core.Link; 017import javax.ws.rs.core.Response; 018import javax.ws.rs.core.UriBuilder; 019import javax.ws.rs.ext.ExceptionMapper; 020import java.net.URI; 021import java.time.Instant; 022import java.util.Arrays; 023import java.util.List; 024import java.util.stream.Collectors; 025 026import static java.time.ZoneOffset.UTC; 027import static java.time.format.DateTimeFormatter.ISO_INSTANT; 028import static javax.ws.rs.core.HttpHeaders.LINK; 029import static javax.ws.rs.core.Response.Status.GONE; 030import static org.fcrepo.kernel.api.FedoraTypes.FCR_VERSIONS; 031import static org.junit.Assert.assertEquals; 032import static org.junit.Assert.assertNull; 033import static org.junit.Assert.fail; 034import static org.mockito.Mockito.when; 035import static org.mockito.MockitoAnnotations.initMocks; 036 037/** 038 * @author cabeer 039 */ 040public class TombstoneExceptionMapperTest { 041 042 @Mock 043 private FedoraResource mockResource; 044 045 private final FedoraId fedoraId = FedoraId.create("/some:uri"); 046 047 private final Instant deleteTime = Instant.now(); 048 049 private ExceptionMapper<TombstoneException> testObj; 050 051 private static final String SERVER_URI = "http://localhost:8080/rest(.*)"; 052 053 private final HttpIdentifierConverter idConverter = new HttpIdentifierConverter(UriBuilder.fromUri(SERVER_URI)); 054 055 @Before 056 public void setUp() { 057 initMocks(this); 058 when(mockResource.getFedoraId()).thenReturn(fedoraId); 059 when(mockResource.getLastModifiedDate()).thenReturn(deleteTime); 060 testObj = new TombstoneExceptionMapper(); 061 } 062 063 @Test 064 public void testUrilessException() { 065 final Response response = testObj.toResponse(new TombstoneException(mockResource)); 066 assertEquals(GONE.getStatusCode(), response.getStatus()); 067 assertTombstone(response, fedoraId.getFullIdPath(), null); 068 } 069 070 @Test 071 public void testExceptionWithUri() { 072 final String tombstone = idConverter.toExternalId(fedoraId.asTombstone().getFullId()); 073 final String timemap = idConverter.toExternalId(fedoraId.resolve(FCR_VERSIONS).getFullId()); 074 final Response response = testObj.toResponse(new TombstoneException(mockResource, tombstone, timemap)); 075 assertEquals(GONE.getStatusCode(), response.getStatus()); 076 assertTombstone(response, fedoraId.getFullIdPath(), tombstone); 077 final List<Link> links = Arrays.stream(response.getHeaderString(LINK).split(",")).map(Link::valueOf) 078 .collect(Collectors.toList()); 079 assertLinkHeaderExists(links, timemap, "timemap"); 080 } 081 082 private void assertTombstone(final Response response, final String tombstoneAt, final String tombstoneUri) { 083 if (tombstoneUri == null) { 084 assertNull(response.getHeaderString(LINK)); 085 } else { 086 final List<Link> links = Arrays.stream(response.getHeaderString(LINK).split(",")).map(Link::valueOf) 087 .collect(Collectors.toList()); 088 089 assertLinkHeaderExists(links, tombstoneUri, "hasTombstone"); 090 } 091 final String expectedString = "Discovered tombstone resource at " + tombstoneAt + ", departed at: " + 092 ISO_INSTANT.withZone(UTC).format(deleteTime); 093 assertEquals(expectedString, response.getEntity().toString()); 094 } 095 096 private void assertLinkHeaderExists(final List<Link> links, final String uri, final String rel) { 097 final URI uriUri = URI.create(uri); 098 if (links.stream().noneMatch(l -> l.getUri().equals(uriUri) && l.getRel().equals(rel))) { 099 fail(String.format("Did not find expected Link header with uri (%s) and rel (%s)", uri, rel)); 100 } 101 } 102}