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 org.apache.jena.rdf.model.Model;
021import org.apache.jena.rdf.model.Property;
022import org.fcrepo.client.FcrepoClient;
023import org.fcrepo.client.FcrepoResponse;
024import org.junit.Test;
025
026import java.io.ByteArrayInputStream;
027import java.io.ByteArrayOutputStream;
028import java.io.InputStream;
029import java.net.URI;
030import java.time.Instant;
031import java.time.LocalDateTime;
032import java.time.ZoneOffset;
033import java.time.ZonedDateTime;
034
035import static javax.ws.rs.core.Response.Status.CREATED;
036import static org.apache.jena.rdf.model.ResourceFactory.createProperty;
037import static org.fcrepo.client.FedoraTypes.MEMENTO_TYPE;
038import static org.fcrepo.client.HeaderHelpers.UTC_RFC_1123_FORMATTER;
039import static org.fcrepo.client.LinkHeaderConstants.MEMENTO_TIME_MAP_REL;
040import static org.fcrepo.client.TestUtils.rdfTtl;
041import static org.junit.Assert.assertEquals;
042import static org.junit.Assert.assertTrue;
043
044/**
045 * @author bbpennel
046 */
047public class VersioningIT extends AbstractResourceIT {
048
049    private static final Property DC_TITLE = createProperty("http://purl.org/dc/elements/1.1/title");
050
051    private final ZonedDateTime HISTORIC_DATETIME = LocalDateTime.of(2000, 1, 1, 0, 0).atZone(ZoneOffset.UTC);
052
053    private final String HISTORIC_TIMESTAMP = UTC_RFC_1123_FORMATTER.format(HISTORIC_DATETIME);
054
055    public VersioningIT() {
056        super();
057
058        client = FcrepoClient.client()
059                .credentials("fedoraAdmin", "fedoraAdmin")
060                .authScope("localhost")
061                .build();
062    }
063
064    @Test
065    public void testCreateMementoFromOriginal() throws Exception {
066        // Create original resource with custom property
067        final FcrepoResponse createOriginalResp = client.post(new URI(serverAddress))
068                .body(new ByteArrayInputStream(rdfTtl.getBytes()), "text/turtle")
069                .perform();
070
071        final URI timemapURI = createOriginalResp.getLinkHeaders(MEMENTO_TIME_MAP_REL).get(0);
072
073        final FcrepoResponse mementoResp = client.createMemento(timemapURI)
074                .perform();
075        assertEquals(CREATED.getStatusCode(), mementoResp.getStatusCode());
076
077        final URI mementoURI = mementoResp.getLocation();
078
079        final FcrepoResponse getResp = client.get(mementoURI).perform();
080        assertTrue("Retrieved object must be a memento", getResp.hasType(MEMENTO_TYPE));
081        final Model respModel = getResponseModel(getResp);
082        assertTrue(respModel.contains(null, DC_TITLE, "Test Object"));
083    }
084
085    @Test
086    public void testDatetimeNegotiation() throws Exception {
087        final FcrepoResponse createOriginalResp = client.post(new URI(serverAddress))
088                .perform();
089
090        final URI location = createOriginalResp.getLocation();
091        final URI timemapURI = createOriginalResp.getLinkHeaders(MEMENTO_TIME_MAP_REL).get(0);
092        // create version
093        client.createMemento(timemapURI).perform();
094
095        // Negotiate for the most recent memento
096        final FcrepoResponse negotiateResp = client.get(location)
097                .acceptDatetime(Instant.now())
098                .perform();
099
100        assertTrue(negotiateResp.hasType(MEMENTO_TYPE));
101    }
102
103    private InputStream modelToInputStream(final Model model) {
104        final ByteArrayOutputStream out = new ByteArrayOutputStream();
105        model.write(out, "text/turtle");
106        return new ByteArrayInputStream(out.toByteArray());
107    }
108}