Skip to content

Commit

Permalink
#1178 Rev2 Remove Letter and PDF (#1473)
Browse files Browse the repository at this point in the history
remove letter and pdf endpoints and test cases
  • Loading branch information
babyjunior56 authored Oct 3, 2023
1 parent b96b62f commit 431dccf
Show file tree
Hide file tree
Showing 4 changed files with 1 addition and 273 deletions.
41 changes: 1 addition & 40 deletions app/v2/notifications/get_notifications.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
from io import BytesIO

from flask import jsonify, request, url_for, current_app, send_file

from flask import jsonify, request, url_for, current_app
from app import api_user, authenticated_service
from app.dao import notifications_dao
from app.letters.utils import get_letter_pdf
from app.schema_validation import validate
from app.v2.errors import BadRequestError, PDFNotReadyError
from app.v2.notifications import v2_notification_blueprint
from app.v2.notifications.notification_schemas import get_notifications_request, notification_by_id
from app.models import (
NOTIFICATION_PENDING_VIRUS_CHECK,
NOTIFICATION_VIRUS_SCAN_FAILED,
NOTIFICATION_TECHNICAL_FAILURE,
LETTER_TYPE,
)


@v2_notification_blueprint.route("/<notification_id>", methods=['GET'])
Expand All @@ -27,34 +16,6 @@ def get_notification_by_id(notification_id):
return jsonify(notification.serialize()), 200


@v2_notification_blueprint.route('/<notification_id>/pdf', methods=['GET'])
def get_pdf_for_notification(notification_id):
_data = {"notification_id": notification_id}
validate(_data, notification_by_id)
notification = notifications_dao.get_notification_by_id(
notification_id, authenticated_service.id, _raise=True
)

if notification.notification_type != LETTER_TYPE:
raise BadRequestError(message="Notification is not a letter")

if notification.status == NOTIFICATION_VIRUS_SCAN_FAILED:
raise BadRequestError(message='Document did not pass the virus scan')

if notification.status == NOTIFICATION_TECHNICAL_FAILURE:
raise BadRequestError(message='PDF not available for letters in status {}'.format(notification.status))

if notification.status == NOTIFICATION_PENDING_VIRUS_CHECK:
raise PDFNotReadyError()

try:
pdf_data = get_letter_pdf(notification)
except Exception:
raise PDFNotReadyError()

return send_file(path_or_file=BytesIO(pdf_data), mimetype='application/pdf')


@v2_notification_blueprint.route("", methods=['GET'])
def get_notifications():
_data = request.args.to_dict(flat=False)
Expand Down
43 changes: 0 additions & 43 deletions app/v2/notifications/post_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from app.celery.research_mode_tasks import create_fake_letter_response_file
from app.config import QueueNames, TaskNames
from app.dao.notifications_dao import update_notification_status_by_reference
from app.dao.templates_dao import get_precompiled_letter_template
from app.feature_flags import accept_recipient_identifiers_enabled, is_feature_enabled, FeatureFlag
from app.letters.utils import upload_letter_pdf
from app.models import (
Expand Down Expand Up @@ -59,52 +58,10 @@
post_sms_request,
post_email_request,
post_letter_request,
post_precompiled_letter_request
)
from app.utils import get_public_notify_type_text


# FIXME: POST requests to /v2/notifications/letter match this route and the
# route hooked to the post_notification function below. Proper execution
# seems to depend on the order of the code (top-to-bottom route matching).
@v2_notification_blueprint.route('/{}'.format(LETTER_TYPE), methods=['POST'])
def post_precompiled_letter_notification():
if 'content' not in (request.get_json() or {}):
return post_notification(LETTER_TYPE)

form = validate(request.get_json(), post_precompiled_letter_request)

if not authenticated_service.has_permissions(LETTER_TYPE):
raise BadRequestError(message="Service is not allowed to send {}".format(
get_public_notify_type_text(LETTER_TYPE, plural=True)))

check_rate_limiting(authenticated_service, api_user)

template = get_precompiled_letter_template(authenticated_service.id)

form['personalisation'] = {
'address_line_1': form['reference']
}

reply_to = get_reply_to_text(LETTER_TYPE, form, template)

notification = process_letter_notification(
letter_data=form,
api_key=api_user,
template=template,
reply_to_text=reply_to,
precompiled=True
)

