cz.cas.lib.proarc.common.fedora.RemoteStorageTest.java Source code

Java tutorial

Introduction

Here is the source code for cz.cas.lib.proarc.common.fedora.RemoteStorageTest.java

Source

/*
 * Copyright (C) 2012 Jan Pokorsky
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package cz.cas.lib.proarc.common.fedora;

import com.yourmediashelf.fedora.client.FedoraClient;
import com.yourmediashelf.fedora.client.response.DescribeRepositoryResponse;
import com.yourmediashelf.fedora.client.response.ListDatastreamsResponse;
import com.yourmediashelf.fedora.generated.access.DatastreamType;
import com.yourmediashelf.fedora.generated.management.DatastreamProfile;
import cz.cas.lib.proarc.common.CustomTemporaryFolder;
import cz.cas.lib.proarc.common.dublincore.DcStreamEditor;
import cz.cas.lib.proarc.common.fedora.FoxmlUtils.ControlGroup;
import cz.cas.lib.proarc.common.fedora.LocalStorage.LocalObject;
import cz.cas.lib.proarc.common.fedora.RemoteStorage.RemoteObject;
import cz.cas.lib.proarc.common.fedora.RemoteStorage.RemoteXmlStreamEditor;
import cz.cas.lib.proarc.common.fedora.XmlStreamEditor.EditorResult;
import cz.cas.lib.proarc.common.fedora.relation.RelationEditor;
import cz.cas.lib.proarc.common.mods.ModsStreamEditor;
import cz.cas.lib.proarc.mods.ModsDefinition;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.List;
import javax.ws.rs.core.MediaType;
import javax.xml.bind.JAXB;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.transform.Source;
import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TestName;

/**
 *
 * @author Jan Pokorsky
 */
public class RemoteStorageTest {

    private static FedoraClient client;
    private static FedoraTestSupport support;

    @Rule
    public TestName test = new TestName();

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Rule
    public CustomTemporaryFolder tmp = new CustomTemporaryFolder();

    public RemoteStorageTest() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
        support = new FedoraTestSupport();
        client = support.getClient();
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Before
    public void setUp() throws Exception {
        support.cleanUp();
    }

    @After
    public void tearDown() {
    }

    @Test
    public void testVersion() throws Exception {
        RemoteStorage fedora = new RemoteStorage(client);
        DescribeRepositoryResponse descr = fedora.getRepositoryDescription(true);
        assertNotNull(descr);
        String version = descr.getRepositoryVersion();
        assertNotNull(version);
        assertTrue(version, fedora.isCompatible("3.5"));
    }

    @Test
    public void testIngest() throws Exception {
        RemoteStorage fedora = new RemoteStorage(client);
        LocalObject object = new LocalStorage().create();
        String label = "testing";
        object.setLabel(label);
        fedora.ingest(object, "junit", "{\"key\":\"val\"}");
    }

    @Test
    public void testIngestPage() throws Exception {
        RemoteStorage fedora = new RemoteStorage(client);
        //        client.debug(true);
        LocalObject local = new LocalStorage().create();
        //        LocalObject local = new LocalStorage().create(new File("/tmp/failing_ingest.foxml"));
        String model = "model:page";

        RelationEditor relsExt = new RelationEditor(local);
        relsExt.setModel(model);
        relsExt.write(0, null);
        ModsStreamEditor modsEditor = new ModsStreamEditor(local);
        ModsDefinition mods = modsEditor.createPage(local.getPid(), "1", "[1]", "Blank");
        DcStreamEditor dcEditor = new DcStreamEditor(local);
        dcEditor.write(mods, model, 0, null);
        modsEditor.write(mods, 0, null);

        StringEditor ocrEditor = StringEditor.ocr(local);
        ocrEditor.write("ocr", 0, null);

        File thumb = tmp.newFile();
        assertTrue(thumb.exists());
        BinaryEditor.dissemination(local, BinaryEditor.THUMB_ID).write(thumb, 0, null);
        local.flush();
        //        System.out.println(FoxmlUtils.toXml(local.getDigitalObject(), true));

        String label = "testing";
        local.setLabel(label);
        fedora.ingest(local, "junit");
        ListDatastreamsResponse response = FedoraClient.listDatastreams(local.getPid()).execute(client);
        List<DatastreamType> datastreams = response.getDatastreams();
        assertDatastream(DcStreamEditor.DATASTREAM_ID, datastreams);
        assertDatastream(ModsStreamEditor.DATASTREAM_ID, datastreams);
        assertDatastream(RelationEditor.DATASTREAM_ID, datastreams);
        assertDatastream(StringEditor.OCR_ID, datastreams);
        assertDatastream(BinaryEditor.THUMB_ID, datastreams);
    }

