/** * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.web.controller.patient; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.commons.beanutils.BeanUtils; import org.junit.Assert; import org.junit.Test; import org.openmrs.Patient; import org.openmrs.PatientIdentifier; import org.openmrs.PersonAddress; import org.openmrs.PersonName; import org.openmrs.api.context.Context; import org.openmrs.test.Verifies; import org.openmrs.util.LocationUtility; import org.openmrs.web.WebConstants; import org.openmrs.web.test.BaseWebContextSensitiveTest; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.validation.BindException; import org.springframework.validation.BindingResult; import org.springframework.web.bind.support.SessionStatus; import org.springframework.web.bind.support.SimpleSessionStatus; import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.WebRequest; /** * Consists of unit tests for the ShortPatientFormController * * @see ShortPatientFormController */ public class ShortPatientFormControllerTest extends BaseWebContextSensitiveTest { /** * @see {@link ShortPatientFormController#saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)} */ @Test @Verifies(value = "should pass if all the form data is valid", method = "saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)") public void saveShortPatient_shouldPassIfAllTheFormDataIsValid() throws Exception { Patient p = Context.getPatientService().getPatient(2); ShortPatientModel patientModel = new ShortPatientModel(p); WebRequest mockWebRequest = new ServletWebRequest(new MockHttpServletRequest()); SimpleSessionStatus status = new SimpleSessionStatus(); BindException errors = new BindException(patientModel, "patientModel"); mockWebRequest.setAttribute("personNameCache", BeanUtils.cloneBean(p.getPersonName()), WebRequest.SCOPE_SESSION); mockWebRequest.setAttribute("personAddressCache", p.getPersonAddress().clone(), WebRequest.SCOPE_SESSION); mockWebRequest.setAttribute("patientModel", patientModel, WebRequest.SCOPE_SESSION); ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, (PersonName) mockWebRequest.getAttribute( "personNameCache", WebRequest.SCOPE_SESSION), (PersonAddress) mockWebRequest.getAttribute("personAddressCache", WebRequest.SCOPE_SESSION), (ShortPatientModel) mockWebRequest.getAttribute("patientModel", WebRequest.SCOPE_SESSION), errors); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("Patient.saved", mockWebRequest.getAttribute(WebConstants.OPENMRS_MSG_ATTR, WebRequest.SCOPE_SESSION)); Assert.assertEquals("redirect:/patientDashboard.form?patientId=" + p.getPatientId(), redirectUrl); } /** * @see {@link ShortPatientFormController#saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)} */ @Test @Verifies(value = "should create a new patient", method = "saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)") public void saveShortPatient_shouldCreateANewPatient() throws Exception { int patientCount = Context.getPatientService().getAllPatients().size(); Patient p = new Patient(); ShortPatientModel patientModel = new ShortPatientModel(p); patientModel.setPersonName(new PersonName("new", "", "patient")); List<PatientIdentifier> identifiers = new ArrayList<PatientIdentifier>(); PatientIdentifier id = new PatientIdentifier("myID", Context.getPatientService().getPatientIdentifierType(2), LocationUtility.getDefaultLocation()); id.setPreferred(true); identifiers.add(id); patientModel.setIdentifiers(identifiers); patientModel.getPatient().setBirthdate(new Date()); patientModel.getPatient().setGender("M"); WebRequest mockWebRequest = new ServletWebRequest(new MockHttpServletRequest()); BindException errors = new BindException(patientModel, "patientModel"); ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, new PersonName(), new PersonAddress(), patientModel, errors); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertNotNull(p.getId()); Assert.assertNotNull(p.getPersonName()); Assert.assertNotNull(p.getPersonName().getId());// the name was create // and added Assert.assertEquals(patientCount + 1, Context.getPatientService().getAllPatients().size()); Assert.assertEquals("Patient.saved", mockWebRequest.getAttribute(WebConstants.OPENMRS_MSG_ATTR, WebRequest.SCOPE_SESSION)); Assert.assertEquals("redirect:/patientDashboard.form?patientId=" + p.getPatientId(), redirectUrl); } /** * @see {@link ShortPatientFormController#saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)} */ @Test @Verifies(value = "should send the user back to the form in case of validation errors", method = "saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)") public void saveShortPatient_shouldSendTheUserBackToTheFormInCaseOfValidationErrors() throws Exception { Patient p = new Patient(); ShortPatientModel patientModel = new ShortPatientModel(p); patientModel.setPersonName(new PersonName("new", "", "patient")); List<PatientIdentifier> identifiers = new ArrayList<PatientIdentifier>(); patientModel.setIdentifiers(identifiers); WebRequest mockWebRequest = new ServletWebRequest(new MockHttpServletRequest()); BindException errors = new BindException(patientModel, "patientModel"); ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String formUrl = controller.saveShortPatient(mockWebRequest, new PersonName(), new PersonAddress(), patientModel, errors); Assert.assertTrue("Should report validation errors", errors.hasErrors()); Assert.assertEquals("/admin/patients/shortPatientForm", formUrl); } /** * @see {@link ShortPatientFormController#saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)} */ @Test @Verifies(value = "should void a name and replace it with a new one if it is changed to a unique value", method = "saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)") public void saveShortPatient_shouldVoidANameAndReplaceItWithANewOneIfItIsChangedToAUniqueValue() throws Exception { Patient p = Context.getPatientService().getPatient(2); ShortPatientModel patientModel = new ShortPatientModel(p); PersonName oldPersonName = p.getPersonName(); String oldGivenName = oldPersonName.getGivenName(); int nameCount = p.getNames().size(); BindException errors = new BindException(patientModel, "patientModel"); ServletWebRequest mockWebRequest = new ServletWebRequest(new MockHttpServletRequest()); PersonName personNameCache = (PersonName) BeanUtils.cloneBean(p.getPersonName()); // edit the name and submit patientModel.getPersonName().setGivenName("Changed"); ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, personNameCache, (PersonAddress) p .getPersonAddress().clone(), patientModel, errors); Assert.assertEquals(nameCount + 1, p.getNames().size()); Assert.assertTrue("The old name should be voided", oldPersonName.isVoided()); Assert.assertNotNull("The void reason should be set", oldPersonName.getVoidReason()); Assert.assertTrue("The old name should have remained un changed", oldGivenName.equalsIgnoreCase(oldPersonName .getGivenName())); Assert.assertEquals("Changed", p.getGivenName());// the changes should // have taken effect Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("redirect:/patientDashboard.form?patientId=" + p.getPatientId(), redirectUrl); } /** * @see {@link ShortPatientFormController#saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)} */ @Test @Verifies(value = "should add a new name if the person had no names", method = "saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)") public void saveShortPatient_shouldAddANewNameIfThePersonHadNoNames() throws Exception { Patient p = Context.getPatientService().getPatient(2); p.getPersonName().setVoided(true); Context.getPatientService().savePatient(p); Assert.assertNull(p.getPersonName());// make sure all names are voided // add a name that will used as a duplicate for testing purposes PersonName newName = new PersonName("new", null, "name"); newName.setDateCreated(new Date()); ShortPatientModel patientModel = new ShortPatientModel(p); patientModel.setPersonName(newName); BindException errors = new BindException(patientModel, "patientModel"); ServletWebRequest mockWebRequest = new ServletWebRequest(new MockHttpServletRequest()); ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, new PersonName(), (PersonAddress) p .getPersonAddress().clone(), patientModel, errors); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("redirect:/patientDashboard.form?patientId=" + p.getPatientId(), redirectUrl); Assert.assertNotNull(newName.getId());// name should have been added to // DB } /** * @see {@link ShortPatientFormController#saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)} */ @Test @Verifies(value = "should void an address and replace it with a new one if it is changed to a unique value", method = "saveShortPatient(WebRequest,ShortPatientModel,BindingResult,SessionStatus)") public void saveShortPatient_shouldVoidAnAddressAndReplaceItWithANewOneIfItIsChangedToAUniqueValue() throws Exception { Patient p = Context.getPatientService().getPatient(2); ShortPatientModel patientModel = new ShortPatientModel(p); PersonAddress oldPersonAddress = patientModel.getPersonAddress(); String oldAddress1 = oldPersonAddress.getAddress1(); int addressCount = p.getAddresses().size(); BindException errors = new BindException(patientModel, "patientModel"); ServletWebRequest mockWebRequest = new ServletWebRequest(new MockHttpServletRequest()); PersonAddress personAddressCache = (PersonAddress) p.getPersonAddress().clone(); // edit address1 value and submit patientModel.getPersonAddress().setAddress1("Kampala"); ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, (PersonName) BeanUtils.cloneBean(p.getPersonName()), personAddressCache, patientModel, errors); Assert.assertEquals(addressCount + 1, p.getAddresses().size()); Assert.assertTrue("The old address should be voided", oldPersonAddress.isVoided()); Assert.assertNotNull("The void reason should be set", oldPersonAddress.getVoidReason()); Assert.assertTrue("The old address should have remained the same", oldAddress1.equalsIgnoreCase(oldPersonAddress .getAddress1())); Assert.assertEquals("Kampala", p.getPersonAddress().getAddress1());// the // changes // should // have // taken // effect Assert.assertEquals("redirect:/patientDashboard.form?patientId=" + p.getPatientId(), redirectUrl); } /** * @see {@link ShortPatientFormController#saveShortPatient(WebRequest,PersonName,ShortPatientModel,BindingResult,SessionStatus)} */ @Test @Verifies(value = "should add a new address if the person had none", method = "saveShortPatient(WebRequest,PersonName,ShortPatientModel,BindingResult,SessionStatus)") public void saveShortPatient_shouldAddANewAddressIfThePersonHadNone() throws Exception { Patient p = Context.getPatientService().getPatient(2); p.getPersonAddress().setVoided(true); Context.getPatientService().savePatient(p); Assert.assertNull(p.getPersonAddress());// make sure all addresses are // voided // add a name that will used as a duplicate for testing purposes PersonAddress newAddress = new PersonAddress(); newAddress.setAddress1("Kampala"); newAddress.setDateCreated(new Date()); ShortPatientModel patientModel = new ShortPatientModel(p); patientModel.setPersonAddress(newAddress); BindException errors = new BindException(patientModel, "patientModel"); ServletWebRequest mockWebRequest = new ServletWebRequest(new MockHttpServletRequest()); ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, (PersonName) BeanUtils.cloneBean(p.getPersonName()), new PersonAddress(), patientModel, errors); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("redirect:/patientDashboard.form?patientId=" + p.getPatientId(), redirectUrl); Assert.assertNotNull(newAddress.getId());// name should have been added // to DB } /** * @see {@link ShortPatientFormController#saveShortPatient(WebRequest,PersonName,PersonAddress,ShortPatientModel,BindingResult,SessionStatus)} */ @Test @Verifies(value = "should ignore a new address that was added and voided at same time", method = "saveShortPatient(WebRequest,PersonName,PersonAddress,ShortPatientModel,BindingResult,SessionStatus)") public void saveShortPatient_shouldIgnoreANewAddressThatWasAddedAndVoidedAtSameTime() throws Exception { Patient p = Context.getPatientService().getPatient(2); p.getPersonAddress().setVoided(true); Context.getPatientService().savePatient(p); // make sure all addresses are voided so that whatever is entered a new // address Assert.assertNull(p.getPersonAddress()); // add the new address PersonAddress newAddress = new PersonAddress(); newAddress.setAddress1("Kampala"); newAddress.setDateCreated(new Date()); newAddress.setVoided(true); ShortPatientModel patientModel = new ShortPatientModel(p); patientModel.setPersonAddress(newAddress); BindException errors = new BindException(patientModel, "patientModel"); ServletWebRequest mockWebRequest = new ServletWebRequest(new MockHttpServletRequest()); ShortPatientFormController controller = (ShortPatientFormController) applicationContext .getBean("shortPatientFormController"); String redirectUrl = controller.saveShortPatient(mockWebRequest, (PersonName) BeanUtils.cloneBean(p.getPersonName()), new PersonAddress(), patientModel, errors); Assert.assertTrue("Should pass with no validation errors", !errors.hasErrors()); Assert.assertEquals("redirect:/patientDashboard.form?patientId=" + p.getPatientId(), redirectUrl); Assert.assertNull(p.getPersonAddress());// address should have been // ignored } }