Fixed two issues and add sanity tests. Issue #1: super now calls the right class, #2: decoupled the initiatlization of call_center and employee.

pull/738/head
Itamar Friedman 2023-02-06 13:00:50 +02:00
parent 2d8231663f
commit 61b64066e0
No known key found for this signature in database
GPG Key ID: 3A7BAAF43A7F0861
3 changed files with 103 additions and 7 deletions

View File

@ -12,12 +12,12 @@ class Rank(Enum):
class Employee(metaclass=ABCMeta):
def __init__(self, employee_id, name, rank, call_center):
def __init__(self, employee_id, name, rank):
self.employee_id = employee_id
self.name = name
self.rank = rank
self.call = None
self.call_center = call_center
self.call_center = None
def take_call(self, call):
"""Assume the employee will always successfully take the call."""
@ -26,6 +26,7 @@ class Employee(metaclass=ABCMeta):
self.call.state = CallState.IN_PROGRESS
def complete_call(self):
assert self.call_center is not None
self.call.state = CallState.COMPLETE
self.call_center.notify_call_completed(self.call)
@ -34,11 +35,15 @@ class Employee(metaclass=ABCMeta):
pass
def _escalate_call(self):
assert self.call_center is not None
self.call.state = CallState.READY
call = self.call
self.call = None
self.call_center.notify_call_escalated(call)
def set_call_center(self, call_center):
self.call_center = call_center
class Operator(Employee):
@ -53,7 +58,7 @@ class Operator(Employee):
class Supervisor(Employee):
def __init__(self, employee_id, name):
super(Operator, self).__init__(employee_id, name, Rank.SUPERVISOR)
super(Supervisor, self).__init__(employee_id, name, Rank.SUPERVISOR)
def escalate_call(self):
self.call.level = Rank.DIRECTOR
@ -63,7 +68,7 @@ class Supervisor(Employee):
class Director(Employee):
def __init__(self, employee_id, name):
super(Operator, self).__init__(employee_id, name, Rank.DIRECTOR)
super(Director, self).__init__(employee_id, name, Rank.DIRECTOR)
def escalate_call(self):
raise NotImplementedError('Directors must be able to handle any call')
@ -87,10 +92,12 @@ class Call(object):
class CallCenter(object):
def __init__(self, operators, supervisors, directors):
self.operators = operators
self.supervisors = supervisors
self.directors = directors
self.operators = []
self.supervisors = []
self.directors = []
self.queued_calls = deque()
for employee in operators + supervisors + directors:
self.add_employee(employee)
def dispatch_call(self, call):
if call.rank not in (Rank.OPERATOR, Rank.SUPERVISOR, Rank.DIRECTOR):
@ -102,6 +109,7 @@ class CallCenter(object):
employee = self._dispatch_call(call, self.supervisors)
if call.rank == Rank.DIRECTOR or employee is None:
employee = self._dispatch_call(call, self.directors)
if employee is None:
self.queued_calls.append(call)
@ -112,6 +120,18 @@ class CallCenter(object):
return employee
return None
def add_employee(self, employee: Employee):
if isinstance(employee, Operator):
self.operators.append(employee)
elif isinstance(employee, Supervisor):
self.supervisors.append(employee)
elif isinstance(employee, Director):
self.directors.append(employee)
else:
raise ValueError('Invalid employee type: {}'.format(type(employee)))
employee.set_call_center(self)
def notify_call_escalated(self, call):
pass

View File

@ -0,0 +1,76 @@
# test_call_center.py - Generated by CodiumAI
import pytest
from call_center.call_center import Operator, Supervisor, Director, Call, CallCenter, Rank
"""
Code Analysis:
- The CallCenter class is used to manage calls in a call center.
- It takes three parameters: operators, supervisors, and directors.
- The queued_calls attribute is a deque object, which is a double-ended queue.
- The dispatch_call() method is used to assign a call to an employee based on the call's rank.
- If an employee is not available, the call is added to the queued_calls deque.
- The _dispatch_call() method is used to assign a call to an employee.
- The notify_call_escalated() and notify_call_completed() methods are used to notify the call center when a call is escalated or completed.
- The dispatch_queued_call_to_newly_freed_employee() method is used to assign a queued call to an employee who has just become available.
"""
"""
Test Plan:
- test_dispatch_call(): tests that the dispatch_call() method assigns the call to the correct employee based on the call's rank
- test_dispatch_call_with_no_available_employee(): tests that the dispatch_call() method adds the call to the queued_calls deque if no employee is available
- test_add_employee(): tests that the add_employee() method adds the employee to the correct list based on the employee's type
"""
class TestCallCenter():
def setup_method(self, method):
self.operators = [Operator(1, 'John'), Operator(2, 'Jane')]
self.supervisors = [Supervisor(3, 'Bob')]
self.directors = [Director(4, 'Alice')]
self.call_center = CallCenter(self.operators, self.supervisors, self.directors)
def test_dispatch_call(self):
call = Call(Rank.OPERATOR)
self.call_center.dispatch_call(call)
assert self.operators[0].call == call
call = Call(Rank.SUPERVISOR)
self.call_center.dispatch_call(call)
assert self.supervisors[0].call == call
call = Call(Rank.DIRECTOR)
self.call_center.dispatch_call(call)
assert self.directors[0].call == call
def test_dispatch_call_with_no_available_employee(self):
for employee in self.operators + self.supervisors + self.directors:
employee.take_call(Call(Rank.OPERATOR))
assert employee.call is not None
call = Call(Rank.OPERATOR)
self.call_center.dispatch_call(call)
assert len(self.call_center.queued_calls) == 1
def test_add_employee(self):
operator = Operator(5, 'Tom')
supervisor = Supervisor(6, 'Jerry')
director = Director(7, 'Sally')
self.call_center.add_employee(operator)
assert operator in self.call_center.operators
self.call_center.add_employee(supervisor)
assert supervisor in self.call_center.supervisors
self.call_center.add_employee(director)
assert director in self.call_center.directors