From f1899c6d53fbb15446348bbc52791162e8a92201 Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Mon, 19 Dec 2016 17:45:46 +0000 Subject: [PATCH] add updated_at to provider_details it's set to utcnow from dao_update_provider_details --- app/dao/provider_details_dao.py | 3 +++ app/models.py | 2 ++ app/provider_details/rest.py | 2 +- migrations/versions/0062_provider_details_history.py | 10 ++++++++-- tests/app/dao/test_provider_details_dao.py | 9 +++++++++ tests/app/provider_details/test_rest.py | 10 ++++++++-- 6 files changed, 31 insertions(+), 5 deletions(-) diff --git a/app/dao/provider_details_dao.py b/app/dao/provider_details_dao.py index 257858eee..9d559ee0b 100644 --- a/app/dao/provider_details_dao.py +++ b/app/dao/provider_details_dao.py @@ -1,3 +1,5 @@ +from datetime import datetime + from sqlalchemy import asc from app.dao.dao_utils import transactional from app.models import ProviderDetails, ProviderDetailsHistory @@ -21,6 +23,7 @@ def get_provider_details_by_notification_type(notification_type): @transactional def dao_update_provider_details(provider_details): provider_details.version += 1 + provider_details.updated_at = datetime.utcnow() history = ProviderDetailsHistory.from_original(provider_details) db.session.add(provider_details) db.session.add(history) diff --git a/app/models.py b/app/models.py index 35fac79f1..8e266e46f 100644 --- a/app/models.py +++ b/app/models.py @@ -368,6 +368,7 @@ class ProviderDetails(db.Model): notification_type = db.Column(notification_types, nullable=False) active = db.Column(db.Boolean, default=False, nullable=False) version = db.Column(db.Integer, default=1, nullable=False) + updated_at = db.Column(db.DateTime, nullable=True, onupdate=datetime.datetime.utcnow) class ProviderDetailsHistory(db.Model, HistoryModel): @@ -380,6 +381,7 @@ class ProviderDetailsHistory(db.Model, HistoryModel): notification_type = db.Column(notification_types, nullable=False) active = db.Column(db.Boolean, nullable=False) version = db.Column(db.Integer, primary_key=True, nullable=False) + updated_at = db.Column(db.DateTime, nullable=True, onupdate=datetime.datetime.utcnow) JOB_STATUS_PENDING = 'pending' diff --git a/app/provider_details/rest.py b/app/provider_details/rest.py index 4b7ae2a7a..35b84c077 100644 --- a/app/provider_details/rest.py +++ b/app/provider_details/rest.py @@ -37,7 +37,7 @@ def update_provider_details(provider_details_id): current_data.update(request.get_json()) update_dict = provider_details_schema.load(current_data).data - invalid_keys = {'identifier', 'version'} & set(key for key in request.get_json().keys()) + invalid_keys = {'identifier', 'version', 'updated_at'} & set(key for key in request.get_json().keys()) if invalid_keys: message = "Not permitted to be updated" errors = {key: [message] for key in invalid_keys} diff --git a/migrations/versions/0062_provider_details_history.py b/migrations/versions/0062_provider_details_history.py index 9b8145e58..823f483af 100644 --- a/migrations/versions/0062_provider_details_history.py +++ b/migrations/versions/0062_provider_details_history.py @@ -1,4 +1,7 @@ -"""empty message +""" +* add version and updated_at to provider_details +* set active to not nullable (any existing null is set to false) +* create provider_details_history table, mimicking provider_details Revision ID: 0062_provider_details_history Revises: 0061_add_client_reference @@ -16,11 +19,12 @@ from sqlalchemy.dialects import postgresql def upgrade(): op.get_bind() + op.add_column('provider_details', sa.Column('updated_at', sa.DateTime())) op.execute('UPDATE provider_details SET active = false WHERE active is null') op.alter_column('provider_details', 'active', nullable=False) - op.add_column('provider_details', sa.Column('version', sa.Integer())) + op.add_column('provider_details', sa.Column('version', sa.Integer(), nullable=True)) op.execute('UPDATE provider_details SET version = 1') op.alter_column('provider_details', 'version', nullable=False) @@ -32,6 +36,7 @@ def upgrade(): sa.Column('notification_type', postgresql.ENUM('email', 'sms', 'letter', name='notification_type', create_type=False), nullable=False), sa.Column('active', sa.Boolean(), nullable=False), sa.Column('version', sa.Integer(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=True), sa.PrimaryKeyConstraint('id', 'version') ) op.execute( @@ -46,3 +51,4 @@ def downgrade(): op.alter_column('provider_details', 'active', existing_type=sa.BOOLEAN(), nullable=True) op.drop_column('provider_details', 'version') + op.drop_column('provider_details', 'updated_at') diff --git a/tests/app/dao/test_provider_details_dao.py b/tests/app/dao/test_provider_details_dao.py index 63db857f2..1bb2d8c09 100644 --- a/tests/app/dao/test_provider_details_dao.py +++ b/tests/app/dao/test_provider_details_dao.py @@ -1,3 +1,7 @@ +from datetime import datetime + +from freezegun import freeze_time + from app.models import ProviderDetails, ProviderDetailsHistory from app import clients from app.dao.provider_details_dao import ( @@ -45,18 +49,21 @@ def test_should_not_error_if_any_provider_in_code_not_in_database(restore_provid assert clients.get_sms_client('mmg') +@freeze_time('2000-01-01T00:00:00') def test_update_adds_history(restore_provider_details): ses = ProviderDetails.query.filter(ProviderDetails.identifier == 'ses').one() ses_history = ProviderDetailsHistory.query.filter(ProviderDetailsHistory.id == ses.id).one() assert ses.version == 1 assert ses_history.version == 1 + assert ses.updated_at is None ses.active = False dao_update_provider_details(ses) assert not ses.active + assert ses.updated_at == datetime(2000, 1, 1, 0, 0, 0) ses_history = ProviderDetailsHistory.query.filter( ProviderDetailsHistory.id == ses.id @@ -66,6 +73,8 @@ def test_update_adds_history(restore_provider_details): assert ses_history[0].active assert ses_history[0].version == 1 + assert ses_history[0].updated_at is None assert not ses_history[1].active assert ses_history[1].version == 2 + assert ses_history[1].updated_at == datetime(2000, 1, 1, 0, 0, 0) diff --git a/tests/app/provider_details/test_rest.py b/tests/app/provider_details/test_rest.py index baafd431c..b0a739296 100644 --- a/tests/app/provider_details/test_rest.py +++ b/tests/app/provider_details/test_rest.py @@ -43,7 +43,9 @@ def test_get_provider_details_contains_correct_fields(client, notify_db): headers=[create_authorization_header()] ) json_resp = json.loads(response.get_data(as_text=True))['provider_details'] - allowed_keys = {"id", "display_name", "identifier", "priority", 'notification_type', "active", "version"} + allowed_keys = { + "id", "display_name", "identifier", "priority", 'notification_type', "active", "version", "updated_at" + } assert allowed_keys == set(json_resp[0].keys()) @@ -81,7 +83,11 @@ def test_should_be_able_to_update_status(client, restore_provider_details): assert not provider.active -@pytest.mark.parametrize('field,value', [('identifier', 'new'), ('version', 7)]) +@pytest.mark.parametrize('field,value', [ + ('identifier', 'new'), + ('version', 7), + ('updated_at', None) +]) def test_should_not_be_able_to_update_disallowed_fields(client, restore_provider_details, field, value): provider = ProviderDetails.query.first()