Skip to content

Commit 2a23911

Browse files
authored
fix: extra 30-minute buffer was added to 60-minute slots without it being set (calcom#24087)
* fix: 30 min buffer added on 60 min slots * update * fix test * Update restrictionSchedule.test.ts * addressed test * Update getSchedule.test.ts
1 parent 5aa24c8 commit 2a23911

4 files changed

Lines changed: 75 additions & 80 deletions

File tree

apps/web/test/lib/getSchedule.test.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,10 +1244,9 @@ describe("getSchedule", () => {
12441244

12451245
expect(scheduleForEventWithBookingNotice13Hrs).toHaveTimeSlots(
12461246
[
1247-
/*`04:00:00.000Z`, `06:00:00.000Z`, - Minimum time slot is 07:30 UTC which is 13hrs from 18:30*/
1248-
`08:00:00.000Z`,
1249-
`10:00:00.000Z`,
1250-
`12:00:00.000Z`,
1247+
/*`03:30:00.000Z`, `05:30:00.000Z`, - Minimum time slot is 07:30 UTC which is 13hrs from 18:30*/
1248+
`07:30:00.000Z`,
1249+
`09:30:00.000Z`,
12511250
],
12521251
{
12531252
dateString: todayDateString,
@@ -1267,10 +1266,11 @@ describe("getSchedule", () => {
12671266
});
12681267
expect(scheduleForEventWithBookingNotice10Hrs).toHaveTimeSlots(
12691268
[
1270-
/*`04:00:00.000Z`, - Minimum bookable time slot is 04:30 UTC which is 10hrs from 18:30 */
1271-
`05:00:00.000Z`,
1272-
`07:00:00.000Z`,
1273-
`09:00:00.000Z`,
1269+
/*`03:30:00.000Z`, - Minimum bookable time slot is 04:30 UTC which is 10hrs from 18:30 */
1270+
`04:30:00.000Z`,
1271+
`06:30:00.000Z`,
1272+
`08:30:00.000Z`,
1273+
`10:30:00.000Z`,
12741274
],
12751275
{
12761276
dateString: todayDateString,
@@ -1334,11 +1334,9 @@ describe("getSchedule", () => {
13341334

13351335
expect(scheduleForEventOnADayWithNonCalBooking).toHaveTimeSlots(
13361336
[
1337-
// `04:00:00.000Z`, // - 4 AM is booked
1338-
// `06:00:00.000Z`, // - 6 AM is not available because 08:00AM slot has a `beforeEventBuffer`
1339-
`08:00:00.000Z`, // - 8 AM is available because of availability of 06:00 - 07:59
1340-
`10:00:00.000Z`,
1341-
`12:00:00.000Z`,
1337+
// `05:30:00.000Z`, // - 5:30 AM is not available because 08:30AM slot has a `beforeEventBuffer`
1338+
`08:30:00.000Z`, // - 8:30 AM is available (2 PM IST)
1339+
`10:30:00.000Z`,
13421340
],
13431341
{
13441342
dateString: plus3DateString,
@@ -1412,11 +1410,9 @@ describe("getSchedule", () => {
14121410

14131411
expect(scheduleForEventOnADayWithCalBooking).toHaveTimeSlots(
14141412
[
1415-
// `04:00:00.000Z`, // - 4 AM is booked
1416-
// `06:00:00.000Z`, // - 6 AM is not available because of afterBuffer(120 mins) of the existing booking(4-5:59AM slot)
1417-
// `08:00:00.000Z`, // - 8 AM is not available because of beforeBuffer(120mins) of possible booking at 08:00
1418-
`10:00:00.000Z`,
1419-
`12:00:00.000Z`,
1413+
// `05:30:00.000Z`, // - 5:30 AM is not available because of afterBuffer(120 mins) of the existing booking(4:00-5:59AM slot)
1414+
// `08:30:00.000Z`, // - 8:30 AM is not available because of beforeBuffer(120mins) of possible booking at 08:30
1415+
`10:30:00.000Z`,
14201416
],
14211417
{
14221418
dateString: plus2DateString,

apps/web/test/lib/getSchedule/futureLimit.timezone.test.ts

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -673,26 +673,26 @@ describe("getSchedule", () => {
673673
});
674674

675675
const allTimeSlotsForToday = [
676-
"2024-05-31T11:30:00.000Z",
677-
"2024-06-01T04:30:00.000Z",
678-
"2024-06-01T05:30:00.000Z",
679-
"2024-06-01T06:30:00.000Z",
680-
"2024-06-01T07:30:00.000Z",
681-
"2024-06-01T08:30:00.000Z",
682-
"2024-06-01T09:30:00.000Z",
683-
"2024-06-01T10:30:00.000Z",
676+
"2024-05-31T11:00:00.000Z",
677+
"2024-06-01T04:00:00.000Z",
678+
"2024-06-01T05:00:00.000Z",
679+
"2024-06-01T06:00:00.000Z",
680+
"2024-06-01T07:00:00.000Z",
681+
"2024-06-01T08:00:00.000Z",
682+
"2024-06-01T09:00:00.000Z",
683+
"2024-06-01T10:00:00.000Z",
684684
];
685685

686686
expect(scheduleForEvent).toHaveTimeSlots(
687687
[
688-
// "2024-05-30T04:30:00.000Z", // Not available as before the start of the range
689-
"2024-05-31T04:30:00.000Z",
690-
"2024-05-31T05:30:00.000Z",
691-
"2024-05-31T06:30:00.000Z",
692-
"2024-05-31T07:30:00.000Z",
693-
"2024-05-31T08:30:00.000Z",
694-
"2024-05-31T09:30:00.000Z",
695-
"2024-05-31T10:30:00.000Z",
688+
// "2024-05-30T04:00:00.000Z", // Not available as before the start of the range
689+
"2024-05-31T04:00:00.000Z",
690+
"2024-05-31T05:00:00.000Z",
691+
"2024-05-31T06:00:00.000Z",
692+
"2024-05-31T07:00:00.000Z",
693+
"2024-05-31T08:00:00.000Z",
694+
"2024-05-31T09:00:00.000Z",
695+
"2024-05-31T10:00:00.000Z",
696696
],
697697
{
698698
dateString: yesterdayDateString,
@@ -1634,13 +1634,13 @@ describe("getSchedule", () => {
16341634

16351635
expect(scheduleForEventForPagoTz).toHaveTimeSlots(
16361636
[
1637-
"2024-07-25T04:30:00.000Z",
1638-
"2024-07-25T05:30:00.000Z",
1639-
"2024-07-25T06:30:00.000Z",
1640-
"2024-07-25T07:30:00.000Z",
1641-
"2024-07-25T08:30:00.000Z",
1642-
"2024-07-25T09:30:00.000Z",
1643-
"2024-07-25T10:30:00.000Z",
1637+
"2024-07-25T04:00:00.000Z",
1638+
"2024-07-25T05:00:00.000Z",
1639+
"2024-07-25T06:00:00.000Z",
1640+
"2024-07-25T07:00:00.000Z",
1641+
"2024-07-25T08:00:00.000Z",
1642+
"2024-07-25T09:00:00.000Z",
1643+
"2024-07-25T10:00:00.000Z",
16441644
],
16451645
{
16461646
// 25th timeslots are shown mostly on 24th of Pago Pago
@@ -1651,22 +1651,22 @@ describe("getSchedule", () => {
16511651

16521652
expect(scheduleForEventForPagoTz).toHaveTimeSlots(
16531653
[
1654-
"2024-07-25T11:30:00.000Z",
1655-
"2024-07-26T04:30:00.000Z",
1656-
"2024-07-26T05:30:00.000Z",
1657-
"2024-07-26T06:30:00.000Z",
1658-
"2024-07-26T07:30:00.000Z",
1659-
"2024-07-26T08:30:00.000Z",
1660-
"2024-07-26T09:30:00.000Z",
1661-
"2024-07-26T10:30:00.000Z",
1654+
"2024-07-25T11:00:00.000Z",
1655+
"2024-07-26T04:00:00.000Z",
1656+
"2024-07-26T05:00:00.000Z",
1657+
"2024-07-26T06:00:00.000Z",
1658+
"2024-07-26T07:00:00.000Z",
1659+
"2024-07-26T08:00:00.000Z",
1660+
"2024-07-26T09:00:00.000Z",
1661+
"2024-07-26T10:00:00.000Z",
16621662
],
16631663
{
16641664
dateString: "2024-07-25",
16651665
doExactMatch: true,
16661666
}
16671667
);
16681668

1669-
expect(scheduleForEventForPagoTz).toHaveTimeSlots(["2024-07-26T11:30:00.000Z"], {
1669+
expect(scheduleForEventForPagoTz).toHaveTimeSlots(["2024-07-26T11:00:00.000Z"], {
16701670
dateString: "2024-07-26",
16711671
doExactMatch: true,
16721672
});

apps/web/test/lib/getSchedule/restrictionSchedule.test.ts

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,11 @@ describe("getSchedule", () => {
173173
// - User availability: 9 AM - 5 PM London
174174
// - Restriction: 10 AM - 6 PM Dubai
175175
const expectedUtcSlots = [
176-
"2025-06-02T08:00:00.000Z", // 9 AM London, 12 PM Dubai, 1:30 PM Kolkata
177-
"2025-06-02T09:00:00.000Z", // 10 AM London, 1 PM Dubai, 2:30 PM Kolkata
178-
"2025-06-02T10:00:00.000Z", // 11 AM London, 2 PM Dubai, 3:30 PM Kolkata
179-
"2025-06-02T11:00:00.000Z", // 12 PM London, 3 PM Dubai, 4:30 PM Kolkata
180-
"2025-06-02T12:00:00.000Z", // 1 PM London, 4 PM Dubai, 5:30 PM Kolkata
181-
"2025-06-02T13:00:00.000Z", // 2 PM London, 5 PM Dubai, 6:30 PM Kolkata
182-
"2025-06-02T14:00:00.000Z", // 3 PM London, 6 PM Dubai, 7:30 PM Kolkata
176+
"2025-06-02T08:30:00.000Z", // 9:30 AM London, 12:30 PM Dubai, 2:00 PM Kolkata
177+
"2025-06-02T09:30:00.000Z", // 10:30 AM London, 1:30 PM Dubai, 3:00 PM Kolkata
178+
"2025-06-02T10:30:00.000Z", // 11:30 AM London, 2:30 PM Dubai, 4:00 PM Kolkata
179+
"2025-06-02T11:30:00.000Z", // 12:30 PM London, 3:30 PM Dubai, 5:00 PM Kolkata
180+
"2025-06-02T12:30:00.000Z", // 1:30 PM London, 4:30 PM Dubai, 6:00 PM Kolkata
183181
];
184182

185183
expect(result).toHaveTimeSlots(expectedUtcSlots, {
@@ -269,12 +267,11 @@ describe("getSchedule", () => {
269267
// - User availability: 9 AM - 5 PM London
270268
// - Restriction: 10 AM - 6 PM Dubai, weekdays only
271269
const getExpectedSlotsForDate = (dateString: string) => [
272-
`${dateString}T08:00:00.000Z`, // 9 AM London, 12 PM Dubai, 1:30 PM Kolkata
273-
`${dateString}T09:00:00.000Z`, // 10 AM London, 1 PM Dubai, 2:30 PM Kolkata
274-
`${dateString}T10:00:00.000Z`, // 11 AM London, 2 PM Dubai, 3:30 PM Kolkata
275-
`${dateString}T11:00:00.000Z`, // 12 PM London, 3 PM Dubai, 4:30 PM Kolkata
276-
`${dateString}T12:00:00.000Z`, // 1 PM London, 4 PM Dubai, 5:30 PM Kolkata
277-
`${dateString}T13:00:00.000Z`, // 2 PM London, 5 PM Dubai, 6:30 PM Kolkata
270+
`${dateString}T08:30:00.000Z`, // 9:30 AM London, 12:30 PM Dubai, 2:00 PM Kolkata
271+
`${dateString}T09:30:00.000Z`, // 10:30 AM London, 1:30 PM Dubai, 3:00 PM Kolkata
272+
`${dateString}T10:30:00.000Z`, // 11:30 AM London, 2:30 PM Dubai, 4:00 PM Kolkata
273+
`${dateString}T11:30:00.000Z`, // 12:30 PM London, 3:30 PM Dubai, 5:00 PM Kolkata
274+
`${dateString}T12:30:00.000Z`, // 1:30 PM London, 4:30 PM Dubai, 6:00 PM Kolkata
278275
];
279276

280277
// Verify weekday slots
@@ -370,11 +367,10 @@ describe("getSchedule", () => {
370367
// - User availability: 9 AM - 5 PM London (1:30 PM - 9:30 PM Kolkata)
371368
// - Restriction: 10 AM - 6 PM Kolkata
372369
const getExpectedSlotsForDate = (dateString: string) => [
373-
`${dateString}T08:00:00.000Z`, // 1:30 PM Kolkata, 9 AM London
374-
`${dateString}T09:00:00.000Z`, // 2:30 PM Kolkata, 10 AM London
375-
`${dateString}T10:00:00.000Z`, // 3:30 PM Kolkata, 11 AM London
376-
`${dateString}T11:00:00.000Z`, // 4:30 PM Kolkata, 12 PM London
377-
`${dateString}T12:00:00.000Z`, // 5:30 PM Kolkata, 1 PM London
370+
`${dateString}T08:30:00.000Z`, // 2:00 PM Kolkata, 9:30 AM London
371+
`${dateString}T09:30:00.000Z`, // 3:00 PM Kolkata, 10:30 AM London
372+
`${dateString}T10:30:00.000Z`, // 4:00 PM Kolkata, 11:30 AM London
373+
`${dateString}T11:30:00.000Z`, // 5:00 PM Kolkata, 12:30 PM London
378374
];
379375

380376
// Verify weekday slots
@@ -453,15 +449,13 @@ describe("getSchedule", () => {
453449

454450
// Expected slots based on user's availability: 9 AM - 5 PM London
455451
const getExpectedSlotsForDate = (dateString: string) => [
456-
`${dateString}T08:00:00.000Z`, // 9 AM London, 1:30 PM Kolkata
457-
`${dateString}T09:00:00.000Z`, // 10 AM London, 2:30 PM Kolkata
458-
`${dateString}T10:00:00.000Z`, // 11 AM London, 3:30 PM Kolkata
459-
`${dateString}T11:00:00.000Z`, // 12 PM London, 4:30 PM Kolkata
460-
`${dateString}T12:00:00.000Z`, // 1 PM London, 5:30 PM Kolkata
461-
`${dateString}T13:00:00.000Z`, // 2 PM London, 6:30 PM Kolkata
462-
`${dateString}T14:00:00.000Z`, // 3 PM London, 7:30 PM Kolkata
463-
`${dateString}T15:00:00.000Z`, // 4 PM London, 8:30 PM Kolkata
464-
`${dateString}T16:00:00.000Z`, // 5 PM London, 9:30 PM Kolkata
452+
`${dateString}T08:30:00.000Z`, // 9:30 AM London, 2:00 PM Kolkata
453+
`${dateString}T09:30:00.000Z`, // 10:30 AM London, 3:00 PM Kolkata
454+
`${dateString}T10:30:00.000Z`, // 11:30 AM London, 4:00 PM Kolkata
455+
`${dateString}T11:30:00.000Z`, // 12:30 PM London, 5:00 PM Kolkata
456+
`${dateString}T12:30:00.000Z`, // 1:30 PM London, 6:00 PM Kolkata
457+
`${dateString}T13:30:00.000Z`, // 2:30 PM London, 7:00 PM Kolkata
458+
`${dateString}T14:30:00.000Z`, // 3:30 PM London, 8:00 PM Kolkata
465459
];
466460

467461
// Verify weekday slots
@@ -472,8 +466,8 @@ describe("getSchedule", () => {
472466
});
473467
});
474468

475-
// Verify a late evening slot (8:30 PM Kolkata, 4 PM London) is present
476-
const lateEveningSlot = `${plus2DateString}T15:00:00.000Z`;
469+
// Verify a late evening slot (8:00 PM Kolkata, 3:30 PM London) is present
470+
const lateEveningSlot = `${plus2DateString}T14:30:00.000Z`;
477471
expect(result.slots[plus2DateString].map((s) => s.time)).toContain(lateEveningSlot);
478472
});
479473
});

packages/lib/slots.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ function buildSlotsWithDateRanges({
131131

132132
// For current day bookings, normalizing the seconds to zero to avoid issues with time calculations
133133
slotStartTime = slotStartTime.set("second", 0).set("millisecond", 0);
134+
135+
// Convert to target timezone BEFORE checking if rounding is needed
136+
// This ensures we check minute alignment in the local timezone, not UTC
137+
// This prevents issues with half-hour offset timezones like Asia/Kolkata (GMT+5:30)
138+
slotStartTime = slotStartTime.tz(timeZone);
134139

135140
if (slotStartTime.minute() % interval !== 0) {
136141
slotStartTime = getCorrectedSlotStartTime({
@@ -141,7 +146,7 @@ function buildSlotsWithDateRanges({
141146
});
142147
}
143148

144-
slotStartTime = slotStartTime.add(offsetStart ?? 0, "minutes").tz(timeZone);
149+
slotStartTime = slotStartTime.add(offsetStart ?? 0, "minutes");
145150

146151
// Find the nearest appropriate slot boundary if this time falls within an existing slot
147152
const slotBoundariesValueArray = Array.from(slotBoundaries.keys());

0 commit comments

Comments
 (0)