From e8388ae8cf7fb0d39a0ce8cf35467e487ddebd20 Mon Sep 17 00:00:00 2001 From: Volker Schmidt Date: Sat, 17 Aug 2019 19:10:29 +0200 Subject: [PATCH] Adds unit tests for DHIS2 to FHIR care related resources. --- ...rollmentToFhirCarePlanTransformerTest.java | 222 +++++++++++++++ .../R4EnrollmentToFhirDataProviderTest.java | 153 +++++++++++ .../R4ProgramStageToFhirDataProviderTest.java | 168 ++++++++++++ ...rQuestionnaireResponseTransformerTest.java | 256 ++++++++++++++++++ .../impl/AbstractDhisToFhirTransformer.java | 3 +- .../dhis/search/SearchFilterCollector.java | 2 +- 6 files changed, 802 insertions(+), 2 deletions(-) create mode 100644 fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirCarePlanTransformerTest.java create mode 100644 fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirDataProviderTest.java create mode 100644 fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/r4/R4ProgramStageToFhirDataProviderTest.java create mode 100644 fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/r4/R4ProgramStageToFhirQuestionnaireResponseTransformerTest.java diff --git a/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirCarePlanTransformerTest.java b/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirCarePlanTransformerTest.java new file mode 100644 index 00000000..444da562 --- /dev/null +++ b/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirCarePlanTransformerTest.java @@ -0,0 +1,222 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.enrollment.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.model.primitive.IdDt; +import org.dhis2.fhir.adapter.dhis.converter.ValueConverter; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; +import org.dhis2.fhir.adapter.dhis.tracker.program.Enrollment; +import org.dhis2.fhir.adapter.dhis.tracker.program.EnrollmentStatus; +import org.dhis2.fhir.adapter.dhis.tracker.program.ProgramMetadataService; +import org.dhis2.fhir.adapter.dhis.tracker.program.WritableProgram; +import org.dhis2.fhir.adapter.dhis.tracker.trackedentity.TrackedEntityAttributes; +import org.dhis2.fhir.adapter.dhis.tracker.trackedentity.TrackedEntityMetadataService; +import org.dhis2.fhir.adapter.dhis.tracker.trackedentity.TrackedEntityService; +import org.dhis2.fhir.adapter.dhis.tracker.trackedentity.TrackedEntityType; +import org.dhis2.fhir.adapter.fhir.data.repository.FhirDhisAssignmentRepository; +import org.dhis2.fhir.adapter.fhir.extension.IncidentDateExtensionUtils; +import org.dhis2.fhir.adapter.fhir.extension.LocationExtensionUtils; +import org.dhis2.fhir.adapter.fhir.metadata.model.EnrollmentRule; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirClient; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType; +import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; +import org.dhis2.fhir.adapter.fhir.metadata.repository.FhirResourceMappingRepository; +import org.dhis2.fhir.adapter.fhir.metadata.repository.SystemRepository; +import org.dhis2.fhir.adapter.fhir.metadata.repository.TrackedEntityRuleRepository; +import org.dhis2.fhir.adapter.fhir.model.FhirVersion; +import org.dhis2.fhir.adapter.fhir.repository.FhirResourceRepository; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutionContext; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; +import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirTransformerContext; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.util.AbstractAssignmentDhisToFhirTransformerUtils; +import org.dhis2.fhir.adapter.fhir.transform.scripted.ImmutableScriptedEnrollment; +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; +import org.dhis2.fhir.adapter.lock.LockManager; +import org.hl7.fhir.r4.model.CarePlan; +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.Reference; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.sql.Date; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * Unit tests for {@link R4EnrollmentToFhirCarePlanTransformer}. + * + * @author volsch + */ +public class R4EnrollmentToFhirCarePlanTransformerTest +{ + @Mock + private ScriptExecutor scriptExecutor; + + @Mock + private LockManager lockManager; + + @Mock + private SystemRepository systemRepository; + + @Mock + private FhirResourceRepository fhirResourceRepository; + + @Mock + private FhirResourceMappingRepository resourceMappingRepository; + + @Mock + private FhirDhisAssignmentRepository fhirDhisAssignmentRepository; + + @Mock + private TrackedEntityMetadataService trackedEntityMetadataService; + + @Mock + private TrackedEntityRuleRepository trackedEntityRuleRepository; + + @Mock + private ProgramMetadataService programMetadataService; + + @Mock + private FhirClient fhirClient; + + @Mock + private DhisToFhirTransformerContext context; + + @Mock + private ScriptExecutionContext scriptExecutionContext; + + @Mock + private TrackedEntityService trackedEntityService; + + @Mock + private TrackedEntityAttributes trackedEntityAttributes; + + @Mock + private TrackedEntityType trackedEntityType; + + @Mock + private ValueConverter valueConverter; + + @Mock + private AbstractAssignmentDhisToFhirTransformerUtils assignmentUtils; + + @InjectMocks + private R4EnrollmentToFhirCarePlanTransformer transformer; + + @Rule + public MockitoRule rule = MockitoJUnit.rule(); + + @Test + public void getFhirVersions() + { + Assert.assertEquals( FhirVersion.R4_ONLY, transformer.getFhirVersions() ); + } + + @Test + public void transformInternal() + { + final WritableProgram program = new WritableProgram(); + program.setName( "Test Program" ); + program.setDescription( "Test Description" ); + program.setWithoutRegistration( false ); + program.setTrackedEntityTypeId( "a1234567890" ); + program.setStages( new ArrayList<>() ); + + final Patient patient = new Patient(); + patient.setId( new IdDt( "Patient/lyau3syaixys" ) ); + + final ScriptedTrackedEntityInstance scriptedTrackedEntityInstance = new WritableScriptedTrackedEntityInstance( trackedEntityMetadataService, trackedEntityService, trackedEntityAttributes, trackedEntityType, "lyau3syaixys", + scriptExecutionContext, valueConverter ); + + final Enrollment enrollment = new Enrollment(); + enrollment.setProgramId( "x72638dsydu" ); + enrollment.setOrgUnitId( "j82jdy28dusx" ); + enrollment.setTrackedEntityInstanceId( "lyau3syaixys" ); + enrollment.setStatus( EnrollmentStatus.COMPLETED ); + enrollment.setEnrollmentDate( ZonedDateTime.parse( "2011-12-03T10:15:30+01:00" ) ); + enrollment.setIncidentDate( ZonedDateTime.parse( "2011-12-01T10:11:30+01:00" ) ); + + final CarePlan fhirCarePlan = new CarePlan(); + + final Map scriptVariables = new HashMap<>(); + scriptVariables.put( "assignmentUtils", assignmentUtils ); + + Mockito.doReturn( new Reference( "Location/j82jdy28dusx" ) ).when( assignmentUtils ).getMappedFhirId( Mockito.same( context ), Mockito.any(), + Mockito.eq( DhisResourceType.ORGANIZATION_UNIT ), Mockito.eq( "j82jdy28dusx" ), Mockito.eq( FhirResourceType.LOCATION ) ); + + transformer.transformInternal( fhirClient, context, new RuleInfo<>( new EnrollmentRule(), Collections.emptyList() ), scriptVariables, + new ImmutableScriptedEnrollment( new WritableScriptedEnrollment( program, enrollment, scriptedTrackedEntityInstance, scriptExecutionContext, valueConverter ) ), + fhirCarePlan, patient ); + + Assert.assertEquals( 1, fhirCarePlan.getInstantiatesUri().size() ); + Assert.assertEquals( "PlanDefinition/x72638dsydu", fhirCarePlan.getInstantiatesUri().get( 0 ).asStringValue() ); + Assert.assertEquals( 1, fhirCarePlan.getInstantiatesCanonical().size() ); + Assert.assertEquals( "PlanDefinition/x72638dsydu", fhirCarePlan.getInstantiatesCanonical().get( 0 ).asStringValue() ); + + Assert.assertEquals( CarePlan.CarePlanIntent.PLAN, fhirCarePlan.getIntent() ); + Assert.assertEquals( CarePlan.CarePlanStatus.COMPLETED, fhirCarePlan.getStatus() ); + + Assert.assertEquals( "Patient/lyau3syaixys", fhirCarePlan.getSubject().getReference() ); + Assert.assertEquals( "Location/j82jdy28dusx", + Objects.requireNonNull( LocationExtensionUtils.getValue( fhirCarePlan ) ).getReferenceElement().getValue() ); + + Assert.assertEquals( Date.from( ZonedDateTime.parse( "2011-12-03T10:15:30+01:00" ).toInstant() ), fhirCarePlan.getPeriod().getStart() ); + Assert.assertEquals( Date.from( ZonedDateTime.parse( "2011-12-01T10:11:30+01:00" ).toInstant() ), IncidentDateExtensionUtils.getValue( fhirCarePlan ) ); + } + + @Test + public void convertStatusActive() + { + Assert.assertEquals( CarePlan.CarePlanStatus.ACTIVE, transformer.convertStatus( EnrollmentStatus.ACTIVE ) ); + } + + @Test + public void convertStatusCompleted() + { + Assert.assertEquals( CarePlan.CarePlanStatus.COMPLETED, transformer.convertStatus( EnrollmentStatus.COMPLETED ) ); + } + + @Test + public void convertStatusCancelled() + { + Assert.assertEquals( CarePlan.CarePlanStatus.REVOKED, transformer.convertStatus( EnrollmentStatus.CANCELLED ) ); + } +} \ No newline at end of file diff --git a/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirDataProviderTest.java b/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirDataProviderTest.java new file mode 100644 index 00000000..34ec6c9d --- /dev/null +++ b/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/enrollment/r4/R4EnrollmentToFhirDataProviderTest.java @@ -0,0 +1,153 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.enrollment.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 org.dhis2.fhir.adapter.dhis.tracker.program.EnrollmentService; +import org.dhis2.fhir.adapter.fhir.metadata.model.EnrollmentRule; +import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; +import org.dhis2.fhir.adapter.fhir.model.FhirVersion; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; +import org.dhis2.fhir.adapter.fhir.transform.dhis.search.SearchFilter; +import org.dhis2.fhir.adapter.fhir.transform.dhis.search.SearchFilterCollector; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.springframework.web.util.DefaultUriBuilderFactory; +import org.springframework.web.util.UriBuilder; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Unit tests for {@link R4EnrollmentToFhirDataProvider}. + * + * @author volsch + */ +public class R4EnrollmentToFhirDataProviderTest +{ + @Mock + private ScriptExecutor scriptExecutor; + + @Mock + private EnrollmentService enrollmentService; + + @InjectMocks + private R4EnrollmentToFhirDataProvider provider; + + @Rule + public MockitoRule rule = MockitoJUnit.rule(); + + @Test + public void getFhirVersions() + { + Assert.assertEquals( FhirVersion.R4_ONLY, provider.getFhirVersions() ); + } + + @Test + public void searchFilterInstantiatesCanonical() throws URISyntaxException + { + final SearchFilterCollector searchFilterCollector = new SearchFilterCollector( Collections.singletonMap( "instantiates-canonical", Collections.singletonList( "PlanDefinition/hyusiofh7s8" ) ) ); + final SearchFilter searchFilter = new SearchFilter( searchFilterCollector, false ); + + provider.initSearchFilter( FhirVersion.R4, new RuleInfo<>( new EnrollmentRule(), Collections.emptyList() ), searchFilter ); + + final List variables = new ArrayList<>(); + UriBuilder uriBuilder = new DefaultUriBuilderFactory().builder(); + uriBuilder = searchFilterCollector.add( uriBuilder, variables ); + + Assert.assertEquals( new URI( "?program=hyusiofh7s8" ), uriBuilder.build( variables ) ); + } + + @Test + public void searchFilterInstantiatesUri() throws URISyntaxException + { + final SearchFilterCollector searchFilterCollector = new SearchFilterCollector( Collections.singletonMap( "instantiates-uri", Collections.singletonList( "PlanDefinition/hyusiofh7s8" ) ) ); + final SearchFilter searchFilter = new SearchFilter( searchFilterCollector, false ); + + provider.initSearchFilter( FhirVersion.R4, new RuleInfo<>( new EnrollmentRule(), Collections.emptyList() ), searchFilter ); + + final List variables = new ArrayList<>(); + UriBuilder uriBuilder = new DefaultUriBuilderFactory().builder(); + uriBuilder = searchFilterCollector.add( uriBuilder, variables ); + + Assert.assertEquals( new URI( "?program=hyusiofh7s8" ), uriBuilder.build( variables ) ); + } + + @Test + public void searchFilterPatient() throws URISyntaxException + { + final SearchFilterCollector searchFilterCollector = new SearchFilterCollector( Collections.singletonMap( "patient", Collections.singletonList( "Patient/hyusiofh7s8" ) ) ); + final SearchFilter searchFilter = new SearchFilter( searchFilterCollector, false ); + + provider.initSearchFilter( FhirVersion.R4, new RuleInfo<>( new EnrollmentRule(), Collections.emptyList() ), searchFilter ); + + final List variables = new ArrayList<>(); + UriBuilder uriBuilder = new DefaultUriBuilderFactory().builder(); + uriBuilder = searchFilterCollector.add( uriBuilder, variables ); + + Assert.assertEquals( new URI( "?trackedEntityInstance=hyusiofh7s8" ), uriBuilder.build( variables ) ); + } + + @Test + public void searchFilterSubject() throws URISyntaxException + { + final SearchFilterCollector searchFilterCollector = new SearchFilterCollector( Collections.singletonMap( "subject", Collections.singletonList( "Patient/hyusiofh7s8" ) ) ); + final SearchFilter searchFilter = new SearchFilter( searchFilterCollector, false ); + + provider.initSearchFilter( FhirVersion.R4, new RuleInfo<>( new EnrollmentRule(), Collections.emptyList() ), searchFilter ); + + final List variables = new ArrayList<>(); + UriBuilder uriBuilder = new DefaultUriBuilderFactory().builder(); + uriBuilder = searchFilterCollector.add( uriBuilder, variables ); + + Assert.assertEquals( new URI( "?trackedEntityInstance=hyusiofh7s8" ), uriBuilder.build( variables ) ); + } + + @Test + public void searchFilterLocation() throws URISyntaxException + { + final SearchFilterCollector searchFilterCollector = new SearchFilterCollector( Collections.singletonMap( "location", Collections.singletonList( "hyusiofh7s8" ) ) ); + final SearchFilter searchFilter = new SearchFilter( searchFilterCollector, false ); + + provider.initSearchFilter( FhirVersion.R4, new RuleInfo<>( new EnrollmentRule(), Collections.emptyList() ), searchFilter ); + + final List variables = new ArrayList<>(); + UriBuilder uriBuilder = new DefaultUriBuilderFactory().builder(); + uriBuilder = searchFilterCollector.add( uriBuilder, variables ); + + Assert.assertEquals( new URI( "?ou=hyusiofh7s8" ), uriBuilder.build( variables ) ); + } +} \ No newline at end of file diff --git a/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/r4/R4ProgramStageToFhirDataProviderTest.java b/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/r4/R4ProgramStageToFhirDataProviderTest.java new file mode 100644 index 00000000..b5ccddcb --- /dev/null +++ b/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/r4/R4ProgramStageToFhirDataProviderTest.java @@ -0,0 +1,168 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.program.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 org.dhis2.fhir.adapter.dhis.tracker.program.EventService; +import org.dhis2.fhir.adapter.dhis.tracker.program.ProgramMetadataService; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType; +import org.dhis2.fhir.adapter.fhir.metadata.model.ProgramStageRule; +import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; +import org.dhis2.fhir.adapter.fhir.model.FhirVersion; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; +import org.dhis2.fhir.adapter.fhir.transform.dhis.search.SearchFilter; +import org.dhis2.fhir.adapter.fhir.transform.dhis.search.SearchFilterCollector; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.springframework.web.util.DefaultUriBuilderFactory; +import org.springframework.web.util.UriBuilder; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Unit tests for {@link R4ProgramStageToFhirDataProvider}. + * + * @author volsch + */ +public class R4ProgramStageToFhirDataProviderTest +{ + @Mock + private ScriptExecutor scriptExecutor; + + @Mock + private ProgramMetadataService programMetadataService; + + @Mock + private EventService eventService; + + private ProgramStageRule questionnaireResponseRule; + + @InjectMocks + private R4ProgramStageToFhirDataProvider provider; + + @Rule + public MockitoRule rule = MockitoJUnit.rule(); + + @Before + public void setUp() + { + questionnaireResponseRule = new ProgramStageRule(); + questionnaireResponseRule.setFhirResourceType( FhirResourceType.QUESTIONNAIRE_RESPONSE ); + } + + @Test + public void getFhirVersions() + { + Assert.assertEquals( FhirVersion.R4_ONLY, provider.getFhirVersions() ); + } + + @Test + public void searchFilterBasedOn() throws URISyntaxException + { + final SearchFilterCollector searchFilterCollector = new SearchFilterCollector( Collections.singletonMap( "based-on", Collections.singletonList( "CarePlan/hyusiofh7s8" ) ) ); + final SearchFilter searchFilter = new SearchFilter( searchFilterCollector, false ); + + provider.initSearchFilter( FhirVersion.R4, new RuleInfo<>( questionnaireResponseRule, Collections.emptyList() ), searchFilter ); + + final List variables = new ArrayList<>(); + UriBuilder uriBuilder = new DefaultUriBuilderFactory().builder(); + uriBuilder = searchFilterCollector.add( uriBuilder, variables ); + + Assert.assertEquals( new URI( "?enrollment=hyusiofh7s8" ), uriBuilder.build( variables ) ); + } + + @Test + public void searchFilterQuestionnaire() throws URISyntaxException + { + final SearchFilterCollector searchFilterCollector = new SearchFilterCollector( Collections.singletonMap( "questionnaire", Collections.singletonList( "hyusiofh7s8" ) ) ); + final SearchFilter searchFilter = new SearchFilter( searchFilterCollector, false ); + + provider.initSearchFilter( FhirVersion.R4, new RuleInfo<>( questionnaireResponseRule, Collections.emptyList() ), searchFilter ); + + final List variables = new ArrayList<>(); + UriBuilder uriBuilder = new DefaultUriBuilderFactory().builder(); + uriBuilder = searchFilterCollector.add( uriBuilder, variables ); + + Assert.assertEquals( new URI( "?programStage=hyusiofh7s8" ), uriBuilder.build( variables ) ); + } + + @Test + public void searchFilterPatient() throws URISyntaxException + { + final SearchFilterCollector searchFilterCollector = new SearchFilterCollector( Collections.singletonMap( "patient", Collections.singletonList( "Patient/hyusiofh7s8" ) ) ); + final SearchFilter searchFilter = new SearchFilter( searchFilterCollector, false ); + + provider.initSearchFilter( FhirVersion.R4, new RuleInfo<>( questionnaireResponseRule, Collections.emptyList() ), searchFilter ); + + final List variables = new ArrayList<>(); + UriBuilder uriBuilder = new DefaultUriBuilderFactory().builder(); + uriBuilder = searchFilterCollector.add( uriBuilder, variables ); + + Assert.assertEquals( new URI( "?trackedEntityInstance=hyusiofh7s8" ), uriBuilder.build( variables ) ); + } + + @Test + public void searchFilterSubject() throws URISyntaxException + { + final SearchFilterCollector searchFilterCollector = new SearchFilterCollector( Collections.singletonMap( "subject", Collections.singletonList( "Patient/hyusiofh7s8" ) ) ); + final SearchFilter searchFilter = new SearchFilter( searchFilterCollector, false ); + + provider.initSearchFilter( FhirVersion.R4, new RuleInfo<>( questionnaireResponseRule, Collections.emptyList() ), searchFilter ); + + final List variables = new ArrayList<>(); + UriBuilder uriBuilder = new DefaultUriBuilderFactory().builder(); + uriBuilder = searchFilterCollector.add( uriBuilder, variables ); + + Assert.assertEquals( new URI( "?trackedEntityInstance=hyusiofh7s8" ), uriBuilder.build( variables ) ); + } + + @Test + public void searchFilterLocation() throws URISyntaxException + { + final SearchFilterCollector searchFilterCollector = new SearchFilterCollector( Collections.singletonMap( "location", Collections.singletonList( "hyusiofh7s8" ) ) ); + final SearchFilter searchFilter = new SearchFilter( searchFilterCollector, false ); + + provider.initSearchFilter( FhirVersion.R4, new RuleInfo<>( questionnaireResponseRule, Collections.emptyList() ), searchFilter ); + + final List variables = new ArrayList<>(); + UriBuilder uriBuilder = new DefaultUriBuilderFactory().builder(); + uriBuilder = searchFilterCollector.add( uriBuilder, variables ); + + Assert.assertEquals( new URI( "?orgUnit=hyusiofh7s8" ), uriBuilder.build( variables ) ); + } +} \ No newline at end of file diff --git a/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/r4/R4ProgramStageToFhirQuestionnaireResponseTransformerTest.java b/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/r4/R4ProgramStageToFhirQuestionnaireResponseTransformerTest.java new file mode 100644 index 00000000..b5819726 --- /dev/null +++ b/fhir-r4/src/test/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/program/r4/R4ProgramStageToFhirQuestionnaireResponseTransformerTest.java @@ -0,0 +1,256 @@ +package org.dhis2.fhir.adapter.fhir.transform.dhis.impl.program.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.model.primitive.IdDt; +import org.dhis2.fhir.adapter.dhis.converter.ValueConverter; +import org.dhis2.fhir.adapter.dhis.model.DhisResourceType; +import org.dhis2.fhir.adapter.dhis.model.WritableDataElement; +import org.dhis2.fhir.adapter.dhis.model.WritableDataValue; +import org.dhis2.fhir.adapter.dhis.tracker.program.Event; +import org.dhis2.fhir.adapter.dhis.tracker.program.EventStatus; +import org.dhis2.fhir.adapter.dhis.tracker.program.ProgramMetadataService; +import org.dhis2.fhir.adapter.dhis.tracker.program.ProgramStageMetadataService; +import org.dhis2.fhir.adapter.dhis.tracker.program.WritableProgram; +import org.dhis2.fhir.adapter.dhis.tracker.program.WritableProgramStage; +import org.dhis2.fhir.adapter.dhis.tracker.program.WritableProgramStageDataElement; +import org.dhis2.fhir.adapter.dhis.tracker.trackedentity.TrackedEntityAttributes; +import org.dhis2.fhir.adapter.dhis.tracker.trackedentity.TrackedEntityMetadataService; +import org.dhis2.fhir.adapter.dhis.tracker.trackedentity.TrackedEntityService; +import org.dhis2.fhir.adapter.dhis.tracker.trackedentity.TrackedEntityType; +import org.dhis2.fhir.adapter.fhir.data.repository.FhirDhisAssignmentRepository; +import org.dhis2.fhir.adapter.fhir.extension.DueDateExtensionUtils; +import org.dhis2.fhir.adapter.fhir.extension.EventStatusExtensionUtils; +import org.dhis2.fhir.adapter.fhir.extension.LocationExtensionUtils; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirClient; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType; +import org.dhis2.fhir.adapter.fhir.metadata.model.ProgramStageRule; +import org.dhis2.fhir.adapter.fhir.metadata.model.RuleInfo; +import org.dhis2.fhir.adapter.fhir.metadata.repository.FhirResourceMappingRepository; +import org.dhis2.fhir.adapter.fhir.metadata.repository.SystemRepository; +import org.dhis2.fhir.adapter.fhir.metadata.repository.TrackedEntityRuleRepository; +import org.dhis2.fhir.adapter.fhir.model.FhirVersion; +import org.dhis2.fhir.adapter.fhir.repository.FhirResourceRepository; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutionContext; +import org.dhis2.fhir.adapter.fhir.script.ScriptExecutor; +import org.dhis2.fhir.adapter.fhir.transform.dhis.DhisToFhirTransformerContext; +import org.dhis2.fhir.adapter.fhir.transform.dhis.impl.util.AbstractAssignmentDhisToFhirTransformerUtils; +import org.dhis2.fhir.adapter.fhir.transform.fhir.impl.util.r4.R4ValueTypeDhisToFhirTransformerUtils; +import org.dhis2.fhir.adapter.fhir.transform.scripted.ImmutableScriptedEvent; +import org.dhis2.fhir.adapter.fhir.transform.scripted.ScriptedTrackedEntityInstance; +import org.dhis2.fhir.adapter.fhir.transform.scripted.WritableScriptedEvent; +import org.dhis2.fhir.adapter.fhir.transform.scripted.WritableScriptedTrackedEntityInstance; +import org.dhis2.fhir.adapter.lock.LockManager; +import org.dhis2.fhir.adapter.model.ValueType; +import org.hl7.fhir.r4.model.Patient; +import org.hl7.fhir.r4.model.QuestionnaireResponse; +import org.hl7.fhir.r4.model.Reference; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.sql.Date; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * Unit tests for {@link R4ProgramStageToFhirQuestionnaireResponseTransformer}. + * + * @author volsch + */ +public class R4ProgramStageToFhirQuestionnaireResponseTransformerTest +{ + @Mock + private ScriptExecutor scriptExecutor; + + @Mock + private LockManager lockManager; + + @Mock + private SystemRepository systemRepository; + + @Mock + private FhirResourceRepository fhirResourceRepository; + + @Mock + private FhirResourceMappingRepository resourceMappingRepository; + + @Mock + private FhirDhisAssignmentRepository fhirDhisAssignmentRepository; + + @Mock + private TrackedEntityMetadataService trackedEntityMetadataService; + + @Mock + private TrackedEntityRuleRepository trackedEntityRuleRepository; + + @Mock + private ProgramMetadataService programMetadataService; + + @Mock + private ProgramStageMetadataService programStageMetadataService; + + @Mock + private FhirClient fhirClient; + + @Mock + private DhisToFhirTransformerContext context; + + @Mock + private ScriptExecutionContext scriptExecutionContext; + + @Mock + private TrackedEntityService trackedEntityService; + + @Mock + private TrackedEntityAttributes trackedEntityAttributes; + + @Mock + private TrackedEntityType trackedEntityType; + + @Mock + private ValueConverter valueConverter; + + @Mock + private AbstractAssignmentDhisToFhirTransformerUtils assignmentUtils; + + @InjectMocks + private R4ProgramStageToFhirQuestionnaireResponseTransformer transformer; + + @Rule + public MockitoRule rule = MockitoJUnit.rule(); + + @Test + public void getFhirVersions() + { + Assert.assertEquals( FhirVersion.R4_ONLY, transformer.getFhirVersions() ); + } + + @Test + public void transformInternal() + { + final WritableProgram program = new WritableProgram(); + program.setName( "Test Program" ); + program.setDescription( "Test Description" ); + program.setWithoutRegistration( false ); + program.setTrackedEntityTypeId( "a1234567890" ); + program.setStages( new ArrayList<>() ); + + final WritableProgramStage programStage = new WritableProgramStage(); + programStage.setId( "b1234567890" ); + programStage.setName( "Test Stage 1" ); + programStage.setDescription( "Test Description 1" ); + programStage.setRepeatable( false ); + programStage.setDataElements( new ArrayList<>() ); + + WritableProgramStageDataElement programStageDataElement = new WritableProgramStageDataElement(); + WritableDataElement dataElement = new WritableDataElement(); + dataElement.setId( "d0123456789" ); + dataElement.setName( "Value 1" ); + dataElement.setValueType( ValueType.TEXT ); + programStageDataElement.setElement( dataElement ); + programStage.getDataElements().add( programStageDataElement ); + + programStageDataElement = new WritableProgramStageDataElement(); + dataElement = new WritableDataElement(); + dataElement.setId( "d7123456789" ); + dataElement.setName( "Value 2" ); + dataElement.setValueType( ValueType.TEXT ); + programStageDataElement.setElement( dataElement ); + programStage.getDataElements().add( programStageDataElement ); + + final Patient patient = new Patient(); + patient.setId( new IdDt( "Patient/lyau3syaixys" ) ); + + final ScriptedTrackedEntityInstance scriptedTrackedEntityInstance = new WritableScriptedTrackedEntityInstance( trackedEntityMetadataService, trackedEntityService, trackedEntityAttributes, trackedEntityType, "lyau3syaixys", + scriptExecutionContext, valueConverter ); + + final ArrayList dataValues = new ArrayList<>(); + dataValues.add( new WritableDataValue( "d0123456789", "Test Value 1x" ) ); + dataValues.add( new WritableDataValue( "d7123456789", "Test Value 2x" ) ); + + final Event event = new Event(); + event.setProgramId( "x72638dsydu" ); + event.setProgramStageId( "x12638bsyda" ); + event.setOrgUnitId( "j82jdy28dusx" ); + event.setEnrollmentId( "a73dhsjxhs8" ); + event.setTrackedEntityInstanceId( "lyau3syaixys" ); + event.setStatus( EventStatus.OVERDUE ); + event.setEventDate( ZonedDateTime.parse( "2011-12-03T10:15:30+01:00" ) ); + event.setDueDate( ZonedDateTime.parse( "2011-12-08T10:11:30+01:00" ) ); + event.setDataValues( dataValues ); + + final QuestionnaireResponse fhirQuestionnaireResponse = new QuestionnaireResponse(); + + final Map scriptVariables = new HashMap<>(); + scriptVariables.put( "assignmentUtils", assignmentUtils ); + scriptVariables.put( "valueTypeUtils", new R4ValueTypeDhisToFhirTransformerUtils( scriptExecutionContext, valueConverter ) ); + + Mockito.doAnswer( invocation -> invocation.getArgument( 0 ) ).when( valueConverter ) + .convert( Mockito.any(), Mockito.any(), Mockito.eq( String.class ) ); + + Mockito.doReturn( new Reference( "Location/j82jdy28dusx" ) ).when( assignmentUtils ).getMappedFhirId( Mockito.same( context ), Mockito.any(), + Mockito.eq( DhisResourceType.ORGANIZATION_UNIT ), Mockito.eq( "j82jdy28dusx" ), Mockito.eq( FhirResourceType.LOCATION ) ); + Mockito.doReturn( new Reference( "Questionnaire/x12638bsyda" ) ).when( assignmentUtils ).getMappedFhirId( Mockito.same( context ), Mockito.any(), + Mockito.eq( DhisResourceType.PROGRAM_STAGE_METADATA ), Mockito.eq( "x12638bsyda" ), Mockito.eq( FhirResourceType.QUESTIONNAIRE ) ); + Mockito.doReturn( new Reference( "CarePlan/a73dhsjxhs8" ) ).when( assignmentUtils ).getMappedFhirId( Mockito.same( context ), Mockito.any(), + Mockito.eq( DhisResourceType.ENROLLMENT ), Mockito.eq( "a73dhsjxhs8" ), Mockito.eq( FhirResourceType.CARE_PLAN ) ); + + transformer.transformInternal( fhirClient, context, new RuleInfo<>( new ProgramStageRule(), Collections.emptyList() ), scriptVariables, + new ImmutableScriptedEvent( new WritableScriptedEvent( program, programStage, event, scriptedTrackedEntityInstance, scriptExecutionContext, valueConverter ) ), + fhirQuestionnaireResponse, patient ); + + Assert.assertEquals( "CarePlan/a73dhsjxhs8", fhirQuestionnaireResponse.getBasedOnFirstRep().getReference() ); + Assert.assertEquals( "Questionnaire/x12638bsyda", fhirQuestionnaireResponse.getQuestionnaire() ); + Assert.assertEquals( QuestionnaireResponse.QuestionnaireResponseStatus.INPROGRESS, fhirQuestionnaireResponse.getStatus() ); + Assert.assertEquals( EventStatus.OVERDUE, EventStatusExtensionUtils.getValue( fhirQuestionnaireResponse ) ); + + Assert.assertEquals( "Patient/lyau3syaixys", fhirQuestionnaireResponse.getSubject().getReference() ); + Assert.assertEquals( "Location/j82jdy28dusx", + Objects.requireNonNull( LocationExtensionUtils.getValue( fhirQuestionnaireResponse ) ).getReferenceElement().getValue() ); + + Assert.assertEquals( Date.from( ZonedDateTime.parse( "2011-12-03T10:15:30+01:00" ).toInstant() ), fhirQuestionnaireResponse.getAuthored() ); + Assert.assertEquals( Date.from( ZonedDateTime.parse( "2011-12-08T10:11:30+01:00" ).toInstant() ), DueDateExtensionUtils.getValue( fhirQuestionnaireResponse ) ); + + Assert.assertEquals( 2, fhirQuestionnaireResponse.getItem().size() ); + Assert.assertEquals( "d0123456789", fhirQuestionnaireResponse.getItem().get( 0 ).getLinkId() ); + Assert.assertEquals( "Test Value 1x", fhirQuestionnaireResponse.getItem().get( 0 ).getAnswerFirstRep().getValue().primitiveValue() ); + Assert.assertEquals( "d7123456789", fhirQuestionnaireResponse.getItem().get( 1 ).getLinkId() ); + Assert.assertEquals( "Test Value 2x", fhirQuestionnaireResponse.getItem().get( 1 ).getAnswerFirstRep().getValue().primitiveValue() ); + } +} \ No newline at end of file diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirTransformer.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirTransformer.java index 57529a70..5b5e6d41 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirTransformer.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/impl/AbstractDhisToFhirTransformer.java @@ -70,6 +70,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; @@ -634,7 +635,7 @@ protected List createAssignedFhirReferences( @Nonn { @SuppressWarnings( "unchecked" ) final T reference = (T) createAssignedFhirReference( context, ruleInfo, scriptVariables, dhisResourceType, dhisId, fhirResourceType ); - return reference == null ? Collections.emptyList() : Collections.singletonList( reference ); + return reference == null ? new ArrayList<>() : new ArrayList<>( Collections.singletonList( reference ) ); } @Nullable diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/search/SearchFilterCollector.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/search/SearchFilterCollector.java index f766ee63..188095e4 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/search/SearchFilterCollector.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/transform/dhis/search/SearchFilterCollector.java @@ -56,7 +56,7 @@ public class SearchFilterCollector implements UriFilterApplier { public static final Set QUERY_PARAM_NAMES = Collections.unmodifiableSet( - new HashSet<>( Arrays.asList( "event", "orgUnit", "ou", "status", "trackedEntityInstance", "program", "programStage" ) ) ); + new HashSet<>( Arrays.asList( "event", "orgUnit", "ou", "status", "trackedEntityInstance", "enrollment", "program", "programStage" ) ) ); private final Function dhisPropertyRefResolver;