Skip to content

Commit

Permalink
Added Notifier
Browse files Browse the repository at this point in the history
  • Loading branch information
bobthemighty committed Feb 3, 2022
1 parent 509b5a1 commit aa0518a
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 31 deletions.
41 changes: 31 additions & 10 deletions python/delivery_controller.py
Expand Up @@ -23,16 +23,42 @@ class Delivery:
on_time: bool


class Notifier:

def request_feedback(self, delivery: Delivery):
raise NotImplemented()

def send_eta_update(self, delivery: Delivery, new_eta: int):
raise NotImplemented()

class SmtpNotifier:

def __init__(self, gateway: EmailGateway):
self.gateway = gateway

def request_feedback(self, delivery: Delivery):
message = f"""Regarding your delivery today at {delivery.time_of_delivery}. How likely would you be to recommend this delivery service to a friend? Click <a href="url">here</a>"""
self.gateway.send(
delivery.contact_email, "Your feedback is important to us", message
)

def send_eta_update(self, delivery: Delivery, new_eta: int):
message = f"Your delivery to {delivery.location} is next, estimated time of arrival is in {new_eta} minutes. Be ready!"
self.gateway.send(
delivery.contact_email, "Your delivery will arrive soon", message
)


class DeliveryController:
def __init__(
self,
delivery_schedule: List[Delivery],
gateway: Optional[EmailGateway],
notifier: Optional[Notifier] = None,
maps: Optional[MapService] = None,
):
self.delivery_schedule = delivery_schedule
self.email_gateway = gateway or EmailGateway()
self.map_service = maps or MapService()
self.notifier = notifier or SmtpNotifier(EmailGateway())

def update_delivery(self, delivery_event: DeliveryEvent):
next_delivery = None
Expand All @@ -45,10 +71,8 @@ def update_delivery(self, delivery_event: DeliveryEvent):
if time_difference < datetime.timedelta(minutes=10):
delivery.on_time = True
delivery.time_of_delivery = delivery_event.time_of_delivery
message = f"""Regarding your delivery today at {delivery.time_of_delivery}. How likely would you be to recommend this delivery service to a friend? Click <a href="url">here</a>"""
self.email_gateway.send(
delivery.contact_email, "Your feedback is important to us", message
)
self.notifier.request_feedback(delivery)

if len(self.delivery_schedule) > i + 1:
next_delivery = self.delivery_schedule[i + 1]
if not delivery.on_time and len(self.delivery_schedule) > 1 and i > 0:
Expand All @@ -63,7 +87,4 @@ def update_delivery(self, delivery_event: DeliveryEvent):
next_eta = self.map_service.calculate_eta(
delivery_event.location, next_delivery.location
)
message = f"Your delivery to {next_delivery.location} is next, estimated time of arrival is in {next_eta} minutes. Be ready!"
self.email_gateway.send(
next_delivery.contact_email, "Your delivery will arrive soon", message
)
self.notifier.send_eta_update(next_delivery, next_eta)
47 changes: 26 additions & 21 deletions python/test_delivery_service.py
@@ -1,13 +1,16 @@
import pytest
import datetime

from delivery_controller import DeliveryController, Delivery, DeliveryEvent
from delivery_controller import DeliveryController, Delivery, DeliveryEvent, SmtpNotifier
from map_service import MapService, Location

location1 = Location(52.2296756, 21.0122287)
location2 = Location(52.406374, 16.9251681)
location3 = Location(51.406374, 17.9251681)

now = datetime.datetime.now()
one_hour = datetime.timedelta(hours=1)


def test_map_service():
map_service = MapService()
Expand Down Expand Up @@ -48,30 +51,19 @@ def a_delivery(
id=id,
contact_email="fred@codefiend.co.uk",
location=location,
time_of_delivery=time or datetime.datetime.now,
time_of_delivery=time or now,
arrived=False,
on_time=False,
)


def test_a_single_delivery_is_delivered():

now = datetime.datetime.now()

delivery = Delivery(
id=1,
contact_email="fred@codefiend.co.uk",
location=location1,
time_of_delivery=now,
arrived=False,
on_time=True,
)

update = DeliveryEvent(1, now, location2)
delivery = a_delivery(1)
gateway = FakeEmailGateway()
controller = DeliveryController([delivery], gateway)
controller = DeliveryController([delivery], SmtpNotifier(gateway))

controller.update_delivery(update)
controller.update_delivery(DeliveryEvent(1, now, location2))

assert delivery.arrived is True
assert delivery.on_time is True
Expand All @@ -87,11 +79,19 @@ def test_a_single_delivery_is_delivered():
)


now = datetime.datetime.now()
one_hour = datetime.timedelta(hours=1)


def test_when_a_delivery_affects_the_schedule():
"""
In this scenario, we have three deliveries to three locations.
The first is scheduled to happen now, the second in an hour, the third in
two hours.
When the second delivery is delivered an hour late, we should call the map
service to recalculate our average speed.
We should send an email to the recipient of delivery 3 with the updated
ETA.
"""

deliveries = [
a_delivery(1, time=now, location=location1),
Expand All @@ -100,8 +100,8 @@ def test_when_a_delivery_affects_the_schedule():
]

gateway = FakeEmailGateway()
maps = FakeMapService(10)
controller = DeliveryController(deliveries, gateway, maps)
maps = FakeMapService(325)
controller = DeliveryController(deliveries, SmtpNotifier(gateway), maps)

controller.update_delivery(DeliveryEvent(2, now + (one_hour * 2), location2))

Expand All @@ -110,3 +110,8 @@ def test_when_a_delivery_affects_the_schedule():
assert start == location1
assert end == location2
assert time == (one_hour * 2)

[_,(address, subject, message)] = gateway.sent

assert subject == "Your delivery will arrive soon"
assert message == f"Your delivery to {location3} is next, estimated time of arrival is in 325 minutes. Be ready!"

0 comments on commit aa0518a

Please sign in to comment.