resp = {
'id': notification.id,
'reference': notification.client_reference,
'postage': notification.postage
}

return jsonify(resp), 201


@v2_notification_blueprint.route('/<notification_type>', methods=['POST'])
def post_notification(notification_type): # noqa: C901
try:
Expand Down
84 changes: 0 additions & 84 deletions tests/app/v2/notifications/test_get_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -670,87 +670,3 @@ def test_get_notifications_renames_letter_statuses(client, sample_letter_templat
json_response = json.loads(response.get_data(as_text=True))
assert response.status_code == 200
assert json_response['status'] == expected_status


def test_get_pdf_for_notification_returns_pdf_content(
client,
sample_letter_notification,
mocker,
):
mock_get_letter_pdf = mocker.patch('app.v2.notifications.get_notifications.get_letter_pdf', return_value=b'foo')
sample_letter_notification.status = 'created'

auth_header = create_authorization_header(service_id=sample_letter_notification.service_id)
response = client.get(
path=url_for('v2_notifications.get_pdf_for_notification', notification_id=sample_letter_notification.id),
headers=[('Content-Type', 'application/json'), auth_header]
)

assert response.status_code == 200
assert response.get_data() == b'foo'
mock_get_letter_pdf.assert_called_once_with(sample_letter_notification)


def test_get_pdf_for_notification_returns_400_if_pdf_not_found(
client,
sample_letter_notification,
mocker,
):
# if no files are returned get_letter_pdf throws StopIteration as the iterator runs out
mock_get_letter_pdf = mocker.patch(
'app.v2.notifications.get_notifications.get_letter_pdf',
side_effect=StopIteration
)
sample_letter_notification.status = 'created'

auth_header = create_authorization_header(service_id=sample_letter_notification.service_id)
response = client.get(
path=url_for('v2_notifications.get_pdf_for_notification', notification_id=sample_letter_notification.id),
headers=[('Content-Type', 'application/json'), auth_header]
)

assert response.status_code == 400
assert response.json['errors'] == [{
'error': 'PDFNotReadyError',
'message': 'PDF not available yet, try again later'
}]
mock_get_letter_pdf.assert_called_once_with(sample_letter_notification)


@pytest.mark.parametrize('status, expected_message', [
('virus-scan-failed', 'Document did not pass the virus scan'),
('technical-failure', 'PDF not available for letters in status technical-failure'),
])
def test_get_pdf_for_notification_only_returns_pdf_content_if_right_status(
client,
sample_letter_notification,
mocker,
status,
expected_message
):
mock_get_letter_pdf = mocker.patch('app.v2.notifications.get_notifications.get_letter_pdf', return_value=b'foo')
sample_letter_notification.status = status

auth_header = create_authorization_header(service_id=sample_letter_notification.service_id)
response = client.get(
path=url_for('v2_notifications.get_pdf_for_notification', notification_id=sample_letter_notification.id),
headers=[('Content-Type', 'application/json'), auth_header]
)

assert response.status_code == 400
assert response.json['errors'] == [{
'error': 'BadRequestError',
'message': expected_message
}]
assert mock_get_letter_pdf.called is False


def test_get_pdf_for_notification_fails_for_non_letters(client, sample_notification):
auth_header = create_authorization_header(service_id=sample_notification.service_id)
response = client.get(
path=url_for('v2_notifications.get_pdf_for_notification', notification_id=sample_notification.id),
headers=[('Content-Type', 'application/json'), auth_header]
)

assert response.status_code == 400
assert response.json['errors'] == [{'error': 'BadRequestError', 'message': 'Notification is not a letter'}]
106 changes: 0 additions & 106 deletions tests/app/v2/notifications/test_post_letter_notifications.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import uuid
from unittest.mock import ANY

from flask import json
from flask import url_for
import pytest

from app.config import QueueNames
from app.models import (
Job,
Expand All @@ -17,7 +14,6 @@
NOTIFICATION_CREATED,
NOTIFICATION_SENDING,
NOTIFICATION_DELIVERED,
NOTIFICATION_PENDING_VIRUS_CHECK,
SMS_TYPE
)
from app.schema_validation import validate
Expand Down Expand Up @@ -376,30 +372,6 @@ def test_post_letter_notification_is_delivered_but_still_creates_pdf_if_in_trial
fake_create_letter_task.assert_called_once_with([str(notification.id)], queue='research-mode-tasks')


def test_post_letter_notification_is_delivered_and_has_pdf_uploaded_to_test_letters_bucket_using_test_key(
client,
notify_user,
mocker
):
sample_letter_service = create_service(service_permissions=['letter'])
mocker.patch('app.celery.letters_pdf_tasks.notify_celery.send_task')
s3mock = mocker.patch('app.v2.notifications.post_notifications.upload_letter_pdf', return_value='test.pdf')
data = {
"reference": "letter-reference",
"content": "bGV0dGVyLWNvbnRlbnQ="
}
letter_request(
client,
data=data,
service_id=str(sample_letter_service.id),
key_type=KEY_TYPE_TEST,
precompiled=True)

notification = Notification.query.one()
assert notification.status == NOTIFICATION_PENDING_VIRUS_CHECK
s3mock.assert_called_once_with(ANY, b'letter-content', precompiled=True)


def test_post_letter_notification_persists_notification_reply_to_text(
client, notify_db_session, mocker
):
Expand All @@ -418,81 +390,3 @@ def test_post_letter_notification_persists_notification_reply_to_text(
notifications = Notification.query.all()
assert len(notifications) == 1
assert notifications[0].reply_to_text == service_address


def test_post_precompiled_letter_with_invalid_base64(client, notify_user, mocker):
sample_service = create_service(service_permissions=['letter'])
mocker.patch('app.v2.notifications.post_notifications.upload_letter_pdf')

data = {
"reference": "letter-reference",
"content": "hi"
}
auth_header = create_authorization_header(service_id=sample_service.id)
response = client.post(
path="v2/notifications/letter",
data=json.dumps(data),
headers=[('Content-Type', 'application/json'), auth_header])

assert response.status_code == 400, response.get_data(as_text=True)
resp_json = json.loads(response.get_data(as_text=True))
assert resp_json['errors'][0]['message'] == 'Cannot decode letter content (invalid base64 encoding)'

assert not Notification.query.first()


@pytest.mark.parametrize('notification_postage, expected_postage', [
('second', 'second'),
('first', 'first'),
(None, 'second')
])
def test_post_precompiled_letter_notification_returns_201(
client, notify_user, mocker, notification_postage, expected_postage
):
sample_service = create_service(service_permissions=['letter'])
s3mock = mocker.patch('app.v2.notifications.post_notifications.upload_letter_pdf')
mocker.patch('app.celery.letters_pdf_tasks.notify_celery.send_task')
data = {
"reference": "letter-reference",
"content": "bGV0dGVyLWNvbnRlbnQ="
}
if notification_postage:
data["postage"] = notification_postage
auth_header = create_authorization_header(service_id=sample_service.id)
response = client.post(
path="v2/notifications/letter",
data=json.dumps(data),
headers=[('Content-Type', 'application/json'), auth_header])

assert response.status_code == 201, response.get_data(as_text=True)

s3mock.assert_called_once_with(ANY, b'letter-content', precompiled=True)

notification = Notification.query.one()

assert notification.billable_units == 0
assert notification.status == NOTIFICATION_PENDING_VIRUS_CHECK
assert notification.postage == expected_postage

resp_json = json.loads(response.get_data(as_text=True))
assert resp_json == {'id': str(notification.id), 'reference': 'letter-reference', 'postage': expected_postage}


def test_post_letter_notification_throws_error_for_invalid_postage(client, notify_user, mocker):
sample_service = create_service(service_permissions=['letter'])
data = {
"reference": "letter-reference",
"content": "bGV0dGVyLWNvbnRlbnQ=",
"postage": "space unicorn"
}
auth_header = create_authorization_header(service_id=sample_service.id)
response = client.post(
path="v2/notifications/letter",
data=json.dumps(data),
headers=[('Content-Type', 'application/json'), auth_header])

assert response.status_code == 400, response.get_data(as_text=True)
resp_json = json.loads(response.get_data(as_text=True))
assert resp_json['errors'][0]['message'] == "postage invalid. It must be either first or second."

assert not Notification.query.first()

0 comments on commit 431dccf

Please sign in to comment.