From 0b883ae362256a09fe7535f94423ed326adf62a1 Mon Sep 17 00:00:00 2001 From: Volker Schmidt Date: Tue, 22 Jan 2019 16:16:37 +0100 Subject: [PATCH] REST interfaces for DHIS2 program stage import. --- fhir/src/main/asciidoc/api-guide.adoc | 72 +++ .../model/ApplicableEnrollmentStatus.java | 8 +- .../metadata/model/ApplicableEventStatus.java | 14 +- .../metadata/model/EventStatusUpdate.java | 8 +- .../metadata/model/MappedTrackerProgram.java | 4 +- .../model/MappedTrackerProgramStage.java | 8 +- .../fhir/metadata/model/ProgramStageRule.java | 12 +- .../metadata/model/RuleDhisDataReference.java | 4 +- .../FhirResourceMappingRepository.java | 4 +- .../MappedTrackerProgramRepository.java | 48 +- .../MappedTrackerProgramStageRepository.java | 52 +- .../listener/AbstractRuleEventListener.java | 55 ++ .../ProgramStageRuleEventListener.java | 52 ++ .../TrackedEntityRuleEventListener.java | 52 ++ ...AbstractBeforeCreateSaveRuleValidator.java | 31 +- ...reateSaveFhirResourceMappingValidator.java | 18 +- ...aveMappedTrackerProgramStageValidator.java | 130 ++++ ...eateSaveMappedTrackerProgramValidator.java | 114 ++++ ...reCreateSaveProgramStageRuleValidator.java | 78 +++ ...xecutableScriptRepositoryRestDocsTest.java | 6 +- ...ResourceMappingRepositoryRestDocsTest.java | 150 +++++ ...dTrackerProgramRepositoryRestDocsTest.java | 174 +++++ ...kerProgramStageRepositoryRestDocsTest.java | 172 +++++ ...rogramStageRuleRepositoryRestDocsTest.java | 262 ++++++++ .../TrackedEntityRepositoryRestDocsTest.java | 7 +- ...ckedEntityRuleRepositoryRestDocsTest.java} | 4 +- ...eSaveFhirResourceMappingValidatorTest.java | 605 ++++++++++++++++++ ...eSaveTrackerProgramStageValidatorTest.java | 192 ++++++ ...CreateSaveTrackerProgramValidatorTest.java | 204 ++++++ fhir/src/test/resources/data.sql | 235 ++++++- .../repository/createExecutableScript.json | 4 +- .../repository/createFhirResourceMapping.json | 11 + .../metadata/repository/createProgram.json | 17 + .../repository/createProgramStage.json | 17 + .../repository/createProgramStageRule.json | 54 ++ pom.xml | 4 +- 36 files changed, 2803 insertions(+), 79 deletions(-) create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/AbstractRuleEventListener.java create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/ProgramStageRuleEventListener.java create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/TrackedEntityRuleEventListener.java create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveMappedTrackerProgramStageValidator.java create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveMappedTrackerProgramValidator.java create mode 100644 fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveProgramStageRuleValidator.java create mode 100644 fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/FhirResourceMappingRepositoryRestDocsTest.java create mode 100644 fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramRepositoryRestDocsTest.java create mode 100644 fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramStageRepositoryRestDocsTest.java create mode 100644 fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/ProgramStageRuleRepositoryRestDocsTest.java rename fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/{RuleRepositoryRestDocsTest.java => TrackedEntityRuleRepositoryRestDocsTest.java} (99%) create mode 100644 fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveFhirResourceMappingValidatorTest.java create mode 100644 fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveTrackerProgramStageValidatorTest.java create mode 100644 fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveTrackerProgramValidatorTest.java create mode 100644 fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createFhirResourceMapping.json create mode 100644 fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgram.json create mode 100644 fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgramStage.json create mode 100644 fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgramStageRule.json diff --git a/fhir/src/main/asciidoc/api-guide.adoc b/fhir/src/main/asciidoc/api-guide.adoc index 04ca005f..e39a350d 100644 --- a/fhir/src/main/asciidoc/api-guide.adoc +++ b/fhir/src/main/asciidoc/api-guide.adoc @@ -424,6 +424,78 @@ include::{snippets}/read-tracked-entity-rule/response-body.adoc[] include::{snippets}/read-tracked-entity-rule/response-fields.adoc[] +[[api-resources-data-fhir-resource-mapping]] +==== FHIR Resource Mapping +Configures how DHIS 2 organization units, DHIS 2 GEO locations, DHIS 2 +timestamps and other values can be retrieved from specific FHIR resources. +For all FHIR resource types that must be transformed from and to DHIS 2 +events a mapping item must exist. + +.Create resource curl snippet +include::{snippets}/create-fhir-resource-mapping/curl-request.adoc[] + +include::{snippets}/create-fhir-resource-mapping/request-fields.adoc[] + +.Read resource curl snippet +include::{snippets}/read-fhir-resource-mapping/curl-request.adoc[] + +.Read resource response body +include::{snippets}/read-fhir-resource-mapping/response-body.adoc[] + +include::{snippets}/read-fhir-resource-mapping/response-fields.adoc[] + +==== Tracker Program +Configures a DHIS 2 Tracker Program for transformations. + +.Create resource curl snippet +include::{snippets}/create-program/curl-request.adoc[] + +include::{snippets}/create-program/request-fields.adoc[] + +.Read resource curl snippet +include::{snippets}/read-program/curl-request.adoc[] + +.Read resource response body +include::{snippets}/read-program/response-body.adoc[] + +include::{snippets}/read-program/response-fields.adoc[] + +==== Tracker Program Stage +Configures a DHIS 2 Tracker Program Stages for transformations. +The Tracker Program Stages belong to a Tracker Program that must +have been configured before. + +.Create resource curl snippet +include::{snippets}/create-program-stage/curl-request.adoc[] + +include::{snippets}/create-program-stage/request-fields.adoc[] + +.Read resource curl snippet +include::{snippets}/read-program-stage/curl-request.adoc[] + +.Read resource response body +include::{snippets}/read-program-stage/response-body.adoc[] + +include::{snippets}/read-program-stage/response-fields.adoc[] + +[[api-resources-data-program-stage-rule]] +==== Program Stage Rule +The program stage rule resource defines a rule that is able to transform +a FHIR resource to a DHIS 2 event. + +.Create resource curl snippet +include::{snippets}/create-program-stage-rule/curl-request.adoc[] + +include::{snippets}/create-program-stage-rule/request-fields.adoc[] + +.Read resource curl snippet +include::{snippets}/read-program-stage-rule/curl-request.adoc[] + +.Read resource response body +include::{snippets}/read-program-stage-rule/response-body.adoc[] + +include::{snippets}/read-program-stage-rule/response-fields.adoc[] + [[api-resources-administration]] === Adapter Administration Resources diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ApplicableEnrollmentStatus.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ApplicableEnrollmentStatus.java index 618065da..c0c67867 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ApplicableEnrollmentStatus.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ApplicableEnrollmentStatus.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.model; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,7 +48,7 @@ public class ApplicableEnrollmentStatus implements Serializable private boolean cancelled; @Basic - @Column( name = "enrollment_active_applicable", nullable = false ) + @Column( name = "enrollment_active_applicable", nullable = false, columnDefinition = "BOOLEAN DEFAULT TRUE NOT NULL" ) public boolean isActive() { return active; @@ -60,7 +60,7 @@ public void setActive( boolean active ) } @Basic - @Column( name = "enrollment_completed_applicable", nullable = false ) + @Column( name = "enrollment_completed_applicable", nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE NOT NULL" ) public boolean isCompleted() { return completed; @@ -72,7 +72,7 @@ public void setCompleted( boolean completed ) } @Basic - @Column( name = "enrollment_cancelled_applicable", nullable = false ) + @Column( name = "enrollment_cancelled_applicable", nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE NOT NULL" ) public boolean isCancelled() { return cancelled; diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ApplicableEventStatus.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ApplicableEventStatus.java index ce70ac34..3997c72c 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ApplicableEventStatus.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ApplicableEventStatus.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.model; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,7 +51,7 @@ public class ApplicableEventStatus implements Serializable private boolean skipped; @Basic - @Column( name = "overdue_applicable", nullable = false ) + @Column( name = "overdue_applicable", nullable = false, columnDefinition = "BOOLEAN DEFAULT TRUE NOT NULL" ) public boolean isOverdue() { return overdue; @@ -63,7 +63,7 @@ public void setOverdue( boolean overdue ) } @Basic - @Column( name = "active_applicable", nullable = false ) + @Column( name = "active_applicable", nullable = false, columnDefinition = "BOOLEAN DEFAULT TRUE NOT NULL" ) public boolean isActive() { return active; @@ -75,7 +75,7 @@ public void setActive( boolean active ) } @Basic - @Column( name = "schedule_applicable", nullable = false ) + @Column( name = "schedule_applicable", nullable = false, columnDefinition = "BOOLEAN DEFAULT TRUE NOT NULL" ) public boolean isSchedule() { return schedule; @@ -87,7 +87,7 @@ public void setSchedule( boolean schedule ) } @Basic - @Column( name = "visited_applicable", nullable = false ) + @Column( name = "visited_applicable", nullable = false, columnDefinition = "BOOLEAN DEFAULT TRUE NOT NULL" ) public boolean isVisited() { return visited; @@ -99,7 +99,7 @@ public void setVisited( boolean visited ) } @Basic - @Column( name = "completed_applicable", nullable = false ) + @Column( name = "completed_applicable", nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE NOT NULL" ) public boolean isCompleted() { return completed; @@ -111,7 +111,7 @@ public void setCompleted( boolean completed ) } @Basic - @Column( name = "skipped_applicable", nullable = false ) + @Column( name = "skipped_applicable", nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE NOT NULL" ) public boolean isSkipped() { return skipped; diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/EventStatusUpdate.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/EventStatusUpdate.java index 4f75d9ea..4ef7dbbd 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/EventStatusUpdate.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/EventStatusUpdate.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.model; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,7 +47,7 @@ public class EventStatusUpdate implements Serializable private boolean completedToActive; @Basic - @Column( name = "overdue_to_active_update" ) + @Column( name = "overdue_to_active_update", nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE NOT NULL" ) public boolean isOverdueToActive() { return overdueToActive; @@ -59,7 +59,7 @@ public void setOverdueToActive( boolean overdueToActive ) } @Basic - @Column( name = "schedule_to_active_update" ) + @Column( name = "schedule_to_active_update", nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE NOT NULL" ) public boolean isScheduleToActive() { return scheduleToActive; @@ -71,7 +71,7 @@ public void setScheduleToActive( boolean scheduleToActive ) } @Basic - @Column( name = "completed_to_active_update" ) + @Column( name = "completed_to_active_update", nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE NOT NULL" ) public boolean isCompletedToActive() { return completedToActive; diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/MappedTrackerProgram.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/MappedTrackerProgram.java index f40f0b1a..cdc4dc98 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/MappedTrackerProgram.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/MappedTrackerProgram.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.model; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -58,6 +58,8 @@ public class MappedTrackerProgram extends VersionedBaseMetadata implements Seria { private static final long serialVersionUID = -2784006479143123933L; + public static final int MAX_NAME_LENGTH = 230; + private String name; private String description; diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/MappedTrackerProgramStage.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/MappedTrackerProgramStage.java index 2f5bd454..a03103e7 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/MappedTrackerProgramStage.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/MappedTrackerProgramStage.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.model; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,6 +56,8 @@ public class MappedTrackerProgramStage extends VersionedBaseMetadata implements { private static final long serialVersionUID = 7561285892767275117L; + public static final int MAX_NAME_LENGTH = 230; + private String name; private String description; @@ -258,7 +260,7 @@ public void setBeforePeriodDayType( EventPeriodDayType beforePeriodDayType ) } @Basic - @Column( name = "before_period_days", nullable = false ) + @Column( name = "before_period_days", nullable = false, columnDefinition = "INTEGER DEFAULT 0 NOT NULL" ) public int getBeforePeriodDays() { return beforePeriodDays; @@ -282,7 +284,7 @@ public void setAfterPeriodDayType( EventPeriodDayType afterPeriodDayType ) } @Basic - @Column( name = "after_period_days", nullable = false ) + @Column( name = "after_period_days", nullable = false, columnDefinition = "INTEGER DEFAULT 0 NOT NULL" ) public int getAfterPeriodDays() { return afterPeriodDays; diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ProgramStageRule.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ProgramStageRule.java index cbbd6d53..1bfa23f6 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ProgramStageRule.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/ProgramStageRule.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.model; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -119,7 +119,7 @@ public ProgramStageRule() } @Basic - @Column( name = "enrollment_creation_enabled", nullable = false ) + @Column( name = "enrollment_creation_enabled", nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE NOT NULL" ) public boolean isEnrollmentCreationEnabled() { return enrollmentCreationEnabled; @@ -131,7 +131,7 @@ public void setEnrollmentCreationEnabled( boolean enrollmentCreationEnabled ) } @Basic - @Column( name = "event_creation_enabled", nullable = false ) + @Column( name = "event_creation_enabled", nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE NOT NULL" ) public boolean isEventCreationEnabled() { return eventCreationEnabled; @@ -143,7 +143,7 @@ public void setEventCreationEnabled( boolean eventCreationEnabled ) } @Basic - @Column( name = "update_event_date", nullable = false ) + @Column( name = "update_event_date", nullable = false, columnDefinition = "BOOLEAN DEFAULT FALSE NOT NULL" ) public boolean isUpdateEventDate() { return updateEventDate; @@ -180,7 +180,7 @@ public void setBeforePeriodDayType( EventPeriodDayType beforePeriodDayType ) } @Basic - @Column( name = "before_period_days", nullable = false ) + @Column( name = "before_period_days", nullable = false, columnDefinition = "INTEGER DEFAULT 0 NOT NULL" ) public Integer getBeforePeriodDays() { return beforePeriodDays; @@ -204,7 +204,7 @@ public void setAfterPeriodDayType( EventPeriodDayType afterPeriodDayType ) } @Basic - @Column( name = "after_period_days" ) + @Column( name = "after_period_days", columnDefinition = "INTEGER DEFAULT 0 NOT NULL" ) public Integer getAfterPeriodDays() { return afterPeriodDays; diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/RuleDhisDataReference.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/RuleDhisDataReference.java index a7751992..2088fbbc 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/RuleDhisDataReference.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/RuleDhisDataReference.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.model; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -57,6 +57,8 @@ public class RuleDhisDataReference extends VersionedBaseMetadata implements Seri { private static final long serialVersionUID = -2784006479143123933L; + public static final int MAX_SCRIPT_ARG_NAME_LENGTH = 230; + private AbstractRule rule; private Reference dataReference; diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/FhirResourceMappingRepository.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/FhirResourceMappingRepository.java index 91401b3f..9761a51b 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/FhirResourceMappingRepository.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/FhirResourceMappingRepository.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.repository; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,6 +37,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.querydsl.QuerydslPredicateExecutor; import org.springframework.data.repository.query.Param; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; import org.springframework.data.rest.core.annotation.RestResource; import org.springframework.security.access.prepost.PreAuthorize; @@ -51,6 +52,7 @@ * @author volsch */ @CacheConfig( cacheManager = "metadataCacheManager", cacheNames = "resourceMapping" ) +@RepositoryRestResource @PreAuthorize( "hasRole('DATA_MAPPING')" ) public interface FhirResourceMappingRepository extends JpaRepository, QuerydslPredicateExecutor { diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramRepository.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramRepository.java index 0de31a63..cd65fca5 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramRepository.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramRepository.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.repository; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,15 +31,19 @@ import org.dhis2.fhir.adapter.dhis.model.Reference; import org.dhis2.fhir.adapter.fhir.metadata.model.MappedTrackerProgram; import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.querydsl.QuerydslPredicateExecutor; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; import org.springframework.data.rest.core.annotation.RestResource; import org.springframework.security.access.prepost.PreAuthorize; import javax.annotation.Nonnull; import java.util.Collection; +import java.util.List; import java.util.UUID; /** @@ -48,6 +52,7 @@ * @author volsch */ @CacheConfig( cacheManager = "metadataCacheManager", cacheNames = "mappedProgram" ) +@RepositoryRestResource( path = "trackerPrograms", collectionResourceRel = "trackerPrograms", itemResourceRel = "trackerProgram" ) @PreAuthorize( "hasRole('DATA_MAPPING')" ) public interface MappedTrackerProgramRepository extends JpaRepository, QuerydslPredicateExecutor { @@ -56,4 +61,45 @@ public interface MappedTrackerProgramRepository extends JpaRepository findAllPolledProgramReferences(); + + @Override + @Nonnull + @CacheEvict( allEntries = true ) + List saveAll( @Nonnull Iterable entities ); + + @Override + @Nonnull + @CachePut( key = "#a0.id" ) + @CacheEvict( allEntries = true ) + S saveAndFlush( @Nonnull S entity ); + + @Override + @Nonnull + @CachePut( key = "#a0.id" ) + @CacheEvict( allEntries = true ) + S save( @Nonnull S entity ); + + @Override + @CacheEvict( allEntries = true ) + void deleteInBatch( @Nonnull Iterable entities ); + + @Override + @CacheEvict( allEntries = true ) + void deleteAllInBatch(); + + @Override + @CacheEvict( key = "#a0" ) + void deleteById( @Nonnull UUID id ); + + @Override + @CacheEvict( key = "#a0.id" ) + void delete( @Nonnull MappedTrackerProgram entity ); + + @Override + @CacheEvict( allEntries = true ) + void deleteAll( @Nonnull Iterable entities ); + + @Override + @CacheEvict( allEntries = true ) + void deleteAll(); } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramStageRepository.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramStageRepository.java index 8b45ff35..342cb315 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramStageRepository.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramStageRepository.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.repository; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,9 +29,16 @@ */ import org.dhis2.fhir.adapter.fhir.metadata.model.MappedTrackerProgramStage; +import org.springframework.cache.annotation.CacheConfig; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.CachePut; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.querydsl.QuerydslPredicateExecutor; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; +import org.springframework.security.access.prepost.PreAuthorize; +import javax.annotation.Nonnull; +import java.util.List; import java.util.UUID; /** @@ -39,6 +46,49 @@ * * @author volsch */ +@CacheConfig( cacheManager = "metadataCacheManager", cacheNames = "mappedProgramStage" ) +@RepositoryRestResource( path = "trackerProgramStages", collectionResourceRel = "trackerProgramStages", itemResourceRel = "trackerProgramStage" ) +@PreAuthorize( "hasRole('DATA_MAPPING')" ) public interface MappedTrackerProgramStageRepository extends JpaRepository, QuerydslPredicateExecutor { + @Override + @Nonnull + @CacheEvict( allEntries = true ) + List saveAll( @Nonnull Iterable entities ); + + @Override + @Nonnull + @CachePut( key = "#a0.id" ) + @CacheEvict( allEntries = true ) + S saveAndFlush( @Nonnull S entity ); + + @Override + @Nonnull + @CachePut( key = "#a0.id" ) + @CacheEvict( allEntries = true ) + S save( @Nonnull S entity ); + + @Override + @CacheEvict( allEntries = true ) + void deleteInBatch( @Nonnull Iterable entities ); + + @Override + @CacheEvict( allEntries = true ) + void deleteAllInBatch(); + + @Override + @CacheEvict( key = "#a0" ) + void deleteById( @Nonnull UUID id ); + + @Override + @CacheEvict( key = "#a0.id" ) + void delete( @Nonnull MappedTrackerProgramStage entity ); + + @Override + @CacheEvict( allEntries = true ) + void deleteAll( @Nonnull Iterable entities ); + + @Override + @CacheEvict( allEntries = true ) + void deleteAll(); } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/AbstractRuleEventListener.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/AbstractRuleEventListener.java new file mode 100644 index 00000000..b5e524c4 --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/AbstractRuleEventListener.java @@ -0,0 +1,55 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository.listener; + +/* + * 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.fhir.metadata.model.AbstractRule; +import org.springframework.data.rest.core.event.AbstractRepositoryEventListener; + +/** + * Event listener that prepares {@link AbstractRule} class before saving. + * + * @author volsch + */ +public abstract class AbstractRuleEventListener extends AbstractRepositoryEventListener +{ + @Override + protected void onBeforeCreate( AbstractRule entity ) + { + onBeforeSave( entity ); + } + + @Override + protected void onBeforeSave( AbstractRule entity ) + { + if ( entity.getDhisDataReferences() != null ) + { + entity.getDhisDataReferences().stream().filter( dr -> dr.getRule() == null ).forEach( dr -> dr.setRule( entity ) ); + } + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/ProgramStageRuleEventListener.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/ProgramStageRuleEventListener.java new file mode 100644 index 00000000..995f8ca8 --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/ProgramStageRuleEventListener.java @@ -0,0 +1,52 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository.listener; + +/* + * 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.fhir.metadata.model.ProgramStageRule; +import org.springframework.data.rest.core.event.AbstractRepositoryEventListener; + +/** + * Event listener that prepares {@link ProgramStageRule} class before saving. + * + * @author volsch + */ +public class ProgramStageRuleEventListener extends AbstractRepositoryEventListener +{ + @Override + protected void onBeforeCreate( ProgramStageRule entity ) + { + super.onBeforeCreate( entity ); + } + + @Override + protected void onBeforeSave( ProgramStageRule entity ) + { + super.onBeforeSave( entity ); + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/TrackedEntityRuleEventListener.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/TrackedEntityRuleEventListener.java new file mode 100644 index 00000000..853459fa --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/listener/TrackedEntityRuleEventListener.java @@ -0,0 +1,52 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository.listener; + +/* + * 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.fhir.metadata.model.TrackedEntityRule; +import org.springframework.data.rest.core.event.AbstractRepositoryEventListener; + +/** + * Event listener that prepares {@link TrackedEntityRule} class before saving. + * + * @author volsch + */ +public class TrackedEntityRuleEventListener extends AbstractRepositoryEventListener +{ + @Override + protected void onBeforeCreate( TrackedEntityRule entity ) + { + super.onBeforeCreate( entity ); + } + + @Override + protected void onBeforeSave( TrackedEntityRule entity ) + { + super.onBeforeSave( entity ); + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/AbstractBeforeCreateSaveRuleValidator.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/AbstractBeforeCreateSaveRuleValidator.java index 31d823a2..85d41d52 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/AbstractBeforeCreateSaveRuleValidator.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/AbstractBeforeCreateSaveRuleValidator.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.repository.validator; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,6 +33,7 @@ import org.dhis2.fhir.adapter.fhir.metadata.model.DataType; import org.dhis2.fhir.adapter.fhir.metadata.model.ExecutableScript; import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType; +import org.dhis2.fhir.adapter.fhir.metadata.model.RuleDhisDataReference; import org.dhis2.fhir.adapter.fhir.metadata.model.ScriptType; import org.dhis2.fhir.adapter.fhir.metadata.model.TransformDataType; import org.springframework.validation.Errors; @@ -71,10 +72,36 @@ protected void validate( Object target, @Nonnull TransformDataType transformData } else { - checkValidApplicableInScript( errors, "applicableImpScript", rule.getFhirResourceType(), rule.getApplicableImpScript() ); checkValidTransformInScript( errors, "transformImpScript", rule.getFhirResourceType(), transformDataType, rule.getTransformImpScript() ); } + + if ( rule.getDhisDataReferences() != null ) + { + int index = 0; + for ( RuleDhisDataReference dataReference : rule.getDhisDataReferences() ) + { + errors.pushNestedPath( "dataReferences[" + index + "]" ); + if ( (dataReference.getRule() != null) && (dataReference.getRule() != rule) ) + { + errors.rejectValue( "rule", "AbstractRule.dataReference.rule.invalid", "Data element must reference rule that includes the data reference." ); + } + if ( StringUtils.length( dataReference.getScriptArgName() ) > RuleDhisDataReference.MAX_SCRIPT_ARG_NAME_LENGTH ) + { + errors.rejectValue( "scriptArgName", "AbstractRule.dataReference.scriptArgName.length", new Object[]{ RuleDhisDataReference.MAX_SCRIPT_ARG_NAME_LENGTH }, "Script argument name length must not be longer than {} characters." ); + } + if ( dataReference.getDataReference() == null ) + { + errors.rejectValue( "dataReference", "AbstractRule.dataReference.dataReference.null", "Data reference is mandatory." ); + } + else if ( !dataReference.getDataReference().isValid() ) + { + errors.rejectValue( "rule", "AbstractRule.dataReference.dataReference.invalid", "Data reference is invalid." ); + } + errors.popNestedPath(); + index++; + } + } } protected static void checkValidApplicableInScript( @NonNull Errors errors, @Nonnull String field, @Nonnull FhirResourceType fhirResourceType, @Nullable ExecutableScript executableScript ) diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveFhirResourceMappingValidator.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveFhirResourceMappingValidator.java index e1b6fc83..863dbbba 100644 --- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveFhirResourceMappingValidator.java +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveFhirResourceMappingValidator.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.repository.validator; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,14 +66,14 @@ public void validate( Object target, @Nonnull Errors errors ) } if ( fhirResourceMapping.getFhirResourceType() != null ) { - checkValidTeiLookupScript( errors, "teiLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpTeiLookupScript() ); - checkValidOrgLookupScript( errors, "FhirResourceMapping.", "enrollmentOrgLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEnrollmentOrgLookupScript() ); - checkValidOrgLookupScript( errors, "FhirResourceMapping.", "eventOrgLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEventOrgLookupScript() ); - checkValidLocationLookupScript( errors, "FhirResourceMapping.", "enrollmentLocationLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEnrollmentGeoLookupScript() ); - checkValidLocationLookupScript( errors, "FhirResourceMapping.", "eventLocationLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEventGeoLookupScript() ); - checkValidDateLookupScript( errors, "enrollmentDateLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEnrollmentDateLookupScript() ); - checkValidDateLookupScript( errors, "eventDateLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEventDateLookupScript() ); - checkValidDateLookupScript( errors, "effectiveDateLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEffectiveDateLookupScript() ); + checkValidTeiLookupScript( errors, "impTeiLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpTeiLookupScript() ); + checkValidOrgLookupScript( errors, "FhirResourceMapping.", "impEnrollmentOrgLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEnrollmentOrgLookupScript() ); + checkValidOrgLookupScript( errors, "FhirResourceMapping.", "impEventOrgLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEventOrgLookupScript() ); + checkValidLocationLookupScript( errors, "FhirResourceMapping.", "impEnrollmentGeoLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEnrollmentGeoLookupScript() ); + checkValidLocationLookupScript( errors, "FhirResourceMapping.", "impEventGeoLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEventGeoLookupScript() ); + checkValidDateLookupScript( errors, "impEnrollmentDateLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEnrollmentDateLookupScript() ); + checkValidDateLookupScript( errors, "impEventDateLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEventDateLookupScript() ); + checkValidDateLookupScript( errors, "impEffectiveDateLookupScript", fhirResourceMapping.getFhirResourceType(), fhirResourceMapping.getImpEffectiveDateLookupScript() ); } } diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveMappedTrackerProgramStageValidator.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveMappedTrackerProgramStageValidator.java new file mode 100644 index 00000000..9261be2a --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveMappedTrackerProgramStageValidator.java @@ -0,0 +1,130 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository.validator; + +/* + * 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.apache.commons.lang3.StringUtils; +import org.dhis2.fhir.adapter.fhir.metadata.model.DataType; +import org.dhis2.fhir.adapter.fhir.metadata.model.ExecutableScript; +import org.dhis2.fhir.adapter.fhir.metadata.model.MappedTrackerProgramStage; +import org.dhis2.fhir.adapter.fhir.metadata.model.ScriptType; +import org.dhis2.fhir.adapter.fhir.metadata.model.TransformDataType; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; +import reactor.util.annotation.NonNull; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Spring Data REST validator for {@link MappedTrackerProgramStage}. + * + * @author volsch + */ +@Component +public class BeforeCreateSaveMappedTrackerProgramStageValidator implements Validator +{ + @Override + public boolean supports( @Nonnull Class clazz ) + { + return MappedTrackerProgramStage.class.isAssignableFrom( clazz ); + } + + @Override + public void validate( Object target, @Nonnull Errors errors ) + { + final MappedTrackerProgramStage trackerProgramStage = (MappedTrackerProgramStage) target; + + if ( trackerProgramStage.getProgram() == null ) + { + errors.rejectValue( "program", "MappedTrackerProgramStage.program.null", "Program is mandatory." ); + } + if ( trackerProgramStage.getProgramStageReference() == null ) + { + errors.rejectValue( "programStageReference", "MappedTrackerProgramStage.programStageReference.null", "Program stage reference is mandatory." ); + } + if ( StringUtils.isBlank( trackerProgramStage.getName() ) ) + { + errors.rejectValue( "name", "MappedTrackerProgramStage.name.blank", "Name must not be blank." ); + } + if ( StringUtils.length( trackerProgramStage.getName() ) > MappedTrackerProgramStage.MAX_NAME_LENGTH ) + { + errors.rejectValue( "name", "MappedTrackerProgramStage.name.length", new Object[]{ MappedTrackerProgramStage.MAX_NAME_LENGTH }, "Name must not be longer than {0} characters." ); + } + if ( trackerProgramStage.getProgramStageReference() == null ) + { + errors.rejectValue( "programStageReference", "MappedTrackerProgramStage.programReference.null", "Tracker program stage reference is mandatory." ); + } + else if ( !trackerProgramStage.getProgramStageReference().isValid() ) + { + errors.rejectValue( "programStageReference", "MappedTrackerProgramStage.programReference.invalid", "Tracker program stage reference is not valid." ); + } + + checkValidApplicableScript( errors, "creationApplicableScript", trackerProgramStage.getCreationApplicableScript() ); + checkValidLifecycleScript( errors, "creationScript", trackerProgramStage.getCreationScript() ); + checkValidLifecycleScript( errors, "beforeScript", trackerProgramStage.getBeforeScript() ); + checkValidLifecycleScript( errors, "afterScript", trackerProgramStage.getAfterScript() ); + } + + protected static void checkValidApplicableScript( @NonNull Errors errors, @Nonnull String field, @Nullable ExecutableScript executableScript ) + { + if ( executableScript == null ) + { + return; + } + if ( executableScript.getScript().getScriptType() != ScriptType.EVALUATE ) + { + errors.rejectValue( field, "MappedTrackerProgramStage." + field + ".scriptType", "Assigned script type for applicable script must be EVALUATE." ); + } + if ( executableScript.getScript().getReturnType() != DataType.BOOLEAN ) + { + errors.rejectValue( field, "MappedTrackerProgramStage." + field + ".returnType", "Assigned return type for applicable script must be BOOLEAN." ); + } + } + + protected static void checkValidLifecycleScript( @NonNull Errors errors, @Nonnull String field, @Nullable ExecutableScript executableScript ) + { + if ( executableScript == null ) + { + return; + } + if ( (executableScript.getScript().getScriptType() != ScriptType.EVALUATE) && (executableScript.getScript().getScriptType() != ScriptType.TRANSFORM_TO_DHIS) ) + { + errors.rejectValue( field, "MappedTrackerProgramStage." + field + ".scriptType", "Assigned script type for applicable script must be EVALUATE or TRANSFORM_TO_DHIS." ); + } + if ( executableScript.getScript().getReturnType() != DataType.BOOLEAN ) + { + errors.rejectValue( field, "MappedTrackerProgramStage." + field + ".returnType", "Assigned return type for lifecycle script must be BOOLEAN." ); + } + if ( (executableScript.getScript().getScriptType() == ScriptType.TRANSFORM_TO_DHIS) && (executableScript.getScript().getOutputType() != TransformDataType.DHIS_EVENT) ) + { + errors.rejectValue( field, "MappedTrackerProgramStage." + field + ".outputType", "Assigned output type of lifecycle script must be DHIS_EVENT." ); + } + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveMappedTrackerProgramValidator.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveMappedTrackerProgramValidator.java new file mode 100644 index 00000000..d6334981 --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveMappedTrackerProgramValidator.java @@ -0,0 +1,114 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository.validator; + +/* + * 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.apache.commons.lang3.StringUtils; +import org.dhis2.fhir.adapter.fhir.metadata.model.DataType; +import org.dhis2.fhir.adapter.fhir.metadata.model.ExecutableScript; +import org.dhis2.fhir.adapter.fhir.metadata.model.MappedTrackerProgram; +import org.dhis2.fhir.adapter.fhir.metadata.model.ScriptType; +import org.dhis2.fhir.adapter.fhir.metadata.model.TransformDataType; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; +import org.springframework.validation.Validator; +import reactor.util.annotation.NonNull; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +/** + * Spring Data REST validator for {@link MappedTrackerProgram}. + * + * @author volsch + */ +@Component +public class BeforeCreateSaveMappedTrackerProgramValidator implements Validator +{ + @Override + public boolean supports( @Nonnull Class clazz ) + { + return MappedTrackerProgram.class.isAssignableFrom( clazz ); + } + + @Override + public void validate( Object target, @Nonnull Errors errors ) + { + final MappedTrackerProgram trackerProgram = (MappedTrackerProgram) target; + + if ( trackerProgram.getTrackedEntityFhirResourceType() == null ) + { + errors.rejectValue( "trackedEntityFhirResourceType", "MappedTrackerProgram.trackedEntityFhirResourceType.null", "Tracked entity FHIR resource type is mandatory." ); + } + if ( trackerProgram.getTrackedEntityRule() == null ) + { + errors.rejectValue( "trackedEntityRule", "MappedTrackerProgram.trackedEntityRuleReference.null", "Tracked entity rule reference is mandatory." ); + } + if ( StringUtils.isBlank( trackerProgram.getName() ) ) + { + errors.rejectValue( "name", "MappedTrackerProgram.name.blank", "Name must not be blank." ); + } + if ( StringUtils.length( trackerProgram.getName() ) > MappedTrackerProgram.MAX_NAME_LENGTH ) + { + errors.rejectValue( "name", "MappedTrackerProgram.name.length", new Object[]{ MappedTrackerProgram.MAX_NAME_LENGTH }, "Name must not be longer than {0} characters." ); + } + if ( trackerProgram.getProgramReference() == null ) + { + errors.rejectValue( "programReference", "MappedTrackerProgram.programReference.null", "Tracker program reference is mandatory." ); + } + else if ( !trackerProgram.getProgramReference().isValid() ) + { + errors.rejectValue( "programReference", "MappedTrackerProgram.programReference.invalid", "Tracker program reference is not valid." ); + } + + checkValidLifecycleScript( errors, "creationApplicableScript", trackerProgram.getCreationApplicableScript() ); + checkValidLifecycleScript( errors, "creationScript", trackerProgram.getCreationScript() ); + checkValidLifecycleScript( errors, "beforeScript", trackerProgram.getBeforeScript() ); + checkValidLifecycleScript( errors, "afterScript", trackerProgram.getAfterScript() ); + } + + protected static void checkValidLifecycleScript( @NonNull Errors errors, @Nonnull String field, @Nullable ExecutableScript executableScript ) + { + if ( executableScript == null ) + { + return; + } + if ( executableScript.getScript().getScriptType() != ScriptType.EVALUATE ) + { + errors.rejectValue( field, "MappedTrackerProgram." + field + ".scriptType", "Assigned script type for lifecycle script must be EVALUATE." ); + } + if ( executableScript.getScript().getReturnType() != DataType.BOOLEAN ) + { + errors.rejectValue( field, "MappedTrackerProgram." + field + ".returnType", "Assigned return type for lifecycle script must be BOOLEAN." ); + } + if ( (executableScript.getScript().getOutputType() != null) && (executableScript.getScript().getOutputType() != TransformDataType.DHIS_EVENT) ) + { + errors.rejectValue( field, "MappedTrackerProgram." + field + ".outputType", "Assigned output type of lifecycle script must be DHIS_EVENT." ); + } + } +} diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveProgramStageRuleValidator.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveProgramStageRuleValidator.java new file mode 100644 index 00000000..99424fbc --- /dev/null +++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveProgramStageRuleValidator.java @@ -0,0 +1,78 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository.validator; + +/* + * 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.fhir.metadata.model.ApplicableEnrollmentStatus; +import org.dhis2.fhir.adapter.fhir.metadata.model.ApplicableEventStatus; +import org.dhis2.fhir.adapter.fhir.metadata.model.EventStatusUpdate; +import org.dhis2.fhir.adapter.fhir.metadata.model.ProgramStageRule; +import org.dhis2.fhir.adapter.fhir.metadata.model.TransformDataType; +import org.springframework.stereotype.Component; +import org.springframework.validation.Errors; + +import javax.annotation.Nonnull; + +/** + * Spring Data REST validator for {@link ProgramStageRule}. + * + * @author volsch + */ +@Component +public class BeforeCreateSaveProgramStageRuleValidator extends AbstractBeforeCreateSaveRuleValidator +{ + @Override + public boolean supports( @Nonnull Class clazz ) + { + return ProgramStageRule.class.isAssignableFrom( clazz ); + } + + @Override + public void validate( Object target, @Nonnull Errors errors ) + { + final ProgramStageRule rule = (ProgramStageRule) target; + validate( rule, TransformDataType.DHIS_EVENT, errors ); + + if ( rule.getApplicableEnrollmentStatus() == null ) + { + rule.setApplicableEnrollmentStatus( new ApplicableEnrollmentStatus() ); + } + if ( rule.getApplicableEventStatus() == null ) + { + rule.setApplicableEventStatus( new ApplicableEventStatus() ); + } + if ( rule.getEventStatusUpdate() == null ) + { + rule.setEventStatusUpdate( new EventStatusUpdate() ); + } + if ( rule.getProgramStage() == null ) + { + errors.rejectValue( "programStage", "ProgramStageRule.programStage.null", "Program stage is mandatory." ); + } + } +} diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/ExecutableScriptRepositoryRestDocsTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/ExecutableScriptRepositoryRestDocsTest.java index c3e1c957..299286eb 100644 --- a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/ExecutableScriptRepositoryRestDocsTest.java +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/ExecutableScriptRepositoryRestDocsTest.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.repository; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -106,8 +106,8 @@ public void createExecutableScript() throws Exception .perform( get( Objects.requireNonNull( location ) ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) ) .andExpect( status().isOk() ) .andExpect( jsonPath( "lastUpdatedBy", is( "2h2maqu827d" ) ) ) - .andExpect( jsonPath( "name", is( "CP: Birth Weight" ) ) ) - .andExpect( jsonPath( "code", is( "CP_BIRTH_WEIGHT" ) ) ) + .andExpect( jsonPath( "name", is( "CP: Baby Birth Weight" ) ) ) + .andExpect( jsonPath( "code", is( "CP_BABY_BIRTH_WEIGHT" ) ) ) .andExpect( jsonPath( "overrideArguments.length()", is( 2 ) ) ) .andExpect( jsonPath( "_links.self.href", is( location ) ) ); } diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/FhirResourceMappingRepositoryRestDocsTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/FhirResourceMappingRepositoryRestDocsTest.java new file mode 100644 index 00000000..02f9cdfb --- /dev/null +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/FhirResourceMappingRepositoryRestDocsTest.java @@ -0,0 +1,150 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository; + +/* + * 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.apache.commons.io.IOUtils; +import org.dhis2.fhir.adapter.fhir.AbstractJpaRepositoryRestDocsTest; +import org.dhis2.fhir.adapter.fhir.ConstrainedFields; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceMapping; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.ExampleMatcher; +import org.springframework.http.MediaType; +import org.springframework.restdocs.payload.JsonFieldType; + +import javax.annotation.Nonnull; +import java.nio.charset.StandardCharsets; +import java.util.Objects; + +import static org.hamcrest.Matchers.is; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.restdocs.snippet.Attributes.attributes; +import static org.springframework.restdocs.snippet.Attributes.key; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Tests for {@link FhirResourceMappingRepository}. + * + * @author volsch + */ +public class FhirResourceMappingRepositoryRestDocsTest extends AbstractJpaRepositoryRestDocsTest +{ + @Autowired + private FhirResourceMappingRepository fhirResourceMappingRepository; + + @Test + public void createFhirResourceMapping() throws Exception + { + final ConstrainedFields fields = new ConstrainedFields( FhirResourceMapping.class, constraintDescriptionResolver ); + final String request = IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/metadata/repository/createFhirResourceMapping.json", StandardCharsets.UTF_8 ) + .replace( "$executableScriptBaseUri", API_BASE_URI + "/executableScripts" ); + final String location = docMockMvc.perform( post( "/api/fhirResourceMappings" ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( request ) ) + .andExpect( status().isCreated() ) + .andExpect( header().exists( "Location" ) ) + .andDo( documentationHandler.document( requestFields( + attributes( key( "title" ).value( "Fields for FHIR resource mapping creation" ) ), + fields.withPath( "fhirResourceType" ).description( "The unique FHIR resource type for which the definition is made." ).type( JsonFieldType.STRING ), + fields.withPath( "deleteWhenAbsent" ).description( "Used for the export of data (not yet supported officially)." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "impTeiLookupScript" ).description( "Link to the executable script that returns the FHIR resource for the TEI that is assigned to the evaluated mapped FHIR resource. The return type of the script must be FHIR_RESOURCE." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "impEventOrgLookupScript" ).description( "Link to the executable evaluation script that returns a reference to a DHIS2 organization unit of an event. The return type of the script must be ORG_UNIT_REF." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "impEventGeoLookupScript" ).description( "Link to the executable evaluation script that returns a location (longitude and latitude) of an event. The returns type of the script must be LOCATION." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "impEventDateLookupScript" ).description( "Link to the executable evaluation script that returns the event date. The return type of the script must be DATE_TIME." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "impEnrollmentOrgLookupScript" ).description( "Link to the executable evaluation script that returns a reference to a DHIS2 organization unit of an enrollment. The return type of the script must be ORG_UNIT_REF." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "impEnrollmentGeoLookupScript" ).description( "Link to the executable evaluation script that returns a location (longitude and latitude) of an event. The returns type of the script must be LOCATION." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "impEnrollmentDateLookupScript" ).description( "Link to the executable evaluation script that returns the event date. The return type of the script must be DATE_TIME." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "impEffectiveDateLookupScript" ).description( "Link to the executable evaluation script that extract the effective date when the data has been collected. The return type of the script must be DATE_TIME." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "expAbsentTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "expTeiTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "expOrgUnitTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "expGeoTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "expStatusTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "expDateTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "expGroupTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).type( JsonFieldType.STRING ).optional() + ) ) ).andReturn().getResponse().getHeader( "Location" ); + + mockMvc + .perform( get( Objects.requireNonNull( location ) ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) ) + .andExpect( status().isOk() ) + .andExpect( jsonPath( "lastUpdatedBy", is( "2h2maqu827d" ) ) ) + .andExpect( jsonPath( "fhirResourceType", is( "IMMUNIZATION" ) ) ) + .andExpect( jsonPath( "_links.self.href", is( location ) ) ); + } + + @Test + public void readFhirResourceMapping() throws Exception + { + final ConstrainedFields fields = new ConstrainedFields( FhirResourceMapping.class, constraintDescriptionResolver ); + final String fhirResourceMappingId = loadFhirResourceMapping( FhirResourceType.OBSERVATION ).getId().toString(); + docMockMvc.perform( get( "/api/fhirResourceMappings/{fhirResourceMappingId}", fhirResourceMappingId ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) ) + .andExpect( status().isOk() ) + .andDo( documentationHandler.document( links( + linkWithRel( "self" ).description( "Link to this resource itself." ), + linkWithRel( "fhirResourceMapping" ).description( "Link to this resource itself." ), + linkWithRel( "impTeiLookupScript" ).description( "Link to the executable script that returns the FHIR resource for the TEI that is assigned to the evaluated mapped FHIR resource. The return type of the script must be FHIR_RESOURCE." ).optional(), + linkWithRel( "impEventOrgLookupScript" ).description( "Link to the executable evaluation script that returns a reference to a DHIS2 organization unit of an event. The return type of the script must be ORG_UNIT_REF." ).optional(), + linkWithRel( "impEventGeoLookupScript" ).description( "Link to the executable evaluation script that returns a location (longitude and latitude) of an event. The returns type of the script must be LOCATION." ).optional(), + linkWithRel( "impEventDateLookupScript" ).description( "Link to the executable evaluation script that returns the event date. The return type of the script must be DATE_TIME." ).optional(), + linkWithRel( "impEnrollmentOrgLookupScript" ).description( "Link to the executable evaluation script that returns a reference to a DHIS2 organization unit of an enrollment. The return type of the script must be ORG_UNIT_REF." ).optional(), + linkWithRel( "impEnrollmentGeoLookupScript" ).description( "Link to the executable evaluation script that returns a location (longitude and latitude) of an event. The returns type of the script must be LOCATION." ).optional(), + linkWithRel( "impEnrollmentDateLookupScript" ).description( "Link to the executable evaluation script that returns the event date. The return type of the script must be DATE_TIME." ).optional(), + linkWithRel( "impEffectiveDateLookupScript" ).description( "Link to the executable evaluation script that extract the effective date when the data has been collected. The return type of the script must be DATE_TIME." ).optional(), + linkWithRel( "expAbsentTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).optional(), + linkWithRel( "expTeiTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).optional(), + linkWithRel( "expOrgUnitTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).optional(), + linkWithRel( "expGeoTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).optional(), + linkWithRel( "expStatusTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).optional(), + linkWithRel( "expDateTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).optional(), + linkWithRel( "expGroupTransformScript" ).description( "Used for the export of data (not yet supported officially)." ).optional() ), + responseFields( + attributes( key( "title" ).value( "Fields for tracked entity reading" ) ), + fields.withPath( "createdAt" ).description( "The timestamp when the resource has been created." ).type( JsonFieldType.STRING ), + fields.withPath( "lastUpdatedBy" ).description( "The ID of the user that has updated the user the last time or null if the data has been imported to the database directly." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "lastUpdatedAt" ).description( "The timestamp when the resource has been updated the last time." ).type( JsonFieldType.STRING ), + fields.withPath( "fhirResourceType" ).description( "The unique FHIR resource type for which the definition is made." ).type( JsonFieldType.STRING ), + fields.withPath( "deleteWhenAbsent" ).description( "Used for the export of data (not yet supported officially)." ).type( JsonFieldType.BOOLEAN ).optional(), + subsectionWithPath( "_links" ).description( "Links to other resources" ) + ) ) ); + } + + @Nonnull + protected FhirResourceMapping loadFhirResourceMapping( @Nonnull FhirResourceType fhirResourceType ) + { + final FhirResourceMapping example = new FhirResourceMapping(); + example.setFhirResourceType( fhirResourceType ); + return fhirResourceMappingRepository.findOne( Example.of( example, ExampleMatcher.matching().withIgnorePaths( "deleteWhenAbsent" ) ) ) + .orElseThrow( () -> new AssertionError( "FHIR resource mapping does not exist: " + fhirResourceType ) ); + } +} \ No newline at end of file diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramRepositoryRestDocsTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramRepositoryRestDocsTest.java new file mode 100644 index 00000000..7dcd523a --- /dev/null +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramRepositoryRestDocsTest.java @@ -0,0 +1,174 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository; + +/* + * 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.apache.commons.io.IOUtils; +import org.dhis2.fhir.adapter.fhir.AbstractJpaRepositoryRestDocsTest; +import org.dhis2.fhir.adapter.fhir.ConstrainedFields; +import org.dhis2.fhir.adapter.fhir.metadata.model.MappedTrackerProgram; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.restdocs.payload.JsonFieldType; + +import javax.annotation.Nonnull; +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.UUID; + +import static org.hamcrest.Matchers.is; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.restdocs.snippet.Attributes.attributes; +import static org.springframework.restdocs.snippet.Attributes.key; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Tests for {@link MappedTrackerProgramRepository}. + * + * @author volsch + */ +public class MappedTrackerProgramRepositoryRestDocsTest extends AbstractJpaRepositoryRestDocsTest +{ + @Autowired + private MappedTrackerProgramRepository mappedTrackerProgramRepository; + + @Test + public void createProgram() throws Exception + { + final ConstrainedFields fields = new ConstrainedFields( MappedTrackerProgram.class, constraintDescriptionResolver ); + final String request = IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgram.json", StandardCharsets.UTF_8 ) + .replace( "$apiBaseUri", API_BASE_URI ); + final String location = docMockMvc.perform( post( "/api/trackerPrograms" ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( request ) ) + .andExpect( status().isCreated() ) + .andExpect( header().exists( "Location" ) ) + .andDo( documentationHandler.document( requestFields( + attributes( key( "title" ).value( "Fields for tracker program creation" ) ), + fields.withPath( "name" ).description( "The unique name of the program." ).type( JsonFieldType.STRING ), + fields.withPath( "description" ).description( "The detailed description that describes for which purpose the program is used." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "enabled" ).description( "Specifies if this rule is enabled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "expEnabled" ).description( "Specifies if output transformation from DHIS to FHIR for this tracked entity type is enabled." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "programReference" ).description( "The reference to the DHIS2 Program." ).type( JsonFieldType.OBJECT ), + fields.withPath( "programReference.value" ).description( "The unique ID/code/name of the Program." ).type( JsonFieldType.STRING ), + fields.withPath( "programReference.type" ).description( "The type of reference value of the Program." ).type( JsonFieldType.STRING ), + fields.withPath( "trackedEntityFhirResourceType" ).description( "The FHIR resource type of the mapped tracked entity." ).type( JsonFieldType.STRING ), + fields.withPath( "fhirCreateEnabled" ).description( "Specifies if the creation of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type (by default true)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirUpdateEnabled" ).description( "Specifies if the update of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type. (by default false)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirDeleteEnabled" ).description( "Specifies if the deletion of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type. (by default false)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "creationEnabled" ).description( "Specifies if the automatic creation of this program has been enabled (by default false)." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "creationStatus" ).description( "The status of the event when it is created automatically." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "enrollmentDateIsIncident" ).description( "Specifies if the enrollment date should be set based on the incident date." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "beforePeriodDayType" ).description( "Specifies to which date the the amount of the specified before period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "beforePeriodDays" ).description( "The day (relative according to the specified setting) on and after which FHIR resources (according to their effective date) are regarded as being applicable for this program ." ) + .type( JsonFieldType.NUMBER ).optional(), + fields.withPath( "afterPeriodDayType" ).description( "Specifies to which date the the amount of the specified after period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "afterPeriodDays" ).description( "The day (relative according to the specified setting) on and before which FHIR resources (according to their effective date) are regarded as being applicable for this program ." ) + .type( JsonFieldType.NUMBER ).optional(), + fields.withPath( "trackedEntityRule" ).description( "Link to the tracked entity rule that is used for the tracked entity of this program." ).type( JsonFieldType.STRING ), + fields.withPath( "creationApplicableScript" ).description( "Link to the script that evaluates if the creation of the program is applicable (when creation is enabled)." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "creationScript" ).description( "Link to the evaluation of transformation script that is executed when the program event is created (when creation is enabled)." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "beforeScript" ).description( "Link to the evaluation of transformation script that is executed before the transformed FHIR resource is processed." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "afterScript" ).description( "Link to the evaluation of transformation script that is executed after the transformed FHIR resource has been processed." ).type( JsonFieldType.STRING ).optional() + ) ) ).andReturn().getResponse().getHeader( "Location" ); + + mockMvc + .perform( get( Objects.requireNonNull( location ) ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) ) + .andExpect( status().isOk() ) + .andExpect( jsonPath( "lastUpdatedBy", is( "2h2maqu827d" ) ) ) + .andExpect( jsonPath( "name", is( "Mother Programme" ) ) ) + .andExpect( jsonPath( "enabled", is( true ) ) ) + .andExpect( jsonPath( "expEnabled", is( false ) ) ) + .andExpect( jsonPath( "fhirCreateEnabled", is( true ) ) ) + .andExpect( jsonPath( "fhirUpdateEnabled", is( false ) ) ) + .andExpect( jsonPath( "programReference.value", is( "Mother Programme" ) ) ) + .andExpect( jsonPath( "programReference.type", is( "NAME" ) ) ) + .andExpect( jsonPath( "_links.self.href", is( location ) ) ); + } + + @Test + public void readProgram() throws Exception + { + final ConstrainedFields fields = new ConstrainedFields( MappedTrackerProgram.class, constraintDescriptionResolver ); + final String programId = loadProgram( UUID.fromString( "45e61665-754d-4861-891e-a2064fc0ae7d" ) ).getId().toString(); + docMockMvc.perform( get( "/api/trackerPrograms/{programId}", programId ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) ) + .andExpect( status().isOk() ) + .andDo( documentationHandler.document( links( + linkWithRel( "self" ).description( "Link to this resource itself." ), + linkWithRel( "trackerProgram" ).description( "Link to this resource itself." ), + linkWithRel( "trackedEntityRule" ).description( "Link to the tracked entity rule that is used for the tracked entity of this program." ), + linkWithRel( "creationApplicableScript" ).description( "Link to the script that evaluates if the creation of the program is applicable (when creation is enabled)." ).optional(), + linkWithRel( "creationScript" ).description( "Link to the evaluation of transformation script that is executed when the program event is created (when creation is enabled)." ).optional(), + linkWithRel( "beforeScript" ).description( "Link to the evaluation of transformation script that is executed before the transformed FHIR resource is processed." ).optional(), + linkWithRel( "afterScript" ).description( "Link to the evaluation of transformation script that is executed after the transformed FHIR resource has been processed." ).optional() ), + responseFields( + attributes( key( "title" ).value( "Fields for tracker program reading" ) ), + fields.withPath( "createdAt" ).description( "The timestamp when the resource has been created." ).type( JsonFieldType.STRING ), + fields.withPath( "lastUpdatedBy" ).description( "The ID of the user that has updated the user the last time or null if the data has been imported to the database directly." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "lastUpdatedAt" ).description( "The timestamp when the resource has been updated the last time." ).type( JsonFieldType.STRING ), + fields.withPath( "name" ).description( "The unique name of the program." ).type( JsonFieldType.STRING ), + fields.withPath( "description" ).description( "The detailed description that describes for which purpose the program is used." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "enabled" ).description( "Specifies if this rule is enabled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "expEnabled" ).description( "Specifies if output transformation from DHIS to FHIR for this tracked entity type is enabled." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "programReference" ).description( "The reference to the DHIS2 Program." ).type( JsonFieldType.OBJECT ), + fields.withPath( "programReference.value" ).description( "The unique ID/code/name of the Program." ).type( JsonFieldType.STRING ), + fields.withPath( "programReference.type" ).description( "The type of reference value of the Program." ).type( JsonFieldType.STRING ), + fields.withPath( "trackedEntityFhirResourceType" ).description( "The FHIR resource type of the mapped tracked entity." ).type( JsonFieldType.STRING ), + fields.withPath( "fhirCreateEnabled" ).description( "Specifies if the creation of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type (by default true)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirUpdateEnabled" ).description( "Specifies if the update of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type. (by default false)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirDeleteEnabled" ).description( "Specifies if the deletion of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type. (by default false)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "creationEnabled" ).description( "Specifies if the automatic creation of this program has been enabled (by default false)." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "creationStatus" ).description( "The status of the event when it is created automatically." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "enrollmentDateIsIncident" ).description( "Specifies if the enrollment date should be set based on the incident date." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "beforePeriodDayType" ).description( "Specifies to which date the the amount of the specified before period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "beforePeriodDays" ).description( "The day (relative according to the specified setting) on and after which FHIR resources (according to their effective date) are regarded as being applicable for this program ." ) + .type( JsonFieldType.NUMBER ).optional(), + fields.withPath( "afterPeriodDayType" ).description( "Specifies to which date the the amount of the specified after period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "afterPeriodDays" ).description( "The day (relative according to the specified setting) on and before which FHIR resources (according to their effective date) are regarded as being applicable for this program ." ) + .type( JsonFieldType.NUMBER ).optional(), + subsectionWithPath( "_links" ).description( "Links to other resources" ) + ) ) ); + } + + @Nonnull + protected MappedTrackerProgram loadProgram( @Nonnull UUID id ) + { + return mappedTrackerProgramRepository.findById( id ) + .orElseThrow( () -> new AssertionError( "Mapped tracker program does not exist: " + id ) ); + } +} \ No newline at end of file diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramStageRepositoryRestDocsTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramStageRepositoryRestDocsTest.java new file mode 100644 index 00000000..269269b7 --- /dev/null +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/MappedTrackerProgramStageRepositoryRestDocsTest.java @@ -0,0 +1,172 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository; + +/* + * 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.apache.commons.io.IOUtils; +import org.dhis2.fhir.adapter.fhir.AbstractJpaRepositoryRestDocsTest; +import org.dhis2.fhir.adapter.fhir.ConstrainedFields; +import org.dhis2.fhir.adapter.fhir.metadata.model.MappedTrackerProgramStage; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.restdocs.payload.JsonFieldType; + +import javax.annotation.Nonnull; +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.UUID; + +import static org.hamcrest.Matchers.is; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.restdocs.snippet.Attributes.attributes; +import static org.springframework.restdocs.snippet.Attributes.key; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Tests for {@link MappedTrackerProgramStageRepository}. + * + * @author volsch + */ +public class MappedTrackerProgramStageRepositoryRestDocsTest extends AbstractJpaRepositoryRestDocsTest +{ + @Autowired + private MappedTrackerProgramStageRepository mappedTrackerProgramStageRepository; + + @Test + public void createProgramStage() throws Exception + { + final ConstrainedFields fields = new ConstrainedFields( MappedTrackerProgramStage.class, constraintDescriptionResolver ); + final String request = IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgramStage.json", StandardCharsets.UTF_8 ) + .replace( "$apiBaseUri", API_BASE_URI ); + final String location = docMockMvc.perform( post( "/api/trackerProgramStages" ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( request ) ) + .andExpect( status().isCreated() ) + .andExpect( header().exists( "Location" ) ) + .andDo( documentationHandler.document( requestFields( + attributes( key( "title" ).value( "Fields for tracker program stage creation" ) ), + fields.withPath( "name" ).description( "The unique name of the program stage." ).type( JsonFieldType.STRING ), + fields.withPath( "description" ).description( "The detailed description that describes for which purpose the program stage is used." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "enabled" ).description( "Specifies if this rule is enabled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "expEnabled" ).description( "Specifies if output transformation from DHIS to FHIR for this tracked entity type is enabled." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "programStageReference" ).description( "The reference to the DHIS2 Program Stage." ).type( JsonFieldType.OBJECT ), + fields.withPath( "programStageReference.value" ).description( "The unique ID/code/name of the Program Stage." ).type( JsonFieldType.STRING ), + fields.withPath( "programStageReference.type" ).description( "The type of reference value of the Program Stage." ).type( JsonFieldType.STRING ), + fields.withPath( "fhirCreateEnabled" ).description( "Specifies if the creation of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type (by default true)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirUpdateEnabled" ).description( "Specifies if the update of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type. (by default false)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirDeleteEnabled" ).description( "Specifies if the deletion of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type. (by default false)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "creationEnabled" ).description( "Specifies if the automatic creation of this program stage has been enabled (by default false)." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "creationStatus" ).description( "The status of the event when it is created automatically." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "eventDateIsIncident" ).description( "Specifies if the event date should be set based on the incident date." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "beforePeriodDayType" ).description( "Specifies to which date the the amount of the specified before period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "beforePeriodDays" ).description( "The day (relative according to the specified setting) on and after which FHIR resources (according to their effective date) are regarded as being applicable for this program stage." ) + .type( JsonFieldType.NUMBER ).optional(), + fields.withPath( "afterPeriodDayType" ).description( "Specifies to which date the the amount of the specified after period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "afterPeriodDays" ).description( "The day (relative according to the specified setting) on and before which FHIR resources (according to their effective date) are regarded as being applicable for this program stage." ) + .type( JsonFieldType.NUMBER ).optional(), + fields.withPath( "program" ).description( "Link to the tracker program to which this stage belongs to." ).type( JsonFieldType.STRING ), + fields.withPath( "creationApplicableScript" ).description( "Link to the script that evaluates if the creation of the program stage is applicable (when creation is enabled)." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "creationScript" ).description( "Link to the evaluation of transformation script that is executed when the program stage event is created (when creation is enabled)." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "beforeScript" ).description( "Link to the evaluation of transformation script that is executed before the transformed FHIR resource is processed." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "afterScript" ).description( "Link to the evaluation of transformation script that is executed after the transformed FHIR resource has been processed." ).type( JsonFieldType.STRING ).optional() + ) ) ).andReturn().getResponse().getHeader( "Location" ); + + mockMvc + .perform( get( Objects.requireNonNull( location ) ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) ) + .andExpect( status().isOk() ) + .andExpect( jsonPath( "lastUpdatedBy", is( "2h2maqu827d" ) ) ) + .andExpect( jsonPath( "name", is( "Baby Postnatal" ) ) ) + .andExpect( jsonPath( "enabled", is( true ) ) ) + .andExpect( jsonPath( "expEnabled", is( false ) ) ) + .andExpect( jsonPath( "fhirCreateEnabled", is( true ) ) ) + .andExpect( jsonPath( "fhirUpdateEnabled", is( false ) ) ) + .andExpect( jsonPath( "programStageReference.value", is( "Baby Postnatal" ) ) ) + .andExpect( jsonPath( "programStageReference.type", is( "NAME" ) ) ) + .andExpect( jsonPath( "_links.self.href", is( location ) ) ); + } + + @Test + public void readProgramStage() throws Exception + { + final ConstrainedFields fields = new ConstrainedFields( MappedTrackerProgramStage.class, constraintDescriptionResolver ); + final String programStageId = loadProgramStage( UUID.fromString( "4c074c85-be49-4b9d-8973-9e16b9615dad" ) ).getId().toString(); + docMockMvc.perform( get( "/api/trackerProgramStages/{programStageId}", programStageId ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) ) + .andExpect( status().isOk() ) + .andDo( documentationHandler.document( links( + linkWithRel( "self" ).description( "Link to this resource itself." ), + linkWithRel( "trackerProgramStage" ).description( "Link to this resource itself." ), + linkWithRel( "program" ).description( "Link to the tracker program to which this stage belongs to." ), + linkWithRel( "creationApplicableScript" ).description( "Link to the script that evaluates if the creation of the program stage is applicable (when creation is enabled)." ).optional(), + linkWithRel( "creationScript" ).description( "Link to the evaluation of transformation script that is executed when the program stage event is created (when creation is enabled)." ).optional(), + linkWithRel( "beforeScript" ).description( "Link to the evaluation of transformation script that is executed before the transformed FHIR resource is processed." ).optional(), + linkWithRel( "afterScript" ).description( "Link to the evaluation of transformation script that is executed after the transformed FHIR resource has been processed." ).optional() ), + responseFields( + attributes( key( "title" ).value( "Fields for tracker program stage reading" ) ), + fields.withPath( "createdAt" ).description( "The timestamp when the resource has been created." ).type( JsonFieldType.STRING ), + fields.withPath( "lastUpdatedBy" ).description( "The ID of the user that has updated the user the last time or null if the data has been imported to the database directly." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "lastUpdatedAt" ).description( "The timestamp when the resource has been updated the last time." ).type( JsonFieldType.STRING ), + fields.withPath( "name" ).description( "The unique name of the program stage." ).type( JsonFieldType.STRING ), + fields.withPath( "description" ).description( "The detailed description that describes for which purpose the program stage is used." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "enabled" ).description( "Specifies if this rule is enabled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "expEnabled" ).description( "Specifies if output transformation from DHIS to FHIR for this tracked entity type is enabled." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "programStageReference" ).description( "The reference to the DHIS2 Program Stage." ).type( JsonFieldType.OBJECT ), + fields.withPath( "programStageReference.value" ).description( "The unique ID/code/name of the Program Stage." ).type( JsonFieldType.STRING ), + fields.withPath( "programStageReference.type" ).description( "The type of reference value of the Program Stage." ).type( JsonFieldType.STRING ), + fields.withPath( "fhirCreateEnabled" ).description( "Specifies if the creation of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type (by default true)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirUpdateEnabled" ).description( "Specifies if the update of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type. (by default false)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirDeleteEnabled" ).description( "Specifies if the deletion of a FHIR resource is enabled for output transformations from DHIS to FHIR for this tracked entity type. (by default false)." ) + .type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "creationEnabled" ).description( "Specifies if the automatic creation of this program stage has been enabled (by default false)." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "creationStatus" ).description( "The status of the event when it is created automatically." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "eventDateIsIncident" ).description( "Specifies if the event date should be set based on the incident date." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "beforePeriodDayType" ).description( "Specifies to which date the the amount of the specified before period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "beforePeriodDays" ).description( "The day (relative according to the specified setting) on and after which FHIR resources (according to their effective date) are regarded as being applicable for this program stage." ) + .type( JsonFieldType.NUMBER ).optional(), + fields.withPath( "afterPeriodDayType" ).description( "Specifies to which date the the amount of the specified after period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "afterPeriodDays" ).description( "The day (relative according to the specified setting) on and before which FHIR resources (according to their effective date) are regarded as being applicable for this program stage." ) + .type( JsonFieldType.NUMBER ).optional(), + subsectionWithPath( "_links" ).description( "Links to other resources" ) + ) ) ); + } + + @Nonnull + protected MappedTrackerProgramStage loadProgramStage( @Nonnull UUID id ) + { + return mappedTrackerProgramStageRepository.findById( id ) + .orElseThrow( () -> new AssertionError( "Mapped tracker program stage does not exist: " + id ) ); + } +} \ No newline at end of file diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/ProgramStageRuleRepositoryRestDocsTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/ProgramStageRuleRepositoryRestDocsTest.java new file mode 100644 index 00000000..1d6b17a4 --- /dev/null +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/ProgramStageRuleRepositoryRestDocsTest.java @@ -0,0 +1,262 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository; + +/* + * 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.apache.commons.io.IOUtils; +import org.dhis2.fhir.adapter.fhir.AbstractJpaRepositoryRestDocsTest; +import org.dhis2.fhir.adapter.fhir.ConstrainedFields; +import org.dhis2.fhir.adapter.fhir.metadata.model.AbstractRule; +import org.dhis2.fhir.adapter.fhir.metadata.model.ExecutableScript; +import org.dhis2.fhir.adapter.fhir.metadata.model.MappedTrackerProgramStage; +import org.dhis2.fhir.adapter.fhir.metadata.model.ProgramStageRule; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Example; +import org.springframework.http.MediaType; +import org.springframework.restdocs.payload.JsonFieldType; + +import javax.annotation.Nonnull; +import java.nio.charset.StandardCharsets; +import java.util.Objects; +import java.util.UUID; + +import static org.hamcrest.Matchers.is; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.linkWithRel; +import static org.springframework.restdocs.hypermedia.HypermediaDocumentation.links; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get; +import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post; +import static org.springframework.restdocs.payload.PayloadDocumentation.*; +import static org.springframework.restdocs.snippet.Attributes.attributes; +import static org.springframework.restdocs.snippet.Attributes.key; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Tests for {@link RuleRepository}. + * + * @author volsch + */ +public class ProgramStageRuleRepositoryRestDocsTest extends AbstractJpaRepositoryRestDocsTest +{ + @Autowired + private RuleRepository ruleRepository; + + @Autowired + private MappedTrackerProgramStageRepository mappedTrackerProgramStageRepository; + + @Autowired + private ExecutableScriptRepository executableScriptRepository; + + @Test + public void createProgramStageRule() throws Exception + { + final MappedTrackerProgramStage mappedProgramStage = loadTrackerProgramStage( UUID.fromString( "4c074c85-be49-4b9d-8973-9e16b9615dad" ) ); + final ConstrainedFields fields = new ConstrainedFields( ProgramStageRule.class, constraintDescriptionResolver ); + final String request = IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgramStageRule.json", StandardCharsets.UTF_8 ) + .replace( "$apiBaseUri", API_BASE_URI ); + final String location = docMockMvc.perform( post( "/api/rules" ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( request ) ) + .andExpect( status().isCreated() ) + .andExpect( header().exists( "Location" ) ) + .andDo( documentationHandler.document( requestFields( + attributes( key( "title" ).value( "Fields for program stage rule creation" ) ), + fields.withPath( "name" ).description( "The unique name of the rule." ).type( JsonFieldType.STRING ), + fields.withPath( "description" ).description( "The detailed description that describes for which purpose the rule is used." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "dhisResourceType" ).description( "The type of the rule and the type of the data that is stored in DHIS2." ).type( JsonFieldType.STRING ), + fields.withPath( "fhirResourceType" ).description( "The FHIR resource type of the incoming resource." ).type( JsonFieldType.STRING ), + fields.withPath( "enabled" ).description( "Specifies if this rule is enabled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "impEnabled" ).description( "Specifies if transformation of a FHIR to a DHIS2 resource has been enabled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "expEnabled" ).description( "Specifies if transformation of a DHIS2 to a FHIR resource has been enabled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "fhirCreateEnabled" ).description( "Specifies if the creation of a FHIR resource is enabled for output transformations from DHIS to FHIR for this rule (by default true)." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirUpdateEnabled" ).description( "Specifies if the update of a FHIR resource is enabled for output transformations from DHIS to FHIR for this rule (by default false)." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirDeleteEnabled" ).description( "Specifies if the deletion of a FHIR resource is enabled for output transformations from DHIS to FHIR for this rule (by default false)." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "stop" ).description( "'Specifies if this rule is the last applied rule. When the transformation should not stop further rules are applied as well." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "evaluationOrder" ).description( "Specifies the precedence of this rule when several rules match. Higher values define a higher precedence." ).type( JsonFieldType.NUMBER ), + fields.withPath( "containedAllowed" ).description( "Specified if this rule can process contained resources." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "enrollmentCreationEnabled" ).description( "Specifies if the creation of an enrollment is allowed when processing the rule and the enrollment does not exist." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "eventCreationEnabled" ).description( "Specifies if the creation of an event is allowed when processing the rule and the event does not exist." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "updateEventDate" ).description( "Specifies if the event date can be updated with the content of the transformed FHIR resource." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "beforePeriodDayType" ).description( "Specifies to which date the the amount of the specified before period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "beforePeriodDays" ).description( "The day (relative according to the specified setting) on and after which FHIR resources (according to their effective date) are regarded as being applicable for this program stage." ) + .type( JsonFieldType.NUMBER ).optional(), + fields.withPath( "afterPeriodDayType" ).description( "Specifies to which date the the amount of the specified after period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "afterPeriodDays" ).description( "The day (relative according to the specified setting) on and before which FHIR resources (according to their effective date) are regarded as being applicable for this program stage." ) + .type( JsonFieldType.NUMBER ).optional(), + fields.withPath( "applicableEnrollmentStatus" ).description( "Specifies for which status of the corresponding enrollment the transformation can be performed." ).type( JsonFieldType.OBJECT ), + fields.withPath( "applicableEnrollmentStatus.active" ).description( "Specifies that the transformation can be performed when the status of the enrollment is active." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEnrollmentStatus.completed" ).description( "Specifies that the transformation can be performed when the status of the enrollment is completed." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEnrollmentStatus.cancelled" ).description( "Specifies that the transformation can be performed when the status of the enrollment is cancelled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus" ).description( "Specifies for which status of the corresponding event the transformation can be performed." ).type( JsonFieldType.OBJECT ), + fields.withPath( "applicableEventStatus.active" ).description( "Specifies that the transformation can be performed when the status of the event is active." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus.overdue" ).description( "Specifies that the transformation can be performed when the status of the event is overdue." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus.schedule" ).description( "Specifies that the transformation can be performed when the status of the event is schedule." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus.visited" ).description( "Specifies that the transformation can be performed when the status of the event is visited." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus.skipped" ).description( "Specifies that the transformation can be performed when the status of the event is skipped." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus.completed" ).description( "Specifies that the transformation can be performed when the status of the event is completed." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "eventStatusUpdate" ).description( "Specifies if the status of the event should set to active when it is not active." ).type( JsonFieldType.OBJECT ), + fields.withPath( "eventStatusUpdate.overdueToActive" ).description( "Specifies that the event status should be set to active when the event status is overdue." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "eventStatusUpdate.scheduleToActive" ).description( "Specifies that the event status should be set to active when the event status is schedule." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "eventStatusUpdate.completedToActive" ).description( "Specifies that the event status should be set to active when the event status is completed." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "dhisDataReferences" ).description( "Contains the references to DHIS2 data elements in which the data that is processed by the assigned rule is stored." ).type( JsonFieldType.ARRAY ).optional(), + fields.withPath( "dhisDataReferences[].description" ).description( "The description of the purpose of the data reference." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "dhisDataReferences[].scriptArgName" ).description( "The name of the script argument to which the data reference is passed when performing the transformation." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "dhisDataReferences[].required" ).description( "Specifies if the data element is required. If the data element is required and has no value, the value is regarded as absent and absence handling " + + "is performed when transforming." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "dhisDataReferences[].dataReference" ).description( "Specifies the reference to the data element." ).type( JsonFieldType.OBJECT ), + fields.withPath( "dhisDataReferences[].dataReference.value" ).description( "The unique ID/code/name of the data element." ).type( JsonFieldType.STRING ), + fields.withPath( "dhisDataReferences[].dataReference.type" ).description( "The type of reference value of the data element." ).type( JsonFieldType.STRING ), + fields.withPath( "applicableCodeSet" ).description( "Link to the code set reference that is used to check if the incoming request is applicable for this rule." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "applicableImpScript" ).description( "Link to the executable script reference that is used to check if the incoming request is applicable for this rule. The script must be an evaluation script that returns a boolean value." ) + .type( JsonFieldType.STRING ).optional(), + fields.withPath( "transformImpScript" ).description( "Link to the executable script reference that is used to transform the FHIR resource input to the DHIS2 resource." ) + .type( JsonFieldType.STRING ).optional(), + fields.withPath( "applicableExpScript" ).description( "Link to the executable script reference that is used to check if the incoming request is applicable for this rule when transforming a DHIS2 to FHIR resource. " + + "The script must be an evaluation script that returns a boolean value." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "transformExpScript" ).description( "Link to the executable script reference that is used to transform the DHIS2 resource input to the FHIR resource." ) + .type( JsonFieldType.STRING ).optional(), + fields.withPath( "programStage" ).description( "Link to the tracked entity resource that describes the tracked entity of the transformation." ).type( JsonFieldType.STRING ), + fields.withPath( "expDeleteEvaluateScript" ).description( "Link to the executable evaluation script that evaluates if the transformation should result in a deletion of the corresponding FHIR resource." ) + .type( JsonFieldType.STRING ).optional() ) + ) ).andReturn().getResponse().getHeader( "Location" ); + + mockMvc + .perform( get( Objects.requireNonNull( location ) ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) ) + .andExpect( status().isOk() ) + .andExpect( jsonPath( "lastUpdatedBy", is( "2h2maqu827d" ) ) ) + .andExpect( jsonPath( "name", is( "Child Programme: Estimated Infant Weight" ) ) ) + .andExpect( jsonPath( "enabled", is( true ) ) ) + .andExpect( jsonPath( "impEnabled", is( true ) ) ) + .andExpect( jsonPath( "expEnabled", is( false ) ) ) + .andExpect( jsonPath( "fhirCreateEnabled", is( true ) ) ) + .andExpect( jsonPath( "fhirUpdateEnabled", is( false ) ) ) + .andExpect( jsonPath( "stop", is( false ) ) ) + .andExpect( jsonPath( "evaluationOrder", is( 10 ) ) ) + .andExpect( jsonPath( "dhisResourceType", is( "PROGRAM_STAGE_EVENT" ) ) ) + .andExpect( jsonPath( "fhirResourceType", is( "OBSERVATION" ) ) ) + .andExpect( jsonPath( "_links.self.href", is( location ) ) ); + } + + @Test + public void readProgramStageRule() throws Exception + { + final ConstrainedFields fields = new ConstrainedFields( ProgramStageRule.class, constraintDescriptionResolver ); + final String ruleId = loadProgramStageRule( UUID.fromString( "a6636c83-f236-48cd-bb2b-592147db9a34" ) ).getId().toString(); + docMockMvc.perform( get( "/api/rules/{ruleId}", ruleId ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) ) + .andExpect( status().isOk() ) + .andDo( documentationHandler.document( links( + linkWithRel( "self" ).description( "Link to this resource itself." ), + linkWithRel( "programStageRule" ).description( "Link to this resource itself." ), + linkWithRel( "applicableCodeSet" ).description( "Link to the code set reference that is used to check if the incoming request is applicable for this rule." ).optional(), + linkWithRel( "applicableImpScript" ).description( "Link to the executable script reference that is used to check if the incoming request is applicable for this rule. The script must be an evaluation script that returns a boolean value." ).optional(), + linkWithRel( "transformImpScript" ).description( "Link to the executable script reference that is used to transform the FHIR resource input to the DHIS2 resource." ).optional(), + linkWithRel( "applicableExpScript" ).description( "Link to the executable script reference that is used to check if the incoming request is applicable for this rule when transforming a DHIS2 to FHIR resource. " + + "The script must be an evaluation script that returns a boolean value." ).optional(), + linkWithRel( "transformExpScript" ).description( "Link to the executable script reference that is used to transform the DHIS2 resource input to the FHIR resource." ).optional(), + linkWithRel( "programStage" ).description( "Link to the tracked entity resource that describes the tracked entity of the transformation." ), + linkWithRel( "expDeleteEvaluateScript" ).description( "Link to the executable evaluation script that evaluates if the transformation should result in a deletion of the corresponding FHIR resource." ).optional() ), + responseFields( + attributes( key( "title" ).value( "Fields for rule reading" ) ), + fields.withPath( "createdAt" ).description( "The timestamp when the resource has been created." ).type( JsonFieldType.STRING ), + fields.withPath( "lastUpdatedBy" ).description( "The ID of the user that has updated the user the last time or null if the data has been imported to the database directly." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "lastUpdatedAt" ).description( "The timestamp when the resource has been updated the last time." ).type( JsonFieldType.STRING ), + fields.withPath( "name" ).description( "The unique name of the rule." ).type( JsonFieldType.STRING ), + fields.withPath( "description" ).description( "The detailed description that describes for which purpose the rule is used." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "dhisResourceType" ).description( "The type of the rule and the type of the data that is stored in DHIS2." ).type( JsonFieldType.STRING ), + fields.withPath( "fhirResourceType" ).description( "The FHIR resource type of the incoming resource." ).type( JsonFieldType.STRING ), + fields.withPath( "enabled" ).description( "Specifies if this rule is enabled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "impEnabled" ).description( "Specifies if transformation of a FHIR to a DHIS2 resource has been enabled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "expEnabled" ).description( "Specifies if transformation of a DHIS2 to a FHIR resource has been enabled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "fhirCreateEnabled" ).description( "Specifies if the creation of a FHIR resource is enabled for output transformations from DHIS to FHIR for this rule (by default true)." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirUpdateEnabled" ).description( "Specifies if the update of a FHIR resource is enabled for output transformations from DHIS to FHIR for this rule (by default false)." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "fhirDeleteEnabled" ).description( "Specifies if the deletion of a FHIR resource is enabled for output transformations from DHIS to FHIR for this rule (by default false)." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "stop" ).description( "'Specifies if this rule is the last applied rule. When the transformation should not stop further rules are applied as well." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "evaluationOrder" ).description( "Specifies the precedence of this rule when several rules match. Higher values define a higher precedence." ).type( JsonFieldType.NUMBER ), + fields.withPath( "containedAllowed" ).description( "Specified if this rule can process contained resources." ).type( JsonFieldType.BOOLEAN ).optional(), + fields.withPath( "enrollmentCreationEnabled" ).description( "Specifies if the creation of an enrollment is allowed when processing the rule and the enrollment does not exist." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "eventCreationEnabled" ).description( "Specifies if the creation of an event is allowed when processing the rule and the event does not exist." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "updateEventDate" ).description( "Specifies if the event date can be updated with the content of the transformed FHIR resource." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "beforePeriodDayType" ).description( "Specifies to which date the the amount of the specified before period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "beforePeriodDays" ).description( "The day (relative according to the specified setting) on and after which FHIR resources (according to their effective date) are regarded as being applicable for this program stage." ) + .type( JsonFieldType.NUMBER ).optional(), + fields.withPath( "afterPeriodDayType" ).description( "Specifies to which date the the amount of the specified after period days are relative." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "afterPeriodDays" ).description( "The day (relative according to the specified setting) on and before which FHIR resources (according to their effective date) are regarded as being applicable for this program stage." ) + .type( JsonFieldType.NUMBER ).optional(), + fields.withPath( "applicableEnrollmentStatus" ).description( "Specifies for which status of the corresponding enrollment the transformation can be performed." ).type( JsonFieldType.OBJECT ), + fields.withPath( "applicableEnrollmentStatus.active" ).description( "Specifies that the transformation can be performed when the status of the enrollment is active." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEnrollmentStatus.completed" ).description( "Specifies that the transformation can be performed when the status of the enrollment is completed." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEnrollmentStatus.cancelled" ).description( "Specifies that the transformation can be performed when the status of the enrollment is cancelled." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus" ).description( "Specifies for which status of the corresponding event the transformation can be performed." ).type( JsonFieldType.OBJECT ), + fields.withPath( "applicableEventStatus.active" ).description( "Specifies that the transformation can be performed when the status of the event is active." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus.overdue" ).description( "Specifies that the transformation can be performed when the status of the event is overdue." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus.schedule" ).description( "Specifies that the transformation can be performed when the status of the event is schedule." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus.visited" ).description( "Specifies that the transformation can be performed when the status of the event is visited." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus.skipped" ).description( "Specifies that the transformation can be performed when the status of the event is skipped." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "applicableEventStatus.completed" ).description( "Specifies that the transformation can be performed when the status of the event is completed." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "eventStatusUpdate" ).description( "Specifies if the status of the event should set to active when it is not active." ).type( JsonFieldType.OBJECT ), + fields.withPath( "eventStatusUpdate.overdueToActive" ).description( "Specifies that the event status should be set to active when the event status is overdue." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "eventStatusUpdate.scheduleToActive" ).description( "Specifies that the event status should be set to active when the event status is schedule." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "eventStatusUpdate.completedToActive" ).description( "Specifies that the event status should be set to active when the event status is completed." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "dhisDataReferences" ).description( "Contains the references to DHIS2 data elements in which the data that is processed by the assigned rule is stored." ).type( JsonFieldType.ARRAY ).optional(), + fields.withPath( "dhisDataReferences[].createdAt" ).description( "The timestamp when the resource has been created." ).type( JsonFieldType.STRING ), + fields.withPath( "dhisDataReferences[].lastUpdatedBy" ).description( "The ID of the user that has updated the user the last time or null if the data has been imported to the database directly." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "dhisDataReferences[].lastUpdatedAt" ).description( "The timestamp when the resource has been updated the last time." ).type( JsonFieldType.STRING ), + fields.withPath( "dhisDataReferences[].description" ).description( "The description of the purpose of the data reference." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "dhisDataReferences[].scriptArgName" ).description( "The name of the script argument to which the data reference is passed when performing the transformation." ).type( JsonFieldType.STRING ).optional(), + fields.withPath( "dhisDataReferences[].required" ).description( "Specifies if the data element is required. If the data element is required and has no value, the value is regarded as absent and absence handling " + + "is performed when transforming." ).type( JsonFieldType.BOOLEAN ), + fields.withPath( "dhisDataReferences[].dataReference" ).description( "Specifies the reference to the data element." ).type( JsonFieldType.OBJECT ), + fields.withPath( "dhisDataReferences[].dataReference.value" ).description( "The unique ID/code/name of the data element." ).type( JsonFieldType.STRING ), + fields.withPath( "dhisDataReferences[].dataReference.type" ).description( "The type of reference value of the data element." ).type( JsonFieldType.STRING ), + subsectionWithPath( "dhisDataReferences[]._links" ).ignored(), + subsectionWithPath( "_links" ).description( "Links to other resources" ) + ) ) ); + } + + @Nonnull + protected MappedTrackerProgramStage loadTrackerProgramStage( @Nonnull UUID id ) + { + return mappedTrackerProgramStageRepository.findById( id ) + .orElseThrow( () -> new AssertionError( "Mapped tracker program stage does not exist: " + id ) ); + } + + @Nonnull + protected AbstractRule loadProgramStageRule( @Nonnull UUID id ) + { + return ruleRepository.findById( id ) + .orElseThrow( () -> new AssertionError( "Rule does not exist: " + id ) ); + } + + @Nonnull + protected ExecutableScript loadScript( @Nonnull String code ) + { + final ExecutableScript example = new ExecutableScript(); + example.setCode( code ); + return executableScriptRepository.findOne( Example.of( example ) ) + .orElseThrow( () -> new AssertionError( "Executable script does not exist: " + code ) ); + } +} \ No newline at end of file diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/TrackedEntityRepositoryRestDocsTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/TrackedEntityRepositoryRestDocsTest.java index aa1832a6..eb54ac95 100644 --- a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/TrackedEntityRepositoryRestDocsTest.java +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/TrackedEntityRepositoryRestDocsTest.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.repository; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,7 +32,6 @@ import org.dhis2.fhir.adapter.fhir.AbstractJpaRepositoryRestDocsTest; import org.dhis2.fhir.adapter.fhir.ConstrainedFields; import org.dhis2.fhir.adapter.fhir.metadata.model.MappedTrackedEntity; -import org.dhis2.fhir.adapter.fhir.metadata.model.TrackedEntityRule; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Example; @@ -67,7 +66,7 @@ public class TrackedEntityRepositoryRestDocsTest extends AbstractJpaRepositoryRe @Test public void createTrackedEntity() throws Exception { - final ConstrainedFields fields = new ConstrainedFields( TrackedEntityRule.class, constraintDescriptionResolver ); + final ConstrainedFields fields = new ConstrainedFields( MappedTrackedEntity.class, constraintDescriptionResolver ); final String request = IOUtils.resourceToString( "/org/dhis2/fhir/adapter/fhir/metadata/repository/createTrackedEntity.json", StandardCharsets.UTF_8 ); final String location = docMockMvc.perform( post( "/api/trackedEntities" ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) .contentType( MediaType.APPLICATION_JSON ).content( request ) ) @@ -110,7 +109,7 @@ public void createTrackedEntity() throws Exception @Test public void readTrackedEntity() throws Exception { - final ConstrainedFields fields = new ConstrainedFields( TrackedEntityRule.class, constraintDescriptionResolver ); + final ConstrainedFields fields = new ConstrainedFields( MappedTrackedEntity.class, constraintDescriptionResolver ); final String trackedEntityId = loadTrackedEntity( "Person" ).getId().toString(); docMockMvc.perform( get( "/api/trackedEntities/{trackedEntityId}", trackedEntityId ).header( AUTHORIZATION_HEADER_NAME, DATA_MAPPING_AUTHORIZATION_HEADER_VALUE ) ) .andExpect( status().isOk() ) diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/RuleRepositoryRestDocsTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/TrackedEntityRuleRepositoryRestDocsTest.java similarity index 99% rename from fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/RuleRepositoryRestDocsTest.java rename to fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/TrackedEntityRuleRepositoryRestDocsTest.java index 40590d94..2a6d2f44 100644 --- a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/RuleRepositoryRestDocsTest.java +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/TrackedEntityRuleRepositoryRestDocsTest.java @@ -1,7 +1,7 @@ package org.dhis2.fhir.adapter.fhir.metadata.repository; /* - * Copyright (c) 2004-2018, University of Oslo + * Copyright (c) 2004-2019, University of Oslo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,7 +61,7 @@ * * @author volsch */ -public class RuleRepositoryRestDocsTest extends AbstractJpaRepositoryRestDocsTest +public class TrackedEntityRuleRepositoryRestDocsTest extends AbstractJpaRepositoryRestDocsTest { @Autowired private RuleRepository ruleRepository; diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveFhirResourceMappingValidatorTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveFhirResourceMappingValidatorTest.java new file mode 100644 index 00000000..669bb966 --- /dev/null +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveFhirResourceMappingValidatorTest.java @@ -0,0 +1,605 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository.validator; + +/* + * 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.fhir.AbstractJpaRepositoryTest; +import org.dhis2.fhir.adapter.fhir.metadata.model.ExecutableScript; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceMapping; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Test; +import org.springframework.http.MediaType; +import org.springframework.test.annotation.Rollback; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Validator tests for the corresponding repository. + * + * @author volsch + */ +@Rollback +public class BeforeCreateSaveFhirResourceMappingValidatorTest extends AbstractJpaRepositoryTest +{ + public static final String RESOURCE_PATH = "/api/fhirResourceMappings"; + + public static final String AUTHORIZATION_HEADER_VALUE = DATA_MAPPING_AUTHORIZATION_HEADER_VALUE; + + private FhirResourceMapping entity; + + private ExecutableScript impTeiLookupScript; + + private ExecutableScript impEnrollmentOrgLookupScript; + + private ExecutableScript impEventOrgLookupScript; + + private ExecutableScript impEnrollmentDateLookupScript; + + private ExecutableScript impEventDateLookupScript; + + private ExecutableScript impEnrollmentGeoLookupScript; + + private ExecutableScript impEventGeoLookupScript; + + private ExecutableScript impEffectiveDateLookupScript; + + private ExecutableScript impTransformationScript; + + private ExecutableScript impBooleanScript; + + private ExecutableScript impOtherDateLookupScript; + + private ExecutableScript impOtherOrgUnitLookupScript; + + private ExecutableScript impOtherGeoLookupScript; + + @Before + public void before() + { + impTeiLookupScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "OBSERVATION_TEI_LOOKUP" ).getSingleResult(); + impEnrollmentOrgLookupScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "EXTRACT_FHIR_PATIENT_DHIS_ORG_UNIT_CODE" ).getSingleResult(); + impEventOrgLookupScript = impEnrollmentOrgLookupScript; + impEnrollmentGeoLookupScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "EXTRACT_FHIR_OBSERVATION_GEO_LOCATION" ).getSingleResult(); + impEventGeoLookupScript = impEnrollmentGeoLookupScript; + impEnrollmentDateLookupScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "OBSERVATION_DATE_LOOKUP" ).getSingleResult(); + impEventDateLookupScript = impEnrollmentDateLookupScript; + impEffectiveDateLookupScript = impEnrollmentDateLookupScript; + + impTransformationScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "CP_OPV_DOSE" ).getSingleResult(); + impBooleanScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "TRUE" ).getSingleResult(); + impOtherDateLookupScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "OTHER_DATE_LOOKUP" ).getSingleResult(); + impOtherOrgUnitLookupScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "OTHER_ORG_UNIT_LOOKUP" ).getSingleResult(); + impOtherGeoLookupScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "OTHER_GEO_LOOKUP" ).getSingleResult(); + + entity = new FhirResourceMapping(); + entity.setFhirResourceType( FhirResourceType.ENCOUNTER ); + } + + @Test + public void testFhirResourceTypeNull() throws Exception + { + entity.setFhirResourceType( null ); + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEnrollmentDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "fhirResourceType" ) ) ); + } + + @Test + public void testImpEffectiveDateLookupScriptNull() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEnrollmentDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isCreated() ); + } + + @Test + public void testImpEffectiveDateLookupScriptTransform() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impTransformationScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEnrollmentDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEffectiveDateLookupScript" ) ) ); + } + + @Test + public void testImpEffectiveDateLookupScriptType() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impOtherDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEnrollmentDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEffectiveDateLookupScript" ) ) ); + } + + @Test + public void testImpEffectiveDateLookupScriptBoolean() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEnrollmentDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEffectiveDateLookupScript" ) ) ); + } + + @Test + public void testImpEnrollmentDateLookupScriptNull() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isCreated() ); + } + + @Test + public void testImpEnrollmentDateLookupScriptTransform() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impTransformationScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEnrollmentDateLookupScript" ) ) ); + } + + @Test + public void testImpEnrollmentDateLookupScriptType() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impOtherDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEnrollmentDateLookupScript" ) ) ); + } + + @Test + public void testImpEnrollmentDateLookupScriptBoolean() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEnrollmentDateLookupScript" ) ) ); + } + + @Test + public void testImpEventDateLookupScriptNull() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEnrollmentDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isCreated() ); + } + + @Test + public void testImpEventDateLookupScriptTransform() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impTransformationScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEventDateLookupScript" ) ) ); + } + + @Test + public void testImpEventDateLookupScriptType() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impOtherDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEventDateLookupScript" ) ) ); + } + + @Test + public void testImpEventDateLookupScriptBoolean() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEventDateLookupScript" ) ) ); + } + + @Test + public void testImpTeiLookupScriptNull() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEnrollmentDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isCreated() ); + } + + @Test + public void testImpTeiLookupScriptTransform() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTransformationScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impTeiLookupScript" ) ) ); + } + + @Test + public void testImpEnrollmentOrgLookupScript() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEnrollmentDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isCreated() ); + } + + @Test + public void testImpEnrollmentOrgLookupScriptTransform() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impTransformationScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEnrollmentOrgLookupScript" ) ) ); + } + + @Test + public void testImpTeiLookupScriptBoolean() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impTeiLookupScript" ) ) ); + } + + @Test + public void testImpTeiLookupScriptType() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impOtherOrgUnitLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impTeiLookupScript" ) ) ); + } + + @Test + public void testImpEventOrgLookupScript() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEnrollmentDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isCreated() ); + } + + @Test + public void testImpEventOrgLookupScriptTransform() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impTransformationScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEventOrgLookupScript" ) ) ); + } + + @Test + public void testImpEventOrgLookupScriptBoolean() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEventOrgLookupScript" ) ) ); + } + + @Test + public void testImpEventOrgLookupScriptType() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impOtherOrgUnitLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEventOrgLookupScript" ) ) ); + } + + @Test + public void testImpEnrollmentGeoLookupScript() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEnrollmentDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isCreated() ); + } + + @Test + public void testImpEnrollmentGeoLookupScriptTransform() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impTransformationScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEnrollmentGeoLookupScript" ) ) ); + } + + @Test + public void testImpEnrollmentGeoLookupScriptBoolean() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEnrollmentGeoLookupScript" ) ) ); + } + + @Test + public void testImpEnrollmentGeoLookupScriptType() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impOtherGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impEventGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEnrollmentGeoLookupScript" ) ) ); + } + + @Test + public void testImpEventGeoLookupScript() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEnrollmentDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEnrollmentOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isCreated() ); + } + + @Test + public void testImpEventGeoLookupScriptTransform() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impTransformationScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEventGeoLookupScript" ) ) ); + } + + @Test + public void testImpEventGeoLookupScriptBoolean() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impBooleanScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEventGeoLookupScript" ) ) ); + } + + @Test + public void testImpEventGeoLookupScriptType() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "impEffectiveDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentDateLookupScript", "executableScripts", impEffectiveDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventDateLookupScript", "executableScripts", impEventDateLookupScript.getId().toString() ), + JsonEntityValue.create( "impTeiLookupScript", "executableScripts", impTeiLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventOrgLookupScript", "executableScripts", impEventOrgLookupScript.getId().toString() ), + JsonEntityValue.create( "impEnrollmentGeoLookupScript", "executableScripts", impEnrollmentGeoLookupScript.getId().toString() ), + JsonEntityValue.create( "impEventGeoLookupScript", "executableScripts", impOtherGeoLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "impEventGeoLookupScript" ) ) ); + } +} \ No newline at end of file diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveTrackerProgramStageValidatorTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveTrackerProgramStageValidatorTest.java new file mode 100644 index 00000000..bb8a9f44 --- /dev/null +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveTrackerProgramStageValidatorTest.java @@ -0,0 +1,192 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository.validator; + +/* + * 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.apache.commons.lang3.StringUtils; +import org.dhis2.fhir.adapter.dhis.model.Reference; +import org.dhis2.fhir.adapter.dhis.model.ReferenceType; +import org.dhis2.fhir.adapter.fhir.AbstractJpaRepositoryTest; +import org.dhis2.fhir.adapter.fhir.metadata.model.ExecutableScript; +import org.dhis2.fhir.adapter.fhir.metadata.model.MappedTrackerProgram; +import org.dhis2.fhir.adapter.fhir.metadata.model.MappedTrackerProgramStage; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Test; +import org.springframework.http.MediaType; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Validator tests for the corresponding repository. + * + * @author volsch + */ +public class BeforeCreateSaveTrackerProgramStageValidatorTest extends AbstractJpaRepositoryTest +{ + public static final String RESOURCE_PATH = "/api/trackerProgramStages"; + + public static final String AUTHORIZATION_HEADER_VALUE = DATA_MAPPING_AUTHORIZATION_HEADER_VALUE; + + private MappedTrackerProgramStage entity; + + private MappedTrackerProgram trackerProgram; + + private ExecutableScript impBooleanScript; + + private ExecutableScript impOtherDateLookupScript; + + @Before + public void before() + { + trackerProgram = entityManager.createQuery( "SELECT e FROM MappedTrackerProgram e WHERE e.name=:name", MappedTrackerProgram.class ) + .setParameter( "name", "Child Programme" ).getSingleResult(); + impBooleanScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "TRUE" ).getSingleResult(); + impOtherDateLookupScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "OTHER_DATE_LOOKUP" ).getSingleResult(); + + entity = new MappedTrackerProgramStage(); + entity.setName( createUnique() ); + entity.setProgramStageReference( Reference.createIdReference( "abc" ) ); + } + + @Test + public void testNameBlank() throws Exception + { + entity.setName( " " ); + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "program", "trackerPrograms", trackerProgram.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "name" ) ) ); + } + + @Test + public void testNameLength() throws Exception + { + entity.setName( StringUtils.repeat( 'a', MappedTrackerProgramStage.MAX_NAME_LENGTH + 1 ) ); + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "program", "trackerPrograms", trackerProgram.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "name" ) ) ); + } + + @Test + public void testProgramNull() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "program" ) ) ); + } + + @Test + public void testProgramStageReferenceNull() throws Exception + { + entity.setProgramStageReference( null ); + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "program", "trackerPrograms", trackerProgram.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "programStageReference" ) ) ); + } + + @Test + public void testProgramStageReferenceInvalid() throws Exception + { + entity.setProgramStageReference( new Reference( StringUtils.repeat( 'a', 250 ), ReferenceType.ID ) ); + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "program", "trackerPrograms", trackerProgram.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "programStageReference" ) ) ); + } + + @Test + public void testOk() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "program", "trackerPrograms", trackerProgram.getId().toString() ), + JsonEntityValue.create( "creationApplicableScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "creationScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "beforeScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "afterScript", "executableScripts", impBooleanScript.getId().toString() ) ) ) ) + .andExpect( status().isCreated() ); + } + + @Test + public void testCreationApplicableScriptInvalid() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "program", "trackerPrograms", trackerProgram.getId().toString() ), + JsonEntityValue.create( "creationApplicableScript", "executableScripts", impOtherDateLookupScript.getId().toString() ), + JsonEntityValue.create( "creationScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "beforeScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "afterScript", "executableScripts", impBooleanScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "creationApplicableScript" ) ) ); + } + + @Test + public void testCreationScriptInvalid() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "program", "trackerPrograms", trackerProgram.getId().toString() ), + JsonEntityValue.create( "creationApplicableScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "creationScript", "executableScripts", impOtherDateLookupScript.getId().toString() ), + JsonEntityValue.create( "beforeScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "afterScript", "executableScripts", impBooleanScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "creationScript" ) ) ); + } + + @Test + public void testBeforeScriptInvalid() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "program", "trackerPrograms", trackerProgram.getId().toString() ), + JsonEntityValue.create( "creationApplicableScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "creationScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "beforeScript", "executableScripts", impOtherDateLookupScript.getId().toString() ), + JsonEntityValue.create( "afterScript", "executableScripts", impBooleanScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "beforeScript" ) ) ); + } + + @Test + public void testAfterScriptInvalid() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "program", "trackerPrograms", trackerProgram.getId().toString() ), + JsonEntityValue.create( "creationApplicableScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "creationScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "beforeScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "afterScript", "executableScripts", impOtherDateLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "afterScript" ) ) ); + } +} \ No newline at end of file diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveTrackerProgramValidatorTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveTrackerProgramValidatorTest.java new file mode 100644 index 00000000..d0e309dd --- /dev/null +++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/validator/BeforeCreateSaveTrackerProgramValidatorTest.java @@ -0,0 +1,204 @@ +package org.dhis2.fhir.adapter.fhir.metadata.repository.validator; + +/* + * 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.apache.commons.lang3.StringUtils; +import org.dhis2.fhir.adapter.dhis.model.Reference; +import org.dhis2.fhir.adapter.dhis.model.ReferenceType; +import org.dhis2.fhir.adapter.fhir.AbstractJpaRepositoryTest; +import org.dhis2.fhir.adapter.fhir.metadata.model.ExecutableScript; +import org.dhis2.fhir.adapter.fhir.metadata.model.FhirResourceType; +import org.dhis2.fhir.adapter.fhir.metadata.model.MappedTrackerProgram; +import org.dhis2.fhir.adapter.fhir.metadata.model.TrackedEntityRule; +import org.hamcrest.Matchers; +import org.junit.Before; +import org.junit.Test; +import org.springframework.http.MediaType; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Validator tests for the corresponding repository. + * + * @author volsch + */ +public class BeforeCreateSaveTrackerProgramValidatorTest extends AbstractJpaRepositoryTest +{ + public static final String RESOURCE_PATH = "/api/trackerPrograms"; + + public static final String AUTHORIZATION_HEADER_VALUE = DATA_MAPPING_AUTHORIZATION_HEADER_VALUE; + + private MappedTrackerProgram entity; + + private ExecutableScript impBooleanScript; + + private ExecutableScript impOtherDateLookupScript; + + private TrackedEntityRule trackedEntityRule; + + @Before + public void before() + { + impBooleanScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "TRUE" ).getSingleResult(); + impOtherDateLookupScript = entityManager.createQuery( "SELECT e FROM ExecutableScript e WHERE e.code=:code", ExecutableScript.class ) + .setParameter( "code", "OTHER_DATE_LOOKUP" ).getSingleResult(); + trackedEntityRule = entityManager.createQuery( "SELECT e FROM TrackedEntityRule e WHERE e.name=:name", TrackedEntityRule.class ) + .setParameter( "name", "FHIR Patient to Person" ).getSingleResult(); + + entity = new MappedTrackerProgram(); + entity.setName( createUnique() ); + entity.setProgramReference( Reference.createIdReference( "abc" ) ); + entity.setTrackedEntityFhirResourceType( FhirResourceType.PATIENT ); + } + + @Test + public void testNameBlank() throws Exception + { + entity.setName( " " ); + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "trackedEntityRule", "rules", trackedEntityRule.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "name" ) ) ); + } + + @Test + public void testNameLength() throws Exception + { + entity.setName( StringUtils.repeat( 'a', MappedTrackerProgram.MAX_NAME_LENGTH + 1 ) ); + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "trackedEntityRule", "rules", trackedEntityRule.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "name" ) ) ); + } + + @Test + public void testTrackedEntityFhirResourceType() throws Exception + { + entity.setTrackedEntityFhirResourceType( null ); + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "trackedEntityRule", "rules", trackedEntityRule.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "trackedEntityFhirResourceType" ) ) ); + } + + @Test + public void testTrackedEntityRuleNull() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "trackedEntityRule" ) ) ); + } + + @Test + public void testProgramStageReferenceNull() throws Exception + { + entity.setProgramReference( null ); + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "trackedEntityRule", "rules", trackedEntityRule.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "programReference" ) ) ); + } + + @Test + public void testProgramStageReferenceInvalid() throws Exception + { + entity.setProgramReference( new Reference( StringUtils.repeat( 'a', 250 ), ReferenceType.ID ) ); + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "trackedEntityRule", "rules", trackedEntityRule.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "programReference" ) ) ); + } + + @Test + public void testOk() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "trackedEntityRule", "rules", trackedEntityRule.getId().toString() ), + JsonEntityValue.create( "creationApplicableScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "creationScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "beforeScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "afterScript", "executableScripts", impBooleanScript.getId().toString() ) ) ) ) + .andExpect( status().isCreated() ); + } + + @Test + public void testCreationApplicableScriptInvalid() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "trackedEntityRule", "rules", trackedEntityRule.getId().toString() ), + JsonEntityValue.create( "creationApplicableScript", "executableScripts", impOtherDateLookupScript.getId().toString() ), + JsonEntityValue.create( "creationScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "beforeScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "afterScript", "executableScripts", impBooleanScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "creationApplicableScript" ) ) ); + } + + @Test + public void testCreationScriptInvalid() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "trackedEntityRule", "rules", trackedEntityRule.getId().toString() ), + JsonEntityValue.create( "creationApplicableScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "creationScript", "executableScripts", impOtherDateLookupScript.getId().toString() ), + JsonEntityValue.create( "beforeScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "afterScript", "executableScripts", impBooleanScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "creationScript" ) ) ); + } + + @Test + public void testBeforeScriptInvalid() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "trackedEntityRule", "rules", trackedEntityRule.getId().toString() ), + JsonEntityValue.create( "creationApplicableScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "creationScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "beforeScript", "executableScripts", impOtherDateLookupScript.getId().toString() ), + JsonEntityValue.create( "afterScript", "executableScripts", impBooleanScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "beforeScript" ) ) ); + } + + @Test + public void testAfterScriptInvalid() throws Exception + { + mockMvc.perform( post( RESOURCE_PATH ).header( AUTHORIZATION_HEADER_NAME, AUTHORIZATION_HEADER_VALUE ) + .contentType( MediaType.APPLICATION_JSON ).content( replaceJsonEntityReferences( entity, + JsonEntityValue.create( "trackedEntityRule", "rules", trackedEntityRule.getId().toString() ), + JsonEntityValue.create( "creationApplicableScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "creationScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "beforeScript", "executableScripts", impBooleanScript.getId().toString() ), + JsonEntityValue.create( "afterScript", "executableScripts", impOtherDateLookupScript.getId().toString() ) ) ) ) + .andExpect( status().isBadRequest() ).andExpect( jsonPath( "errors[0].property", Matchers.is( "afterScript" ) ) ); + } +} \ No newline at end of file diff --git a/fhir/src/test/resources/data.sql b/fhir/src/test/resources/data.sql index 13972788..5b580bbe 100644 --- a/fhir/src/test/resources/data.sql +++ b/fhir/src/test/resources/data.sql @@ -26,6 +26,8 @@ -- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- +-- @formatter:off + INSERT INTO fhir_code_category(id, version, created_at, last_updated_at, last_updated_by, name, code, description) VALUES ('8673a315dd274e4cbb8b1212808d4ca1', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', 'Organization Unit', 'ORGANIZATION_UNIT', 'Includes the mapping for organization units.'); @@ -93,6 +95,9 @@ VALUES ('1ef4f760de9a4c29a321a8eee5c52313', 0, CURRENT_TIMESTAMP(), CURRENT_TIME INSERT INTO fhir_script_argument(id, version, created_at, last_updated_at, last_updated_by, script_id, name, data_type, mandatory, array_value, default_value, description) VALUES ('d8cd0e7d778045d18094b448b480e6b8', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', 'f1da6937e2fe47a4b0f38bbff7818ee1', 'round', 'BOOLEAN', TRUE, FALSE, 'true', 'Specifies if the resulting value should be rounded.'); +INSERT INTO fhir_script_argument(id, version, script_id, name, data_type, mandatory, default_value, description) +VALUES ('3d15bf81343c45bc9c281e87a8da6fa5', 0, 'f1da6937e2fe47a4b0f38bbff7818ee1', +'weightUnit', 'WEIGHT_UNIT', TRUE, 'KILO_GRAM', 'The resulting weight unit in which the value will be set on the data element.'); INSERT INTO fhir_system (id, version, created_at, last_updated_at, last_updated_by, name, code, system_uri, description_protected, enabled) VALUES ('2dd51309331940d29a1fbe2a102df4a7', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', 'Sierra Leone Location', 'SYSTEM_SL_LOCATION', 'http://example.sl/locations', FALSE, TRUE); @@ -117,38 +122,23 @@ VALUES ('ea9804a39e824d0d9cd2e417b32b1c0c', 0, CURRENT_TIMESTAMP(), CURRENT_TIME INSERT INTO fhir_code_category (id, version, created_at, last_updated_at, last_updated_by, name, code, description) VALUES ('7090561ef45b411e99c065fa1d145018', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', 'Vaccine', 'VACCINE', 'Available vaccines.'); -INSERT INTO fhir_code(id, version, created_at, last_updated_at, last_updated_by, code_category_id, name, code, description) -VALUES ('f9462e8c653b4c6aa5028470a1ab2187', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', '7090561ef45b411e99c065fa1d145018', 'DTaP', 'VACCINE_20', +INSERT INTO fhir_code(id, version, created_at, last_updated_at, last_updated_by, code_category_id, name, code, description) +VALUES ('f9462e8c653b4c6aa5028470a1ab2187', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', '7090561ef45b411e99c065fa1d145018', 'DTaP', 'VACCINE_20', 'diphtheria, tetanus toxoids and acellular pertussis vaccine'); -INSERT INTO fhir_code(id, version, created_at, last_updated_at, last_updated_by, code_category_id, name, code, description) -VALUES ('02422dddb6064bb68d0fcca090182b5d', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', '7090561ef45b411e99c065fa1d145018', +INSERT INTO fhir_code(id, version, created_at, last_updated_at, last_updated_by, code_category_id, name, code, description) +VALUES ('02422dddb6064bb68d0fcca090182b5d', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', '7090561ef45b411e99c065fa1d145018', 'DTaP, 5 pertussis antigens', 'VACCINE_106', 'diphtheria, tetanus toxoids and acellular pertussis vaccine, 5 pertussis antigens'); -INSERT INTO fhir_code(id, version, created_at, last_updated_at, last_updated_by, code_category_id, name, code, description) -VALUES ('71f5536a258745b988ac9aba362a424a', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', '7090561ef45b411e99c065fa1d145018', 'MMR', 'VACCINE_03', +INSERT INTO fhir_code(id, version, created_at, last_updated_at, last_updated_by, code_category_id, name, code, description) +VALUES ('71f5536a258745b988ac9aba362a424a', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', '7090561ef45b411e99c065fa1d145018', 'MMR', 'VACCINE_03', 'measles, mumps and rubella virus vaccine'); -INSERT INTO fhir_code(id, version, created_at, last_updated_at, last_updated_by, code_category_id, name, code, description) -VALUES ('eac12b34ddeb47afa1de59ee2dac488f', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', '7090561ef45b411e99c065fa1d145018', 'M/R', 'VACCINE_04', +INSERT INTO fhir_code(id, version, created_at, last_updated_at, last_updated_by, code_category_id, name, code, description) +VALUES ('eac12b34ddeb47afa1de59ee2dac488f', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', '7090561ef45b411e99c065fa1d145018', 'M/R', 'VACCINE_04', 'measles and rubella virus vaccine'); INSERT INTO fhir_code_set(id, version, created_at, last_updated_at, last_updated_by, code_category_id, name, code, description) VALUES ('bb66ee918e86422cbb005a90ac95a558', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', '7090561ef45b411e99c065fa1d145018', 'All DTP/DTaP', 'ALL_DTP_DTAP', 'All DTP/DTaP vaccines.'); INSERT INTO fhir_code_set_value(id, code_set_id, code_id, enabled) SELECT RANDOM_UUID(), 'bb66ee918e86422cbb005a90ac95a558', id, TRUE FROM fhir_code WHERE code IN ('VACCINE_106', 'VACCINE_20'); --- Script that performs the lookup of TEI FHIR Resource from FHIR Observation -INSERT INTO fhir_script (id, version, name, code, description, script_type, return_type, input_type, output_type) -VALUES ('8b5ab5f1363d4ccb8e63d6ecf25b3017', 0, 'Observation TEI Lookup', 'OBSERVATION_TEI_LOOKUP', 'Lookup of the Tracked Entity Instance FHIR Resource from FHIR Observation.', 'EVALUATE', 'FHIR_RESOURCE', 'FHIR_OBSERVATION', NULL); -INSERT INTO fhir_script_variable (script_id, variable) -VALUES ('8b5ab5f1363d4ccb8e63d6ecf25b3017', 'CONTEXT'); -INSERT INTO fhir_script_variable (script_id, variable) -VALUES ('8b5ab5f1363d4ccb8e63d6ecf25b3017', 'INPUT'); -INSERT INTO fhir_script_source (id, version, script_id, source_text, source_type) -VALUES ('960d2e6c247948a2b04eb14879e71d14', 0, '8b5ab5f1363d4ccb8e63d6ecf25b3017', 'referenceUtils.getResource(input.subject, ''PATIENT'')', 'JAVASCRIPT'); -INSERT INTO fhir_script_source_version (script_source_id, fhir_version) -VALUES ('960d2e6c247948a2b04eb14879e71d14', 'DSTU3'); -INSERT INTO fhir_executable_script (id, version, script_id, name, code, description) -VALUES ('1b6a2f75cb4a47b18e903dfb4db07d36', 0, '8b5ab5f1363d4ccb8e63d6ecf25b3017', - 'Observation TEI Lookup', 'OBSERVATION_TEI_LOOKUP', 'Lookup of the Tracked Entity Instance FHIR Resource from FHIR Observation.'); - -- Script that performs the lookup of TEI FHIR Resource from FHIR Patient (the patient itself) INSERT INTO fhir_script (id, version, name, code, description, script_type, return_type, input_type, output_type) VALUES ('8b5ab5f1363d4ccb8e63d6ecf25b3018', 0, 'Patient TEI Lookup', 'PATIENT_TEI_LOOKUP', 'Lookup of the Tracked Entity Instance FHIR Resource from FHIR Patient.', 'EVALUATE', 'FHIR_RESOURCE', 'FHIR_PATIENT', NULL); @@ -163,11 +153,11 @@ VALUES ('960d2e6c247948a2b04eb14879e71d15', 'DSTU3'); INSERT INTO fhir_executable_script (id, version, script_id, name, code, description) VALUES ('1b6a2f75cb4a47b18e903dfb4db07d37', 0, '8b5ab5f1363d4ccb8e63d6ecf25b3018', 'Patient TEI Lookup', 'PATIENT_TEI_LOOKUP', 'Lookup of the Tracked Entity Instance FHIR Resource from FHIR Patient.'); - + INSERT INTO fhir_script (id, version, created_at, last_updated_at, last_updated_by, name, code, description, script_type, return_type, input_type, output_type) VALUES ('a250e109a13542b28bdb1c050c1d384c', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', 'Org Unit Code from Patient Org', 'EXTRACT_FHIR_PATIENT_DHIS_ORG_UNIT_CODE', 'Extracts the organization unit code reference from the business identifier that is specified by the FHIR Organization of the FHIR Patient.', -'EVALUATE', 'ORG_UNIT_REF', 'FHIR_PATIENT', NULL); +'EVALUATE', 'ORG_UNIT_REF', NULL, NULL); INSERT INTO fhir_script_variable (script_id, variable) VALUES ('a250e109a13542b28bdb1c050c1d384c', 'CONTEXT'); INSERT INTO fhir_script_variable (script_id, variable) VALUES ('a250e109a13542b28bdb1c050c1d384c', 'INPUT'); INSERT INTO fhir_script_source (id, version, created_at, last_updated_at, last_updated_by, script_id, source_text, source_type) @@ -193,7 +183,7 @@ VALUES ('039ac2e650f24e4a9e4adc0515560273', 'DSTU3'); INSERT INTO fhir_executable_script (id, version, created_at, last_updated_at, last_updated_by, script_id, name, code, description) VALUES ('ef90531f443848bd83b36370dd65875a', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', '2263b2969d964698bc1d17930005eef3', 'GEO Location from Patient', 'EXTRACT_FHIR_PATIENT_GEO_LOCATION', 'Extracts the GEO location form FHIR Patient.'); - + INSERT INTO fhir_script (id, version, created_at, last_updated_at, last_updated_by, name, code, description, script_type, return_type, input_type, output_type) VALUES ('ea8879435e944e319441c7661fe1063e', 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', 'Transforms FHIR Patient to DHIS Person', 'TRANSFORM_FHIR_PATIENT_DHIS_PERSON', 'Transforms FHIR Patient to DHIS Person.', 'TRANSFORM_TO_DHIS', 'BOOLEAN', 'FHIR_PATIENT', 'DHIS_TRACKED_ENTITY_INSTANCE'); @@ -235,3 +225,196 @@ VALUES ('5f9ebdc9852e4c8387ca795946aabc35', 0, CURRENT_TIMESTAMP(), CURRENT_TIME INSERT INTO fhir_tracked_entity_rule (id, tracked_entity_id, org_lookup_script_id, loc_lookup_script_id) VALUES ('5f9ebdc9852e4c8387ca795946aabc35', '4203754d21774a4486aa2de31ee4c8ee', '25a97bb47b394ed48677db4bcaa28ccf', 'ef90531f443848bd83b36370dd65875a'); +INSERT INTO fhir_script (id, version, name, code, description, script_type, return_type, input_type, output_type) +VALUES ('8b5ab5f1363d4ccb8e63d6ecf25b3017', 0, 'Observation TEI Lookup', 'OBSERVATION_TEI_LOOKUP', 'Lookup of the Tracked Entity Instance FHIR Resource from FHIR Observation.', 'EVALUATE', 'FHIR_RESOURCE', NULL, NULL); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('8b5ab5f1363d4ccb8e63d6ecf25b3017', 'CONTEXT'); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('8b5ab5f1363d4ccb8e63d6ecf25b3017', 'INPUT'); +INSERT INTO fhir_script_source (id,version,script_id,source_text,source_type) +VALUES ('960d2e6c247948a2b04eb14879e71d14', 0, '8b5ab5f1363d4ccb8e63d6ecf25b3017', 'referenceUtils.getResource(input.subject, ''PATIENT'')', 'JAVASCRIPT'); +INSERT INTO fhir_script_source_version (script_source_id,fhir_version) +VALUES ('960d2e6c247948a2b04eb14879e71d14', 'DSTU3'); +INSERT INTO fhir_executable_script (id, version, script_id, name, code, description) +VALUES ('1b6a2f75cb4a47b18e903dfb4db07d36', 0, '8b5ab5f1363d4ccb8e63d6ecf25b3017', + 'Observation TEI Lookup', 'OBSERVATION_TEI_LOOKUP', 'Lookup of the Tracked Entity Instance FHIR Resource from FHIR Observation.'); + +-- Script that extracts GEO location from Observation +INSERT INTO fhir_script (id, version, name, code, description, script_type, return_type, input_type, output_type) +VALUES ('efb7fa7adf454c6a90960bc38f08c067', 0, 'GEO Location from Observation', 'EXTRACT_FHIR_OBSERVATION_GEO_LOCATION', +'Extracts the GEO location form FHIR Observation.', +'EVALUATE', 'LOCATION', NULL, NULL); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('efb7fa7adf454c6a90960bc38f08c067', 'CONTEXT'); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('efb7fa7adf454c6a90960bc38f08c067', 'INPUT'); +INSERT INTO fhir_script_source (id, version, script_id, source_text, source_type) VALUES ('2e0565a0ecde4ce2b313b0f786105385', 0, 'efb7fa7adf454c6a90960bc38f08c067', +'null', 'JAVASCRIPT'); +INSERT INTO fhir_script_source_version (script_source_id, fhir_version) +VALUES ('2e0565a0ecde4ce2b313b0f786105385', 'DSTU3'); +INSERT INTO fhir_executable_script (id, version, script_id, name, code, description) +VALUES ('bb07063146b342ec83b200ea219bcf50', 0, 'efb7fa7adf454c6a90960bc38f08c067', 'GEO Location from Observation', 'EXTRACT_FHIR_OBSERVATION_GEO_LOCATION', +'Extracts the GEO location form FHIR Observation.'); + +-- Script that gets the exact date from FHIR Observation +INSERT INTO fhir_script (id, version, name, code, description, script_type, return_type, input_type, output_type) +VALUES ('49d3570129794b36a9ba4269c1572cfd', 0, 'Observation Date Lookup', 'OBSERVATION_DATE_LOOKUP', 'Lookup of the exact date of the FHIR Observation.', 'EVALUATE', 'DATE_TIME', NULL, NULL); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('49d3570129794b36a9ba4269c1572cfd', 'CONTEXT'); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('49d3570129794b36a9ba4269c1572cfd', 'INPUT'); +INSERT INTO fhir_script_source (id,version,script_id,source_text,source_type) +VALUES ('630cd8383506410b9b668785682d5e0c', 0, '49d3570129794b36a9ba4269c1572cfd', +'var date = null; +if (input.hasEffectiveDateTimeType()) + date = dateTimeUtils.getPreciseDate(input.getEffectiveDateTimeType()); +else if (input.hasEffectivePeriod()) + date = dateTimeUtils.getPreciseDate(input.getEffectivePeriod().hasStart() ? input.getEffectivePeriod().getStartElement() : null); +else if (input.hasIssued()) + date = dateTimeUtils.getPreciseDate(input.getIssuedElement()); +date', 'JAVASCRIPT'); +INSERT INTO fhir_script_source_version (script_source_id,fhir_version) +VALUES ('630cd8383506410b9b668785682d5e0c', 'DSTU3'); +INSERT INTO fhir_executable_script (id, version, script_id, name, code, description) +VALUES ('a7b604369fa74fe48bf7f5e22123a980', 0, '49d3570129794b36a9ba4269c1572cfd', +'Observation Date Lookup', 'OBSERVATION_DATE_LOOKUP', 'Lookup of the exact date of the FHIR Observation.'); + +-- Script that gets a null date +INSERT INTO fhir_script (id, version, name, code, description, script_type, return_type, input_type, output_type) +VALUES ('04d4dc1f7c0f443790eaf432928bfcf2', 0, 'Other Date Lookup', 'OTHER_DATE_LOOKUP', 'Returns date time null.', 'EVALUATE', 'DATE_TIME', 'FHIR_RELATED_PERSON', NULL); +INSERT INTO fhir_script_source (id,version,script_id,source_text,source_type) +VALUES ('04df8d72ace2482f954d424749af5461', 0, '04d4dc1f7c0f443790eaf432928bfcf2', 'null', 'JAVASCRIPT'); +INSERT INTO fhir_executable_script (id, version, script_id, name, code, description) +VALUES ('b8625033eede4bf3bd341469d5952a2d', 0, '04d4dc1f7c0f443790eaf432928bfcf2', +'Other Date Lookup', 'OTHER_DATE_LOOKUP', 'Returns date time null.'); + +-- Script that gets a null organization unit reference +INSERT INTO fhir_script (id, version, name, code, description, script_type, return_type, input_type, output_type) +VALUES ('b6b7f1eb2eea4a6eb59f042ae3e07556', 0, 'Other Date Lookup', 'OTHER_ORG_UNIT_LOOKUP', 'Returns organization unit null.', 'EVALUATE', 'ORG_UNIT_REF', 'FHIR_RELATED_PERSON', NULL); +INSERT INTO fhir_script_source (id,version,script_id,source_text,source_type) +VALUES ('816a12da1fbb462981bd14764485acfd', 0, 'b6b7f1eb2eea4a6eb59f042ae3e07556', 'null', 'JAVASCRIPT'); +INSERT INTO fhir_executable_script (id, version, script_id, name, code, description) +VALUES ('e1aa08bfa91b47f5a0cddae996e225b9', 0, 'b6b7f1eb2eea4a6eb59f042ae3e07556', +'Other organization unit Lookup', 'OTHER_ORG_UNIT_LOOKUP', 'Returns null.'); + +-- Script that gets a null GEO reference +INSERT INTO fhir_script (id, version, name, code, description, script_type, return_type, input_type, output_type) +VALUES ('fa8a9a4ec9c44c6e91a8b32ef477cf41', 0, 'Other Date Lookup', 'OTHER_GEO_LOOKUP', 'Returns GEO location null.', 'EVALUATE', 'LOCATION', 'FHIR_RELATED_PERSON', NULL); +INSERT INTO fhir_script_source (id,version,script_id,source_text,source_type) +VALUES ('8e96c41de0dd4d6380afe23cc09b6564', 0, 'fa8a9a4ec9c44c6e91a8b32ef477cf41', 'null', 'JAVASCRIPT'); +INSERT INTO fhir_executable_script (id, version, script_id, name, code, description) +VALUES ('9da5690f9d5c4e6b974836d292c4f47a', 0, 'fa8a9a4ec9c44c6e91a8b32ef477cf41', +'Other Geo Lookup', 'OTHER_GEO_LOOKUP', 'Returns null.'); + +INSERT INTO fhir_resource_mapping(id, version, fhir_resource_type, created_at, last_updated_by, last_updated_at, imp_tei_lookup_script_id, imp_enrollment_org_lookup_script_id, imp_event_org_lookup_script_id, imp_enrollment_date_lookup_script_id, imp_event_date_lookup_script_id, imp_enrollment_geo_lookup_script_id, imp_event_geo_lookup_script_id, imp_effective_date_lookup_script_id) VALUES +('f1cbd84fa3db4aa7a9f2a5e547e60bed', 0, 'OBSERVATION', CURRENT_TIMESTAMP(), 'h2maqu827d', CURRENT_TIMESTAMP(), '1b6a2f75cb4a47b18e903dfb4db07d36', '25a97bb47b394ed48677db4bcaa28ccf', '25a97bb47b394ed48677db4bcaa28ccf', + 'a7b604369fa74fe48bf7f5e22123a980', 'a7b604369fa74fe48bf7f5e22123a980', 'bb07063146b342ec83b200ea219bcf50', 'bb07063146b342ec83b200ea219bcf50', 'a7b604369fa74fe48bf7f5e22123a980'); + +INSERT INTO fhir_code_category (id, version, name, code, description) +VALUES ('1197b27e395643dda75cbfc6808dc49d', 0, 'Vital Sign', 'VITAL_SIGN', 'Vital signs.'); +INSERT INTO fhir_code_set(id, version, code_category_id, name, code, description) +VALUES ('d4aa72e9b57e4d5c8856860ebdf460af', 0, '1197b27e395643dda75cbfc6808dc49d', 'All Birth Weight Observations', 'ALL_OB_BIRTH_WEIGHT', 'All Birth Weight Observations.'); +-- Code set with all Body Weight Observations +INSERT INTO fhir_code_set(id, version, code_category_id, name, code, description) +VALUES ('d37dfecbce884fa49a7844ffe874c140', 0, '1197b27e395643dda75cbfc6808dc49d', 'All Body Weight Observations', 'ALL_OB_BODY_WEIGHT', 'All Body Weight Observations.'); + +-- Script that sets for a data element the birth weight with a specific weight unit +INSERT INTO fhir_script (id, version, code, name, description, script_type, return_type, input_type, output_type) +VALUES ('50a60c9bd7f24ceabbc7b633d276a2f7', 0, 'TRANSFORM_FHIR_OB_BIRTH_WEIGHT', 'Transforms FHIR Observation Birth Weight', 'Transforms FHIR Observation Birth Weight to a data element and performs weight unit conversion.', +'TRANSFORM_TO_DHIS', 'BOOLEAN', 'FHIR_OBSERVATION', 'DHIS_EVENT'); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('50a60c9bd7f24ceabbc7b633d276a2f7', 'CONTEXT'); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('50a60c9bd7f24ceabbc7b633d276a2f7', 'INPUT'); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('50a60c9bd7f24ceabbc7b633d276a2f7', 'OUTPUT'); +INSERT INTO fhir_script_argument(id, version, script_id, name, data_type, mandatory, default_value, description) +VALUES ('600187f8eba545999061b6fe8bc1c518', 0, '50a60c9bd7f24ceabbc7b633d276a2f7', +'dataElement', 'DATA_ELEMENT_REF', TRUE, NULL, 'Data element on which the birth weight must be set.'); +INSERT INTO fhir_script_argument(id, version, script_id, name, data_type, mandatory, default_value, description) +VALUES ('ead06d428e4047f58a8974fbcf237b2b', 0, '50a60c9bd7f24ceabbc7b633d276a2f7', +'weightUnit', 'WEIGHT_UNIT', TRUE, 'KILO_GRAM', 'The resulting weight unit in which the value will be set on the data element.'); +INSERT INTO fhir_script_argument(id, version, script_id, name, data_type, mandatory, default_value, description) +VALUES ('5e272692021444fea16c0c79f2f61917', 0, '50a60c9bd7f24ceabbc7b633d276a2f7', +'round', 'BOOLEAN', TRUE, 'true', 'Specifies if the resulting value should be rounded.'); +INSERT INTO fhir_script_source (id, version, script_id, source_text, source_type) +VALUES ('05485e11fb1f4fc18518f9322dfb7dbb', 0, '50a60c9bd7f24ceabbc7b633d276a2f7', +'output.setValue(args[''dataElement''], vitalSignUtils.getWeight(input.value, args[''weightUnit''], args[''round'']), null, context.getFhirRequest().getLastUpdated())', 'JAVASCRIPT'); +INSERT INTO fhir_script_source_version (script_source_id, fhir_version) +VALUES ('05485e11fb1f4fc18518f9322dfb7dbb', 'DSTU3'); + +-- Script that is executed to check if enrollment into Child Programme is applicable +INSERT INTO fhir_script (id,version,name,code,description,script_type,return_type,input_type,output_type) +VALUES ('3ddfc83e065546db81110a3370970125', 0, 'Child Programme Creation Applicable', 'CHILD_PROGRAMME_CREATION_APPLICABLE', +'Checks if the enrollment into child programme is applicable. The enrollment is applicable if the person is younger than a defined amount time.', +'EVALUATE', 'BOOLEAN', NULL, NULL); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('3ddfc83e065546db81110a3370970125', 'TRACKED_ENTITY_INSTANCE'); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('3ddfc83e065546db81110a3370970125', 'DATE_TIME'); +INSERT INTO fhir_script_argument(id, version, script_id, name, data_type, mandatory, array_value, default_value, description) +VALUES ('b06c9036006b40439c6f57dd7286098b', 0, '3ddfc83e065546db81110a3370970125', +'birthDateAttribute', 'TRACKED_ENTITY_ATTRIBUTE_REF', TRUE, FALSE, 'CODE:MMD_PER_DOB', 'The reference of the tracked entity attribute that contains the birth date of the Person.'); +INSERT INTO fhir_script_argument(id, version, script_id, name, data_type, mandatory, array_value, default_value, description) +VALUES ('8cddd857d510472c835ad9454ffe1d39', 0, '3ddfc83e065546db81110a3370970125', +'age', 'INTEGER', TRUE, FALSE, '1', 'The person must be younger than the this amount of time (in specified units).'); +INSERT INTO fhir_script_argument(id, version, script_id, name, data_type, mandatory, array_value, default_value, description) +VALUES ('331db7c9edd84ff59e7740c391aa789e', 0, '3ddfc83e065546db81110a3370970125', +'ageUnit', 'DATE_UNIT', TRUE, FALSE, 'YEARS', 'The unit in which the age is specified.'); +INSERT INTO fhir_script_source (id,version,script_id,source_text,source_type) +VALUES ('1f9dc84d29a544609192eb03cea156d9', 0, '3ddfc83e065546db81110a3370970125', 'dateTimeUtils.isYoungerThan(dateTime, trackedEntityInstance.getValue(args[''birthDateAttribute'']), args[''age''], args[''ageUnit''])', 'JAVASCRIPT'); +INSERT INTO fhir_script_source_version (script_source_id,fhir_version) +VALUES ('1f9dc84d29a544609192eb03cea156d9', 'DSTU3'); +INSERT INTO fhir_executable_script (id, version, script_id, name, code, description) +VALUES ('dfb7f13cae214cfb88156f1416ca8388', 0, '3ddfc83e065546db81110a3370970125', +'Child Programme Creation Applicable', 'CHILD_PROGRAMME_CREATION_APPLICABLE', 'Checks if the enrollment of a person is applicable.'); + +-- Script that is executed on creation of a program instance of Child Programme +INSERT INTO fhir_script (id,version,name,code,description,script_type,return_type,input_type,output_type) +VALUES ('60e83e185f6640a19c9d1d993e5ccdb3', 0, 'Child Programme Creation', 'CHILD_PROGRAMME_CREATION', 'Child programme creation.', 'EVALUATE', 'BOOLEAN', NULL, 'DHIS_EVENT'); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('60e83e185f6640a19c9d1d993e5ccdb3', 'CONTEXT'); +INSERT INTO fhir_script_variable (script_id, variable) VALUES ('60e83e185f6640a19c9d1d993e5ccdb3', 'ENROLLMENT'); +INSERT INTO fhir_script_argument(id, version, script_id, name, data_type, mandatory, array_value, default_value, description) +VALUES ('363ed415be4a4311a7bf780a304d6f8c', 0, '60e83e185f6640a19c9d1d993e5ccdb3', +'birthDateAttribute', 'TRACKED_ENTITY_ATTRIBUTE_REF', TRUE, FALSE, 'CODE:MMD_PER_DOB', 'The reference of the tracked entity attribute that contains the birth date of the Person.'); +INSERT INTO fhir_script_source (id,version,script_id,source_text,source_type) +VALUES ('f45aed605208430e869ef0b87f5a6321', 0, '60e83e185f6640a19c9d1d993e5ccdb3', 'enrollment.setIncidentDate(trackedEntityInstance.getValue(args[''birthDateAttribute'']))', 'JAVASCRIPT'); +INSERT INTO fhir_script_source_version (script_source_id,fhir_version) +VALUES ('f45aed605208430e869ef0b87f5a6321', 'DSTU3'); +INSERT INTO fhir_executable_script (id, version, script_id, name, code, description) +VALUES ('6836cbd193ba4ab8a4cb69348ad9d099', 0, '60e83e185f6640a19c9d1d993e5ccdb3', +'Child Programme Creation', 'CHILD_PROGRAMME_CREATION', 'Child programme creation.'); + +-- Tracker Program Child Programme +INSERT INTO fhir_tracker_program (id,version,name,program_ref,tracked_entity_rule_id,enabled,creation_enabled,creation_applicable_script_id,creation_script_id,enrollment_date_is_incident,tracked_entity_fhir_resource_type) +VALUES ('45e61665754d4861891ea2064fc0ae7d', 0, 'Child Programme', 'NAME:Child Programme', '5f9ebdc9852e4c8387ca795946aabc35', TRUE, TRUE, +'dfb7f13cae214cfb88156f1416ca8388', '6836cbd193ba4ab8a4cb69348ad9d099', TRUE, 'PATIENT'); +-- Tracker Program Child Programme, Stage Birth +INSERT INTO fhir_tracker_program_stage (id,version,name,program_stage_ref,program_id,enabled,creation_enabled,event_date_is_incident) +VALUES ('4c074c85be494b9d89739e16b9615dad', 0, 'Birth', 'NAME:Birth', '45e61665754d4861891ea2064fc0ae7d', TRUE, TRUE, TRUE); +-- Tracker Program Child Programme, Stage Baby Postnatal +INSERT INTO fhir_tracker_program_stage (id,version,name,program_stage_ref,program_id,enabled,creation_enabled,event_date_is_incident) +VALUES ('526b4e01774747efa25df32ccd739e87', 0, 'Baby Postnatal', 'NAME:Baby Postnatal', '45e61665754d4861891ea2064fc0ae7d', TRUE, TRUE, TRUE); + +-- Tracker Program Child Programme, Birth: Weight from Birth Weight +INSERT INTO fhir_executable_script (id, version, script_id, name, code) +VALUES ('518b52d22d1e417186ce1e40ec269a1a', 0, '50a60c9bd7f24ceabbc7b633d276a2f7', 'CP: Birth Weight', 'CP_BIRTH_WEIGHT'); +INSERT INTO fhir_executable_script_argument(id, executable_script_id, script_argument_id, override_value) +VALUES ('75c2d252e7c24321b20bba7d5f89af80', '518b52d22d1e417186ce1e40ec269a1a', 'ead06d428e4047f58a8974fbcf237b2b', 'GRAM'); + +-- Rule Tracker Program Child Programme, Birth: Weight from Birth Weight +INSERT INTO fhir_rule (id, version, name, description, enabled, evaluation_order, fhir_resource_type, dhis_resource_type, applicable_code_set_id, transform_imp_script_id) +VALUES ('ff043b6e40c94fa79721ba2239b38360', 0, 'Child Programme: Birth Weight', NULL, TRUE, 0, 'OBSERVATION', 'PROGRAM_STAGE_EVENT', 'd4aa72e9b57e4d5c8856860ebdf460af', '518b52d22d1e417186ce1e40ec269a1a'); +INSERT INTO fhir_program_stage_rule (id, program_stage_id,enrollment_creation_enabled,event_creation_enabled) +VALUES ('ff043b6e40c94fa79721ba2239b38360','4c074c85be494b9d89739e16b9615dad',TRUE,TRUE); + +INSERT INTO fhir_rule_dhis_data_ref(id, version, rule_id, data_ref, script_arg_name, required) +SELECT '87388c6e449e466f8ef8c2b44557a10f', 0, id, 'CODE:DE_2005736', 'dataElement', true +FROM fhir_rule +WHERE id = 'ff043b6e40c94fa79721ba2239b38360'; + +-- Tracker Program Child Programme, Baby Postnatal: Infant Weight +INSERT INTO fhir_executable_script (id, version, script_id, name, code) +VALUES ('0104ad19ba8248dcbbd138dd5f0d8a2c', 0, 'f1da6937e2fe47a4b0f38bbff7818ee1', 'CP: Infant Weight', 'CP_BODY_WEIGHT'); +INSERT INTO fhir_executable_script_argument(id, executable_script_id, script_argument_id, override_value) +VALUES ('5b729da43f0b49ba9059cc7fc74841d8', '0104ad19ba8248dcbbd138dd5f0d8a2c', '3d15bf81343c45bc9c281e87a8da6fa5', 'GRAM'); + +-- Rule Tracker Program Child Programme, Baby Postnatal: Infant Weight +INSERT INTO fhir_rule (id, version, name, description, enabled, evaluation_order, fhir_resource_type, dhis_resource_type, applicable_code_set_id, transform_imp_script_id) +VALUES ('a6636c83f23648cdbb2b592147db9a34', 0, 'Child Programme: Infant Weight', NULL, TRUE, 10, 'OBSERVATION', 'PROGRAM_STAGE_EVENT', 'd37dfecbce884fa49a7844ffe874c140', '0104ad19ba8248dcbbd138dd5f0d8a2c'); +INSERT INTO fhir_program_stage_rule (id, program_stage_id, before_period_day_type, after_period_day_type, after_period_days,enrollment_creation_enabled,event_creation_enabled) +VALUES ('a6636c83f23648cdbb2b592147db9a34','526b4e01774747efa25df32ccd739e87', 'ORIG_DUE_DATE', 'ORIG_DUE_DATE', 1,TRUE,TRUE); + +INSERT INTO fhir_rule_dhis_data_ref(id, version, rule_id, data_ref, script_arg_name, required) +SELECT '9589bff180b94f9dbafb8e679a219bf1', 0, id, 'CODE:DE_2006099', 'dataElement', true +FROM fhir_rule +WHERE id = 'a6636c83f23648cdbb2b592147db9a34'; diff --git a/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createExecutableScript.json b/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createExecutableScript.json index 047699dd..9add7dd0 100644 --- a/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createExecutableScript.json +++ b/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createExecutableScript.json @@ -1,7 +1,7 @@ { "script": "$scriptId", - "name": "CP: Birth Weight", - "code": "CP_BIRTH_WEIGHT", + "name": "CP: Baby Birth Weight", + "code": "CP_BABY_BIRTH_WEIGHT", "overrideArguments": [ { "argument": "$dataElementArgId", diff --git a/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createFhirResourceMapping.json b/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createFhirResourceMapping.json new file mode 100644 index 00000000..70771223 --- /dev/null +++ b/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createFhirResourceMapping.json @@ -0,0 +1,11 @@ +{ + "fhirResourceType": "IMMUNIZATION", + "impEventGeoLookupScript": "$executableScriptBaseUri/bb070631-46b3-42ec-83b2-00ea219bcf50", + "impEffectiveDateLookupScript": "$executableScriptBaseUri/a7b60436-9fa7-4fe4-8bf7-f5e22123a980", + "impTeiLookupScript": "$executableScriptBaseUri/1b6a2f75-cb4a-47b1-8e90-3dfb4db07d36", + "impEventDateLookupScript": "$executableScriptBaseUri/a7b60436-9fa7-4fe4-8bf7-f5e22123a980", + "impEnrollmentOrgLookupScript": "$executableScriptBaseUri/25a97bb4-7b39-4ed4-8677-db4bcaa28ccf", + "impEventOrgLookupScript": "$executableScriptBaseUri/25a97bb4-7b39-4ed4-8677-db4bcaa28ccf", + "impEnrollmentGeoLookupScript": "$executableScriptBaseUri/bb070631-46b3-42ec-83b2-00ea219bcf50", + "impEnrollmentDateLookupScript": "$executableScriptBaseUri/a7b60436-9fa7-4fe4-8bf7-f5e22123a980" +} diff --git a/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgram.json b/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgram.json new file mode 100644 index 00000000..a3c78b09 --- /dev/null +++ b/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgram.json @@ -0,0 +1,17 @@ +{ + "name": "Mother Programme", + "description": null, + "programReference": { + "value": "Mother Programme", + "type": "NAME" + }, + "enabled": true, + "creationEnabled": true, + "enrollmentDateIsIncident": true, + "expEnabled": false, + "fhirCreateEnabled": true, + "fhirUpdateEnabled": false, + "fhirDeleteEnabled": false, + "trackedEntityFhirResourceType": "PATIENT", + "trackedEntityRule": "$apiBaseUri/trackedEntityRules/5f9ebdc9-852e-4c83-87ca-795946aabc35" +} diff --git a/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgramStage.json b/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgramStage.json new file mode 100644 index 00000000..e46bc737 --- /dev/null +++ b/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgramStage.json @@ -0,0 +1,17 @@ +{ + "name": "Baby Postnatal", + "description": null, + "programStageReference": { + "value": "Baby Postnatal", + "type": "NAME" + }, + "enabled": true, + "creationEnabled": true, + "creationStatus": null, + "eventDateIsIncident": true, + "beforePeriodDayType": null, + "beforePeriodDays": 0, + "afterPeriodDayType": null, + "afterPeriodDays": 0, + "program": "$apiBaseUri/trackerPrograms/45e61665-754d-4861-891e-a2064fc0ae7d" +} diff --git a/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgramStageRule.json b/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgramStageRule.json new file mode 100644 index 00000000..44737dac --- /dev/null +++ b/fhir/src/test/resources/org/dhis2/fhir/adapter/fhir/metadata/repository/createProgramStageRule.json @@ -0,0 +1,54 @@ +{ + "name": "Child Programme: Estimated Infant Weight", + "description": null, + "enabled": true, + "evaluationOrder": 10, + "dhisResourceType": "PROGRAM_STAGE_EVENT", + "fhirResourceType": "OBSERVATION", + "impEnabled": true, + "expEnabled": false, + "fhirCreateEnabled": true, + "fhirUpdateEnabled": false, + "fhirDeleteEnabled": false, + "stop": false, + "containedAllowed": false, + "dhisDataReferences": [ + { + "dataReference": { + "value": "DE_2006099", + "type": "CODE" + }, + "scriptArgName": "dataElement", + "description": "The data element that receives the value.", + "required": true + } + ], + "enrollmentCreationEnabled": true, + "eventCreationEnabled": true, + "updateEventDate": false, + "beforePeriodDayType": "ORIG_DUE_DATE", + "beforePeriodDays": 0, + "afterPeriodDayType": "ORIG_DUE_DATE", + "afterPeriodDays": 1, + "applicableEnrollmentStatus": { + "active": true, + "completed": true, + "cancelled": false + }, + "applicableEventStatus": { + "overdue": true, + "active": true, + "schedule": true, + "visited": true, + "completed": true, + "skipped": false + }, + "eventStatusUpdate": { + "overdueToActive": false, + "scheduleToActive": true, + "completedToActive": false + }, + "transformImpScript": "$apiBaseUri/executableScripts/0104ad19-ba82-48dc-bbd1-38dd5f0d8a2c", + "programStage": "$apiBaseUri/executableScripts/526b4e01-7747-47ef-a25d-f32ccd739e87", + "applicableCodeSet": "$apiBaseUri/codeSets/d37dfecb-ce88-4fa4-9a78-44ffe874c140" +} diff --git a/pom.xml b/pom.xml index 9993c1e8..ad3bc50b 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,6 @@