* add Add Group button * add host groups to schema * UI for host groups * raname groups to hostGroups * schema update * show groups in assignment tab * add no group hosts to Group 1 * add dummy group for non group hosts * fix type errors * use two dimensional array for luckyUserPools * fix empty array * group RR hosts in handleNewBooking * improve logic for grouping lucky users * find all lucky users of all groups * allow several RR hosts on booking * clean up migrations * create helper function * group hosts for slots logic * add group logic to loading available slots * adding hosts to groups * add groupId to hostSchema * disable hosts from other groups * handle groups in checkedTeamSelect * fix adding hosts to groups * remove and add groups * show hosts if there are no groups * fixing adding first group with existing hosts * show groups empty groups correctly * UI upddate fixes * fix adding hosts to existing first host group * small fixes + code clean up * add availability fix with test * create new round-robin test file * disable reassignment * fix losing fixed hosts * fix updating weights and priorities * disable load balancing with Round Robin Groups * automatically disable load balancing in update handler * allRRHosts should only include hosts from same group * fix type errors * fix type error * fix tests * fix type error * remove undefined from groupId type * type changes * add tests for hostGroups * add tests for host groups * fixes * fix type errors with undefined groupId * remove seperate host groups prop * fix editing weights * remove console.log * code clean up * improve getAggregatedAvailability tests * throw error when no available hosts in a group * add fixme comment * create constant for DEFAULT_GROUP_ID * clean up code * mock default_group_id for unit tests * don't show fixed hosts in edit weights side bar * add DEFAULT_GROUP_ID to mock test-setup * remove unused index variable * code clean up * fix updating host groups * fix imports * add default_group_id to mocks * add uuid() to zod schema * remove unused code * fix singular translation key * remove unnessary !! * Revert formatting changes * add additional tests for bookingActions * use createMany * import DEFAULT_GROUP_ID for mocks * fix mocks * clean up EventTeamAssignmentTab * fix type errors in tests * fix mocks * remove constants.example.test.ts * fix type error * add missing groupId * fix margin * clean up empty host groups * fix constants mock * useCalback * use reduce * extract handlers into seperate functions * fix handler functions * fix border radius * fix type error in CheckForEmptyAssignment * fix type error --------- Co-authored-by: CarinaWolli <wollencarina@gmail.com>
473 lines
17 KiB
TypeScript
473 lines
17 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
|
|
import type { Dayjs } from "@calcom/dayjs";
|
|
import dayjs from "@calcom/dayjs";
|
|
|
|
import { getAggregatedAvailability } from "./getAggregatedAvailability";
|
|
|
|
// Helper to check if a time range overlaps with availability
|
|
const isAvailable = (availability: { start: Dayjs; end: Dayjs }[], range: { start: Dayjs; end: Dayjs }) => {
|
|
return availability.some(({ start, end }) => {
|
|
return start <= range.start && end >= range.end;
|
|
});
|
|
};
|
|
|
|
describe("getAggregatedAvailability", () => {
|
|
// rr-host availability used to combine into erroneous slots, this confirms it no longer happens
|
|
it("should not merge RR availability resulting in an unavailable slot due to overlap", () => {
|
|
const userAvailability = [
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:20:00.000Z") },
|
|
{ start: dayjs("2025-01-23T16:10:00.000Z"), end: dayjs("2025-01-23T16:30:00.000Z") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:15:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
{ start: dayjs("2025-01-23T13:20:00.000Z"), end: dayjs("2025-01-23T13:30:00.000Z") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
];
|
|
|
|
const result = getAggregatedAvailability(userAvailability, "ROUND_ROBIN");
|
|
const timeRangeToCheckBusy = {
|
|
start: dayjs("2025-01-23T11:00:00.000Z"),
|
|
end: dayjs("2025-01-23T11:30:00.000Z"),
|
|
};
|
|
|
|
expect(isAvailable(result, timeRangeToCheckBusy)).toBe(false);
|
|
|
|
const timeRangeToCheckAvailable = {
|
|
start: dayjs("2025-01-23T11:00:00.000Z"),
|
|
end: dayjs("2025-01-23T11:20:00.000Z"),
|
|
};
|
|
|
|
expect(isAvailable(result, timeRangeToCheckAvailable)).toBe(true);
|
|
});
|
|
|
|
it("it returns the right amount of date ranges even if the end time is before the start time", () => {
|
|
const userAvailability = [
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-27T14:00:00.000Z"), end: dayjs("2025-01-27T04:30-05:00") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-27T14:00:00.000Z"), end: dayjs("2025-01-27T14:45:00.000Z") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
];
|
|
|
|
const result = getAggregatedAvailability(userAvailability, "ROUND_ROBIN");
|
|
|
|
expect(result).toEqual([
|
|
{
|
|
start: dayjs("2025-01-27T14:00:00.000Z"),
|
|
end: dayjs("2025-01-27T09:30:00.000Z"),
|
|
},
|
|
{
|
|
start: dayjs("2025-01-27T14:00:00.000Z"),
|
|
end: dayjs("2025-01-27T14:45:00.000Z"),
|
|
},
|
|
]);
|
|
});
|
|
|
|
// validates fixed host behaviour, they all have to be available
|
|
it("correctly joins fixed host availability resulting in one or more combined date ranges", () => {
|
|
const userAvailability = [
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:20:00.000Z") },
|
|
{ start: dayjs("2025-01-23T16:10:00.000Z"), end: dayjs("2025-01-23T16:30:00.000Z") },
|
|
],
|
|
user: { isFixed: true },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:15:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
{ start: dayjs("2025-01-23T13:20:00.000Z"), end: dayjs("2025-01-23T13:30:00.000Z") },
|
|
],
|
|
user: { isFixed: true },
|
|
},
|
|
];
|
|
|
|
const result = getAggregatedAvailability(userAvailability, "ROUND_ROBIN");
|
|
const timeRangeToCheckBusy = {
|
|
start: dayjs("2025-01-23T11:00:00.000Z"),
|
|
end: dayjs("2025-01-23T11:30:00.000Z"),
|
|
};
|
|
|
|
expect(isAvailable(result, timeRangeToCheckBusy)).toBe(false);
|
|
|
|
expect(result[0].start.format()).toEqual(dayjs("2025-01-23T11:15:00.000Z").format());
|
|
expect(result[0].end.format()).toEqual(dayjs("2025-01-23T11:20:00.000Z").format());
|
|
});
|
|
|
|
// Combines rr hosts and fixed hosts, both fixed and one of the rr hosts has to be available for the whole period
|
|
// All fixed user ranges are merged with each rr-host
|
|
it("Fixed hosts and at least one rr host available between 11:00-11:30 & 12:30-13:00 on January 23, 2025", () => {
|
|
// Both fixed user A and B are available 11:00-11:30 & 12:30-13:00 & 13:15-13:30
|
|
// Only user C (rr) is available 11:00-11:30 and only user D (rr) is available 12:30-13:00
|
|
// No rr users are available 13:15-13:30 and this date range should not be a result.
|
|
const userAvailability = [
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
{ start: dayjs("2025-01-23T12:30:00.000Z"), end: dayjs("2025-01-23T13:00:00.000Z") },
|
|
{ start: dayjs("2025-01-23T13:15:00.000Z"), end: dayjs("2025-01-23T13:30:00.000Z") },
|
|
{ start: dayjs("2025-01-23T16:10:00.000Z"), end: dayjs("2025-01-23T16:30:00.000Z") },
|
|
],
|
|
user: { isFixed: true },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
{ start: dayjs("2025-01-23T12:30:00.000Z"), end: dayjs("2025-01-23T13:00:00.000Z") },
|
|
{ start: dayjs("2025-01-23T13:15:00.000Z"), end: dayjs("2025-01-23T13:30:00.000Z") },
|
|
{ start: dayjs("2025-01-23T13:20:00.000Z"), end: dayjs("2025-01-23T13:30:00.000Z") },
|
|
],
|
|
user: { isFixed: true },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T12:30:00.000Z"), end: dayjs("2025-01-23T13:00:00.000Z") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
];
|
|
|
|
const result = getAggregatedAvailability(userAvailability, "ROUND_ROBIN");
|
|
const timeRangeToCheckAvailable = {
|
|
start: dayjs("2025-01-23T11:00:00.000Z"),
|
|
end: dayjs("2025-01-23T11:30:00.000Z"),
|
|
};
|
|
|
|
expect(isAvailable(result, timeRangeToCheckAvailable)).toBe(true);
|
|
|
|
expect(result[0].start.format()).toEqual(dayjs("2025-01-23T11:00:00.000Z").format());
|
|
expect(result[0].end.format()).toEqual(dayjs("2025-01-23T11:30:00.000Z").format());
|
|
expect(result[1].start.format()).toEqual(dayjs("2025-01-23T12:30:00.000Z").format());
|
|
expect(result[1].end.format()).toEqual(dayjs("2025-01-23T13:00:00.000Z").format());
|
|
});
|
|
|
|
it("does not duplicate slots when multiple rr-hosts offer the same availability", () => {
|
|
const userAvailability = [
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
{ start: dayjs("2025-01-23T12:30:00.000Z"), end: dayjs("2025-01-23T13:00:00.000Z") },
|
|
{ start: dayjs("2025-01-23T13:15:00.000Z"), end: dayjs("2025-01-23T13:30:00.000Z") },
|
|
{ start: dayjs("2025-01-23T16:10:00.000Z"), end: dayjs("2025-01-23T16:30:00.000Z") },
|
|
],
|
|
user: { isFixed: true },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
];
|
|
|
|
const result = getAggregatedAvailability(userAvailability, "ROUND_ROBIN");
|
|
const timeRangeToCheckAvailable = {
|
|
start: dayjs("2025-01-23T11:00:00.000Z"),
|
|
end: dayjs("2025-01-23T11:30:00.000Z"),
|
|
};
|
|
|
|
expect(isAvailable(result, timeRangeToCheckAvailable)).toBe(true);
|
|
expect(result.length).toBe(1);
|
|
});
|
|
|
|
it("requires at least one RR host from each group to be available", () => {
|
|
// Test scenario with two groups:
|
|
// Group 1: Host A (available 11:00-11:30), Host B (available 12:00-12:30)
|
|
// Group 2: Host C (available 11:15-11:45), Host D (available 12:15-12:45)
|
|
// Fixed host: available 11:00-13:00
|
|
// Expected: Only slots where at least one host from each group is available
|
|
const userAvailability = [
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T13:00:00.000Z") },
|
|
],
|
|
user: { isFixed: true },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
],
|
|
user: { isFixed: false, groupId: "group1" },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T12:00:00.000Z"), end: dayjs("2025-01-23T12:30:00.000Z") },
|
|
],
|
|
user: { isFixed: false, groupId: "group1" },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:15:00.000Z"), end: dayjs("2025-01-23T11:45:00.000Z") },
|
|
],
|
|
user: { isFixed: false, groupId: "group2" },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T12:15:00.000Z"), end: dayjs("2025-01-23T12:45:00.000Z") },
|
|
],
|
|
user: { isFixed: false, groupId: "group2" },
|
|
},
|
|
];
|
|
|
|
const result = getAggregatedAvailability(userAvailability, "ROUND_ROBIN");
|
|
|
|
const timeRangeAvailable = {
|
|
start: dayjs("2025-01-23T11:15:00.000Z"),
|
|
end: dayjs("2025-01-23T11:30:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeAvailable)).toBe(true);
|
|
|
|
const timeRangeAvailable2 = {
|
|
start: dayjs("2025-01-23T12:15:00.000Z"),
|
|
end: dayjs("2025-01-23T12:30:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeAvailable2)).toBe(true);
|
|
|
|
// Should NOT be available when only one group has hosts available
|
|
const timeRangeNotAvailable = {
|
|
start: dayjs("2025-01-23T11:00:00.000Z"),
|
|
end: dayjs("2025-01-23T11:15:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeNotAvailable)).toBe(false);
|
|
|
|
// Should NOT be available when only one group has hosts available
|
|
const timeRangeNotAvailable2 = {
|
|
start: dayjs("2025-01-23T12:30:00.000Z"),
|
|
end: dayjs("2025-01-23T12:45:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeNotAvailable2)).toBe(false);
|
|
});
|
|
|
|
it("handles single group with multiple RR hosts (union behavior)", () => {
|
|
// Test that when all RR hosts are in the same group, we get union behavior
|
|
// Host A: available 11:00-11:20, 16:10-16:30
|
|
// Host B: available 11:15-11:30, 13:20-13:30
|
|
// Expected: Union of both hosts' availability
|
|
const userAvailability = [
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:20:00.000Z") },
|
|
{ start: dayjs("2025-01-23T16:10:00.000Z"), end: dayjs("2025-01-23T16:30:00.000Z") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:15:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
{ start: dayjs("2025-01-23T13:20:00.000Z"), end: dayjs("2025-01-23T13:30:00.000Z") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
];
|
|
|
|
const result = getAggregatedAvailability(userAvailability, "ROUND_ROBIN");
|
|
|
|
// Should be available when either host is available
|
|
const timeRangeAvailable = {
|
|
start: dayjs("2025-01-23T11:00:00.000Z"),
|
|
end: dayjs("2025-01-23T11:20:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeAvailable)).toBe(true);
|
|
|
|
const timeRangeAvailable2 = {
|
|
start: dayjs("2025-01-23T13:20:00.000Z"),
|
|
end: dayjs("2025-01-23T13:30:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeAvailable2)).toBe(true);
|
|
|
|
// Should NOT be available when neither host is available
|
|
const timeRangeNotAvailable = {
|
|
start: dayjs("2025-01-23T11:00:00.000Z"),
|
|
end: dayjs("2025-01-23T11:30:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeNotAvailable)).toBe(false);
|
|
});
|
|
|
|
it("handles mixed groups with some hosts having groupId and others not", () => {
|
|
// Test scenario:
|
|
// Group 1: Host A (available 11:00-11:45)
|
|
// Group 2: Host B (available 11:15-12:00)
|
|
// Default group: Host C (available 11:30-12:30), Host D (available 12:15-12:45)
|
|
// Fixed host: available 11:00-13:00
|
|
|
|
const userAvailability = [
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T13:00:00.000Z") },
|
|
],
|
|
user: { isFixed: true },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:45:00.000Z") },
|
|
],
|
|
user: { isFixed: false, groupId: "group1" },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:15:00.000Z"), end: dayjs("2025-01-23T12:00:00.000Z") },
|
|
],
|
|
user: { isFixed: false, groupId: "group2" },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:30:00.000Z"), end: dayjs("2025-01-23T12:30:00.000Z") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T12:15:00.000Z"), end: dayjs("2025-01-23T12:45:00.000Z") },
|
|
],
|
|
user: { isFixed: false },
|
|
},
|
|
];
|
|
|
|
const result = getAggregatedAvailability(userAvailability, "ROUND_ROBIN");
|
|
|
|
// Should be available when all groups have at least one host available
|
|
// Fixed host + Group 1 + Group 2 + Default group all available in this time range
|
|
const timeRangeAvailable = {
|
|
start: dayjs("2025-01-23T11:30:00.000Z"),
|
|
end: dayjs("2025-01-23T11:45:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeAvailable)).toBe(true);
|
|
|
|
// Should NOT be available when not all groups have hosts available
|
|
// Only Group 1, Group 2, and fixed host available, but Default group not available
|
|
const timeRangeNotAvailable = {
|
|
start: dayjs("2025-01-23T11:15:00.000Z"),
|
|
end: dayjs("2025-01-23T11:30:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeNotAvailable)).toBe(false);
|
|
|
|
// Should NOT be available when not all groups have hosts available
|
|
// Only Group 1 and fixed host available, Group 2 and Default group not available
|
|
const timeRangeNotAvailable2 = {
|
|
start: dayjs("2025-01-23T11:00:00.000Z"),
|
|
end: dayjs("2025-01-23T11:15:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeNotAvailable2)).toBe(false);
|
|
|
|
// Should NOT be available when not all groups have hosts available
|
|
// Only Group 2 and fixed host available, Group 1 and Default group not available
|
|
const timeRangeNotAvailable3 = {
|
|
start: dayjs("2025-01-23T11:45:00.000Z"),
|
|
end: dayjs("2025-01-23T12:00:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeNotAvailable3)).toBe(false);
|
|
});
|
|
|
|
it("handles empty groups gracefully", () => {
|
|
// Test scenario with empty groups
|
|
const userAvailability = [
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
],
|
|
user: { isFixed: true },
|
|
},
|
|
];
|
|
|
|
const result = getAggregatedAvailability(userAvailability, "ROUND_ROBIN");
|
|
|
|
// Should only have fixed host availability
|
|
const timeRangeAvailable = {
|
|
start: dayjs("2025-01-23T11:00:00.000Z"),
|
|
end: dayjs("2025-01-23T11:30:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeAvailable)).toBe(true);
|
|
expect(result.length).toBe(1);
|
|
});
|
|
|
|
it("handles scenario where one group has no available hosts", () => {
|
|
// Test scenario where one group has no available hosts
|
|
// Group 1: Host A (available 11:00-11:30)
|
|
// Group 2: Host B (not available at all)
|
|
// Fixed host: available 11:00-13:00
|
|
const userAvailability = [
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T13:00:00.000Z") },
|
|
],
|
|
user: { isFixed: true },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [
|
|
{ start: dayjs("2025-01-23T11:00:00.000Z"), end: dayjs("2025-01-23T11:30:00.000Z") },
|
|
],
|
|
user: { isFixed: false, groupId: "group1" },
|
|
},
|
|
{
|
|
dateRanges: [],
|
|
oooExcludedDateRanges: [], // No availability
|
|
user: { isFixed: false, groupId: "group2" },
|
|
},
|
|
];
|
|
|
|
const result = getAggregatedAvailability(userAvailability, "ROUND_ROBIN");
|
|
|
|
// Should NOT be available when one group has no hosts available
|
|
const timeRangeNotAvailable = {
|
|
start: dayjs("2025-01-23T11:00:00.000Z"),
|
|
end: dayjs("2025-01-23T11:30:00.000Z"),
|
|
};
|
|
expect(isAvailable(result, timeRangeNotAvailable)).toBe(false);
|
|
});
|
|
});
|