/**
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 *
 * http://www.dspace.org/license/
 */
package org.dspace.identifier;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import org.apache.log4j.Logger;
import org.dspace.AbstractUnitTest;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.*;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.CommunityService;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.identifier.factory.IdentifierServiceFactory;
import org.dspace.identifier.service.DOIService;
import org.dspace.services.ConfigurationService;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.workflow.WorkflowException;
import org.dspace.workflow.WorkflowItem;
import org.dspace.workflow.factory.WorkflowServiceFactory;
import org.junit.*;
import static org.junit.Assert.*;
import static org.junit.Assume.*;

/**
* Tests for {@link DataCiteIdentifierProvider}.
*
* @author Mark H. Wood
* @author Pascal-Nicolas Becker
*/
public class DOIIdentifierProviderTest
        extends AbstractUnitTest
{
    /** log4j category */
    private static final Logger log = Logger.getLogger(DOIIdentifierProviderTest.class);
    
    private static final String PREFIX = "10.5072";
    private static final String NAMESPACE_SEPARATOR = "dspaceUnitTests-";

    private static ConfigurationService config = null;

    protected DOIService doiService = IdentifierServiceFactory.getInstance().getDOIService();
    protected CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
    protected CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
    protected ItemService itemService = ContentServiceFactory.getInstance().getItemService();
    protected WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService();


    private static Community community;
    private static Collection collection;

    private static MockDOIConnector connector;
    private DOIIdentifierProvider provider;

    public DOIIdentifierProviderTest()
    {
    }

    /**
     * This method will be run before every test as per @Before. It will
     * initialize resources required for the tests.
     *
     * Other methods can be annotated with @Before here or in subclasses
     * but no execution order is guaranteed
     */
    @Before
    @Override
    public void init()
    {
        super.init();
        
        try
        {
            context.turnOffAuthorisationSystem();
            // Create an environment for our test objects to live in.
            community = communityService.create(null, context);
            communityService.setMetadata(context, community, "name", "A Test Community");
            communityService.update(context, community);
            collection = collectionService.create(context, community);
            collectionService.setMetadata(context, collection, "name", "A Test Collection");
            collectionService.update(context, collection);
            //we need to commit the changes so we don't block the table for testing
            context.restoreAuthSystemState();

            config = DSpaceServicesFactory.getInstance().getConfigurationService();
            // Configure the service under test.
            config.setProperty(DOIIdentifierProvider.CFG_PREFIX, PREFIX);
            config.setProperty(DOIIdentifierProvider.CFG_NAMESPACE_SEPARATOR, 
                NAMESPACE_SEPARATOR);
        
            connector = new MockDOIConnector();
            
            provider = DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName(DOIIdentifierProvider.class.getName(), DOIIdentifierProvider.class);
            provider.setConfigurationService(config);
            provider.setDOIConnector(connector);
        }
        catch (AuthorizeException ex)
        {
            log.error("Authorization Error in init", ex);
            fail("Authorization Error in init: " + ex.getMessage());
        }
        catch (SQLException ex)
        {
            log.error("SQL Error in init", ex);
            fail("SQL Error in init: " + ex.getMessage());
        }
        
    }
    
     /**
     * This method will be run after every test as per @After. It will
     * clean resources initialized by the @Before methods.
     *
     * Other methods can be annotated with @After here or in subclasses
     * but no execution order is guaranteed
     */
    @After
    @Override
    public void destroy()
    {
        community = null;
        collection = null;
        connector.reset();
        connector = null;
        provider = null;
        super.destroy();
    }

    /**
    * Create a fresh Item, installed in the repository.
    *
    * @throws SQLException if database error
    * @throws AuthorizeException if authorization error
    * @throws IOException if IO error
    */
    private Item newItem()
            throws SQLException, AuthorizeException, IOException, IllegalAccessException, IdentifierException, WorkflowException
    {
        context.turnOffAuthorisationSystem();

        WorkspaceItem wsItem = workspaceItemService.create(context, collection, false);

        WorkflowItem wfItem = WorkflowServiceFactory.getInstance().getWorkflowService().start(context, wsItem);

        Item item = wfItem.getItem();
        itemService.addMetadata(context, item, "dc", "contributor", "author", null, "Author, A. N.");
        itemService.addMetadata(context, item, "dc", "title", null, null, "A Test Object");
        itemService.addMetadata(context, item, "dc", "publisher", null, null, "DSpace Test Harness");

        // If DOIIdentifierProvider is configured
        // (dspace/conf/spring/api/identifier-service.xml) the new created item
        // gets automatically a DOI. We remove this DOI as it can make problems
        // with the tests.
        provider.delete(context, item);
        
        List<MetadataValue> metadata = itemService.getMetadata(item,
                DOIIdentifierProvider.MD_SCHEMA, 
                DOIIdentifierProvider.DOI_ELEMENT,
                DOIIdentifierProvider.DOI_QUALIFIER,
                null);
        List<String> remainder = new ArrayList<String>();

        for (MetadataValue id : metadata) {
            if (!id.getValue().startsWith(DOI.RESOLVER))
            {
                remainder.add(id.getValue());
            }
        }

        itemService.clearMetadata(context, item,
                DOIIdentifierProvider.MD_SCHEMA,
                DOIIdentifierProvider.DOI_ELEMENT,
                DOIIdentifierProvider.DOI_QUALIFIER,
                null);
        itemService.addMetadata(context, item, DOIIdentifierProvider.MD_SCHEMA,
                DOIIdentifierProvider.DOI_ELEMENT,
                DOIIdentifierProvider.DOI_QUALIFIER,
                null,
                remainder);
        
        itemService.update(context, item);
        //we need to commit the changes so we don't block the table for testing
        context.restoreAuthSystemState();

        return item;
    }
    
    public String createDOI(Item item, Integer status, boolean metadata)
            throws SQLException, IdentifierException, AuthorizeException
    {
        return this.createDOI(item, status, metadata, null);
    }
    
    /**
     * Create a DOI to an item.
     * @param item Item the DOI should be created for.
     * @param status The status of the DOI.
     * @param metadata Whether the DOI should be included in the metadata of the item.
     * @param doi The doi or null if we should generate one.
     * @return the DOI
     * @throws SQLException if database error
     */
    public String createDOI(Item item, Integer status, boolean metadata, String doi)
            throws SQLException, IdentifierException, AuthorizeException
    {
        context.turnOffAuthorisationSystem();
        // we need some random data. UUIDs would be bloated here
        Random random = new Random();
        if (null == doi)
        {
            doi = DOI.SCHEME + PREFIX + "/" + NAMESPACE_SEPARATOR 
                    + Long.toHexString(new Date().getTime()) + "-"
                    + random.nextInt(997);
        }
        
        DOI doiRow = doiService.create(context);
        doiRow.setDoi(doi.substring(DOI.SCHEME.length()));
        doiRow.setDSpaceObject(item);
        doiRow.setStatus(status);
        doiService.update(context, doiRow);
        
        if (metadata)
        {
            itemService.addMetadata(context, item, DOIIdentifierProvider.MD_SCHEMA,
                    DOIIdentifierProvider.DOI_ELEMENT,
                    DOIIdentifierProvider.DOI_QUALIFIER,
                    null,
                    doiService.DOIToExternalForm(doi));
            itemService.update(context, item);
        }
        
        //we need to commit the changes so we don't block the table for testing
        context.restoreAuthSystemState();
        return doi;
    }
    
    /**
     * Test of supports method, of class DataCiteIdentifierProvider.
     */
    @Test
    public void testSupports_Class()
    {        
        Class<? extends Identifier> identifier = DOI.class;
        assertTrue("DOI should be supported", provider.supports(identifier));
    }
    
    @Test
    public void testSupports_valid_String()
    {
        String[] validDOIs = new String[]
        {
            "10.5072/123abc-lkj/kljl",
            PREFIX + "/" + NAMESPACE_SEPARATOR + "lkjljasd1234",
            DOI.SCHEME + "10.5072/123abc-lkj/kljl",
            "http://dx.doi.org/10.5072/123abc-lkj/kljl",
            DOI.RESOLVER + "/10.5072/123abc-lkj/kljl"
        };
        
        for (String doi : validDOIs)
        {
            assertTrue("DOI should be supported", provider.supports(doi));
        }
    }
    
    @Test
    public void testDoes_not_support_invalid_String()
    {
        String[] invalidDOIs = new String[]
        {
            "11.5072/123abc-lkj/kljl",
            "http://hdl.handle.net/handle/10.5072/123abc-lkj/kljl",
            "",
            null
        };
        
        for (String notADoi : invalidDOIs)
        {
            assertFalse("Invalid DOIs shouldn't be supported",
                    provider.supports(notADoi));
        }
    }
    
    @Test
    public void testStore_DOI_as_item_metadata()
            throws SQLException, AuthorizeException, IOException, IdentifierException, IllegalAccessException, WorkflowException
    {
        Item item = newItem();
        String doi = DOI.SCHEME + PREFIX + "/" + NAMESPACE_SEPARATOR 
                + Long.toHexString(new Date().getTime());
        context.turnOffAuthorisationSystem();
        provider.saveDOIToObject(context, item, doi);
        context.restoreAuthSystemState();
        
        List<MetadataValue> metadata = itemService.getMetadata(item, DOIIdentifierProvider.MD_SCHEMA,
                DOIIdentifierProvider.DOI_ELEMENT,
                DOIIdentifierProvider.DOI_QUALIFIER,
                null);
        boolean result = false;
        for (MetadataValue id : metadata)
        {
            if (id.getValue().equals(doiService.DOIToExternalForm(doi)))
            {
                result = true;
            }
        }
        assertTrue("Cannot store DOI as item metadata value.", result);
    }
    
    @Test
    public void testGet_DOI_out_of_item_metadata()
            throws SQLException, AuthorizeException, IOException, IdentifierException, IllegalAccessException, WorkflowException
    {
        Item item = newItem();
        String doi = DOI.SCHEME + PREFIX + "/" + NAMESPACE_SEPARATOR 
                + Long.toHexString(new Date().getTime());

        context.turnOffAuthorisationSystem();
        itemService.addMetadata(context, item, DOIIdentifierProvider.MD_SCHEMA,
                DOIIdentifierProvider.DOI_ELEMENT,
                DOIIdentifierProvider.DOI_QUALIFIER,
                null,
                doiService.DOIToExternalForm(doi));
        itemService.update(context, item);
        context.restoreAuthSystemState();

        assertTrue("Failed to recognize DOI in item metadata.", 
                doi.equals(provider.getDOIOutOfObject(item)));
    }

    @Test
    public void testRemove_DOI_from_item_metadata()
            throws SQLException, AuthorizeException, IOException, IdentifierException, WorkflowException, IllegalAccessException
    {
        Item item = newItem();
        String doi = DOI.SCHEME + PREFIX + "/" + NAMESPACE_SEPARATOR 
                + Long.toHexString(new Date().getTime());

        context.turnOffAuthorisationSystem();
        itemService.addMetadata(context, item, DOIIdentifierProvider.MD_SCHEMA,
                DOIIdentifierProvider.DOI_ELEMENT,
                DOIIdentifierProvider.DOI_QUALIFIER,
                null,
                doiService.DOIToExternalForm(doi));
        itemService.update(context, item);
        
        provider.removeDOIFromObject(context, item, doi);
        context.restoreAuthSystemState();
        
        List<MetadataValue> metadata = itemService.getMetadata(item, DOIIdentifierProvider.MD_SCHEMA,
                DOIIdentifierProvider.DOI_ELEMENT,
                DOIIdentifierProvider.DOI_QUALIFIER,
                null);
        boolean foundDOI = false;
        for (MetadataValue id : metadata)
        {
            if (id.getValue().equals(doiService.DOIToExternalForm(doi)))
            {
                foundDOI = true;
            }
        }
        assertFalse("Cannot remove DOI from item metadata.", foundDOI);
    }
    
    @Test
    public void testGet_DOI_by_DSpaceObject()
            throws SQLException, AuthorizeException, IOException,
            IllegalArgumentException, IdentifierException, WorkflowException, IllegalAccessException
    {
        Item item = newItem();
        String doi = this.createDOI(item, DOIIdentifierProvider.IS_REGISTERED, false);
        
        String retrievedDOI = provider.getDOIByObject(context, item);
        
        assertNotNull("Failed to load DOI by DSpaceObject.", retrievedDOI);
        assertTrue("Loaded wrong DOI by DSpaceObject.", doi.equals(retrievedDOI));
    }
    
    @Test
    public void testGet_DOI_lookup()
            throws SQLException, AuthorizeException, IOException,
            IllegalArgumentException, IdentifierException, WorkflowException, IllegalAccessException
    {
        Item item = newItem();
        String doi = this.createDOI(item, DOIIdentifierProvider.IS_REGISTERED, false);
        
        String retrievedDOI = provider.lookup(context, (DSpaceObject) item);
        
        assertNotNull("Failed to loookup doi.", retrievedDOI);
        assertTrue("Loaded wrong DOI on lookup.", doi.equals(retrievedDOI));
    }
    
    @Test
    public void testGet_DSpaceObject_by_DOI()
            throws SQLException, AuthorizeException, IOException,
            IllegalArgumentException, IdentifierException, WorkflowException, IllegalAccessException
    {
        Item item = newItem();
        String doi = this.createDOI(item, DOIIdentifierProvider.IS_REGISTERED, false);
        
        DSpaceObject dso = provider.getObjectByDOI(context, doi);
        
        assertNotNull("Failed to load DSpaceObject by DOI.", dso);
        if (item.getType() != dso.getType() || item.getID() != dso.getID())
        {
            fail("Object loaded by DOI was another object then expected!");
        }
    }

    @Test
    public void testResolve_DOI()
            throws SQLException, AuthorizeException, IOException,
            IllegalArgumentException, IdentifierException, WorkflowException, IllegalAccessException
    {
        Item item = newItem();
        String doi = this.createDOI(item, DOIIdentifierProvider.IS_REGISTERED, false);
        
        DSpaceObject dso = provider.resolve(context, doi);
        
        assertNotNull("Failed to resolve DOI.", dso);
        if (item.getType() != dso.getType() || item.getID() != dso.getID())
        {
            fail("Object return by DOI lookup was another object then expected!");
        }
    }

    /*
     * The following test seems a bit silly, but it was helpful to debug some
     * problems while deleting DOIs.
     */
    @Test
    public void testRemove_two_DOIs_from_item_metadata()
            throws SQLException, AuthorizeException, IOException, IdentifierException, WorkflowException, IllegalAccessException
    {
        // add two DOIs.
        Item item = newItem();
        String doi1 = this.createDOI(item, DOIIdentifierProvider.IS_REGISTERED, true);
        String doi2 = this.createDOI(item, DOIIdentifierProvider.IS_REGISTERED, true);
        
        // remove one of it
        context.turnOffAuthorisationSystem();
        provider.removeDOIFromObject(context, item, doi1);
        context.restoreAuthSystemState();

        // assure that the right one was removed
        List<MetadataValue> metadata = itemService.getMetadata(item, DOIIdentifierProvider.MD_SCHEMA,
                DOIIdentifierProvider.DOI_ELEMENT,
                DOIIdentifierProvider.DOI_QUALIFIER,
                null);
        boolean foundDOI1 = false;
        boolean foundDOI2 = false;
        for (MetadataValue id : metadata)
        {
            if (id.getValue().equals(doiService.DOIToExternalForm(doi1)))
            {
                foundDOI1 = true;
            }
            if (id.getValue().equals(doiService.DOIToExternalForm(doi2)))
            {
                foundDOI2 = true;
            }

        }
        assertFalse("Cannot remove DOI from item metadata.", foundDOI1);
        assertTrue("Removed wrong DOI from item metadata.", foundDOI2);
        
        // remove the otherone as well.
        context.turnOffAuthorisationSystem();
        provider.removeDOIFromObject(context, item, doi2);
        context.restoreAuthSystemState();
        
        // check it
        metadata = itemService.getMetadata(item, DOIIdentifierProvider.MD_SCHEMA,
                DOIIdentifierProvider.DOI_ELEMENT,
                DOIIdentifierProvider.DOI_QUALIFIER,
                null);
        foundDOI1 = false;
        foundDOI2 = false;
        for (MetadataValue id : metadata)
        {
            if (id.getValue().equals(doiService.DOIToExternalForm(doi1)))
            {
                foundDOI1 = true;
            }
            if (id.getValue().equals(doiService.DOIToExternalForm(doi2)))
            {
                foundDOI2 = true;
            }

        }
        assertFalse("Cannot remove DOI from item metadata.", foundDOI1);
        assertFalse("Cannot remove DOI from item metadata.", foundDOI2);
    }
    
    @Test
    public void testMintDOI() throws SQLException, AuthorizeException, IOException, IllegalAccessException, IdentifierException, WorkflowException
    {
        Item item = newItem();
        String doi = null;
        try
        {
            // get a DOI:
            doi = provider.mint(context, item);
        }
        catch(IdentifierException e)
        {
            e.printStackTrace();
            fail("Got an IdentifierException: " + e.getMessage());
        }
        
        assertNotNull("Minted DOI is null!", doi);
        assertFalse("Minted DOI is empty!", doi.isEmpty());
        
        try
        {
            doiService.formatIdentifier(doi);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            fail("Minted an unrecognizable DOI: " + e.getMessage());
        }
    }
    
    @Test
    public void testMint_returns_existing_DOI()
            throws SQLException, AuthorizeException, IOException, IdentifierException, WorkflowException, IllegalAccessException
    {
        Item item = newItem();
        String doi = this.createDOI(item, null, true);
        
        String retrievedDOI = provider.mint(context, item);

        assertNotNull("Minted DOI is null?!", retrievedDOI);
        assertEquals("Mint did not returned an existing DOI!", doi, retrievedDOI);
    }

    @Test
    public void testReserve_DOI()
            throws SQLException, SQLException, AuthorizeException, IOException,
            IdentifierException, WorkflowException, IllegalAccessException
    {
        Item item = newItem();
        String doi = this.createDOI(item, null, true);
        
        provider.reserve(context, item, doi);
        
        DOI doiRow = doiService.findByDoi(context, doi.substring(DOI.SCHEME.length()));
        assumeNotNull(doiRow);
        
        assertTrue("Reservation of DOI did not set the corret DOI status.",
                DOIIdentifierProvider.TO_BE_RESERVED.equals(doiRow.getStatus()));
    }
    
    @Test
    public void testRegister_unreserved_DOI()
            throws SQLException, SQLException, AuthorizeException, IOException,
            IdentifierException, WorkflowException, IllegalAccessException
    {
        Item item = newItem();
        String doi = this.createDOI(item, null, true);
        
        provider.register(context, item, doi);
        
        DOI doiRow = doiService.findByDoi(context, doi.substring(DOI.SCHEME.length()));
        assumeNotNull(doiRow);
        
        assertTrue("Registration of DOI did not set the corret DOI status.",
                DOIIdentifierProvider.TO_BE_REGISTERED.equals(doiRow.getStatus()));
    }

    @Test
    public void testRegister_reserved_DOI()
            throws SQLException, SQLException, AuthorizeException, IOException,
            IdentifierException, WorkflowException, IllegalAccessException
    {
        Item item = newItem();
        String doi = this.createDOI(item, DOIIdentifierProvider.IS_RESERVED, true);
        
        provider.register(context, item, doi);
        
        DOI doiRow = doiService.findByDoi(context, doi.substring(DOI.SCHEME.length()));
        assumeNotNull(doiRow);
        
        assertTrue("Registration of DOI did not set the corret DOI status.",
                DOIIdentifierProvider.TO_BE_REGISTERED.equals(doiRow.getStatus()));
    }
    
    @Test
    public void testCreate_and_Register_DOI()
            throws SQLException, SQLException, AuthorizeException, IOException,
            IdentifierException, WorkflowException, IllegalAccessException
    {
        Item item = newItem();
        
        String doi = provider.register(context, item);
        
        // we want the created DOI to be returned in the following format:
        // doi:10.<prefix>/<suffix>.
        String formated_doi = doiService.formatIdentifier(doi);
        assertTrue("DOI was not in the expected format!", doi.equals(formated_doi));
        
        DOI doiRow = doiService.findByDoi(context, doi.substring(DOI.SCHEME.length()));
        assertNotNull("Created DOI was not stored in database.", doiRow);
        
        assertTrue("Registration of DOI did not set the corret DOI status.",
                DOIIdentifierProvider.TO_BE_REGISTERED.equals(doiRow.getStatus()));
    }
    
    @Test
    public void testDelete_specified_DOI()
            throws SQLException, AuthorizeException, IOException, IdentifierException, WorkflowException, IllegalAccessException
    {
        Item item = newItem();
        String doi1 = this.createDOI(item, DOIIdentifierProvider.IS_REGISTERED, true);
        String doi2 = this.createDOI(item, DOIIdentifierProvider.IS_REGISTERED, true);
        
        // remove one of it
        context.turnOffAuthorisationSystem();
        provider.delete(context, item, doi1);
        context.restoreAuthSystemState();

        // assure that the right one was removed
        List<MetadataValue> metadata = itemService.getMetadata(item, DOIIdentifierProvider.MD_SCHEMA,
                DOIIdentifierProvider.DOI_ELEMENT,
                DOIIdentifierProvider.DOI_QUALIFIER,
                null);
        boolean foundDOI1 = false;
        boolean foundDOI2 = false;
        for (MetadataValue id : metadata)
        {
            if (id.getValue().equals(doiService.DOIToExternalForm(doi1)))
            {
                foundDOI1 = true;
            }
            if (id.getValue().equals(doiService.DOIToExternalForm(doi2)))
            {
                foundDOI2 = true;
            }
        }
        assertFalse("Cannot remove DOI from item metadata.", foundDOI1);
        assertTrue("Removed wrong DOI from item metadata.", foundDOI2);
        
        DOI doiRow1 = doiService.findByDoi(context, doi1.substring(DOI.SCHEME.length()));
        assumeNotNull(doiRow1);
        assertTrue("Status of deleted DOI was not set correctly.",
                DOIIdentifierProvider.TO_BE_DELETED.equals(doiRow1.getStatus()));

        DOI doiRow2 = doiService.findByDoi(context, doi2.substring(DOI.SCHEME.length()));
        assumeNotNull(doiRow2);
        assertTrue("While deleting a DOI the status of another changed.",
                DOIIdentifierProvider.IS_REGISTERED.equals(doiRow2.getStatus()));
    }
    
    @Test
    public void testDelete_all_DOIs()
            throws SQLException, AuthorizeException, IOException, IdentifierException, IllegalAccessException, WorkflowException {
        Item item = newItem();
        String doi1 = this.createDOI(item, DOIIdentifierProvider.IS_REGISTERED, true);
        String doi2 = this.createDOI(item, DOIIdentifierProvider.IS_REGISTERED, true);
        
        // remove one of it
        context.turnOffAuthorisationSystem();
        provider.delete(context, item);
        context.restoreAuthSystemState();

        // assure that the right one was removed
        List<MetadataValue> metadata = itemService.getMetadata(item, DOIIdentifierProvider.MD_SCHEMA,
                DOIIdentifierProvider.DOI_ELEMENT,
                DOIIdentifierProvider.DOI_QUALIFIER,
                null);
        boolean foundDOI1 = false;
        boolean foundDOI2 = false;
        for (MetadataValue id : metadata)
        {
            if (id.getValue().equals(doiService.DOIToExternalForm(doi1)))
            {
                foundDOI1 = true;
            }
            if (id.getValue().equals(doiService.DOIToExternalForm(doi2)))
            {
                foundDOI2 = true;
            }
        }
        assertFalse("Cannot remove DOI from item metadata.", foundDOI1);
        assertFalse("Did not removed all DOIs from item metadata.", foundDOI2);
        
        DOI doiRow1 = doiService.findByDoi(context, doi1.substring(DOI.SCHEME.length()));
        assumeNotNull(doiRow1);
        assertTrue("Status of deleted DOI was not set correctly.",
                DOIIdentifierProvider.TO_BE_DELETED.equals(doiRow1.getStatus()));

        DOI doiRow2 = doiService.findByDoi(context, doi1.substring(DOI.SCHEME.length()));
        assumeNotNull(doiRow2);
        assertTrue("Did not set the status of all deleted DOIs as expected.",
                DOIIdentifierProvider.TO_BE_DELETED.equals(doiRow2.getStatus()));
    }

    
    // test the following methods using the MockDOIConnector.
    // updateMetadataOnline
    // registerOnline
    // reserveOnline
    
}