    @Test
    public void testPurge() throws Exception {
        RemoteStorage fedora = new RemoteStorage(client);
        LocalObject object = new LocalStorage().create();
        String label = "testPurge";
        object.setLabel(label);
        fedora.ingest(object, "junit");
        assertTrue(object.getPid(), fedora.exist(object.getPid()));
        RemoteObject robject = fedora.find(object.getPid());
        robject.purge("{\"key\":\"val\"}");
        assertFalse(object.getPid(), fedora.exist(object.getPid()));
    }

    @Test
    public void testPurgeMissing() throws Exception {
        RemoteStorage fedora = new RemoteStorage(client);
        RemoteObject missing = fedora.find("uuid:missing");
        thrown.expect(DigitalObjectNotFoundException.class);
        missing.purge("testPurgeMissing");
    }

    private static void assertDatastream(String id, List<DatastreamType> datastreams) {
        for (DatastreamType ds : datastreams) {
            if (id.equals(ds.getDsid())) {
                return;
            }
        }
        fail(id);
    }

    @Test
    public void testXmlRead() throws Exception {
        String dsId = "testId";
        LocalObject local = new LocalStorage().create();
        local.setLabel(test.getMethodName());
        String format = "testns";
        XmlStreamEditor leditor = local.getEditor(FoxmlUtils.inlineProfile(dsId, format, "label"));
        EditorResult editorResult = leditor.createResult();
        TestXml content = new TestXml("test content");
        JAXB.marshal(content, editorResult);
        leditor.write(editorResult, 0, null);

        RemoteStorage fedora = new RemoteStorage(client);
        fedora.ingest(local, "junit");

        RemoteObject remote = fedora.find(local.getPid());
        RemoteXmlStreamEditor editor = new RemoteXmlStreamEditor(remote, dsId);
        Source src = editor.read();
        assertNotNull(src);
        TestXml resultContent = JAXB.unmarshal(src, TestXml.class);
        assertEquals(content, resultContent);
        long lastModified = editor.getLastModified();
        assertTrue(String.valueOf(lastModified), lastModified != 0 && lastModified < System.currentTimeMillis());
        assertEquals(format, editor.getProfile().getDsFormatURI());
    }

    @Test(expected = DigitalObjectNotFoundException.class)
    public void testXmlReadDataStreamOfMissingPid() throws Exception {
        RemoteStorage fedora = new RemoteStorage(client);
        LocalObject local = new LocalStorage().create();
        local.setLabel(test.getMethodName());
        // no ingest!
        RemoteObject remote = fedora.find(local.getPid());
        RemoteXmlStreamEditor editor = new RemoteXmlStreamEditor(remote, FoxmlUtils
                .managedProfile("managedDatastream", MediaType.TEXT_PLAIN_TYPE, "managedDatastreamLabel"));
        editor.read();
    }

