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.impl; 017 018import static com.hp.hpl.jena.graph.NodeFactory.createLiteral; 019import static com.hp.hpl.jena.graph.NodeFactory.createURI; 020import static org.apache.http.HttpStatus.SC_CREATED; 021import static org.apache.http.HttpStatus.SC_NOT_FOUND; 022import static org.apache.http.HttpStatus.SC_OK; 023import static org.fcrepo.kernel.api.RdfLexicon.HAS_PRIMARY_IDENTIFIER; 024import static org.junit.Assert.assertEquals; 025import static org.junit.Assert.assertFalse; 026import static org.junit.Assert.assertNotNull; 027import static org.junit.Assert.assertTrue; 028import static org.mockito.Matchers.any; 029import static org.mockito.Matchers.anyString; 030import static org.mockito.Matchers.eq; 031import static org.mockito.Mockito.doReturn; 032import static org.mockito.Mockito.doThrow; 033import static org.mockito.Mockito.mock; 034import static org.mockito.Mockito.spy; 035import static org.mockito.Mockito.when; 036import static org.mockito.MockitoAnnotations.initMocks; 037 038import java.io.ByteArrayInputStream; 039import java.io.IOException; 040import java.io.InputStream; 041import java.net.URI; 042 043import org.fcrepo.client.NotFoundException; 044 045import com.hp.hpl.jena.graph.Graph; 046import org.apache.http.Header; 047import org.apache.http.HttpEntity; 048import org.apache.http.HttpResponse; 049import org.apache.http.StatusLine; 050import org.apache.http.client.HttpClient; 051import org.apache.http.client.methods.HttpUriRequest; 052import org.apache.http.client.methods.HttpPut; 053import org.fcrepo.client.FedoraContent; 054import org.fcrepo.client.FedoraException; 055import org.fcrepo.client.FedoraObject; 056import org.fcrepo.client.utils.HttpHelper; 057import org.junit.Before; 058import org.junit.Test; 059import org.mockito.Mock; 060 061/** 062 * Writable repository impl -- read and write operations should both work. 063 * 064 * @author lsitu 065 * @author escowles 066 * 067 */ 068public class FedoraRepositoryImplTest { 069 070 FedoraRepositoryImpl fedoraRepository; 071 HttpHelper httpHelper; 072 073 @Mock 074 HttpClient mockClient; 075 076 @Mock 077 private HttpResponse mockResponse; 078 079 @Mock 080 private HttpEntity mockEntity; 081 082 @Mock 083 private StatusLine mockStatusLine; 084 085 @Mock 086 private FedoraObjectImpl mockObject; 087 088 String testRepositoryUrl = "http://localhost:8080/rest"; 089 090 private final String testContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + 091 "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"" + 092 " xmlns:fcrepo=\"http://fedora.info/definitions/v4/repository#\">" + 093 "<rdf:Description rdf:about=\"http://localhost:8080/rest/testObject\">" + 094 "<rdf:type rdf:resource=\"http://fedora.info/definitions/v4/rest-api#resource\"/>" + 095 "<rdf:type rdf:resource=\"http://fedora.info/definitions/v4/rest-api#object\"/>" + 096 "<fcrepo:uuid>2fb9c440-db63-434f-929b-0ff29253205c</fcrepo:uuid>" + 097 "</rdf:Description>" + 098 "</rdf:RDF>"; 099 100 101 @Before 102 public void setUp() throws IOException { 103 initMocks(this); 104 fedoraRepository = new FedoraRepositoryImpl (testRepositoryUrl, mockClient); 105 httpHelper = new HttpHelper( testRepositoryUrl, mockClient, false ); 106 } 107 108 @Test 109 public void testGetObject() throws IOException, FedoraException { 110 final String testId = "testGetObject"; 111 when(mockClient.execute(any(HttpUriRequest.class))).thenReturn(mockResponse); 112 when(mockResponse.getEntity()).thenReturn(mockEntity); 113 final Header mockContentType = mock(Header.class); 114 when(mockEntity.getContentType()).thenReturn(mockContentType); 115 when(mockContentType.getValue()).thenReturn("application/rdf+xml"); 116 when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); 117 when(mockStatusLine.getStatusCode()).thenReturn(SC_OK); 118 try ( 119 InputStream rdf = 120 new ByteArrayInputStream(testContent.getBytes())) { 121 when(mockEntity.getContent()).thenReturn(rdf); 122 } 123 final FedoraObject testObject = fedoraRepository.getObject(testId); 124 assertNotNull(testObject); 125 assertTrue(testObject.getProperties().hasNext()); 126 } 127 128 @Test 129 public void testGetRepositoryUrl() { 130 assertEquals ("Resitory URL is not the same", testRepositoryUrl, fedoraRepository.getRepositoryUrl()); 131 } 132 133 @Test 134 public void testExists() throws IOException, FedoraException { 135 final String testId = "testGetObject"; 136 when(mockClient.execute(any(HttpUriRequest.class))).thenReturn(mockResponse); 137 when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); 138 when(mockStatusLine.getStatusCode()).thenReturn(SC_OK); 139 assertTrue(fedoraRepository.exists(testId)); 140 } 141 142 @Test 143 public void testExistsNonExistent() throws IOException, FedoraException { 144 final String testId = "testNonExistent"; 145 when(mockClient.execute(any(HttpUriRequest.class))).thenReturn(mockResponse); 146 when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); 147 when(mockStatusLine.getStatusCode()).thenReturn(SC_NOT_FOUND); 148 assertFalse(fedoraRepository.exists(testId)); 149 } 150 151 @Test 152 public void testCreateObject() throws IOException, FedoraException { 153 final String testId = "testNewObject"; 154 final HttpResponse mockResponse2 = mock(HttpResponse.class); 155 final StatusLine mockStatusLine2 = mock(StatusLine.class); 156 157 when(mockClient.execute(any(HttpUriRequest.class))).thenReturn(mockResponse2,mockResponse); 158 159 // put 160 when(mockResponse2.getStatusLine()).thenReturn(mockStatusLine2); 161 when(mockStatusLine2.getStatusCode()).thenReturn(SC_CREATED); 162 when(mockStatusLine2.getReasonPhrase()).thenReturn("Created"); 163 164 // get 165 when(mockResponse.getEntity()).thenReturn(mockEntity); 166 final Header mockContentType = mock(Header.class); 167 when(mockEntity.getContentType()).thenReturn(mockContentType); 168 when(mockContentType.getValue()).thenReturn("application/rdf+xml"); 169 when(mockResponse.getStatusLine()).thenReturn(mockStatusLine); 170 when(mockStatusLine.getStatusCode()).thenReturn(SC_OK); 171 when(mockStatusLine.getReasonPhrase()).thenReturn("OK"); 172 try ( 173 InputStream rdf = 174 new ByteArrayInputStream(testContent.getBytes())) { 175 when(mockEntity.getContent()).thenReturn(rdf); 176 } 177 178 final FedoraObject testObject = fedoraRepository.createObject(testId); 179 assertNotNull(testObject); 180 assertTrue(testObject.getProperties().hasNext()); 181 } 182 183 @Test 184 public void testFindOrCreateObject() throws FedoraException { 185 final FedoraRepositoryImpl spy = spy( new FedoraRepositoryImpl(testRepositoryUrl, mockClient) ); 186 final FedoraObject mockObject = mock(FedoraObject.class); 187 doReturn(mockObject).when(spy).getObject(anyString()); 188 189 final FedoraObject object = spy.findOrCreateObject("/foo"); 190 assertEquals(mockObject, object); 191 } 192 193 @Test 194 public void testFindOrCreateObjectNonExistent() throws FedoraException { 195 final FedoraRepositoryImpl spy = spy( new FedoraRepositoryImpl(testRepositoryUrl, mockClient) ); 196 final NotFoundException mockException = mock(NotFoundException.class); 197 doThrow(mockException).when(spy).getObject(anyString()); 198 final FedoraObject mockObject = mock(FedoraObject.class); 199 doReturn(mockObject).when(spy).createObject(anyString()); 200 201 final FedoraObject object = spy.findOrCreateObject("/foo"); 202 assertEquals(mockObject, object); 203 } 204 205 @Test 206 public void testWritable() { 207 assertTrue( fedoraRepository.isWritable() ); 208 } 209 210 @Test 211 public void testUpdateProperties() throws Exception { 212 final String path = "/testObject"; 213 final String etag = "urn:sha1:e242ed3bffccdf271b7fbaf34ed72d089537b42f"; 214 final URI uri = new URI( testRepositoryUrl + path ); 215 final HttpResponse response = mock(HttpResponse.class); 216 final StatusLine status = mock(StatusLine.class); 217 final FedoraObjectImpl object = new FedoraObjectImpl( fedoraRepository, httpHelper, path ); 218 final Header etagHeader = mock(Header.class); 219 final Header[] etagArray = new Header[]{ etagHeader }; 220 final Header typeHeader = mock(Header.class); 221 final HttpEntity entity = mock(HttpEntity.class); 222 223 when(mockClient.execute(any(HttpUriRequest.class))).thenReturn(response); 224 when(response.getStatusLine()).thenReturn(status); 225 when(status.getStatusCode()).thenReturn(200); 226 when(response.getHeaders(eq("ETag"))).thenReturn(etagArray); 227 when(response.getEntity()).thenReturn(entity); 228 when(entity.getContentType()).thenReturn(typeHeader); 229 when(etagHeader.getValue()).thenReturn(etag); 230 when(typeHeader.getValue()).thenReturn("application/rdf+xml"); 231 when(entity.getContent()).thenReturn(new ByteArrayInputStream(testContent.getBytes())); 232 233 httpHelper.loadProperties( object ); 234 final Graph g = object.getGraph(); 235 assertNotNull(g); 236 assertTrue( g.contains( createURI(uri.toString()), HAS_PRIMARY_IDENTIFIER.asNode(), 237 createLiteral("2fb9c440-db63-434f-929b-0ff29253205c")) ); 238 } 239 240 @Test 241 public void testCreateContentPutMethod() throws Exception { 242 final String path = "/test"; 243 final InputStream in = new ByteArrayInputStream( "foo".getBytes() ); 244 final String mime = "image/jpeg"; 245 final String fn = "image.jpg"; 246 final String chk = "urn:sha1:c6bbf022f8f19d09106622aa912218417723f543"; 247 final URI checksumURI = new URI(chk); 248 final FedoraContent cont = new FedoraContent().setContent(in).setContentType(mime) 249 .setFilename(fn).setChecksum(checksumURI); 250 251 final HttpPut put = httpHelper.createContentPutMethod(path, null, cont); 252 253 assertEquals( testRepositoryUrl + path + "?checksum=" + chk, put.getURI().toString() ); 254 assertEquals( in, put.getEntity().getContent() ); 255 assertEquals( mime, put.getFirstHeader("Content-Type").getValue() ); 256 assertEquals( "attachment; filename=\"" + fn + "\"", put.getFirstHeader("Content-Disposition").getValue() ); 257 } 258}