← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 12963: Implement unit tests on ProgramStageInstance service methods

 

------------------------------------------------------------
revno: 12963
committer: Tran Chau <tran.hispvietnam@xxxxxxxxx>
branch nick: dhis2
timestamp: Tue 2013-11-19 10:45:56 +0700
message:
   Implement unit tests on ProgramStageInstance service methods
added:
  dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageInstanceServiceTest.java
  dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageInstanceStoreTest.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceService.java
  dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramStageInstanceService.java
  dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramStageInstanceStore.java
  dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/patient/PatientReminderServiceTest.java
  dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramInstanceServiceTest.java
  dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageDataElementServiceTest.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceService.java	2013-11-04 06:00:38 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/program/ProgramStageInstanceService.java	2013-11-19 03:45:56 +0000
@@ -238,7 +238,7 @@
     int getOverDueEventCount( ProgramStage programStage, Collection<Integer> orgunitIds, Date startDate, Date endDate );
 
     /**
-     * Get the number of program instances completed
+     * Get the number of program instances completed, includes all program stage instances were completed
      * 
      * @param program Program
      * @param orgunitIds The ids of orgunits where the events happened
@@ -330,8 +330,10 @@
      * @param program Single event without registration
      * @param executionDate Report date of the event
      * @param organisationUnit Orgunit where the event happens
+     * 
+     * @return ProgramStageInstance ProgramStageInstance object
      */
