diff --git a/app/dao/returned_letters_dao.py b/app/dao/returned_letters_dao.py index e69de29bb..24d8ae438 100644 --- a/app/dao/returned_letters_dao.py +++ b/app/dao/returned_letters_dao.py @@ -0,0 +1,40 @@ +from datetime import datetime + +from sqlalchemy.dialects.postgresql import insert + +from app import db +from app.dao.dao_utils import transactional +from app.models import Notification, NotificationHistory, ReturnedLetter + + +@transactional +def insert_or_update_returned_letters(references): + data = _get_notification_ids_for_references(references) + now = datetime.utcnow() + for row in data: + table = ReturnedLetter.__table__ + + stmt = insert(table).values( + reported_at=now, + service_id=row.service_id, + notification_id=row.id) + + stmt = stmt.on_conflict_do_update( + index_elements=[table.c.notification_id], + set_={ + 'reported_at': now, + } + ) + db.session.connection().execute(stmt) + + +def _get_notification_ids_for_references(references): + notification_ids = db.session.query(Notification.id, Notification.service_id).filter( + Notification.reference.in_(references) + ).all() + + notification_history_ids = db.session.query(NotificationHistory.id, NotificationHistory.service_id).filter( + NotificationHistory.reference.in_(references) + ).all() + + return notification_ids + notification_history_ids diff --git a/tests/app/dao/test_returned_letters_dao.py b/tests/app/dao/test_returned_letters_dao.py index e69de29bb..1a94f1fde 100644 --- a/tests/app/dao/test_returned_letters_dao.py +++ b/tests/app/dao/test_returned_letters_dao.py @@ -0,0 +1,83 @@ +from datetime import datetime + +from freezegun import freeze_time + +from app.dao.returned_letters_dao import insert_or_update_returned_letters +from app.models import ReturnedLetter +from tests.app.db import create_notification, create_notification_history + + +def test_insert_or_update_returned_letters_inserts(sample_letter_template): + notification = create_notification(template=sample_letter_template, + reference='ref1') + history = create_notification_history(template=sample_letter_template, + reference='ref2') + + assert ReturnedLetter.query.count() == 0 + + insert_or_update_returned_letters(['ref1', 'ref2']) + + returned_letters = ReturnedLetter.query.all() + + assert len(returned_letters) == 2 + returned_letters_ = [x.notification_id for x in returned_letters] + assert notification.id in returned_letters_ + assert history.id in returned_letters_ + + +def test_insert_or_update_returned_letters_updates(sample_letter_template): + notification = create_notification(template=sample_letter_template, + reference='ref1') + history = create_notification_history(template=sample_letter_template, + reference='ref2') + + assert ReturnedLetter.query.count() == 0 + with freeze_time('2019-12-09 13:30'): + insert_or_update_returned_letters(['ref1', 'ref2']) + returned_letters = ReturnedLetter.query.all() + assert len(returned_letters) == 2 + for x in returned_letters: + assert x.reported_at == datetime(2019, 12, 9, 13, 30) + assert x.notification_id in [notification.id, history.id] + + with freeze_time('2019-12-10 14:20'): + insert_or_update_returned_letters(['ref1', 'ref2']) + + returned_letters = ReturnedLetter.query.all() + assert len(returned_letters) == 2 + for x in returned_letters: + assert x.reported_at == datetime(2019, 12, 10, 14, 20) + assert x.notification_id in [notification.id, history.id] + + +def test_insert_or_update_returned_letters_when_no_notification(sample_letter_template): + insert_or_update_returned_letters(['ref1']) + assert ReturnedLetter.query.count() == 0 + + +def test_insert_or_update_returned_letters_for_history_only(sample_letter_template): + history_1 = create_notification_history(template=sample_letter_template, + reference='ref1') + history_2 = create_notification_history(template=sample_letter_template, + reference='ref2') + + assert ReturnedLetter.query.count() == 0 + insert_or_update_returned_letters(['ref1', 'ref2']) + returned_letters = ReturnedLetter.query.all() + assert len(returned_letters) == 2 + for x in returned_letters: + assert x.notification_id in [history_1.id, history_2.id] + + +def test_insert_or_update_returned_letters_with_duplicates_in_reference_list(sample_letter_template): + notification_1 = create_notification(template=sample_letter_template, + reference='ref1') + notification_2 = create_notification(template=sample_letter_template, + reference='ref2') + + assert ReturnedLetter.query.count() == 0 + insert_or_update_returned_letters(['ref1', 'ref2', 'ref1', 'ref2']) + returned_letters = ReturnedLetter.query.all() + assert len(returned_letters) == 2 + for x in returned_letters: + assert x.notification_id in [notification_1.id, notification_2.id]