[WIP] New model class and dao for notification. This will be used for

recording status and outcome of sending notifications.
This commit is contained in:
Adam Shimali
2016-02-09 12:01:17 +00:00
parent c1b0cef864
commit c7121be5a2
5 changed files with 202 additions and 1 deletions

View File

@@ -0,0 +1,22 @@
from app import db
from app.models import Notification
def save_notification(notification, update_dict={}):
if update_dict:
update_dict.pop('id', None)
update_dict.pop('job', None)
update_dict.pop('service_id', None)
update_dict.pop('template_id', None)
Notification.query.filter_by(id=notification.id).update(update_dict)
else:
db.session.add(notification)
db.session.commit()
def get_notification(job_id, notification_id):
return Notification.query.filter_by(job_id=job_id, id=notification_id).one()
def get_notifications_by_job(job_id):
return Notification.query.filter_by(job_id=job_id).all()

View File

@@ -189,3 +189,32 @@ class VerifyCode(db.Model):
def check_code(self, cde): def check_code(self, cde):
return check_hash(cde, self._code) return check_hash(cde, self._code)
NOTIFICATION_STATUS_TYPES = ['sent', 'failed']
class Notification(db.Model):
__tablename__ = 'notifications'
id = db.Column(UUID(as_uuid=True), primary_key=True)
to = db.Column(db.String, nullable=False)
job_id = db.Column(UUID(as_uuid=True), db.ForeignKey('jobs.id'), index=True, unique=False, nullable=False)
job = db.relationship('Job', backref=db.backref('notifications', lazy='dynamic'))
service_id = db.Column(UUID(as_uuid=True), db.ForeignKey('services.id'), index=True, unique=False)
template_id = db.Column(db.BigInteger, db.ForeignKey('templates.id'), index=True, unique=False)
created_at = db.Column(
db.DateTime,
index=False,
unique=False,
nullable=False,
default=datetime.datetime.now)
updated_at = db.Column(
db.DateTime,
index=False,
unique=False,
nullable=True,
onupdate=datetime.datetime.now)
status = db.Column(
db.Enum(*NOTIFICATION_STATUS_TYPES, name='notification_status_types'), nullable=False, default='sent')

View File

@@ -0,0 +1,47 @@
"""empty message
Revision ID: 0013_add_notifications
Revises: 0012_add_status_to_job
Create Date: 2016-02-09 11:14:46.708551
"""
# revision identifiers, used by Alembic.
revision = '0013_add_notifications'
down_revision = '0012_add_status_to_job'
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_table('notifications',
sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('to', sa.String(), nullable=False),
sa.Column('job_id', postgresql.UUID(as_uuid=True), nullable=False),
sa.Column('service_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('template_id', sa.BigInteger(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('status', sa.Enum('sent', 'failed', name='notification_status_types'), nullable=False),
sa.ForeignKeyConstraint(['job_id'], ['jobs.id'], ),
sa.ForeignKeyConstraint(['service_id'], ['services.id'], ),
sa.ForeignKeyConstraint(['template_id'], ['templates.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_notifications_job_id'), 'notifications', ['job_id'], unique=False)
op.create_index(op.f('ix_notifications_service_id'), 'notifications', ['service_id'], unique=False)
op.create_index(op.f('ix_notifications_template_id'), 'notifications', ['template_id'], unique=False)
### end Alembic commands ###
def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_index(op.f('ix_notifications_template_id'), table_name='notifications')
op.drop_index(op.f('ix_notifications_service_id'), table_name='notifications')
op.drop_index(op.f('ix_notifications_job_id'), table_name='notifications')
op.drop_table('notifications')
op.get_bind()
op.execute("drop type notification_status_types")
### end Alembic commands ###

View File

@@ -1,12 +1,13 @@
import pytest import pytest
from flask import jsonify from flask import jsonify
from app.models import (User, Service, Template, ApiKey, Job, VerifyCode) from app.models import (User, Service, Template, ApiKey, Job, VerifyCode, Notification)
from app.dao.users_dao import (save_model_user, create_user_code, create_secret_code) from app.dao.users_dao import (save_model_user, create_user_code, create_secret_code)
from app.dao.services_dao import save_model_service from app.dao.services_dao import save_model_service
from app.dao.templates_dao import save_model_template from app.dao.templates_dao import save_model_template
from app.dao.api_key_dao import save_model_api_key from app.dao.api_key_dao import save_model_api_key
from app.dao.jobs_dao import save_job from app.dao.jobs_dao import save_job
from app.dao.notifications_dao import save_notification
import uuid import uuid
@@ -180,3 +181,31 @@ def mock_secret_code(mocker):
mock_class = mocker.patch('app.dao.users_dao.create_secret_code', side_effect=_create) mock_class = mocker.patch('app.dao.users_dao.create_secret_code', side_effect=_create)
return mock_class return mock_class
@pytest.fixture(scope='function')
def sample_notification(notify_db,
notify_db_session,
service=None,
template=None,
job=None):
if service is None:
service = sample_service(notify_db, notify_db_session)
if template is None:
template = sample_template(notify_db, notify_db_session, service=service)
if job is None:
job = sample_job(notify_db, notify_db_session, service=service, template=template)
notificaton_id = uuid.uuid4()
to = '+44709123456'
data = {
'id': notificaton_id,
'to': to,
'job_id': job.id,
'service_id': service.id,
'template_id': template.id
}
notification = Notification(**data)
save_notification(notification)
return notification

View File

@@ -0,0 +1,74 @@
import uuid
from app.models import Notification
from app.dao.notifications_dao import (
save_notification,
get_notification,
get_notifications_by_job
)
def test_save_notification(notify_db, notify_db_session, sample_template, sample_job):
assert Notification.query.count() == 0
notification_id = uuid.uuid4()
to = '+44709123456'
job_id = sample_job.id
data = {
'id': notification_id,
'to': to,
'job_id': job_id,
'service_id': sample_template.service.id,
'template_id': sample_template.id
}
notification = Notification(**data)
save_notification(notification)
assert Notification.query.count() == 1
notification_from_db = Notification.query.get(notification_id)
assert data['id'] == notification_from_db.id
assert data['to'] == notification_from_db.to
assert data['job_id'] == notification_from_db.job_id
assert data['service_id'] == notification_from_db.service_id
assert data['template_id'] == notification_from_db.template_id
assert 'sent' == notification_from_db.status
def test_get_notification_for_job(notify_db, notify_db_session, sample_notification):
notifcation_from_db = get_notification(sample_notification.job_id, sample_notification.id)
assert sample_notification == notifcation_from_db
def test_get_all_notifications_for_job(notify_db, notify_db_session, sample_job):
from tests.app.conftest import sample_notification
for i in range(0, 5):
sample_notification(notify_db,
notify_db_session,
service=sample_job.service,
template=sample_job.template,
job=sample_job)
notifcations_from_db = get_notifications_by_job(sample_job.id)
assert len(notifcations_from_db) == 5
def test_update_notification(notify_db, notify_db_session, sample_notification):
assert sample_notification.status == 'sent'
update_dict = {
'id': sample_notification.id,
'service_id': sample_notification.service_id,
'template_id': sample_notification.template_id,
'job': sample_notification.job,
'status': 'failed'
}
save_notification(sample_notification, update_dict=update_dict)
notification_from_db = Notification.query.get(sample_notification.id)
assert notification_from_db.status == 'failed'