From aebaea1072c9a1345667d2587287584cb57d6f7b Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Tue, 30 Aug 2016 15:54:22 +0100 Subject: [PATCH] add public contract tests use jsonschema to test the GET /notification/{} endpoint to highlight any key name/format/type changes --- requirements_for_test.txt | 2 + tests/app/notifications/test_rest.py | 38 ------ .../GET_notification_return_email.json | 128 ++++++++++++++++++ .../GET_notification_return_sms.json | 127 +++++++++++++++++ tests/app/public_contracts/__init__.py | 0 .../public_contracts/test_GET_notification.py | 30 ++++ 6 files changed, 287 insertions(+), 38 deletions(-) create mode 100644 tests/app/public_contracts/GET_notification_return_email.json create mode 100644 tests/app/public_contracts/GET_notification_return_sms.json create mode 100644 tests/app/public_contracts/__init__.py create mode 100644 tests/app/public_contracts/test_GET_notification.py diff --git a/requirements_for_test.txt b/requirements_for_test.txt index 52f1665aa..e7ded4dff 100644 --- a/requirements_for_test.txt +++ b/requirements_for_test.txt @@ -8,3 +8,5 @@ moto==0.4.25 flex==5.8.0 freezegun==0.3.7 requests-mock==1.0.0 +jsonschema==2.5.1 +strict-rfc3339==0.7 diff --git a/tests/app/notifications/test_rest.py b/tests/app/notifications/test_rest.py index 778bbe66e..f30659f56 100644 --- a/tests/app/notifications/test_rest.py +++ b/tests/app/notifications/test_rest.py @@ -625,44 +625,6 @@ 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, diff --git a/tests/app/public_contracts/GET_notification_return_email.json b/tests/app/public_contracts/GET_notification_return_email.json new file mode 100644 index 000000000..78318cdaa --- /dev/null +++ b/tests/app/public_contracts/GET_notification_return_email.json @@ -0,0 +1,128 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "GET notification return schema - for SMS notifications", + "type" : "object", + "properties": { + "data": { + "type": "object", + "properties": { + "notification": { + "type": "object", + "properties": { + "id": {"$ref": "#/definitions/uuid"}, + "to": {"type": "string", "format": "email"}, + "job_row_number": {"oneOf":[ + {"type": "number"}, + {"type": "null"} + ]}, + "template_version": {"type": "number"}, + "billable_units": {"type": "number"}, + "notification_type": { + "type": "string", + "enum": ["email"] + }, + "created_at": {"$ref": "#/definitions/datetime"}, + "sent_at": {"oneOf":[ + {"$ref": "#/definitions/datetime"}, + {"type": "null"} + ]}, + "sent_by": {"oneOf":[ + {"type": "string"}, + {"type": "null"} + ]}, + "updated_at": {"oneOf":[ + {"$ref": "#/definitions/datetime"}, + {"type": "null"} + ]}, + "status": { + "type": "string", + "enum": [ + "created", + "sending", + "delivered", + "pending", + "failed", + "technical-failure", + "temporary-failure", + "permanent-failure" + ] + }, + "reference": {"oneOf":[ + {"type": "string"}, + {"type": "null"} + ]}, + "template": { + "type": "object", + "properties": { + "id": {"$ref": "#/definitions/uuid"}, + "name": {"type": "string"}, + "template_type": { + "type": "string", + "enum": ["email"] + }, + "version": {"type": "number"} + }, + "additionalProperties": false, + "required": ["id", "name", "template_type", "version"] + }, + "service": {"$ref": "#/definitions/uuid"}, + "job": { + "oneOf": [ + { + "type": "object", + "properties": { + "id": {"$ref": "#/definitions/uuid"}, + "original_file_name": {"type": "string"} + }, + "additionalProperties": false, + "required": ["id", "original_file_name"] + }, + {"type": "null"} + ] + }, + "api_key": {"oneOf":[ + {"$ref": "#/definitions/uuid"}, + {"type": "null"} + ]}, + "body": {"type": "string"}, + "content_char_count": {"type": "null"}, + "subject": {"type": "string"} + }, + "additionalProperties": false, + "required": [ + "id", + "to", + "job_row_number", + "template_version", + "billable_units", + "notification_type", + "created_at", + "sent_at", + "sent_by", + "updated_at", + "status", + "reference", + "template", + "service", + "job", + "api_key", + "body", + "content_char_count" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false, + "definitions": { + "uuid": { + "type": "string", + "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" + }, + "datetime": { + "type": "string", + "format": "date-time" + } + } +} diff --git a/tests/app/public_contracts/GET_notification_return_sms.json b/tests/app/public_contracts/GET_notification_return_sms.json new file mode 100644 index 000000000..804b91722 --- /dev/null +++ b/tests/app/public_contracts/GET_notification_return_sms.json @@ -0,0 +1,127 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "GET notification return schema - for SMS notifications", + "type" : "object", + "properties": { + "data": { + "type": "object", + "properties": { + "notification": { + "type": "object", + "properties": { + "id": {"$ref": "#/definitions/uuid"}, + "to": {"type": "string"}, + "job_row_number": {"oneOf":[ + {"type": "number"}, + {"type": "null"} + ]}, + "template_version": {"type": "number"}, + "billable_units": {"type": "number"}, + "notification_type": { + "type": "string", + "enum": ["sms"] + }, + "created_at": {"$ref": "#/definitions/datetime"}, + "sent_at": {"oneOf":[ + {"$ref": "#/definitions/datetime"}, + {"type": "null"} + ]}, + "sent_by": {"oneOf":[ + {"type": "string"}, + {"type": "null"} + ]}, + "updated_at": {"oneOf":[ + {"$ref": "#/definitions/datetime"}, + {"type": "null"} + ]}, + "status": { + "type": "string", + "enum": [ + "created", + "sending", + "delivered", + "pending", + "failed", + "technical-failure", + "temporary-failure", + "permanent-failure" + ] + }, + "reference": {"oneOf":[ + {"type": "string"}, + {"type": "null"} + ]}, + "template": { + "type": "object", + "properties": { + "id": {"$ref": "#/definitions/uuid"}, + "name": {"type": "string"}, + "template_type": { + "type": "string", + "enum": ["sms"] + }, + "version": {"type": "number"} + }, + "additionalProperties": false, + "required": ["id", "name", "template_type", "version"] + }, + "service": {"$ref": "#/definitions/uuid"}, + "job": { + "oneOf": [ + { + "type": "object", + "properties": { + "id": {"$ref": "#/definitions/uuid"}, + "original_file_name": {"type": "string"} + }, + "additionalProperties": false, + "required": ["id", "original_file_name"] + }, + {"type": "null"} + ] + }, + "api_key": {"oneOf":[ + {"$ref": "#/definitions/uuid"}, + {"type": "null"} + ]}, + "body": {"type": "string"}, + "content_char_count": {"type": "number"} + }, + "additionalProperties": false, + "required": [ + "id", + "to", + "job_row_number", + "template_version", + "billable_units", + "notification_type", + "created_at", + "sent_at", + "sent_by", + "updated_at", + "status", + "reference", + "template", + "service", + "job", + "api_key", + "body", + "content_char_count" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false, + "definitions": { + "uuid": { + "type": "string", + "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$" + }, + "datetime": { + "type": "string", + "format": "date-time" + } + } +} diff --git a/tests/app/public_contracts/__init__.py b/tests/app/public_contracts/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/app/public_contracts/test_GET_notification.py b/tests/app/public_contracts/test_GET_notification.py new file mode 100644 index 000000000..d048e34e2 --- /dev/null +++ b/tests/app/public_contracts/test_GET_notification.py @@ -0,0 +1,30 @@ +import os + +from flask import json +import jsonschema + +from tests import create_authorization_header + + +def test_get_sms_contract(client, sample_notification): + auth_header = create_authorization_header(service_id=sample_notification.service_id) + response = client.get('/notifications/{}'.format(sample_notification.id), headers=[auth_header]) + + with open(os.path.join(os.path.dirname(__file__), './GET_notification_return_sms.json')) as schema: + jsonschema.validate( + json.loads(response.get_data(as_text=True)), + json.load(schema), + format_checker=jsonschema.FormatChecker() + ) + + +def test_get_email_contract(client, sample_email_notification): + auth_header = create_authorization_header(service_id=sample_email_notification.service_id) + response = client.get('/notifications/{}'.format(sample_email_notification.id), headers=[auth_header]) + + with open(os.path.join(os.path.dirname(__file__), './GET_notification_return_email.json')) as schema: + jsonschema.validate( + json.loads(response.get_data(as_text=True)), + json.load(schema), + format_checker=jsonschema.FormatChecker() + )