diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/index/IdHelperServiceTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/index/IdHelperServiceTest.java index 77b341fedb8..200078811c0 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/index/IdHelperServiceTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/index/IdHelperServiceTest.java @@ -13,12 +13,22 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import jakarta.persistence.EntityManager; import jakarta.persistence.TypedQuery; import jakarta.persistence.criteria.CriteriaQuery; + +import java.util.ArrayList; +import java.util.Collection; + import org.hibernate.sql.results.internal.TupleImpl; import org.hl7.fhir.r4.model.Patient; + +import static org.junit.jupiter.api.Assertions.fail; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Answers; + +import static org.mockito.ArgumentMatchers.anyBoolean; + import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; @@ -107,5 +117,30 @@ public class IdHelperServiceTest { assertEquals(tuple[3], result.getDeleted()); } + @Test + public void testResolveResourceIdentity_withPersistentIdOfResourceWithForcedIdAndDefaultClientIdStrategy_returnsNotFound(){ + RequestPartitionId partitionId = RequestPartitionId.fromPartitionIdAndName(1, "partition"); + String resourceType = "Patient"; + Object[] tuple = new Object[] { + JpaPid.fromId(1L), + "Patient", + "AAA", + new Date(), + null + }; + + when(myEntityManager.createQuery(any(CriteriaQuery.class))).thenReturn(myTypedQuery); + when(myTypedQuery.getResultList()).thenReturn(List.of( + new TupleImpl(null, tuple) + )); + + try { + // Search by the PID of the resource that has a client assigned FHIR Id + myHelperSvc.resolveResourceIdentity(partitionId, resourceType, "1", ResolveIdentityMode.includeDeleted().cacheOk()); + fail(); + } catch(ResourceNotFoundException e) { + assertThat(e.getMessage()).isEqualTo("HAPI-2001: Resource Patient/1 is not known"); + } + } } diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ReferentialIntegrityTest.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ReferentialIntegrityTest.java index 5f10635772a..632eae07e32 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ReferentialIntegrityTest.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4ReferentialIntegrityTest.java @@ -2,10 +2,14 @@ package ca.uhn.fhir.jpa.dao.r4; import ca.uhn.fhir.i18n.Msg; import ca.uhn.fhir.jpa.api.config.JpaStorageSettings; +import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome; import ca.uhn.fhir.jpa.test.BaseJpaR4Test; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; + +import static org.assertj.core.api.Assertions.assertThat; + import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r4.model.IdType; import org.hl7.fhir.r4.model.Observation; @@ -16,6 +20,10 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.EnumSource; + +import static org.junit.jupiter.params.provider.EnumSource.Mode.EXCLUDE; + import org.junit.jupiter.params.provider.MethodSource; import java.util.stream.Stream; @@ -190,6 +198,29 @@ public class FhirResourceDaoR4ReferentialIntegrityTest extends BaseJpaR4Test { } } + @ParameterizedTest + @EnumSource(value = JpaStorageSettings.ClientIdStrategyEnum.class, mode = EXCLUDE, names = {"NOT_ALLOWED"}) + public void testReferentialIntegrityOnWrite_withReferenceByPidForClientAssignedIdResource(JpaStorageSettings.ClientIdStrategyEnum theClientIdStrategy) { + myStorageSettings.setResourceClientIdStrategy(theClientIdStrategy); + myStorageSettings.setEnforceReferentialIntegrityOnWrite(true); + + Organization o = new Organization(); + o.setName("FOO"); + o.setId("O1"); + DaoMethodOutcome outcome = myOrganizationDao.update(o); + Long organizationPid = (Long) outcome.getEntity().getPersistentId().getId(); + + Patient p = new Patient(); + p.setManagingOrganization(new Reference("Organization/" + organizationPid)); + + try { + myPatientDao.create(p); + fail(); + } catch (InvalidRequestException e) { + assertThat(e.getMessage()).contains("Resource Organization/" + organizationPid + " not found, specified in path: Patient.managingOrganization"); + } + } + @Test public void testDeleteFail() { Organization o = new Organization();