From ad5297b714a0b79e3f393252fd5dd6a8c68c5d5e Mon Sep 17 00:00:00 2001 From: Justin Dar Date: Tue, 21 Sep 2021 13:09:08 -0700 Subject: [PATCH 1/7] fix for issue #3014 --- .../fhir/jpa/dao/BaseHapiFhirResourceDao.java | 8 ++++--- .../jpa/dao/expunge/DeleteExpungeDaoTest.java | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index 2afd65245eb..54264fc136c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -86,6 +86,7 @@ import ca.uhn.fhir.rest.server.IRestfulServerDefaults; import ca.uhn.fhir.rest.server.RestfulServerUtils; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; +import ca.uhn.fhir.rest.server.exceptions.NotImplementedOperationException; import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; @@ -136,12 +137,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -588,6 +586,10 @@ public abstract class BaseHapiFhirResourceDao extends B throw new MethodNotAllowedException("_expunge is not enabled on this server: " + getConfig().cannotDeleteExpungeReason()); } + if (theUrl.contains("_cascade")) { + throw new NotImplementedOperationException("_expunge cannot be used with _cascade"); + } + List urlsToDeleteExpunge = Collections.singletonList(theUrl); try { JobExecution jobExecution = myDeleteExpungeJobSubmitter.submitJob(getConfig().getExpungeBatchSize(), urlsToDeleteExpunge, theRequest); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java index c4b430c4e57..306f1f14e50 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java @@ -7,6 +7,8 @@ import ca.uhn.fhir.jpa.batch.writer.SqlExecutorWriter; import ca.uhn.fhir.jpa.dao.r4.BaseJpaR4Test; import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.partition.SystemRequestDetails; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.test.utilities.BatchJobHelper; import ca.uhn.fhir.util.BundleBuilder; import org.hl7.fhir.instance.model.api.IIdType; @@ -27,6 +29,7 @@ import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; class DeleteExpungeDaoTest extends BaseJpaR4Test { @Autowired @@ -51,6 +54,25 @@ class DeleteExpungeDaoTest extends BaseJpaR4Test { myDaoConfig.setExpungeBatchSize(defaultDaoConfig.getExpungeBatchSize()); } + @Test + public void testDeleteCascadeExpungeReturns501() { + // Create new organization + Organization organization = new Organization(); + organization.setName("FOO"); + IIdType organizationId = myOrganizationDao.create(organization).getId().toUnqualifiedVersionless(); + + Patient patient = new Patient(); + patient.setManagingOrganization(new Reference(organizationId)); + IIdType patientId = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); + + // Try to delete _cascade and _expunge on the organization + BaseServerResponseException e = assertThrows(BaseServerResponseException.class, () -> {myOrganizationDao + .deleteByUrl("Organization?" + "_cascade=true&" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd);}); + + // Get not implemented HTTP 501 error + assertEquals(Constants.STATUS_HTTP_501_NOT_IMPLEMENTED, e.getStatusCode()); + } + @Test public void testDeleteExpungeThrowExceptionIfForeignKeyLinksExists() { // setup From c9137075990ef2f7b312ab117cedcabf7da7ab14 Mon Sep 17 00:00:00 2001 From: Jimmy Deng Date: Wed, 22 Sep 2021 10:15:22 -0400 Subject: [PATCH 2/7] added header check --- .../java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java | 2 +- .../ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java | 3 ++- .../main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java | 6 ++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index 54264fc136c..c1605a90183 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -586,7 +586,7 @@ public abstract class BaseHapiFhirResourceDao extends B throw new MethodNotAllowedException("_expunge is not enabled on this server: " + getConfig().cannotDeleteExpungeReason()); } - if (theUrl.contains("_cascade")) { + if (theUrl.contains(JpaConstants.PARAM_DELETE_CASACADE) || theRequest.getHeader("X-Cascade").equals("delete")) { throw new NotImplementedOperationException("_expunge cannot be used with _cascade"); } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java index 306f1f14e50..fd1fa912677 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java @@ -67,10 +67,11 @@ class DeleteExpungeDaoTest extends BaseJpaR4Test { // Try to delete _cascade and _expunge on the organization BaseServerResponseException e = assertThrows(BaseServerResponseException.class, () -> {myOrganizationDao - .deleteByUrl("Organization?" + "_cascade=true&" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd);}); + .deleteByUrl("Organization?" + "_cascade=delete&" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd);}); // Get not implemented HTTP 501 error assertEquals(Constants.STATUS_HTTP_501_NOT_IMPLEMENTED, e.getStatusCode()); + assertEquals("_expunge cannot be used with _cascade", e.getMessage()); } @Test diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java index 823c3a42cd3..c3a1f35722e 100644 --- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java +++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java @@ -200,6 +200,12 @@ public class JpaConstants { public static final String PARAM_DELETE_EXPUNGE = "_expunge"; + /** + * Parameter for delete to indicate the resource should be cascading delete + */ + + public static final String PARAM_DELETE_CASACADE = "_cascade"; + /** * URL for extension on a SearchParameter indicating that text values should not be indexed */ From 48f73fa1d184de3f3d3bf3533fe4367051aaa62b Mon Sep 17 00:00:00 2001 From: Jimmy Deng Date: Wed, 22 Sep 2021 10:25:57 -0400 Subject: [PATCH 3/7] typo --- .../main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java | 2 +- .../src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index c1605a90183..16ff7b45fb6 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -586,7 +586,7 @@ public abstract class BaseHapiFhirResourceDao extends B throw new MethodNotAllowedException("_expunge is not enabled on this server: " + getConfig().cannotDeleteExpungeReason()); } - if (theUrl.contains(JpaConstants.PARAM_DELETE_CASACADE) || theRequest.getHeader("X-Cascade").equals("delete")) { + if (theUrl.contains(JpaConstants.PARAM_DELETE_CASCADE) || theRequest.getHeader("X-Cascade").equals("delete")) { throw new NotImplementedOperationException("_expunge cannot be used with _cascade"); } diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java index c3a1f35722e..845c6d0d8c1 100644 --- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java +++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java @@ -204,7 +204,7 @@ public class JpaConstants { * Parameter for delete to indicate the resource should be cascading delete */ - public static final String PARAM_DELETE_CASACADE = "_cascade"; + public static final String PARAM_DELETE_CASCADE = "_cascade"; /** * URL for extension on a SearchParameter indicating that text values should not be indexed From 9a18422173e796dce0355cba69de656d17922961 Mon Sep 17 00:00:00 2001 From: Jimmy Deng Date: Wed, 22 Sep 2021 11:09:50 -0400 Subject: [PATCH 4/7] fix review --- .../5_6_0/3014-prevent-delete-expunge-and-cascade.yaml | 0 .../java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java | 3 ++- .../main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java | 6 ------ 3 files changed, 2 insertions(+), 7 deletions(-) create mode 100644 hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3014-prevent-delete-expunge-and-cascade.yaml diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3014-prevent-delete-expunge-and-cascade.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3014-prevent-delete-expunge-and-cascade.yaml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index 16ff7b45fb6..3b1b64ba9e8 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -92,6 +92,7 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; +import ca.uhn.fhir.rest.server.provider.ProviderConstants; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster; import ca.uhn.fhir.util.ObjectUtil; @@ -586,7 +587,7 @@ public abstract class BaseHapiFhirResourceDao extends B throw new MethodNotAllowedException("_expunge is not enabled on this server: " + getConfig().cannotDeleteExpungeReason()); } - if (theUrl.contains(JpaConstants.PARAM_DELETE_CASCADE) || theRequest.getHeader("X-Cascade").equals("delete")) { + if (theUrl.contains(Constants.PARAMETER_CASCADE_DELETE) || theRequest.getHeader(Constants.HEADER_CASCADE).equals(Constants.CASCADE_DELETE)) { throw new NotImplementedOperationException("_expunge cannot be used with _cascade"); } diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java index 845c6d0d8c1..823c3a42cd3 100644 --- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java +++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/util/JpaConstants.java @@ -200,12 +200,6 @@ public class JpaConstants { public static final String PARAM_DELETE_EXPUNGE = "_expunge"; - /** - * Parameter for delete to indicate the resource should be cascading delete - */ - - public static final String PARAM_DELETE_CASCADE = "_cascade"; - /** * URL for extension on a SearchParameter indicating that text values should not be indexed */ From 26ac6499460cfc376681eac567bd3b8df24e1d4d Mon Sep 17 00:00:00 2001 From: Jimmy Deng Date: Wed, 22 Sep 2021 11:11:10 -0400 Subject: [PATCH 5/7] changelog --- .../5_6_0/3014-prevent-delete-expunge-and-cascade.yaml | 4 ++++ .../java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java | 3 +-- .../ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3014-prevent-delete-expunge-and-cascade.yaml b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3014-prevent-delete-expunge-and-cascade.yaml index e69de29bb2d..4dc59bc95aa 100644 --- a/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3014-prevent-delete-expunge-and-cascade.yaml +++ b/hapi-fhir-docs/src/main/resources/ca/uhn/hapi/fhir/changelog/5_6_0/3014-prevent-delete-expunge-and-cascade.yaml @@ -0,0 +1,4 @@ +--- +type: change +jira: SMILE-3128 +title: "Prevent _expunge and _cascade from being used on the same DELETE operation" diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index 3b1b64ba9e8..d7bd6077fbf 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -92,7 +92,6 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; -import ca.uhn.fhir.rest.server.provider.ProviderConstants; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.rest.server.util.CompositeInterceptorBroadcaster; import ca.uhn.fhir.util.ObjectUtil; @@ -588,7 +587,7 @@ public abstract class BaseHapiFhirResourceDao extends B } if (theUrl.contains(Constants.PARAMETER_CASCADE_DELETE) || theRequest.getHeader(Constants.HEADER_CASCADE).equals(Constants.CASCADE_DELETE)) { - throw new NotImplementedOperationException("_expunge cannot be used with _cascade"); + throw new InvalidRequestException("_expunge cannot be used with _cascade"); } List urlsToDeleteExpunge = Collections.singletonList(theUrl); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java index fd1fa912677..bb28b8dd050 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java @@ -55,7 +55,7 @@ class DeleteExpungeDaoTest extends BaseJpaR4Test { } @Test - public void testDeleteCascadeExpungeReturns501() { + public void testDeleteCascadeExpungeReturns400() { // Create new organization Organization organization = new Organization(); organization.setName("FOO"); @@ -69,8 +69,8 @@ class DeleteExpungeDaoTest extends BaseJpaR4Test { BaseServerResponseException e = assertThrows(BaseServerResponseException.class, () -> {myOrganizationDao .deleteByUrl("Organization?" + "_cascade=delete&" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd);}); - // Get not implemented HTTP 501 error - assertEquals(Constants.STATUS_HTTP_501_NOT_IMPLEMENTED, e.getStatusCode()); + // Get not implemented HTTP 400 error + assertEquals(Constants.STATUS_HTTP_400_BAD_REQUEST, e.getStatusCode()); assertEquals("_expunge cannot be used with _cascade", e.getMessage()); } From f9796b9e2a88243fb85199bc90483b0dc6091497 Mon Sep 17 00:00:00 2001 From: Jimmy Deng Date: Wed, 22 Sep 2021 12:52:28 -0400 Subject: [PATCH 6/7] fix test --- .../main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index d7bd6077fbf..d43a08cdde1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -586,7 +586,7 @@ public abstract class BaseHapiFhirResourceDao extends B throw new MethodNotAllowedException("_expunge is not enabled on this server: " + getConfig().cannotDeleteExpungeReason()); } - if (theUrl.contains(Constants.PARAMETER_CASCADE_DELETE) || theRequest.getHeader(Constants.HEADER_CASCADE).equals(Constants.CASCADE_DELETE)) { + if (theUrl.contains(Constants.PARAMETER_CASCADE_DELETE) || (theRequest.getHeader(Constants.HEADER_CASCADE) != null && theRequest.getHeader(Constants.HEADER_CASCADE).equals(Constants.CASCADE_DELETE))) { throw new InvalidRequestException("_expunge cannot be used with _cascade"); } From 2436f748aaae00058a49ed98d4c6587b4e94056a Mon Sep 17 00:00:00 2001 From: Jimmy Deng Date: Wed, 22 Sep 2021 14:38:53 -0400 Subject: [PATCH 7/7] fix test --- .../jpa/dao/expunge/DeleteExpungeDaoTest.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java index bb28b8dd050..ba7712066cb 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/expunge/DeleteExpungeDaoTest.java @@ -17,9 +17,11 @@ import org.hl7.fhir.r4.model.OperationOutcome; import org.hl7.fhir.r4.model.Organization; import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Reference; +import org.hl7.fhir.r5.model.StructureDefinition; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.stubbing.Answer; import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.JobExecution; import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +32,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.Mockito.when; class DeleteExpungeDaoTest extends BaseJpaR4Test { @Autowired @@ -66,14 +70,29 @@ class DeleteExpungeDaoTest extends BaseJpaR4Test { IIdType patientId = myPatientDao.create(patient).getId().toUnqualifiedVersionless(); // Try to delete _cascade and _expunge on the organization - BaseServerResponseException e = assertThrows(BaseServerResponseException.class, () -> {myOrganizationDao - .deleteByUrl("Organization?" + "_cascade=delete&" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd);}); + BaseServerResponseException e = assertThrows(BaseServerResponseException.class, () -> { + myOrganizationDao + .deleteByUrl("Organization?" + "_cascade=delete&" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd); + }); + + // Get not implemented HTTP 400 error + assertEquals(Constants.STATUS_HTTP_400_BAD_REQUEST, e.getStatusCode()); + assertEquals("_expunge cannot be used with _cascade", e.getMessage()); + + + // Try to delete with header 'X-Cascade' = delete + when(mySrd.getHeader(Constants.HEADER_CASCADE)).thenReturn(Constants.CASCADE_DELETE); + e = assertThrows(BaseServerResponseException.class, () -> { + myOrganizationDao + .deleteByUrl("Organization?" + JpaConstants.PARAM_DELETE_EXPUNGE + "=true", mySrd); + }); // Get not implemented HTTP 400 error assertEquals(Constants.STATUS_HTTP_400_BAD_REQUEST, e.getStatusCode()); assertEquals("_expunge cannot be used with _cascade", e.getMessage()); } + @Test public void testDeleteExpungeThrowExceptionIfForeignKeyLinksExists() { // setup