    /**
     * test read missing data stream with
     * {@link RemoteXmlStreamEditor#RemoteXmlStreamEditor(RemoteObject, String) }.
     */
    @Test(expected = DigitalObjectException.class)
    public void testReadMissingDataStreamFailure() throws Exception {
        RemoteStorage fedora = new RemoteStorage(client);
        LocalObject local = new LocalStorage().create();
        local.setLabel(test.getMethodName());
        fedora.ingest(local, "junit");
        RemoteObject remote = fedora.find(local.getPid());
        RemoteXmlStreamEditor editor = new RemoteXmlStreamEditor(remote, "missingDatastream");
        editor.read();
    }

    @Test
    public void testPlainTextReadWriteMissingDataStream() throws Exception {
        RemoteStorage fedora = new RemoteStorage(client);
        LocalObject local = new LocalStorage().create();
        local.setLabel(test.getMethodName());
        fedora.ingest(local, "junit");
        RemoteObject remote = fedora.find(local.getPid());
        RemoteXmlStreamEditor editor = new RemoteXmlStreamEditor(remote, FoxmlUtils
                .managedProfile("managedDatastream", MediaType.TEXT_PLAIN_TYPE, "managedDatastreamLabel"));
        InputStream src = editor.readStream();
        assertNull(src);
        long lastModified = editor.getLastModified();
        assertEquals(-1, lastModified);
        assertEquals(MediaType.TEXT_PLAIN, editor.getProfile().getDsMIME());
        editor.write("plain text".getBytes("UTF-8"), lastModified, null);
        remote.flush();

        // first test current editor
        src = editor.readStream();
        assertNotNull(src);
        assertEquals(MediaType.TEXT_PLAIN, editor.getProfile().getDsMIME());
        assertTrue(lastModified < editor.getLastModified());
        String content = StringEditor.read(src);
        assertEquals("plain text", content);
        assertNull(editor.getProfile().getDsFormatURI());

        // test new editor
        editor = new RemoteXmlStreamEditor(remote, FoxmlUtils.managedProfile("managedDatastream",
                MediaType.TEXT_PLAIN_TYPE, "managedDatastreamLabel"));
        src = editor.readStream();
        assertNotNull(src);
        assertEquals(MediaType.TEXT_PLAIN, editor.getProfile().getDsMIME());
        assertTrue(lastModified < editor.getLastModified());
        content = StringEditor.read(src);
        assertEquals("plain text", content);
        assertNull(editor.getProfile().getDsFormatURI());
    }

    @Test
    public void testXmlWrite() throws Exception {
        String dsId = "testId";
        LocalObject local = new LocalStorage().create();
        local.setLabel(test.getMethodName());
        String format = "testns";
        XmlStreamEditor leditor = local.getEditor(FoxmlUtils.inlineProfile(dsId, format, "label"));
        EditorResult editorResult = leditor.createResult();
        TestXml content = new TestXml("test content");
        JAXB.marshal(content, editorResult);
        leditor.write(editorResult, 0, null);

        RemoteStorage fedora = new RemoteStorage(client);
        fedora.ingest(local, "junit");

        RemoteObject remote = fedora.find(local.getPid());
        RemoteXmlStreamEditor editor = new RemoteXmlStreamEditor(remote, dsId);
        Source src = editor.read();
        assertNotNull(src);
        TestXml resultContent = JAXB.unmarshal(src, TestXml.class);

        // write modification
        String expectedContent = "changed test content";
        resultContent.data = expectedContent;
        editorResult = editor.createResult();
        JAXB.marshal(resultContent, editorResult);
        long lastModified = editor.getLastModified();
        assertEquals(format, editor.getProfile().getDsFormatURI());
        editor.write(editorResult, lastModified, null);
        remote.flush();

        // test current editor
        assertTrue(lastModified < editor.getLastModified());
        long expectLastModified = editor.getLastModified();
        resultContent = JAXB.unmarshal(editor.read(), TestXml.class);
        assertEquals(new TestXml(expectedContent), resultContent);
        assertEquals(format, editor.getProfile().getDsFormatURI());

        // test new editor
        remote = fedora.find(local.getPid());
        editor = new RemoteXmlStreamEditor(remote, dsId);
        src = editor.read();
        assertNotNull(src);
        resultContent = JAXB.unmarshal(src, TestXml.class);
        assertEquals(new TestXml(expectedContent), resultContent);
        long resultLastModified = editor.getLastModified();
        assertEquals(expectLastModified, resultLastModified);
        assertEquals(format, editor.getProfile().getDsFormatURI());
    }

