package org.ei.drishti.service;
import org.ei.drishti.service.scheduling.ANCSchedulesService;
import org.ei.drishti.service.scheduling.ScheduleService;
import org.joda.time.LocalDate;
import org.motechproject.model.Time;
import org.motechproject.scheduletracking.api.service.EnrollmentRecord;
import org.motechproject.scheduletracking.api.service.ScheduleTrackingService;
import java.util.Arrays;
import java.util.List;
import static org.ei.drishti.common.util.DateUtil.today;
import static org.ei.drishti.scheduler.DrishtiScheduleConstants.MotherScheduleConstants.*;
import static org.mockito.Mockito.*;
public class FastForwardScheduleTestBase {
private final ScheduleTrackingService scheduleTrackingService;
private final ScheduleService scheduleService;
private String scheduleName;
private String expectedNextMilestone;
private int visitNumberToTryAndFulfill;
private ANCSchedulesService schedulesService;
private Action serviceCall;
private ActionService actionService;
private String numberOfIFATabletsGiven;
public FastForwardScheduleTestBase() {
this.scheduleTrackingService = mock(ScheduleTrackingService.class);
this.actionService = mock(ActionService.class);
this.scheduleService = mock(ScheduleService.class);
this.schedulesService = new ANCSchedulesService(scheduleTrackingService, actionService, scheduleService);
}
public FastForwardScheduleTestBase forANCSchedule() {
this.scheduleName = SCHEDULE_ANC;
this.serviceCall = new Action() {
@Override
public void make(String caseId, int visitNumber, LocalDate visitDate) {
schedulesService.ancVisitHasHappened(caseId, "ANM 1", visitNumber, visitDate.toString());
}
};
return this;
}
public FastForwardScheduleTestBase forTT1Schedule() {
this.scheduleName = SCHEDULE_TT_1;
this.serviceCall = new Action() {
@Override
public void make(String caseId, int visitNumber, LocalDate visitDate) {
schedulesService.ttVisitHasHappened(caseId, "ANM 1", "tt1", visitDate.toString());
}
};
return this;
}
public FastForwardScheduleTestBase forTT2Schedule() {
this.scheduleName = SCHEDULE_TT_2;
this.serviceCall = new Action() {
@Override
public void make(String caseId, int visitNumber, LocalDate visitDate) {
schedulesService.ttVisitHasHappened(caseId, "ANM 1", "tt2", visitDate.toString());
}
};
return this;
}
public FastForwardScheduleTestBase forIFA1Schedule() {
return forIFASchedule(SCHEDULE_IFA_1);
}
public FastForwardScheduleTestBase forIFA2Schedule() {
return forIFASchedule(SCHEDULE_IFA_2);
}
public FastForwardScheduleTestBase forIFA3Schedule() {
return forIFASchedule(SCHEDULE_IFA_3);
}
private FastForwardScheduleTestBase forIFASchedule(String scheduleName) {
this.scheduleName = scheduleName;
this.serviceCall = new Action() {
@Override
public void make(String caseId, int visitNumber, LocalDate visitDate) {
schedulesService.ifaTabletsGiven(caseId, "ANM 1", numberOfIFATabletsGiven, visitDate.toString());
}
};
return this;
}
public FastForwardScheduleTestBase whenExpecting(String expectedNextMilestone) {
this.expectedNextMilestone = expectedNextMilestone;
return this;
}
public FastForwardScheduleTestBase providedWithVisitNumber(int visitNumberToTryAndFulfill) {
this.visitNumberToTryAndFulfill = visitNumberToTryAndFulfill;
return this;
}
public FastForwardScheduleTestBase providedWithNumberOfIFATablets(String numberOfIFATabletsGiven) {
this.numberOfIFATabletsGiven = numberOfIFATabletsGiven;
return this;
}
public void willFulfillFor(String... expectedVisitCodes) {
EnrollmentRecord recordForNextMilestone = enrollmentRecord(scheduleName, expectedNextMilestone);
when(scheduleTrackingService.getEnrollment("Case X", scheduleName)).thenReturn(recordForNextMilestone);
LocalDate visitDate = today();
serviceCall.make("Case X", visitNumberToTryAndFulfill, visitDate);
verify(scheduleTrackingService, times(expectedVisitCodes.length)).fulfillCurrentMilestone(eq("Case X"), eq(scheduleName), eq(visitDate), any(Time.class));
verifyAllActionInteractions(Arrays.asList(expectedVisitCodes));
}
public void willNotFulfillAnything() {
willFulfillFor();
}
private void verifyAllActionInteractions(List<String> expectedVisitCodes) {
if (expectedVisitCodes.isEmpty()) {
verifyZeroInteractions(actionService);
}
for (String visitCode : expectedVisitCodes) {
verify(actionService).markAlertAsClosed("Case X", "ANM 1", visitCode, today().toString());
}
verifyNoMoreInteractions(actionService);
}
private EnrollmentRecord enrollmentRecord(String scheduleName, String currentMilestone) {
return new EnrollmentRecord("Case X", scheduleName, currentMilestone, null, null, null, null, null, null, null);
}
private class Action {
public void make(String caseId, int visitNumber, LocalDate visitDate) {
throw new RuntimeException("Unsupported.");
}
}
}