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.Factory.createDefaultGraph;
019import static com.hp.hpl.jena.graph.NodeFactory.createURI;
020import static com.hp.hpl.jena.graph.Triple.create;
021import static org.mockito.Matchers.any;
022import static org.mockito.Matchers.anyString;
023import static org.mockito.Matchers.eq;
024import static org.mockito.MockitoAnnotations.initMocks;
025import static org.mockito.Mockito.mock;
026import static org.mockito.Mockito.verify;
027import static org.mockito.Mockito.when;
028
029import static org.fcrepo.kernel.api.RdfLexicon.CREATED_DATE;
030import static org.fcrepo.kernel.api.RdfLexicon.LAST_MODIFIED_DATE;
031import static org.fcrepo.kernel.api.RdfLexicon.HAS_MIXIN_TYPE;
032import static org.fcrepo.kernel.api.RdfLexicon.WRITABLE;
033import static org.fcrepo.kernel.api.RdfLexicon.DESCRIBES;
034import static org.fcrepo.kernel.api.RdfLexicon.HAS_SIZE;
035import static org.fcrepo.kernel.api.RdfLexicon.HAS_MIME_TYPE;
036import static org.fcrepo.kernel.api.RdfLexicon.HAS_ORIGINAL_NAME;
037import static org.fcrepo.client.impl.FedoraDatastreamImpl.REST_API_DIGEST;
038
039import static org.junit.Assert.assertTrue;
040import static org.junit.Assert.assertEquals;
041import static org.junit.Assert.assertNotNull;
042
043import java.io.ByteArrayInputStream;
044import java.io.InputStream;
045import java.io.IOException;
046import java.net.URI;
047import java.net.URISyntaxException;
048import java.text.SimpleDateFormat;
049import java.util.Iterator;
050import java.util.Map;
051
052import com.hp.hpl.jena.graph.Graph;
053import com.hp.hpl.jena.graph.Node;
054import com.hp.hpl.jena.graph.Triple;
055import com.hp.hpl.jena.rdf.model.ResourceFactory;
056
057import org.apache.commons.io.IOUtils;
058
059import org.apache.http.HttpEntity;
060import org.apache.http.HttpResponse;
061import org.apache.http.StatusLine;
062import org.apache.http.client.methods.HttpGet;
063import org.apache.http.client.methods.HttpPut;
064
065import org.fcrepo.client.FedoraContent;
066import org.fcrepo.client.FedoraException;
067import org.fcrepo.client.FedoraObject;
068import org.fcrepo.client.utils.HttpHelper;
069import org.fcrepo.kernel.api.RdfLexicon;
070
071import org.junit.Before;
072import org.junit.Test;
073import org.mockito.Mock;
074
075/**
076 * Datastream Impl test.
077 * @author escowles
078 * @since 2014-08-25
079 */
080public class FedoraDatastreamImplTest {
081
082    @Mock
083    FedoraRepositoryImpl mockRepository;
084
085    @Mock
086    HttpHelper mockHelper;
087
088    @Mock
089    private FedoraObject mockObject;
090
091    @Mock
092    private Iterator<Triple> mockTriples;
093
094    private FedoraDatastreamImpl datastream;
095
096    private String path = "/test/image/fcr:metadata";
097
098    private boolean isWritable = true;
099
100    private static SimpleDateFormat dateFormat =
101            new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
102
103    private String testDateValue = "2014-08-14T15:11:30.118Z";
104    private String testMixinType = RdfLexicon.REPOSITORY_NAMESPACE + "test";
105    private String checksum = "urn:sha1:187ff331acaea139c8dc1eb77da8be32bd81ac7d";
106    private String filename = "test.jpg";
107    private String mimeType = "image/jpeg";
108    private String contentSize = "545376";
109    private final String repositoryURL = "http://localhost:8080/rest";
110    private Node dsSubj = createURI(repositoryURL + path);
111    private Node contentSubj = createURI(repositoryURL + path.substring(0, path.lastIndexOf("/")));
112
113
114    @Before
115    public void setUp() throws IOException, FedoraException {
116        initMocks(this);
117        mockRepository.httpHelper = mockHelper;
118
119        when(mockRepository.getRepositoryUrl()).thenReturn(repositoryURL);
120        when(mockRepository.getObject(eq("/test"))).thenReturn(mockObject);
121        datastream = new FedoraDatastreamImpl(mockRepository, mockHelper, path);
122        assertTrue(datastream != null);
123
124        final Graph graph = createDefaultGraph();
125        graph.add( create(dsSubj, CREATED_DATE.asNode(), ResourceFactory.createPlainLiteral(testDateValue).asNode()) );
126        graph.add( create(dsSubj, LAST_MODIFIED_DATE.asNode(),
127            ResourceFactory.createPlainLiteral(testDateValue).asNode()) );
128        graph.add( create(dsSubj, HAS_MIXIN_TYPE.asNode(), createURI(testMixinType)) );
129        graph.add( create(dsSubj, WRITABLE.asNode(),
130            ResourceFactory.createTypedLiteral(new Boolean(isWritable)).asNode()) );
131        graph.add( create(dsSubj, DESCRIBES.asNode(), contentSubj) );
132        graph.add( create(contentSubj, HAS_SIZE.asNode(), ResourceFactory.createPlainLiteral(contentSize).asNode()) );
133        graph.add( create(contentSubj, HAS_MIME_TYPE.asNode(), ResourceFactory.createPlainLiteral(mimeType).asNode()) );
134        graph.add( create(contentSubj, HAS_ORIGINAL_NAME.asNode(),
135            ResourceFactory.createPlainLiteral(filename).asNode()) );
136        graph.add( create(contentSubj, REST_API_DIGEST.asNode(), createURI(checksum)) );
137        datastream.setGraph( graph );
138    }
139
140    // functionality inherited from FedoraResourceImpl
141
142    @Test
143    public void testGetCreatedDate() throws FedoraException {
144        assertEquals("Created date is not the same",
145                testDateValue, dateFormat.format(datastream.getCreatedDate()));
146    }
147
148    @Test
149    public void testGetAndSetEtagValue() throws FedoraException {
150        ((FedoraDatastreamImpl)datastream).setEtagValue("2a0e84efa8a39de57ebbc5ed3bc7e454a1a768de");
151        assertEquals("ETag is not the same",
152                "2a0e84efa8a39de57ebbc5ed3bc7e454a1a768de", datastream.getEtagValue());
153     }
154
155    @Test
156    public void testGetLastModifiedDate() throws FedoraException {
157        assertEquals("LastModifiedDate is not the same",
158                testDateValue, dateFormat.format(datastream.getLastModifiedDate()));
159    }
160
161    @Test
162    public void testGetMixins() throws FedoraException {
163        assertTrue(datastream.getMixins().contains(testMixinType));
164    }
165
166    @Test
167    public void testGetName() throws IOException, FedoraException {
168        assertEquals("Name is not the same", "image", datastream.getName());
169    }
170
171    @Test
172    public void testGetPath() throws FedoraException {
173        assertEquals("Path is not the same", path, datastream.getPath());
174    }
175
176    @Test
177    public void testGetProperties() throws FedoraException {
178        assertEquals("Can't retrieve Properties",
179                datastream.getProperties().hasNext(), true);
180    }
181
182    @Test
183    public void testIsWritable() {
184        assertEquals("IsWriatable value is not the same",
185                isWritable, datastream.isWritable());
186    }
187
188    @Test
189    public void TestGetGraph() {
190        assertNotNull(((FedoraDatastreamImpl)datastream).getGraph());
191    }
192
193    // datastream-specific functionality
194
195    @Test
196    public void testHasContent() throws FedoraException {
197        assertTrue("Should have content", datastream.hasContent());
198    }
199
200    @Test
201    public void testGetContentDigest() throws FedoraException {
202        assertEquals("Checksum is not the same", checksum, datastream.getContentDigest().toString());
203    }
204
205    @Test
206    public void testGetContentSize() throws FedoraException {
207        assertEquals("Content size is not the same", contentSize, String.valueOf(datastream.getContentSize()));
208    }
209
210    @Test
211    public void testGetFilename() throws FedoraException {
212        assertEquals("Content filename is not the same", filename, datastream.getFilename());
213    }
214
215    @Test
216    public void testGetContentType() throws FedoraException {
217        assertEquals("Content mime type is not the same", mimeType, datastream.getContentType());
218    }
219
220    @Test
221    public void testGetObject() throws FedoraException {
222        final FedoraObject obj = datastream.getObject();
223        assertEquals("Parent object doesn't match", mockObject, obj);
224    }
225
226    @Test
227    public void testGetContent() throws IOException, URISyntaxException, FedoraException {
228        final URI getURI = new URI(repositoryURL + path);
229        final HttpGet mockGet = mock(HttpGet.class);
230        final HttpResponse mockResponse = mock(HttpResponse.class);
231        final StatusLine mockStatus = mock(StatusLine.class);
232        final HttpEntity mockEntity = mock(HttpEntity.class);
233        final String mockContent = "test datastream content";
234
235        when(mockHelper.createGetMethod(anyString(), any(Map.class))).thenReturn(mockGet);
236        when(mockGet.getURI()).thenReturn(getURI);
237        when(mockHelper.execute(any(HttpGet.class))).thenReturn(mockResponse);
238        when(mockResponse.getStatusLine()).thenReturn(mockStatus);
239        when(mockStatus.getStatusCode()).thenReturn(200);
240        when(mockResponse.getEntity()).thenReturn(mockEntity);
241        when(mockEntity.getContent()).thenReturn(new ByteArrayInputStream(mockContent.getBytes()));
242
243        final InputStream contentStream = datastream.getContent();
244        final String content = IOUtils.toString(contentStream);
245        assertEquals("Content doesn't match", mockContent, content);
246    }
247
248    @Test
249    public void testUpdateContent() throws IOException, URISyntaxException, FedoraException {
250        final String newFilename = "test.png";
251        final String newMimeType = "image/png";
252        final String mockContent = "test datastream content";
253        final FedoraContent content = new FedoraContent()
254            .setContent(new ByteArrayInputStream(mockContent.getBytes()))
255            .setFilename(newFilename).setContentType(newMimeType);
256
257        final URI putURI = new URI(repositoryURL + path);
258        final HttpPut mockPut = mock(HttpPut.class);
259        final HttpResponse mockResponse = mock(HttpResponse.class);
260        final StatusLine mockStatus = mock(StatusLine.class);
261        final HttpEntity mockEntity = mock(HttpEntity.class);
262
263        when(mockHelper.createContentPutMethod(anyString(), any(Map.class), eq(content))).thenReturn(mockPut);
264        when(mockPut.getURI()).thenReturn(putURI);
265        when(mockHelper.execute(any(HttpPut.class))).thenReturn(mockResponse);
266        when(mockResponse.getStatusLine()).thenReturn(mockStatus);
267        when(mockStatus.getStatusCode()).thenReturn(204);
268        when(mockResponse.getEntity()).thenReturn(mockEntity);
269        when(mockEntity.getContent()).thenReturn(new ByteArrayInputStream(mockContent.getBytes()));
270        when(mockHelper.loadProperties(eq(datastream))).thenReturn(datastream);
271
272        datastream.updateContent( content );
273
274        verify(mockHelper).execute(any(HttpPut.class));
275        verify(mockHelper).loadProperties(datastream);
276    }
277}