    @Test(expected = DigitalObjectConcurrentModificationException.class)
    public void testXmlWriteConcurrent() throws Exception {
        String dsId = "testId";
        LocalObject local = new LocalStorage().create();
        local.setLabel(test.getMethodName());
        XmlStreamEditor leditor = local.getEditor(FoxmlUtils.inlineProfile(dsId, "testns", "label"));
        EditorResult editorResult = leditor.createResult();
        TestXml content = new TestXml("test content");
        JAXB.marshal(content, editorResult);
        leditor.write(editorResult, 0, null);

        RemoteStorage fedora = new RemoteStorage(client);
        fedora.ingest(local, "junit");

        RemoteObject remote = fedora.find(local.getPid());
        RemoteXmlStreamEditor editor = new RemoteXmlStreamEditor(remote, dsId);
        Source src = editor.read();
        assertNotNull(src);
        TestXml resultContent = JAXB.unmarshal(src, TestXml.class);

        // concurrent write
        RemoteObject concurrentRemote = fedora.find(local.getPid());
        RemoteXmlStreamEditor concurrentEditor = new RemoteXmlStreamEditor(concurrentRemote, dsId);
        TestXml concurrentContent = JAXB.unmarshal(concurrentEditor.read(), TestXml.class);
        concurrentContent.data = "concurrent change";
        EditorResult concurrentResult = concurrentEditor.createResult();
        JAXB.marshal(concurrentContent, concurrentResult);
        concurrentEditor.write(concurrentResult, editor.getLastModified(), null);
        concurrentRemote.flush();

        // write out of date modification
        String expectedContent = "changed test content";
        resultContent.data = expectedContent;
        editorResult = editor.createResult();
        JAXB.marshal(resultContent, editorResult);
        long lastModified = editor.getLastModified();
        editor.write(editorResult, lastModified, null);

        remote.flush();
    }

    @Test
    public void testDatastreamEditorWriteStream_Managed() throws Exception {
        LocalStorage storage = new LocalStorage();
        LocalObject local = storage.create();
        local.setLabel(test.getMethodName());
        String dsID = "dsID";
        MediaType mime = MediaType.TEXT_PLAIN_TYPE;
        String label = "label";
        DatastreamProfile dsProfile = FoxmlUtils.managedProfile(dsID, mime, label);

        RemoteStorage fedora = new RemoteStorage(client);
        fedora.ingest(local, "junit");

        byte[] data = "data".getBytes("UTF-8");
        RemoteObject remote = fedora.find(local.getPid());
        XmlStreamEditor reditor = remote.getEditor(dsProfile);
        assertNotNull(reditor);
        reditor.write(new ByteArrayInputStream(data), reditor.getLastModified(), null);

        // test read cached
        InputStream is = reditor.readStream();
        assertNotNull(is);
        ByteArrayOutputStream resultData = new ByteArrayOutputStream();
        FoxmlUtils.copy(is, resultData);
        is.close();
        assertArrayEquals(data, resultData.toByteArray());
        remote.flush();

        // test remote read
        remote = fedora.find(local.getPid());
        reditor = remote.getEditor(dsProfile);
        is = reditor.readStream();
        assertNotNull(is);
        resultData = new ByteArrayOutputStream();
        FoxmlUtils.copy(is, resultData);
        is.close();
        assertArrayEquals(data, resultData.toByteArray());
    }

