code cleanup

This commit is contained in:
Muhsin Keloth
2024-03-15 00:14:36 +05:30
parent d8708e5ee5
commit 11ae25535a
2 changed files with 283 additions and 89 deletions
@@ -1,3 +1,4 @@
import { utcToZonedTime } from 'date-fns-tz';
// Array defining days of the week
const daysOfWeek = [
'Sunday',
@@ -9,6 +10,64 @@ const daysOfWeek = [
'Saturday',
];
/**
* Find the next available time for the specified day
* @param {Object[]} workingHours - Array of objects representing working hours for each day
* @param {number} dayOfWeek - Index of the day of the week (0 for Sunday, 1 for Monday, etc.)
* @param {number} currentHour - Current hour of the day (24-hour format)
* @param {number} currentMinutes - Current minutes of the hour
* @returns {Object|null} - Object containing next available time information or null if not available
*/
const findNextAvailableTimeForDay = (
workingHours,
dayOfWeek,
currentHour,
currentMinutes
) => {
const availableHours = workingHours.find(
hours =>
hours.day_of_week === dayOfWeek &&
!hours.closed_all_day &&
(currentHour < hours.close_hour ||
(currentHour === hours.close_hour &&
currentMinutes < hours.close_minutes))
);
if (availableHours) {
return {
hour: availableHours.open_hour,
minutes: availableHours.open_minutes,
};
}
return null;
};
/**
* Find the next available time across days
* @param {Object[]} workingHours - Array of objects representing working hours for each day
* @param {number} currentDayOfWeek - Index of the current day of the week (0 for Sunday, 1 for Monday, etc.)
* @returns {Object|null} - Object containing next available time information or null if not available
*/
const findNextAvailableTimeAcrossDays = (workingHours, currentDayOfWeek) => {
const nextAvailableDays = workingHours.filter(hours => !hours.closed_all_day);
for (let i = 0; i < 7; i += 1) {
const nextDayIndex = (currentDayOfWeek + 1 + i) % 7;
const nextDay = nextAvailableDays.find(
hours => hours.day_of_week === nextDayIndex
);
if (nextDay) {
return {
hour: nextDay.open_hour,
minutes: nextDay.open_minutes,
day: nextDayIndex,
};
}
}
return null;
};
/**
* Function to find the next available time
* @param {Array} workingHours - Array of working hours for each day
@@ -23,48 +82,17 @@ const findNextAvailableTime = (
currentHour,
currentMinutes
) => {
let nextAvailableDays = [];
let nextAvailableTime = null;
// Find the next available time for today
const nextAvailableTimeToday = workingHours.find(
workingHour =>
currentDayOfWeek === workingHour.day_of_week && // Match current day
!workingHour.closed_all_day && // Check if not closed for the whole day
(currentHour < workingHour.close_hour || // Check if current hour is before closing hour
(currentHour === workingHour.close_hour && // or if hours are equal but minutes are before closing minutes
currentMinutes < workingHour.close_minutes))
const nextAvailableTimeToday = findNextAvailableTimeForDay(
workingHours,
currentDayOfWeek,
currentHour,
currentMinutes
);
// If next available time for today is found
if (nextAvailableTimeToday) {
nextAvailableTime = {
hour: nextAvailableTimeToday.open_hour,
minutes: nextAvailableTimeToday.open_minutes,
day: 'today',
};
return { ...nextAvailableTimeToday, day: 'today' };
}
// If no available time for today, find the next available time for the next day(s)
if (nextAvailableTime === null) {
nextAvailableDays = workingHours.filter(hours => !hours.closed_all_day);
for (let i = 0; i < 7; i += 1) {
const nextDayIndex = (currentDayOfWeek + 1 + i) % 7;
const nextDay = nextAvailableDays.find(
hours => hours.day_of_week === nextDayIndex
);
if (nextDay) {
nextAvailableTime = {
hour: nextDay.open_hour,
minutes: nextDay.open_minutes,
day: nextDayIndex,
};
break;
}
}
}
return nextAvailableTime;
return findNextAvailableTimeAcrossDays(workingHours, currentDayOfWeek);
};
/**
@@ -73,10 +101,15 @@ const findNextAvailableTime = (
* @param {Date} currentTime - Current time object
* @returns {string} - Next availability message
*/
export const getNextAvailabilityMessage = (workingHours, currentTime) => {
const currentDayOfWeek = currentTime.getDay();
const currentHour = currentTime.getHours();
const currentMinutes = currentTime.getMinutes();
export const getNextAvailabilityMessage = (
workingHours,
currentTime,
timezone = 'UTC'
) => {
const utcZonedTime = utcToZonedTime(currentTime, timezone);
const currentDayOfWeek = utcZonedTime.getDay();
const currentHour = utcZonedTime.getHours();
const currentMinutes = utcZonedTime.getMinutes();
const nextAvailableTime = findNextAvailableTime(
workingHours,
currentDayOfWeek,
@@ -1,6 +1,170 @@
import { getNextAvailabilityMessage } from '../availabilityHelper';
describe('getNextAvailabilityMessage function', () => {
describe('getNextAvailabilityMessage with out timezone', () => {
const working_hours = [
{
id: 8,
inbox_id: 2,
account_id: 1,
day_of_week: 0,
closed_all_day: true,
open_hour: null,
open_minutes: null,
close_hour: null,
close_minutes: null,
created_at: '2024-01-08T06:12:53.980Z',
updated_at: '2024-01-08T06:12:53.980Z',
open_all_day: false,
},
{
id: 9,
inbox_id: 2,
account_id: 1,
day_of_week: 1,
closed_all_day: false,
open_hour: 9,
open_minutes: 0,
close_hour: 17,
close_minutes: 0,
created_at: '2024-01-08T06:12:53.982Z',
updated_at: '2024-01-08T06:12:53.982Z',
open_all_day: false,
},
{
id: 10,
inbox_id: 2,
account_id: 1,
day_of_week: 2,
closed_all_day: true,
open_hour: 15,
open_minutes: 0,
close_hour: 23,
close_minutes: 30,
created_at: '2024-01-08T06:12:53.983Z',
updated_at: '2024-03-12T06:54:00.313Z',
open_all_day: false,
},
{
id: 11,
inbox_id: 2,
account_id: 1,
day_of_week: 3,
closed_all_day: true,
open_hour: null,
open_minutes: null,
close_hour: null,
close_minutes: null,
created_at: '2024-01-08T06:12:53.984Z',
updated_at: '2024-03-13T07:15:41.249Z',
open_all_day: false,
},
{
id: 12,
inbox_id: 2,
account_id: 1,
day_of_week: 4,
closed_all_day: false,
open_hour: 15,
open_minutes: 0,
close_hour: 20,
close_minutes: 0,
created_at: '2024-01-08T06:12:53.985Z',
updated_at: '2024-03-13T07:21:31.430Z',
open_all_day: false,
},
{
id: 13,
inbox_id: 2,
account_id: 1,
day_of_week: 5,
closed_all_day: false,
open_hour: 9,
open_minutes: 0,
close_hour: 17,
close_minutes: 0,
created_at: '2024-01-08T06:12:53.986Z',
updated_at: '2024-01-08T06:12:53.986Z',
open_all_day: false,
},
{
id: 14,
inbox_id: 2,
account_id: 1,
day_of_week: 6,
closed_all_day: false,
open_hour: 9,
open_minutes: 0,
close_hour: 7,
close_minutes: 0,
created_at: '2024-01-08T06:12:53.987Z',
updated_at: '2024-01-08T06:12:53.987Z',
open_all_day: false,
},
];
test('returns correct message for less than a minute', () => {
const lessThanMinute = new Date('2024-03-14T14:59:59'); // Current time + 59 seconds
expect(getNextAvailabilityMessage(working_hours, lessThanMinute)).toBe(
'We will be back online in less than a minute.'
);
});
test('returns correct message for less than 10 minutes', () => {
const lessThan10Minutes = new Date('2024-03-14T14:50:00'); // Current time + 9 minutes
expect(getNextAvailabilityMessage(working_hours, lessThan10Minutes)).toBe(
'We will be back online in 10 minutes.'
);
});
test('returns minutes message for less than an hour', () => {
const lessThanHour = new Date('2024-03-14T14:45:00'); // Current time + 30 minutes
expect(getNextAvailabilityMessage(working_hours, lessThanHour)).toBe(
'We will be back online in 15 minutes.'
);
});
test('returns correct message for greater than 2 hours', () => {
const lessThanHour = new Date('2024-03-14T12:30:00'); // Current time + 30 minutes
expect(getNextAvailabilityMessage(working_hours, lessThanHour)).toBe(
'We will be back online in 2 hours'
);
});
test('returns correct message for next day', () => {
const nextDay = new Date('2024-03-14T00:00:00'); // Next day
working_hours[4].closed_all_day = true;
expect(getNextAvailabilityMessage(working_hours, nextDay)).toBe(
'We will be back online tomorrow'
);
});
test('returns correct message for specific day', () => {
const specificDay = new Date('2024-03-14T00:00:00'); // Next day
working_hours[4].closed_all_day = true;
working_hours[5].closed_all_day = true;
expect(getNextAvailabilityMessage(working_hours, specificDay)).toBe(
'We will be back online on Saturday'
);
});
test('returns correct message for next week', () => {
const nextWeek = new Date('2024-03-21T21:00:00'); // Next day
working_hours[5].closed_all_day = true;
working_hours[6].closed_all_day = true;
working_hours[0].closed_all_day = true;
working_hours[1].closed_all_day = true;
working_hours[2].closed_all_day = true;
working_hours[3].closed_all_day = true;
working_hours[4].closed_all_day = false;
expect(getNextAvailabilityMessage(working_hours, nextWeek)).toBe(
'We will be back online on Thursday'
);
});
afterEach(() => {
jest.useRealTimers();
});
});
describe('getNextAvailabilityMessage with timezone', () => {
const working_hours = [
{
id: 8,
@@ -103,65 +267,62 @@ describe('getNextAvailabilityMessage function', () => {
];
test('returns correct message for less than a minute', () => {
const lessThanMinute = new Date('2024-03-14T14:59:59'); // Current time + 59 seconds
expect(getNextAvailabilityMessage(working_hours, lessThanMinute)).toBe(
'We will be back online in less than a minute.'
);
jest.useFakeTimers('modern');
jest.setSystemTime(new Date('2024-03-14T19:50:00'));
const lessThan10Minutes = new Date('2024-03-14T19:50:00');
expect(
getNextAvailabilityMessage(
working_hours,
lessThan10Minutes,
'America/New_York'
)
).toBe('We will be back online in less than a minute.');
});
test('returns correct message for less than 10 minutes', () => {
const lessThan10Minutes = new Date('2024-03-14T14:50:00'); // Current time + 9 minutes
expect(getNextAvailabilityMessage(working_hours, lessThan10Minutes)).toBe(
'We will be back online in 10 minutes.'
);
});
test('returns minutes message for less than an hour', () => {
const lessThanHour = new Date('2024-03-14T14:45:00'); // Current time + 30 minutes
expect(getNextAvailabilityMessage(working_hours, lessThanHour)).toBe(
'We will be back online in 15 minutes.'
);
jest.useFakeTimers('modern');
jest.setSystemTime(new Date('2024-03-14T19:50:00'));
const lessThan10Minutes = new Date('2024-03-14T19:50:00');
expect(
getNextAvailabilityMessage(
working_hours,
lessThan10Minutes,
'America/New_York'
)
).toBe('We will be back online in less than a minute.');
});
test('returns correct message for greater than 2 hours', () => {
const lessThanHour = new Date('2024-03-14T12:30:00'); // Current time + 30 minutes
expect(getNextAvailabilityMessage(working_hours, lessThanHour)).toBe(
'We will be back online in 2 hours'
);
jest.useFakeTimers('modern');
jest.setSystemTime(new Date('2024-03-14T14:59:59'));
const lessThanMinute = new Date('2024-03-14T14:59:59');
expect(
getNextAvailabilityMessage(
working_hours,
lessThanMinute,
'America/New_York'
)
).toBe('We will be back online in 4 hours');
});
test('returns correct message for next day', () => {
const nextDay = new Date('2024-03-14T00:00:00'); // Next day
jest.useFakeTimers('modern');
jest.setSystemTime(new Date('2024-03-14T14:59:59'));
const nextDay = new Date('2024-03-15T00:00:00'); // Next day
working_hours[4].closed_all_day = true;
expect(getNextAvailabilityMessage(working_hours, nextDay)).toBe(
'We will be back online tomorrow'
);
expect(
getNextAvailabilityMessage(working_hours, nextDay, 'America/New_York')
).toBe('We will be back online tomorrow');
});
test('returns correct message for specific day', () => {
const specificDay = new Date('2024-03-14T00:00:00'); // Next day
jest.useFakeTimers('modern');
jest.setSystemTime(new Date('2024-03-14T14:59:59'));
const specificDay = new Date('2024-03-17T00:00:00'); // Next day
working_hours[4].closed_all_day = true;
working_hours[5].closed_all_day = true;
expect(getNextAvailabilityMessage(working_hours, specificDay)).toBe(
'We will be back online on Saturday'
);
});
test('returns correct message for next week', () => {
const nextWeek = new Date('2024-03-21T21:00:00'); // Next day
working_hours[5].closed_all_day = true;
working_hours[6].closed_all_day = true;
working_hours[0].closed_all_day = true;
working_hours[1].closed_all_day = true;
working_hours[2].closed_all_day = true;
working_hours[3].closed_all_day = true;
working_hours[4].closed_all_day = false;
expect(getNextAvailabilityMessage(working_hours, nextWeek)).toBe(
'We will be back online on Thursday'
);
});
afterEach(() => {
jest.useRealTimers();
expect(
getNextAvailabilityMessage(working_hours, specificDay, 'America/New_York')
).toBe('We will be back online on Monday');
});
});