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