mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-02 17:31:14 -05:00
Wrap the saving the notification and uploading the precompiled letter to
s3 in a transation. If the upload to s3 fails the notification will not be saved to the database.
This commit is contained in:
@@ -23,6 +23,7 @@ from app.celery.research_mode_tasks import create_fake_letter_response_file
|
|||||||
from app.celery.tasks import save_api_email, save_api_sms
|
from app.celery.tasks import save_api_email, save_api_sms
|
||||||
from app.clients.document_download import DocumentDownloadError
|
from app.clients.document_download import DocumentDownloadError
|
||||||
from app.config import QueueNames, TaskNames
|
from app.config import QueueNames, TaskNames
|
||||||
|
from app.dao.dao_utils import transaction
|
||||||
from app.dao.templates_dao import get_precompiled_letter_template
|
from app.dao.templates_dao import get_precompiled_letter_template
|
||||||
from app.letters.utils import upload_letter_pdf
|
from app.letters.utils import upload_letter_pdf
|
||||||
from app.models import (
|
from app.models import (
|
||||||
@@ -412,12 +413,14 @@ def process_precompiled_letter_notifications(*, letter_data, api_key, service, t
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
raise BadRequestError(message='Cannot decode letter content (invalid base64 encoding)', status_code=400)
|
raise BadRequestError(message='Cannot decode letter content (invalid base64 encoding)', status_code=400)
|
||||||
|
|
||||||
notification = create_letter_notification(letter_data=letter_data,
|
with transaction():
|
||||||
service=service,
|
notification = create_letter_notification(letter_data=letter_data,
|
||||||
template=template,
|
service=service,
|
||||||
api_key=api_key,
|
template=template,
|
||||||
status=status,
|
api_key=api_key,
|
||||||
reply_to_text=reply_to_text)
|
status=status,
|
||||||
|
reply_to_text=reply_to_text)
|
||||||
|
filename = upload_letter_pdf(notification, letter_content, precompiled=True)
|
||||||
|
|
||||||
resp = {
|
resp = {
|
||||||
'id': notification.id,
|
'id': notification.id,
|
||||||
@@ -425,8 +428,6 @@ def process_precompiled_letter_notifications(*, letter_data, api_key, service, t
|
|||||||
'postage': notification.postage
|
'postage': notification.postage
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = upload_letter_pdf(notification, letter_content, precompiled=True)
|
|
||||||
|
|
||||||
current_app.logger.info('Calling task scan-file for {}'.format(filename))
|
current_app.logger.info('Calling task scan-file for {}'.format(filename))
|
||||||
|
|
||||||
# call task to add the filename to anti virus queue
|
# call task to add the filename to anti virus queue
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ from app.models import (
|
|||||||
Job,
|
Job,
|
||||||
Notification,
|
Notification,
|
||||||
)
|
)
|
||||||
|
from app.notifications.process_letter_notifications import (
|
||||||
|
create_letter_notification,
|
||||||
|
)
|
||||||
from app.schema_validation import validate
|
from app.schema_validation import validate
|
||||||
from app.v2.errors import RateLimitError
|
from app.v2.errors import RateLimitError
|
||||||
from app.v2.notifications.notification_schemas import post_letter_response
|
from app.v2.notifications.notification_schemas import post_letter_response
|
||||||
@@ -673,6 +676,31 @@ def test_post_precompiled_letter_notification_returns_201(
|
|||||||
assert resp_json == {'id': str(notification.id), 'reference': 'letter-reference', 'postage': expected_postage}
|
assert resp_json == {'id': str(notification.id), 'reference': 'letter-reference', 'postage': expected_postage}
|
||||||
|
|
||||||
|
|
||||||
|
def test_post_precompiled_letter_notification_if_s3_upload_fails_notification_is_not_persisted(
|
||||||
|
client, notify_user, mocker
|
||||||
|
):
|
||||||
|
sample_service = create_service(service_permissions=['letter'])
|
||||||
|
persist_letter_mock = mocker.patch('app.v2.notifications.post_notifications.create_letter_notification',
|
||||||
|
side_effect=create_letter_notification)
|
||||||
|
s3mock = mocker.patch('app.v2.notifications.post_notifications.upload_letter_pdf', side_effect=Exception())
|
||||||
|
mocker.patch('app.celery.letters_pdf_tasks.notify_celery.send_task')
|
||||||
|
data = {
|
||||||
|
"reference": "letter-reference",
|
||||||
|
"content": "bGV0dGVyLWNvbnRlbnQ="
|
||||||
|
}
|
||||||
|
|
||||||
|
auth_header = create_authorization_header(service_id=sample_service.id)
|
||||||
|
with pytest.raises(expected_exception=Exception):
|
||||||
|
client.post(
|
||||||
|
path="v2/notifications/letter",
|
||||||
|
data=json.dumps(data),
|
||||||
|
headers=[('Content-Type', 'application/json'), auth_header])
|
||||||
|
|
||||||
|
assert s3mock.called
|
||||||
|
assert persist_letter_mock.called
|
||||||
|
assert Notification.query.count() == 0
|
||||||
|
|
||||||
|
|
||||||
def test_post_letter_notification_throws_error_for_invalid_postage(client, notify_user, mocker):
|
def test_post_letter_notification_throws_error_for_invalid_postage(client, notify_user, mocker):
|
||||||
sample_service = create_service(service_permissions=['letter'])
|
sample_service = create_service(service_permissions=['letter'])
|
||||||
data = {
|
data = {
|
||||||
|
|||||||
Reference in New Issue
Block a user