package org.openlmis.core.model.service; import com.google.inject.AbstractModule; import org.joda.time.DateTime; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.openlmis.core.LMISTestApp; import org.openlmis.core.LMISTestRunner; import org.openlmis.core.exceptions.LMISException; import org.openlmis.core.model.Period; import org.openlmis.core.model.Program; import org.openlmis.core.model.RnRForm; import org.openlmis.core.model.repository.InventoryRepository; import org.openlmis.core.model.repository.ProgramRepository; import org.openlmis.core.model.repository.RnrFormRepository; import org.openlmis.core.model.repository.StockMovementRepository; import org.openlmis.core.model.repository.StockRepository; import org.openlmis.core.utils.DateUtil; import org.robolectric.RuntimeEnvironment; import roboguice.RoboGuice; import static junit.framework.Assert.assertFalse; import static junit.framework.TestCase.assertTrue; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import static org.roboguice.shaded.goole.common.collect.Lists.newArrayList; @RunWith(LMISTestRunner.class) public class RequisitionPeriodServiceTest { private ProgramRepository mockProgramRepository; private RnrFormRepository mockRnrFormRepository; private StockRepository mockStockRepository; private RequisitionPeriodService requisitionPeriodService; private Program programMMIA; private InventoryRepository mockInventoryRepository; private StockMovementRepository mockStockMovementRepository; @Before public void setup() throws LMISException { mockProgramRepository = mock(ProgramRepository.class); mockRnrFormRepository = mock(RnrFormRepository.class); mockStockRepository = mock(StockRepository.class); mockInventoryRepository = mock(InventoryRepository.class); mockStockMovementRepository = mock(StockMovementRepository.class); RoboGuice.overrideApplicationInjector(RuntimeEnvironment.application, new MyTestModule()); requisitionPeriodService = RoboGuice.getInjector(RuntimeEnvironment.application).getInstance(RequisitionPeriodService.class); programMMIA = new Program("MMIA", "MMIA", null, false, null); programMMIA.setId(1l); when(mockProgramRepository.queryByCode(anyString())).thenReturn(programMMIA); } @Test public void shouldGeneratePeriodWithPreviousRnrEndDateAsBeginAndNextMonthAsEndDate() throws Exception { RnRForm previousRnrForm = new RnRForm(); previousRnrForm.setProgram(programMMIA); previousRnrForm.setPeriodEnd(DateUtil.parseString("2020-10-18", DateUtil.DB_DATE_FORMAT)); DateTime dateTime = new DateTime(previousRnrForm.getPeriodEnd()).plusMonths(1); DateTime expectedPeriodEnd = DateUtil.cutTimeStamp(dateTime.withDate(dateTime.getYear(), dateTime.getMonthOfYear(), Period.END_DAY)); when(mockRnrFormRepository.listInclude(RnRForm.Emergency.No, programMMIA.getProgramCode())).thenReturn(newArrayList(previousRnrForm)); Period period = requisitionPeriodService.generateNextPeriod(programMMIA.getProgramCode(), null); assertThat(period.getBegin().toDate(), is(previousRnrForm.getPeriodEnd())); assertThat(new DateTime(period.getEnd()).getMonthOfYear(), is(11)); assertThat(period.getEnd(), is(expectedPeriodEnd)); } @Test public void shouldGeneratePeriodOfJan21ToFebWhenRnrNotExists() throws Exception { when(mockStockMovementRepository.queryEarliestStockMovementDateByProgram(anyString())).thenReturn(new DateTime("2016-02-17").toDate()); Period period = requisitionPeriodService.generateNextPeriod(programMMIA.getProgramCode(), null); assertThat(period.getBegin(), is(new DateTime("2016-01-21"))); assertThat(new DateTime(period.getEnd()).getMonthOfYear(), is(2)); } @Test public void shouldGeneratePeriodOfFeb18ToMarWhenRnrNotExists() throws Exception { when(mockStockMovementRepository.queryEarliestStockMovementDateByProgram(anyString())).thenReturn(DateUtil.parseString("2016-02-18 13:00:00", DateUtil.DATE_TIME_FORMAT)); Period period = requisitionPeriodService.generateNextPeriod(programMMIA.getProgramCode(), null); assertThat(period.getBegin(), is(new DateTime(DateUtil.parseString("2016-02-18 00:00:00", DateUtil.DATE_TIME_FORMAT)))); assertThat(new DateTime(period.getEnd()).getMonthOfYear(), is(3)); } @Test public void shouldGeneratePeriodOfFeb21ToMarWhenRnrNotExists() throws Exception { when(mockStockMovementRepository.queryEarliestStockMovementDateByProgram(anyString())).thenReturn(new DateTime("2016-02-26").toDate()); Period period = requisitionPeriodService.generateNextPeriod(programMMIA.getProgramCode(), null); assertThat(period.getBegin(), is(new DateTime("2016-02-21"))); assertThat(new DateTime(period.getEnd()).getMonthOfYear(), is(3)); } @Test public void shouldReturnTrueWhenPreviousPeriodIsMissed() throws Exception { requisitionPeriodService = spy(requisitionPeriodService); LMISTestApp.getInstance().setCurrentTimeMillis(DateUtil.parseString("2015-05-18 17:30:00", DateUtil.DATE_TIME_FORMAT).getTime()); DateTime nextPeriodBegin = new DateTime(DateUtil.parseString("2015-01-21", DateUtil.DB_DATE_FORMAT)); DateTime nextPeriodEnd = new DateTime(DateUtil.parseString("2015-02-20", DateUtil.DB_DATE_FORMAT)); Period nextPeriodInSchedule = new Period(nextPeriodBegin, nextPeriodEnd); doReturn(nextPeriodInSchedule).when(requisitionPeriodService).generateNextPeriod("P1", null); assertTrue(requisitionPeriodService.hasMissedPeriod("P1")); } @Test public void shouldReturnFalseWhenPreviousPeriodIsNotMissed() throws Exception { requisitionPeriodService = spy(requisitionPeriodService); LMISTestApp.getInstance().setCurrentTimeMillis(DateUtil.parseString("2015-02-25 17:30:00", DateUtil.DATE_TIME_FORMAT).getTime()); DateTime nextPeriodBegin = new DateTime(DateUtil.parseString("2015-01-21", DateUtil.DB_DATE_FORMAT)); DateTime nextPeriodEnd = new DateTime(DateUtil.parseString("2015-02-20", DateUtil.DB_DATE_FORMAT)); Period nextPeriodInSchedule = new Period(nextPeriodBegin, nextPeriodEnd); doReturn(nextPeriodInSchedule).when(requisitionPeriodService).generateNextPeriod("P1", null); assertFalse(requisitionPeriodService.hasMissedPeriod("P1")); } @Test public void shouldGetOffsetPeriodMonthWhenHasMissedPeriod() throws Exception { requisitionPeriodService = spy(requisitionPeriodService); LMISTestApp.getInstance().setCurrentTimeMillis(DateUtil.parseString("2015-05-18 17:30:00", DateUtil.DATE_TIME_FORMAT).getTime()); DateTime nextPeriodBegin = new DateTime(DateUtil.parseString("2015-01-21", DateUtil.DB_DATE_FORMAT)); DateTime nextPeriodEnd = new DateTime(DateUtil.parseString("2015-02-20", DateUtil.DB_DATE_FORMAT)); Period nextPeriodInSchedule = new Period(nextPeriodBegin, nextPeriodEnd); doReturn(nextPeriodInSchedule).when(requisitionPeriodService).generateNextPeriod("P1", null); assertThat(requisitionPeriodService.getMissedPeriodOffsetMonth("P1"), is(4)); } @Test public void shouldGetOffsetPeriodMonthWhenHasNoMissedPeriod() throws Exception { requisitionPeriodService = spy(requisitionPeriodService); LMISTestApp.getInstance().setCurrentTimeMillis(DateUtil.parseString("2015-05-17 17:30:00", DateUtil.DATE_TIME_FORMAT).getTime()); DateTime nextPeriodBegin = new DateTime(DateUtil.parseString("2015-04-21", DateUtil.DB_DATE_FORMAT)); DateTime nextPeriodEnd = new DateTime(DateUtil.parseString("2015-05-20", DateUtil.DB_DATE_FORMAT)); Period nextPeriodInSchedule = new Period(nextPeriodBegin, nextPeriodEnd); doReturn(nextPeriodInSchedule).when(requisitionPeriodService).generateNextPeriod("P1", null); assertThat(requisitionPeriodService.getMissedPeriodOffsetMonth("P1"), is(0)); } @Test public void shouldGetOffsetPeriodIsZeroMonthWhenHasMissedPeriod() throws Exception { requisitionPeriodService = spy(requisitionPeriodService); LMISTestApp.getInstance().setCurrentTimeMillis(DateUtil.parseString("2015-03-17 17:30:00", DateUtil.DATE_TIME_FORMAT).getTime()); DateTime nextPeriodBegin = new DateTime(DateUtil.parseString("2015-01-21", DateUtil.DB_DATE_FORMAT)); DateTime nextPeriodEnd = new DateTime(DateUtil.parseString("2015-02-20", DateUtil.DB_DATE_FORMAT)); Period nextPeriodInSchedule = new Period(nextPeriodBegin, nextPeriodEnd); doReturn(nextPeriodInSchedule).when(requisitionPeriodService).generateNextPeriod("P1", null); assertThat(requisitionPeriodService.getMissedPeriodOffsetMonth("P1"), is(1)); } @Test public void shouldGeneratePeriodOfDes21ToJanWhenRnrNotExists() throws Exception { when(mockStockMovementRepository.queryEarliestStockMovementDateByProgram(anyString())).thenReturn(new DateTime("2016-01-06").toDate()); Period period = requisitionPeriodService.generateNextPeriod(programMMIA.getProgramCode(), null); assertThat(period.getBegin(), is(new DateTime("2015-12-21"))); assertThat(new DateTime(period.getEnd()).getMonthOfYear(), is(1)); } @Test public void shouldGeneratePeriodOfDes19ToJanWhenRnrNotExists() throws Exception { DateTime dateTime = new DateTime("2015-12-19").plusMonths(1); DateTime expectedPeriodEnd = DateUtil.cutTimeStamp(dateTime.withDate(dateTime.getYear(), dateTime.getMonthOfYear(), Period.END_DAY)); when(mockStockMovementRepository.queryEarliestStockMovementDateByProgram(anyString())).thenReturn(new DateTime("2015-12-19").toDate()); Period period = requisitionPeriodService.generateNextPeriod(programMMIA.getProgramCode(), null); assertThat(period.getBegin(), is(new DateTime("2015-12-19"))); assertThat(new DateTime(period.getEnd()).getMonthOfYear(), is(1)); assertThat(period.getEnd(), is(expectedPeriodEnd)); } @Test public void shouldReturnTrueIfRnrFromPreviousPeriodExistsButIsNotAuthorized() throws Exception { requisitionPeriodService = spy(requisitionPeriodService); LMISTestApp.getInstance().setCurrentTimeMillis(DateUtil.parseString("2015-06-18 17:30:00", DateUtil.DATE_TIME_FORMAT).getTime()); DateTime nextPeriodBegin = new DateTime(DateUtil.parseString("2015-05-18", DateUtil.DB_DATE_FORMAT)); DateTime nextPeriodEnd = new DateTime(DateUtil.parseString("2015-06-20", DateUtil.DB_DATE_FORMAT)); Period nextPeriodInSchedule = new Period(nextPeriodBegin, nextPeriodEnd); doReturn(nextPeriodInSchedule).when(requisitionPeriodService).generateNextPeriod("P1", null); RnRForm rnRForm = new RnRForm(); rnRForm.setStatus(RnRForm.STATUS.DRAFT_MISSED); rnRForm.setPeriodBegin(DateUtil.parseString("2015-04-18", DateUtil.DB_DATE_FORMAT)); rnRForm.setPeriodEnd(DateUtil.parseString("2015-05-18", DateUtil.DB_DATE_FORMAT)); when(mockRnrFormRepository.listInclude(RnRForm.Emergency.No, "P1")).thenReturn(newArrayList(rnRForm)); assertTrue(requisitionPeriodService.hasMissedPeriod("P1")); } public class MyTestModule extends AbstractModule { @Override protected void configure() { bind(ProgramRepository.class).toInstance(mockProgramRepository); bind(RnrFormRepository.class).toInstance(mockRnrFormRepository); bind(StockRepository.class).toInstance(mockStockRepository); bind(InventoryRepository.class).toInstance(mockInventoryRepository); bind(StockMovementRepository.class).toInstance(mockStockMovementRepository); } } }