diff --git a/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/AbstractProgramStageFhirRestAppTest.java b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/AbstractProgramStageFhirRestAppTest.java index a5683b12..a3a9ca94 100644 --- a/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/AbstractProgramStageFhirRestAppTest.java +++ b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/AbstractProgramStageFhirRestAppTest.java @@ -68,17 +68,15 @@ protected void expectProgramStageMetadataRequests() throws Exception systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs/EPDyQuoRnXk.json?" + "fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration,withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid," + - "name,valueType," + - "mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,program%5Bid%5D,lastUpdated,name,description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart," + - "programStageDataElements%5Bid,compulsory," + - "allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D" ) ) + "name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid,program%5Bid%5D,lastUpdated,name,description,repeatable,captureCoordinates,generatedByEnrollmentDate," + + "minDaysFromStart," + + "programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-program.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/programs.json?paging=false&fields=id,name,code,description,lastUpdated,selectIncidentDatesInFuture,selectEnrollmentDatesInFuture,displayIncidentDate,registration," + "withoutRegistration,captureCoordinates,trackedEntityType%5Bid%5D,programTrackedEntityAttributes%5Bid,name,valueType,mandatory,allowFutureDate,trackedEntityAttribute%5Bid,name,code,valueType,generated%5D%5D,programStages%5Bid," + - "program%5Bid%5D,lastUpdated,name," + - "description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType,optionSetValue,optionSet%5Bid,name," + - "options%5Bcode,name%5D%5D%5D%5D%5D&filter=name:eq:Child%20Programme" ) ) + "program%5Bid%5D,lastUpdated,name,description,repeatable,captureCoordinates,generatedByEnrollmentDate,minDaysFromStart,programStageDataElements%5Bid,compulsory,allowProvidedElsewhere,dataElement%5Bid,name,code,formName,valueType," + + "optionSetValue,optionSet%5Bid,name,options%5Bcode,name%5D%5D%5D%5D%5D&filter=name:eq:Child%20Programme" ) ) .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-program.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); } } diff --git a/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/r4/R4CarePlanEnrollmentFhirRestAppTest.java b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/r4/R4CarePlanEnrollmentFhirRestAppTest.java new file mode 100644 index 00000000..516e0734 --- /dev/null +++ b/app/src/test/java/org/dhis2/fhir/adapter/fhir/server/r4/R4CarePlanEnrollmentFhirRestAppTest.java @@ -0,0 +1,369 @@ +package org.dhis2.fhir.adapter.fhir.server.r4; + +/* + * Copyright (c) 2004-2019, University of Oslo + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * Neither the name of the HISP project nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.client.api.IGenericClient; +import ca.uhn.fhir.rest.client.interceptor.BasicAuthInterceptor; +import ca.uhn.fhir.rest.server.exceptions.AuthenticationException; +import org.apache.commons.io.IOUtils; +import org.dhis2.fhir.adapter.fhir.extension.IncidentDateExtensionUtils; +import org.dhis2.fhir.adapter.fhir.extension.LocationExtensionUtils; +import org.dhis2.fhir.adapter.fhir.model.FhirVersion; +import org.dhis2.fhir.adapter.fhir.server.AbstractProgramStageFhirRestAppTest; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.CarePlan; +import org.hl7.fhir.r4.model.IdType; +import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r4.model.ResourceFactory; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.test.web.client.ExpectedCount; + +import javax.annotation.Nonnull; +import java.nio.charset.StandardCharsets; +import java.sql.Date; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Objects; + +import static org.springframework.test.web.client.match.MockRestRequestMatchers.*; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus; +import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; + +/** + * R4 tests for rest interfaces that access + * DHIS2 enrollments. Some methods are executed twice in order to + * verify that no cached data is used without authentication. + * + * @author volsch + */ +public class R4CarePlanEnrollmentFhirRestAppTest extends AbstractProgramStageFhirRestAppTest +{ + @Nonnull + @Override + protected FhirVersion getFhirVersion() + { + return FhirVersion.R4; + } + + @Test( expected = AuthenticationException.class ) + public void getCarePlanWithoutAuthorization() + { + final IGenericClient client = createGenericClient(); + client.read().resource( CarePlan.class ).withId( "ieR4nl4muff" ).execute(); + } + + @Test( expected = AuthenticationException.class ) + public void getCarePlanWithInvalidAuthorization() throws Exception + { + expectProgramStageMetadataRequests(); + userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6aW52YWxpZF8x" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments/ieR4nl4muff.json" ) ) + .andRespond( withStatus( HttpStatus.UNAUTHORIZED ) ); + + final IGenericClient client = createGenericClient(); + client.registerInterceptor( new BasicAuthInterceptor( "fhir_client", "invalid_1" ) ); + client.read().resource( CarePlan.class ).withId( "ieR4nl4muff" ).execute(); + } + + @Test + public void getCarePlanRepeated() throws Exception + { + getCarePlan(); + getCarePlan(); + } + + private void getCarePlan() throws Exception + { + systemDhis2Server.reset(); + userDhis2Server.reset(); + + expectProgramStageMetadataRequests(); + userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments/ieR4nl4muff.json" ) ) + .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-enrollment-90-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); + systemDhis2Server.expect( ExpectedCount.between( 0, 1 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", testConfiguration.getDhis2SystemAuthorization() ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/organisationUnits/ldXIdLNUNEp.json?fields=lastUpdated,id,code,name,shortName,displayName,level,openingDate,closedDate,coordinates,leaf,parent%5Bid%5D" ) ) + .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-org-unit-OU_4567.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); + + final IGenericClient client = createGenericClient(); + client.registerInterceptor( new BasicAuthInterceptor( "fhir_client", "fhir_client_1" ) ); + CarePlan carePlan = client.read().resource( CarePlan.class ).withId( "ieR4nl4muff" ).execute(); + Assert.assertEquals( 0, carePlan.getIdentifier().size() ); + Assert.assertEquals( "Patient/JeR2Ul4mZfx", carePlan.getSubject().getReference() ); + Assert.assertEquals( "Location/ldXIdLNUNEn", + Objects.requireNonNull( LocationExtensionUtils.getValue( carePlan ) ).getReferenceElement().getValue() ); + + systemDhis2Server.verify(); + userDhis2Server.verify(); + } + + @Test( expected = AuthenticationException.class ) + public void searchCarePlanWithoutAuthorization() throws Exception + { + expectProgramStageMetadataRequests(); + final IGenericClient client = createGenericClient(); + client.search().forResource( CarePlan.class ).returnBundle( Bundle.class ).execute(); + } + + @Test( expected = AuthenticationException.class ) + public void searchCarePlanInvalidAuthorization() throws Exception + { + expectProgramStageMetadataRequests(); + userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6aW52YWxpZF8x" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments.json?skipPaging=false&page=1&pageSize=10&ouMode=ACCESSIBLE&fields=:all" ) ) + .andRespond( withStatus( HttpStatus.UNAUTHORIZED ) ); + + final IGenericClient client = createGenericClient(); + client.registerInterceptor( new BasicAuthInterceptor( "fhir_client", "invalid_1" ) ); + client.search().forResource( CarePlan.class ).returnBundle( Bundle.class ).execute(); + } + + @Test + public void searchCarePlanRepeated() throws Exception + { + searchCarePlan(); + searchCarePlan(); + } + + private void searchCarePlan() throws Exception + { + systemDhis2Server.reset(); + userDhis2Server.reset(); + + expectProgramStageMetadataRequests(); + userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments.json?skipPaging=false&page=1&pageSize=10&ouMode=ACCESSIBLE&fields=:all" ) ) + .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-enrollment-90-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); + + final IGenericClient client = createGenericClient(); + client.registerInterceptor( new BasicAuthInterceptor( "fhir_client", "fhir_client_1" ) ); + Bundle bundle = client.search().forResource( CarePlan.class ).returnBundle( Bundle.class ).execute(); + Assert.assertEquals( 1, bundle.getEntry().size() ); + CarePlan carePlan = (CarePlan) bundle.getEntry().get( 0 ).getResource(); + Assert.assertEquals( 0, carePlan.getIdentifier().size() ); + Assert.assertEquals( "Patient/JeR2Ul4mZfx", carePlan.getSubject().getReference() ); + Assert.assertEquals( "Location/ldXIdLNUNEn", + Objects.requireNonNull( LocationExtensionUtils.getValue( carePlan ) ).getReferenceElement().getValue() ); + + systemDhis2Server.verify(); + userDhis2Server.verify(); + } + + @Test + public void searchCarePlanPatient() throws Exception + { + expectProgramStageMetadataRequests(); + userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments.json?trackedEntityInstance=JeR2Ul4mZfx&skipPaging=false&page=1&pageSize=10&ouMode=ACCESSIBLE&fields=:all" ) ) + .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-enrollment-90-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); + + final IGenericClient client = createGenericClient(); + client.registerInterceptor( new BasicAuthInterceptor( "fhir_client", "fhir_client_1" ) ); + Bundle bundle = client.search().forResource( CarePlan.class ).where( CarePlan.PATIENT.hasId( new IdType( "Patient", "JeR2Ul4mZfx" ) ) ).returnBundle( Bundle.class ).execute(); + Assert.assertEquals( 1, bundle.getEntry().size() ); + CarePlan carePlan = (CarePlan) bundle.getEntry().get( 0 ).getResource(); + Assert.assertEquals( 0, carePlan.getIdentifier().size() ); + Assert.assertEquals( "Patient/JeR2Ul4mZfx", carePlan.getSubject().getReference() ); + Assert.assertEquals( "Location/ldXIdLNUNEn", + Objects.requireNonNull( LocationExtensionUtils.getValue( carePlan ) ).getReferenceElement().getValue() ); + + systemDhis2Server.verify(); + userDhis2Server.verify(); + } + + @Test( expected = AuthenticationException.class ) + public void createCarePlanWithoutAuthorization() throws Exception + { + expectProgramStageMetadataRequests(); + + CarePlan carePlan = (CarePlan) getFhirContext().newJsonParser().parseResource( + IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/test/" + getResourceDir() + "/get-care-plan-90.json", StandardCharsets.UTF_8 ) ); + carePlan.setId( (IdType) null ); + carePlan.setSubject( new Reference( "Patient/JeR2Ul4mZfx" ) ); + + final IGenericClient client = createGenericClient(); + client.create().resource( carePlan ).execute(); + } + + @Test( expected = AuthenticationException.class ) + public void createCarePlanInvalidAuthorization() throws Exception + { + expectProgramStageMetadataRequests(); + userDhis2Server.expect( ExpectedCount.once(), requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments.json?strategy=CREATE" ) ).andExpect( method( HttpMethod.POST ) ) + .andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6aW52YWxpZF8x" ) ) + .andExpect( content().contentTypeCompatibleWith( MediaType.APPLICATION_JSON ) ) + .andExpect( content().json( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-enrollment-90-create.json", StandardCharsets.UTF_8 ) ) ) + .andRespond( withStatus( HttpStatus.UNAUTHORIZED ) ); + + CarePlan carePlan = (CarePlan) getFhirContext().newJsonParser().parseResource( + IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/test/" + getResourceDir() + "/get-care-plan-90.json", StandardCharsets.UTF_8 ) ); + carePlan.setId( (IdType) null ); + carePlan.setSubject( new Reference( "Patient/JeR2Ul4mZfx" ) ); + LocationExtensionUtils.setValue( carePlan, new Reference( "Location/ldXIdLNUNEn" ) ); + + final IGenericClient client = createGenericClient(); + client.registerInterceptor( new BasicAuthInterceptor( "fhir_client", "invalid_1" ) ); + client.create().resource( carePlan ).execute(); + } + + @Test + public void createCarePlan() throws Exception + { + expectProgramStageMetadataRequests(); + userDhis2Server.expect( ExpectedCount.once(), requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments.json?strategy=CREATE" ) ).andExpect( method( HttpMethod.POST ) ) + .andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) + .andExpect( content().contentTypeCompatibleWith( MediaType.APPLICATION_JSON ) ) + .andExpect( content().json( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-enrollment-90-create.json", StandardCharsets.UTF_8 ) ) ) + .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-enrollment-90-create-response.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) + .headers( createDefaultHeaders() ) ); + + CarePlan carePlan = (CarePlan) getFhirContext().newJsonParser().parseResource( + IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/test/" + getResourceDir() + "/get-care-plan-90.json", StandardCharsets.UTF_8 ) ); + carePlan.setId( (IdType) null ); + carePlan.setSubject( new Reference( "Patient/JeR2Ul4mZfx" ) ); + LocationExtensionUtils.setValue( carePlan, new Reference( "Location/ldXIdLNUNEn" ) ); + + final IGenericClient client = createGenericClient(); + client.registerInterceptor( new BasicAuthInterceptor( "fhir_client", "fhir_client_1" ) ); + MethodOutcome methodOutcome = client.create().resource( carePlan ).execute(); + Assert.assertEquals( Boolean.TRUE, methodOutcome.getCreated() ); + Assert.assertEquals( "http://localhost:" + localPort + "/fhir/r4/default/CarePlan/ieR4nl4muff", methodOutcome.getId().toString() ); + } + + @Test( expected = AuthenticationException.class ) + public void updateCarePlanWithoutAuthorization() throws Exception + { + expectProgramStageMetadataRequests(); + userDhis2Server.expect( ExpectedCount.once(), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/trackedEntityInstances/JeR2Ul4mZfx.json?" + + "fields=deleted,trackedEntityInstance,trackedEntityType,orgUnit,coordinates,lastUpdated,attributes%5Battribute,value,lastUpdated,storedBy%5D" ) ) + .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-tei-15-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); + + CarePlan carePlan = (CarePlan) getFhirContext().newJsonParser().parseResource( + IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/test/" + getResourceDir() + "/get-care-plan-90.json", StandardCharsets.UTF_8 ) ); + carePlan.setId( "ieR4nl4muff" ); + carePlan.setSubject( new Reference( "Patient/JeR2Ul4mZfx" ) ); + + final IGenericClient client = createGenericClient(); + client.update().resource( carePlan ).execute(); + } + + @Test( expected = AuthenticationException.class ) + public void updateCarePlanInvalidAuthorization() throws Exception + { + expectProgramStageMetadataRequests(); + userDhis2Server.expect( ExpectedCount.between( 1, 2 ), method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6aW52YWxpZF8x" ) ) + .andExpect( requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments/ieR4nl4muff.json" ) ) + .andRespond( withStatus( HttpStatus.UNAUTHORIZED ) ); + + CarePlan carePlan = (CarePlan) getFhirContext().newJsonParser().parseResource( + IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/test/" + getResourceDir() + "/get-care-plan-90.json", StandardCharsets.UTF_8 ) ); + carePlan.setId( "ieR4nl4muff" ); + carePlan.setSubject( new Reference( "Patient/JeR2Ul4mZfx" ) ); + + final IGenericClient client = createGenericClient(); + client.registerInterceptor( new BasicAuthInterceptor( "fhir_client", "invalid_1" ) ); + client.update().resource( carePlan ).execute(); + } + + @Test + public void updateCarePlan() throws Exception + { + expectProgramStageMetadataRequests(); + + userDhis2Server.expect( ExpectedCount.between( 1, 3 ), requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments/ieR4nl4muff.json" ) ) + .andExpect( method( HttpMethod.GET ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) + .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-enrollment-90-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); + userDhis2Server.expect( ExpectedCount.once(), requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments/ieR4nl4muff.json?mergeMode=MERGE" ) ).andExpect( method( HttpMethod.PUT ) ) + .andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) + .andExpect( content().contentTypeCompatibleWith( MediaType.APPLICATION_JSON ) ) + .andExpect( content().json( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-enrollment-90-update.json", StandardCharsets.UTF_8 ) ) ) + .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/default-enrollment-90-update-response.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) + .headers( createDefaultHeaders() ) ); + + CarePlan carePlan = (CarePlan) getFhirContext().newJsonParser().parseResource( + IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/test/" + getResourceDir() + "/get-care-plan-90.json", StandardCharsets.UTF_8 ) ); + carePlan.setId( "ieR4nl4muff" ); + carePlan.setSubject( new Reference( "Patient/JeR2Ul4mZfx" ) ); + carePlan.setStatus( CarePlan.CarePlanStatus.COMPLETED ); + LocationExtensionUtils.setValue( carePlan, new Reference( "Location/ldXIdLNUNEn" ) ); + IncidentDateExtensionUtils.setValue( carePlan, + Date.from( LocalDate.of( 2018, 11, 9 ).atStartOfDay( ZoneId.systemDefault() ).toInstant() ), ResourceFactory::createType ); + + final IGenericClient client = createGenericClient(); + client.registerInterceptor( new BasicAuthInterceptor( "fhir_client", "fhir_client_1" ) ); + MethodOutcome methodOutcome = client.update().resource( carePlan ).execute(); + Assert.assertNotEquals( Boolean.TRUE, methodOutcome.getCreated() ); + Assert.assertEquals( "http://localhost:" + localPort + "/fhir/r4/default/CarePlan/ieR4nl4muff", methodOutcome.getId().toString() ); + } + + @Test( expected = AuthenticationException.class ) + public void deleteCarePlanWithoutAuthorization() throws Exception + { + expectProgramStageMetadataRequests(); + + final IGenericClient client = createGenericClient(); + client.delete().resourceById( "CarePlan", "ieR4nl4muff" ).execute(); + } + + @Test( expected = AuthenticationException.class ) + public void deleteCarePlanInvalidAuthorization() throws Exception + { + expectProgramStageMetadataRequests(); + userDhis2Server.expect( ExpectedCount.once(), requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments/ieR4nl4muff" ) ) + .andExpect( method( HttpMethod.DELETE ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6aW52YWxpZF8x" ) ) + .andRespond( withStatus( HttpStatus.UNAUTHORIZED ) ); + + final IGenericClient client = createGenericClient(); + client.registerInterceptor( new BasicAuthInterceptor( "fhir_client", "invalid_1" ) ); + client.delete().resourceById( "CarePlan", "ieR4nl4muff" ).execute(); + + userDhis2Server.verify(); + } + + @Test + public void deleteCarePlan() throws Exception + { + expectProgramStageMetadataRequests(); + userDhis2Server.expect( ExpectedCount.once(), requestTo( dhis2BaseUrl + "/api/" + dhis2ApiVersion + "/enrollments/ieR4nl4muff" ) ) + .andExpect( method( HttpMethod.DELETE ) ).andExpect( header( "Authorization", "Basic Zmhpcl9jbGllbnQ6Zmhpcl9jbGllbnRfMQ==" ) ) + .andRespond( withSuccess( IOUtils.resourceToString( "/org/dhis2/fhir/adapter/dhis/test/single-enrollment-90-get.json", StandardCharsets.UTF_8 ), MediaType.APPLICATION_JSON ) ); + + final IGenericClient client = createGenericClient(); + client.registerInterceptor( new BasicAuthInterceptor( "fhir_client", "fhir_client_1" ) ); + client.delete().resourceById( "CarePlan", "ieR4nl4muff" ).execute(); + + userDhis2Server.verify(); + } +} diff --git a/app/src/test/resources/data.sql b/app/src/test/resources/data.sql index f3a14822..fda7511e 100644 --- a/app/src/test/resources/data.sql +++ b/app/src/test/resources/data.sql @@ -2455,7 +2455,7 @@ VALUES ('41d3bd48578847618274f8327f15fcbe', 0, 'Subject TEI Lookup', 'SUBJECT_TE INSERT INTO fhir_script_variable (script_id, variable) VALUES ('41d3bd48578847618274f8327f15fcbe', 'CONTEXT'); INSERT INTO fhir_script_variable (script_id, variable) VALUES ('41d3bd48578847618274f8327f15fcbe', 'INPUT'); INSERT INTO fhir_script_source (id,version,script_id,source_text,source_type) -VALUES ('67249e7b4ba7466ca770a78923fbf1c3', 0, '41d3bd48578847618274f8327f15fcbe', 'referenceUtils.getResource(input.subject, ''PATIENT'')', 'JAVASCRIPT'); +VALUES ('67249e7b4ba7466ca770a78923fbf1c3', 0, '41d3bd48578847618274f8327f15fcbe', 'fhirResourceUtils.getIdentifiedResource(input.subject, ''Patient'')', 'JAVASCRIPT'); INSERT INTO fhir_script_source_version (script_source_id,fhir_version) VALUES ('67249e7b4ba7466ca770a78923fbf1c3', 'DSTU3'); INSERT INTO fhir_script_source_version (script_source_id,fhir_version) diff --git a/fhir-r4/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirDataProvider.java b/fhir-r4/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirDataProvider.java index 7f08663d..a909c249 100644 --- a/fhir-r4/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirDataProvider.java +++ b/fhir-r4/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirDataProvider.java @@ -71,6 +71,6 @@ protected void initSearchFilter( @Nonnull FhirVersion fhirVersion, @Nonnull Rule searchFilter.addReference( CarePlan.SP_INSTANTIATES_URI, FhirResourceType.PLAN_DEFINITION, DhisResourceType.PROGRAM_METADATA, "program" ); searchFilter.addReference( CarePlan.SP_PATIENT, FhirResourceType.PATIENT, DhisResourceType.TRACKED_ENTITY, "trackedEntityInstance" ); searchFilter.addReference( CarePlan.SP_SUBJECT, null, DhisResourceType.TRACKED_ENTITY, "trackedEntityInstance" ); - searchFilter.addReference( LocationExtensionUtils.LOCATION_SEARCH_PARAM, DhisResourceType.ORGANIZATION_UNIT, FhirResourceType.LOCATION, "ou" ); + searchFilter.addReference( LocationExtensionUtils.LOCATION_SEARCH_PARAM, FhirResourceType.LOCATION, DhisResourceType.ORGANIZATION_UNIT, "ou" ); } } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/extension/BaseExtensionUtils.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/extension/BaseExtensionUtils.java index 8cc33690..0e4961f3 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/extension/BaseExtensionUtils.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/extension/BaseExtensionUtils.java @@ -106,6 +106,19 @@ protected static void setDateValue( @Nonnull String url, @Nonnull IBaseHasExtens } } + @Nullable + protected static IBaseReference getReferenceValue( @Nonnull String url, @Nonnull IBaseHasExtensions resource ) + { + final IBaseDatatype value = getValue( url, resource ); + + if ( value instanceof IBaseReference ) + { + return (IBaseReference) value; + } + + return null; + } + protected static void setReferenceValue( @Nonnull String url, @Nonnull IBaseHasExtensions resource, @Nullable IBaseReference value ) { resource.getExtension().removeIf( e -> url.equals( e.getUrl() ) ); diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/extension/LocationExtensionUtils.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/extension/LocationExtensionUtils.java index 091c053f..cea2a010 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/extension/LocationExtensionUtils.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/extension/LocationExtensionUtils.java @@ -50,6 +50,12 @@ public static void setValue( @Nonnull IBaseHasExtensions resource, @Nullable IBa BaseExtensionUtils.setReferenceValue( URL, resource, locationReference ); } + @Nullable + public static IBaseReference getValue( @Nonnull IBaseHasExtensions resource ) + { + return BaseExtensionUtils.getReferenceValue( URL, resource ); + } + private LocationExtensionUtils() { super(); diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomProgramStageRuleRepositoryImpl.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomProgramStageRuleRepositoryImpl.java index 1c54bdee..c091cda4 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomProgramStageRuleRepositoryImpl.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/impl/CustomProgramStageRuleRepositoryImpl.java @@ -87,6 +87,7 @@ public Collection> findAllExp( @Nonnull Collection { Hibernate.initialize( r.getDhisDataReferences() ); return new RuleInfo<>( r, r.getDhisDataReferences() ); diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/EnrollmentToFhirRequestResolver.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/EnrollmentToFhirRequestResolver.java index 3346e2ae..a65af7a7 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/EnrollmentToFhirRequestResolver.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/EnrollmentToFhirRequestResolver.java @@ -44,7 +44,7 @@ import org.dhis2.fhir.adapter.fhir.metadata.model.EnrollmentRule; import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; import org.dhis2.fhir.adapter.fhir.metadata.repository.FhirClientRepository; -import org.dhis2.fhir.adapter.fhir.metadata.repository.ProgramStageRuleRepository; +import org.dhis2.fhir.adapter.fhir.metadata.repository.RuleRepository; import org.dhis2.fhir.adapter.fhir.script.ScriptExecutionContext; import org.dhis2.fhir.adapter.fhir.transform.TransformerDataException; import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.AbstractDhisToFhirRequestResolver; @@ -53,7 +53,6 @@ import org.dhis2.fhir.adapter.fhir.transform.scripted.ImmutableScriptedEnrollment; import org.dhis2.fhir.adapter.fhir.transform.scripted.ImmutableScriptedTrackedEntityInstance; import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedDhisResource; -import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedEvent; import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedTrackedEntityInstance; import org.dhis2.fhir.adapter.fhir.transform.scripted.WritableScriptedEnrollment; import org.dhis2.fhir.adapter.fhir.transform.scripted.WritableScriptedTrackedEntityInstance; @@ -73,7 +72,7 @@ public class EnrollmentToFhirRequestResolver extends AbstractDhisToFhirRequestRe { private final ProgramMetadataService programMetadataService; - private final ProgramStageRuleRepository ruleRepository; + private final RuleRepository ruleRepository; private final TrackedEntityService trackedEntityService; @@ -86,7 +85,7 @@ public class EnrollmentToFhirRequestResolver extends AbstractDhisToFhirRequestRe public EnrollmentToFhirRequestResolver( @Nonnull FhirClientRepository fhirClientRepository, @Nonnull ProgramMetadataService programMetadataService, - @Nonnull ProgramStageRuleRepository ruleRepository, + @Nonnull RuleRepository ruleRepository, @Nonnull TrackedEntityService trackedEntityService, @Nonnull TrackedEntityMetadataService trackedEntityMetadataService, @Nonnull ScriptExecutionContext scriptExecutionContext, @@ -113,8 +112,7 @@ public DhisResourceType getDhisResourceType() @Override public List> resolveRules( @Nonnull ScriptedDhisResource dhisResource ) { - final ScriptedEvent event = (ScriptedEvent) dhisResource; - return ruleRepository.findAllExp( event.getProgram().getAllReferences(), event.getProgramStage().getAllReferences(), null ) + return ruleRepository.findAllExp( DhisResourceType.ENROLLMENT ) .stream().sorted().collect( Collectors.toList() ); } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirRequestResolver.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirRequestResolver.java index 58f75c02..87f9d1ac 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirRequestResolver.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/ProgramStageToFhirRequestResolver.java @@ -115,6 +115,7 @@ public DhisResourceType getDhisResourceType() public List> resolveRules( @Nonnull ScriptedDhisResource dhisResource ) { final ScriptedEvent event = (ScriptedEvent) dhisResource; + return ruleRepository.findAllExp( event.getProgram().getAllReferences(), event.getProgramStage().getAllReferences(), null ) .stream().sorted().collect( Collectors.toList() ); } diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/extension/BaseExtensionUtilsTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/extension/BaseExtensionUtilsTest.java index c2290b2b..3875f94b 100644 --- a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/extension/BaseExtensionUtilsTest.java +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/extension/BaseExtensionUtilsTest.java @@ -134,4 +134,15 @@ public void setReferenceValue() Assert.assertEquals( "testUrl", planDefinition.getExtension().get( 0 ).getUrl() ); Assert.assertSame( reference, planDefinition.getExtension().get( 0 ).getValue() ); } + + @Test + public void getReferenceValue() + { + TestPlanDefinition planDefinition = new TestPlanDefinition(); + + final IBaseReference reference = new TestReference(); + + BaseExtensionUtils.setReferenceValue( "testUrl", planDefinition, reference ); + Assert.assertSame( reference, BaseExtensionUtils.getReferenceValue( "testUrl", planDefinition ) ); + } } \ No newline at end of file diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/extension/LocationExtensionUtilsTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/extension/LocationExtensionUtilsTest.java index 9f09f0a2..b67662ce 100644 --- a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/extension/LocationExtensionUtilsTest.java +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/extension/LocationExtensionUtilsTest.java @@ -28,6 +28,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +import org.hl7.fhir.instance.model.api.IBaseReference; import org.junit.Assert; import org.junit.Test; @@ -62,4 +63,15 @@ public void setValue() Assert.assertEquals( LocationExtensionUtils.URL, planDefinition.getExtension().get( 0 ).getUrl() ); Assert.assertEquals( reference, planDefinition.getExtension().get( 0 ).getValue() ); } + + @Test + public void getValue() + { + TestPlanDefinition planDefinition = new TestPlanDefinition(); + + final IBaseReference reference = new TestReference(); + + LocationExtensionUtils.setValue( planDefinition, reference ); + Assert.assertSame( reference, LocationExtensionUtils.getValue( planDefinition ) ); + } } \ No newline at end of file