Fixed two issues and add sanity tests. Issue #1: super now calls the right class, #2: decoupled the initiatlization of call_center and employee.
parent
2d8231663f
commit
61b64066e0
|
@ -12,12 +12,12 @@ class Rank(Enum):
|
||||||
|
|
||||||
class Employee(metaclass=ABCMeta):
|
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.employee_id = employee_id
|
||||||
self.name = name
|
self.name = name
|
||||||
self.rank = rank
|
self.rank = rank
|
||||||
self.call = None
|
self.call = None
|
||||||
self.call_center = call_center
|
self.call_center = None
|
||||||
|
|
||||||
def take_call(self, call):
|
def take_call(self, call):
|
||||||
"""Assume the employee will always successfully take the call."""
|
"""Assume the employee will always successfully take the call."""
|
||||||
|
@ -26,6 +26,7 @@ class Employee(metaclass=ABCMeta):
|
||||||
self.call.state = CallState.IN_PROGRESS
|
self.call.state = CallState.IN_PROGRESS
|
||||||
|
|
||||||
def complete_call(self):
|
def complete_call(self):
|
||||||
|
assert self.call_center is not None
|
||||||
self.call.state = CallState.COMPLETE
|
self.call.state = CallState.COMPLETE
|
||||||
self.call_center.notify_call_completed(self.call)
|
self.call_center.notify_call_completed(self.call)
|
||||||
|
|
||||||
|
@ -34,11 +35,15 @@ class Employee(metaclass=ABCMeta):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _escalate_call(self):
|
def _escalate_call(self):
|
||||||
|
assert self.call_center is not None
|
||||||
self.call.state = CallState.READY
|
self.call.state = CallState.READY
|
||||||
call = self.call
|
call = self.call
|
||||||
self.call = None
|
self.call = None
|
||||||
self.call_center.notify_call_escalated(call)
|
self.call_center.notify_call_escalated(call)
|
||||||
|
|
||||||
|
def set_call_center(self, call_center):
|
||||||
|
self.call_center = call_center
|
||||||
|
|
||||||
|
|
||||||
class Operator(Employee):
|
class Operator(Employee):
|
||||||
|
|
||||||
|
@ -53,7 +58,7 @@ class Operator(Employee):
|
||||||
class Supervisor(Employee):
|
class Supervisor(Employee):
|
||||||
|
|
||||||
def __init__(self, employee_id, name):
|
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):
|
def escalate_call(self):
|
||||||
self.call.level = Rank.DIRECTOR
|
self.call.level = Rank.DIRECTOR
|
||||||
|
@ -63,7 +68,7 @@ class Supervisor(Employee):
|
||||||
class Director(Employee):
|
class Director(Employee):
|
||||||
|
|
||||||
def __init__(self, employee_id, name):
|
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):
|
def escalate_call(self):
|
||||||
raise NotImplementedError('Directors must be able to handle any call')
|
raise NotImplementedError('Directors must be able to handle any call')
|
||||||
|
@ -87,10 +92,12 @@ class Call(object):
|
||||||
class CallCenter(object):
|
class CallCenter(object):
|
||||||
|
|
||||||
def __init__(self, operators, supervisors, directors):
|
def __init__(self, operators, supervisors, directors):
|
||||||
self.operators = operators
|
self.operators = []
|
||||||
self.supervisors = supervisors
|
self.supervisors = []
|
||||||
self.directors = directors
|
self.directors = []
|
||||||
self.queued_calls = deque()
|
self.queued_calls = deque()
|
||||||
|
for employee in operators + supervisors + directors:
|
||||||
|
self.add_employee(employee)
|
||||||
|
|
||||||
def dispatch_call(self, call):
|
def dispatch_call(self, call):
|
||||||
if call.rank not in (Rank.OPERATOR, Rank.SUPERVISOR, Rank.DIRECTOR):
|
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)
|
employee = self._dispatch_call(call, self.supervisors)
|
||||||
if call.rank == Rank.DIRECTOR or employee is None:
|
if call.rank == Rank.DIRECTOR or employee is None:
|
||||||
employee = self._dispatch_call(call, self.directors)
|
employee = self._dispatch_call(call, self.directors)
|
||||||
|
|
||||||
if employee is None:
|
if employee is None:
|
||||||
self.queued_calls.append(call)
|
self.queued_calls.append(call)
|
||||||
|
|
||||||
|
@ -112,6 +120,18 @@ class CallCenter(object):
|
||||||
return employee
|
return employee
|
||||||
return None
|
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):
|
def notify_call_escalated(self, call):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue