From a81206091538584e8ada3e4817786e5fce346b36 Mon Sep 17 00:00:00 2001 From: Rebecca Law Date: Wed, 25 Jul 2018 14:12:13 +0100 Subject: [PATCH 1/2] The unique constraint on SeviceCallbackApi was on service_id only. Now that we have 2 types of api callbacks the constraint to be on service_id + callback_type. --- app/models.py | 6 ++- .../app/dao/test_service_callback_api_dao.py | 43 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/app/models.py b/app/models.py index 216c3bc16..bff4a664a 100644 --- a/app/models.py +++ b/app/models.py @@ -597,7 +597,7 @@ class ServiceInboundApi(db.Model, Versioned): class ServiceCallbackApi(db.Model, Versioned): __tablename__ = 'service_callback_api' id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) - service_id = db.Column(UUID(as_uuid=True), db.ForeignKey('services.id'), index=True, nullable=False, unique=True) + service_id = db.Column(UUID(as_uuid=True), db.ForeignKey('services.id'), index=True, nullable=False) service = db.relationship('Service', backref='service_callback_api') url = db.Column(db.String(), nullable=False) callback_type = db.Column(db.String(), db.ForeignKey('service_callback_type.name'), nullable=True) @@ -607,6 +607,10 @@ class ServiceCallbackApi(db.Model, Versioned): updated_by = db.relationship('User') updated_by_id = db.Column(UUID(as_uuid=True), db.ForeignKey('users.id'), index=True, nullable=False) + __table_args__ = ( + UniqueConstraint('service_id', 'callback_type', name='uix_service_callback_type'), + ) + @property def bearer_token(self): if self._bearer_token: diff --git a/tests/app/dao/test_service_callback_api_dao.py b/tests/app/dao/test_service_callback_api_dao.py index 16d4ae95d..3b05e2fd1 100644 --- a/tests/app/dao/test_service_callback_api_dao.py +++ b/tests/app/dao/test_service_callback_api_dao.py @@ -56,6 +56,49 @@ def test_save_service_callback_api_fails_if_service_does_not_exist(notify_db, no save_service_callback_api(service_callback_api) +def test_update_service_callback_api_unique_constraint(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, + callback_type='delivery_status' + ) + save_service_callback_api(service_callback_api) + another = ServiceCallbackApi( + service_id=sample_service.id, + url="https://some_service/another_callback_endpoint", + bearer_token="different_string", + updated_by_id=sample_service.users[0].id, + callback_type='delivery_status' + ) + with pytest.raises(expected_exception=SQLAlchemyError): + save_service_callback_api(another) + + +def test_update_service_callback_can_add_two_api_of_different_types(sample_service): + delivery_status = 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, + callback_type='delivery_status' + ) + save_service_callback_api(delivery_status) + complaint = ServiceCallbackApi( + service_id=sample_service.id, + url="https://some_service/another_callback_endpoint", + bearer_token="different_string", + updated_by_id=sample_service.users[0].id, + callback_type='complaint' + ) + save_service_callback_api(complaint) + results = ServiceCallbackApi.query.order_by(ServiceCallbackApi.callback_type).all() + assert len(results) == 2 + assert results[0].serialize() == complaint.serialize() + assert results[1].serialize() == delivery_status.serialize() + + def test_update_service_callback_api(sample_service): service_callback_api = ServiceCallbackApi( service_id=sample_service.id, From 2b0ec9353eed43ef9c2a8f51bd450d5ee97868f0 Mon Sep 17 00:00:00 2001 From: Rebecca Law Date: Wed, 25 Jul 2018 14:16:36 +0100 Subject: [PATCH 2/2] Added missing migration file --- migrations/versions/0208_fix_unique_index.py | 23 ++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 migrations/versions/0208_fix_unique_index.py diff --git a/migrations/versions/0208_fix_unique_index.py b/migrations/versions/0208_fix_unique_index.py new file mode 100644 index 000000000..52ac87c23 --- /dev/null +++ b/migrations/versions/0208_fix_unique_index.py @@ -0,0 +1,23 @@ +""" + +Revision ID: 0208_fix_unique_index +Revises: 0207_set_callback_history_type +Create Date: 2018-07-25 13:55:24.941794 + +""" +from alembic import op + +revision = '84c3b6eb16b3' +down_revision = '0207_set_callback_history_type' + + +def upgrade(): + op.create_unique_constraint('uix_service_callback_type', 'service_callback_api', ['service_id', 'callback_type']) + op.drop_index('ix_service_callback_api_service_id', table_name='service_callback_api') + op.create_index(op.f('ix_service_callback_api_service_id'), 'service_callback_api', ['service_id'], unique=False) + + +def downgrade(): + op.drop_index(op.f('ix_service_callback_api_service_id'), table_name='service_callback_api') + op.create_index('ix_service_callback_api_service_id', 'service_callback_api', ['service_id'], unique=True) + op.drop_constraint('uix_service_callback_type', 'service_callback_api', type_='unique')