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 *
006 */
007package org.fcrepo.migration;
008
009import java.io.ByteArrayInputStream;
010import java.io.ByteArrayOutputStream;
011import java.io.File;
012import java.io.FileNotFoundException;
013import java.io.IOException;
014import java.io.InputStream;
015import java.net.URL;
016import java.util.ArrayList;
017import java.util.Collections;
018import java.util.Iterator;
019import java.util.List;
020
021import javax.xml.stream.XMLStreamException;
022
023import org.apache.commons.io.IOUtils;
024import org.fcrepo.migration.foxml.CachedContent;
025import org.fcrepo.migration.foxml.FoxmlInputStreamFedoraObjectProcessor;
026import org.fcrepo.migration.foxml.InternalIDResolver;
027import org.fcrepo.migration.foxml.URLFetcher;
028import org.junit.Assert;
029import org.junit.Test;
030
031/**
032 * An abstract base class that defines some dummy classes useful for
033 * testing a Migrator instance and a suite of tests appropriate for
034 * a single example object.  Subclasses may expose this example object
035 * in different ways.
036 * @author mdurbin
037 */
038public abstract class Example1TestSuite {
039
040    protected abstract DummyHandler getResult();
041
042    protected abstract DummyURLFetcher getFetcher();
043
044
045    @Test
046    public void testObjectInfoParsing() {
047        Assert.assertEquals("example:1", getResult().objectInfo.getPid());
048        Assert.assertNull(getResult().objectInfo.getFedoraURI());
049    }
050
051    @Test
052    public void testPropertiesParsing() {
053        final List<? extends ObjectProperty> propertyList = getResult().properties.listProperties();
054        Assert.assertEquals(5, propertyList.size());
055        Assert.assertEquals("info:fedora/fedora-system:def/model#state", propertyList.get(0).getName());
056        Assert.assertEquals("Active", propertyList.get(0).getValue());
057        Assert.assertEquals("info:fedora/fedora-system:def/model#label", propertyList.get(1).getName());
058        Assert.assertEquals("This is an example object.", propertyList.get(1).getValue());
059        Assert.assertEquals("info:fedora/fedora-system:def/model#ownerId", propertyList.get(2).getName());
060        Assert.assertEquals("exampleOwner", propertyList.get(2).getValue());
061        Assert.assertEquals("info:fedora/fedora-system:def/model#createdDate", propertyList.get(3).getName());
062        Assert.assertEquals("2015-01-27T19:07:33.120Z", propertyList.get(3).getValue());
063        Assert.assertEquals("info:fedora/fedora-system:def/view#lastModifiedDate", propertyList.get(4).getName());
064        Assert.assertEquals("2015-01-27T20:26:16.998Z", propertyList.get(4).getValue());
065    }
066
067    @Test
068    public void testDatastreamParsing() throws XMLStreamException, IOException {
069        Assert.assertEquals(7, getResult().dsVersions.size());
070    }
071
072    @Test
073    public void testAuditDatastreamParsing() {
074        final DatastreamVersion audit0 = getResult().dsVersions.get(0);
075        Assert.assertEquals("AUDIT", audit0.getDatastreamInfo().getDatastreamId());
076        Assert.assertEquals("A", audit0.getDatastreamInfo().getState());
077        Assert.assertEquals("X", audit0.getDatastreamInfo().getControlGroup());
078        Assert.assertFalse(audit0.getDatastreamInfo().getVersionable());
079        Assert.assertEquals("AUDIT.0", audit0.getVersionId());
080        Assert.assertEquals("Audit Trail for this object", audit0.getLabel());
081        Assert.assertEquals("2015-01-27T19:07:33.120Z", audit0.getCreated());
082        Assert.assertEquals("text/xml", audit0.getMimeType());
083        Assert.assertEquals("info:fedora/fedora-system:format/xml.fedora.audit", audit0.getFormatUri());
084        Assert.assertTrue(audit0.getFile().isEmpty());
085    }
086
087    @Test
088    public void testDCDatastreamParsing() throws IOException {
089        final DatastreamVersion dc0 = getResult().dsVersions.get(1);
090        Assert.assertEquals("DC", dc0.getDatastreamInfo().getDatastreamId());
091        Assert.assertEquals("A", dc0.getDatastreamInfo().getState());
092        Assert.assertEquals("X", dc0.getDatastreamInfo().getControlGroup());
093        Assert.assertTrue(dc0.getDatastreamInfo().getVersionable());
094        Assert.assertEquals("DC1.0", dc0.getVersionId());
095        Assert.assertEquals("Dublin Core Record for this object", dc0.getLabel());
096        Assert.assertEquals("2015-01-27T19:07:33.120Z", dc0.getCreated());
097        Assert.assertEquals("text/xml", dc0.getMimeType());
098        Assert.assertEquals("http://www.openarchives.org/OAI/2.0/oai_dc/", dc0.getFormatUri());
099        Assert.assertEquals(dc0.getSize(), IOUtils.toByteArray(dc0.getContent()).length);
100        Assert.assertEquals("<oai_dc:dc xmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\"\n" +
101                "xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" +
102                "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
103                "xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd\">\n" +
104                "  <dc:title>This is an example object.</dc:title>\n" +
105                "  <dc:identifier>example:1</dc:identifier>\n" +
106                "</oai_dc:dc>", IOUtils.toString(dc0.getContent()).trim());
107        Assert.assertTrue(dc0.getFile().isEmpty());
108    }
109
110    @Test
111    public void testDS1VersionedDatastreamParsing() throws IOException {
112        final DatastreamVersion ds1 = getResult().dsVersions.get(2);
113        Assert.assertEquals("DS1", ds1.getDatastreamInfo().getDatastreamId());
114        Assert.assertEquals("A", ds1.getDatastreamInfo().getState());
115        Assert.assertEquals("X", ds1.getDatastreamInfo().getControlGroup());
116        Assert.assertTrue(ds1.getDatastreamInfo().getVersionable());
117        Assert.assertEquals("DS1.0", ds1.getVersionId());
118        Assert.assertEquals("Example inline XML datastream", ds1.getLabel());
119        Assert.assertEquals("2015-01-27T19:08:43.701Z", ds1.getCreated());
120        Assert.assertEquals("text/xml", ds1.getMimeType());
121        Assert.assertEquals("alternate_id", ds1.getAltIds());
122        Assert.assertEquals("format:uri", ds1.getFormatUri());
123        Assert.assertEquals(34, ds1.getSize());
124        Assert.assertEquals("<test>\n" +
125                "  This is a test.\n" +
126                "</test>", IOUtils.toString(ds1.getContent()).trim());
127        Assert.assertTrue(ds1.getFile().isEmpty());
128
129        final DatastreamVersion ds2 = getResult().dsVersions.get(3);
130        Assert.assertEquals("DS1", ds2.getDatastreamInfo().getDatastreamId());
131        Assert.assertEquals("A", ds2.getDatastreamInfo().getState());
132        Assert.assertEquals("X", ds2.getDatastreamInfo().getControlGroup());
133        Assert.assertTrue(ds2.getDatastreamInfo().getVersionable());
134        Assert.assertEquals("DS1.1", ds2.getVersionId());
135        Assert.assertEquals("Example inline XML datastream", ds2.getLabel());
136        Assert.assertEquals("2015-01-27T19:20:40.678Z", ds2.getCreated());
137        Assert.assertEquals("text/xml", ds2.getMimeType());
138        Assert.assertEquals("alternate_id", ds2.getAltIds());
139        Assert.assertEquals("format:uri", ds2.getFormatUri());
140        Assert.assertEquals(50, ds2.getSize());
141        Assert.assertNull(ds2.getContentDigest());
142        Assert.assertEquals("<test>\n" +
143                "  This is a test that was edited.\n" +
144                "</test>", IOUtils.toString(ds2.getContent()).trim());
145        Assert.assertTrue(ds2.getFile().isEmpty());
146    }
147
148    @Test
149    public void testDS2BinaryParsing() throws IOException {
150        final DatastreamVersion ds2 = getResult().dsVersions.get(4);
151        Assert.assertEquals("DS2", ds2.getDatastreamInfo().getDatastreamId());
152        Assert.assertEquals("A", ds2.getDatastreamInfo().getState());
153        Assert.assertEquals("M", ds2.getDatastreamInfo().getControlGroup());
154        Assert.assertFalse(ds2.getDatastreamInfo().getVersionable());
155        Assert.assertEquals("DS2.0", ds2.getVersionId());
156        Assert.assertEquals("Example Managed binary datastream", ds2.getLabel());
157        Assert.assertEquals("2015-01-27T19:09:18.112Z", ds2.getCreated());
158        Assert.assertEquals("image/jpeg", ds2.getMimeType());
159        Assert.assertEquals(46168, ds2.getSize());
160        Assert.assertEquals("MD5", ds2.getContentDigest().getType());
161        Assert.assertEquals("d4f18b8b9c64466819ddaad46228fb9b", ds2.getContentDigest().getDigest());
162        Assert.assertTrue("Managed Base64 encoded datastream must be preserved.", IOUtils.contentEquals(
163                getClass().getClassLoader().getResourceAsStream("small-mountains.jpg"),
164                new ByteArrayInputStream(getResult().cachedDsVersionBinaries.get(4))));
165        Assert.assertTrue(ds2.getFile().isPresent());
166    }
167
168    @Test
169    public void testDS3RedirectParsing() throws IOException {
170        final DatastreamVersion ds3 = getResult().dsVersions.get(5);
171        Assert.assertEquals("DS3", ds3.getDatastreamInfo().getDatastreamId());
172        Assert.assertEquals("A", ds3.getDatastreamInfo().getState());
173        Assert.assertEquals("R", ds3.getDatastreamInfo().getControlGroup());
174        Assert.assertTrue(ds3.getDatastreamInfo().getVersionable());
175        Assert.assertEquals("DS3.0", ds3.getVersionId());
176        Assert.assertEquals("Example Redirect \u007Fdatastream.", ds3.getLabel());
177        Assert.assertEquals("2015-01-27T19:14:05.948Z", ds3.getCreated());
178        Assert.assertEquals("image/jpeg", ds3.getMimeType());
179        Assert.assertEquals(-1, ds3.getSize());
180        ds3.getContent().close();
181        Assert.assertEquals("http://" + SimpleObjectSource.LOCAL_FEDORA_SERVER + "/fedora/get/example:1/DS2",
182                getFetcher().getLastUrl().toExternalForm());
183        Assert.assertTrue(ds3.getFile().isEmpty());
184    }
185
186    @Test
187    public void testDS4ExternalParsing() throws IOException {
188        final DatastreamVersion ds4 = getResult().dsVersions.get(6);
189        Assert.assertEquals("DS4", ds4.getDatastreamInfo().getDatastreamId());
190        Assert.assertEquals("A", ds4.getDatastreamInfo().getState());
191        Assert.assertEquals("E", ds4.getDatastreamInfo().getControlGroup());
192        Assert.assertTrue(ds4.getDatastreamInfo().getVersionable());
193        Assert.assertEquals("DS4.0", ds4.getVersionId());
194        Assert.assertEquals("Example External datastream.", ds4.getLabel());
195        Assert.assertEquals("2015-01-27T19:14:38.999Z", ds4.getCreated());
196        Assert.assertEquals("image/jpeg", ds4.getMimeType());
197        Assert.assertEquals(-1, ds4.getSize());
198        ds4.getContent().close();
199        Assert.assertEquals("http://" + SimpleObjectSource.LOCAL_FEDORA_SERVER
200                        + "/fedora/objects/example:1/datastreams/DS2/content",
201                getFetcher().getLastUrl().toExternalForm());
202        Assert.assertTrue(ds4.getFile().isEmpty());
203    }
204
205    public static class SimpleObjectSource implements ObjectSource {
206
207        private static final String LOCAL_FEDORA_SERVER = "replaced-local-fedora-server";
208
209        private FedoraObjectProcessor p;
210
211        public SimpleObjectSource(final String path, final URLFetcher f,
212                final InternalIDResolver resolver) throws XMLStreamException {
213            try {
214                p = new FoxmlInputStreamFedoraObjectProcessor(new File(path),
215                        f, resolver, LOCAL_FEDORA_SERVER);
216            } catch (FileNotFoundException e) {
217                throw new RuntimeException(e);
218            }
219        }
220
221        @Override
222        public Iterator<FedoraObjectProcessor> iterator() {
223            return Collections.singletonList(p).iterator();
224        }
225    }
226
227    public static class DummyHandler implements StreamingFedoraObjectHandler {
228
229        ObjectInfo objectInfo;
230        ObjectProperties properties;
231        List<DatastreamVersion> dsVersions = new ArrayList<DatastreamVersion>();
232        List<byte[]> cachedDsVersionBinaries = new ArrayList<byte[]>();
233
234        @Override
235        public void beginObject(final ObjectInfo object) {
236            this.objectInfo = object;
237        }
238
239        @Override
240        public void processObjectProperties(final ObjectProperties properties) {
241            this.properties = properties;
242        }
243
244        @Override
245        public void processDatastreamVersion(final DatastreamVersion dsVersion) {
246            dsVersions.add(dsVersion);
247            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
248            try (InputStream content = dsVersion.getContent()) {
249                IOUtils.copy(content, baos);
250                cachedDsVersionBinaries.add(baos.toByteArray());
251            } catch (final IOException e) {
252                throw new RuntimeException(e);
253            }
254
255
256        }
257
258        @Override
259        public void completeObject(final ObjectInfo object) {
260
261        }
262
263        @Override
264        public void abortObject(final ObjectInfo object) {
265
266        }
267    }
268
269    public static class DummyURLFetcher implements URLFetcher {
270
271        private URL lastUrl;
272
273        public URL getLastUrl() {
274            return lastUrl;
275        }
276
277        @Override
278        public InputStream getContentAtUrl(final URL url) throws IOException {
279            lastUrl = url;
280            return new ByteArrayInputStream("DummyURLFetcher".getBytes("UTF-8"));
281        }
282    }
283
284    public static class DummyIDResolver implements InternalIDResolver {
285        @Override
286        public CachedContent resolveInternalID(final String id) {
287            return null;
288        }
289
290        @Override
291        public void close() throws IOException { };
292    }
293
294}