mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-04 02:11:11 -05:00
Mark letters as validation-failed if the templated letter is too long.
It is possible that the personalisation for a templated letter can make the letter exceed 10 pages or 5 sheets. We are not validating the letters posted via the API for this validation error. It is only possible to validate the letter once we create the PDF in notifications-template-preview. This means that the letter can only get a validation-failed status after the client has received a 201 from the POST to /v2/notifications.
NOTE: we only validate the preview row of a CSV for this validation error, this change will mean that it is possible for a letter to be marked as validation-failed after a successful file upload.
A new task to update the notification to `validation-failed` has been added to the API. If we find that the letter is too long once we have created the PDF we call the `update-validation-failed-for-templated-letter` task rather than `update-billable-units-for-letter` task.
New work flow for a letter in brief:
API - receives POST /v2/notifications
:: save to db
:: put CREATE_LETTERS_PDF task on queue for template preview to consume
TEMPLATE-PREVIEW - consumes task CREATE_LETTERS_PDF
:: create PDF
:: count pages of PDF
:: IF page count exceeds 10 pages
put in the letters-invalid-pdf S3 bucket with metadata (similar to the precompiled letters)
put `update-validation-failed-for-templated-letter` task on the queue for the API to consume
ELSE
put PDF in the `letters-pdf` bucket
put `update-billable-units-for-letter` task on the queue
API - consumes `update-billable-units-for-letter` OR `update-validation-failed-for-templated-letter` task
:: IF `update-billable-units-for-letter` task:
update billable units for notification as usual
:: ELSE `update-validation-failed-for-templated-letter`:
update notification_status = `validation-failed`
ADMIN - view notification page for letter
:: show validation letter for templated letter
There will be 3 PRs in order to make this change, one for the API, template-preview and the admin app.
Deployment plan
Deploy Admin first
Deploy API
Deploy template-preview
Related PRs:
alphagov/notifications-template-preview#619
alphagov/notifications-admin#4107
https://www.pivotaltracker.com/story/show/169209742
This commit is contained in:
@@ -26,7 +26,7 @@ from app.celery.letters_pdf_tasks import (
|
||||
resanitise_pdf,
|
||||
sanitise_letter,
|
||||
send_letters_volume_email_to_dvla,
|
||||
update_billable_units_for_letter,
|
||||
update_billable_units_or_validation_failed_for_templated_letter,
|
||||
)
|
||||
from app.config import QueueNames, TaskNames
|
||||
from app.dao.notifications_dao import get_notifications
|
||||
@@ -146,32 +146,55 @@ def test_get_pdf_for_templated_letter_sets_technical_failure_max_retries(mocker,
|
||||
|
||||
|
||||
@pytest.mark.parametrize('number_of_pages, expected_billable_units', [(2, 1), (3, 2), (10, 5)])
|
||||
def test_update_billable_units_for_letter(mocker, sample_letter_notification, number_of_pages, expected_billable_units):
|
||||
def test_update_billable_units_or_validation_failed_for_templated_letter(
|
||||
mocker, sample_letter_notification, number_of_pages, expected_billable_units
|
||||
):
|
||||
sample_letter_notification.billable_units = 0
|
||||
mock_logger = mocker.patch('app.celery.tasks.current_app.logger.info')
|
||||
|
||||
update_billable_units_for_letter(sample_letter_notification.id, number_of_pages)
|
||||
update_billable_units_or_validation_failed_for_templated_letter(sample_letter_notification.id, number_of_pages)
|
||||
|
||||
notification = Notification.query.filter(Notification.reference == sample_letter_notification.reference).one()
|
||||
assert notification.billable_units == expected_billable_units
|
||||
assert sample_letter_notification.status == NOTIFICATION_CREATED
|
||||
mock_logger.assert_called_once_with(
|
||||
f"Letter notification id: {sample_letter_notification.id} reference {sample_letter_notification.reference}:"
|
||||
f" billable units set to {expected_billable_units}"
|
||||
)
|
||||
|
||||
|
||||
def test_update_billable_units_for_letter_doesnt_update_if_sent_with_test_key(mocker, sample_letter_notification):
|
||||
def test_update_billable_units_or_validation_failed_for_templated_letter_doesnt_update_if_sent_with_test_key(
|
||||
mocker, sample_letter_notification
|
||||
):
|
||||
sample_letter_notification.billable_units = 0
|
||||
sample_letter_notification.key_type = KEY_TYPE_TEST
|
||||
mock_logger = mocker.patch('app.celery.tasks.current_app.logger.info')
|
||||
|
||||
update_billable_units_for_letter(sample_letter_notification.id, 2)
|
||||
update_billable_units_or_validation_failed_for_templated_letter(sample_letter_notification.id, 2)
|
||||
|
||||
notification = Notification.query.filter(Notification.reference == sample_letter_notification.reference).one()
|
||||
assert notification.billable_units == 0
|
||||
mock_logger.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.parametrize('key_type', ['test', 'normal', 'team'])
|
||||
def test_update_billable_units_or_validation_failed_for_templated_letter_with_too_many_pages(
|
||||
mocker, sample_letter_notification, key_type
|
||||
):
|
||||
sample_letter_notification.billable_units = 0
|
||||
sample_letter_notification.key_type = key_type
|
||||
mock_logger = mocker.patch('app.celery.tasks.current_app.logger.info')
|
||||
|
||||
update_billable_units_or_validation_failed_for_templated_letter(sample_letter_notification.id, 11)
|
||||
|
||||
assert sample_letter_notification.billable_units == 0
|
||||
assert sample_letter_notification.status == NOTIFICATION_VALIDATION_FAILED
|
||||
mock_logger.assert_called_once_with(
|
||||
f"Letter notification id: {sample_letter_notification.id} reference {sample_letter_notification.reference}: "
|
||||
f"validation failed: letter is too long 11"
|
||||
)
|
||||
|
||||
|
||||
@mock_s3
|
||||
@freeze_time('2020-02-17 18:00:00')
|
||||
def test_get_key_and_size_of_letters_to_be_sent_to_print(
|
||||
|
||||
Reference in New Issue
Block a user