Design Calendar Event CRUD with Unit Tests
RampSoftware Engineer · Technical ScreenLast updated
Design and implement a robust in-memory calendar event service supporting full CRUD operations, conflict detection, and search, along with a comprehensive suite of unit test cases.
Calendar Event Service with Unit Tests
Design and implement an in-memory CalendarService class that handles standard CRUD operations for single-user or team calendar events, enforces business validation rules, and includes a comprehensive set of unit tests.
Requirements
Implement the following class interface:
from typing import List, Optional, Dict
class Event:
def __init__(self, event_id: str, title: str, start_time: int, end_time: int, attendees: List[str]):
self.id = event_id
self.title = title
self.start_time = start_time # Unix timestamp in seconds
self.end_time = end_time # Unix timestamp in seconds
self.attendees = attendees
class CalendarService:
def create_event(self, title: str, start_time: int, end_time: int, attendees: List[str]) -> Event:
"""Creates a new event. Raises ValueError if validation fails."""
pass
def get_event(self, event_id: str) -> Optional[Event]:
"""Fetches event by ID, or None if not found."""
pass
def update_event(self, event_id: str, title: Optional[str] = None,
start_time: Optional[int] = None, end_time: Optional[int] = None,
attendees: Optional[List[str]] = None) -> Event:
"""Updates an existing event. Raises ValueError or KeyError on error."""
pass
def delete_event(self, event_id: str) -> bool:
"""Deletes an event. Returns True if deleted, False if not found."""
pass
def get_events_in_range(self, start_time: int, end_time: int) -> List[Event]:
"""Returns all events that overlap with [start_time, end_time], sorted by start_time ascending."""
pass
def find_conflicts(self, user: str, start_time: int, end_time: int, exclude_event_id: Optional[str] = None) -> List[Event]:
"""Returns existing events involving `user` that overlap with [start_time, end_time]."""
pass
Validation Rules
start_timemust be strictly less thanend_time(start_time < end_time).titlemust be a non-empty, non-whitespace string.- Overlap definition: Two intervals
[s1, e1]and[s2, e2]overlap if and only ifmax(s1, s2) < min(e1, e2)(i.e., touching boundariese1 == s2do not overlap). - All timestamps are non-negative integers.
Deliverables
- A complete, clean implementation of
CalendarService. - A suite of unit tests (using
unittestor standardpyteststyle assertions) covering normal paths, edge cases (boundary touching, missing IDs, invalid times), and partial updates.
Example
service = CalendarService()
e1 = service.create_event("Sprint Planning", 100, 200, ["[email protected]", "[email protected]"])
e2 = service.create_event("1:1 Sync", 200, 300, ["[email protected]"])
# Querying range [150, 250] returns both events because [100, 200] and [200, 300] both overlap [150, 250]
assert len(service.get_events_in_range(150, 250)) == 2
# Touching intervals do not conflict: [100, 200] does not overlap with candidate [200, 250]
assert len(service.find_conflicts("[email protected]", 200, 250, exclude_event_id=e2.id)) == 0
Hints
Hint 1
Ensure interval comparison strictly uses `max(s1, s2) < min(e1, e2)` to prevent off-by-one errors with adjacent events.
Hint 2
For updates, construct the prospective state of the event first to validate it before committing changes to storage.
Hint 3
Structure your unit tests into distinct classes or test functions: validation tests, CRUD behavior tests, and range/overlap query tests.
Follow-up questions
- How would you optimize `get_events_in_range` and `find_conflicts` if the calendar holds millions of events (e.g., using interval trees or segment trees)?
- How would you extend this service and its test suite to support recurring events (e.g., daily, weekly, RRULE format) without storing infinite instances?
- How would you handle concurrent writes to the same calendar in a distributed environment to prevent race conditions during conflict checks?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.