Created
December 15, 2023 15:49
-
-
Save ygrenzinger/6fbd3e2694fad6ea31fecd386814e58b to your computer and use it in GitHub Desktop.
Refactoring of the code at the end of the interview
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ================================================ | |
// ==== ⬇️🚫 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