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;
019
020import static java.net.URI.create;
021import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_DISPOSITION;
022import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_TYPE;
023import static org.fcrepo.client.FedoraHeaderConstants.DIGEST;
024import static org.fcrepo.client.FedoraHeaderConstants.IF_MATCH;
025import static org.fcrepo.client.FedoraHeaderConstants.IF_UNMODIFIED_SINCE;
026import static org.fcrepo.client.FedoraHeaderConstants.PREFER;
027import static org.fcrepo.client.TestUtils.baseUrl;
028import static org.junit.Assert.assertEquals;
029import static org.junit.Assert.assertNull;
030import static org.mockito.Matchers.any;
031import static org.mockito.Matchers.eq;
032import static org.mockito.Mockito.mock;
033import static org.mockito.Mockito.verify;
034import static org.mockito.Mockito.when;
035
036import java.io.InputStream;
037import java.net.URI;
038
039import org.apache.http.HttpEntity;
040import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
041import org.apache.http.client.methods.HttpRequestBase;
042import org.junit.Before;
043import org.junit.Test;
044import org.junit.runner.RunWith;
045import org.mockito.ArgumentCaptor;
046import org.mockito.Mock;
047import org.mockito.runners.MockitoJUnitRunner;
048
049/**
050 * @author bbpennel
051 */
052@RunWith(MockitoJUnitRunner.class)
053public class PutBuilderTest {
054
055    @Mock
056    private FcrepoClient client;
057
058    @Mock
059    private FcrepoResponse fcrepoResponse;
060
061    private PutBuilder testBuilder;
062
063    private URI uri;
064
065    @Before
066    public void setUp() throws Exception {
067        when(client.executeRequest(any(URI.class), any(HttpRequestBase.class)))
068                .thenReturn(fcrepoResponse);
069
070        uri = create(baseUrl);
071        testBuilder = new PutBuilder(uri, client);
072    }
073
074    @Test
075    public void testPutNoBody() throws Exception {
076        testBuilder.perform();
077
078        final ArgumentCaptor<HttpRequestBase> requestCaptor = ArgumentCaptor.forClass(HttpRequestBase.class);
079        verify(client).executeRequest(eq(uri), requestCaptor.capture());
080
081        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
082        assertNull("Request body should not be set", request.getEntity());
083        assertEquals(0, request.getAllHeaders().length);
084    }
085
086    @Test
087    public void testWithBody() throws Exception {
088        final InputStream bodyStream = mock(InputStream.class);
089
090        testBuilder.body(bodyStream, "plain/text")
091                .digestSha1("checksum")
092                .filename("file.txt")
093                .perform();
094
095        final ArgumentCaptor<HttpRequestBase> requestCaptor = ArgumentCaptor.forClass(HttpRequestBase.class);
096        verify(client).executeRequest(eq(uri), requestCaptor.capture());
097
098        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
099        final HttpEntity bodyEntity = request.getEntity();
100        assertEquals(bodyStream, bodyEntity.getContent());
101
102        assertEquals("plain/text", request.getFirstHeader(CONTENT_TYPE).getValue());
103        assertEquals("sha1=checksum", request.getFirstHeader(DIGEST).getValue());
104        assertEquals("attachment; filename=\"file.txt\"", request.getFirstHeader(CONTENT_DISPOSITION).getValue());
105    }
106
107    @Test
108    public void testDisposition() throws Exception {
109        final InputStream bodyStream = mock(InputStream.class);
110        testBuilder.body(bodyStream, "plain/text").filename(null).perform();
111
112        final ArgumentCaptor<HttpRequestBase> requestCaptor = ArgumentCaptor.forClass(HttpRequestBase.class);
113        verify(client).executeRequest(eq(uri), requestCaptor.capture());
114
115        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
116        final HttpEntity bodyEntity = request.getEntity();
117        assertEquals(bodyStream, bodyEntity.getContent());
118        assertEquals("attachment", request.getFirstHeader(CONTENT_DISPOSITION).getValue());
119    }
120
121    @Test(expected = FcrepoOperationFailedException.class)
122    public void testPostClientError() throws Exception {
123        when(client.executeRequest(any(URI.class), any(HttpRequestBase.class)))
124                .thenThrow(new FcrepoOperationFailedException(uri, 415, "status"));
125
126        testBuilder.perform();
127    }
128
129    @Test
130    public void testWithModificationHeaders() throws Exception {
131        final InputStream bodyStream = mock(InputStream.class);
132
133        final String etag = "123456";
134        final String lastModified = "Mon, 19 May 2014 19:44:59 GMT";
135        testBuilder.body(bodyStream, "plain/text")
136                .ifMatch(etag)
137                .ifUnmodifiedSince(lastModified)
138                .perform();
139
140        final ArgumentCaptor<HttpRequestBase> requestCaptor = ArgumentCaptor.forClass(HttpRequestBase.class);
141        verify(client).executeRequest(eq(uri), requestCaptor.capture());
142
143        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
144        final HttpEntity bodyEntity = request.getEntity();
145        assertEquals(bodyStream, bodyEntity.getContent());
146
147        assertEquals("plain/text", request.getFirstHeader(CONTENT_TYPE).getValue());
148        assertEquals(etag, request.getFirstHeader(IF_MATCH).getValue());
149        assertEquals(lastModified, request.getFirstHeader(IF_UNMODIFIED_SINCE).getValue());
150    }
151
152    @Test
153    public void testPreferLenient() throws Exception {
154        testBuilder.preferLenient().perform();
155
156        final ArgumentCaptor<HttpRequestBase> requestCaptor = ArgumentCaptor.forClass(HttpRequestBase.class);
157        verify(client).executeRequest(eq(uri), requestCaptor.capture());
158
159        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
160        assertEquals("handling=lenient; received=\"minimal\"", request.getFirstHeader(PREFER).getValue());
161    }
162}