Skip to content

Commit 86fb27b

Browse files
authored
Ignore SUCCESSFUL pinpoint receipts (#2176)
1 parent 6770073 commit 86fb27b

File tree

3 files changed

+65
-8
lines changed

3 files changed

+65
-8
lines changed

app/aws/mocks.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,33 @@ def sns_failed_callback(provider_response, reference=None, timestamp="2016-06-28
193193

194194

195195
# Note that 1467074434 = 2016-06-28 00:40:34.558 UTC
196-
def pinpoint_success_callback(reference=None, timestamp=1467074434, destination="+1XXX5550100"):
196+
def pinpoint_successful_callback(reference=None, timestamp=1467074434, destination="+1XXX5550100"):
197+
body = {
198+
"eventType": "TEXT_SUCCESSFUL",
199+
"eventVersion": "1.0",
200+
"eventTimestamp": timestamp,
201+
"isFinal": False,
202+
"originationPhoneNumber": "+18078061258",
203+
"destinationPhoneNumber": destination,
204+
"isoCountryCode": "CA",
205+
"mcc": "302",
206+
"mnc": "610",
207+
"carrierName": "Bell Cellular Inc. / Aliant Telecom",
208+
"messageId": reference,
209+
"messageRequestTimestamp": timestamp,
210+
"messageEncoding": "GSM",
211+
"messageType": "TRANSACTIONAL",
212+
"messageStatus": "SUCCESSFUL",
213+
"messageStatusDescription": "Message has been accepted by phone carrier",
214+
"totalMessageParts": 1,
215+
"totalMessagePrice": 0.00581,
216+
"totalCarrierFee": 0.00767,
217+
}
218+
219+
return _pinpoint_callback(body)
220+
221+
222+
def pinpoint_delivered_callback(reference=None, timestamp=1467074434, destination="+1XXX5550100"):
197223
body = {
198224
"eventType": "TEXT_DELIVERED",
199225
"eventVersion": "1.0",

app/celery/process_pinpoint_receipts_tasks.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ def process_pinpoint_results(self, response):
5353
provider_response = receipt["messageStatusDescription"]
5454

5555
notification_status = determine_pinpoint_status(status, provider_response)
56+
57+
if notification_status == NOTIFICATION_SENT:
58+
return # we don't want to update the status to sent if it's already sent
59+
5660
if not notification_status:
5761
current_app.logger.warning(f"unhandled provider response for reference {reference}, received '{provider_response}'")
5862
notification_status = NOTIFICATION_TECHNICAL_FAILURE # revert to tech failure by default
@@ -125,6 +129,8 @@ def determine_pinpoint_status(status: str, provider_response: str) -> Union[str,
125129

126130
if status == "DELIVERED":
127131
return NOTIFICATION_DELIVERED
132+
elif status == "SUCCESSFUL": # carrier has accepted the message but it hasn't gone to the phone yet
133+
return NOTIFICATION_SENT
128134

129135
response_lower = provider_response.lower()
130136

tests/app/celery/test_process_pinpoint_receipts_tasks.py

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@
44
from freezegun import freeze_time
55

66
from app import statsd_client
7-
from app.aws.mocks import pinpoint_failed_callback, pinpoint_success_callback
7+
from app.aws.mocks import (
8+
pinpoint_delivered_callback,
9+
pinpoint_failed_callback,
10+
pinpoint_successful_callback,
11+
)
812
from app.celery.process_pinpoint_receipts_tasks import process_pinpoint_results
913
from app.dao.notifications_dao import get_notification_by_id
1014
from app.models import (
@@ -39,7 +43,7 @@ def test_process_pinpoint_results_delivered(sample_template, notify_db, notify_d
3943
)
4044
assert get_notification_by_id(notification.id).status == NOTIFICATION_SENT
4145

42-
process_pinpoint_results(pinpoint_success_callback(reference="ref"))
46+
process_pinpoint_results(pinpoint_delivered_callback(reference="ref"))
4347

4448
assert mock_callback_task.called_once_with(get_notification_by_id(notification.id))
4549
assert get_notification_by_id(notification.id).status == NOTIFICATION_DELIVERED
@@ -48,6 +52,27 @@ def test_process_pinpoint_results_delivered(sample_template, notify_db, notify_d
4852
mock_logger.assert_called_once_with(f"Pinpoint callback return status of delivered for notification: {notification.id}")
4953

5054

55+
def test_process_pinpoint_results_succeeded(sample_template, notify_db, notify_db_session, mocker):
56+
mock_callback_task = mocker.patch("app.notifications.callbacks._check_and_queue_callback_task")
57+
58+
notification = create_sample_notification(
59+
notify_db,
60+
notify_db_session,
61+
template=sample_template,
62+
reference="ref",
63+
status=NOTIFICATION_SENT,
64+
sent_by="pinpoint",
65+
sent_at=datetime.utcnow(),
66+
)
67+
assert get_notification_by_id(notification.id).status == NOTIFICATION_SENT
68+
69+
process_pinpoint_results(pinpoint_successful_callback(reference="ref"))
70+
71+
assert mock_callback_task.not_called()
72+
assert get_notification_by_id(notification.id).status == NOTIFICATION_SENT
73+
assert get_notification_by_id(notification.id).provider_response is None
74+
75+
5176
@pytest.mark.parametrize(
5277
"provider_response, expected_status, should_log_warning, should_save_provider_response",
5378
[
@@ -120,7 +145,7 @@ def test_pinpoint_callback_should_retry_if_notification_is_missing(notify_db, mo
120145
mock_retry = mocker.patch("app.celery.process_pinpoint_receipts_tasks.process_pinpoint_results.retry")
121146
mock_callback_task = mocker.patch("app.notifications.callbacks._check_and_queue_callback_task")
122147

123-
process_pinpoint_results(pinpoint_success_callback(reference="ref"))
148+
process_pinpoint_results(pinpoint_delivered_callback(reference="ref"))
124149

125150
mock_callback_task.assert_not_called()
126151
assert mock_retry.call_count == 1
@@ -134,7 +159,7 @@ def test_pinpoint_callback_should_give_up_after_max_tries(notify_db, mocker):
134159
mock_logger = mocker.patch("app.celery.process_pinpoint_receipts_tasks.current_app.logger.warning")
135160
mock_callback_task = mocker.patch("app.notifications.callbacks._check_and_queue_callback_task")
136161

137-
process_pinpoint_results(pinpoint_success_callback(reference="ref")) is None
162+
process_pinpoint_results(pinpoint_delivered_callback(reference="ref")) is None
138163
mock_callback_task.assert_not_called()
139164

140165
mock_logger.assert_called_with("notification not found for Pinpoint reference: ref (update to delivered). Giving up.")
@@ -156,7 +181,7 @@ def test_process_pinpoint_results_retry_called(sample_template, mocker):
156181
side_effect=Exception("EXPECTED"),
157182
)
158183
mocked = mocker.patch("app.celery.process_pinpoint_receipts_tasks.process_pinpoint_results.retry")
159-
process_pinpoint_results(response=pinpoint_success_callback(reference="ref1"))
184+
process_pinpoint_results(response=pinpoint_delivered_callback(reference="ref1"))
160185
assert mocked.call_count == 1
161186

162187

@@ -173,7 +198,7 @@ def test_process_pinpoint_results_does_not_process_other_providers(sample_templa
173198
)
174199
)
175200

176-
process_pinpoint_results(response=pinpoint_success_callback(reference="ref1")) is None
201+
process_pinpoint_results(response=pinpoint_delivered_callback(reference="ref1")) is None
177202
assert mock_logger.called_once_with("")
178203
assert not mock_dao.called
179204

@@ -197,7 +222,7 @@ def test_process_pinpoint_results_calls_service_callback(sample_template, notify
197222
callback_api = create_service_callback_api(service=sample_template.service, url="https://example.com")
198223
assert get_notification_by_id(notification.id).status == NOTIFICATION_SENT
199224

200-
process_pinpoint_results(pinpoint_success_callback(reference="ref"))
225+
process_pinpoint_results(pinpoint_delivered_callback(reference="ref"))
201226

202227
assert mock_callback.called_once_with(get_notification_by_id(notification.id))
203228
assert get_notification_by_id(notification.id).status == NOTIFICATION_DELIVERED

0 commit comments

Comments
 (0)