    @Test
    public void testDatastreamEditorWriteReference_Managed() throws Exception {
        LocalStorage storage = new LocalStorage();
        LocalObject local = storage.create();
        local.setLabel(test.getMethodName());
        String dsID = "dsID";
        MediaType mime = MediaType.TEXT_PLAIN_TYPE;
        String label = "label";
        DatastreamProfile dsProfile = FoxmlUtils.managedProfile(dsID, mime, label);

        RemoteStorage fedora = new RemoteStorage(client);
        fedora.ingest(local, "junit");

        // prepare referenced contents
        byte[] data = "data".getBytes("UTF-8");
        File file = tmp.newFile();
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(data);
        fos.close();

        RemoteObject remote = fedora.find(local.getPid());
        XmlStreamEditor reditor = remote.getEditor(dsProfile);
        assertNotNull(reditor);
        reditor.write(file.toURI(), reditor.getLastModified(), null);

        // test read cached
        InputStream is = reditor.readStream();
        assertNotNull(is);
        ByteArrayOutputStream resultData = new ByteArrayOutputStream();
        FoxmlUtils.copy(is, resultData);
        is.close();
        assertArrayEquals(data, resultData.toByteArray());
        remote.flush();

        // test remote read
        remote = fedora.find(local.getPid());
        reditor = remote.getEditor(dsProfile);
        is = reditor.readStream();
        assertNotNull(is);
        resultData = new ByteArrayOutputStream();
        FoxmlUtils.copy(is, resultData);
        is.close();
        assertArrayEquals(data, resultData.toByteArray());
    }

    @Test
    public void testDatastreamEditorWriteReference_External() throws Exception {
        LocalStorage storage = new LocalStorage();
        LocalObject local = storage.create();
        local.setLabel(test.getMethodName());
        String dsID = "dsID";
        MediaType mime = MediaType.TEXT_PLAIN_TYPE;
        String label = "label";
        DatastreamProfile dsProfile = FoxmlUtils.externalProfile(dsID, mime, label);

        RemoteStorage fedora = new RemoteStorage(client);
        fedora.ingest(local, support.getTestUser());

        // prepare referenced contents
        byte[] data = "data".getBytes("UTF-8");
        File file = tmp.newFile();
        FileUtils.writeByteArrayToFile(file, data);

        RemoteObject remote = fedora.find(local.getPid());
        XmlStreamEditor reditor = remote.getEditor(dsProfile);
        assertNotNull(reditor);
        reditor.write(file.toURI(), reditor.getLastModified(), "add");

        // test read cached
        InputStream is = reditor.readStream();
        assertNotNull(is);
        ByteArrayOutputStream resultData = new ByteArrayOutputStream();
        FoxmlUtils.copy(is, resultData);
        is.close();
        assertArrayEquals(data, resultData.toByteArray());
        assertEquals(mime.toString(), reditor.getProfile().getDsMIME());
        assertEquals(ControlGroup.EXTERNAL.toExternal(), reditor.getProfile().getDsControlGroup());

        // test remote read
        remote.flush();
        remote = fedora.find(local.getPid());
        reditor = remote.getEditor(dsProfile);
        is = reditor.readStream();
        assertNotNull(is);
        resultData = new ByteArrayOutputStream();
        FoxmlUtils.copy(is, resultData);
        is.close();
        assertArrayEquals(data, resultData.toByteArray());
        assertEquals(mime.toString(), reditor.getProfile().getDsMIME());
        assertEquals(ControlGroup.EXTERNAL.toExternal(), reditor.getProfile().getDsControlGroup());

        // test update MIME + location
        MediaType mime2 = MediaType.APPLICATION_OCTET_STREAM_TYPE;
        byte[] data2 = "data2".getBytes("UTF-8");
        File file2 = tmp.newFile();
        FileUtils.writeByteArrayToFile(file2, data2);
        remote = fedora.find(local.getPid());
        reditor = remote.getEditor(dsProfile);
        DatastreamProfile dsProfile2 = FoxmlUtils.externalProfile(dsID, mime2, label);
        reditor.setProfile(dsProfile2);
        reditor.write(file2.toURI(), reditor.getLastModified(), "update");
        remote.flush();

        remote = fedora.find(local.getPid());
        reditor = remote.getEditor(dsProfile);
        is = reditor.readStream();
        assertNotNull(is);
        resultData = new ByteArrayOutputStream();
        FoxmlUtils.copy(is, resultData);
        is.close();
        assertArrayEquals(data2, resultData.toByteArray());
        assertEquals(mime2.toString(), reditor.getProfile().getDsMIME());
        assertEquals(ControlGroup.EXTERNAL.toExternal(), reditor.getProfile().getDsControlGroup());
    }

    @Test
    public void testDatastreamEditorRewriteControlGroup() throws Exception {
        // prepare referenced contents
        byte[] data1 = "data1".getBytes("UTF-8");
        File file1 = tmp.newFile();
        FileUtils.writeByteArrayToFile(file1, data1);
        byte[] data2 = "data2".getBytes("UTF-8");
        File file2 = tmp.newFile();
        FileUtils.writeByteArrayToFile(file2, data2);

        LocalStorage storage = new LocalStorage();
        LocalObject local = storage.create();
        System.out.println(local.getPid());
        local.setLabel(test.getMethodName());
        String dsID = "dsID";
        String label = "label";
        MediaType mime1 = MediaType.APPLICATION_OCTET_STREAM_TYPE;
        DatastreamProfile dsProfile1 = FoxmlUtils.managedProfile(dsID, mime1, label);
        XmlStreamEditor leditor = local.getEditor(dsProfile1);
        assertNotNull(leditor);
        leditor.write(file1.toURI(), leditor.getLastModified(), null);
        local.flush();

        RemoteStorage fedora = new RemoteStorage(client);
        fedora.ingest(local, support.getTestUser());

        MediaType mime2 = MediaType.TEXT_PLAIN_TYPE;
        DatastreamProfile dsProfile2 = FoxmlUtils.externalProfile(dsID, mime2, label);
        RemoteObject remote = fedora.find(local.getPid());
        XmlStreamEditor reditor = remote.getEditor(dsProfile1);
        assertNotNull(reditor);
        reditor.setProfile(dsProfile2);
        reditor.write(file2.toURI(), reditor.getLastModified(), null);

        // test read cached
        InputStream is = reditor.readStream();
        assertNotNull(is);
        ByteArrayOutputStream resultData = new ByteArrayOutputStream();
        FoxmlUtils.copy(is, resultData);
        is.close();
        assertArrayEquals(data2, resultData.toByteArray());
        assertEquals(mime2.toString(), reditor.getProfile().getDsMIME());
        assertEquals(ControlGroup.EXTERNAL.toExternal(), reditor.getProfile().getDsControlGroup());

        // test remote read
        remote.flush();
        remote = fedora.find(local.getPid());
        reditor = remote.getEditor(dsProfile1);
        is = reditor.readStream();
        assertNotNull(is);
        resultData = new ByteArrayOutputStream();
        FoxmlUtils.copy(is, resultData);
        is.close();
        assertArrayEquals(data2, resultData.toByteArray());
        assertEquals(mime2.toString(), reditor.getProfile().getDsMIME());
        assertEquals(ControlGroup.EXTERNAL.toExternal(), reditor.getProfile().getDsControlGroup());
    }

