@Test
  public void
      shouldScheduleDailyAdherenceQualityJobsForAPatientOnDailyReminderStartingFromTreatmentAdviceStartDate() {
    final String patientId = "123456";
    Patient patient =
        PatientBuilder.startRecording()
            .withDefaults()
            .withId(patientId)
            .withCallPreference(CallPreference.DailyPillReminder)
            .build();

    final LocalDate startDate = DateUtil.today().plusDays(1);
    final LocalDate endDate = startDate.plusDays(1);

    TreatmentAdvice advice = getTreatmentAdvice(startDate, endDate);

    schedulerService.scheduleJobForDeterminingAdherenceQualityInDailyPillReminder(patient, advice);

    final ArgumentCaptor<CronSchedulableJob> cronArgCaptor =
        ArgumentCaptor.forClass(CronSchedulableJob.class);
    verify(motechSchedulerService, times(1)).safeScheduleJob(cronArgCaptor.capture());

    CronSchedulableJob jobScheduledWithParams = cronArgCaptor.getValue();
    final MotechEvent motechEventInScheduledJob = jobScheduledWithParams.getMotechEvent();
    Map<String, Object> paramsInScheduledJob = motechEventInScheduledJob.getParameters();

    assertCronSchedulableJob(
        jobScheduledWithParams, "0 0 0 * * ?", startDate.toDate(), endDate.plusDays(1).toDate());

    assertEquals(paramsInScheduledJob.get(EventKeys.EXTERNAL_ID_KEY), patientId);
    assertEquals(
        motechEventInScheduledJob.getSubject(), TAMAConstants.DAILY_ADHERENCE_IN_RED_ALERT_SUBJECT);
  }
  @Test
  public void shouldSetUpCorrectCronExpressionForDailyJob() {
    final LocalDate today = DateUtil.today();
    pillRegimen = new PillRegimen(externalId, dosages, new DailyScheduleDetails(15, 2));
    pillRegimen.setId(pillRegimenId);
    final HashSet<Medicine> medicines =
        new HashSet<Medicine>() {
          {
            add(new Medicine("med1", today.minusDays(1), null));
          }
        };
    final Dosage dosage1 = new Dosage(new Time(10, 5), medicines);

    jobScheduler =
        new PillRegimenJobScheduler(schedulerService) {
          @Override
          public CronSchedulableJob getSchedulableDailyJob(
              String pillRegimenId, String externalId, Dosage dosage) {
            return super.getSchedulableDailyJob(pillRegimenId, externalId, dosage);
          }
        };

    final CronSchedulableJob schedulableJob =
        jobScheduler.getSchedulableDailyJob(pillRegimenId, externalId, dosage1);
    assertEquals(String.format("0 %d %d * * ?", 5, 10), schedulableJob.getCronExpression());
    assertEquals(
        EventKeys.PILLREMINDER_REMINDER_EVENT_SUBJECT_SCHEDULER,
        schedulableJob.getMotechEvent().getSubject());
    assertTrue(schedulableJob.getStartTime().getTime() > today.minusDays(1).toDate().getTime());
  }
  @Test
  public void
      shouldScheduleDailyAdherenceQualityJobsForAPatientOnDailyReminderStartingFromTodayIfTreatmentAdviceStartDateIsInPast() {
    final String patientId = "123456";
    Patient patient =
        PatientBuilder.startRecording()
            .withDefaults()
            .withId(patientId)
            .withCallPreference(CallPreference.DailyPillReminder)
            .build();

    final LocalDate startDate = DateUtil.today().minusDays(2);
    final LocalDate endDate = DateUtil.today().plusDays(2);
    final DateTime timeFewMillisBack = DateUtil.now().minusMillis(1000);

    TreatmentAdvice advice = getTreatmentAdvice(startDate, endDate);

    schedulerService.scheduleJobForDeterminingAdherenceQualityInDailyPillReminder(patient, advice);

    final ArgumentCaptor<CronSchedulableJob> cronArgCaptor =
        ArgumentCaptor.forClass(CronSchedulableJob.class);
    verify(motechSchedulerService).safeScheduleJob(cronArgCaptor.capture());

    CronSchedulableJob jobScheduledWithParams = cronArgCaptor.getValue();
    final MotechEvent motechEventInScheduledJob = jobScheduledWithParams.getMotechEvent();
    Map<String, Object> paramsInScheduledJob = motechEventInScheduledJob.getParameters();

    assertEquals(
        "Should setup the cron expression to run at every midnight.",
        jobScheduledWithParams.getCronExpression(),
        "0 0 0 * * ?");

    DateTime actualTimeWhenTriggerWasActivated =
        DateUtil.newDateTime(jobScheduledWithParams.getStartTime());
    assertTrue(
        "Since the advice has already started in past, we should schedule it starting now, which is after a time few milli seconds back.",
        timeFewMillisBack.isBefore(actualTimeWhenTriggerWasActivated));
    DateTime rightNow = DateUtil.now();
    assertTrue(rightNow.isEqual(actualTimeWhenTriggerWasActivated));

    assertEquals(jobScheduledWithParams.getEndTime(), endDate.plusDays(1).toDate());

    assertEquals(paramsInScheduledJob.get(EventKeys.EXTERNAL_ID_KEY), patientId);
    assertEquals(
        motechEventInScheduledJob.getSubject(), TAMAConstants.DAILY_ADHERENCE_IN_RED_ALERT_SUBJECT);
  }
 private void assertCronSchedulableJob(
     CronSchedulableJob cronSchedulableJob, String cronExpression, Date startTime, Date endTime) {
   assertEquals(cronExpression, cronSchedulableJob.getCronExpression());
   assertEquals(startTime, cronSchedulableJob.getStartTime());
   assertEquals(endTime, cronSchedulableJob.getEndTime());
 }