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_TYPE;
022import static org.fcrepo.client.FedoraHeaderConstants.LOCATION;
023import static org.fcrepo.client.TestUtils.RDF_XML;
024import static org.fcrepo.client.TestUtils.SPARQL_UPDATE;
025import static org.fcrepo.client.TestUtils.TEXT_TURTLE;
026import static org.fcrepo.client.TestUtils.baseUrl;
027import static org.fcrepo.client.TestUtils.rdfXml;
028import static org.fcrepo.client.TestUtils.setField;
029import static org.fcrepo.client.TestUtils.sparqlUpdate;
030import static org.junit.Assert.assertEquals;
031import static org.mockito.Matchers.any;
032import static org.mockito.Mockito.when;
033
034import java.io.ByteArrayInputStream;
035import java.io.IOException;
036import java.io.InputStream;
037import java.net.URI;
038
039import org.apache.commons.io.IOUtils;
040import org.apache.http.Header;
041import org.apache.http.StatusLine;
042import org.apache.http.client.methods.CloseableHttpResponse;
043import org.apache.http.client.methods.HttpUriRequest;
044import org.apache.http.entity.ByteArrayEntity;
045import org.apache.http.impl.client.CloseableHttpClient;
046import org.apache.http.message.BasicHeader;
047import org.junit.Before;
048import org.junit.Test;
049import org.junit.runner.RunWith;
050import org.mockito.Mock;
051import org.mockito.runners.MockitoJUnitRunner;
052
053/**
054 * @author acoburn
055 */
056@RunWith(MockitoJUnitRunner.class)
057public class FcrepoClientErrorTest {
058
059    private FcrepoClient testClient;
060
061    @Mock
062    private CloseableHttpClient mockHttpclient;
063
064    @Mock
065    private StatusLine mockStatus;
066
067    @Mock
068    private CloseableHttpResponse mockResponse;
069
070    @Before
071    public void setUp() throws IOException {
072        testClient = FcrepoClient.client().build();
073        setField(testClient, "httpclient", mockHttpclient);
074    }
075
076    @Test
077    public void testGet() throws IOException, FcrepoOperationFailedException {
078        final int status = 100;
079        final URI uri = create(baseUrl);
080        final ByteArrayEntity entity = new ByteArrayEntity(rdfXml.getBytes());
081
082        entity.setContentType(RDF_XML);
083        doSetupMockRequest(RDF_XML, entity, status);
084
085        final FcrepoResponse response = testClient.get(uri).accept(RDF_XML).perform();
086
087        assertEquals(response.getUrl(), uri);
088        assertEquals(response.getStatusCode(), status);
089        assertEquals(response.getContentType(), RDF_XML);
090        assertEquals(response.getLocation(), null);
091        assertEquals(IOUtils.toString(response.getBody()), rdfXml);
092    }
093
094    @Test
095    public void testGetError() throws Exception {
096        final int status = 400;
097        final URI uri = create(baseUrl);
098        final ByteArrayEntity entity = new ByteArrayEntity(rdfXml.getBytes());
099
100        entity.setContentType(RDF_XML);
101        doSetupMockRequest(RDF_XML, entity, status);
102
103        final FcrepoResponse response = testClient.get(uri)
104                .accept(RDF_XML)
105                .preferRepresentation()
106                .perform();
107
108        assertEquals(response.getUrl(), uri);
109        assertEquals(response.getStatusCode(), status);
110        assertEquals(response.getContentType(), RDF_XML);
111        assertEquals(response.getLocation(), null);
112        assertEquals(IOUtils.toString(response.getBody()), rdfXml);
113    }
114
115    @Test
116    public void testHead() throws IOException, FcrepoOperationFailedException {
117        final int status = 100;
118        final URI uri = create(baseUrl);
119
120        doSetupMockRequest(TEXT_TURTLE, null, status);
121
122        final FcrepoResponse response = testClient.head(uri).perform();
123
124        assertEquals(response.getUrl(), uri);
125        assertEquals(response.getStatusCode(), status);
126        assertEquals(response.getContentType(), TEXT_TURTLE);
127        assertEquals(response.getLocation(), null);
128        assertEquals(response.getBody(), null);
129    }
130
131    @Test
132    public void testHeadError() throws IOException, FcrepoOperationFailedException {
133        final int status = 400;
134        final URI uri = create(baseUrl);
135
136        doSetupMockRequest(TEXT_TURTLE, null, status);
137
138        final FcrepoResponse response = testClient.head(uri).perform();
139
140        assertEquals(response.getUrl(), uri);
141        assertEquals(response.getStatusCode(), status);
142        assertEquals(response.getContentType(), TEXT_TURTLE);
143        assertEquals(response.getLocation(), null);
144        assertEquals(response.getBody(), null);
145    }
146
147    @Test
148    public void testPut() throws IOException, FcrepoOperationFailedException {
149        final int status = 100;
150        final URI uri = create(baseUrl);
151        final InputStream body = new ByteArrayInputStream(rdfXml.getBytes());
152
153        doSetupMockRequest(RDF_XML, null, status);
154
155        final FcrepoResponse response = testClient.put(uri)
156                .body(body, RDF_XML)
157                .perform();
158
159        assertEquals(response.getUrl(), uri);
160        assertEquals(response.getStatusCode(), status);
161        assertEquals(response.getContentType(), RDF_XML);
162        assertEquals(response.getLocation(), null);
163        assertEquals(response.getBody(), null);
164    }
165
166    @Test
167    public void testPutError() throws IOException, FcrepoOperationFailedException {
168        final int status = 500;
169        final URI uri = create(baseUrl);
170        final InputStream body = new ByteArrayInputStream(rdfXml.getBytes());
171
172        doSetupMockRequest(RDF_XML, null, status);
173
174        final FcrepoResponse response = testClient.put(uri)
175                .body(body, RDF_XML)
176                .perform();
177
178        assertEquals(response.getUrl(), uri);
179        assertEquals(response.getStatusCode(), status);
180        assertEquals(response.getContentType(), RDF_XML);
181        assertEquals(response.getLocation(), null);
182        assertEquals(response.getBody(), null);
183    }
184
185    @Test
186    public void testDelete() throws IOException, FcrepoOperationFailedException {
187        final int status = 100;
188        final URI uri = create(baseUrl);
189
190        doSetupMockRequest(null, null, status);
191
192        final FcrepoResponse response = testClient.delete(uri).perform();
193
194        assertEquals(response.getUrl(), uri);
195        assertEquals(response.getStatusCode(), status);
196        assertEquals(response.getContentType(), null);
197        assertEquals(response.getLocation(), null);
198        assertEquals(response.getBody(), null);
199    }
200
201    @Test
202    public void testDeleteError() throws IOException, FcrepoOperationFailedException {
203        final int status = 404;
204        final URI uri = create(baseUrl);
205
206        doSetupMockRequest(null, null, status);
207
208        final FcrepoResponse response = testClient.delete(uri).perform();
209
210        assertEquals(response.getUrl(), uri);
211        assertEquals(response.getStatusCode(), status);
212        assertEquals(response.getContentType(), null);
213        assertEquals(response.getLocation(), null);
214        assertEquals(response.getBody(), null);
215    }
216
217    @Test
218    public void testPatch() throws IOException, FcrepoOperationFailedException {
219        final int status = 100;
220        final URI uri = create(baseUrl);
221        final InputStream body = new ByteArrayInputStream(sparqlUpdate.getBytes());
222
223        doSetupMockRequest(SPARQL_UPDATE, null, status);
224
225        final FcrepoResponse response = testClient.patch(uri)
226                .body(body)
227                .perform();
228
229        assertEquals(response.getUrl(), uri);
230        assertEquals(response.getStatusCode(), status);
231        assertEquals(response.getContentType(), SPARQL_UPDATE);
232        assertEquals(response.getLocation(), null);
233        assertEquals(response.getBody(), null);
234    }
235
236    @Test
237    public void testPatchError() throws IOException, FcrepoOperationFailedException {
238        final int status = 401;
239        final URI uri = create(baseUrl);
240        final InputStream body = new ByteArrayInputStream(sparqlUpdate.getBytes());
241
242        doSetupMockRequest(SPARQL_UPDATE, null, status);
243
244        final FcrepoResponse response = testClient.patch(uri)
245                .body(body)
246                .perform();
247
248        assertEquals(response.getUrl(), uri);
249        assertEquals(response.getStatusCode(), status);
250        assertEquals(response.getContentType(), SPARQL_UPDATE);
251        assertEquals(response.getLocation(), null);
252        assertEquals(response.getBody(), null);
253    }
254
255    @Test
256    public void testPost() throws IOException, FcrepoOperationFailedException {
257        final int status = 100;
258        final URI uri = create(baseUrl);
259        final InputStream body = new ByteArrayInputStream(sparqlUpdate.getBytes());
260
261        doSetupMockRequest(SPARQL_UPDATE, null, status);
262
263        final FcrepoResponse response = testClient.post(uri)
264                .body(body, SPARQL_UPDATE)
265                .perform();
266
267        assertEquals(response.getUrl(), uri);
268        assertEquals(response.getStatusCode(), status);
269        assertEquals(response.getContentType(), SPARQL_UPDATE);
270        assertEquals(response.getLocation(), null);
271        assertEquals(response.getBody(), null);
272    }
273
274    @Test
275    public void testPostError() throws IOException, FcrepoOperationFailedException {
276        final int status = 404;
277        final URI uri = create(baseUrl);
278        final InputStream body = new ByteArrayInputStream(sparqlUpdate.getBytes());
279
280        doSetupMockRequest(SPARQL_UPDATE, null, status);
281
282        final FcrepoResponse response = testClient.post(uri)
283                .body(body, SPARQL_UPDATE)
284                .perform();
285
286        assertEquals(response.getUrl(), uri);
287        assertEquals(response.getStatusCode(), status);
288        assertEquals(response.getContentType(), SPARQL_UPDATE);
289        assertEquals(response.getLocation(), null);
290        assertEquals(response.getBody(), null);
291    }
292
293    @Test
294    public void testHeaders() throws IOException, FcrepoOperationFailedException {
295        final int status = 100;
296        final URI uri = create(baseUrl);
297        final Header locationHeader = new BasicHeader(LOCATION, null);
298        final Header contentTypeHeader = new BasicHeader("Content-Type", TEXT_TURTLE);
299        final Header linkHeader = new BasicHeader("Link", "<" + baseUrl + "/bar>; rel=\"describedby\"");
300        final Header linkFooHeader = new BasicHeader("Link" ,"<" + baseUrl + "/bar>; rel=\"foo\"");
301        final Header[] headers = new Header[]{ locationHeader, contentTypeHeader, linkHeader, linkFooHeader };
302
303        when(mockHttpclient.execute(any(HttpUriRequest.class))).thenReturn(mockResponse);
304        when(mockResponse.getAllHeaders()).thenReturn(headers);
305        when(mockResponse.getStatusLine()).thenReturn(mockStatus);
306        when(mockStatus.getStatusCode()).thenReturn(status);
307
308        final FcrepoResponse response = testClient.head(uri).perform();
309
310        assertEquals(response.getUrl(), uri);
311        assertEquals(response.getStatusCode(), status);
312        assertEquals(response.getContentType(), TEXT_TURTLE);
313        assertEquals(response.getLocation(), create(baseUrl + "/bar"));
314        assertEquals(response.getBody(), null);
315    }
316
317    @Test
318    public void testHeadersWithoutContentType() throws IOException, FcrepoOperationFailedException {
319        final int status = 100;
320        final URI uri = create(baseUrl);
321        final Header locationHeader = new BasicHeader(LOCATION, null);
322        final Header contentTypeHeader = new BasicHeader(CONTENT_TYPE, null);
323        final Header linkHeader = new BasicHeader("Link", "<" + baseUrl + "/bar>; rel=\"describedby\"");
324        final Header linkFooHeader = new BasicHeader("Link" ,"<" + baseUrl + "/bar>; rel=\"foo\"");
325        final Header[] headers = new Header[]{ locationHeader, contentTypeHeader, linkHeader, linkFooHeader };
326
327        when(mockHttpclient.execute(any(HttpUriRequest.class))).thenReturn(mockResponse);
328        when(mockResponse.getAllHeaders()).thenReturn(headers);
329        when(mockResponse.getStatusLine()).thenReturn(mockStatus);
330        when(mockStatus.getStatusCode()).thenReturn(status);
331
332        final FcrepoResponse response = testClient.head(uri).perform();
333
334        assertEquals(response.getUrl(), uri);
335        assertEquals(response.getStatusCode(), status);
336        assertEquals(response.getContentType(), null);
337        assertEquals(response.getLocation(), create(baseUrl + "/bar"));
338        assertEquals(response.getBody(), null);
339    }
340
341    private void doSetupMockRequest(final String contentType, final ByteArrayEntity entity, final int status)
342            throws IOException {
343
344        final Header contentTypeHeader = new BasicHeader(CONTENT_TYPE, contentType);
345        final Header locationHeader = new BasicHeader(LOCATION, null);
346        final Header[] responseHeaders = new Header[] { contentTypeHeader, locationHeader };
347
348        when(mockHttpclient.execute(any(HttpUriRequest.class))).thenReturn(mockResponse);
349        when(mockResponse.getEntity()).thenReturn(entity);
350        when(mockResponse.getStatusLine()).thenReturn(mockStatus);
351        when(mockStatus.getStatusCode()).thenReturn(status);
352        when(mockResponse.getAllHeaders()).thenReturn(responseHeaders);
353    }
354}