/** * 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.api; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Assert; import org.junit.Test; import org.openmrs.Concept; import org.openmrs.Encounter; import org.openmrs.Location; import org.openmrs.Obs; import org.openmrs.Order; import org.openmrs.Patient; import org.openmrs.Person; import org.openmrs.api.context.Context; import org.openmrs.api.impl.ObsServiceImpl; import org.openmrs.obs.ComplexData; import org.openmrs.obs.ComplexObsHandler; import org.openmrs.obs.handler.ImageHandler; import org.openmrs.obs.handler.TextHandler; import org.openmrs.test.BaseContextSensitiveTest; import org.openmrs.test.Verifies; import org.openmrs.util.OpenmrsConstants; import org.openmrs.util.OpenmrsUtil; import org.openmrs.util.OpenmrsConstants.PERSON_TYPE; /** * TODO clean up and add tests for all methods in ObsService */ public class ObsServiceTest extends BaseContextSensitiveTest { protected static final String INITIAL_OBS_XML = "org/openmrs/api/include/ObsServiceTest-initial.xml"; protected static final String COMPLEX_OBS_XML = "org/openmrs/api/include/ObsServiceTest-complex.xml"; /** * This test tests multi-level heirarchy obsGroup cascades for create, delete, update, void, and * unvoid * * @throws Exception */ @Test public void shouldSaveUpdateDeleteVoidObsGroupCascades() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService os = Context.getObsService(); ConceptService cs = Context.getConceptService(); //create an obs Obs o = new Obs(); o.setConcept(cs.getConcept(3)); o.setDateCreated(new Date()); o.setCreator(Context.getAuthenticatedUser()); o.setLocation(new Location(1)); o.setObsDatetime(new Date()); o.setPerson(new Patient(2)); o.setValueText("original obs value text"); //create a second obs Obs o2 = new Obs(); o2.setConcept(cs.getConcept(3)); o2.setDateCreated(new Date()); o2.setCreator(Context.getAuthenticatedUser()); o2.setLocation(new Location(1)); o2.setObsDatetime(new Date()); o2.setValueText("second obs value text"); o2.setPerson(new Patient(2)); //create a parent obs Obs oParent = new Obs(); oParent.setConcept(cs.getConcept(23)); //in the concept set table as a set oParent.setDateCreated(new Date()); oParent.setCreator(Context.getAuthenticatedUser()); oParent.setLocation(new Location(1)); oParent.setObsDatetime(new Date()); oParent.setPerson(new Patient(2)); //add o and o2 to the parent obs oParent.addGroupMember(o2); oParent.addGroupMember(o); //create a grandparent obs Obs oGP = new Obs(); oGP.setConcept(cs.getConcept(3)); oGP.setDateCreated(new Date()); oGP.setCreator(Context.getAuthenticatedUser()); oGP.setLocation(new Location(1)); oGP.setObsDatetime(new Date()); oGP.setPerson(new Patient(2)); oGP.setValueText("grandparent obs value text"); oGP.addGroupMember(oParent); //create a leaf observation Obs o3 = new Obs(); o3.setConcept(cs.getConcept(3)); o3.setDateCreated(new Date()); o3.setCreator(Context.getAuthenticatedUser()); o3.setLocation(new Location(1)); o3.setObsDatetime(new Date()); o3.setValueText("leaf obs value text"); o3.setPerson(new Patient(2)); //and add it to the grandparent oGP.addGroupMember(o3); //create a great-grandparent Obs oGGP = new Obs(); oGGP.setConcept(cs.getConcept(3)); oGGP.setDateCreated(new Date()); oGGP.setCreator(Context.getAuthenticatedUser()); oGGP.setLocation(new Location(1)); oGGP.setObsDatetime(new Date()); oGGP.setValueText("great grandparent value text"); oGGP.setPerson(new Patient(2)); oGGP.addGroupMember(oGP); //create a great-great grandparent Obs oGGGP = new Obs(); oGGGP.setConcept(cs.getConcept(3)); oGGGP.setDateCreated(new Date()); oGGGP.setCreator(Context.getAuthenticatedUser()); oGGGP.setLocation(new Location(1)); oGGGP.setObsDatetime(new Date()); oGGGP.setValueText("great great grandparent value text"); oGGGP.setPerson(new Patient(2)); oGGGP.addGroupMember(oGGP); //Create the great great grandparent os.saveObs(oGGGP, null); int oGGGPId = oGGGP.getObsId(); //now navigate the tree and make sure that all tree members have obs_ids //indicating that they've been saved (unsaved_value in the hibernate mapping set to null so // the notNull assertion is sufficient): Obs testGGGP = os.getObs(oGGGPId); assertTrue(testGGGP.isObsGrouping()); Set<Obs> GGGPmembers = testGGGP.getGroupMembers(); assertEquals(GGGPmembers.size(), 1); for (Obs testGGP : GGGPmembers) { assertTrue(testGGP.isObsGrouping()); assertEquals(testGGP.getGroupMembers().size(), 1); assertNotNull(testGGP.getObsId()); for (Obs testGP : testGGP.getGroupMembers()) { assertTrue(testGP.isObsGrouping()); assertEquals(testGP.getGroupMembers().size(), 2); assertNotNull(testGP.getObsId()); for (Obs parent : testGP.getGroupMembers()) { if (parent.isObsGrouping()) { assertEquals(parent.getGroupMembers().size(), 2); assertNotNull(parent.getObsId()); for (Obs child : parent.getGroupMembers()) { assertNotNull(child.getObsId()); //make an edit to a value so that we can save the great great grandfather //and see if the changes have been reflected: child.setValueText("testingUpdate"); } } } } } Obs oGGGPThatWasUpdated = os.saveObs(oGGGP, "Updating obs group parent"); //now, re-walk the tree to verify that the bottom-level leaf obs have the new text value: int childOneId = 0; int childTwoId = 0; assertTrue(oGGGPThatWasUpdated.isObsGrouping()); Set<Obs> GGGPmembers2 = oGGGPThatWasUpdated.getGroupMembers(); assertEquals(GGGPmembers2.size(), 1); for (Obs testGGP : GGGPmembers2) { assertTrue(testGGP.isObsGrouping()); assertEquals(testGGP.getGroupMembers().size(), 1); assertNotNull(testGGP.getObsId()); for (Obs testGP : testGGP.getGroupMembers()) { assertTrue(testGP.isObsGrouping()); assertEquals(testGP.getGroupMembers().size(), 2); assertNotNull(testGP.getObsId()); for (Obs parent : testGP.getGroupMembers()) { if (parent.isObsGrouping()) { assertEquals(parent.getGroupMembers().size(), 2); assertNotNull(parent.getObsId()); int i = 0; for (Obs child : parent.getGroupMembers()) { assertEquals("testingUpdate", child.getValueText()); //set childIds, so that we can test voids/unvoids/delete if (i == 0) childOneId = child.getObsId(); else childTwoId = child.getObsId(); i++; } } } } } //check voiding: //first, just create an Obs, and void it, and verify: Obs oVoidTest = new Obs(); oVoidTest.setConcept(cs.getConcept(1)); oVoidTest.setDateCreated(new Date()); oVoidTest.setCreator(Context.getAuthenticatedUser()); oVoidTest.setLocation(new Location(1)); oVoidTest.setObsDatetime(new Date()); oVoidTest.setPerson(new Patient(2)); oVoidTest.setValueText("value text of soon-to-be-voided obs"); Obs obsThatWasVoided = os.saveObs(oVoidTest, null); os.voidObs(obsThatWasVoided, "testing void method"); assertTrue(obsThatWasVoided.getVoided()); //unvoid: obsThatWasVoided.setVoided(false); assertFalse(obsThatWasVoided.isVoided()); //Now test voiding cascade: // i.e. by voiding the grandparent, we void the n-th generation leaf obs os.voidObs(oGGGPThatWasUpdated, "testing void cascade"); assertTrue(oGGGPThatWasUpdated.isVoided()); Obs childLeafObs = os.getObs(childOneId); assertTrue(childLeafObs.isVoided()); //now test the un-void: os.unvoidObs(oGGGPThatWasUpdated); assertFalse(oGGGPThatWasUpdated.isVoided()); assertFalse(childLeafObs.isVoided()); //test this again using just the os.updateObs method on the great great grandparent: os.voidObs(oGGGPThatWasUpdated, "testing void cascade"); childLeafObs = os.getObs(childOneId); assertTrue(childLeafObs.isVoided()); os.unvoidObs(oGGGPThatWasUpdated); childLeafObs = os.getObs(childOneId); assertFalse(childLeafObs.isVoided()); //now, test the feature that unvoid doesn't happen unless child obs has the same dateVoided as // the Obj argument that gets passed into unvoid: os.voidObs(oGGGPThatWasUpdated, "testing void cascade"); childLeafObs = os.getObs(childOneId); assertTrue(childLeafObs.isVoided()); childLeafObs.setDateVoided(new Date(childLeafObs.getDateVoided().getTime() - 5000)); //os.saveObs(childLeafObs, "saving child leaf obs"); os.unvoidObs(oGGGPThatWasUpdated); // commenting this out because junit4 doesn't seem to care //commitTransaction(false); childLeafObs = os.getObs(childOneId); Obs childLeafObsTwo = os.getObs(childTwoId); //childLeafObs had its date voided date changed, so it should not get unvoided by the unvoid cascade //childLeafObsTwo should be unvoided, as the dateVoided date is still the same as the great-great //grandparent Obs assertFalse(childLeafObsTwo.getVoided()); assertTrue(childLeafObs.getVoided()); //finally, check the delete cascade: os.purgeObs(oGGGPThatWasUpdated); assertNull(os.getObs(oGGGPThatWasUpdated.getObsId())); assertNull(os.getObs(childOneId)); assertNull(os.getObs(childTwoId)); } /** * This method gets observations and only fetches obs that are for patients * * @see ObsService#getObservations(List, List, List, List, List, List, List, Integer, Integer, * Date, Date, boolean) */ @Test @Verifies(value = "should compare dates using lte and gte", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldCompareDatesUsingLteAndGte() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService os = Context.getObsService(); DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); // Test 1, No bounderies Date sd = df.parse("2006-02-01"); Date ed = df.parse("2006-02-20"); List<Obs> obs = os.getObservations(null, null, null, null, null, null, null, null, null, sd, ed, false); assertEquals(8, obs.size()); // Test 2, From boundary sd = df.parse("2006-02-13"); ed = df.parse("2006-02-20"); obs = os.getObservations(null, null, null, null, null, null, null, null, null, sd, ed, false); assertEquals(4, obs.size()); // Test 3, To boundary sd = df.parse("2006-02-01"); ed = df.parse("2006-02-15"); obs = os.getObservations(null, null, null, null, null, null, null, null, null, sd, ed, false); assertEquals(7, obs.size()); // Test 4, Both Boundaries sd = df.parse("2006-02-11"); ed = new SimpleDateFormat("yyyy-MM-dd-hh-mm").parse("2006-02-11-11-59"); obs = os.getObservations(null, null, null, null, null, null, null, null, null, sd, ed, false); assertEquals(1, obs.size()); // Test 5, Outside before sd = df.parse("2006-02-01"); ed = df.parse("2006-02-08"); obs = os.getObservations(null, null, null, null, null, null, null, null, null, sd, ed, false); assertEquals(0, obs.size()); // Test 6, Outside After sd = df.parse("2006-02-17"); ed = df.parse("2006-02-20"); obs = os.getObservations(null, null, null, null, null, null, null, null, null, sd, ed, false); assertEquals(0, obs.size()); } /** * Uses the OpenmrsUtil.lastSecondOfDay(Date) method to get all observations for a given day * * @throws Exception */ @Test public void shouldGetObservationsOnDay() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService os = Context.getObsService(); DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); Date sd = df.parse("2006-02-13"); Date ed = df.parse("2006-02-13"); List<Obs> obs = os.getObservations(null, null, null, null, null, null, null, null, null, sd, OpenmrsUtil .lastSecondOfDay(ed), false); assertEquals(1, obs.size()); } /** * @see ObsService#getComplexObs(Integer,String) */ @Test @Verifies(value = "should fill in complex data object for complex obs", method = "getComplexObs(Integer,String)") public void getComplexObs_shouldFillInComplexDataObjectForComplexObs() throws Exception { executeDataSet(COMPLEX_OBS_XML); ObsService os = Context.getObsService(); Obs complexObs = os.getComplexObs(44, OpenmrsConstants.RAW_VIEW); Assert.assertNotNull(complexObs); Assert.assertTrue(complexObs.isComplex()); Assert.assertNotNull(complexObs.getValueComplex()); Assert.assertNotNull(complexObs.getComplexData()); } /** * @see ObsService#getComplexObs(Integer,String) */ @Test @Verifies(value = "should not fail with null view", method = "getComplexObs(Integer,String)") public void getComplexObs_shouldNotFailWithNullView() throws Exception { executeDataSet(COMPLEX_OBS_XML); ObsService os = Context.getObsService(); os.getComplexObs(44, null); } /** * @see ObsService#getComplexObs(Integer,String) */ @Test @Verifies(value = "should return normal obs for non complex obs", method = "getComplexObs(Integer,String)") public void getComplexObs_shouldReturnNormalObsForNonComplexObs() throws Exception { executeDataSet(COMPLEX_OBS_XML); ObsService os = Context.getObsService(); Obs normalObs = os.getComplexObs(7, OpenmrsConstants.RAW_VIEW); Assert.assertFalse(normalObs.isComplex()); } /** * @see ObsService#getHandler(String) */ @Test @Verifies(value = "should have default image and text handlers registered by spring", method = "getHandler(String)") public void getHandler_shouldHaveDefaultImageAndTextHandlersRegisteredBySpring() throws Exception { ObsService os = Context.getObsService(); ComplexObsHandler imgHandler = os.getHandler("ImageHandler"); Assert.assertNotNull(imgHandler); ComplexObsHandler textHandler = os.getHandler("TextHandler"); Assert.assertNotNull(textHandler); } /** * @see ObsService#getHandler(String) */ @Test @Verifies(value = "should get handler with matching key", method = "getHandler(String)") public void getHandler_shouldGetHandlerWithMatchingKey() throws Exception { ObsService os = Context.getObsService(); ComplexObsHandler handler = os.getHandler("ImageHandler"); Assert.assertNotNull(handler); Assert.assertTrue(handler instanceof ImageHandler); } /** * @see ObsService#getHandlers() */ @Test @Verifies(value = "should never return null", method = "getHandlers()") public void getHandlers_shouldNeverReturnNull() throws Exception { Assert.assertNotNull(Context.getObsService().getHandlers()); // test our current implementation without it being initialized by spring Assert.assertNotNull(new ObsServiceImpl().getHandlers()); } /** * @see ObsService#registerHandler(String,ComplexObsHandler) */ @Test @Verifies(value = "should register handler with the given key", method = "registerHandler(String,ComplexObsHandler)") public void registerHandler_shouldRegisterHandlerWithTheGivenKey() throws Exception { ObsService os = Context.getObsService(); os.registerHandler("DummyHandler", new ImageHandler()); ComplexObsHandler dummyHandler = os.getHandler("DummyHandler"); Assert.assertNotNull(dummyHandler); } /** * @see ObsService#registerHandler(String,String) */ @Test @Verifies(value = "should load handler and register key", method = "registerHandler(String,String)") public void registerHandler_shouldLoadHandlerAndRegisterKey() throws Exception { ObsService os = Context.getObsService(); // name it something other than what we used in the previous test os.registerHandler("DummyHandler2", "org.openmrs.obs.handler.ImageHandler"); ComplexObsHandler dummyHandler = os.getHandler("DummyHandler2"); Assert.assertNotNull(dummyHandler); } /** * @see ObsService#removeHandler(String) */ @Test @Verifies(value = "should not fail with invalid key", method = "removeHandler(String)") public void removeHandler_shouldNotFailWithInvalidKey() throws Exception { Context.getObsService().removeHandler("SomeRandomHandler"); } /** * @see ObsService#removeHandler(String) */ @Test @Verifies(value = "should remove handler with matching key", method = "removeHandler(String)") public void removeHandler_shouldRemoveHandlerWithMatchingKey() throws Exception { ObsService os = Context.getObsService(); // add the handler and make sure its there os.registerHandler("DummyHandler3", "org.openmrs.obs.handler.ImageHandler"); ComplexObsHandler dummyHandler = os.getHandler("DummyHandler3"); Assert.assertNotNull(dummyHandler); // now remove the handler and make sure its gone os.removeHandler("DummyHandler3"); ComplexObsHandler dummyHandlerAgain = os.getHandler("DummyHandler3"); Assert.assertNull(dummyHandlerAgain); } /** * @see ObsService#saveObs(Obs,String) */ @Test @Verifies(value = "should create new file from complex data for new obs", method = "saveObs(Obs,String)") public void saveObs_shouldCreateNewFileFromComplexDataForNewObs() throws Exception { executeDataSet(COMPLEX_OBS_XML); ObsService os = Context.getObsService(); ConceptService cs = Context.getConceptService(); AdministrationService as = Context.getAdministrationService(); // make sure the file isn't there to begin with File complexObsDir = OpenmrsUtil.getDirectoryInApplicationDataDirectory(as .getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_COMPLEX_OBS_DIR)); File createdFile = new File(complexObsDir, "nameOfFile.txt"); if (createdFile.exists()) createdFile.delete(); // the complex data to put onto an obs that will be saved InputStream inputStream = new ByteArrayInputStream("This is a string to save to a file".getBytes()); ComplexData complexData = new ComplexData("nameOfFile.txt", inputStream); // must fetch the concept instead of just new Concept(8473) because the attributes on concept are checked // this is a concept mapped to the text handler Concept questionConcept = cs.getConcept(8474); Obs obsToSave = new Obs(new Person(1), questionConcept, new Date(), new Location(1)); obsToSave.setComplexData(complexData); try { os.saveObs(obsToSave, null); // make sure the file appears now after the save Assert.assertTrue(createdFile.exists()); } finally { // we always have to delete this inside the same unit test because it is outside the // database and hence can't be "rolled back" like everything else createdFile.delete(); } } /** * @see ObsService#saveObs(Obs,String) */ @Test @Verifies(value = "should not overwrite file when updating a complex obs", method = "saveObs(Obs,String)") public void saveObs_shouldNotOverwriteFileWhenUpdatingAComplexObs() throws Exception { executeDataSet(COMPLEX_OBS_XML); ObsService os = Context.getObsService(); ConceptService cs = Context.getConceptService(); AdministrationService as = Context.getAdministrationService(); // Create the file that was supposedly put there by another obs File complexObsDir = OpenmrsUtil.getDirectoryInApplicationDataDirectory(as .getGlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_COMPLEX_OBS_DIR)); File previouslyCreatedFile = new File(complexObsDir, "nameOfFile.txt"); InputStream inputStream = new ByteArrayInputStream("a string to save to a file".getBytes()); OpenmrsUtil.copyFile(inputStream, new FileOutputStream(previouslyCreatedFile)); inputStream.close(); // the file we'll be creating...defining it here so we can delete it in a finally block File newComplexFile = null; try { long oldFileSize = previouslyCreatedFile.length(); // now add a new file to this obs and update it // ...then make sure the original file is still there // the complex data to put onto an obs that will be saved InputStream inputStream2 = new ByteArrayInputStream("diff string to save to a file with the same name" .getBytes()); ComplexData complexData = new ComplexData("nameOfFile.txt", inputStream2); // must fetch the concept instead of just new Concept(8473) because the attributes on concept are checked // this is a concept mapped to the text handler Concept questionConcept = cs.getConcept(8474); Obs obsToSave = new Obs(new Person(1), questionConcept, new Date(), new Location(1)); obsToSave.setComplexData(complexData); os.saveObs(obsToSave, null); // make sure the old file still appears now after the save Assert.assertEquals(oldFileSize, previouslyCreatedFile.length()); String valueComplex = obsToSave.getValueComplex(); String filename = valueComplex.substring(valueComplex.indexOf("|") + 1).trim(); newComplexFile = new File(complexObsDir, filename); // make sure the file appears now after the save Assert.assertTrue(newComplexFile.length() > oldFileSize); } finally { // clean up the files we created newComplexFile.delete(); try { previouslyCreatedFile.delete(); } catch (Throwable t) { // pass } } } /** * @see ObsService#setHandlers(Map<QString;QComplexObsHandler;>)} */ @Test @Verifies(value = "should add new handlers with new keys", method = "setHandlers(Map<QString;QComplexObsHandler;>)") public void setHandlers_shouldAddNewHandlersWithNewKeys() throws Exception { ObsService os = Context.getObsService(); Map<String, ComplexObsHandler> handlers = new HashMap<String, ComplexObsHandler>(); handlers.put("DummyHandler4", new ImageHandler()); handlers.put("DummyHandler5", new TextHandler()); // set the handlers and make sure they're there os.setHandlers(handlers); ComplexObsHandler dummyHandler4 = os.getHandler("DummyHandler4"); Assert.assertNotNull(dummyHandler4); ComplexObsHandler dummyHandler5 = os.getHandler("DummyHandler5"); Assert.assertNotNull(dummyHandler5); } /** * @see ObsService#setHandlers(Map<QString;QComplexObsHandler;>)} */ @Test @Verifies(value = "should override handlers with same key", method = "setHandlers(Map<QString;QComplexObsHandler;>)") public void setHandlers_shouldOverrideHandlersWithSameKey() throws Exception { ObsService os = Context.getObsService(); Map<String, ComplexObsHandler> handlers = new HashMap<String, ComplexObsHandler>(); handlers.put("DummyHandlerToOverride", new ImageHandler()); // set the handlers and make sure they're there os.setHandlers(handlers); ComplexObsHandler dummyHandlerToOverride = os.getHandler("DummyHandlerToOverride"); Assert.assertTrue(dummyHandlerToOverride instanceof ImageHandler); // now override that key and make sure the new class is stored Map<String, ComplexObsHandler> handlersAgain = new HashMap<String, ComplexObsHandler>(); handlersAgain.put("DummyHandlerToOverride", new TextHandler()); os.setHandlers(handlersAgain); ComplexObsHandler dummyHandlerToOverrideAgain = os.getHandler("DummyHandlerToOverride"); Assert.assertTrue(dummyHandlerToOverrideAgain instanceof TextHandler); } /** * @see ObsService#saveObs(Obs,String) */ @Test @Verifies(value = "should void the given obs in the database", method = "saveObs(Obs,String)") public void saveObs_shouldVoidTheGivenObsInTheDatabase() throws Exception { Obs obs = Context.getObsService().getObs(7); obs.setValueNumeric(1.0); Context.getObsService().saveObs(obs, "just testing"); // fetch the obs from the database again obs = Context.getObsService().getObs(7); Assert.assertTrue(obs.isVoided()); } /** * @see ObsService#getObs(Integer) */ @Test @Verifies(value = "should get obs matching given obsId", method = "getObs(Integer)") public void getObs_shouldGetObsMatchingGivenObsId() throws Exception { ObsService obsService = Context.getObsService(); Obs obs = obsService.getObs(7); Assert.assertEquals(new Concept(5089), obs.getConcept()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should get all obs assigned to given encounters", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldGetAllObsAssignedToGivenEncounters() throws Exception { ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(null, Collections.singletonList(new Encounter(4)), null, null, null, null, null, null, null, null, null, false); Assert.assertEquals(6, obss.size()); } /** * @see ObsService#getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should get count of all obs assigned to given encounters", method = "getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean)") public void getObservationCount_shouldGetCountOfObsAssignedToGivenEncounters() throws Exception { ObsService obsService = Context.getObsService(); Integer count = obsService.getObservationCount(null, Collections.singletonList(new Encounter(4)), null, null, null, null, null, null, null, false); Assert.assertEquals(6, count.intValue()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should get all obs with answer concept in given answers parameter", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldGetAllObsWithAnswerConceptInGivenAnswersParameter() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(null, null, null, Collections.singletonList(new Concept(7)), null, null, null, null, null, null, null, false); Assert.assertEquals(1, obss.size()); Assert.assertEquals(11, obss.get(0).getObsId().intValue()); } /** * @see ObsService#getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should get count of obs with answer concept in given answers parameter", method = "getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean)") public void getObservationCount_shouldGetCountOfObsWithAnswerConceptInGivenAnswersParameter() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); Integer count = obsService.getObservationCount(null, null, null, Collections.singletonList(new Concept(7)), null, null, null, null, null, false); Assert.assertEquals(1, count.intValue()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should get all obs with question concept in given questions parameter", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldGetAllObsWithQuestionConceptInGivenQuestionsParameter() throws Exception { ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(null, null, Collections.singletonList(new Concept(5497)), null, null, null, null, null, null, null, null, false); Assert.assertEquals(2, obss.size()); } /** * @see ObsService#getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should get count of obs with question concept in given questions parameter", method = "getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean)") public void getObservationCount_shouldGetCountOfObsWithQuestionConceptInGivenQuestionsParameter() throws Exception { ObsService obsService = Context.getObsService(); Integer count = obsService.getObservationCount(null, null, Collections.singletonList(new Concept(5497)), null, null, null, null, null, null, false); Assert.assertEquals(2, count.intValue()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should include voided obs if includeVoidedObs is true", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldIncludeVoidedObsIfIncludeVoidedObsIsTrue() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(Collections.singletonList(new Person(9)), null, null, null, null, null, null, null, null, null, null, true); Assert.assertEquals(2, obss.size()); Assert.assertEquals(10, obss.get(0).getObsId().intValue()); Assert.assertEquals(9, obss.get(1).getObsId().intValue()); } /** * @see ObsService#getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should include voided obs in count if includeVoidedObs is true", method = "getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean)") public void getObservationCount_shouldIncludeVoidedObsInTheCountIfIncludeVoidedObsIsTrue() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); Integer obss = obsService.getObservationCount(Collections.singletonList(new Person(9)), null, null, null, null, null, null, null, null, true); Assert.assertEquals(2, obss.intValue()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should limit number of obs returned to mostReturnN parameter", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldLimitNumberOfObsReturnedToMostReturnNParameter() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); List<Obs> count = obsService.getObservations(Collections.singletonList(new Person(8)), null, null, null, null, null, null, 1, null, null, null, false); Assert.assertEquals(1, count.size()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should not include voided obs", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldNotIncludeVoidedObs() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(Collections.singletonList(new Person(9)), null, null, null, null, null, null, null, null, null, null, false); Assert.assertEquals(1, obss.size()); Assert.assertEquals(9, obss.get(0).getObsId().intValue()); } /** * @see ObsService#getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should not include voided obs in count", method = "getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean)") public void getObservationCount_shouldNotIncludeVoidedObsInCount() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); Integer obss = obsService.getObservationCount(Collections.singletonList(new Person(9)), null, null, null, null, null, null, null, null, false); Assert.assertEquals(1, obss.intValue()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should return obs whose groupId is given obsGroupId", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldReturnObsWhoseGroupIdIsGivenObsGroupId() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(null, null, null, null, null, null, null, null, 2 /*obsGroupId*/, null, null, false); Assert.assertEquals(1, obss.size()); } /** * @see ObsService#getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should return count of obs whose groupId is given obsGroupId", method = "getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean)") public void getObservationCount_shouldReturnCountOfObsWhoseGroupIdIsGivenObsGroupId() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); Integer count = obsService.getObservationCount(null, null, null, null, null, null, 2 /*obsGroupId*/, null, null, false); Assert.assertEquals(1, count.intValue()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should return obs whose person is a patient only", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldReturnObsWhosePersonIsAPatientOnly() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(null, null, null, null, Collections.singletonList(PERSON_TYPE.PATIENT), null, null, null, null, null, null, false); Assert.assertEquals(13, obss.size()); } /** * @see ObsService#getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should return count of obs whose person is a patient only", method = "getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean)") public void getObservationCount_shouldReturnCountOfObsWhosePersonIsAPatientOnly() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); Integer count = obsService.getObservationCount(null, null, null, null, Collections.singletonList(PERSON_TYPE.PATIENT), null, null, null, null, false); Assert.assertEquals(13, count.intValue()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should return all obs whose person is a person only", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldReturnAllObsWhosePersonIsAPersonOnly() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(null, null, null, null, Collections.singletonList(PERSON_TYPE.PERSON), null, null, null, null, null, null, false); Assert.assertEquals(15, obss.size()); } /** * @see ObsService#getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should return count of all obs whose person is a person only", method = "getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean)") public void getObservationCount_shouldReturnCountOfAllObsWhosePersonIsAPersonOnly() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); Integer count = obsService.getObservationCount(null, null, null, null, Collections.singletonList(PERSON_TYPE.PERSON), null, null, null, null, false); Assert.assertEquals(15, count.intValue()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should return obs whose person is a user only", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldReturnObsWhosePersonIsAUserOnly() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(null, null, null, null, Collections.singletonList(PERSON_TYPE.USER), null, null, null, null, null, null, false); Assert.assertEquals(1, obss.size()); } /** * @see ObsService#getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should return count of obs whose person is a user only", method = "getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean)") public void getObservationCount_shouldReturnCountOfObsWhosePersonIsAUserOnly() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); Integer count = obsService.getObservationCount(null, null, null, null, Collections.singletonList(PERSON_TYPE.USER), null, null, null, null, false); Assert.assertEquals(1, count.intValue()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should return obs with location in given locations parameter", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldReturnObsWithLocationInGivenLocationsParameter() throws Exception { ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(null, null, null, null, null, Collections.singletonList(new Location(1)), null, null, null, null, null, false); Assert.assertEquals(8, obss.size()); } /** * @see ObsService#getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should return count of obs with location in given locations parameter", method = "getObservationCount(List,List,List,List,List,List,Integer,Date,Date,boolean)") public void getObservationCount_shouldReturnCountOfObsWithLocationInGivenLocationsParameter() throws Exception { ObsService obsService = Context.getObsService(); Integer count = obsService.getObservationCount(null, null, null, null, null, Collections.singletonList(new Location(1)), null, null, null, false); Assert.assertEquals(8, count.intValue()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should sort returned obs by conceptId if sort is concept", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldSortReturnedObsByConceptIdIfSortIsConcept() throws Exception { ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(Collections.singletonList(new Person(7)), null, null, null, null, null, Collections.singletonList("concept"), null, null, null, null, false); // check the order of a few of the obs returned Assert.assertEquals(11, obss.get(0).getObsId().intValue()); Assert.assertEquals(9, obss.get(1).getObsId().intValue()); Assert.assertEquals(16, obss.get(2).getObsId().intValue()); } /** * @see ObsService#getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean) */ @Test @Verifies(value = "should sort returned obs by obsDatetime if sort is empty", method = "getObservations(List,List,List,List,List,List,List,Integer,Integer,Date,Date,boolean)") public void getObservations_shouldSortReturnedObsByObsDatetimeIfSortIsEmpty() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations(Collections.singletonList(new Person(8)), null, null, null, null, null, new ArrayList<String>(), null, null, null, null, false); Assert.assertEquals(8, obss.get(0).getObsId().intValue()); Assert.assertEquals(7, obss.get(1).getObsId().intValue()); } /** * @see ObsService#getObservations(String) */ @Test @Verifies(value = "should get obs matching patient identifier in searchString", method = "getObservations(String)") public void getObservations_shouldGetObsMatchingPatientIdentifierInSearchString() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations("12345K"); Assert.assertEquals(2, obss.size()); Assert.assertEquals(4, obss.get(0).getObsId().intValue()); Assert.assertEquals(3, obss.get(1).getObsId().intValue()); } /** * @see ObsService#getObservations(String) */ @Test @Verifies(value = "should get obs matching encounterId in searchString", method = "getObservations(String)") public void getObservations_shouldGetObsMatchingEncounterIdInSearchString() throws Exception { ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations("5"); Assert.assertEquals(1, obss.size()); Assert.assertEquals(16, obss.get(0).getObsId().intValue()); } /** * @see ObsService#getObservations(String) */ @Test @Verifies(value = "should get obs matching obsId 1n searchString", method = "getObservations(String)") public void getObservations_shouldGetObsMatchingObsIdInSearchString() throws Exception { ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservations("15"); Assert.assertEquals(1, obss.size()); Assert.assertEquals(15, obss.get(0).getObsId().intValue()); } /** * @see ObsService#getObservationsByPerson(Person) */ @Test @Verifies(value = "should get all observations assigned to given person", method = "getObservationsByPerson(Person)") public void getObservationsByPerson_shouldGetAllObservationsAssignedToGivenPerson() throws Exception { ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservationsByPerson(new Person(7)); Assert.assertEquals(9, obss.size()); Assert.assertEquals(16, obss.get(0).getObsId().intValue()); Assert.assertEquals(7, obss.get(8).getObsId().intValue()); } /** * @see ObsService#getObservationsByPersonAndConcept(Person,Concept) */ @Test @Verifies(value = "should get observations matching person and question", method = "getObservationsByPersonAndConcept(Person,Concept)") public void getObservationsByPersonAndConcept_shouldGetObservationsMatchingPersonAndQuestion() throws Exception { ObsService obsService = Context.getObsService(); List<Obs> obss = obsService.getObservationsByPersonAndConcept(new Person(7), new Concept(5089)); Assert.assertEquals(3, obss.size()); Assert.assertEquals(16, obss.get(0).getObsId().intValue()); Assert.assertEquals(10, obss.get(1).getObsId().intValue()); Assert.assertEquals(7, obss.get(2).getObsId().intValue()); } /** * @see ObsService#getObservationsByPersonAndConcept(Person,Concept) */ @Test @Verifies(value = "should not fail with null person parameter", method = "getObservationsByPersonAndConcept(Person,Concept)") public void getObservationsByPersonAndConcept_shouldNotFailWithNullPersonParameter() throws Exception { ObsService obsService = Context.getObsService(); obsService.getObservationsByPersonAndConcept(null, new Concept(7)); } /** * @see ObsService#purgeObs(Obs) */ @Test @Verifies(value = "should delete the given obs from the database", method = "purgeObs(Obs)") public void purgeObs_shouldDeleteTheGivenObsFromTheDatabase() throws Exception { ObsService obsService = Context.getObsService(); Obs obs = obsService.getObs(7); obsService.purgeObs(obs); Assert.assertNull(obsService.getObs(7)); } /** * @see ObsService#purgeObs(Obs,boolean) */ @Test(expected = APIException.class) @Verifies(value = "should throw APIException if given true cascade", method = "purgeObs(Obs,boolean)") public void purgeObs_shouldThrowAPIExceptionIfGivenTrueCascade() throws Exception { Context.getObsService().purgeObs(new Obs(1), true); } /** * @see ObsService#saveObs(Obs,String) */ @Test @Verifies(value = "should allow changing of every property on obs", method = "saveObs(Obs,String)") public void saveObs_shouldAllowChangingOfEveryPropertyOnObs() throws Exception { ObsService obsService = Context.getObsService(); Order order = null; Concept concept = new Concept(3); Patient patient = new Patient(2); Encounter encounter = new Encounter(3); Date datetime = new Date(); Location location = new Location(1); Integer valueGroupId = new Integer(7); Date valueDatetime = new Date(); Concept valueCoded = new Concept(3); Double valueNumeric = 2.0; String valueModifier = "cc"; String valueText = "value text2"; String comment = "commenting2"; Obs oToUpdate = new Obs(); oToUpdate.setOrder(order); oToUpdate.setConcept(concept); oToUpdate.setPerson(patient); oToUpdate.setEncounter(encounter); oToUpdate.setObsDatetime(datetime); oToUpdate.setLocation(location); oToUpdate.setValueGroupId(valueGroupId); oToUpdate.setValueDatetime(valueDatetime); oToUpdate.setValueCoded(valueCoded); oToUpdate.setValueNumeric(valueNumeric); oToUpdate.setValueModifier(valueModifier); oToUpdate.setValueText(valueText); oToUpdate.setComment(comment); // do an update in the database for the same Obs Obs o1ToUpdateSaved = obsService.saveObs(oToUpdate, "Updating o1 with all new values"); Obs obsSaved = obsService.getObs(o1ToUpdateSaved.getObsId()); assertEquals(order, obsSaved.getOrder()); assertEquals(patient, obsSaved.getPerson()); assertEquals(comment, obsSaved.getComment()); assertEquals(concept, obsSaved.getConcept()); assertEquals(encounter, obsSaved.getEncounter()); assertEquals(datetime, obsSaved.getObsDatetime()); assertEquals(location, obsSaved.getLocation()); assertEquals(valueGroupId, obsSaved.getValueGroupId()); assertEquals(valueDatetime, obsSaved.getValueDatetime()); assertEquals(valueCoded, obsSaved.getValueCoded()); assertEquals(valueNumeric, obsSaved.getValueNumeric()); assertEquals(valueModifier, obsSaved.getValueModifier()); assertEquals(valueText, obsSaved.getValueText()); } /** * @see ObsService#saveObs(Obs,String) */ @Test @Verifies(value = "should create very basic obs and add new obsId", method = "saveObs(Obs,String)") public void saveObs_shouldCreateVeryBasicObsAndAddNewObsId() throws Exception { Obs o = new Obs(); o.setConcept(new Concept(3)); o.setPerson(new Patient(2)); o.setEncounter(new Encounter(3)); o.setObsDatetime(new Date()); o.setLocation(new Location(1)); Obs oSaved = Context.getObsService().saveObs(o, null); // make sure the returned Obs and the passed in obs // now both have primary key obsIds assertTrue(oSaved.getObsId().equals(o.getObsId())); } /** * @see ObsService#saveObs(Obs,String) */ @Test @Verifies(value = "should return a different object when updating an obs", method = "saveObs(Obs,String)") public void saveObs_shouldReturnADifferentObjectWhenUpdatingAnObs() throws Exception { ObsService obsService = Context.getObsService(); Obs obs = obsService.getObs(7); // change something on the obs and save it again obs.setComment("A new comment"); Obs obsSaved = obsService.saveObs(obs, "Testing that a new obs is returned"); assertFalse(obsSaved.getObsId().equals(obs.getObsId())); } /** * @see ObsService#unvoidObs(Obs) */ @Test @Verifies(value = "should cascade unvoid to child grouped obs", method = "unvoidObs(Obs)") public void unvoidObs_shouldCascadeUnvoidToChildGroupedObs() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); // a obs with child groups Obs parentObs = obsService.getObs(2); obsService.voidObs(parentObs, "testing void cascade to child obs groups"); Assert.assertTrue(obsService.getObs(9).isVoided()); Assert.assertTrue(obsService.getObs(10).isVoided()); } /** * @see ObsService#unvoidObs(Obs) */ @Test @Verifies(value = "should unset voided bit on given obs", method = "unvoidObs(Obs)") public void unvoidObs_shouldUnsetVoidedBitOnGivenObs() throws Exception { ObsService obsService = Context.getObsService(); Obs obs = obsService.getObs(7); obsService.unvoidObs(obs); assertFalse(obs.isVoided()); } /** * @see ObsService#voidObs(Obs,String) */ @Test(expected = IllegalArgumentException.class) @Verifies(value = "should fail if reason parameter is empty", method = "voidObs(Obs,String)") public void voidObs_shouldFailIfReasonParameterIsEmpty() throws Exception { ObsService obsService = Context.getObsService(); Obs obs = obsService.getObs(7); obsService.voidObs(obs, ""); } /** * @see ObsService#voidObs(Obs,String) */ @Test @Verifies(value = "should set voided bit on given obs", method = "voidObs(Obs,String)") public void voidObs_shouldSetVoidedBitOnGivenObs() throws Exception { ObsService obsService = Context.getObsService(); Obs obs = obsService.getObs(7); obsService.voidObs(obs, "testing void function"); assertTrue(obs.isVoided()); } /** * @see ObsService#saveObs(Obs,String) */ @Test @Verifies(value = "should set creator and dateCreated on new obs", method = "saveObs(Obs,String)") public void saveObs_shouldSetCreatorAndDateCreatedOnNewObs() throws Exception { Obs o = new Obs(); o.setConcept(new Concept(3)); o.setPerson(new Patient(2)); o.setEncounter(new Encounter(3)); o.setObsDatetime(new Date()); o.setLocation(new Location(1)); Context.getObsService().saveObs(o, null); assertNotNull(o.getDateCreated()); assertNotNull(o.getCreator()); } /** * @see ObsService#saveObs(Obs,String) */ @Test @Verifies(value = "should cascade save to child obs groups", method = "saveObs(Obs,String)") public void saveObs_shouldCascadeSaveToChildObsGroups() throws Exception { ObsService obsService = Context.getObsService(); Obs parentObs = new Obs(); parentObs.setConcept(new Concept(3)); parentObs.setObsDatetime(new Date()); parentObs.setPerson(new Patient(2)); parentObs.setLocation(new Location(1)); Obs groupMember = new Obs(); groupMember.setConcept(new Concept(3)); groupMember.setValueNumeric(1.0); groupMember.setObsDatetime(new Date()); groupMember.setPerson(new Patient(2)); groupMember.setLocation(new Location(1)); parentObs.addGroupMember(groupMember); obsService.saveObs(parentObs, null); // make sure the child obs was saved Assert.assertNotNull(groupMember.getObsId()); } /** * @see ObsService#saveObs(Obs,String) */ @Test @Verifies(value = "should cascade update to new child obs groups", method = "saveObs(Obs,String)") public void saveObs_shouldCascadeUpdateToNewChildObsGroups() throws Exception { executeDataSet(INITIAL_OBS_XML); ObsService obsService = Context.getObsService(); // a obs with child groups Obs parentObs = obsService.getObs(2); Obs groupMember = new Obs(); groupMember.setConcept(new Concept(3)); groupMember.setObsDatetime(new Date()); groupMember.setPerson(new Patient(2)); groupMember.setLocation(new Location(2)); parentObs.addGroupMember(groupMember); assertNotNull(groupMember.getObsGroup()); obsService.saveObs(parentObs, "Updating obs group"); // make sure the api filled in all of the necessary ids again assertNotNull(groupMember.getObsId()); // make sure the api didn't change the obsId of the first group member Assert.assertEquals(9, parentObs.getGroupMembers().toArray(new Obs[] {})[0].getObsId().intValue()); } }