diff --git a/omod/src/main/java/org/openmrs/module/cohort/web/resource/CohortMemberResource.java b/omod/src/main/java/org/openmrs/module/cohort/web/resource/CohortMemberResource.java index 76894f3..4e1928a 100644 --- a/omod/src/main/java/org/openmrs/module/cohort/web/resource/CohortMemberResource.java +++ b/omod/src/main/java/org/openmrs/module/cohort/web/resource/CohortMemberResource.java @@ -108,15 +108,15 @@ public CohortMember save(CohortMember cohortMember) throws ResponseException { if (cohort.getVoided()) { throw new RuntimeException("Cannot add patient to ended group."); } - for (CohortMember member : cohort.getCohortMembers()) { - if (member.getPatient().getUuid().equals(newPatient.getUuid()) && !cohortMember.getVoided()) { - if (member.getEndDate() == null) { + for (CohortMember currentMember : cohort.getCohortMembers()) { + if (currentMember.getPatient().getUuid().equals(newPatient.getUuid()) && !cohortMember.getVoided()) { + if (currentMember.getEndDate() == null && cohortMember.getEndDate() == null) { throw new RuntimeException("Patient already exists in group."); - } else { - member.setVoided(false); - member.setEndDate(null); - cohortMember = member; } + currentMember.setEndDate(cohortMember.getEndDate()); + currentMember.setVoided(false); + cohortMember = currentMember; + break; } } return Context.getService(CohortMemberService.class).saveCohortMember(cohortMember); diff --git a/omod/src/test/java/org/openmrs/module/cohort/web/resource/CohortMemberResourceControllerTest.java b/omod/src/test/java/org/openmrs/module/cohort/web/resource/CohortMemberResourceControllerTest.java new file mode 100644 index 0000000..a36a121 --- /dev/null +++ b/omod/src/test/java/org/openmrs/module/cohort/web/resource/CohortMemberResourceControllerTest.java @@ -0,0 +1,178 @@ +package org.openmrs.module.cohort.web.resource; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.sql.Date; +import java.time.Instant; +import java.util.Collection; +import java.util.UUID; + +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Location; +import org.openmrs.Patient; +import org.openmrs.PatientIdentifier; +import org.openmrs.PatientIdentifierType; +import org.openmrs.PersonName; +import org.openmrs.api.context.Context; +import org.openmrs.module.cohort.CohortM; +import org.openmrs.module.cohort.CohortMember; +import org.openmrs.module.cohort.api.CohortMemberService; +import org.openmrs.module.cohort.api.CohortService; +import org.openmrs.module.webservices.rest.web.v1_0.controller.MainResourceControllerTest; + +public class CohortMemberResourceControllerTest extends MainResourceControllerTest { + + private CohortM cohort; + + private Patient patient; + + @Override + public String getURI() { + return "cohortm/cohortmember"; + } + + @Override + public String getUuid() { + return null; + } + + @Override + public long getAllCount() { + return 0; + } + + @Before + public void setUp() { + cohort = createMinimalCohort(); + + Location location = Context.getLocationService().saveLocation(createMinimalLocation()); + PatientIdentifierType patientIdentifierType = Context.getPatientService() + .savePatientIdentifierType(createMinimalPatientIdentifierType()); + patient = createMinimalPatient(location, patientIdentifierType); + Context.getPatientService().savePatient(patient); + } + + @Test + // Verifies if a new CohortMember can be successfully created and saved + public void shouldCreateNewCohortMember() throws Exception { + Context.getService(CohortService.class).saveCohortM(cohort); + + String json = String.format( + "{ \"cohort\": \"%s\", \"patient\":\"%s\", \"startDate\":\"2023-08-22T01:00:00.000+0100\" }", cohort.getUuid(), + patient.getUuid()); + + assertEquals(0, Context.getService(CohortMemberService.class).findAllCohortMembers().size()); + + handle(newPostRequest(getURI(), json)); + + Collection cohortMembers = Context.getService(CohortMemberService.class).findAllCohortMembers(); + assertEquals(1, cohortMembers.size()); + + CohortMember cohortMember = cohortMembers.iterator().next(); + assertEquals(cohort.getUuid(), cohortMember.getCohort().getUuid()); + assertEquals(patient.getUuid(), cohortMember.getPatient().getUuid()); + assertNotNull(cohortMember.getStartDate()); + assertNull(cohortMember.getEndDate()); + } + + @Test + // Verifies if an existing CohortMember can be successfully updated + public void shouldUpdateExistingCohortMember() throws Exception { + CohortMember cohortMember = createMinimalCohortMember(); + cohort.addMemberships(cohortMember); + + Context.getService(CohortService.class).saveCohortM(cohort); + Context.getService(CohortMemberService.class).saveCohortMember(cohortMember); + + String json = String.format( + "{ \"cohort\": \"%s\", \"patient\":\"%s\", \"startDate\":\"2023-08-22T01:00:00.000+0100\", \"endDate\":\"2023-09-22T01:00:00.000+0100\" }", + cohort.getUuid(), patient.getUuid()); + + assertEquals(1, Context.getService(CohortMemberService.class).findAllCohortMembers().size()); + assertNull(cohortMember.getEndDate()); + + handle(newPostRequest(getURI(), json)); + + Collection cohortMembers = Context.getService(CohortMemberService.class).findAllCohortMembers(); + assertEquals(1, cohortMembers.size()); + + CohortMember updatedCohortMember = cohortMembers.iterator().next(); + assertNotNull(updatedCohortMember.getEndDate()); + assertEquals(cohortMember.getEndDate(), updatedCohortMember.getEndDate()); + } + + private CohortM createMinimalCohort() { + CohortM cohort = new CohortM(); + cohort.setName("sample cohort"); + cohort.setUuid("4eece76a-111e-40cb-be1c-e717801876f6"); + cohort.setDescription("sample cohort"); + return cohort; + } + + private Patient createMinimalPatient(Location location, PatientIdentifierType patientIdentifierType) { + Patient patient = new Patient(); + patient.setUuid(UUID.randomUUID().toString()); + + PersonName pName = new PersonName(); + pName.setGivenName("John"); + pName.setMiddleName("A."); + pName.setFamilyName("Doe"); + + patient.addName(pName); + patient.setGender("M"); + + PatientIdentifier patientIdentifier = new PatientIdentifier(); + patientIdentifier.setIdentifier("123456"); + patientIdentifier.setLocation(location); + patientIdentifier.setIdentifierType(patientIdentifierType); + + patient.addIdentifier(patientIdentifier); + + return patient; + } + + private Location createMinimalLocation() { + Location location = new Location(); + location.setName("Sample Location"); + location.setDescription("Sample Location Description"); + return location; + } + + private PatientIdentifierType createMinimalPatientIdentifierType() { + PatientIdentifierType identifierType = new PatientIdentifierType(); + identifierType.setName("Sample Identifier Type"); + identifierType.setDescription("Sample Identifier Type Description"); + return identifierType; + } + + private CohortMember createMinimalCohortMember() { + CohortMember cohortMember = new CohortMember(); + cohortMember.setCohort(cohort); + cohortMember.setPatient(patient); + cohortMember.setStartDate(Date.from(Instant.now())); + return cohortMember; + } + + @Override + public void shouldGetDefaultByUuid() throws Exception { + + } + + @Override + public void shouldGetFullByUuid() throws Exception { + + } + + @Override + public void shouldGetRefByUuid() throws Exception { + + } + + @Override + public void shouldGetAll() throws Exception { + + } +} diff --git a/omod/src/test/java/org/openmrs/module/cohort/web/resource/CohortMemberResourceTest.java b/omod/src/test/java/org/openmrs/module/cohort/web/resource/CohortMemberResourceTest.java index 8180a5b..e224b14 100644 --- a/omod/src/test/java/org/openmrs/module/cohort/web/resource/CohortMemberResourceTest.java +++ b/omod/src/test/java/org/openmrs/module/cohort/web/resource/CohortMemberResourceTest.java @@ -13,16 +13,24 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.sql.Date; +import java.time.Instant; import java.util.Collections; +import java.util.UUID; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.openmrs.Patient; import org.openmrs.api.context.Context; import org.openmrs.module.cohort.CohortM; import org.openmrs.module.cohort.CohortMember; @@ -34,6 +42,7 @@ import org.openmrs.module.webservices.rest.web.response.ResourceDoesNotSupportOperationException; import org.powermock.modules.junit4.PowerMockRunner; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Description; @RunWith(PowerMockRunner.class) public class CohortMemberResourceTest extends BaseCohortResourceTest { @@ -109,6 +118,119 @@ public void shouldCreateNewResource() { assertThat(newlyCreatedObject.getUuid(), is(COHORT_MEMBER_UUID)); } + @Test + @Description("Should raise exception for duplicate member with no end date if the existing member has no endDate") + public void shouldRaiseRuntimeExceptionWhenSavingExistingMemberWithoutEndDate() { + // Mocking objects + CohortM cohort = mock(CohortM.class); + Patient currentMemberPatient = mock(Patient.class); + Patient newMemberPatient = mock(Patient.class); + CohortMember duplicateCohortMember = new CohortMember(); + String patientUUID = UUID.randomUUID().toString(); + + // Setting up existing member + cohortMember.setCohort(cohort); + cohortMember.setPatient(currentMemberPatient); + cohortMember.setEndDate(null); + + // Setting up new member + duplicateCohortMember.setUuid(COHORT_MEMBER_UUID); + duplicateCohortMember.setCohort(cohort); + duplicateCohortMember.setPatient(newMemberPatient); + duplicateCohortMember.setEndDate(null); + + // Mock behavior + when(cohort.getVoided()).thenReturn(false); + when(cohort.getCohortMembers()).thenReturn(Collections.singleton(cohortMember)); + when(currentMemberPatient.getUuid()).thenReturn(patientUUID); + when(newMemberPatient.getUuid()).thenReturn(patientUUID); + + // Preconditions check + assertEquals(newMemberPatient.getUuid(), currentMemberPatient.getUuid()); + assertEquals(duplicateCohortMember.getUuid(), cohortMember.getUuid()); + assertNull(cohortMember.getEndDate()); + assertNull(duplicateCohortMember.getEndDate()); + + // Validate expected Exception + try { + getResource().save(duplicateCohortMember); + fail(); + } + catch (RuntimeException e) { + // test passed + } + } + + @Test + public void shouldUpdateExistingMemberWhenEndDateIsNonNull() { + // Mocking objects + CohortM cohort = mock(CohortM.class); + Patient currentMemberPatient = mock(Patient.class); + Patient updatedMemberPatient = mock(Patient.class); + CohortMember updatedCohortMember = new CohortMember(); + String patientUUID = UUID.randomUUID().toString(); + + // Setting up existing member + cohortMember.setCohort(cohort); + cohortMember.setPatient(currentMemberPatient); + cohortMember.setEndDate(null); + + // Setting up new member + updatedCohortMember.setUuid(COHORT_MEMBER_UUID); + updatedCohortMember.setCohort(cohort); + updatedCohortMember.setPatient(updatedMemberPatient); + updatedCohortMember.setEndDate(Date.from(Instant.now())); + + // Mock behavior + when(cohort.getVoided()).thenReturn(false); + when(cohort.getCohortMembers()).thenReturn(Collections.singleton(cohortMember)); + when(currentMemberPatient.getUuid()).thenReturn(patientUUID); + when(updatedMemberPatient.getUuid()).thenReturn(patientUUID); + when(cohortMemberService.saveCohortMember(updatedCohortMember)).thenReturn(updatedCohortMember); + + // Verify behaviour + CohortMember newlyCreatedObject = getResource().save(updatedCohortMember); + assertNotNull(newlyCreatedObject); + assertNotNull(newlyCreatedObject.getEndDate()); + assertEquals(updatedCohortMember.getUuid(), newlyCreatedObject.getUuid()); + assertEquals(updatedCohortMember.getEndDate(), newlyCreatedObject.getEndDate()); + } + + @Test + public void shouldReinstateMemberWithNullEndDate() { + // Mocking objects + CohortM cohort = mock(CohortM.class); + Patient currentMemberPatient = mock(Patient.class); + Patient updatedMemberPatient = mock(Patient.class); + CohortMember updatedCohortMember = new CohortMember(); + String patientUUID = UUID.randomUUID().toString(); + + // Setting up existing member + cohortMember.setCohort(cohort); + cohortMember.setPatient(currentMemberPatient); + cohortMember.setEndDate(Date.from(Instant.now())); + + // Setting up new member + updatedCohortMember.setUuid(COHORT_MEMBER_UUID); + updatedCohortMember.setCohort(cohort); + updatedCohortMember.setPatient(updatedMemberPatient); + updatedCohortMember.setEndDate(null); + + // Mock behavior + when(cohort.getVoided()).thenReturn(false); + when(cohort.getCohortMembers()).thenReturn(Collections.singleton(cohortMember)); + when(currentMemberPatient.getUuid()).thenReturn(patientUUID); + when(updatedMemberPatient.getUuid()).thenReturn(patientUUID); + when(cohortMemberService.saveCohortMember(updatedCohortMember)).thenReturn(updatedCohortMember); + + // Verify behaviour + CohortMember newlyCreatedObject = getResource().save(updatedCohortMember); + assertNotNull(newlyCreatedObject); + assertNull(newlyCreatedObject.getEndDate()); + assertEquals(updatedCohortMember.getUuid(), newlyCreatedObject.getUuid()); + assertEquals(updatedCohortMember.getEndDate(), newlyCreatedObject.getEndDate()); + } + @Test(expected = ResourceDoesNotSupportOperationException.class) public void shouldGetAllResources() { when(cohortMemberService.findAllCohortMembers()).thenReturn(Collections.singletonList(getObject()));