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