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.client;
007
008import static java.net.URI.create;
009import static org.fcrepo.client.ExternalContentHandling.PROXY;
010import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_DISPOSITION;
011import static org.fcrepo.client.FedoraHeaderConstants.CONTENT_TYPE;
012import static org.fcrepo.client.FedoraHeaderConstants.DIGEST;
013import static org.fcrepo.client.FedoraHeaderConstants.IF_MATCH;
014import static org.fcrepo.client.FedoraHeaderConstants.IF_STATE_TOKEN;
015import static org.fcrepo.client.FedoraHeaderConstants.IF_UNMODIFIED_SINCE;
016import static org.fcrepo.client.FedoraHeaderConstants.LINK;
017import static org.fcrepo.client.FedoraHeaderConstants.PREFER;
018import static org.fcrepo.client.FedoraTypes.LDP_DIRECT_CONTAINER;
019import static org.fcrepo.client.LinkHeaderConstants.ACL_REL;
020import static org.fcrepo.client.LinkHeaderConstants.EXTERNAL_CONTENT_HANDLING;
021import static org.fcrepo.client.LinkHeaderConstants.EXTERNAL_CONTENT_REL;
022import static org.fcrepo.client.LinkHeaderConstants.TYPE_REL;
023import static org.fcrepo.client.TestUtils.baseUrl;
024import static org.junit.Assert.assertEquals;
025import static org.junit.Assert.assertNull;
026import static org.mockito.ArgumentMatchers.any;
027import static org.mockito.ArgumentMatchers.eq;
028import static org.mockito.Mockito.mock;
029import static org.mockito.Mockito.verify;
030import static org.mockito.Mockito.when;
031
032import java.io.InputStream;
033import java.net.URI;
034
035import org.apache.http.HttpEntity;
036import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
037import org.apache.http.client.methods.HttpRequestBase;
038import org.junit.Before;
039import org.junit.Test;
040import org.junit.runner.RunWith;
041import org.mockito.ArgumentCaptor;
042import org.mockito.Captor;
043import org.mockito.Mock;
044import org.mockito.junit.MockitoJUnitRunner;
045
046/**
047 * @author bbpennel
048 */
049@RunWith(MockitoJUnitRunner.class)
050public class PutBuilderTest {
051
052    @Mock
053    private FcrepoClient client;
054
055    @Mock
056    private FcrepoResponse fcrepoResponse;
057
058    @Captor
059    private ArgumentCaptor<HttpRequestBase> requestCaptor;
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        verify(client).executeRequest(eq(uri), requestCaptor.capture());
079
080        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
081        assertNull("Request body should not be set", request.getEntity());
082        assertEquals(0, request.getAllHeaders().length);
083    }
084
085    @Test
086    public void testWithBody() throws Exception {
087        final InputStream bodyStream = mock(InputStream.class);
088
089        testBuilder.body(bodyStream, "plain/text")
090                .digestSha1("checksum")
091                .filename("file.txt")
092                .perform();
093
094        verify(client).executeRequest(eq(uri), requestCaptor.capture());
095
096        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
097        final HttpEntity bodyEntity = request.getEntity();
098        assertEquals(bodyStream, bodyEntity.getContent());
099
100        assertEquals("plain/text", request.getFirstHeader(CONTENT_TYPE).getValue());
101        assertEquals("sha=checksum", request.getFirstHeader(DIGEST).getValue());
102        assertEquals("attachment; filename=\"file.txt\"", request.getFirstHeader(CONTENT_DISPOSITION).getValue());
103    }
104
105    @Test
106    public void testExternalContent() throws Exception {
107        final URI contentURI = URI.create("file:///path/to/file");
108        testBuilder.externalContent(contentURI, "plain/text", PROXY)
109                .perform();
110
111        verify(client).executeRequest(eq(uri), requestCaptor.capture());
112
113        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
114
115        final FcrepoLink extLink = new FcrepoLink(request.getFirstHeader(LINK).getValue());
116        assertEquals(EXTERNAL_CONTENT_REL, extLink.getRel());
117        assertEquals(PROXY, extLink.getParams().get(EXTERNAL_CONTENT_HANDLING));
118        assertEquals("plain/text", extLink.getType());
119    }
120
121    @Test
122    public void testDisposition() throws Exception {
123        final InputStream bodyStream = mock(InputStream.class);
124        testBuilder.body(bodyStream, "plain/text").filename(null).perform();
125
126        verify(client).executeRequest(eq(uri), requestCaptor.capture());
127
128        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
129        final HttpEntity bodyEntity = request.getEntity();
130        assertEquals(bodyStream, bodyEntity.getContent());
131        assertEquals("attachment", request.getFirstHeader(CONTENT_DISPOSITION).getValue());
132    }
133
134    @Test(expected = FcrepoOperationFailedException.class)
135    public void testPostClientError() throws Exception {
136        when(client.executeRequest(any(URI.class), any(HttpRequestBase.class)))
137                .thenThrow(new FcrepoOperationFailedException(uri, 415, "status"));
138
139        testBuilder.perform();
140    }
141
142    @Test
143    public void testWithModificationHeaders() throws Exception {
144        final InputStream bodyStream = mock(InputStream.class);
145
146        final String etag = "123456";
147        final String lastModified = "Mon, 19 May 2014 19:44:59 GMT";
148        testBuilder.body(bodyStream, "plain/text")
149                .ifMatch(etag)
150                .ifUnmodifiedSince(lastModified)
151                .perform();
152
153        verify(client).executeRequest(eq(uri), requestCaptor.capture());
154
155        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
156        final HttpEntity bodyEntity = request.getEntity();
157        assertEquals(bodyStream, bodyEntity.getContent());
158
159        assertEquals("plain/text", request.getFirstHeader(CONTENT_TYPE).getValue());
160        assertEquals(etag, request.getFirstHeader(IF_MATCH).getValue());
161        assertEquals(lastModified, request.getFirstHeader(IF_UNMODIFIED_SINCE).getValue());
162    }
163
164    @Test
165    public void testPreferLenient() throws Exception {
166        testBuilder.preferLenient().perform();
167
168        verify(client).executeRequest(eq(uri), requestCaptor.capture());
169
170        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
171        assertEquals("handling=lenient; received=\"minimal\"", request.getFirstHeader(PREFER).getValue());
172    }
173
174    @Test
175    public void testAddInteractionModel() throws Exception {
176        testBuilder.addInteractionModel(LDP_DIRECT_CONTAINER)
177                .perform();
178
179        verify(client).executeRequest(eq(uri), requestCaptor.capture());
180
181        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
182
183        final FcrepoLink interLink = new FcrepoLink(request.getFirstHeader(LINK).getValue());
184        assertEquals(TYPE_REL, interLink.getRel());
185        assertEquals(LDP_DIRECT_CONTAINER, interLink.getUri().toString());
186    }
187
188    @Test
189    public void testLinkAcl() throws Exception {
190        testBuilder.linkAcl("http://localhost/acl")
191                .perform();
192
193        verify(client).executeRequest(eq(uri), requestCaptor.capture());
194
195        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
196
197        final FcrepoLink aclLink = new FcrepoLink(request.getFirstHeader(LINK).getValue());
198        assertEquals(ACL_REL, aclLink.getRel());
199        assertEquals("http://localhost/acl", aclLink.getUri().toString());
200    }
201
202    @Test
203    public void testStateToken() throws Exception {
204        final InputStream bodyStream = mock(InputStream.class);
205        final String token = "state";
206
207        testBuilder.body(bodyStream)
208                .ifStateToken(token)
209                .perform();
210
211        verify(client).executeRequest(eq(uri), requestCaptor.capture());
212
213        final HttpEntityEnclosingRequestBase request = (HttpEntityEnclosingRequestBase) requestCaptor.getValue();
214        assertEquals(token, request.getFirstHeader(IF_STATE_TOKEN).getValue());
215    }
216
217    @Test
218    public void testAddHeader() throws Exception {
219        testBuilder.addHeader("my-header", "head-val").perform();
220
221        verify(client).executeRequest(eq(uri), requestCaptor.capture());
222        final HttpRequestBase request = requestCaptor.getValue();
223        assertEquals("head-val", request.getFirstHeader("my-header").getValue());
224    }
225
226    @Test
227    public void testAddLinkHeader() throws Exception {
228        final FcrepoLink link = FcrepoLink.fromUri("http://example.com/link").type("foo").build();
229        testBuilder.addLinkHeader(link).perform();
230
231        verify(client).executeRequest(eq(uri), requestCaptor.capture());
232        final HttpRequestBase request = requestCaptor.getValue();
233        assertEquals(link.toString(), request.getFirstHeader(LINK).getValue());
234    }
235}