package org.synyx.urlaubsverwaltung.web.statistics; import org.joda.time.DateMidnight; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.synyx.urlaubsverwaltung.core.account.domain.Account; import org.synyx.urlaubsverwaltung.core.account.service.AccountService; import org.synyx.urlaubsverwaltung.core.account.service.VacationDaysService; import org.synyx.urlaubsverwaltung.core.application.domain.Application; import org.synyx.urlaubsverwaltung.core.application.domain.ApplicationStatus; import org.synyx.urlaubsverwaltung.core.application.domain.VacationType; import org.synyx.urlaubsverwaltung.core.application.service.ApplicationService; import org.synyx.urlaubsverwaltung.core.application.service.VacationTypeService; import org.synyx.urlaubsverwaltung.core.overtime.OvertimeService; import org.synyx.urlaubsverwaltung.core.period.DayLength; import org.synyx.urlaubsverwaltung.core.person.Person; import org.synyx.urlaubsverwaltung.core.workingtime.WorkDaysService; import org.synyx.urlaubsverwaltung.test.TestDataCreator; import java.math.BigDecimal; import java.util.Arrays; import java.util.List; import java.util.Optional; /** * Unit test for {@link org.synyx.urlaubsverwaltung.web.statistics.ApplicationForLeaveStatisticsBuilder}. * * @author Aljona Murygina - murygina@synyx.de */ public class ApplicationForLeaveStatisticsBuilderTest { private AccountService accountService; private ApplicationService applicationService; private WorkDaysService calendarService; private VacationDaysService vacationDaysService; private OvertimeService overtimeService; private VacationTypeService vacationTypeService; private ApplicationForLeaveStatisticsBuilder builder; private List<VacationType> vacationTypes; @Before public void setUp() { accountService = Mockito.mock(AccountService.class); applicationService = Mockito.mock(ApplicationService.class); calendarService = Mockito.mock(WorkDaysService.class); vacationDaysService = Mockito.mock(VacationDaysService.class); overtimeService = Mockito.mock(OvertimeService.class); vacationTypeService = Mockito.mock(VacationTypeService.class); vacationTypes = TestDataCreator.createVacationTypes(); Mockito.when(vacationTypeService.getVacationTypes()).thenReturn(vacationTypes); builder = new ApplicationForLeaveStatisticsBuilder(accountService, applicationService, calendarService, vacationDaysService, overtimeService, vacationTypeService); } @Test(expected = IllegalArgumentException.class) public void ensureThrowsIfTheGivenPersonIsNull() { builder.build(null, new DateMidnight(2015, 1, 1), new DateMidnight(2015, 12, 31)); } @Test(expected = IllegalArgumentException.class) public void ensureThrowsIfTheGivenFromDateIsNull() { builder.build(Mockito.mock(Person.class), null, new DateMidnight(2015, 12, 31)); } @Test(expected = IllegalArgumentException.class) public void ensureThrowsIfTheGivenToDateIsNull() { builder.build(Mockito.mock(Person.class), new DateMidnight(2014, 1, 1), null); } @Test(expected = IllegalArgumentException.class) public void ensureThrowsIfTheGivenFromAndToDatesAreNotInTheSameYear() { builder.build(Mockito.mock(Person.class), new DateMidnight(2014, 1, 1), new DateMidnight(2015, 1, 1)); } @Test public void ensureUsesWaitingAndAllowedVacationOfAllHolidayTypesToBuildStatistics() { DateMidnight from = new DateMidnight(2014, 1, 1); DateMidnight to = new DateMidnight(2014, 12, 31); Person person = Mockito.mock(Person.class); Account account = Mockito.mock(Account.class); Mockito.when(person.getEmail()).thenReturn("muster@firma.test"); Mockito.when(accountService.getHolidaysAccount(2014, person)).thenReturn(Optional.of(account)); Mockito.when(vacationDaysService.calculateTotalLeftVacationDays(Mockito.eq(account))) .thenReturn(BigDecimal.TEN); Mockito.when(overtimeService.getLeftOvertimeForPerson(person)).thenReturn(new BigDecimal("9")); Application holidayWaiting = new Application(); holidayWaiting.setVacationType(vacationTypes.get(0)); holidayWaiting.setStartDate(new DateMidnight(2014, 10, 13)); holidayWaiting.setEndDate(new DateMidnight(2014, 10, 13)); holidayWaiting.setStatus(ApplicationStatus.WAITING); holidayWaiting.setPerson(person); Application holidayTemporaryAllowed = new Application(); holidayTemporaryAllowed.setVacationType(vacationTypes.get(0)); holidayTemporaryAllowed.setStartDate(new DateMidnight(2014, 10, 12)); holidayTemporaryAllowed.setEndDate(new DateMidnight(2014, 10, 12)); holidayTemporaryAllowed.setStatus(ApplicationStatus.TEMPORARY_ALLOWED); holidayTemporaryAllowed.setPerson(person); Application holidayAllowed = new Application(); holidayAllowed.setVacationType(vacationTypes.get(0)); holidayAllowed.setStartDate(new DateMidnight(2014, 10, 14)); holidayAllowed.setEndDate(new DateMidnight(2014, 10, 14)); holidayAllowed.setStatus(ApplicationStatus.ALLOWED); holidayAllowed.setPerson(person); Application holidayRejected = new Application(); holidayRejected.setVacationType(vacationTypes.get(0)); holidayRejected.setStartDate(new DateMidnight(2014, 11, 6)); holidayRejected.setEndDate(new DateMidnight(2014, 11, 6)); holidayRejected.setStatus(ApplicationStatus.REJECTED); holidayRejected.setPerson(person); Application specialLeaveWaiting = new Application(); specialLeaveWaiting.setVacationType(vacationTypes.get(1)); specialLeaveWaiting.setStartDate(new DateMidnight(2014, 10, 15)); specialLeaveWaiting.setEndDate(new DateMidnight(2014, 10, 15)); specialLeaveWaiting.setStatus(ApplicationStatus.WAITING); specialLeaveWaiting.setPerson(person); Application unpaidLeaveAllowed = new Application(); unpaidLeaveAllowed.setVacationType(vacationTypes.get(2)); unpaidLeaveAllowed.setStartDate(new DateMidnight(2014, 10, 16)); unpaidLeaveAllowed.setEndDate(new DateMidnight(2014, 10, 16)); unpaidLeaveAllowed.setStatus(ApplicationStatus.ALLOWED); unpaidLeaveAllowed.setPerson(person); Application overTimeWaiting = new Application(); overTimeWaiting.setVacationType(vacationTypes.get(3)); overTimeWaiting.setStartDate(new DateMidnight(2014, 11, 3)); overTimeWaiting.setEndDate(new DateMidnight(2014, 11, 3)); overTimeWaiting.setStatus(ApplicationStatus.WAITING); overTimeWaiting.setPerson(person); List<Application> applications = Arrays.asList(holidayWaiting, holidayTemporaryAllowed, holidayAllowed, holidayRejected, specialLeaveWaiting, unpaidLeaveAllowed, overTimeWaiting); Mockito.when(applicationService.getApplicationsForACertainPeriodAndPerson(from, to, person)) .thenReturn(applications); // just return 1 day for each application for leave Mockito.when(calendarService.getWorkDays(Mockito.any(DayLength.class), Mockito.any(DateMidnight.class), Mockito.any(DateMidnight.class), Mockito.eq(person))) .thenReturn(BigDecimal.ONE); ApplicationForLeaveStatistics statistics = builder.build(person, from, to); // PERSON Assert.assertNotNull("Person should not be null", statistics.getPerson()); Assert.assertEquals("Wrong person", person, statistics.getPerson()); // VACATION DAYS Assert.assertNotNull("Waiting vacation days should not be null", statistics.getTotalWaitingVacationDays()); Assert.assertNotNull("Allowed vacation days should not be null", statistics.getTotalAllowedVacationDays()); Assert.assertNotNull("Left vacation days should not be null", statistics.getLeftVacationDays()); Assert.assertEquals("Wrong number of waiting vacation days", new BigDecimal("4"), statistics.getTotalWaitingVacationDays()); Assert.assertEquals("Wrong number of allowed vacation days", new BigDecimal("2"), statistics.getTotalAllowedVacationDays()); Assert.assertEquals("Wrong number of left vacation days", BigDecimal.TEN, statistics.getLeftVacationDays()); } @Test public void ensureCallsCalendarServiceToCalculatePartialVacationDaysOfVacationsSpanningTwoYears() { DateMidnight from = new DateMidnight(2015, 1, 1); DateMidnight to = new DateMidnight(2015, 12, 31); Person person = Mockito.mock(Person.class); Account account = Mockito.mock(Account.class); Mockito.when(person.getEmail()).thenReturn("muster@firma.test"); Mockito.when(accountService.getHolidaysAccount(2015, person)).thenReturn(Optional.of(account)); Mockito.when(vacationDaysService.calculateTotalLeftVacationDays(Mockito.eq(account))) .thenReturn(BigDecimal.TEN); Mockito.when(overtimeService.getLeftOvertimeForPerson(person)).thenReturn(new BigDecimal("9")); Application holidayAllowed = new Application(); holidayAllowed.setVacationType(vacationTypes.get(0)); holidayAllowed.setStartDate(new DateMidnight(2014, 12, 29)); holidayAllowed.setEndDate(new DateMidnight(2015, 1, 9)); holidayAllowed.setStatus(ApplicationStatus.ALLOWED); holidayAllowed.setDayLength(DayLength.FULL); holidayAllowed.setPerson(person); Application holidayWaiting = new Application(); holidayWaiting.setVacationType(vacationTypes.get(0)); holidayWaiting.setStartDate(new DateMidnight(2015, 12, 21)); holidayWaiting.setEndDate(new DateMidnight(2016, 1, 4)); holidayWaiting.setStatus(ApplicationStatus.WAITING); holidayWaiting.setDayLength(DayLength.FULL); holidayWaiting.setPerson(person); List<Application> applications = Arrays.asList(holidayWaiting, holidayAllowed); Mockito.when(applicationService.getApplicationsForACertainPeriodAndPerson(from, to, person)) .thenReturn(applications); Mockito.when(calendarService.getWorkDays(DayLength.FULL, new DateMidnight(2015, 1, 1), new DateMidnight(2015, 1, 9), person)) .thenReturn(new BigDecimal("5")); Mockito.when(calendarService.getWorkDays(DayLength.FULL, new DateMidnight(2015, 12, 21), new DateMidnight(2015, 12, 31), person)) .thenReturn(new BigDecimal("7")); ApplicationForLeaveStatistics statistics = builder.build(person, from, to); // VACATION DAYS Assert.assertNotNull("Waiting vacation days should not be null", statistics.getTotalWaitingVacationDays()); Assert.assertNotNull("Allowed vacation days should not be null", statistics.getTotalAllowedVacationDays()); Assert.assertNotNull("Left vacation days should not be null", statistics.getLeftVacationDays()); Assert.assertEquals("Wrong number of waiting vacation days", new BigDecimal("7"), statistics.getTotalWaitingVacationDays()); Assert.assertEquals("Wrong number of allowed vacation days", new BigDecimal("5"), statistics.getTotalAllowedVacationDays()); Assert.assertEquals("Wrong number of left vacation days", BigDecimal.TEN, statistics.getLeftVacationDays()); } @Test public void ensureCalculatesLeftVacationDaysAndLeftOvertimeCorrectly() { DateMidnight from = new DateMidnight(2015, 1, 1); DateMidnight to = new DateMidnight(2015, 12, 31); Person person = Mockito.mock(Person.class); Account account = Mockito.mock(Account.class); Mockito.when(accountService.getHolidaysAccount(2015, person)).thenReturn(Optional.of(account)); Mockito.when(overtimeService.getLeftOvertimeForPerson(person)).thenReturn(new BigDecimal("6.5")); Mockito.when(vacationDaysService.calculateTotalLeftVacationDays(account)).thenReturn(new BigDecimal("8.5")); ApplicationForLeaveStatistics statistics = builder.build(person, from, to); Assert.assertEquals("Wrong left overtime", new BigDecimal("6.5"), statistics.getLeftOvertime()); Assert.assertEquals("Wrong left vacation days", new BigDecimal("8.5"), statistics.getLeftVacationDays()); Mockito.verify(overtimeService).getLeftOvertimeForPerson(person); Mockito.verify(vacationDaysService).calculateTotalLeftVacationDays(account); } }