diff --git a/app/schemas.py b/app/schemas.py index 6de8c5ed4..7cad5de42 100644 --- a/app/schemas.py +++ b/app/schemas.py @@ -292,11 +292,24 @@ class NotificationWithTemplateSchema(BaseSchema): class NotificationWithPersonalisationSchema(NotificationWithTemplateSchema): - template = None actual_template = fields.Nested(TemplateHistorySchema, only=['id', 'name', 'template_type', 'content', 'subject', 'version'], dump_only=True) + class Meta(NotificationWithTemplateSchema.Meta): + # mark as many fields as possible as required since this is a public api. + # WARNING: Does _not_ reference fields computed in handle_template_merge, such as + # 'body', 'subject' [for emails], and 'content_char_count' + fields = ( + # db rows + 'id', 'to', 'job_row_number', 'template_version', 'billable_units', 'notification_type', 'created_at', + 'sent_at', 'sent_by', 'updated_at', 'status', 'reference', + # computed fields + 'personalisation', + # relationships + 'service', 'job', 'api_key', 'actual_template' + ) + @pre_dump def handle_personalisation_property(self, in_data): self.personalisation = in_data.personalisation @@ -312,8 +325,13 @@ class NotificationWithPersonalisationSchema(NotificationWithTemplateSchema): renderer=PassThrough() ) in_data['body'] = template.replaced - if in_data['template']['template_type'] == 'email': + template_type = in_data['template']['template_type'] + if template_type == 'email': in_data['subject'] = template.replaced_subject + in_data['content_char_count'] = None + else: + in_data['content_char_count'] = len(in_data['body']) + in_data.pop('personalisation', None) in_data['template'].pop('content', None) in_data['template'].pop('subject', None) @@ -532,7 +550,6 @@ job_email_template_notification_schema = JobEmailTemplateNotificationSchema() notification_schema = NotificationModelSchema() notification_with_template_schema = NotificationWithTemplateSchema() notification_with_personalisation_schema = NotificationWithPersonalisationSchema() -notification_with_personalisation_schema_load_json = NotificationWithPersonalisationSchema(load_json=True) invited_user_schema = InvitedUserSchema() permission_schema = PermissionSchema() email_data_request_schema = EmailDataSchema() diff --git a/tests/app/notifications/test_rest.py b/tests/app/notifications/test_rest.py index 3386f1d84..df611adca 100644 --- a/tests/app/notifications/test_rest.py +++ b/tests/app/notifications/test_rest.py @@ -564,6 +564,7 @@ def test_get_notification_by_id_returns_merged_template_content(notify_db, assert response.status_code == 200 assert notification['body'] == 'Hello world\nYour thing is due soon' assert 'subject' not in notification + assert notification['content_char_count'] == 34 def test_get_notification_by_id_returns_merged_template_content_for_email( @@ -587,6 +588,7 @@ def test_get_notification_by_id_returns_merged_template_content_for_email( assert response.status_code == 200 assert notification['body'] == 'Hello world\nThis is an email from GOV.UK' assert notification['subject'] == 'world' + assert notification['content_char_count'] is None def test_get_notifications_for_service_returns_merged_template_content(notify_api, @@ -623,6 +625,44 @@ def test_get_notifications_for_service_returns_merged_template_content(notify_ap } +def test_get_notification_public_api_format_is_not_changed(notify_api, sample_notification): + with notify_api.test_request_context(), notify_api.test_client() as client: + auth_header = create_authorization_header(service_id=sample_notification.service_id) + + response = client.get( + '/notifications/{}'.format(sample_notification.id), + headers=[auth_header]) + + assert response.status_code == 200 + notification = json.loads(response.get_data(as_text=True))['data']['notification'] + # you should never remove things from this list! + assert set(notification.keys()) == { + # straight from db + 'id', + 'to', + 'job_row_number', + 'template_version', + 'billable_units', + 'notification_type', + 'created_at', + 'sent_at', + 'sent_by', + 'updated_at', + 'status', + 'reference', + + # relationships + 'template', + 'service', + 'job', + 'api_key', + + # other + 'body', + 'content_char_count' + } + + def test_get_notification_selects_correct_template_for_personalisation(notify_api, notify_db, notify_db_session,