Skip to content

Instantly share code, notes, and snippets.

@ygrenzinger
Created December 15, 2023 15:49
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 ygrenzinger/6fbd3e2694fad6ea31fecd386814e58b to your computer and use it in GitHub Desktop.
Save ygrenzinger/6fbd3e2694fad6ea31fecd386814e58b to your computer and use it in GitHub Desktop.
Refactoring of the code at the end of the interview
// ================================================
// ==== ⬇️🚫 DO NOT TOUCH CODE BELOW HERE 🚫⬇️ ====
// ************ DATABASE STUFF ***************
interface EventModel {
id: number
kind: string
starts_at: string
ends_at: string
}
let AllEvents: EventModel[] = []
// *******************************************
// *************** TEST SETUP ****************
const chai = require('chai')
const { assert } = chai
const it = async (name: string, cb: Function): Promise<void> => {
try {
await cb()
console.log(`✅ ${name}`)
} catch (e) {
console.warn(`❌ ${name}`)
console.error(e)
}
}
// ==== ⬆️🚫 DO NOT TOUCH CODE ABOVE HERE 🚫⬆️ ====
// ================================================
// ====================================================
// ==== ⬇️ ⬇️ ⬇️ START OF CODING EXERCISE ⬇️ ⬇️ ⬇️ ====
const moment = require('moment')
const fetchEvents = async (): Promise<EventModel[]> => {
return AllEvents;
}
const extractDayAsString = (date: any) => {
return date.format('YYYY-MM-DD')
}
const buildAvailableSlotsForOpening = (opening: EventModel) => {
const slots = [];
let currentTime = moment(opening.starts_at);
let endTime = moment(opening.ends_at);
while (currentTime.isBefore(endTime)) {
slots.push(currentTime.format('HH:mm'));
currentTime.add(30, 'minute');
}
return slots;
}
const buildAvailableSlots = (day: string, events: EventModel[]) => {
const openings = events.filter((e) => {
const d = extractDayAsString(moment(e.starts_at));
return e.kind === 'opening' && day === d;
});
return openings.map((opening) => buildAvailableSlotsForOpening(opening)).flat();
}
const buildSevenDays = (startDay: Date): string[] => {
const days = [];
const current = moment(startDay);
const end = moment(startDay).add(7, 'day');
while (current.isBefore(end)) {
days.push(extractDayAsString(current));
current.add(1, 'day');
}
return days;
}
// Implement your algorithm below. You can also write helper functions or type definitions
const getAvailabilitiesByDay = async (date: Date): Promise<Record<string, Array<string>>> => {
// next line: "fetches" events from the mock database, not needed for first test
const events = await fetchEvents()
return Object.fromEntries(
buildSevenDays(date).map((d) => [d, buildAvailableSlots(d, events)])
)
}
// *******************************************
// **************** TESTS ********************
// *******************************************
it('returns an object with the next seven days as keys (in YYYY-MM-DD format) and empty arrays as values', async () => {
const availabilitiesByDay = await getAvailabilitiesByDay(new Date('2020-01-01 00:00'))
const returnedObject = {
'2020-01-01': [],
'2020-01-02': [],
'2020-01-03': [],
'2020-01-04': [],
'2020-01-05': [],
'2020-01-06': [],
'2020-01-07': [],
}
// As the database is empty, the doctor doesn't have any available slots
assert.deepEqual(availabilitiesByDay, returnedObject)
})
it('a 30-minute opening creates an available slot in HH:mm format', async () => {
AllEvents = [
{
id: 1,
kind: 'opening',
starts_at: '2020-01-03 12:00',
ends_at: '2020-01-03 12:30',
},
]
const availabilitiesByDay = await getAvailabilitiesByDay(new Date('2020-01-02 00:00'))
const returnedObject = {
'2020-01-02': [],
'2020-01-03': ['12:00'],
'2020-01-04': [],
'2020-01-05': [],
'2020-01-06': [],
'2020-01-07': [],
'2020-01-08': [],
}
assert.deepEqual(availabilitiesByDay, returnedObject)
})
it('openings longer than 30 minutes are split into 30-minute slots', async () => {
AllEvents = [
{
id: 1,
kind: 'opening',
starts_at: '2020-01-05 13:00',
ends_at: '2020-01-05 14:00',
},
]
const availabilitiesByDay = await getAvailabilitiesByDay(new Date('2020-01-03 00:00'))
const returnedObject = {
'2020-01-03': [],
'2020-01-04': [],
'2020-01-05': ['13:00', '13:30'],
'2020-01-06': [],
'2020-01-07': [],
'2020-01-08': [],
'2020-01-09': [],
}
assert.deepEqual(availabilitiesByDay, returnedObject)
})
it('openings outside the seven-day window do not create slots', async () => {
AllEvents = [
{
id: 1,
kind: 'opening',
starts_at: '2020-01-07 11:00',
ends_at: '2020-01-07 12:00',
},
]
const availabilitiesByDay = await getAvailabilitiesByDay(new Date('2020-01-08 00:00'))
const returnedObject = {
'2020-01-08': [],
'2020-01-09': [],
'2020-01-10': [],
'2020-01-11': [],
'2020-01-12': [],
'2020-01-13': [],
'2020-01-14': [],
}
assert.deepEqual(availabilitiesByDay, returnedObject)
assert.deepEqual(availabilitiesByDay['2020-01-07'], undefined)
})
// Interviewer to add more tests here ===>>>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment