-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add schemas, endpoints and supporting tests
- Loading branch information
1 parent
ac8e556
commit 9e4b1b2
Showing
8 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from flask import Blueprint | ||
|
||
from app.v2.errors import register_errors | ||
|
||
template_blueprint = Blueprint("v2_template", __name__, url_prefix='/v2/template') | ||
|
||
register_errors(template_blueprint) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import uuid | ||
|
||
from flask import jsonify, request | ||
from werkzeug.exceptions import abort | ||
|
||
from app import api_user | ||
from app.dao import templates_dao | ||
from app.schema_validation import validate | ||
from app.v2.template import template_blueprint | ||
from app.v2.template.template_schemas import get_template_by_id_request | ||
|
||
|
||
@template_blueprint.route("/<template_id>", methods=['GET']) | ||
@template_blueprint.route("/<template_id>/version/<version>", methods=['GET']) | ||
def get_template_by_id(template_id, version=None): | ||
try: | ||
casted_id = uuid.UUID(template_id) | ||
|
||
_data = {} | ||
_data['id'] = template_id | ||
if version: | ||
_data['version'] = int(version) | ||
|
||
data = validate(_data, get_template_by_id_request) | ||
except ValueError or AttributeError: | ||
abort(404) | ||
|
||
template = templates_dao.dao_get_template_by_id_and_service_id( | ||
casted_id, api_user.service_id, data.get('version')) | ||
|
||
return jsonify(template.serialize()), 200 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from app.models import TEMPLATE_TYPES | ||
from app.schema_validation.definitions import uuid | ||
|
||
|
||
get_template_by_id_request = { | ||
"$schema": "http://json-schema.org/draft-04/schema#", | ||
"description": "schema for query parameters allowed when getting list of notifications", | ||
"type": "object", | ||
"properties": { | ||
"id": uuid, | ||
"version": {"type": ["integer", "null"], "minimum": 1} | ||
}, | ||
"required": ["id"], | ||
"additionalProperties": False, | ||
} | ||
|
||
get_template_by_id_response = { | ||
"$schema": "http://json-schema.org/draft-04/schema#", | ||
"description": "GET template by id schema response", | ||
"type": "object", | ||
"title": "reponse v2/template", | ||
"properties": { | ||
"id": uuid, | ||
"type": {"enum": TEMPLATE_TYPES}, | ||
"created_at": { | ||
"format": "date-time", | ||
"type": "string", | ||
"description": "Date+time created" | ||
}, | ||
"updated_at": { | ||
"format": "date-time", | ||
"type": "string", | ||
"description": "Date+time updated" | ||
}, | ||
"created_by": {"type": "string"}, | ||
"version": {"type": "integer"}, | ||
"body": {"type": "string"}, | ||
"subject": {"type": ["string", "null"]} | ||
}, | ||
"required": ["id", "type", "created_at", "updated_at", "version", "created_by", "body"] | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import pytest | ||
|
||
from flask import json | ||
|
||
from app import DATETIME_FORMAT | ||
from tests import create_authorization_header | ||
from tests.app.conftest import sample_template as create_sample_template | ||
|
||
EMAIL_TYPE = 'email' | ||
SMS_TYPE = 'sms' | ||
LETTER_TYPE = 'letter' | ||
|
||
template_types = [EMAIL_TYPE, SMS_TYPE, LETTER_TYPE] | ||
valid_version_params = [None, 1] | ||
|
||
|
||
@pytest.mark.parametrize("tmp_type", template_types) | ||
@pytest.mark.parametrize("version", valid_version_params) | ||
def test_get_email_template_by_id_returns_200(client, notify_db, notify_db_session, sample_service, tmp_type, version): | ||
template = create_sample_template(notify_db, notify_db_session, template_type=tmp_type) | ||
auth_header = create_authorization_header(service_id=sample_service.id) | ||
|
||
version_path = '/version/{}'.format(version) if version else '' | ||
|
||
response = client.get(path='/v2/template/{}{}'.format(template.id, version_path), | ||
headers=[('Content-Type', 'application/json'), auth_header]) | ||
|
||
assert response.status_code == 200 | ||
assert response.headers['Content-type'] == 'application/json' | ||
|
||
json_response = json.loads(response.get_data(as_text=True)) | ||
|
||
expected_response = { | ||
'id': '{}'.format(template.id), | ||
'type': '{}'.format(template.template_type), | ||
'created_at': template.created_at.strftime(DATETIME_FORMAT), | ||
'updated_at': None, | ||
'version': template.version, | ||
'created_by': template.created_by.email_address, | ||
'body': template.content, | ||
"subject": template.subject if tmp_type == EMAIL_TYPE else None | ||
} | ||
|
||
assert json_response == expected_response | ||
|
||
|
||
def test_get_template_with_invalid_template_id_returns_404(client, sample_service): | ||
auth_header = create_authorization_header(service_id=sample_service.id) | ||
|
||
invalid_template_id = 'some_other_id' | ||
|
||
response = client.get(path='/v2/template/{}'.format(invalid_template_id), | ||
headers=[('Content-Type', 'application/json'), auth_header]) | ||
|
||
assert response.status_code == 404 | ||
assert response.headers['Content-type'] == 'application/json' | ||
|
||
json_response = json.loads(response.get_data(as_text=True)) | ||
|
||
assert json_response == { | ||
"message": "The requested URL was not found on the server. " | ||
"If you entered the URL manually please check your spelling and try again.", | ||
"result": "error" | ||
} | ||
|
||
|
||
@pytest.mark.parametrize("tmp_type", template_types) | ||
def test_get_template_with_invalid_version_returns_404(client, notify_db, notify_db_session, sample_service, tmp_type): | ||
template = create_sample_template( | ||
notify_db, notify_db_session, template_type=tmp_type) | ||
|
||
auth_header = create_authorization_header(service_id=sample_service.id) | ||
|
||
# test with version number beyond latest version | ||
invalid_version = template.version + 1 | ||
|
||
response = client.get(path='/v2/template/{}/version/{}'.format(template.id, invalid_version), | ||
headers=[('Content-Type', 'application/json'), auth_header]) | ||
|
||
assert response.status_code == 404 | ||
assert response.headers['Content-type'] == 'application/json' | ||
|
||
json_response = json.loads(response.get_data(as_text=True)) | ||
|
||
assert json_response == { | ||
"errors": [ | ||
{ | ||
"error": "NoResultFound", | ||
"message": "No result found" | ||
} | ||
], | ||
"status_code": 404 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import uuid | ||
|
||
import pytest | ||
from flask import json | ||
|
||
from app.v2.template.template_schemas import ( | ||
get_template_by_id_response, | ||
get_template_by_id_request | ||
) | ||
from app.schema_validation import validate | ||
from jsonschema.exceptions import ValidationError | ||
|
||
|
||
valid_json = { | ||
'id': str(uuid.uuid4()), | ||
'type': 'email', | ||
'created_at': '2017-01-10T18:25:43.511Z', | ||
'updated_at': '2017-04-23T18:25:43.511Z', | ||
'version': 1, | ||
'created_by': 'someone@test.com', | ||
'body': "some body" | ||
} | ||
|
||
valid_json_with_optionals = { | ||
'id': str(uuid.uuid4()), | ||
'type': 'email', | ||
'created_at': '2017-01-10T18:25:43.511Z', | ||
'updated_at': '2017-04-23T18:25:43.511Z', | ||
'version': 1, | ||
'created_by': 'someone', | ||
'body': "some body", | ||
'subject': "some subject" | ||
} | ||
|
||
valid_request_args = [ | ||
{"id": str(uuid.uuid4()), "version": 1}, {"id": str(uuid.uuid4())}] | ||
|
||
invalid_request_args = [ | ||
({"id": str(uuid.uuid4()), "version": "test"}, ["version test is not of type integer, null"]), | ||
({"id": str(uuid.uuid4()), "version": 0}, ["version 0 is less than the minimum of 1"]), | ||
({"version": 1}, ["id is a required property"]), | ||
({"id": "invalid_uuid"}, ["id is not a valid UUID"]), | ||
({"id": "invalid_uuid", "version": 0}, ["version 0 is less than the minimum of 1", | ||
"id is not a valid UUID"]) | ||
] | ||
|
||
|
||
@pytest.mark.parametrize("args", valid_request_args) | ||
def test_get_template_request_schema__against_valid_args_is_valid(args): | ||
assert validate(args, get_template_by_id_request) == args | ||
|
||
|
||
@pytest.mark.parametrize("args,error_message", invalid_request_args) | ||
def test_get_template_request_schema_against_invalid_args_is_invalid(args, error_message): | ||
with pytest.raises(ValidationError) as e: | ||
validate(args, get_template_by_id_request) | ||
errors = json.loads(str(e.value)) | ||
|
||
assert errors['status_code'] == 400 | ||
|
||
for error in errors['errors']: | ||
assert error['message'] in error_message | ||
|
||
|
||
@pytest.mark.parametrize("response", [valid_json, valid_json_with_optionals]) | ||
def test_get_template_response_schema_is_valid(response): | ||
assert validate(response, get_template_by_id_response) == response |