    @Test
    public void testSetDatastreamProfile() throws Exception {
        RemoteStorage fedora = new RemoteStorage(client);
        LocalObject local = new LocalStorage().create();
        local.setLabel(test.getMethodName());
        fedora.ingest(local, "junit");
        RemoteObject remote = fedora.find(local.getPid());
        String dsId = "missingDatastream";
        MediaType mime = MediaType.TEXT_PLAIN_TYPE;

        // first test missing datastream
        RemoteXmlStreamEditor editor = new RemoteXmlStreamEditor(remote,
                FoxmlUtils.managedProfile(dsId, mime, "defaultLabel"));
        DatastreamProfile profile = editor.getProfile();
        assertEquals(mime.toString(), profile.getDsMIME());
        String expectedLabel = "label1";
        profile.setDsLabel(expectedLabel);
        editor.setProfile(profile);
        editor.write(new byte[2], editor.getLastModified(), "write1");
        remote.flush();

        editor = new RemoteXmlStreamEditor(remote, FoxmlUtils.managedProfile(dsId, mime, ""));
        profile = editor.getProfile();
        assertEquals(mime.toString(), profile.getDsMIME());
        assertEquals(expectedLabel, profile.getDsLabel());

        // test existing datastream
        expectedLabel = "label2";
        MediaType newMime = MediaType.TEXT_HTML_TYPE;
        profile = editor.getProfile();
        profile.setDsMIME(newMime.toString());
        profile.setDsLabel(expectedLabel);
        editor.setProfile(profile);
        editor.write(new byte[2], editor.getLastModified(), "write2");
        profile = editor.getProfile();
        assertEquals(newMime.toString(), profile.getDsMIME());
        assertEquals(expectedLabel, profile.getDsLabel());
        remote.flush();

        editor = new RemoteXmlStreamEditor(remote, FoxmlUtils.managedProfile(dsId, mime, ""));
        profile = editor.getProfile();
        assertEquals(newMime.toString(), profile.getDsMIME());
        assertEquals(expectedLabel, profile.getDsLabel());

        // test standalone profile change (without content)
        newMime = MediaType.APPLICATION_JSON_TYPE;
        expectedLabel = "label3";
        profile.setDsMIME(newMime.toString());
        profile.setDsLabel(expectedLabel);
        editor.setProfile(profile);
        remote.flush();

        editor = new RemoteXmlStreamEditor(remote, FoxmlUtils.managedProfile(dsId, mime, ""));
        profile = editor.getProfile();
        assertEquals(newMime.toString(), profile.getDsMIME());
        assertEquals(expectedLabel, profile.getDsLabel());
    }

    @Test
    public void testGetStreamProfile() throws Exception {
        String dsId = "testId";
        LocalObject local = new LocalStorage().create();
        local.setLabel(test.getMethodName());
        String format = "testns";
        XmlStreamEditor leditor = local.getEditor(FoxmlUtils.inlineProfile(dsId, format, "label"));
        EditorResult editorResult = leditor.createResult();
        TestXml content = new TestXml("test content");
        JAXB.marshal(content, editorResult);
        leditor.write(editorResult, 0, null);

        RemoteStorage fedora = new RemoteStorage(client);
        fedora.ingest(local, support.getTestUser());

        RemoteObject remote = fedora.find(local.getPid());
        List<DatastreamProfile> resultProfiles = remote.getStreamProfile(null);
        assertNotNull(resultProfiles);
        assertEquals(2, resultProfiles.size()); // + DC
        assertEquals(dsId, resultProfiles.get(0).getDsID());
    }

    @Test
    public void testObjectNotFound() throws Exception {
        RemoteStorage fedora = new RemoteStorage(client);
        RemoteObject remote = fedora.find("prefix:unknown");
        try {
            remote.asText();
        } catch (DigitalObjectNotFoundException ex) {
            // ok
        }
    }

    @XmlRootElement(namespace = "testns")
    @XmlAccessorType(XmlAccessType.FIELD)
    public static class TestXml {

        String data;

        public TestXml() {
        }

        public TestXml(String data) {
            this.data = data;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final TestXml other = (TestXml) obj;
            if ((this.data == null) ? (other.data != null) : !this.data.equals(other.data)) {
                return false;
            }
            return true;
        }

        @Override
        public String toString() {
            return "TestXml{" + "data=" + data + '}';
        }

    }
}