Skip to content

Instantly share code, notes, and snippets.

@MinSomai
Created October 27, 2023 06:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MinSomai/616e58d0bcb8a28081191dab63e393fa to your computer and use it in GitHub Desktop.
Save MinSomai/616e58d0bcb8a28081191dab63e393fa to your computer and use it in GitHub Desktop.
const _ = require('lodash');

// RequestedDateTimeHelper is a helper related to requested times.
// Requested dates can be either datetime or time (military).
class RequestedDateTimeHelper {
    /**
     * isDateTimeDifferent method returns true if datetime/time is different
     *
     * Time can change from:
     * - time to new time (military)
     * - time to datetime (military to full datetime)
     * - datetime to new datetime (full datetime)
     * - datetime to time (full datetime to military)
     *
     *
     * @param {array} prevTimes.requestedAppointmentTimeSlots - array of requested time slots (military)
     * @param {array} prevTimes.requestedAppointmentDateTimeSlots - array of requested datetime slots (full date time)
     * @param {array} newTimes.requestedAppointmentTimeSlots - array of new requested time slots
     * @param {array} newTimes.requestedAppointmentDateTimeSlots - array of new requested datetime slots
     *
     */
    isDateTimeDifferent = (prevTimes, newTimes) => {
        try {
            if (prevTimes && !newTimes) return false;

            if (prevTimes == null && newTimes) {
                let allValuesAreNull = Object.values(newTimes).every(eachTime => !eachTime);
                if (allValuesAreNull) return false;
                return true;
            }

            // similar to prevTimes is null
            if (
                prevTimes &&
                typeof prevTimes == 'object' &&
                Object.keys(prevTimes)?.length == 0 &&
                Object.keys(newTimes)?.length > 0
            )
                return true;

            let isPrevTime =
                prevTimes &&
                prevTimes.requestedAppointmentTimeSlots &&
                Array.isArray(prevTimes.requestedAppointmentTimeSlots) &&
                prevTimes?.requestedAppointmentTimeSlots?.length > 0;

            let isNewTime =
                newTimes &&
                newTimes.requestedAppointmentTimeSlots &&
                Array.isArray(newTimes.requestedAppointmentTimeSlots) &&
                newTimes?.requestedAppointmentTimeSlots?.length > 0;

            let isPrevDateTime =
                prevTimes &&
                prevTimes.requestedAppointmentDateTimeSlots &&
                Array.isArray(prevTimes.requestedAppointmentDateTimeSlots) &&
                prevTimes?.requestedAppointmentDateTimeSlots?.length > 0;

            let isNewDateTime =
                newTimes &&
                newTimes.requestedAppointmentDateTimeSlots &&
                Array.isArray(newTimes.requestedAppointmentDateTimeSlots) &&
                newTimes?.requestedAppointmentDateTimeSlots?.length > 0;

            // from stackoverflow (checks whether array of object are deep equal)
            const isArrayEqual = (x, y) => {
                return _.isEmpty(_.xorWith(x, y, _.isEqual));
            };

            if (isPrevTime) {
                if (isNewTime) {
                    const isTimeEqual = isArrayEqual(
                        prevTimes.requestedAppointmentTimeSlots,
                        newTimes.requestedAppointmentTimeSlots
                    );

                    return isTimeEqual ? false : true;
                }

                // Format changed
                if (isNewDateTime) {
                    return true;
                }
            }

            if (isPrevDateTime) {
                if (isNewDateTime) {
                    const isDateTimeEqual = isArrayEqual(
                        prevTimes.requestedAppointmentDateTimeSlots,
                        newTimes.requestedAppointmentDateTimeSlots
                    );
                    return isDateTimeEqual ? false : true;
                }

                // Format changed
                if (isNewTime) {
                    return true;
                }
            }
            return false;
        } catch (e) {
            console.log('Error checking datetime difference: ', e);
            return false;
        }
    };
}

module.exports = RequestedDateTimeHelper;
const RequestedDateTimeHelper = require('@src/utils/requestedDateTimeHelper'); // Import your class

describe('RequestedDateTimeHelper', () => {
    let helper;

    beforeAll(() => {
        helper = new RequestedDateTimeHelper();
    });

    it('should return false when both previous and new times are empty', () => {
        expect(helper.isDateTimeDifferent({}, {})).toBe(false);
    });

    it('should handle null cases', () => {
        expect(helper.isDateTimeDifferent(null, null)).toBe(false);
    });

    it('should handle prev nested null cases', () => {
        let prevTimes = { requestedAppointmentTimeSlots: null, requestedAppointmentDateTimeSlots: null };
        expect(helper.isDateTimeDifferent(prevTimes, null)).toBe(false);
    });

    it('should handle new datetimes nested null cases', () => {
        let newTimes = { requestedAppointmentTimeSlots: null, requestedAppointmentDateTimeSlots: null };
        expect(helper.isDateTimeDifferent(null, newTimes)).toBe(false);
    });

    it('should return false when previous times have time slots, but new times are empty', () => {
        const prevTimes = {
            requestedAppointmentTimeSlots: ['08:00', '10:00'],
            requestedAppointmentDateTimeSlots: [],
        };
        const newTimes = {};

        expect(helper.isDateTimeDifferent(prevTimes, newTimes)).toBe(false);
    });

    it('should return true when new times have time slots, but previous times are empty', () => {
        const prevTimes = {};
        const newTimes = {
            requestedAppointmentTimeSlots: ['08:00', '10:00'],
            requestedAppointmentDateTimeSlots: [],
        };

        expect(helper.isDateTimeDifferent(prevTimes, newTimes)).toBe(true);
    });

    it('should return false when previous and new times have the same time slots', () => {
        const prevTimes = {
            requestedAppointmentTimeSlots: ['08:00', '10:00'],
            requestedAppointmentDateTimeSlots: [],
        };
        const newTimes = {
            requestedAppointmentTimeSlots: ['08:00', '10:00'],
            requestedAppointmentDateTimeSlots: [],
        };

        expect(helper.isDateTimeDifferent(prevTimes, newTimes)).toBe(false);
    });

    it('should return true when previous and new times have different time slots', () => {
        const prevTimes = {
            requestedAppointmentTimeSlots: ['08:00', '10:00'],
            requestedAppointmentDateTimeSlots: [],
        };
        const newTimes = {
            requestedAppointmentTimeSlots: ['07:00', '11:00'],
            requestedAppointmentDateTimeSlots: [],
        };

        expect(helper.isDateTimeDifferent(prevTimes, newTimes)).toBe(true);
    });

    it('should return true when there is a format change from time slots to date time slots', () => {
        const prevTimes = {
            requestedAppointmentTimeSlots: ['08:00', '10:00'],
            requestedAppointmentDateTimeSlots: [],
        };
        const newTimes = {
            requestedAppointmentTimeSlots: [],
            requestedAppointmentDateTimeSlots: ['2023-10-26T08:00:00', '2023-10-27T10:00:00'],
        };

        expect(helper.isDateTimeDifferent(prevTimes, newTimes)).toBe(true);
    });

    it('should return true when there is a format change from date time slots to time slots', () => {
        const prevTimes = {
            requestedAppointmentTimeSlots: [],
            requestedAppointmentDateTimeSlots: ['2023-10-26T08:00:00', '2023-10-27T10:00:00'],
        };
        const newTimes = {
            requestedAppointmentTimeSlots: ['08:00', '10:00'],
            requestedAppointmentDateTimeSlots: [],
        };

        expect(helper.isDateTimeDifferent(prevTimes, newTimes)).toBe(true);
    });
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment