From 918e4b390f4ca71fa76a936b0095de94add7cc77 Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Wed, 19 Sep 2018 10:49:11 +0100 Subject: [PATCH] add postage to notification + noti_history if it's a letter notification, postage must equal "first" or "second", else it must equal null --- app/celery/tasks.py | 2 +- app/models.py | 13 +++++-- app/user/rest.py | 2 +- .../versions/0228_notification_postage.py | 23 +++++++++++ tests/app/db.py | 9 ++++- .../notifications/test_get_notifications.py | 38 ++++++++++--------- 6 files changed, 62 insertions(+), 25 deletions(-) create mode 100644 migrations/versions/0228_notification_postage.py diff --git a/app/celery/tasks.py b/app/celery/tasks.py index d2f090ef8..c9e0227f5 100644 --- a/app/celery/tasks.py +++ b/app/celery/tasks.py @@ -87,7 +87,7 @@ def process_job(job_id): if not service.active: job.job_status = JOB_STATUS_CANCELLED dao_update_job(job) - current_app.logger.warn( + current_app.logger.warning( "Job {} has been cancelled, service {} is inactive".format(job_id, service.id)) return diff --git a/app/models.py b/app/models.py index b61809f89..76cce1fb8 100644 --- a/app/models.py +++ b/app/models.py @@ -212,7 +212,7 @@ class EmailBranding(db.Model): db.String(255), db.ForeignKey('branding_type.name'), index=True, - nullable=True, + nullable=False, default=BRANDING_ORG ) @@ -1182,6 +1182,9 @@ class Notification(db.Model): reply_to_text = db.Column(db.String, nullable=True) + postage = db.Column(db.String, nullable=True) + CheckConstraint("notification_type != 'letter' or postage in ('first', 'second')") + __table_args__ = ( db.ForeignKeyConstraint( ['template_id', 'template_version'], @@ -1373,7 +1376,8 @@ class Notification(db.Model): ).strftime(DATETIME_FORMAT) if self.scheduled_notification else None - ) + ), + "postage": self.postage } if self.notification_type == LETTER_TYPE: @@ -1432,6 +1436,9 @@ class NotificationHistory(db.Model, HistoryModel): created_by = db.relationship('User') created_by_id = db.Column(UUID(as_uuid=True), db.ForeignKey('users.id'), nullable=True) + postage = db.Column(db.String, nullable=True, default='second') + CheckConstraint("notification_type != 'letter' or postage in ('first', 'second')") + __table_args__ = ( db.ForeignKeyConstraint( ['template_id', 'template_version'], @@ -1783,7 +1790,7 @@ class FactBilling(db.Model): provider = db.Column(db.Text, nullable=True, primary_key=True) rate_multiplier = db.Column(db.Integer(), nullable=True, primary_key=True) international = db.Column(db.Boolean, nullable=False, primary_key=False) - rate = db.Column(db.Numeric(), nullable=True) + rate = db.Column(db.Numeric(), nullable=False) billable_units = db.Column(db.Integer(), nullable=True) notifications_sent = db.Column(db.Integer(), nullable=True) created_at = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow) diff --git a/app/user/rest.py b/app/user/rest.py index cfce893a6..0bca01a4c 100644 --- a/app/user/rest.py +++ b/app/user/rest.py @@ -164,7 +164,7 @@ def send_user_2fa_code(user_id, code_type): if count_user_verify_codes(user_to_send_to) >= current_app.config.get('MAX_VERIFY_CODE_COUNT'): # Prevent more than `MAX_VERIFY_CODE_COUNT` active verify codes at a time - current_app.logger.warn('Too many verify codes created for user {}'.format(user_to_send_to.id)) + current_app.logger.warning('Too many verify codes created for user {}'.format(user_to_send_to.id)) else: data = request.get_json() if code_type == SMS_TYPE: diff --git a/migrations/versions/0228_notification_postage.py b/migrations/versions/0228_notification_postage.py new file mode 100644 index 000000000..26b592504 --- /dev/null +++ b/migrations/versions/0228_notification_postage.py @@ -0,0 +1,23 @@ +""" + +Revision ID: 0228_notification_postage +Revises: 0227_postage_constraints +Create Date: 2018-09-19 11:42:52.229430 + +""" +from alembic import op +import sqlalchemy as sa + + +revision = '0228_notification_postage' +down_revision = '0227_postage_constraints' + + +def upgrade(): + op.add_column('notification_history', sa.Column('postage', sa.String(), nullable=True)) + op.add_column('notifications', sa.Column('postage', sa.String(), nullable=True)) + + +def downgrade(): + op.drop_column('notifications', 'postage') + op.drop_column('notification_history', 'postage') diff --git a/tests/app/db.py b/tests/app/db.py index bb5eaedce..5c4e5f674 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -178,7 +178,8 @@ def create_notification( one_off=False, sms_sender_id=None, reply_to_text=None, - created_by_id=None + created_by_id=None, + postage=None ): if created_at is None: created_at = datetime.utcnow() @@ -196,6 +197,9 @@ def create_notification( if not api_key: api_key = create_api_key(template.service, key_type=key_type) + if template.template_type == 'letter' and postage is None: + postage = 'second' + data = { 'id': uuid.uuid4(), 'to': to_field, @@ -224,7 +228,8 @@ def create_notification( 'phone_prefix': phone_prefix, 'normalised_to': normalised_to, 'reply_to_text': reply_to_text, - 'created_by_id': created_by_id + 'created_by_id': created_by_id, + 'postage': postage } notification = Notification(**data) dao_create_notification(notification) diff --git a/tests/app/v2/notifications/test_get_notifications.py b/tests/app/v2/notifications/test_get_notifications.py index 18e2b72dc..426e5e273 100644 --- a/tests/app/v2/notifications/test_get_notifications.py +++ b/tests/app/v2/notifications/test_get_notifications.py @@ -9,11 +9,6 @@ from tests.app.db import ( create_template, ) -from tests.app.conftest import ( - sample_notification, - sample_email_notification, -) - @pytest.mark.parametrize('billable_units, provider', [ (1, 'mmg'), @@ -75,7 +70,8 @@ def test_get_notification_by_id_returns_200( "subject": None, 'sent_at': sample_notification.sent_at, 'completed_at': sample_notification.completed_at(), - 'scheduled_for': '2017-05-12T14:15:00.000000Z' + 'scheduled_for': '2017-05-12T14:15:00.000000Z', + 'postage': None, } assert json_response == expected_response @@ -126,7 +122,8 @@ def test_get_notification_by_id_with_placeholders_returns_200( "subject": "Bob", 'sent_at': sample_notification.sent_at, 'completed_at': sample_notification.completed_at(), - 'scheduled_for': None + 'scheduled_for': None, + 'postage': None, } assert json_response == expected_response @@ -267,17 +264,22 @@ def test_get_notification_adds_delivery_estimate_for_letters( assert json_response['estimated_delivery'] == estimated_delivery -@pytest.mark.parametrize('notification_mock', [ - sample_notification, - sample_email_notification, -]) -def test_get_notification_doesnt_have_delivery_estimate_for_non_letters( - client, - notify_db, - notify_db_session, - notification_mock, -): - mocked_notification = notification_mock(notify_db, notify_db_session) +def test_get_notification_by_id_returns_postage_class_for_letters(client, sample_letter_notification): + auth_header = create_authorization_header(service_id=sample_letter_notification.service_id) + response = client.get( + path='/v2/notifications/{}'.format(sample_letter_notification.id), + headers=[('Content-Type', 'application/json'), auth_header] + ) + + assert response.status_code == 200 + assert response.json['postage'] == 'second' + + +@pytest.mark.parametrize('template_type', ['sms', 'email']) +def test_get_notification_doesnt_have_delivery_estimate_for_non_letters(client, sample_service, template_type): + template = create_template(service=sample_service, template_type=template_type) + mocked_notification = create_notification(template=template) + auth_header = create_authorization_header(service_id=mocked_notification.service_id) response = client.get( path='/v2/notifications/{}'.format(mocked_notification.id),