Merge branch 'main' into 2199-add-pending-message-data-to-daily-and-user_daily-stats

This commit is contained in:
Beverly Nguyen
2025-01-21 16:40:19 -08:00
98 changed files with 1678 additions and 743 deletions

View File

@@ -150,7 +150,9 @@ def test_send_notification_with_placeholders_replaced(
{"template_version": sample_email_template_with_placeholders.version}
)
mocked.assert_called_once_with([notification_id], queue="send-email-tasks")
mocked.assert_called_once_with(
[notification_id], queue="send-email-tasks", countdown=60
)
assert response.status_code == 201
assert response_data["body"] == "Hello Jo\nThis is an email from GOV.UK"
assert response_data["subject"] == "Jo"
@@ -420,7 +422,9 @@ def test_should_allow_valid_sms_notification(notify_api, sample_template, mocker
response_data = json.loads(response.data)["data"]
notification_id = response_data["notification"]["id"]
mocked.assert_called_once_with([notification_id], queue="send-sms-tasks")
mocked.assert_called_once_with(
[notification_id], queue="send-sms-tasks", countdown=60
)
assert response.status_code == 201
assert notification_id
assert "subject" not in response_data
@@ -476,7 +480,7 @@ def test_should_allow_valid_email_notification(
response_data = json.loads(response.get_data(as_text=True))["data"]
notification_id = response_data["notification"]["id"]
app.celery.provider_tasks.deliver_email.apply_async.assert_called_once_with(
[notification_id], queue="send-email-tasks"
[notification_id], queue="send-email-tasks", countdown=60
)
assert response.status_code == 201
@@ -620,7 +624,7 @@ def test_should_send_email_if_team_api_key_and_a_service_user(
)
app.celery.provider_tasks.deliver_email.apply_async.assert_called_once_with(
[fake_uuid], queue="send-email-tasks"
[fake_uuid], queue="send-email-tasks", countdown=60
)
assert response.status_code == 201
@@ -658,7 +662,7 @@ def test_should_send_sms_to_anyone_with_test_key(
],
)
app.celery.provider_tasks.deliver_sms.apply_async.assert_called_once_with(
[fake_uuid], queue="send-sms-tasks"
[fake_uuid], queue="send-sms-tasks", countdown=60
)
assert response.status_code == 201
@@ -697,7 +701,7 @@ def test_should_send_email_to_anyone_with_test_key(
)
app.celery.provider_tasks.deliver_email.apply_async.assert_called_once_with(
[fake_uuid], queue="send-email-tasks"
[fake_uuid], queue="send-email-tasks", countdown=60
)
assert response.status_code == 201
@@ -735,7 +739,7 @@ def test_should_send_sms_if_team_api_key_and_a_service_user(
)
app.celery.provider_tasks.deliver_sms.apply_async.assert_called_once_with(
[fake_uuid], queue="send-sms-tasks"
[fake_uuid], queue="send-sms-tasks", countdown=60
)
assert response.status_code == 201
@@ -792,7 +796,7 @@ def test_should_persist_notification(
],
)
mocked.assert_called_once_with([fake_uuid], queue=queue_name)
mocked.assert_called_once_with([fake_uuid], queue=queue_name, countdown=60)
assert response.status_code == 201
notification = notifications_dao.get_notification_by_id(fake_uuid)
@@ -853,9 +857,9 @@ def test_should_delete_notification_and_return_error_if_redis_fails(
)
assert str(e.value) == "failed to talk to redis"
mocked.assert_called_once_with([fake_uuid], queue=queue_name)
mocked.assert_called_once_with([fake_uuid], queue=queue_name, countdown=60)
assert not notifications_dao.get_notification_by_id(fake_uuid)
assert not NotificationHistory.query.get(fake_uuid)
assert not db.session.get(NotificationHistory, fake_uuid)
@pytest.mark.parametrize(
@@ -1065,7 +1069,7 @@ def test_should_error_if_notification_type_does_not_match_template_type(
def test_create_template_raises_invalid_request_exception_with_missing_personalisation(
sample_template_with_placeholders,
):
template = Template.query.get(sample_template_with_placeholders.id)
template = db.session.get(Template, sample_template_with_placeholders.id)
from app.notifications.rest import create_template_object_for_notification
with pytest.raises(InvalidRequest) as e:
@@ -1078,7 +1082,7 @@ def test_create_template_doesnt_raise_with_too_much_personalisation(
):
from app.notifications.rest import create_template_object_for_notification
template = Template.query.get(sample_template_with_placeholders.id)
template = db.session.get(Template, sample_template_with_placeholders.id)
create_template_object_for_notification(template, {"name": "Jo", "extra": "stuff"})
@@ -1095,7 +1099,7 @@ def test_create_template_raises_invalid_request_when_content_too_large(
sample = create_template(
sample_service, template_type=template_type, content="((long_text))"
)
template = Template.query.get(sample.id)
template = db.session.get(Template, sample.id)
from app.notifications.rest import create_template_object_for_notification
try:
@@ -1185,10 +1189,12 @@ def test_should_allow_store_original_number_on_sms_notification(
response_data = json.loads(response.data)["data"]
notification_id = response_data["notification"]["id"]
mocked.assert_called_once_with([notification_id], queue="send-sms-tasks")
mocked.assert_called_once_with(
[notification_id], queue="send-sms-tasks", countdown=60
)
assert response.status_code == 201
assert notification_id
notifications = Notification.query.all()
notifications = db.session.execute(select(Notification)).scalars().all()
assert len(notifications) == 1
assert "1" == notifications[0].to
@@ -1349,7 +1355,7 @@ def test_post_notification_should_set_reply_to_text(
],
)
assert response.status_code == 201
notifications = Notification.query.all()
notifications = db.session.execute(select(Notification)).scalars().all()
assert len(notifications) == 1
assert notifications[0].reply_to_text == expected_reply_to
@@ -1377,5 +1383,5 @@ def test_send_notification_should_set_client_reference_from_placeholder(
notification_id = send_one_off_notification(sample_letter_template.service_id, data)
assert deliver_mock.called
notification = Notification.query.get(notification_id["id"])
notification = db.session.get(Notification, notification_id["id"])
assert notification.client_reference == reference_paceholder

View File

@@ -3,6 +3,7 @@ from unittest.mock import Mock
import pytest
from app import db
from app.dao.service_guest_list_dao import dao_add_and_commit_guest_list_contacts
from app.enums import (
KeyType,
@@ -266,7 +267,7 @@ def test_send_one_off_notification_should_add_email_reply_to_text_for_notificati
notification_id = send_one_off_notification(
service_id=sample_email_template.service.id, post_data=data
)
notification = Notification.query.get(notification_id["id"])
notification = db.session.get(Notification, notification_id["id"])
celery_mock.assert_called_once_with(notification=notification, queue=None)
assert notification.reply_to_text == reply_to_email.email_address
@@ -289,7 +290,7 @@ def test_send_one_off_sms_notification_should_use_sms_sender_reply_to_text(
notification_id = send_one_off_notification(
service_id=sample_service.id, post_data=data
)
notification = Notification.query.get(notification_id["id"])
notification = db.session.get(Notification, notification_id["id"])
celery_mock.assert_called_once_with(notification=notification, queue=None)
assert notification.reply_to_text == "+12028675309"
@@ -313,7 +314,7 @@ def test_send_one_off_sms_notification_should_use_default_service_reply_to_text(
notification_id = send_one_off_notification(
service_id=sample_service.id, post_data=data
)
notification = Notification.query.get(notification_id["id"])
notification = db.session.get(Notification, notification_id["id"])
celery_mock.assert_called_once_with(notification=notification, queue=None)
assert notification.reply_to_text == "+12028675309"

View File

@@ -27,7 +27,13 @@ def test_api_key_should_create_new_api_key_for_service(notify_api, sample_servic
)
assert response.status_code == 201
assert "data" in json.loads(response.get_data(as_text=True))
saved_api_key = ApiKey.query.filter_by(service_id=sample_service.id).first()
saved_api_key = (
db.session.execute(
select(ApiKey).where(ApiKey.service_id == sample_service.id)
)
.scalars()
.first()
)
assert saved_api_key.service_id == sample_service.id
assert saved_api_key.name == "some secret name"
@@ -81,7 +87,7 @@ def test_revoke_should_expire_api_key_for_service(notify_api, sample_api_key):
headers=[auth_header],
)
assert response.status_code == 202
api_keys_for_service = ApiKey.query.get(sample_api_key.id)
api_keys_for_service = db.session.get(ApiKey, sample_api_key.id)
assert api_keys_for_service.expiry_date is not None

View File

@@ -3,6 +3,7 @@ from datetime import datetime
import pytest
from freezegun import freeze_time
from sqlalchemy import select
from app import db
from app.dao.api_key_dao import expire_api_key
@@ -85,8 +86,12 @@ def test_deactivating_service_archives_templates(archived_service):
def test_deactivating_service_creates_history(archived_service):
ServiceHistory = Service.get_history_model()
history = (
ServiceHistory.query.filter_by(id=archived_service.id)
.order_by(ServiceHistory.version.desc())
db.session.execute(
select(ServiceHistory)
.where(ServiceHistory.id == archived_service.id)
.order_by(ServiceHistory.version.desc())
)
.scalars()
.first()
)

View File

@@ -1,5 +1,8 @@
import uuid
from sqlalchemy import func, select
from app import db
from app.models import ServiceCallbackApi, ServiceInboundApi
from tests.app.db import create_service_callback_api, create_service_inbound_api
@@ -101,7 +104,10 @@ def test_delete_service_inbound_api(admin_request, sample_service):
)
assert response is None
assert ServiceInboundApi.query.count() == 0
stmt = select(func.count()).select_from(ServiceInboundApi)
count = db.session.execute(stmt).scalar() or 0
assert count == 0
def test_create_service_callback_api(admin_request, sample_service):
@@ -207,4 +213,7 @@ def test_delete_service_callback_api(admin_request, sample_service):
)
assert response is None
assert ServiceCallbackApi.query.count() == 0
stmt = select(func.count()).select_from(ServiceCallbackApi)
count = db.session.execute(stmt).scalar() or 0
assert count == 0

View File

@@ -415,7 +415,7 @@ def test_create_service(
assert json_resp["data"]["email_from"] == "created.service"
assert json_resp["data"]["count_as_live"] is expected_count_as_live
service_db = Service.query.get(json_resp["data"]["id"])
service_db = db.session.get(Service, json_resp["data"]["id"])
assert service_db.name == "created service"
json_resp = admin_request.get(
@@ -501,10 +501,11 @@ def test_create_service_should_create_annual_billing_for_service(
"email_from": "created.service",
"created_by": str(sample_user.id),
}
assert len(AnnualBilling.query.all()) == 0
assert len(db.session.execute(select(AnnualBilling)).scalars().all()) == 0
admin_request.post("service.create_service", _data=data, _expected_status=201)
annual_billing = AnnualBilling.query.all()
annual_billing = db.session.execute(select(AnnualBilling)).scalars().all()
assert len(annual_billing) == 1
@@ -525,11 +526,11 @@ def test_create_service_should_raise_exception_and_not_create_service_if_annual_
"email_from": "created.service",
"created_by": str(sample_user.id),
}
assert len(AnnualBilling.query.all()) == 0
assert len(db.session.execute(select(AnnualBilling)).scalars().all()) == 0
with pytest.raises(expected_exception=SQLAlchemyError):
admin_request.post("service.create_service", _data=data)
annual_billing = AnnualBilling.query.all()
annual_billing = db.session.execute(select(AnnualBilling)).scalars().all()
assert len(annual_billing) == 0
stmt = (
select(func.count())
@@ -2849,7 +2850,7 @@ def test_send_one_off_notification(sample_service, admin_request, mocker):
_expected_status=201,
)
noti = Notification.query.one()
noti = db.session.execute(select(Notification)).scalars().one()
assert response["id"] == str(noti.id)
@@ -3039,11 +3040,11 @@ def test_verify_reply_to_email_address_should_send_verification_email(
_expected_status=201,
)
notification = Notification.query.first()
notification = db.session.execute(select(Notification)).scalars().first()
assert notification.template_id == verify_reply_to_address_email_template.id
assert response["data"] == {"id": str(notification.id)}
mocked.assert_called_once_with(
[str(notification.id)], queue="notify-internal-tasks"
[str(notification.id)], queue="notify-internal-tasks", countdown=60
)
assert (
notification.reply_to_text
@@ -3078,7 +3079,7 @@ def test_add_service_reply_to_email_address(admin_request, sample_service):
_expected_status=201,
)
results = ServiceEmailReplyTo.query.all()
results = db.session.execute(select(ServiceEmailReplyTo)).scalars().all()
assert len(results) == 1
assert response["data"] == results[0].serialize()
@@ -3118,7 +3119,7 @@ def test_add_service_reply_to_email_address_can_add_multiple_addresses(
_data=second,
_expected_status=201,
)
results = ServiceEmailReplyTo.query.all()
results = db.session.execute(select(ServiceEmailReplyTo)).scalars().all()
assert len(results) == 2
default = [x for x in results if x.is_default]
assert response["data"] == default[0].serialize()
@@ -3169,7 +3170,7 @@ def test_update_service_reply_to_email_address(admin_request, sample_service):
_expected_status=200,
)
results = ServiceEmailReplyTo.query.all()
results = db.session.execute(select(ServiceEmailReplyTo)).scalars().all()
assert len(results) == 1
assert response["data"] == results[0].serialize()
@@ -3281,7 +3282,7 @@ def test_add_service_sms_sender_can_add_multiple_senders(client, notify_db_sessi
resp_json = json.loads(response.get_data(as_text=True))
assert resp_json["sms_sender"] == "second"
assert not resp_json["is_default"]
senders = ServiceSmsSender.query.all()
senders = db.session.execute(select(ServiceSmsSender)).scalars().all()
assert len(senders) == 2
@@ -3307,7 +3308,7 @@ def test_add_service_sms_sender_when_it_is_an_inbound_number_updates_the_only_ex
],
)
assert response.status_code == 201
updated_number = InboundNumber.query.get(inbound_number.id)
updated_number = db.session.get(InboundNumber, inbound_number.id)
assert updated_number.service_id == service.id
resp_json = json.loads(response.get_data(as_text=True))
assert resp_json["sms_sender"] == inbound_number.number
@@ -3338,7 +3339,7 @@ def test_add_service_sms_sender_when_it_is_an_inbound_number_inserts_new_sms_sen
],
)
assert response.status_code == 201
updated_number = InboundNumber.query.get(inbound_number.id)
updated_number = db.session.get(InboundNumber, inbound_number.id)
assert updated_number.service_id == service.id
resp_json = json.loads(response.get_data(as_text=True))
assert resp_json["sms_sender"] == inbound_number.number

View File

@@ -23,7 +23,7 @@ def test_send_notification_to_service_users_persists_notifications_correctly(
service_id=sample_service.id, template_id=template.id
)
notification = Notification.query.one()
notification = db.session.execute(select(Notification)).scalars().one()
stmt = select(func.count()).select_from(Notification)
count = db.session.execute(stmt).scalar() or 0

View File

@@ -1,6 +1,9 @@
import json
import uuid
from sqlalchemy import select
from app import db
from app.enums import NotificationType
from app.models import ServiceDataRetention
from tests import create_admin_authorization_header
@@ -106,7 +109,7 @@ def test_create_service_data_retention(client, sample_service):
assert response.status_code == 201
json_resp = json.loads(response.get_data(as_text=True))["result"]
results = ServiceDataRetention.query.all()
results = db.session.execute(select(ServiceDataRetention)).scalars().all()
assert len(results) == 1
data_retention = results[0]
assert json_resp == data_retention.serialize()

View File

@@ -1,6 +1,9 @@
import json
import uuid
from sqlalchemy import select
from app import db
from app.dao.service_guest_list_dao import dao_add_and_commit_guest_list_contacts
from app.enums import RecipientType
from app.models import ServiceGuestList
@@ -87,7 +90,13 @@ def test_update_guest_list_replaces_old_guest_list(client, sample_service_guest_
)
assert response.status_code == 204
guest_list = ServiceGuestList.query.order_by(ServiceGuestList.recipient).all()
guest_list = (
db.session.execute(
select(ServiceGuestList).order_by(ServiceGuestList.recipient)
)
.scalars()
.all()
)
assert len(guest_list) == 2
assert guest_list[0].recipient == "+12028765309"
assert guest_list[1].recipient == "foo@bar.com"
@@ -112,5 +121,5 @@ def test_update_guest_list_doesnt_remove_old_guest_list_if_error(
"result": "error",
"message": 'Invalid guest list: "" is not a valid email address or phone number',
}
guest_list = ServiceGuestList.query.one()
guest_list = db.session.execute(select(ServiceGuestList)).scalars().one()
assert guest_list.id == sample_service_guest_list.id

View File

@@ -3,7 +3,9 @@ from datetime import datetime
import pytest
from freezegun import freeze_time
from sqlalchemy import select
from app import db
from app.models import Service
from tests import create_admin_authorization_header
@@ -77,8 +79,12 @@ def test_service_history_is_created(client, sample_service, action, original_sta
)
ServiceHistory = Service.get_history_model()
history = (
ServiceHistory.query.filter_by(id=sample_service.id)
.order_by(ServiceHistory.version.desc())
db.session.execute(
select(ServiceHistory)
.where(ServiceHistory.id == sample_service.id)
.order_by(ServiceHistory.version.desc())
)
.scalars()
.first()
)