diff --git a/src/main/java/org/folio/rest/utils/CalendarUtils.java b/src/main/java/org/folio/rest/utils/CalendarUtils.java index cfc07f72..2d2b5c65 100644 --- a/src/main/java/org/folio/rest/utils/CalendarUtils.java +++ b/src/main/java/org/folio/rest/utils/CalendarUtils.java @@ -107,12 +107,42 @@ private static Map getOpeningDays(OpeningPeriod en EnumMap openingDays = new EnumMap(DayOfWeek.class); for (OpeningDayWeekDay openingDay : entity.getOpeningDays()) { - openingDays.put(DayOfWeek.valueOf(openingDay.getWeekdays().getDay().toString()), openingDay); + if (!isOverlap(openingDay.getOpeningDay().getOpeningHour())) { + openingDays.put(DayOfWeek.valueOf(openingDay.getWeekdays().getDay().toString()), openingDay); + } else { + throw new OverlapIntervalException("Intervals can not overlap."); + } } - return openingDays; } + private static boolean isOverlap(List openingHours) + { + // Sort intervals in increasing order of start time + openingHours.sort(Comparator.comparingInt(hours -> toMinutes(hours.getStartTime()))); + + // In the sorted array, if start time of an interval + // is less than end of previous interval, then there is an overlap + for (int i = 1; i < openingHours.size(); i++) { + if (toMinutes(openingHours.get(i - 1).getEndTime()) > toMinutes(openingHours.get(i).getStartTime())) { + return true; + } + } + return false; + } + + /** + * @param time H:m timestamp, i.e. [Hour in day (0-23)]:[Minute in hour (0-59)] + * @return total minutes after 00:00 + */ + private static int toMinutes(String time) { + String[] hourMin = time.split(":"); + int hour = Integer.parseInt(hourMin[0]); + int minutes = Integer.parseInt(hourMin[1]); + int hoursInMinutes = hour * 60; + return hoursInMinutes + minutes; + } + private static List createEvents(OpeningDay openingDay, Calendar actualDay, String generatedId, boolean isExceptional) { Calendar currentStartDate = Calendar.getInstance(TimeZone.getTimeZone(ZoneOffset.UTC)); currentStartDate.setTimeInMillis(actualDay.getTimeInMillis()); diff --git a/src/test/java/org/folio/rest/impl/CalendarIT.java b/src/test/java/org/folio/rest/impl/CalendarIT.java index 01522434..575ad540 100644 --- a/src/test/java/org/folio/rest/impl/CalendarIT.java +++ b/src/test/java/org/folio/rest/impl/CalendarIT.java @@ -68,8 +68,8 @@ public class CalendarIT { private static final Logger log = LoggerFactory.getLogger(CalendarIT.class); private static final String ERROR_CODE_INTERVALS_OVERLAP = "intervalsOverlap"; - private static final String ERROR_MESSAGE_EXCEPTION_PERIOD_INTERVALS_OVERLAP = "Intervals can not overlap."; - private static final String ERROR_MESSAGE_OPENING_PERIOD_INTERVALS_OVERLAP = "Intervals can The date range entered overlaps " + + private static final String ERROR_MESSAGE_INTERVALS_CANNOT_OVERLAP = "Intervals can not overlap."; + private static final String ERROR_MESSAGE_OPENING_PERIOD_INTERVALS_OVERLAP = "The date range entered overlaps " + "with another calendar for this service point. Please correct the date range or enter the hours as exceptions."; private static int port; @@ -151,7 +151,9 @@ public void checkEndpointsTest() { public void addNewPeriodTest() { String uuid = UUID.randomUUID().toString(); String servicePointUUID = UUID.randomUUID().toString(); - OpeningPeriod opening = generateDescription(2017, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, true, true, false); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); + OpeningPeriod opening = generateDescription(2017, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, + true, true, false, openingHours); postPeriod(servicePointUUID, opening); @@ -167,7 +169,9 @@ public void addNewPeriodTest() { public void addInvalidPeriodTest() { String uuid = UUID.randomUUID().toString(); String servicePointUUID = UUID.randomUUID().toString(); - OpeningPeriod opening = generateDescription(2017, Calendar.JANUARY, 1, 0, servicePointUUID, uuid, true, true, false); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); + OpeningPeriod opening = generateDescription(2017, Calendar.JANUARY, 1, 0, servicePointUUID, uuid, + true, true, false, openingHours); postPeriod(servicePointUUID, opening); @@ -183,7 +187,9 @@ public void addInvalidPeriodTest() { public void addNewPeriodWithoutServicePoint() { String uuid = UUID.randomUUID().toString(); String servicePointUUID = UUID.randomUUID().toString(); - OpeningPeriod opening = generateDescription(2017, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, true, true, false); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); + OpeningPeriod opening = generateDescription(2017, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, + true, true, false, openingHours); opening.setServicePointId(null); postWithHeaderAndBody(opening, "/calendar/periods/" + servicePointUUID + "/period") .then() @@ -196,7 +202,9 @@ public void addNewPeriodWithoutServicePoint() { public void getPeriodsWithServicePointIdTest() { String uuid = UUID.randomUUID().toString(); String servicePointUUID = UUID.randomUUID().toString(); - OpeningPeriod opening = generateDescription(2018, Calendar.AUGUST, 27, 8, servicePointUUID, uuid, true, true, false); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); + OpeningPeriod opening = generateDescription(2018, Calendar.AUGUST, 27, 8, servicePointUUID, uuid, + true, true, false, openingHours); postPeriod(servicePointUUID, opening); @@ -212,7 +220,9 @@ public void getPeriodsWithServicePointIdTest() { public void getPeriodsWithIncludedDateRange() { String uuid = UUID.randomUUID().toString(); String servicePointUUID = UUID.randomUUID().toString(); - OpeningPeriod opening = generateDescription(2018, Calendar.AUGUST, 27, 8, servicePointUUID, uuid, true, true, false); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); + OpeningPeriod opening = generateDescription(2018, Calendar.AUGUST, 27, 8, servicePointUUID, uuid, + true, true, false, openingHours); postPeriod(servicePointUUID, opening); @@ -228,7 +238,10 @@ public void getPeriodsWithIncludedDateRange() { public void getPeriodsWithExcludedDateRange() { String uuid = UUID.randomUUID().toString(); String servicePointUUID = UUID.randomUUID().toString(); - OpeningPeriod opening = generateDescription(2018, Calendar.AUGUST, 27, 8, servicePointUUID, uuid, true, true, false); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); + + OpeningPeriod opening = generateDescription(2018, Calendar.AUGUST, 27, 8, servicePointUUID, uuid, + true, true, false, openingHours); postPeriod(servicePointUUID, opening); @@ -252,7 +265,10 @@ private void postPeriod(String servicePointUUID, OpeningPeriod opening) { public void getPeriodWithOpeningDaysTest() { String uuid = UUID.randomUUID().toString(); String servicePointUUID = UUID.randomUUID().toString(); - OpeningPeriod opening = generateDescription(2018, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, true, true, false); + + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); + OpeningPeriod opening = generateDescription(2018, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, + true, true, false, openingHours); postPeriod(servicePointUUID, opening); @@ -285,7 +301,9 @@ public void testGetCalendarPeriodsCalculateOpening() { public void getPeriodsExceptionalTest() { String uuid = UUID.randomUUID().toString(); String servicePointUUID = UUID.randomUUID().toString(); - OpeningPeriod opening = generateDescription(2019, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, true, false, true); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); + OpeningPeriod opening = generateDescription(2019, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, + true, false, true, openingHours); postPeriod(servicePointUUID, opening); @@ -301,7 +319,10 @@ public void getPeriodsExceptionalTest() { public void postExceptionalTest() { String uuid = UUID.randomUUID().toString(); String servicePointUUID = UUID.randomUUID().toString(); - OpeningPeriod opening = generateDescription(2019, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, null, false, true); + + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); + OpeningPeriod opening = generateDescription(2019, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, + null, false, true, openingHours); postPeriod(servicePointUUID, opening); @@ -319,7 +340,9 @@ public void deletePeriodTest() { String servicePointUUID = UUID.randomUUID().toString(); // create a new period - OpeningPeriod opening = generateDescription(2020, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, true, true, true); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); + OpeningPeriod opening = generateDescription(2020, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, + true, true, true, openingHours); postPeriod(servicePointUUID, opening); // check created period @@ -359,7 +382,10 @@ public void deleteNotExistPeriodTest() { public void overlappingPeriodsTest() { String uuid = UUID.randomUUID().toString(); String servicePointUUID = UUID.randomUUID().toString(); - OpeningPeriod opening = generateDescription(2017, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, false, true, false); + + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); + OpeningPeriod opening = generateDescription(2017, Calendar.JANUARY, 1, 7, servicePointUUID, uuid, + false, true, false, openingHours); postPeriod(servicePointUUID, opening); @@ -373,7 +399,7 @@ public void overlappingPeriodsTest() { postWithHeaderAndBody(opening, "/calendar/periods/" + servicePointUUID + "/period") .then() .contentType(ContentType.JSON) - .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_EXCEPTION_PERIOD_INTERVALS_OVERLAP))) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_INTERVALS_CANNOT_OVERLAP))) .statusCode(422); } @@ -383,8 +409,9 @@ public void canCreateExceptionalPeriodWithoutOverlapping() { // create a new calendar String uuid = UUID.randomUUID().toString(); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod opening = generateDescription(2020, Calendar.MARCH, 1, 5, - servicePointUUID, uuid, true, true, false); + servicePointUUID, uuid, true, true, false, openingHours); postPeriod(servicePointUUID, opening); createExceptionalExistingPeriod(servicePointUUID); @@ -392,7 +419,7 @@ public void canCreateExceptionalPeriodWithoutOverlapping() { // save a new exceptional period String newIdExPeriod = UUID.randomUUID().toString(); OpeningPeriod newExceptionalPeriod = generateDescription(2020, Calendar.MARCH, 6, 1, - servicePointUUID, newIdExPeriod, true, true, true); + servicePointUUID, newIdExPeriod, true, true, true, openingHours); postWithHeaderAndBody(newExceptionalPeriod, "/calendar/periods/" + servicePointUUID + "/period") .then() .statusCode(201); @@ -403,12 +430,13 @@ public void cannotCreateExceptionalPeriodWithOverlappingAtTheBeginning() { String servicePointUUID = UUID.randomUUID().toString(); createExceptionalExistingPeriod(servicePointUUID); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod invalidExceptionalPeriod = generateDescription(2020, Calendar.MARCH, 3, 3, - servicePointUUID, UUID.randomUUID().toString(), true, false, true); + servicePointUUID, UUID.randomUUID().toString(), true, false, true, openingHours); postWithHeaderAndBody(invalidExceptionalPeriod, "/calendar/periods/" + servicePointUUID + "/period") .then() .contentType(ContentType.JSON) - .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_EXCEPTION_PERIOD_INTERVALS_OVERLAP))) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_INTERVALS_CANNOT_OVERLAP))) .statusCode(422); } @@ -417,12 +445,13 @@ public void cannotCreateExceptionalPeriodWithOverlappingAtTheEnd() { String servicePointUUID = UUID.randomUUID().toString(); createExceptionalExistingPeriod(servicePointUUID); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod invalidExceptionalPeriod = generateDescription(2020, Calendar.FEBRUARY, 28, 3, - servicePointUUID, UUID.randomUUID().toString(), true, false, true); + servicePointUUID, UUID.randomUUID().toString(), true, false, true, openingHours); postWithHeaderAndBody(invalidExceptionalPeriod, "/calendar/periods/" + servicePointUUID + "/period") .then() .contentType(ContentType.JSON) - .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_EXCEPTION_PERIOD_INTERVALS_OVERLAP))) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_INTERVALS_CANNOT_OVERLAP))) .statusCode(422); } @@ -431,12 +460,13 @@ public void cannotCreateExceptionalPeriodInsideOverlapping() { String servicePointUUID = UUID.randomUUID().toString(); createExceptionalExistingPeriod(servicePointUUID); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod invalidExceptionalPeriod = generateDescription(2020, Calendar.MARCH, 2, 2, - servicePointUUID, UUID.randomUUID().toString(), true, false, true); + servicePointUUID, UUID.randomUUID().toString(), true, false, true, openingHours); postWithHeaderAndBody(invalidExceptionalPeriod, "/calendar/periods/" + servicePointUUID + "/period") .then() .contentType(ContentType.JSON) - .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_EXCEPTION_PERIOD_INTERVALS_OVERLAP))) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_INTERVALS_CANNOT_OVERLAP))) .statusCode(422); } @@ -445,12 +475,13 @@ public void cannotCreateExceptionalPeriodWithTotalOverlapping() { String servicePointUUID = UUID.randomUUID().toString(); createExceptionalExistingPeriod(servicePointUUID); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod invalidExceptionalPeriod = generateDescription(2020, Calendar.FEBRUARY, 28, 10, - servicePointUUID, UUID.randomUUID().toString(), true, false, true); + servicePointUUID, UUID.randomUUID().toString(), true, false, true, openingHours); postWithHeaderAndBody(invalidExceptionalPeriod, "/calendar/periods/" + servicePointUUID + "/period") .then() .contentType(ContentType.JSON) - .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_EXCEPTION_PERIOD_INTERVALS_OVERLAP))) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_INTERVALS_CANNOT_OVERLAP))) .statusCode(422); } @@ -458,8 +489,9 @@ public void cannotCreateExceptionalPeriodWithTotalOverlapping() { public void putPeriodTest() { String uuid = UUID.randomUUID().toString(); String servicePointUUID = UUID.randomUUID().toString(); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod opening = generateDescription(2017, Calendar.JANUARY, 1, 7, - servicePointUUID, uuid, true, false, true); + servicePointUUID, uuid, true, false, true, openingHours); postPeriod(servicePointUUID, opening); @@ -490,17 +522,18 @@ public void putPeriodTest() { public void cannotUpdateOverlappingExceptionalPeriod() { String servicePointUUID = UUID.randomUUID().toString(); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod existingOpening = generateDescription(2020, Calendar.JANUARY, 1, 7, - servicePointUUID, UUID.randomUUID().toString(), true, false, true); + servicePointUUID, UUID.randomUUID().toString(), true, false, true, openingHours); postPeriod(servicePointUUID, existingOpening); String uuid = UUID.randomUUID().toString(); OpeningPeriod opening = generateDescription(2020, Calendar.JANUARY, 10, 7, - servicePointUUID, uuid, true, false, true); + servicePointUUID, uuid, true, false, true, openingHours); postPeriod(servicePointUUID, opening); OpeningPeriod invalidUpdatedOpening = generateDescription(2020, Calendar.JANUARY, 4, 7, - servicePointUUID, uuid, true, false, true); + servicePointUUID, uuid, true, false, true, openingHours); getWithHeaderAndBody("/calendar/periods/" + servicePointUUID + "/period/" + uuid) .then() @@ -512,7 +545,7 @@ public void cannotUpdateOverlappingExceptionalPeriod() { putWithHeaderAndBody(invalidUpdatedOpening.withName("PUT_TEST"), "/calendar/periods/" + servicePointUUID + "/period/" + uuid) .then() - .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_EXCEPTION_PERIOD_INTERVALS_OVERLAP))) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_INTERVALS_CANNOT_OVERLAP))) .statusCode(422); } @@ -521,8 +554,9 @@ public void cannotCreateOpeningPeriodWithOverlappingAtTheBeginning() { String servicePointUUID = UUID.randomUUID().toString(); createWorkingHoursExistingPeriod(servicePointUUID); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod invalidOpeningPeriod = generateDescription(2020, Calendar.MARCH, 3, 3, - servicePointUUID, UUID.randomUUID().toString(), true, false, false); + servicePointUUID, UUID.randomUUID().toString(), true, false, false, openingHours); postWithHeaderAndBody(invalidOpeningPeriod, "/calendar/periods/" + servicePointUUID + "/period") .then() .contentType(ContentType.JSON) @@ -535,12 +569,13 @@ public void cannotCreateOpeningPeriodWithOverlappingAtTheEnd() { String servicePointUUID = UUID.randomUUID().toString(); createWorkingHoursExistingPeriod(servicePointUUID); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod invalidOpeningPeriod = generateDescription(2020, Calendar.FEBRUARY, 28, 3, - servicePointUUID, UUID.randomUUID().toString(), true, false, false); + servicePointUUID, UUID.randomUUID().toString(), true, false, false, openingHours); postWithHeaderAndBody(invalidOpeningPeriod, "/calendar/periods/" + servicePointUUID + "/period") .then() .contentType(ContentType.JSON) - .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_EXCEPTION_PERIOD_INTERVALS_OVERLAP))) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_OPENING_PERIOD_INTERVALS_OVERLAP))) .statusCode(422); } @@ -549,12 +584,13 @@ public void cannotCreateOpeningPeriodInsideOverlapping() { String servicePointUUID = UUID.randomUUID().toString(); createWorkingHoursExistingPeriod(servicePointUUID); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod invalidOpeningPeriod = generateDescription(2020, Calendar.MARCH, 2, 2, - servicePointUUID, UUID.randomUUID().toString(), true, false, false); + servicePointUUID, UUID.randomUUID().toString(), true, false, false, openingHours); postWithHeaderAndBody(invalidOpeningPeriod, "/calendar/periods/" + servicePointUUID + "/period") .then() .contentType(ContentType.JSON) - .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_EXCEPTION_PERIOD_INTERVALS_OVERLAP))) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_OPENING_PERIOD_INTERVALS_OVERLAP))) .statusCode(422); } @@ -563,16 +599,64 @@ public void cannotCreateOpeningPeriodWithTotalOverlapping() { String servicePointUUID = UUID.randomUUID().toString(); createWorkingHoursExistingPeriod(servicePointUUID); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod invalidOpeningPeriod = generateDescription(2020, Calendar.FEBRUARY, 28, 10, - servicePointUUID, UUID.randomUUID().toString(), true, false, false); + servicePointUUID, UUID.randomUUID().toString(), true, false, false, openingHours); postWithHeaderAndBody(invalidOpeningPeriod, "/calendar/periods/" + servicePointUUID + "/period") .then() .contentType(ContentType.JSON) - .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_EXCEPTION_PERIOD_INTERVALS_OVERLAP))) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_OPENING_PERIOD_INTERVALS_OVERLAP))) .statusCode(422); } - private OpeningPeriod generateDescription(int startYear, int month, int day, int numberOfDays, String servicePointId, String uuid, Boolean isAllDay, boolean isOpen, boolean isExceptional) { + @Test + public void cannotCreateWorkingHoursWithOverlappingAtTheEnd() { + String servicePointUUID = UUID.randomUUID().toString(); + + List openingHoursWithOverlapping = prepareOpeningHours("08:00", "14:00", "12:00", "16:00"); + OpeningPeriod invalidOpeningPeriodWithOverlapping = generateDescription(2020, Calendar.JANUARY, 8, 2, + servicePointUUID, UUID.randomUUID().toString(), false, true, false, openingHoursWithOverlapping); + + postWithHeaderAndBody(invalidOpeningPeriodWithOverlapping, "/calendar/periods/" + servicePointUUID + "/period") + .then() + .contentType(ContentType.JSON) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_INTERVALS_CANNOT_OVERLAP))) + .statusCode(422); + } + + @Test + public void cannotCreateWorkingHoursWithOverlappingAtTheBeginning() { + String servicePointUUID = UUID.randomUUID().toString(); + + List openingHoursWithOverlapping = prepareOpeningHours("08:00", "14:00", "06:00", "09:00"); + OpeningPeriod invalidOpeningPeriodWithOverlapping = generateDescription(2020, Calendar.JANUARY, 8, 2, + servicePointUUID, UUID.randomUUID().toString(), false, true, false, openingHoursWithOverlapping); + + postWithHeaderAndBody(invalidOpeningPeriodWithOverlapping, "/calendar/periods/" + servicePointUUID + "/period") + .then() + .contentType(ContentType.JSON) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_INTERVALS_CANNOT_OVERLAP))) + .statusCode(422); + } + + @Test + public void cannotCreateWorkingHoursWithTotalOverlapping() { + String servicePointUUID = UUID.randomUUID().toString(); + + List openingHoursWithOverlapping = prepareOpeningHours("08:00", "14:00", "10:00", "12:00"); + OpeningPeriod invalidOpeningPeriodWithOverlapping = generateDescription(2020, Calendar.JANUARY, 8, 2, + servicePointUUID, UUID.randomUUID().toString(), false, true, false, openingHoursWithOverlapping); + + postWithHeaderAndBody(invalidOpeningPeriodWithOverlapping, "/calendar/periods/" + servicePointUUID + "/period") + .then() + .contentType(ContentType.JSON) + .assertThat().body(matchesJsonSchema(errIntervalsOverlapSchema(ERROR_MESSAGE_INTERVALS_CANNOT_OVERLAP))) + .statusCode(422); + } + + private OpeningPeriod generateDescription( + int startYear, int month, int day, int numberOfDays, String servicePointId, String uuid, Boolean isAllDay, + boolean isOpen, boolean isExceptional, List openingHours) { List openingDays = new ArrayList<>(); Calendar startDate = createStartDate(startYear, month, day); Calendar endDate = createEndDate(startDate, numberOfDays); @@ -582,33 +666,41 @@ private OpeningPeriod generateDescription(int startYear, int month, int day, int openingPeriod.setEndDate(endDate.getTime()); openingPeriod.setServicePointId(servicePointId); openingPeriod.setName("test"); - createAndAddOpeningDay(openingDays, Weekdays.Day.MONDAY, isAllDay, isOpen, isExceptional); + createAndAddOpeningDay(openingDays, Weekdays.Day.MONDAY, isAllDay, isOpen, isExceptional, openingHours); openingPeriod.setOpeningDays(openingDays); return openingPeriod; } - private void createAndAddOpeningDay(List openingDays, Weekdays.Day day, Boolean isAllDay, boolean isOpen, boolean isExceptional) { + private void createAndAddOpeningDay( + List openingDays, Weekdays.Day day, Boolean isAllDay, boolean isOpen, boolean isExceptional, List openingHours) { OpeningDayWeekDay opening = new OpeningDayWeekDay(); OpeningDay openingDay = new OpeningDay().withAllDay(isAllDay).withOpen(isOpen).withExceptional(isExceptional); - List openingHours = new ArrayList<>(); if (!isExceptional) { opening.setWeekdays(new Weekdays().withDay(day)); - OpeningHour openingHour = new OpeningHour(); - openingHour.setStartTime("08:00"); - openingHour.setEndTime("12:00"); - openingHours.add(openingHour); - openingHour.setStartTime("13:00"); - openingHour.setEndTime("17:00"); - openingHours.add(openingHour); } else { openingDay.setAllDay(true); } openingDay.setOpeningHour(openingHours); opening.setOpeningDay(openingDay); - openingDays.add(opening); } + private List prepareOpeningHours( + String startFirstPeriod, String endFirstPeriod, String startSecondPeriod, String endSecondPeriod) { + + List openingHours = new ArrayList<>(); + OpeningHour firstOpeningHour = new OpeningHour(); + firstOpeningHour.setStartTime(startFirstPeriod); + firstOpeningHour.setEndTime(endFirstPeriod); + openingHours.add(firstOpeningHour); + OpeningHour secondOpeningHour = new OpeningHour(); + secondOpeningHour.setStartTime(startSecondPeriod); + secondOpeningHour.setEndTime(endSecondPeriod); + openingHours.add(secondOpeningHour); + + return openingHours; + } + private Calendar createStartDate(int startYear, int month, int day) { Calendar startDate = Calendar.getInstance(TimeZone.getTimeZone("UTC")); startDate.clear(); @@ -661,15 +753,17 @@ private RequestSpecification restGivenWithHeader() { private void createExceptionalExistingPeriod(String servicePointUUID) { String uuidExPeriod = UUID.randomUUID().toString(); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod exceptionalPeriod = generateDescription(2020, Calendar.MARCH, 1, - 3, servicePointUUID, uuidExPeriod, true, false, true); + 3, servicePointUUID, uuidExPeriod, true, false, true, openingHours); postPeriod(servicePointUUID, exceptionalPeriod); } private void createWorkingHoursExistingPeriod(String servicePointUUID) { String uuidExPeriod = UUID.randomUUID().toString(); + List openingHours = prepareOpeningHours("08:00", "12:00", "13:00", "17:00"); OpeningPeriod openingPeriod = generateDescription(2020, Calendar.MARCH, 1, - 3, servicePointUUID, uuidExPeriod, true, false, false); + 3, servicePointUUID, uuidExPeriod, true, false, false, openingHours); postPeriod(servicePointUUID, openingPeriod); }