package org.gbif.ipt.action.manage; import org.gbif.api.model.common.DOI; import org.gbif.doi.service.datacite.DataCiteService; import org.gbif.ipt.config.AppConfig; import org.gbif.ipt.config.Constants; import org.gbif.ipt.config.DataDir; import org.gbif.ipt.model.Organisation; import org.gbif.ipt.model.Resource; import org.gbif.ipt.model.User; import org.gbif.ipt.model.VersionHistory; import org.gbif.ipt.model.voc.DOIRegistrationAgency; import org.gbif.ipt.model.voc.IdentifierStatus; import org.gbif.ipt.model.voc.PublicationStatus; import org.gbif.ipt.service.AlreadyExistingException; import org.gbif.ipt.service.ImportException; import org.gbif.ipt.service.admin.ExtensionManager; import org.gbif.ipt.service.admin.RegistrationManager; import org.gbif.ipt.service.admin.UserAccountManager; import org.gbif.ipt.service.admin.VocabulariesManager; import org.gbif.ipt.service.manage.ResourceManager; import org.gbif.ipt.struts2.SimpleTextProvider; import org.gbif.ipt.task.GenerateDwcaFactory; import org.gbif.ipt.utils.DOIUtils; import org.gbif.metadata.eml.Citation; import org.gbif.metadata.eml.Eml; import org.gbif.metadata.eml.EmlWriter; import java.io.File; import java.io.IOException; import java.math.BigDecimal; import java.util.Date; import java.util.UUID; import javax.xml.parsers.ParserConfigurationException; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; import freemarker.template.TemplateException; import org.junit.Before; import org.junit.Test; import org.xml.sax.SAXException; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class OverviewActionTest { private OverviewAction action; private File emlFile; @Before public void setup() throws IOException, ParserConfigurationException, SAXException, AlreadyExistingException, ImportException { ResourceManager mockResourceManager = mock(ResourceManager.class); ListMultimap<String, Date> processFailures = ArrayListMultimap.create(); processFailures.put("res1", new Date()); processFailures.put("res1", new Date()); when(mockResourceManager.getProcessFailures()).thenReturn(processFailures); // mock returning eml-1.0.xml emlFile = File.createTempFile("eml-1.0", ".xml"); AppConfig mockCfg = mock(AppConfig.class); DataDir mockDataDir = mock(DataDir.class); when(mockDataDir.resourceEmlFile(anyString(), any(BigDecimal.class))).thenReturn(emlFile); when(mockCfg.getDataDir()).thenReturn(mockDataDir); // mock action action = new OverviewAction(mock(SimpleTextProvider.class), mockCfg, mock(RegistrationManager.class), mockResourceManager, mock(UserAccountManager.class), mock(ExtensionManager.class), mock(VocabulariesManager.class), mock(GenerateDwcaFactory.class)); } @Test public void testLogProcessFailures() { Resource resource = new Resource(); resource.setShortname("res1"); resource.setTitle("Mammals"); action.logProcessFailures(resource); resource.setShortname("res2"); action.logProcessFailures(resource); } @Test public void testFindExistingDoi() { Resource resource = new Resource(); Eml eml = new Eml(); resource.setEml(eml); Citation citation1 = new Citation("Text", "doi:10.1594/J67TGE"); eml.setCitation(citation1); DOI identifier = action.findExistingDoi(resource); assertEquals("10.1594/j67tge", identifier.getDoiName()); Citation citation2 = new Citation("Text", "http://dx.doi.org/10.8894/887TGE"); eml.setCitation(citation2); identifier = action.findExistingDoi(resource); assertEquals("10.8894/887tge", identifier.getDoiName()); } /** * CC0 is a GBIF-supported license. */ @Test public void testIsLastPublishedVersionAssignedGBIFSupportedLicense() throws IOException, TemplateException { Resource r = new Resource(); // CCO r.getEml().setIntellectualRights( "This work is licensed under <a href=\"http://creativecommons.org/publicdomain/zero/1.0/legalcode\">Creative Commons CCZero (CC0) 1.0 License</a>."); assertEquals("http://creativecommons.org/publicdomain/zero/1.0/legalcode", r.getEml().parseLicenseUrl()); assertTrue(r.isAssignedGBIFSupportedLicense()); EmlWriter.writeEmlFile(emlFile, r.getEml()); User user = new User(); user.setEmail("jsmith@gbif.org"); VersionHistory vh = new VersionHistory(new BigDecimal("1.0"), new Date(), PublicationStatus.PRIVATE); r.addVersionHistory(vh); assertTrue(action.isLastPublishedVersionAssignedGBIFSupportedLicense(r)); } @Test public void testGetLastPublishedVersionAssignedLicense() throws IOException, TemplateException { Resource r = new Resource(); // CCO r.getEml().setIntellectualRights( "This work is licensed under <a href=\"http://creativecommons.org/publicdomain/zero/1.0/legalcode\">Creative Commons CCZero (CC0) 1.0 License</a>."); assertEquals("http://creativecommons.org/publicdomain/zero/1.0/legalcode", r.getEml().parseLicenseUrl()); assertTrue(r.isAssignedGBIFSupportedLicense()); EmlWriter.writeEmlFile(emlFile, r.getEml()); User user = new User(); user.setEmail("jsmith@gbif.org"); VersionHistory vh = new VersionHistory(new BigDecimal("1.0"), new Date(), PublicationStatus.PRIVATE); r.addVersionHistory(vh); assertEquals("http://creativecommons.org/publicdomain/zero/1.0/legalcode", action.getLastPublishedVersionAssignedLicense(r)); } /** * ODbl is not a GBIF-supported license - test registration fails when last published version of resource is assigned * ODbl. */ @Test public void testRegisterResourceNotGBIFSupportedLicense() throws Exception { Resource r = new Resource(); // ODbl r.getEml().setIntellectualRights( "This work is licensed under a <a href=\"http://opendatacommons.org/licenses/odbl/1.0\">Open Data Commons Open Database License (ODbL) 1.0</a>"); assertEquals("http://opendatacommons.org/licenses/odbl/1.0", r.getEml().parseLicenseUrl()); assertFalse(r.isAssignedGBIFSupportedLicense()); EmlWriter.writeEmlFile(emlFile, r.getEml()); User user = new User(); user.setEmail("jsmith@gbif.org"); VersionHistory vh = new VersionHistory(new BigDecimal("1.0"), new Date(), PublicationStatus.PRIVATE); r.addVersionHistory(vh); action.setResource(r); assertEquals("input", action.registerResource()); assertEquals(1, action.getActionErrors().size()); } /** * ODbl is not a GBIF-supported license - test publishing fails when last current version of resource is assigned * ODbl. */ @Test public void testPublishResourceNotGBIFSupportedLicense() throws Exception { Resource r = new Resource(); r.getEml().setIntellectualRights( "This work is licensed under a <a href=\"http://opendatacommons.org/licenses/odbl/1.0\">Open Data Commons Open Database License (ODbL) 1.0</a>"); r.setKey(UUID.randomUUID()); r.setStatus(PublicationStatus.REGISTERED); action.setResource(r); action.setPublish("true"); assertEquals("input", action.publish()); assertEquals(1, action.getActionErrors().size()); } /** * If a public resource has a DOI - publishing will trigger a DOI operation (register or update). This test ensures * that if a DOI service is not configured, publishing fails. */ @Test public void testPublishPublicResourceWithDOIButNoDOIService() throws Exception { Resource r = new Resource(); r.setDoi(DOIUtils.mintDOI(DOIRegistrationAgency.DATACITE, Constants.TEST_DOI_PREFIX)); r.setStatus(PublicationStatus.PUBLIC); action.setResource(r); action.setPublish("true"); assertNull(action.getOrganisationWithPrimaryDoiAccount()); assertEquals("input", action.publish()); assertEquals(1, action.getActionErrors().size()); } /** * Test trying to delete a resource that is already deleted - redirects back to manage page showing warning. */ @Test public void testDeleteDeletedResource() throws Exception { Resource r = new Resource(); r.setStatus(PublicationStatus.DELETED); action.setResource(r); action.setDelete("true"); assertEquals("input", action.delete()); assertEquals(1, action.getActionWarnings().size()); } /** * If a public resource has a DOI - deleting will trigger a DOI operation (delete reserved DOI or deactivate * registered DOI. This test ensures that if a DOI service is not configured, deletion fails. */ @Test public void testDeletePublicResourceWithDOIButNoDOIService() throws Exception { Resource r = new Resource(); r.setDoi(DOIUtils.mintDOI(DOIRegistrationAgency.DATACITE, Constants.TEST_DOI_PREFIX)); r.setStatus(PublicationStatus.PUBLIC); action.setResource(r); action.setDelete("true"); assertNull(action.getOrganisationWithPrimaryDoiAccount()); assertEquals("input", action.delete()); assertEquals(1, action.getActionErrors().size()); } @Test public void testUndeleteNonDeletedResource() { Resource r = new Resource(); r.setDoi(DOIUtils.mintDOI(DOIRegistrationAgency.DATACITE, Constants.TEST_DOI_PREFIX)); r.setStatus(PublicationStatus.PUBLIC); action.setResource(r); action.setUndelete("true"); assertEquals("input", action.undelete()); assertEquals(1, action.getActionWarnings().size()); } @Test public void testUndeleteButNoDOIAssigned() { Resource r = new Resource(); r.setStatus(PublicationStatus.DELETED); action.setResource(r); action.setUndelete("true"); assertEquals("input", action.undelete()); assertEquals(1, action.getActionWarnings().size()); } @Test public void testUndeleteButNoDOIService() { Resource r = new Resource(); DOI doiToUndelete = DOIUtils.mintDOI(DOIRegistrationAgency.DATACITE, Constants.TEST_DOI_PREFIX); BigDecimal versionToUndelete = new BigDecimal("1.0"); VersionHistory vh = new VersionHistory(versionToUndelete, new Date(), PublicationStatus.PUBLIC); vh.setDoi(doiToUndelete); vh.setStatus(IdentifierStatus.PUBLIC); r.addVersionHistory(vh); // resource deleted! r.setStatus(PublicationStatus.DELETED); action.setResource(r); action.setUndelete("true"); assertEquals("input", action.undelete()); assertEquals(1, action.getActionErrors().size()); } @Test public void testUndeleteButResourceHasNoOrganisation() { Resource r = new Resource(); DOI doiToUndelete = DOIUtils.mintDOI(DOIRegistrationAgency.DATACITE, Constants.TEST_DOI_PREFIX); BigDecimal versionToUndelete = new BigDecimal("1.0"); VersionHistory vh = new VersionHistory(versionToUndelete, new Date(), PublicationStatus.PUBLIC); vh.setDoi(doiToUndelete); vh.setStatus(IdentifierStatus.PUBLIC); r.addVersionHistory(vh); // resource deleted! r.setStatus(PublicationStatus.DELETED); // mock organisation missing r.setOrganisation(null); action.setResource(r); action.setUndelete("true"); assertEquals("input", action.undelete()); assertEquals(1, action.getActionErrors().size()); } @Test public void testUndeleteButResourceOrganisationNoLongerInIPT() { Resource r = new Resource(); DOI doiToUndelete = DOIUtils.mintDOI(DOIRegistrationAgency.DATACITE, Constants.TEST_DOI_PREFIX); BigDecimal versionToUndelete = new BigDecimal("1.0"); VersionHistory vh = new VersionHistory(versionToUndelete, new Date(), PublicationStatus.PUBLIC); vh.setDoi(doiToUndelete); vh.setStatus(IdentifierStatus.PUBLIC); r.addVersionHistory(vh); // resource deleted! r.setStatus(PublicationStatus.DELETED); // mock organisation that is not associated to IPT Organisation org = new Organisation(); org.setKey(UUID.randomUUID().toString()); r.setOrganisation(org); // mock RegistrationManager returning mock DoiService RegistrationManager mockRegistrationManager = mock(RegistrationManager.class); DataCiteService mockDataCiteService = mock(DataCiteService.class); when(mockRegistrationManager.getDoiService()).thenReturn(mockDataCiteService); // mock action action = new OverviewAction(mock(SimpleTextProvider.class), mock(AppConfig.class), mockRegistrationManager, mock(ResourceManager.class), mock(UserAccountManager.class), mock(ExtensionManager.class), mock(VocabulariesManager.class), mock(GenerateDwcaFactory.class)); action.setResource(r); action.setUndelete("true"); assertEquals("input", action.undelete()); assertEquals(1, action.getActionErrors().size()); } @Test public void testUndeleteButResourceDOIPrefixNotMatchingDOIAccountActivatedInIPT() { Resource r = new Resource(); DOI doiToUndelete = DOIUtils.mintDOI(DOIRegistrationAgency.DATACITE, Constants.TEST_DOI_PREFIX); BigDecimal versionToUndelete = new BigDecimal("1.0"); VersionHistory vh = new VersionHistory(versionToUndelete, new Date(), PublicationStatus.PUBLIC); vh.setDoi(doiToUndelete); vh.setStatus(IdentifierStatus.PUBLIC); r.addVersionHistory(vh); // resource deleted! r.setStatus(PublicationStatus.DELETED); // mock organisation that is not associated to IPT Organisation resourceOrganisation = new Organisation(); resourceOrganisation.setKey(UUID.randomUUID().toString()); r.setOrganisation(resourceOrganisation); // mock RegistrationManager returning mock DoiService RegistrationManager mockRegistrationManager = mock(RegistrationManager.class); DataCiteService mockDataCiteService = mock(DataCiteService.class); when(mockRegistrationManager.getDoiService()).thenReturn(mockDataCiteService); // mock RegistrationManager returning resource organisation when(mockRegistrationManager.get(any(UUID.class))).thenReturn(resourceOrganisation); // mock RegistrationManager returning organisation with DOI agency account activated Organisation doiAccoutActivated = new Organisation(); doiAccoutActivated.setKey(UUID.randomUUID().toString()); doiAccoutActivated.setDoiPrefix("10.5000"); // different to resource doi that has 10.5072 (DataCite test prefix) when(mockRegistrationManager.findPrimaryDoiAgencyAccount()).thenReturn(doiAccoutActivated); // mock action action = new OverviewAction(mock(SimpleTextProvider.class), mock(AppConfig.class), mockRegistrationManager, mock(ResourceManager.class), mock(UserAccountManager.class), mock(ExtensionManager.class), mock(VocabulariesManager.class), mock(GenerateDwcaFactory.class)); action.setResource(r); action.setUndelete("true"); assertEquals("input", action.undelete()); assertEquals(1, action.getActionErrors().size()); } }