-    void createProgramStageInstance( Patient patient, Program program, Date executionDate,
+    ProgramStageInstance createProgramStageInstance( Patient patient, Program program, Date executionDate,
         OrganisationUnit organisationUnit );
 
 }

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramStageInstanceService.java'
--- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramStageInstanceService.java	2013-11-04 06:00:38 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/DefaultProgramStageInstanceService.java	2013-11-19 03:45:56 +0000
@@ -528,7 +528,7 @@
     {
         Collection<MessageConversation> messageConversations = new HashSet<MessageConversation>();
 
-        Collection<PatientReminder> reminders = programStageInstance.getProgramStage().getPatientReminders();
+        Collection<PatientReminder> reminders = programStageInstance.getProgramStage().getPatientReminders(); 
         for ( PatientReminder rm : reminders )
         {
             if ( rm != null
@@ -616,7 +616,7 @@
      * registration.
      */
     @Override
-    public void createProgramStageInstance( Patient patient, Program program, Date executionDate,
+    public ProgramStageInstance createProgramStageInstance( Patient patient, Program program, Date executionDate,
         OrganisationUnit organisationUnit )
     {
         ProgramStage programStage = null;
@@ -670,6 +670,8 @@
         programStageInstance.setOrganisationUnit( organisationUnit );
 
         addProgramStageInstance( programStageInstance );
+        
+        return programStageInstance;
     }
 
     // -------------------------------------------------------------------------

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramStageInstanceStore.java'
--- dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramStageInstanceStore.java	2013-11-04 06:00:38 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/main/java/org/hisp/dhis/program/hibernate/HibernateProgramStageInstanceStore.java	2013-11-19 03:45:56 +0000
@@ -127,7 +127,6 @@
         return getQuery( hql ).setEntity( "patient", patient ).setBoolean( "completed", completed ).list();
     }
 
-
     @Override
     public void removeEmptyEvents( ProgramStage programStage, OrganisationUnit organisationUnit )
     {
@@ -484,7 +483,8 @@
         {
             criteria.add( Restrictions.not( Restrictions.in( "programInstance", programInstances ) ) );
         }
-
+System.out.println("\n\n\n ............. \n programInstances : " + programInstances.iterator().next().getProgram().getName() );
+System.out.println("\n\n\n ............. \n stageInstances : " + programInstances.iterator().next().getProgramStageInstances() );
         Number rs = (Number) criteria.setProjection( Projections.rowCount() ).uniqueResult();
         return rs != null ? rs.intValue() : 0;
     }
@@ -507,7 +507,7 @@
     private String sendMessageToPatientSql()
     {
         return "select psi.programstageinstanceid, p.phonenumber, prm.templatemessage, p.name, org.name as orgunitName "
-            + ",pg.name as programName, ps.name as programStageName, psi.duedate,(DATE(now()) - DATE(psi.duedate) ) as days_since_due_date "
+            + ",pg.name as programName, ps.name as programStageName, psi.duedate,(now() - psi.duedate ) as days_since_due_date "
             + "from patient p INNER JOIN programinstance pi "
             + "     ON p.patientid=pi.patientid "
             + " INNER JOIN programstageinstance psi  "
@@ -520,13 +520,13 @@
             + "     ON org.organisationunitid = p.organisationunitid "
             + " INNER JOIN patientreminder prm  "
             + "     ON prm.programstageid = ps.programstageid "
-            + "WHERE pi.status="
+            + " WHERE pi.status="
             + ProgramInstance.STATUS_ACTIVE
             + "     and p.phonenumber is not NULL and p.phonenumber != '' "
             + "     and prm.templatemessage is not NULL and prm.templatemessage != '' "
             + "     and pg.type=1 and prm.daysallowedsendmessage is not null  "
             + "     and psi.executiondate is null "
-            + "     and (  DATE(now()) - DATE(psi.duedate) ) = prm.daysallowedsendmessage "
+            + "     and ( now() - psi.duedate ) = prm.daysallowedsendmessage "
             + "     and prm.whentosend is null and prm.sendto = " + PatientReminder.SEND_TO_PATIENT;
     }
 
@@ -534,7 +534,7 @@
     {
         return "SELECT psi.programstageinstanceid, uif.phonenumber, prm.templatemessage, p.name, org.name as orgunitName, "
             + "pg.name as programName, ps.name as programStageName, psi.duedate, "
-            + "         (DATE(now()) - DATE(psi.duedate) ) as days_since_due_date "
+            + "         (now() - psi.duedate ) as days_since_due_date "
             + " FROM patient p INNER JOIN programinstance pi "
             + "          ON p.patientid=pi.patientid "
             + "           INNER JOIN programstageinstance psi  "
@@ -557,7 +557,7 @@
             + "               and prm.templatemessage is not NULL and prm.templatemessage != '' "
             + "               and pg.type=1 and prm.daysallowedsendmessage is not null "
             + "               and psi.executiondate is null "
-            + "               and (  DATE(now()) - DATE(psi.duedate) ) = prm.daysallowedsendmessage "
+            + "               and (  now() - psi.duedate ) = prm.daysallowedsendmessage "
             + "               and prm.whentosend is null and prm.sendto = " + PatientReminder.SEND_TO_HEALTH_WORKER;
     }
 
@@ -565,7 +565,7 @@
     {
         return "select psi.programstageinstanceid, ou.phonenumber, prm.templatemessage, p.name, org.name as orgunitName, "
             + "pg.name as programName, ps.name as programStageName, psi.duedate,"
-            + "(DATE(now()) - DATE(psi.duedate) ) as days_since_due_date "
+            + "(now() - psi.duedate) as days_since_due_date "
             + "            from patient p INNER JOIN programinstance pi "
             + "               ON p.patientid=pi.patientid "
             + "           INNER JOIN programstageinstance psi "
@@ -586,7 +586,7 @@
             + "               and prm.templatemessage is not NULL and prm.templatemessage != '' "
             + "               and pg.type=1 and prm.daysallowedsendmessage is not null "
             + "               and psi.executiondate is null "
-            + "               and (  DATE(now()) - DATE(psi.duedate) ) = prm.daysallowedsendmessage "
+            + "               and (now() - psi.duedate ) = prm.daysallowedsendmessage "
             + "               and prm.whentosend is null and prm.sendto = "
             + +PatientReminder.SEND_TO_ORGUGNIT_REGISTERED;
     }
@@ -595,7 +595,7 @@
     {
         return "select psi.programstageinstanceid, uif.phonenumber,prm.templatemessage, p.name, org.name as orgunitName ,"
             + " pg.name as programName, ps.name as programStageName, psi.duedate, "
-            + "(DATE(now()) - DATE(psi.duedate) ) as days_since_due_date "
+            + "(now() - psi.duedate ) as days_since_due_date "
             + "  from patient p INNER JOIN programinstance pi "
             + "       ON p.patientid=pi.patientid "
             + "   INNER JOIN programstageinstance psi "
@@ -618,7 +618,7 @@
             + "       and prm.templatemessage is not NULL and prm.templatemessage != '' "
             + "       and pg.type=1 and prm.daysallowedsendmessage is not null "
             + "       and psi.executiondate is null "
-            + "       and (  DATE(now()) - DATE(psi.duedate) ) = prm.daysallowedsendmessage "
+            + "       and ( now() - psi.duedate ) = prm.daysallowedsendmessage "
             + "       and prm.whentosend is null and prm.sendto = "
             + PatientReminder.SEND_TO_ALL_USERS_IN_ORGUGNIT_REGISTERED;
     }
@@ -627,7 +627,7 @@
     {
         return "select psi.programstageinstanceid, uif.phonenumber,prm.templatemessage, p.name, org.name as orgunitName ,"
             + " pg.name as programName, ps.name as programStageName, psi.duedate, "
-            + "(DATE(now()) - DATE(psi.duedate) ) as days_since_due_date "
+            + "(now() - psi.duedate) as days_since_due_date "
             + "  from patient p INNER JOIN programinstance pi "
             + "       ON p.patientid=pi.patientid "
             + "   INNER JOIN programstageinstance psi "
@@ -650,7 +650,7 @@
             + "       and prm.templatemessage is not NULL and prm.templatemessage != '' "
             + "       and pg.type=1 and prm.daysallowedsendmessage is not null "
             + "       and psi.executiondate is not null "
-            + "       and (  DATE(now()) - DATE(psi.duedate) ) = prm.daysallowedsendmessage "
+            + "       and (  now() - psi.duedate ) = prm.daysallowedsendmessage "
             + "       and prm.whentosend is null " + "       and prm.sendto = " + PatientReminder.SEND_TO_USER_GROUP;
     }
 }
\ No newline at end of file

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/patient/PatientReminderServiceTest.java'
--- dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/patient/PatientReminderServiceTest.java	2013-11-13 04:19:10 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/patient/PatientReminderServiceTest.java	2013-11-19 03:45:56 +0000
@@ -106,6 +106,7 @@
 
         OrganisationUnit organisationUnit = createOrganisationUnit( 'A' );
         organisationUnitService.addOrganisationUnit( organisationUnit );
+        
         Set<OrganisationUnit> orgUnits = new HashSet<OrganisationUnit>();
         orgUnits.add( organisationUnit );
 

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramInstanceServiceTest.java'
--- dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramInstanceServiceTest.java	2013-11-14 09:51:24 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramInstanceServiceTest.java	2013-11-19 03:45:56 +0000
@@ -39,6 +39,7 @@
 import java.util.Set;
 
 import org.hisp.dhis.DhisSpringTest;
+import org.hisp.dhis.message.MessageConversation;
 import org.hisp.dhis.mock.MockI18nFormat;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
@@ -76,9 +77,9 @@
 
     @Autowired
     private ProgramStageService programStageService;
-    
+
     @Autowired
-    private SmsConfigurationManager smsConfigurationManager; 
+    private SmsConfigurationManager smsConfigurationManager;
 
     private Date incidenDate;
 
@@ -107,10 +108,10 @@
     private Collection<Integer> orgunitIds;
 
     private MockI18nFormat mockFormat;
-    
+
     @Autowired
     JdbcTemplate jdbcTemplate;
-    
+
     @Override
     public void setUpTest()
     {
@@ -127,24 +128,23 @@
         orgunitIds.add( idB );
 
         programA = createProgram( 'A', new HashSet<ProgramStage>(), organisationUnitA );
-        
+
         PatientReminder patientReminderA = new PatientReminder( "A", 0, "Test program message template "
             + PatientReminder.TEMPLATE_MESSSAGE_PATIENT_NAME, PatientReminder.ENROLLEMENT_DATE_TO_COMPARE,
             PatientReminder.SEND_TO_PATIENT, null, PatientReminder.MESSAGE_TYPE_BOTH );
-        
+
         PatientReminder patientReminderB = new PatientReminder( "B", 0, "Test program message template "
             + PatientReminder.TEMPLATE_MESSSAGE_PATIENT_NAME, PatientReminder.ENROLLEMENT_DATE_TO_COMPARE,
             PatientReminder.SEND_TO_PATIENT, PatientReminder.SEND_WHEN_TO_C0MPLETED_EVENT,
             PatientReminder.MESSAGE_TYPE_BOTH );
-        
+
         Set<PatientReminder> patientReminders = new HashSet<PatientReminder>();
         patientReminders.add( patientReminderA );
         patientReminders.add( patientReminderB );
         programA.setPatientReminders( patientReminders );
-        
-        programService.addProgram( programA ); 
-        
-        
+
+        programService.addProgram( programA );
+
         ProgramStage stageA = new ProgramStage( "StageA", programA );
         programStageService.saveProgramStage( stageA );
 
@@ -566,13 +566,13 @@
         this.createSMSConfiguration();
         SmsConfiguration smsConfiguration = new SmsConfiguration();
         smsConfiguration.setEnabled( true );
-        
+
         programInstanceService.addProgramInstance( programInstanceB );
 
-        Collection<OutboundSms> outboundSmsList = programInstanceService.sendMessages( programInstanceA,
+        Collection<MessageConversation> messages = programInstanceService.sendMessageConversations( programInstanceA,
             PatientReminder.SEND_WHEN_TO_C0MPLETED_EVENT, mockFormat );
-        assertEquals( 1, outboundSmsList.size() );
-        assertEquals( "Test program message template NameA", outboundSmsList.iterator().next().getMessage() );
+        assertEquals( 1, messages.size() );
+        assertEquals( "Test program message template NameA", messages.iterator().next().getMessages().get( 0 ).getText() );
     }
 
     @Test
@@ -619,20 +619,21 @@
         assertEquals( ProgramInstance.STATUS_CANCELLED, programInstanceService.getProgramInstance( idA ).getStatus() );
         assertEquals( ProgramInstance.STATUS_CANCELLED, programInstanceService.getProgramInstance( idD ).getStatus() );
     }
-    
-    private void createSMSConfiguration() {
+
+    private void createSMSConfiguration()
+    {
         BulkSmsGatewayConfig bulkGatewayConfig = new BulkSmsGatewayConfig();
         bulkGatewayConfig.setName( "bulksms" );
         bulkGatewayConfig.setPassword( "bulk" );
         bulkGatewayConfig.setUsername( "bulk" );
         bulkGatewayConfig.setRegion( "uk" );
         bulkGatewayConfig.setDefault( true );
-        
+
         SmsConfiguration smsConfig = new SmsConfiguration();
         smsConfig.setPollingInterval( 3000 );
         smsConfig.getGateways().add( bulkGatewayConfig );
         smsConfig.setEnabled( true );
         smsConfigurationManager.updateSmsConfiguration( smsConfig );
-        
+
     }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageDataElementServiceTest.java'
--- dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageDataElementServiceTest.java	2013-11-15 04:35:36 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageDataElementServiceTest.java	2013-11-19 03:45:56 +0000
@@ -118,16 +118,12 @@
         dataElementService.addDataElement( dataElementB );
 
         stageDataElementA = new ProgramStageDataElement( stageA, dataElementA, false, 1 );
-        programStageDataElementService.addProgramStageDataElement( stageDataElementA );
 
         stageDataElementB = new ProgramStageDataElement( stageA, dataElementB, false, 2 );
-        programStageDataElementService.addProgramStageDataElement( stageDataElementB );
 
         stageDataElementC = new ProgramStageDataElement( stageB, dataElementA, false, 1 );
-        programStageDataElementService.addProgramStageDataElement( stageDataElementA );
 
         stageDataElementD = new ProgramStageDataElement( stageB, dataElementB, false, 2 );
-        programStageDataElementService.addProgramStageDataElement( stageDataElementB );
     }
 
     @Test

=== added file 'dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageInstanceServiceTest.java'
--- dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageInstanceServiceTest.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageInstanceServiceTest.java	2013-11-19 03:45:56 +0000
@@ -0,0 +1,621 @@
+/*
+ * Copyright (c) 2004-2013, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.hisp.dhis.program;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.hisp.dhis.DhisSpringTest;
+import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.dataelement.DataElementService;
+import org.hisp.dhis.dataentryform.DataEntryFormService;
+import org.hisp.dhis.message.MessageConversation;
+import org.hisp.dhis.mock.MockI18nFormat;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitService;
+import org.hisp.dhis.patient.Patient;
+import org.hisp.dhis.patient.PatientReminder;
+import org.hisp.dhis.patient.PatientService;
+import org.hisp.dhis.period.PeriodType;
+import org.hisp.dhis.sms.config.BulkSmsGatewayConfig;
+import org.hisp.dhis.sms.config.SmsConfiguration;
+import org.hisp.dhis.sms.config.SmsConfigurationManager;
+import org.hisp.dhis.sms.outbound.OutboundSms;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author Chau Thu Tran
+ * 
+ * @version $ ProgramStageInstanceServiceTest.java Nov 14, 2013 4:22:27 PM $
+ */
+public class ProgramStageInstanceServiceTest
+    extends DhisSpringTest
+{
+    @Autowired
+    private ProgramStageInstanceService programStageInstanceService;
+
+    @Autowired
+    private ProgramStageDataElementStore programStageDataElementStore;
+
+    @Autowired
+    private OrganisationUnitService organisationUnitService;
+
+    @Autowired
+    private DataElementService dataElementService;
+
+    @Autowired
+    private ProgramService programService;
+
+    @Autowired
+    private DataEntryFormService dataEntryFormService;
+
+    @Autowired
+    private ProgramStageService programStageService;
+
+    @Autowired
+    private PatientService patientService;
+
+    @Autowired
+    private ProgramInstanceService programInstanceService;
+
+    @Autowired
+    private SmsConfigurationManager smsConfigurationManager;
+
+    private OrganisationUnit organisationUnitA;
+
+    private OrganisationUnit organisationUnitB;
+
+    private int orgunitAId;
+
+    private int orgunitBId;
+
+    private ProgramStage stageA;
+
+    private ProgramStage stageB;
+
+    private ProgramStage stageC;
+
+    private ProgramStage stageD;
+
+    private DataElement dataElementA;
+
+    private DataElement dataElementB;
+
+    private ProgramStageDataElement stageDataElementA;
+
+    private ProgramStageDataElement stageDataElementB;
+
+    private ProgramStageDataElement stageDataElementC;
+
+    private ProgramStageDataElement stageDataElementD;
+
+    private Date incidenDate;
+
+    private Date enrollmentDate;
+
+    private ProgramInstance programInstanceA;
+
+    private ProgramInstance programInstanceB;
+
+    private ProgramStageInstance programStageInstanceA;
+
+    private ProgramStageInstance programStageInstanceB;
+
+    private ProgramStageInstance programStageInstanceC;
+
+    private ProgramStageInstance programStageInstanceD1;
+
+    private ProgramStageInstance programStageInstanceD2;
+
+    private Patient patientA;
+
+    private Patient patientB;
+
+    private Program programA;
+
+    private MockI18nFormat mockFormat;
+
+    @Override
+    public void setUpTest()
+    {
+        mockFormat = new MockI18nFormat();
+
+        organisationUnitA = createOrganisationUnit( 'A' );
+        orgunitAId = organisationUnitService.addOrganisationUnit( organisationUnitA );
+
+        organisationUnitB = createOrganisationUnit( 'B' );
+        orgunitBId = organisationUnitService.addOrganisationUnit( organisationUnitB );
+
+        patientA = createPatient( 'A', organisationUnitA );
+        patientService.savePatient( patientA );
+
+        patientB = createPatient( 'B', organisationUnitB );
+        patientService.savePatient( patientB );
+
+        /**
+         * Program A
+         */
+        programA = createProgram( 'A', new HashSet<ProgramStage>(), organisationUnitA );
+        programService.addProgram( programA );
+
+        stageA = new ProgramStage( "A", programA );
+
+        PatientReminder patientReminderA = new PatientReminder( "A", 0, "Test program stage message template "
+            + PatientReminder.TEMPLATE_MESSSAGE_PATIENT_NAME, PatientReminder.DUE_DATE_TO_COMPARE,
+            PatientReminder.SEND_TO_PATIENT, null, PatientReminder.MESSAGE_TYPE_BOTH );
+
+        PatientReminder patientReminderB = new PatientReminder( "B", 0, "Test program stage message template "
+            + PatientReminder.TEMPLATE_MESSSAGE_PATIENT_NAME, PatientReminder.DUE_DATE_TO_COMPARE,
+            PatientReminder.SEND_TO_PATIENT, PatientReminder.SEND_WHEN_TO_C0MPLETED_EVENT,
+            PatientReminder.MESSAGE_TYPE_BOTH );
+
+        Set<PatientReminder> patientReminders = new HashSet<PatientReminder>();
+        patientReminders.add( patientReminderA );
+        patientReminders.add( patientReminderB );
+        stageA.setPatientReminders( patientReminders );
+
+        programStageService.saveProgramStage( stageA );
+
+        stageB = new ProgramStage( "B", programA );
+        PatientReminder patientReminderC = new PatientReminder( "C", 0, "Test program stage message template "
+            + PatientReminder.TEMPLATE_MESSSAGE_PATIENT_NAME, PatientReminder.DUE_DATE_TO_COMPARE,
+            PatientReminder.SEND_TO_PATIENT, PatientReminder.SEND_WHEN_TO_C0MPLETED_EVENT,
+            PatientReminder.MESSAGE_TYPE_BOTH );
+
+        patientReminders = new HashSet<PatientReminder>();
+        patientReminders.add( patientReminderC );
+        stageB.setPatientReminders( patientReminders );
+        programStageService.saveProgramStage( stageB );
+
+        Set<ProgramStage> programStages = new HashSet<ProgramStage>();
+        programStages.add( stageA );
+        programStages.add( stageB );
+        programA.setProgramStages( programStages );
+        programService.updateProgram( programA );
+
+        dataElementA = createDataElement( 'A' );
+        dataElementB = createDataElement( 'B' );
+
+        dataElementService.addDataElement( dataElementA );
+        dataElementService.addDataElement( dataElementB );
+
+        stageDataElementA = new ProgramStageDataElement( stageA, dataElementA, false, 1 );
+        stageDataElementB = new ProgramStageDataElement( stageA, dataElementB, false, 2 );
+        stageDataElementC = new ProgramStageDataElement( stageB, dataElementA, false, 1 );
+        stageDataElementD = new ProgramStageDataElement( stageB, dataElementB, false, 2 );
+
+        programStageDataElementStore.save( stageDataElementA );
+        programStageDataElementStore.save( stageDataElementB );
+        programStageDataElementStore.save( stageDataElementC );
+        programStageDataElementStore.save( stageDataElementD );
+
+        /**
+         * Program B
+         */
+
+        Program programB = createProgram( 'B', new HashSet<ProgramStage>(), organisationUnitB );
+        programService.addProgram( programB );
+
+        stageC = new ProgramStage( "C", programB );
+        programStageService.saveProgramStage( stageC );
+
+        stageD = new ProgramStage( "D", programB );
+        stageC.setIrregular( true );
+        programStageService.saveProgramStage( stageD );
+
+        programStages = new HashSet<ProgramStage>();
+        programStages.add( stageC );
+        programStages.add( stageD );
+        programB.setProgramStages( programStages );
+        programService.updateProgram( programB );
+
+        /**
+         * Program Instance and Program Stage Instance
+         */
+
+        Calendar calIncident = Calendar.getInstance();
+        PeriodType.clearTimeOfDay( calIncident );
+        calIncident.add( Calendar.DATE, -70 );
+        incidenDate = calIncident.getTime();
+
+        Calendar calEnrollment = Calendar.getInstance();
+        PeriodType.clearTimeOfDay( calEnrollment );
+        enrollmentDate = calEnrollment.getTime();
+
+        programInstanceA = new ProgramInstance( enrollmentDate, incidenDate, patientA, programA );
+        programInstanceA.setUid( "UID-PIA" );
+        programInstanceService.addProgramInstance( programInstanceA );
+
+        programInstanceB = new ProgramInstance( enrollmentDate, incidenDate, patientB, programB );
+        programInstanceService.addProgramInstance( programInstanceB );
+
+        programStageInstanceA = new ProgramStageInstance( programInstanceA, stageA );
+        programStageInstanceA.setDueDate( enrollmentDate );
+        programStageInstanceA.setUid( "UID-A" );
+
+        programStageInstanceB = new ProgramStageInstance( programInstanceA, stageB );
+        programStageInstanceB.setDueDate( enrollmentDate );
+        programStageInstanceB.setUid( "UID-B" );
+
+        programStageInstanceC = new ProgramStageInstance( programInstanceB, stageC );
+        programStageInstanceC.setDueDate( enrollmentDate );
+        programStageInstanceC.setUid( "UID-C" );
+
+        programStageInstanceD1 = new ProgramStageInstance( programInstanceB, stageD );
+        programStageInstanceD1.setDueDate( enrollmentDate );
+        programStageInstanceD1.setUid( "UID-D1" );
+
+        programStageInstanceD2 = new ProgramStageInstance( programInstanceB, stageD );
+        programStageInstanceD2.setDueDate( enrollmentDate );
+        programStageInstanceD2.setUid( "UID-D2" );
+    }
+
+    @Test
+    public void testAddProgramStageInstance()
+    {
+        int idA = programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        int idB = programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+
+        assertNotNull( programStageInstanceService.getProgramStageInstance( idA ) );
+        assertNotNull( programStageInstanceService.getProgramStageInstance( idB ) );
+    }
+
+    @Test
+    public void testDeleteProgramStageInstance()
+    {
+        int idA = programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        int idB = programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+
+        assertNotNull( programStageInstanceService.getProgramStageInstance( idA ) );
+        assertNotNull( programStageInstanceService.getProgramStageInstance( idB ) );
+
+        programStageInstanceService.deleteProgramStageInstance( programStageInstanceA );
+
+        assertNull( programStageInstanceService.getProgramStageInstance( idA ) );
+        assertNotNull( programStageInstanceService.getProgramStageInstance( idB ) );
+
+        programStageInstanceService.deleteProgramStageInstance( programStageInstanceB );
+
+        assertNull( programStageInstanceService.getProgramStageInstance( idA ) );
+        assertNull( programStageInstanceService.getProgramStageInstance( idB ) );
+    }
+
+    @Test
+    public void testUpdateProgramStageInstance()
+    {
+        int idA = programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+
+        assertNotNull( programStageInstanceService.getProgramStageInstance( idA ) );
+
+        programStageInstanceA.setName( "B" );
+        programStageInstanceService.updateProgramStageInstance( programStageInstanceA );
+
+        assertEquals( "B", programStageInstanceService.getProgramStageInstance( idA ).getName() );
+    }
+
+    @Test
+    public void testGetProgramStageInstanceById()
+    {
+        int idA = programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        int idB = programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+
+        assertEquals( programStageInstanceA, programStageInstanceService.getProgramStageInstance( idA ) );
+        assertEquals( programStageInstanceB, programStageInstanceService.getProgramStageInstance( idB ) );
+    }
+
+    @Test
+    public void testGetProgramStageInstanceByUid()
+    {
+        int idA = programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        int idB = programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+
+        assertEquals( programStageInstanceA, programStageInstanceService.getProgramStageInstance( idA ) );
+        assertEquals( programStageInstanceB, programStageInstanceService.getProgramStageInstance( idB ) );
+
+        assertEquals( programStageInstanceA, programStageInstanceService.getProgramStageInstance( "UID-A" ) );
+        assertEquals( programStageInstanceB, programStageInstanceService.getProgramStageInstance( "UID-B" ) );
+    }
+
+    @Test
+    public void testGetProgramStageInstanceByProgramInstanceStage()
+    {
+        programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+
+        ProgramStageInstance programStageInstance = programStageInstanceService.getProgramStageInstance(
+            programInstanceA, stageA );
+        assertEquals( programStageInstanceA, programStageInstance );
+
+        programStageInstance = programStageInstanceService.getProgramStageInstance( programInstanceA, stageB );
+        assertEquals( programStageInstanceB, programStageInstance );
+    }
+
+    @Test
+    public void testGetProgramStageInstanceListByProgramInstanceStage()
+    {
+        programStageInstanceService.addProgramStageInstance( programStageInstanceD1 );
+        programStageInstanceService.addProgramStageInstance( programStageInstanceD2 );
+
+        Collection<ProgramStageInstance> stageInstances = programStageInstanceService.getProgramStageInstances(
+            programInstanceB, stageD );
+        assertEquals( 2, stageInstances.size() );
+        assertTrue( stageInstances.contains( programStageInstanceD1 ) );
+        assertTrue( stageInstances.contains( programStageInstanceD2 ) );
+    }
+
+    @Test
+    public void testGetProgramStageInstancesByInstanceListComplete()
+    {
+        programStageInstanceA.setCompleted( true );
+        programStageInstanceB.setCompleted( false );
+        programStageInstanceC.setCompleted( true );
+        programStageInstanceD1.setCompleted( false );
+
+        programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+        programStageInstanceService.addProgramStageInstance( programStageInstanceC );
+        programStageInstanceService.addProgramStageInstance( programStageInstanceD1 );
+
+        Collection<ProgramInstance> programInstances = new HashSet<ProgramInstance>();
+        programInstances.add( programInstanceA );
+        programInstances.add( programInstanceB );
+
+        Collection<ProgramStageInstance> stageInstances = programStageInstanceService.getProgramStageInstances(
+            programInstances, true );
+        assertEquals( 2, stageInstances.size() );
+        assertTrue( stageInstances.contains( programStageInstanceA ) );
+        assertTrue( stageInstances.contains( programStageInstanceC ) );
+
+        stageInstances = programStageInstanceService.getProgramStageInstances( programInstances, false );
+        assertEquals( 2, stageInstances.size() );
+        assertTrue( stageInstances.contains( programStageInstanceB ) );
+        assertTrue( stageInstances.contains( programStageInstanceD1 ) );
+    }
+
+    @Test
+    public void testStatusProgramStageInstances()
+    {
+        programStageInstanceA.setCompleted( true );
+        programStageInstanceC.setStatus( ProgramStageInstance.SKIPPED_STATUS );
+
+        int idA = programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        int idB = programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+        int idC = programStageInstanceService.addProgramStageInstance( programStageInstanceC );
+        int idD = programStageInstanceService.addProgramStageInstance( programStageInstanceD1 );
+
+        Collection<ProgramStageInstance> programStageInstances = new HashSet<ProgramStageInstance>();
+        programStageInstances.add( programStageInstanceA );
+        programStageInstances.add( programStageInstanceB );
+        programStageInstances.add( programStageInstanceC );
+        programStageInstances.add( programStageInstanceD1 );
+
+        Map<Integer, Integer> expectedMap = new HashMap<Integer, Integer>();
+        expectedMap.put( idA, ProgramStageInstance.COMPLETED_STATUS );
+        expectedMap.put( idB, ProgramStageInstance.FUTURE_VISIT_STATUS );
+        expectedMap.put( idC, ProgramStageInstance.SKIPPED_STATUS );
+        expectedMap.put( idD, ProgramStageInstance.FUTURE_VISIT_STATUS );
+
+        Map<Integer, Integer> actualMap = programStageInstanceService
+            .statusProgramStageInstances( programStageInstances );
+        assertEquals( expectedMap, actualMap );
+    }
+
+    @Test
+    public void testGetProgramStageInstancesByPatientStatus()
+    {
+        programStageInstanceA.setCompleted( true );
+        programStageInstanceB.setCompleted( false );
+        programStageInstanceC.setCompleted( true );
+        programStageInstanceD1.setCompleted( true );
+
+        programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+        programStageInstanceService.addProgramStageInstance( programStageInstanceC );
+        programStageInstanceService.addProgramStageInstance( programStageInstanceD1 );
+
+        List<ProgramStageInstance> stageInstances = programStageInstanceService.getProgramStageInstances( patientA,
+            true );
+        assertEquals( 1, stageInstances.size() );
+        assertTrue( stageInstances.contains( programStageInstanceA ) );
+
+        stageInstances = programStageInstanceService.getProgramStageInstances( patientA, false );
+        assertEquals( 1, stageInstances.size() );
+        assertTrue( stageInstances.contains( programStageInstanceB ) );
+    }
+
+    @Test
+    public void testUpdateProgramStageInstances()
+    {
+        int idA = programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        int idB = programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+
+        OutboundSms outboundSms = new OutboundSms();
+        Collection<Integer> programStageInstances = new HashSet<Integer>();
+        programStageInstances.add( idA );
+        programStageInstances.add( idB );
+
+        programStageInstanceService.updateProgramStageInstances( programStageInstances, outboundSms );
+        assertTrue( programStageInstanceService.getProgramStageInstance( idA ).getOutboundSms().contains( outboundSms ) );
+        assertTrue( programStageInstanceService.getProgramStageInstance( idB ).getOutboundSms().contains( outboundSms ) );
+    }
+
+    @Test
+    public void testGetProgramStageInstancesByOuPeriodProgram()
+    {
+        programStageInstanceA.setExecutionDate( enrollmentDate );
+        programStageInstanceA.setOrganisationUnit( organisationUnitA );
+        programStageInstanceB.setExecutionDate( enrollmentDate );
+        programStageInstanceB.setOrganisationUnit( organisationUnitB );
+
+        programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+
+        Collection<Integer> orgunitIds = new HashSet<Integer>();
+        orgunitIds.add( orgunitAId );
+        orgunitIds.add( orgunitBId );
+
+        Collection<ProgramStageInstance> result = programStageInstanceService.getProgramStageInstances( programA,
+            orgunitIds, incidenDate, enrollmentDate, false );
+
+        assertEquals( 2, result.size() );
+        assertTrue( result.contains( programStageInstanceA ) );
+        assertTrue( result.contains( programStageInstanceB ) );
+    }
+
+    @Test
+    public void testGetOverDueEventCount()
+    {
+        Calendar cal = Calendar.getInstance();
+        PeriodType.clearTimeOfDay( cal );
+        cal.add( Calendar.DATE, -1 );
+        Date date = cal.getTime();
+
+        programStageInstanceA.setDueDate( date );
+        programStageInstanceB.setDueDate( date );
+
+        programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+
+        Collection<Integer> orgunitIds = new HashSet<Integer>();
+        orgunitIds.add( orgunitAId );
+        orgunitIds.add( orgunitBId );
+
+        int count = programStageInstanceService.getOverDueEventCount( stageA, orgunitIds, incidenDate, enrollmentDate );
+        assertEquals( 1, count );
+    }
+
+    @Test
+    public void testGetOrganisationUnitIds()
+    {
+        programStageInstanceA.setExecutionDate( enrollmentDate );
+        programStageInstanceA.setOrganisationUnit( organisationUnitA );
+        programStageInstanceB.setExecutionDate( enrollmentDate );
+        programStageInstanceB.setOrganisationUnit( organisationUnitB );
+
+        programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+        programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+
+        Collection<Integer> orgunitIds = programStageInstanceService.getOrganisationUnitIds( incidenDate,
+            enrollmentDate );
+        assertEquals( 2, orgunitIds.size() );
+        assertTrue( orgunitIds.contains( orgunitAId ) );
+        assertTrue( orgunitIds.contains( orgunitBId ) );
+    }
+
+    @Test
+    public void testSendMessages()
+    {
+        createSMSConfiguration();
+
+        programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+
+        Collection<OutboundSms> outboundSmsList = programStageInstanceService.sendMessages( programStageInstanceA,
+            PatientReminder.SEND_WHEN_TO_C0MPLETED_EVENT, mockFormat );
+        assertEquals( 1, outboundSmsList.size() );
+        assertEquals( "Test program stage message template NameA", outboundSmsList.iterator().next().getMessage() );
+    }
+
+    @Test
+    public void testSendMessageConversations()
+    {
+        programStageInstanceService.addProgramStageInstance( programStageInstanceB );
+
+        Collection<MessageConversation> messages = programStageInstanceService.sendMessageConversations(
+            programStageInstanceA, PatientReminder.SEND_WHEN_TO_C0MPLETED_EVENT, mockFormat );
+        assertEquals( 1, messages.size() );
+        assertEquals( "Test program stage message template NameA", messages.iterator().next().getMessages().get( 0 )
+            .getText() );
+    }
+
+    @Test
+    public void testCompleteProgramStageInstance()
+    {
+        this.createSMSConfiguration();
+        SmsConfiguration smsConfiguration = new SmsConfiguration();
+        smsConfiguration.setEnabled( true );
+
+        int idA = programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+
+        programStageInstanceService.completeProgramStageInstance( programStageInstanceA, mockFormat );
+        assertEquals( true, programStageInstanceService.getProgramStageInstance( idA ).isCompleted() );
+    }
+
+    @Test
+    public void testSetExecutionDate()
+    {
+        int idA = programStageInstanceService.addProgramStageInstance( programStageInstanceA );
+
+        programStageInstanceService.setExecutionDate( programStageInstanceA, enrollmentDate, organisationUnitA );
+
+        ProgramStageInstance programStageInstance = programStageInstanceService.getProgramStageInstance( idA );
+        assertEquals( enrollmentDate, programStageInstance.getExecutionDate() );
+        assertEquals( organisationUnitA, programStageInstance.getOrganisationUnit() );
+    }
+
+    @Test
+    public void testCreateProgramStageInstance()
+    {
+        programA.setType( Program.SINGLE_EVENT_WITHOUT_REGISTRATION );
+        programService.updateProgram( programA );
+
+        ProgramStageInstance programStageInstance = programStageInstanceService.createProgramStageInstance( patientA,
+            programA, enrollmentDate, organisationUnitA );
+
+        assertNotNull( programStageInstanceService.getProgramStageInstance( programStageInstance.getUid() ) );
+    }
+
+    private void createSMSConfiguration()
+    {
+        BulkSmsGatewayConfig bulkGatewayConfig = new BulkSmsGatewayConfig();
+        bulkGatewayConfig.setName( "bulksms" );
+        bulkGatewayConfig.setPassword( "bulk" );
+        bulkGatewayConfig.setUsername( "bulk" );
+        bulkGatewayConfig.setRegion( "uk" );
+        bulkGatewayConfig.setDefault( true );
+
+        SmsConfiguration smsConfig = new SmsConfiguration();
+        smsConfig.setPollingInterval( 3000 );
+        smsConfig.getGateways().add( bulkGatewayConfig );
+        smsConfig.setEnabled( true );
+        smsConfigurationManager.updateSmsConfiguration( smsConfig );
+
+    }
+
+}
\ No newline at end of file

=== added file 'dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageInstanceStoreTest.java'
--- dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageInstanceStoreTest.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-patient/src/test/java/org/hisp/dhis/program/ProgramStageInstanceStoreTest.java	2013-11-19 03:45:56 +0000
@@ -0,0 +1,410 @@
+/*
+ * Copyright (c) 2004-2013, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright notice, this
+ *   list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of the HISP project nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.hisp.dhis.program;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.hisp.dhis.DhisSpringTest;
+import org.hisp.dhis.dataelement.DataElement;
+import org.hisp.dhis.dataelement.DataElementService;
+import org.hisp.dhis.dataentryform.DataEntryFormService;
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+import org.hisp.dhis.organisationunit.OrganisationUnitService;
+import org.hisp.dhis.patient.Patient;
+import org.hisp.dhis.patient.PatientReminder;
+import org.hisp.dhis.patient.PatientService;
+import org.hisp.dhis.period.PeriodType;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * @author Chau Thu Tran
+ * 
+ * @version $ ProgramStageInstanceStoreTest.java Nov 14, 2013 4:22:27 PM $
+ */
+public class ProgramStageInstanceStoreTest
+    extends DhisSpringTest
+{
+    @Autowired
+    private ProgramStageInstanceStore programStageInstanceStore;
+
+    @Autowired
+    private ProgramStageDataElementStore programStageDataElementStore;
+
+    @Autowired
+    private OrganisationUnitService organisationUnitService;
+
+    @Autowired
+    private DataElementService dataElementService;
+
+    @Autowired
+    private ProgramService programService;
+
+    @Autowired
+    private DataEntryFormService dataEntryFormService;
+
+    @Autowired
+    private ProgramStageService programStageService;
+
+    @Autowired
+    private PatientService patientService;
+
+    @Autowired
+    private ProgramInstanceService programInstanceService;
+
+    private OrganisationUnit organisationUnitA;
+
+    private OrganisationUnit organisationUnitB;
+
+    private int orgunitAId;
+
+    private int orgunitBId;
+
+    private ProgramStage stageA;
+
+    private ProgramStage stageB;
+
+    private ProgramStage stageC;
+
+    private ProgramStage stageD;
+
+    private DataElement dataElementA;
+
+    private DataElement dataElementB;
+
+    private ProgramStageDataElement stageDataElementA;
+
+    private ProgramStageDataElement stageDataElementB;
+
+    private ProgramStageDataElement stageDataElementC;
+
+    private ProgramStageDataElement stageDataElementD;
+
+    private Date incidenDate;
+
+    private Date enrollmentDate;
+
+    private ProgramInstance programInstanceA;
+
+    private ProgramInstance programInstanceB;
+
+    private ProgramStageInstance programStageInstanceA;
+
+    private ProgramStageInstance programStageInstanceB;
+
+    private ProgramStageInstance programStageInstanceC;
+
+    private ProgramStageInstance programStageInstanceD1;
+
+    private ProgramStageInstance programStageInstanceD2;
+
+    private Patient patientA;
+
+    private Patient patientB;
+
+    private Program programA;
+
+    @Override
+    public void setUpTest()
+    {
+        organisationUnitA = createOrganisationUnit( 'A' );
+        orgunitAId = organisationUnitService.addOrganisationUnit( organisationUnitA );
+
+        organisationUnitB = createOrganisationUnit( 'B' );
+        orgunitBId = organisationUnitService.addOrganisationUnit( organisationUnitB );
+
+        patientA = createPatient( 'A', organisationUnitA );
+        patientService.savePatient( patientA );
+
+        patientB = createPatient( 'B', organisationUnitB );
+        patientService.savePatient( patientB );
+
+        /**
+         * Program A
+         */
+        programA = createProgram( 'A', new HashSet<ProgramStage>(), organisationUnitA );
+        programService.addProgram( programA );
+
+        stageA = new ProgramStage( "A", programA );
+
+        PatientReminder patientReminderA = new PatientReminder( "A", 0, "Test program stage message template "
+            + PatientReminder.TEMPLATE_MESSSAGE_PATIENT_NAME, PatientReminder.DUE_DATE_TO_COMPARE,
+            PatientReminder.SEND_TO_PATIENT, null, PatientReminder.MESSAGE_TYPE_BOTH );
+
+        PatientReminder patientReminderB = new PatientReminder( "B", 0, "Test program stage message template "
+            + PatientReminder.TEMPLATE_MESSSAGE_PATIENT_NAME, PatientReminder.DUE_DATE_TO_COMPARE,
+            PatientReminder.SEND_TO_PATIENT, PatientReminder.SEND_WHEN_TO_C0MPLETED_EVENT,
+            PatientReminder.MESSAGE_TYPE_BOTH );
+
+        Set<PatientReminder> patientReminders = new HashSet<PatientReminder>();
+        patientReminders.add( patientReminderA );
+        patientReminders.add( patientReminderB );
+        stageA.setPatientReminders( patientReminders );
+
+        programStageService.saveProgramStage( stageA );
+
+        stageB = new ProgramStage( "B", programA );
+        PatientReminder patientReminderC = new PatientReminder( "C", 0, "Test program stage message template "
+            + PatientReminder.TEMPLATE_MESSSAGE_PATIENT_NAME, PatientReminder.DUE_DATE_TO_COMPARE,
+            PatientReminder.SEND_TO_PATIENT, PatientReminder.SEND_WHEN_TO_C0MPLETED_EVENT,
+            PatientReminder.MESSAGE_TYPE_BOTH );
+
+        patientReminders = new HashSet<PatientReminder>();
+        patientReminders.add( patientReminderC );
+        stageB.setPatientReminders( patientReminders );
+        programStageService.saveProgramStage( stageB );
+
+        Set<ProgramStage> programStages = new HashSet<ProgramStage>();
+        programStages.add( stageA );
+        programStages.add( stageB );
+        programA.setProgramStages( programStages );
+        programService.updateProgram( programA );
+
+        dataElementA = createDataElement( 'A' );
+        dataElementB = createDataElement( 'B' );
+
+        dataElementService.addDataElement( dataElementA );
+        dataElementService.addDataElement( dataElementB );
+
+        stageDataElementA = new ProgramStageDataElement( stageA, dataElementA, false, 1 );
+        stageDataElementB = new ProgramStageDataElement( stageA, dataElementB, false, 2 );
+        stageDataElementC = new ProgramStageDataElement( stageB, dataElementA, false, 1 );
+        stageDataElementD = new ProgramStageDataElement( stageB, dataElementB, false, 2 );
+
+        programStageDataElementStore.save( stageDataElementA );
+        programStageDataElementStore.save( stageDataElementB );
+        programStageDataElementStore.save( stageDataElementC );
+        programStageDataElementStore.save( stageDataElementD );
+
+        /**
+         * Program B
+         */
+
+        Program programB = createProgram( 'B', new HashSet<ProgramStage>(), organisationUnitB );
+        programService.addProgram( programB );
+
+        stageC = new ProgramStage( "C", programB );
+        programStageService.saveProgramStage( stageC );
+
+        stageD = new ProgramStage( "D", programB );
+        stageC.setIrregular( true );
+        programStageService.saveProgramStage( stageD );
+
+        programStages = new HashSet<ProgramStage>();
+        programStages.add( stageC );
+        programStages.add( stageD );
+        programB.setProgramStages( programStages );
+        programService.updateProgram( programB );
+
+        /**
+         * Program Instance and Program Stage Instance
+         */
+
+        Calendar calIncident = Calendar.getInstance();
+        PeriodType.clearTimeOfDay( calIncident );
+        calIncident.add( Calendar.DATE, -70 );
+        incidenDate = calIncident.getTime();
+
+        Calendar calEnrollment = Calendar.getInstance();
+        PeriodType.clearTimeOfDay( calEnrollment );
+        enrollmentDate = calEnrollment.getTime();
+
+        programInstanceA = new ProgramInstance( enrollmentDate, incidenDate, patientA, programA );
+        programInstanceA.setUid( "UID-PIA" );
+        programInstanceService.addProgramInstance( programInstanceA );
+
+        programInstanceB = new ProgramInstance( enrollmentDate, incidenDate, patientB, programB );
+        programInstanceService.addProgramInstance( programInstanceB );
+
+        programStageInstanceA = new ProgramStageInstance( programInstanceA, stageA );
+        programStageInstanceA.setDueDate( enrollmentDate );
+        programStageInstanceA.setUid( "UID-A" );
+
+        programStageInstanceB = new ProgramStageInstance( programInstanceA, stageB );
+        programStageInstanceB.setDueDate( enrollmentDate );
+        programStageInstanceB.setUid( "UID-B" );
+
+        programStageInstanceC = new ProgramStageInstance( programInstanceB, stageC );
+        programStageInstanceC.setDueDate( enrollmentDate );
+        programStageInstanceC.setUid( "UID-C" );
+
+        programStageInstanceD1 = new ProgramStageInstance( programInstanceB, stageD );
+        programStageInstanceD1.setDueDate( enrollmentDate );
+        programStageInstanceD1.setUid( "UID-D1" );
+
+        programStageInstanceD2 = new ProgramStageInstance( programInstanceB, stageD );
+        programStageInstanceD2.setDueDate( enrollmentDate );
+        programStageInstanceD2.setUid( "UID-D2" );
+    }
+
+    @Test
+    public void testGetProgramStageInstanceByProgramInstanceStage()
+    {
+        programStageInstanceStore.save( programStageInstanceA );
+        programStageInstanceStore.save( programStageInstanceB );
+
+        ProgramStageInstance programStageInstance = programStageInstanceStore.get( programInstanceA, stageA );
+        assertEquals( programStageInstanceA, programStageInstance );
+
+        programStageInstance = programStageInstanceStore.get( programInstanceA, stageB );
+        assertEquals( programStageInstanceB, programStageInstance );
+    }
+
+    @Test
+    public void testGetProgramStageInstanceListByProgramInstanceStage()
+    {
+        programStageInstanceStore.save( programStageInstanceD1 );
+        programStageInstanceStore.save( programStageInstanceD2 );
+
+        Collection<ProgramStageInstance> stageInstances = programStageInstanceStore.getAll( programInstanceB, stageD );
+        assertEquals( 2, stageInstances.size() );
+        assertTrue( stageInstances.contains( programStageInstanceD1 ) );
+        assertTrue( stageInstances.contains( programStageInstanceD2 ) );
+    }
+
+    @Test
+    public void testGetProgramStageInstancesByInstanceListComplete()
+    {
+        programStageInstanceA.setCompleted( true );
+        programStageInstanceB.setCompleted( false );
+        programStageInstanceC.setCompleted( true );
+        programStageInstanceD1.setCompleted( false );
+
+        programStageInstanceStore.save( programStageInstanceA );
+        programStageInstanceStore.save( programStageInstanceB );
+        programStageInstanceStore.save( programStageInstanceC );
+        programStageInstanceStore.save( programStageInstanceD1 );
+
+        Collection<ProgramInstance> programInstances = new HashSet<ProgramInstance>();
+        programInstances.add( programInstanceA );
+        programInstances.add( programInstanceB );
+
+        Collection<ProgramStageInstance> stageInstances = programStageInstanceStore.get( programInstances, true );
+        assertEquals( 2, stageInstances.size() );
+        assertTrue( stageInstances.contains( programStageInstanceA ) );
+        assertTrue( stageInstances.contains( programStageInstanceC ) );
+
+        stageInstances = programStageInstanceStore.get( programInstances, false );
+        assertEquals( 2, stageInstances.size() );
+        assertTrue( stageInstances.contains( programStageInstanceB ) );
+        assertTrue( stageInstances.contains( programStageInstanceD1 ) );
+    }
+
+    @Test
+    public void testGetProgramStageInstancesByPatientStatus()
+    {
+        programStageInstanceA.setCompleted( true );
+        programStageInstanceB.setCompleted( false );
+        programStageInstanceC.setCompleted( true );
+        programStageInstanceD1.setCompleted( true );
+
+        programStageInstanceStore.save( programStageInstanceA );
+        programStageInstanceStore.save( programStageInstanceB );
+        programStageInstanceStore.save( programStageInstanceC );
+        programStageInstanceStore.save( programStageInstanceD1 );
+
+        List<ProgramStageInstance> stageInstances = programStageInstanceStore.get( patientA, true );
+        assertEquals( 1, stageInstances.size() );
+        assertTrue( stageInstances.contains( programStageInstanceA ) );
+
+        stageInstances = programStageInstanceStore.get( patientA, false );
+        assertEquals( 1, stageInstances.size() );
+        assertTrue( stageInstances.contains( programStageInstanceB ) );
+    }
+
+    @Test
+    public void testGetProgramStageInstancesByOuPeriodProgram()
+    {
+        programStageInstanceA.setExecutionDate( enrollmentDate );
+        programStageInstanceA.setOrganisationUnit( organisationUnitA );
+        programStageInstanceB.setExecutionDate( enrollmentDate );
+        programStageInstanceB.setOrganisationUnit( organisationUnitB );
+
+        programStageInstanceStore.save( programStageInstanceA );
+        programStageInstanceStore.save( programStageInstanceB );
+
+        Collection<Integer> orgunitIds = new HashSet<Integer>();
+        orgunitIds.add( orgunitAId );
+        orgunitIds.add( orgunitBId );
+
+        Collection<ProgramStageInstance> result = programStageInstanceStore.get( programA, orgunitIds, incidenDate,
+            enrollmentDate, false );
+
+        assertEquals( 2, result.size() );
+        assertTrue( result.contains( programStageInstanceA ) );
+        assertTrue( result.contains( programStageInstanceB ) );
+    }
+
+    @Test
+    public void testGetOverDueEventCount()
+    {
+        Calendar cal = Calendar.getInstance();
+        PeriodType.clearTimeOfDay( cal );
+        cal.add( Calendar.DATE, -1 );
+        Date date = cal.getTime();
+
+        programStageInstanceA.setDueDate( date );
+        programStageInstanceB.setDueDate( date );
+
+        programStageInstanceStore.save( programStageInstanceA );
+        programStageInstanceStore.save( programStageInstanceB );
+
+        Collection<Integer> orgunitIds = new HashSet<Integer>();
+        orgunitIds.add( orgunitAId );
+        orgunitIds.add( orgunitBId );
+
+        int count = programStageInstanceStore.getOverDueCount( stageA, orgunitIds, incidenDate, enrollmentDate );
+        assertEquals( 1, count );
+    }
+
+    @Test
+    public void testGetOrganisationUnitIds()
+    {
+        programStageInstanceA.setExecutionDate( enrollmentDate );
+        programStageInstanceA.setOrganisationUnit( organisationUnitA );
+        programStageInstanceB.setExecutionDate( enrollmentDate );
+        programStageInstanceB.setOrganisationUnit( organisationUnitB );
+
+        programStageInstanceStore.save( programStageInstanceA );
+        programStageInstanceStore.save( programStageInstanceB );
+
+        Collection<Integer> orgunitIds = programStageInstanceStore.getOrgunitIds( incidenDate, enrollmentDate );
+        assertEquals( 2, orgunitIds.size() );
+        assertTrue( orgunitIds.contains( orgunitAId ) );
+        assertTrue( orgunitIds.contains( orgunitBId ) );
+    }
+
+}
\ No newline at end of file