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