diff --git a/app/dao/service_callback_api_dao.py b/app/dao/service_callback_api_dao.py new file mode 100644 index 000000000..7db4435ba --- /dev/null +++ b/app/dao/service_callback_api_dao.py @@ -0,0 +1,35 @@ +from datetime import datetime + +from app import db, create_uuid +from app.dao.dao_utils import transactional, version_class +from app.models import ServiceCallbackApi + + +@transactional +@version_class(ServiceCallbackApi) +def save_service_callback_api(service_callback_api): + service_callback_api.id = create_uuid() + service_callback_api.created_at == datetime.utcnow() + service_callback_api.bearer_token = service_callback_api.bearer_token + db.session.add(service_callback_api) + + +@transactional +@version_class(ServiceCallbackApi) +def reset_service_callback_api(service_callback_api, updated_by_id, url=None, bearer_token=None): + if url: + service_callback_api.url = url + if bearer_token: + service_callback_api.bearer_token = bearer_token + service_callback_api.updated_by_id = updated_by_id + service_callback_api.updated_at = datetime.utcnow() + + db.session.add(service_callback_api) + + +def get_service_callback_api(service_callback_api_id, service_id): + return ServiceCallbackApi.query.filter_by(id=service_callback_api_id, service_id=service_id).first() + + +def get_service_callback_api_for_service(service_id): + return ServiceCallbackApi.query.filter_by(service_id=service_id).first() diff --git a/tests/app/dao/test_service_callback_api_dao.py b/tests/app/dao/test_service_callback_api_dao.py new file mode 100644 index 000000000..4f064a8a0 --- /dev/null +++ b/tests/app/dao/test_service_callback_api_dao.py @@ -0,0 +1,129 @@ +import uuid + +import pytest +from sqlalchemy.exc import SQLAlchemyError + +from app import encryption +from app.dao.service_callback_api_dao import ( + save_service_callback_api, + reset_service_callback_api, + get_service_callback_api, + get_service_callback_api_for_service) +from app.models import ServiceCallbackApi +from tests.app.db import create_service_callback_api + + +def test_save_service_callback_api(sample_service): + service_callback_api = ServiceCallbackApi( + service_id=sample_service.id, + url="https://some_service/callback_endpoint", + bearer_token="some_unique_string", + updated_by_id=sample_service.users[0].id + ) + + save_service_callback_api(service_callback_api) + + results = ServiceCallbackApi.query.all() + assert len(results) == 1 + callback_api = results[0] + assert callback_api.id is not None + assert callback_api.service_id == sample_service.id + assert callback_api.updated_by_id == sample_service.users[0].id + assert callback_api.url == "https://some_service/callback_endpoint" + assert callback_api.bearer_token == "some_unique_string" + assert callback_api._bearer_token != "some_unique_string" + assert callback_api.updated_at is None + + versioned = ServiceCallbackApi.get_history_model().query.filter_by(id=callback_api.id).one() + assert versioned.id == callback_api.id + assert versioned.service_id == sample_service.id + assert versioned.updated_by_id == sample_service.users[0].id + assert versioned.url == "https://some_service/callback_endpoint" + assert encryption.decrypt(versioned._bearer_token) == "some_unique_string" + assert versioned.updated_at is None + assert versioned.version == 1 + + +def test_save_service_callback_api_fails_if_service_does_not_exist(notify_db, notify_db_session): + service_callback_api = ServiceCallbackApi( + service_id=uuid.uuid4(), + url="https://some_service/callback_endpoint", + bearer_token="some_unique_string", + updated_by_id=uuid.uuid4() + ) + + with pytest.raises(SQLAlchemyError): + save_service_callback_api(service_callback_api) + + +def test_update_service_callback_api(sample_service): + service_callback_api = ServiceCallbackApi( + service_id=sample_service.id, + url="https://some_service/callback_endpoint", + bearer_token="some_unique_string", + updated_by_id=sample_service.users[0].id + ) + + save_service_callback_api(service_callback_api) + results = ServiceCallbackApi.query.all() + assert len(results) == 1 + saved_callback_api = results[0] + + reset_service_callback_api(saved_callback_api, updated_by_id=sample_service.users[0].id, + url="https://some_service/changed_url") + updated_results = ServiceCallbackApi.query.all() + assert len(updated_results) == 1 + updated = updated_results[0] + assert updated.id is not None + assert updated.service_id == sample_service.id + assert updated.updated_by_id == sample_service.users[0].id + assert updated.url == "https://some_service/changed_url" + assert updated.bearer_token == "some_unique_string" + assert updated._bearer_token != "some_unique_string" + assert updated.updated_at is not None + + versioned_results = ServiceCallbackApi.get_history_model().query.filter_by(id=saved_callback_api.id).all() + assert len(versioned_results) == 2 + for x in versioned_results: + if x.version == 1: + assert x.url == "https://some_service/callback_endpoint" + assert not x.updated_at + elif x.version == 2: + assert x.url == "https://some_service/changed_url" + assert x.updated_at + else: + pytest.fail("version should not exist") + assert x.id is not None + assert x.service_id == sample_service.id + assert x.updated_by_id == sample_service.users[0].id + assert encryption.decrypt(x._bearer_token) == "some_unique_string" + + +def test_get_service_callback_api(sample_service): + service_callback_api = ServiceCallbackApi( + service_id=sample_service.id, + url="https://some_service/callback_endpoint", + bearer_token="some_unique_string", + updated_by_id=sample_service.users[0].id + ) + save_service_callback_api(service_callback_api) + + callback_api = get_service_callback_api(service_callback_api.id, sample_service.id) + assert callback_api.id is not None + assert callback_api.service_id == sample_service.id + assert callback_api.updated_by_id == sample_service.users[0].id + assert callback_api.url == "https://some_service/callback_endpoint" + assert callback_api.bearer_token == "some_unique_string" + assert callback_api._bearer_token != "some_unique_string" + assert callback_api.updated_at is None + + +def test_get_service_callback_api_for_service(sample_service): + service_callback_api = create_service_callback_api(service=sample_service) + result = get_service_callback_api_for_service(sample_service.id) + assert result.id == service_callback_api.id + assert result.url == service_callback_api.url + assert result.bearer_token == service_callback_api.bearer_token + assert result.created_at == service_callback_api.created_at + assert result.updated_at == service_callback_api.updated_at + assert result.updated_by_id == service_callback_api.updated_by_id diff --git a/tests/app/db.py b/tests/app/db.py index 41b6691ca..504245d86 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -4,6 +4,7 @@ import uuid from app import db from app.dao.jobs_dao import dao_create_job from app.dao.service_inbound_api_dao import save_service_inbound_api +from app.dao.service_callback_api_dao import save_service_callback_api from app.dao.service_sms_sender_dao import update_existing_sms_sender_with_inbound_number, dao_update_service_sms_sender from app.models import ( ApiKey, @@ -18,6 +19,7 @@ from app.models import ( Service, ServiceEmailReplyTo, ServiceInboundApi, + ServiceCallbackApi, ServiceLetterContact, ScheduledNotification, ServicePermission, @@ -301,6 +303,20 @@ def create_service_inbound_api( return service_inbound_api +def create_service_callback_api( + service, + url="https://something.com", + bearer_token="some_super_secret", +): + service_callback_api = ServiceCallbackApi(service_id=service.id, + url=url, + bearer_token=bearer_token, + updated_by_id=service.users[0].id + ) + save_service_callback_api(service_callback_api) + return service_callback_api + + def create_organisation(colour='blue', logo='test_x2.png', name='test_org_1'): data = { 'colour': colour,