/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.integration.blackbox.api.v2.rc2.tests; import static org.hamcrest.core.IsNot.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import java.net.URISyntaxException; import javax.annotation.Resource; import javax.ws.rs.core.Response; import org.codehaus.jettison.json.JSONException; import org.junit.Test; import org.junit.runner.RunWith; import org.orcid.integration.blackbox.api.v2.rc2.BlackBoxBaseRC2; import org.orcid.integration.blackbox.api.v2.rc2.MemberV2ApiClientImpl; import org.orcid.jaxb.model.common_rc2.Title; import org.orcid.jaxb.model.common_rc2.Url; import org.orcid.jaxb.model.common_rc2.Visibility; import org.orcid.jaxb.model.error_rc2.OrcidError; import org.orcid.jaxb.model.message.ScopePathType; import org.orcid.jaxb.model.record.summary_rc2.ActivitiesSummary; import org.orcid.jaxb.model.record.summary_rc2.WorkGroup; import org.orcid.jaxb.model.record.summary_rc2.WorkSummary; import org.orcid.jaxb.model.record_rc1.WorkExternalIdentifierType; import org.orcid.jaxb.model.record_rc2.CitationType; import org.orcid.jaxb.model.record_rc2.ExternalID; import org.orcid.jaxb.model.record_rc2.Relationship; import org.orcid.jaxb.model.record_rc2.Work; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.sun.jersey.api.client.ClientResponse; /** * * @author Angel Montenegro * */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:test-context.xml" }) public class WorksTest extends BlackBoxBaseRC2 { @Resource(name = "memberV2ApiClient_rc2") private MemberV2ApiClientImpl memberV2ApiClient; @Test public void createViewUpdateAndDeleteWork() throws JSONException, InterruptedException, URISyntaxException { changeDefaultUserVisibility(webDriver, org.orcid.jaxb.model.common_v2.Visibility.PUBLIC); long time = System.currentTimeMillis(); Work workToCreate = (Work) unmarshallFromPath("/record_2.0_rc2/samples/work-2.0_rc2.xml", Work.class); workToCreate.setPutCode(null); workToCreate.getExternalIdentifiers().getExternalIdentifier().clear(); ExternalID wExtId = new ExternalID(); wExtId.setValue("Work Id " + time); wExtId.setType("agr"); wExtId.setRelationship(Relationship.SELF); wExtId.setUrl(new Url("http://test.orcid.org/" + time)); workToCreate.getExternalIdentifiers().getExternalIdentifier().add(wExtId); String accessToken = getAccessToken(); ClientResponse postResponse = memberV2ApiClient.createWorkXml(this.getUser1OrcidId(), workToCreate, accessToken); assertNotNull(postResponse); assertEquals(Response.Status.CREATED.getStatusCode(), postResponse.getStatus()); String locationPath = postResponse.getLocation().getPath(); assertTrue("Location header path should match pattern, but was " + locationPath, locationPath.matches(".*/v2.0_rc2/" + this.getUser1OrcidId() + "/work/\\d+")); ClientResponse getResponse = memberV2ApiClient.viewLocationXml(postResponse.getLocation(), accessToken); assertEquals(Response.Status.OK.getStatusCode(), getResponse.getStatus()); Work gotWork = getResponse.getEntity(Work.class); assertEquals("common:title", gotWork.getWorkTitle().getTitle().getContent()); assertEquals("work:citation", gotWork.getWorkCitation().getCitation()); assertEquals(CitationType.FORMATTED_UNSPECIFIED, gotWork.getWorkCitation().getWorkCitationType()); gotWork.getWorkTitle().getTitle().setContent("updated title"); //Save the original visibility Visibility originalVisibility = gotWork.getVisibility(); Visibility updatedVisibility = Visibility.PRIVATE.equals(originalVisibility) ? Visibility.LIMITED : Visibility.PRIVATE; //Verify you cant update the visibility gotWork.setVisibility(updatedVisibility); ClientResponse putResponse = memberV2ApiClient.updateLocationXml(postResponse.getLocation(), accessToken, gotWork); assertEquals(Response.Status.FORBIDDEN.getStatusCode(), putResponse.getStatus()); OrcidError error = putResponse.getEntity(OrcidError.class); assertNotNull(error); assertEquals(Integer.valueOf(9035), error.getErrorCode()); //Set the visibility again to the initial one gotWork.setVisibility(originalVisibility); putResponse = memberV2ApiClient.updateLocationXml(postResponse.getLocation(), accessToken, gotWork); assertEquals(Response.Status.OK.getStatusCode(), putResponse.getStatus()); ClientResponse getAfterUpdateResponse = memberV2ApiClient.viewLocationXml(postResponse.getLocation(), accessToken); assertEquals(Response.Status.OK.getStatusCode(), getAfterUpdateResponse.getStatus()); Work gotAfterUpdateWork = getAfterUpdateResponse.getEntity(Work.class); assertEquals("updated title", gotAfterUpdateWork.getWorkTitle().getTitle().getContent()); assertEquals("work:citation", gotAfterUpdateWork.getWorkCitation().getCitation()); assertEquals(CitationType.FORMATTED_UNSPECIFIED, gotAfterUpdateWork.getWorkCitation().getWorkCitationType()); ClientResponse deleteResponse = memberV2ApiClient.deleteWorkXml(this.getUser1OrcidId(), gotWork.getPutCode(), accessToken); assertEquals(Response.Status.NO_CONTENT.getStatusCode(), deleteResponse.getStatus()); } @Test public void testUpdateWorkWithProfileCreationTokenWhenClaimedAndNotSource() throws JSONException, InterruptedException, URISyntaxException { long time = System.currentTimeMillis(); Work workToCreate = (Work) unmarshallFromPath("/record_2.0_rc2/samples/work-2.0_rc2.xml", Work.class); workToCreate.setPutCode(null); workToCreate.setVisibility(Visibility.PUBLIC); workToCreate.getExternalIdentifiers().getExternalIdentifier().clear(); ExternalID wExtId = new ExternalID(); wExtId.setValue("Work Id " + time); wExtId.setType(WorkExternalIdentifierType.AGR.value()); wExtId.setRelationship(Relationship.SELF); workToCreate.getExternalIdentifiers().getExternalIdentifier().add(wExtId); String accessToken = getAccessToken(); ClientResponse postResponse = memberV2ApiClient.createWorkXml(this.getUser1OrcidId(), workToCreate, accessToken); assertNotNull(postResponse); assertEquals(Response.Status.CREATED.getStatusCode(), postResponse.getStatus()); String locationPath = postResponse.getLocation().getPath(); assertTrue("Location header path should match pattern, but was " + locationPath, locationPath.matches(".*/v2.0_rc2/" + this.getUser1OrcidId() + "/work/\\d+")); ClientResponse getResponse = memberV2ApiClient.viewLocationXml(postResponse.getLocation(), accessToken); assertEquals(Response.Status.OK.getStatusCode(), getResponse.getStatus()); Work gotWork = getResponse.getEntity(Work.class); assertEquals("common:title", gotWork.getWorkTitle().getTitle().getContent()); gotWork.getWorkTitle().getTitle().setContent("updated title"); String profileCreateToken = oauthHelper.getClientCredentialsAccessToken(this.getClient2ClientId(), this.getClient2ClientSecret(), ScopePathType.ORCID_PROFILE_CREATE); ClientResponse putResponse = memberV2ApiClient.updateLocationXml(postResponse.getLocation(), profileCreateToken, gotWork); assertEquals(Response.Status.FORBIDDEN.getStatusCode(), putResponse.getStatus()); ClientResponse getAfterUpdateResponse = memberV2ApiClient.viewLocationXml(postResponse.getLocation(), accessToken); assertEquals(Response.Status.OK.getStatusCode(), getAfterUpdateResponse.getStatus()); Work gotAfterUpdateWork = getAfterUpdateResponse.getEntity(Work.class); assertEquals("common:title", gotAfterUpdateWork.getWorkTitle().getTitle().getContent()); ClientResponse deleteResponse = memberV2ApiClient.deleteWorkXml(this.getUser1OrcidId(), gotWork.getPutCode(), accessToken); assertEquals(Response.Status.NO_CONTENT.getStatusCode(), deleteResponse.getStatus()); } @Test public void testWorksWithPartOfRelationshipDontGetGrouped () throws JSONException, InterruptedException, URISyntaxException { long time = System.currentTimeMillis(); String accessTokenForClient1 = getAccessToken(); String accessTokenForClient2 = getAccessToken(getUser1OrcidId(), getUser1Password(), getScopes(ScopePathType.ACTIVITIES_UPDATE, ScopePathType.ACTIVITIES_READ_LIMITED), getClient2ClientId(), getClient2ClientSecret(), getClient2RedirectUri()); Work work1 = (Work) unmarshallFromPath("/record_2.0_rc2/samples/work-2.0_rc2.xml", Work.class); work1.setPutCode(null); work1.setVisibility(Visibility.PUBLIC); work1.getExternalIdentifiers().getExternalIdentifier().clear(); org.orcid.jaxb.model.record_rc2.WorkTitle title1 = new org.orcid.jaxb.model.record_rc2.WorkTitle(); title1.setTitle(new Title("Work # 1" + time)); work1.setWorkTitle(title1); ExternalID wExtId1 = new ExternalID(); wExtId1.setValue("Work Id " + time); wExtId1.setType(WorkExternalIdentifierType.AGR.value()); wExtId1.setRelationship(Relationship.SELF); wExtId1.setUrl(new Url("http://orcid.org/work#1")); work1.getExternalIdentifiers().getExternalIdentifier().clear(); work1.getExternalIdentifiers().getExternalIdentifier().add(wExtId1); Work work2 = (Work) unmarshallFromPath("/record_2.0_rc2/samples/work-2.0_rc2.xml", Work.class); work2.setPutCode(null); work2.setVisibility(Visibility.PUBLIC); org.orcid.jaxb.model.record_rc2.WorkTitle title2 = new org.orcid.jaxb.model.record_rc2.WorkTitle(); title2.setTitle(new Title("Work # 2" + time)); work2.setWorkTitle(title2); work2.getExternalIdentifiers().getExternalIdentifier().clear(); ExternalID wExtId2 = new ExternalID(); wExtId2.setValue("Work Id " + time); wExtId2.setType(WorkExternalIdentifierType.AGR.value()); wExtId2.setRelationship(Relationship.PART_OF); wExtId2.setUrl(new Url("http://orcid.org/work#2")); work2.getExternalIdentifiers().getExternalIdentifier().clear(); work2.getExternalIdentifiers().getExternalIdentifier().add(wExtId2); Work work3 = (Work) unmarshallFromPath("/record_2.0_rc2/samples/work-2.0_rc2.xml", Work.class); work3.setPutCode(null); work3.setVisibility(Visibility.PUBLIC); org.orcid.jaxb.model.record_rc2.WorkTitle title3 = new org.orcid.jaxb.model.record_rc2.WorkTitle(); title3.setTitle(new Title("Work # 3" + time)); work3.setWorkTitle(title3); work3.getExternalIdentifiers().getExternalIdentifier().clear(); ExternalID wExtId3 = new ExternalID(); wExtId3.setValue("Work Id " + time); wExtId3.setType(WorkExternalIdentifierType.AGR.value()); wExtId3.setRelationship(Relationship.SELF); wExtId3.setUrl(new Url("http://orcid.org/work#3")); work3.getExternalIdentifiers().getExternalIdentifier().clear(); work3.getExternalIdentifiers().getExternalIdentifier().add(wExtId3); //Add the three works ClientResponse postResponse = memberV2ApiClient.createWorkXml(this.getUser1OrcidId(), work1, accessTokenForClient1); assertNotNull(postResponse); assertEquals(Response.Status.CREATED.getStatusCode(), postResponse.getStatus()); Long putCode1 = getPutCodeFromResponse(postResponse); postResponse = memberV2ApiClient.createWorkXml(this.getUser1OrcidId(), work2, accessTokenForClient1); assertNotNull(postResponse); assertEquals(Response.Status.CREATED.getStatusCode(), postResponse.getStatus()); Long putCode2 = getPutCodeFromResponse(postResponse); postResponse = memberV2ApiClient.createWorkXml(this.getUser1OrcidId(), work3, accessTokenForClient2); assertNotNull(postResponse); assertEquals(Response.Status.CREATED.getStatusCode(), postResponse.getStatus()); Long putCode3 = getPutCodeFromResponse(postResponse); ClientResponse activitiesResponse = memberV2ApiClient.viewActivities(this.getUser1OrcidId(), accessTokenForClient1); assertEquals(Response.Status.OK.getStatusCode(), activitiesResponse.getStatus()); ActivitiesSummary activities = activitiesResponse.getEntity(ActivitiesSummary.class); assertNotNull(activities); assertFalse(activities.getWorks().getWorkGroup().isEmpty()); WorkGroup work1Group = null; WorkGroup work2Group = null; WorkGroup work3Group = null; boolean work1found = false; boolean work2found = false; boolean work3found = false; for(WorkGroup group : activities.getWorks().getWorkGroup()) { if(group.getIdentifiers().getExternalIdentifier() == null || group.getIdentifiers().getExternalIdentifier().isEmpty()) { for(WorkSummary summary : group.getWorkSummary()) { String title = summary.getTitle().getTitle().getContent(); if (("Work # 2" + time).equals(title)) { work2found = true; work2Group = group; } } } else { for(ExternalID id : group.getIdentifiers().getExternalIdentifier()) { //If it is the ID is the one we are looking for if(id.getValue().equals("Work Id " + time)) { for(WorkSummary summary : group.getWorkSummary()) { String title = summary.getTitle().getTitle().getContent(); if(("Work # 1" + time).equals(title)) { work1found = true; work1Group = group; } else if(("Work # 3" + time).equals(title)) { work3found = true; work3Group = group; } } } } } } assertTrue(work1found); assertTrue(work2found); assertTrue(work3found); //Check that work # 1 and Work # 3 are in the same work assertEquals(work1Group, work3Group); //Check that work # 2 is not in the same group than group # 1 assertThat(work2Group, not(work1Group)); //Remove all created works ClientResponse deleteResponse = memberV2ApiClient.deleteWorkXml(this.getUser1OrcidId(), putCode1, accessTokenForClient1); assertNotNull(deleteResponse); assertEquals(Response.Status.NO_CONTENT.getStatusCode(), deleteResponse.getStatus()); deleteResponse = memberV2ApiClient.deleteWorkXml(this.getUser1OrcidId(), putCode2, accessTokenForClient1); assertNotNull(deleteResponse); assertEquals(Response.Status.NO_CONTENT.getStatusCode(), deleteResponse.getStatus()); deleteResponse = memberV2ApiClient.deleteWorkXml(this.getUser1OrcidId(), putCode3, accessTokenForClient2); assertNotNull(deleteResponse); assertEquals(Response.Status.NO_CONTENT.getStatusCode(), deleteResponse.getStatus()); } private String getAccessToken() throws InterruptedException, JSONException { return getAccessToken(getScopes(ScopePathType.ACTIVITIES_UPDATE, ScopePathType.ACTIVITIES_READ_LIMITED)); } }