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.ExternalContentHandling.PROXY;
022import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_DISPOSITION;
023import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_TYPE;
024import static org.fcrepo.client.FedoraHeaderConstants.DIGEST;
025import static org.fcrepo.client.FedoraHeaderConstants.LINK;
026import static org.fcrepo.client.FedoraHeaderConstants.SLUG;
027import static org.fcrepo.client.FedoraTypes.LDP_DIRECT_CONTAINER;
028import static org.fcrepo.client.LinkHeaderConstants.ACL_REL;
029import static org.fcrepo.client.LinkHeaderConstants.EXTERNAL_CONTENT_HANDLING;
030import static org.fcrepo.client.LinkHeaderConstants.EXTERNAL_CONTENT_REL;
031import static org.fcrepo.client.LinkHeaderConstants.TYPE_REL;
032import static org.fcrepo.client.TestUtils.baseUrl;
033import static org.junit.Assert.assertEquals;
034import static org.junit.Assert.assertNull;
035import static org.mockito.ArgumentMatchers.any;
036import static org.mockito.ArgumentMatchers.eq;
037import static org.mockito.Mockito.mock;
038import static org.mockito.Mockito.verify;
039import static org.mockito.Mockito.when;
040
041import java.io.InputStream;
042import java.net.URI;
043
044import org.apache.http.HttpEntity;
045import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
046import org.apache.http.client.methods.HttpRequestBase;
047import org.junit.Before;
048import org.junit.Test;
049import org.junit.runner.RunWith;
050import org.mockito.ArgumentCaptor;
051import org.mockito.Captor;
052import org.mockito.Mock;
053import org.mockito.junit.MockitoJUnitRunner;
054
055/**
056 * @author bbpennel
057 */
058@RunWith(MockitoJUnitRunner.class)
059public class PostBuilderTest {
060
061    @Mock
062    private FcrepoClient client;
063
064    @Mock
065    private FcrepoResponse fcrepoResponse;
066
067    @Captor
068    private ArgumentCaptor<HttpRequestBase> requestCaptor;
069
070    private PostBuilder testBuilder;
071
072    private URI uri;
073
074    @Before
075    public void setUp() throws Exception {
076        when(client.executeRequest(any(URI.class), any(HttpRequestBase.class)))
077                .thenReturn(fcrepoResponse);
078
079        uri = create(baseUrl);
080        testBuilder = new PostBuilder(uri, client);
081    }
082
083    @Test
084    public void testPostNoBody() throws Exception {
085        testBuilder.perform();
086
087        verify(client).executeRequest(eq(uri), requestCaptor.capture());
088
089        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
090        assertNull("Request body should not be set", request.getEntity());
091        assertEquals(0, request.getAllHeaders().length);
092    }
093
094    @Test
095    public void testWithBody() throws Exception {
096        final InputStream bodyStream = mock(InputStream.class);
097
098        testBuilder.body(bodyStream, "plain/text")
099                .digestSha1("checksum")
100                .filename("file.txt")
101                .slug("slug_value")
102                .perform();
103
104        verify(client).executeRequest(eq(uri), requestCaptor.capture());
105
106        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
107        final HttpEntity bodyEntity = request.getEntity();
108        assertEquals(bodyStream, bodyEntity.getContent());
109
110        assertEquals("plain/text", request.getFirstHeader(CONTENT_TYPE).getValue());
111        assertEquals("sha=checksum", request.getFirstHeader(DIGEST).getValue());
112        assertEquals("slug_value", request.getFirstHeader(SLUG).getValue());
113        assertEquals("attachment; filename=\"file.txt\"", request.getFirstHeader(CONTENT_DISPOSITION).getValue());
114    }
115
116    @Test
117    public void testAttachment() throws Exception {
118        final InputStream bodyStream = mock(InputStream.class);
119        testBuilder.body(bodyStream, "plain/text").filename(null).perform();
120
121        verify(client).executeRequest(eq(uri), requestCaptor.capture());
122
123        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
124        final HttpEntity bodyEntity = request.getEntity();
125        assertEquals(bodyStream, bodyEntity.getContent());
126        assertEquals("attachment", request.getFirstHeader(CONTENT_DISPOSITION).getValue());
127    }
128
129    @Test
130    public void testWithBodyMultipleChecksums() throws Exception {
131        final InputStream bodyStream = mock(InputStream.class);
132
133        testBuilder.body(bodyStream, "plain/text")
134                .digestSha1("checksum")
135                .digestSha256("checksum256")
136                .perform();
137
138        verify(client).executeRequest(eq(uri), requestCaptor.capture());
139
140        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
141        final HttpEntity bodyEntity = request.getEntity();
142        assertEquals(bodyStream, bodyEntity.getContent());
143
144        assertEquals("plain/text", request.getFirstHeader(CONTENT_TYPE).getValue());
145        assertEquals("sha=checksum, sha256=checksum256", request.getFirstHeader(DIGEST).getValue());
146    }
147
148    @Test
149    public void testBodyNoType() throws Exception {
150        final InputStream bodyStream = mock(InputStream.class);
151
152        testBuilder.body(bodyStream).perform();
153
154        verify(client).executeRequest(eq(uri), requestCaptor.capture());
155
156        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
157        final HttpEntity bodyEntity = request.getEntity();
158        assertEquals(bodyStream, bodyEntity.getContent());
159        assertEquals("application/octet-stream", request.getFirstHeader(CONTENT_TYPE).getValue());
160    }
161
162    @Test(expected = FcrepoOperationFailedException.class)
163    public void testPostClientError() throws Exception {
164        when(client.executeRequest(any(URI.class), any(HttpRequestBase.class)))
165                .thenThrow(new FcrepoOperationFailedException(uri, 415, "status"));
166
167        testBuilder.perform();
168    }
169
170    @Test
171    public void testExternalContent() throws Exception {
172        final URI contentURI = URI.create("file:///path/to/file");
173        testBuilder.externalContent(contentURI, "plain/text", PROXY)
174                .perform();
175
176        verify(client).executeRequest(eq(uri), requestCaptor.capture());
177
178        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
179
180        final FcrepoLink extLink = new FcrepoLink(request.getFirstHeader(LINK).getValue());
181        assertEquals(EXTERNAL_CONTENT_REL, extLink.getRel());
182        assertEquals(PROXY, extLink.getParams().get(EXTERNAL_CONTENT_HANDLING));
183        assertEquals("plain/text", extLink.getType());
184    }
185
186    @Test
187    public void testExternalContentNoType() throws Exception {
188        final URI contentURI = URI.create("file:///path/to/file");
189        testBuilder.externalContent(contentURI, null, PROXY)
190                .perform();
191
192        verify(client).executeRequest(eq(uri), requestCaptor.capture());
193
194        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
195
196        final FcrepoLink extLink = new FcrepoLink(request.getFirstHeader(LINK).getValue());
197        assertEquals(EXTERNAL_CONTENT_REL, extLink.getRel());
198        assertEquals(PROXY, extLink.getParams().get(EXTERNAL_CONTENT_HANDLING));
199        assertNull(extLink.getType());
200    }
201
202    @Test
203    public void testAddInteractionModel() throws Exception {
204        testBuilder.addInteractionModel(LDP_DIRECT_CONTAINER)
205                .perform();
206
207        verify(client).executeRequest(eq(uri), requestCaptor.capture());
208
209        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
210
211        final FcrepoLink interLink = new FcrepoLink(request.getFirstHeader(LINK).getValue());
212        assertEquals(TYPE_REL, interLink.getRel());
213        assertEquals(LDP_DIRECT_CONTAINER, interLink.getUri().toString());
214    }
215
216    @Test
217    public void testLinkAcl() throws Exception {
218        testBuilder.linkAcl("http://localhost/acl")
219                .perform();
220
221        verify(client).executeRequest(eq(uri), requestCaptor.capture());
222
223        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
224
225        final FcrepoLink aclLink = new FcrepoLink(request.getFirstHeader(LINK).getValue());
226        assertEquals(ACL_REL, aclLink.getRel());
227        assertEquals("http://localhost/acl", aclLink.getUri().toString());
228    }
229
230    @Test
231    public void testAddHeader() throws Exception {
232        testBuilder.addHeader("my-header", "head-val").perform();
233
234        verify(client).executeRequest(eq(uri), requestCaptor.capture());
235        final HttpRequestBase request = requestCaptor.getValue();
236        assertEquals("head-val", request.getFirstHeader("my-header").getValue());
237    }
238
239    @Test
240    public void testAddLinkHeader() throws Exception {
241        final FcrepoLink link = FcrepoLink.fromUri("http://example.com/link").type("foo").build();
242        testBuilder.addLinkHeader(link).perform();
243
244        verify(client).executeRequest(eq(uri), requestCaptor.capture());
245        final HttpRequestBase request = requestCaptor.getValue();
246        assertEquals(link.toString(), request.getFirstHeader(LINK).getValue());
247    }
248}