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.utils; 017 018import static org.mockito.Matchers.any; 019import static org.mockito.Matchers.eq; 020import static org.mockito.MockitoAnnotations.initMocks; 021import static org.mockito.Mockito.mock; 022import static org.mockito.Mockito.verify; 023import static org.mockito.Mockito.when; 024 025import java.io.ByteArrayInputStream; 026import java.io.IOException; 027import java.io.InputStream; 028import java.util.ArrayList; 029import java.util.HashMap; 030import java.util.List; 031import java.util.Map; 032 033import org.apache.commons.io.IOUtils; 034 035import org.apache.http.Header; 036import org.apache.http.HttpResponse; 037import org.apache.http.StatusLine; 038import org.apache.http.client.HttpClient; 039import org.apache.http.client.methods.HttpGet; 040import org.apache.http.client.methods.HttpHead; 041import org.apache.http.client.methods.HttpPatch; 042import org.apache.http.client.methods.HttpPost; 043import org.apache.http.client.methods.HttpPut; 044import org.apache.http.entity.ByteArrayEntity; 045import org.apache.http.message.BasicHeader; 046 047import org.fcrepo.client.BadRequestException; 048import org.fcrepo.client.FedoraContent; 049import org.fcrepo.client.FedoraException; 050import org.fcrepo.client.FedoraRepository; 051import org.fcrepo.client.ForbiddenException; 052import org.fcrepo.client.NotFoundException; 053import org.fcrepo.client.ReadOnlyException; 054import org.fcrepo.client.impl.FedoraResourceImpl; 055import org.junit.Before; 056import org.junit.Test; 057import org.mockito.Mock; 058 059 060import static org.junit.Assert.assertTrue; 061import static org.junit.Assert.assertEquals; 062 063/** 064 * HttpHelper test 065 * @author escowles 066 * @since 2014-09-04 067 */ 068public class HttpHelperTest { 069 070 @Mock 071 private HttpClient mockClient; 072 073 private HttpHelper helper; 074 private HttpHelper readOnlyHelper; 075 private Map<String, List<String>> params; 076 077 private String repoURL = "http://localhost:8080/rest"; 078 private String etag = "dummyEtag"; 079 080 @Before 081 public void setUp() throws IOException { 082 initMocks(this); 083 helper = new HttpHelper(repoURL, mockClient, false); 084 readOnlyHelper = new HttpHelper(repoURL, mockClient, true); 085 086 final List<String> values = new ArrayList<>(); 087 values.add("bar"); 088 values.add("baz"); 089 params = new HashMap<>(); 090 params.put("foo", values); 091 } 092 093 @Test 094 public void testExecuteGet() throws Exception { 095 final HttpGet get = new HttpGet(repoURL); 096 helper.execute(get); 097 verify(mockClient).execute(eq(get)); 098 } 099 100 @Test 101 public void testExecutePut() throws Exception { 102 final HttpPut put = new HttpPut(repoURL); 103 helper.execute(put); 104 verify(mockClient).execute(eq(put)); 105 } 106 107 @Test 108 public void testExecuteReadOnlyGet() throws Exception { 109 final HttpGet get = new HttpGet(repoURL); 110 readOnlyHelper.execute(get); 111 verify(mockClient).execute(eq(get)); 112 } 113 114 @Test (expected = ReadOnlyException.class) 115 public void testExecuteReadOnlyPut() throws Exception { 116 final HttpPut put = new HttpPut(repoURL); 117 readOnlyHelper.execute(put); 118 } 119 120 @Test 121 public void testCreateHeadMethod() { 122 final HttpHead head = helper.createHeadMethod("/foo"); 123 assertEquals( repoURL + "/foo", head.getURI().toString() ); 124 } 125 126 @Test 127 public void testCreateGetMethod() { 128 final HttpGet get = helper.createGetMethod("/foo", params); 129 assertEquals( repoURL + "/foo?foo=bar&foo=baz", get.getURI().toString() ); 130 } 131 132 @Test 133 public void testCreatePatchMethod() throws Exception { 134 final String sparql = "test sparql command"; 135 final HttpPatch patch = helper.createPatchMethod("/foo", sparql); 136 assertEquals( repoURL + "/foo", patch.getURI().toString() ); 137 assertEquals( "application/sparql-update", patch.getFirstHeader("Content-Type").getValue()); 138 assertEquals( sparql, IOUtils.toString(patch.getEntity().getContent()) ); 139 } 140 141 @Test (expected = FedoraException.class) 142 public void testCreatePatchMethodEmpty() throws Exception { 143 helper.createPatchMethod("/foo", ""); 144 } 145 146 @Test 147 public void testCreatePostMethod() { 148 final HttpPost post = helper.createPostMethod("/foo", params); 149 assertEquals( repoURL + "/foo?foo=bar&foo=baz", post.getURI().toString() ); 150 } 151 152 @Test 153 public void testCreatePutMethod() { 154 final HttpPut put = helper.createPutMethod("/foo", params); 155 assertEquals( repoURL + "/foo?foo=bar&foo=baz", put.getURI().toString() ); 156 } 157 158 @Test 159 public void testCreateContentPutMethod() throws Exception { 160 final String dummyContent = "dummy content"; 161 final InputStream in = new ByteArrayInputStream( dummyContent.getBytes() ); 162 final String mimeType = "text/plain"; 163 final String filename = "dummy.txt"; 164 final FedoraContent content = new FedoraContent().setContent(in).setContentType(mimeType) 165 .setFilename(filename); 166 167 final HttpPut put = helper.createContentPutMethod("/foo", params, content); 168 assertEquals( repoURL + "/foo?foo=bar&foo=baz", put.getURI().toString() ); 169 assertEquals( mimeType, put.getFirstHeader("Content-Type").getValue()); 170 assertEquals( dummyContent, IOUtils.toString(put.getEntity().getContent()) ); 171 assertEquals( "attachment; filename=\"" + filename + "\"", 172 put.getFirstHeader("Content-Disposition").getValue().toString()); 173 } 174 175 @Test 176 public void testCreateTriplesPutMethod() throws Exception { 177 final String dummyContent = "dummy content"; 178 final InputStream in = new ByteArrayInputStream( dummyContent.getBytes() ); 179 final String mimeType = "text/rdf+n3"; 180 181 final HttpPut put = helper.createTriplesPutMethod("/foo", in, mimeType); 182 assertEquals( repoURL + "/foo", put.getURI().toString() ); 183 assertEquals( mimeType, put.getFirstHeader("Content-Type").getValue()); 184 assertEquals( dummyContent, IOUtils.toString(put.getEntity().getContent()) ); 185 } 186 187 @Test (expected = FedoraException.class) 188 public void testCreateTriplesPutMethodWithoutContent() throws Exception { 189 final String mimeType = "text/rdf+n3"; 190 helper.createTriplesPutMethod("/foo", null, mimeType); 191 } 192 193 @Test (expected = FedoraException.class) 194 public void testCreateTriplesPutMethodWithoutType() throws Exception { 195 final String dummyContent = "dummy content"; 196 final InputStream in = new ByteArrayInputStream( dummyContent.getBytes() ); 197 helper.createTriplesPutMethod("/foo", in, ""); 198 } 199 200 @Test 201 public void testLoadProperties() throws Exception { 202 final FedoraResourceImpl testResource = testLoadPropertiesWithStatus(200); 203 assertEquals(etag, testResource.getEtagValue() ); 204 assertTrue(testResource.getMixins().contains("fedora:resource") ); 205 } 206 207 @Test (expected = ForbiddenException.class) 208 public void testLoadPropertiesForbidden() throws Exception { 209 testLoadPropertiesWithStatus(403); 210 } 211 212 @Test (expected = BadRequestException.class) 213 public void testLoadPropertiesBadRequest() throws Exception { 214 testLoadPropertiesWithStatus(400); 215 } 216 217 @Test (expected = NotFoundException.class) 218 public void testLoadPropertiesNotFound() throws Exception { 219 testLoadPropertiesWithStatus(404); 220 } 221 222 private FedoraResourceImpl testLoadPropertiesWithStatus( final int statusCode ) throws Exception { 223 final String triples = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + 224 "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">" + 225 "<rdf:Description rdf:about=\"http://localhost:8080/rest/foo\">" + 226 "<mixinTypes xmlns=\"http://fedora.info/definitions/v4/repository#\" " + 227 "rdf:datatype=\"http://www.w3.org/2001/XMLSchema#string\">fedora:resource</mixinTypes>" + 228 "</rdf:Description>" + 229 "</rdf:RDF>"; 230 final FedoraRepository mockRepo = mock(FedoraRepository.class); 231 when(mockRepo.getRepositoryUrl()).thenReturn(repoURL); 232 final FedoraResourceImpl origResource = new FedoraResourceImpl(mockRepo, helper, "/foo"); 233 final HttpResponse mockResponse = mock(HttpResponse.class); 234 final ByteArrayEntity entity = new ByteArrayEntity(triples.getBytes()); 235 entity.setContentType("application/rdf+xml"); 236 final Header etagHeader = new BasicHeader("Etag", etag); 237 final Header[] etagHeaders = new Header[]{ etagHeader }; 238 final StatusLine mockStatus = mock(StatusLine.class); 239 240 when(mockClient.execute(any(HttpGet.class))).thenReturn(mockResponse); 241 when(mockResponse.getEntity()).thenReturn(entity); 242 when(mockResponse.getHeaders("ETag")).thenReturn(etagHeaders); 243 when(mockResponse.getStatusLine()).thenReturn(mockStatus); 244 when(mockStatus.getStatusCode()).thenReturn(statusCode); 245 246 return helper.loadProperties( origResource ); 247 } 248 249}