fixed the coverage

This commit is contained in:
Fabio Formosa
2026-05-14 00:48:08 +02:00
parent 40d8c952a0
commit b6529b453a

View File

@@ -0,0 +1,221 @@
package it.fabioformosa.quartzmanager.api.services;
import it.fabioformosa.quartzmanager.api.dto.CalendarDTO;
import it.fabioformosa.quartzmanager.api.dto.CalendarIncludedTimeDTO;
import it.fabioformosa.quartzmanager.api.dto.CalendarType;
import it.fabioformosa.quartzmanager.api.exceptions.CalendarNotFoundException;
import it.fabioformosa.quartzmanager.api.exceptions.ResourceConflictException;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.quartz.Calendar;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.calendar.AnnualCalendar;
import org.quartz.impl.calendar.CronCalendar;
import org.quartz.impl.calendar.DailyCalendar;
import org.quartz.impl.calendar.HolidayCalendar;
import org.quartz.impl.calendar.MonthlyCalendar;
import org.quartz.impl.calendar.WeeklyCalendar;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
class CalendarServiceTest {
@Mock
private Scheduler scheduler;
private CalendarService calendarService;
@BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
calendarService = new CalendarService(scheduler);
}
@Test
void givenCalendarNames_whenCalendarsAreFetched_thenReturnsCalendarDtos() throws SchedulerException {
Mockito.when(scheduler.getCalendarNames()).thenReturn(List.of("weekday"));
WeeklyCalendar weeklyCalendar = new WeeklyCalendar();
weeklyCalendar.setDayExcluded(java.util.Calendar.MONDAY, true);
Mockito.when(scheduler.getCalendar("weekday")).thenReturn(weeklyCalendar);
Mockito.when(scheduler.getTriggerKeys(any())).thenReturn(Set.of());
List<CalendarDTO> calendars = calendarService.fetchCalendars();
Assertions.assertThat(calendars).hasSize(1);
Assertions.assertThat(calendars.get(0).getName()).isEqualTo("weekday");
Assertions.assertThat(calendars.get(0).getType()).isEqualTo(CalendarType.WEEKLY);
Assertions.assertThat(calendars.get(0).getExcludedDaysOfWeek()).contains(java.util.Calendar.MONDAY);
}
@Test
void givenMissingCalendar_whenCalendarIsFetched_thenThrowsNotFound() throws SchedulerException {
Mockito.when(scheduler.getCalendar("missing")).thenReturn(null);
Assertions.assertThatThrownBy(() -> calendarService.getCalendar("missing"))
.isInstanceOf(CalendarNotFoundException.class);
}
@Test
void givenExistingCalendar_whenCalendarIsAdded_thenThrowsConflict() throws SchedulerException {
Mockito.when(scheduler.getCalendar("existing")).thenReturn(new HolidayCalendar());
CalendarDTO calendarDTO = CalendarDTO.builder().type(CalendarType.HOLIDAY).build();
Assertions.assertThatThrownBy(() -> calendarService.addCalendar("existing", calendarDTO))
.isInstanceOf(ResourceConflictException.class);
}
@Test
void givenHolidayCalendar_whenCalendarIsAdded_thenStoresAndReturnsExcludedDates() throws SchedulerException, ParseException {
Date excludedDate = new Date(86_400_000L);
CalendarDTO calendarDTO = CalendarDTO.builder()
.type(CalendarType.HOLIDAY)
.description("holidays")
.excludedDates(List.of(excludedDate))
.build();
Mockito.when(scheduler.getCalendar("holidays")).thenReturn(null);
Mockito.when(scheduler.getTriggerKeys(any())).thenReturn(Set.of());
ArgumentCaptor<Calendar> calendarCaptor = ArgumentCaptor.forClass(Calendar.class);
CalendarDTO result = calendarService.addCalendar("holidays", calendarDTO);
Mockito.verify(scheduler).addCalendar(eq("holidays"), calendarCaptor.capture(), eq(false), eq(false));
Assertions.assertThat(calendarCaptor.getValue()).isInstanceOf(HolidayCalendar.class);
Assertions.assertThat(result.getType()).isEqualTo(CalendarType.HOLIDAY);
Assertions.assertThat(result.getDescription()).isEqualTo("holidays");
Assertions.assertThat(result.getExcludedDates()).hasSize(1);
}
@Test
void givenCronCalendar_whenCalendarIsAdded_thenStoresTimezone() throws SchedulerException, ParseException {
CalendarDTO calendarDTO = CalendarDTO.builder()
.type(CalendarType.CRON)
.cronExpression("0 0 12 * * ?")
.timeZone("UTC")
.build();
Mockito.when(scheduler.getCalendar("cron")).thenReturn(null);
Mockito.when(scheduler.getTriggerKeys(any())).thenReturn(Set.of());
ArgumentCaptor<Calendar> calendarCaptor = ArgumentCaptor.forClass(Calendar.class);
CalendarDTO result = calendarService.addCalendar("cron", calendarDTO);
Mockito.verify(scheduler).addCalendar(eq("cron"), calendarCaptor.capture(), eq(false), eq(false));
Assertions.assertThat(calendarCaptor.getValue()).isInstanceOf(CronCalendar.class);
Assertions.assertThat(result.getCronExpression()).isEqualTo("0 0 12 * * ?");
Assertions.assertThat(result.getTimeZone()).isEqualTo("UTC");
}
@Test
void givenDailyCalendar_whenCalendarIsAdded_thenStoresRange() throws SchedulerException, ParseException {
CalendarDTO calendarDTO = CalendarDTO.builder()
.type(CalendarType.DAILY)
.rangeStartingTime("08:00:00")
.rangeEndingTime("18:30:00")
.invertTimeRange(true)
.build();
Mockito.when(scheduler.getCalendar("daily")).thenReturn(null);
Mockito.when(scheduler.getTriggerKeys(any())).thenReturn(Set.of());
CalendarDTO result = calendarService.addCalendar("daily", calendarDTO);
Assertions.assertThat(result.getType()).isEqualTo(CalendarType.DAILY);
Assertions.assertThat(result.getRangeStartingTime()).isEqualTo("08:00:00");
Assertions.assertThat(result.getRangeEndingTime()).isEqualTo("18:30:00");
Assertions.assertThat(result.getInvertTimeRange()).isTrue();
}
@Test
void givenAnnualMonthlyAndWeeklyCalendars_whenFetched_thenCalendarSpecificFieldsAreMapped() throws SchedulerException {
Date excludedDate = new Date(86_400_000L);
AnnualCalendar annualCalendar = new AnnualCalendar();
java.util.Calendar excludedDay = java.util.Calendar.getInstance(TimeZone.getTimeZone("UTC"));
excludedDay.setTime(excludedDate);
annualCalendar.setDayExcluded(excludedDay, true);
MonthlyCalendar monthlyCalendar = new MonthlyCalendar();
monthlyCalendar.setDayExcluded(10, true);
WeeklyCalendar weeklyCalendar = new WeeklyCalendar();
weeklyCalendar.setDayExcluded(java.util.Calendar.FRIDAY, true);
Mockito.when(scheduler.getTriggerKeys(any())).thenReturn(Set.of());
Mockito.when(scheduler.getCalendar("annual")).thenReturn(annualCalendar);
Mockito.when(scheduler.getCalendar("monthly")).thenReturn(monthlyCalendar);
Mockito.when(scheduler.getCalendar("weekly")).thenReturn(weeklyCalendar);
Assertions.assertThat(calendarService.getCalendar("annual").getExcludedDates()).hasSize(1);
Assertions.assertThat(calendarService.getCalendar("monthly").getExcludedDaysOfMonth()).containsExactly(10);
Assertions.assertThat(calendarService.getCalendar("weekly").getExcludedDaysOfWeek()).contains(java.util.Calendar.FRIDAY);
}
@Test
void givenCalendarUsedByTrigger_whenCalendarIsFetched_thenTriggerKeysAreIncluded() throws SchedulerException {
HolidayCalendar holidayCalendar = new HolidayCalendar();
TriggerKey triggerKey = TriggerKey.triggerKey("trigger", "group");
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(triggerKey)
.modifiedByCalendar("holidays")
.build();
Mockito.when(scheduler.getCalendar("holidays")).thenReturn(holidayCalendar);
Mockito.when(scheduler.getTriggerKeys(any())).thenReturn(Set.of(triggerKey));
Mockito.when(scheduler.getTrigger(triggerKey)).thenReturn(trigger);
CalendarDTO result = calendarService.getCalendar("holidays");
Assertions.assertThat(result.getTriggerKeys()).hasSize(1);
Assertions.assertThat(result.getTriggerKeys().get(0).getName()).isEqualTo("trigger");
Assertions.assertThat(result.getTriggerKeys().get(0).getGroup()).isEqualTo("group");
}
@Test
void givenCalendar_whenIncludedTimeIsTested_thenReturnsIncludedAndNextIncludedTime() throws SchedulerException {
HolidayCalendar holidayCalendar = new HolidayCalendar();
Date excludedDate = new Date(86_400_000L);
holidayCalendar.addExcludedDate(excludedDate);
Mockito.when(scheduler.getCalendar("holidays")).thenReturn(holidayCalendar);
CalendarIncludedTimeDTO result = calendarService.testIncludedTime("holidays", CalendarIncludedTimeDTO.builder().time(excludedDate).build());
Assertions.assertThat(result.getIncluded()).isFalse();
Assertions.assertThat(result.getNextIncludedTime()).isAfter(excludedDate);
}
@Test
void givenMissingCalendar_whenDeleted_thenThrowsNotFound() throws SchedulerException {
Mockito.when(scheduler.deleteCalendar("missing")).thenReturn(false);
Assertions.assertThatThrownBy(() -> calendarService.deleteCalendar("missing"))
.isInstanceOf(CalendarNotFoundException.class);
}
@Test
void givenExistingCalendar_whenUpdated_thenReplacesCalendar() throws SchedulerException, ParseException {
Mockito.when(scheduler.getCalendar("monthly")).thenReturn(new MonthlyCalendar());
Mockito.when(scheduler.getTriggerKeys(any())).thenReturn(Set.of());
CalendarDTO calendarDTO = CalendarDTO.builder()
.type(CalendarType.MONTHLY)
.excludedDaysOfMonth(Set.of(3, 9))
.build();
CalendarDTO result = calendarService.updateCalendar("monthly", calendarDTO);
Mockito.verify(scheduler).addCalendar(eq("monthly"), any(Calendar.class), eq(true), eq(true));
Assertions.assertThat(result.getExcludedDaysOfMonth()).containsExactly(3, 9);
}
}