diff --git a/app/dao/inbound_numbers_dao.py b/app/dao/inbound_numbers_dao.py new file mode 100644 index 000000000..4f682710f --- /dev/null +++ b/app/dao/inbound_numbers_dao.py @@ -0,0 +1,28 @@ +from app import db +from app.dao.dao_utils import transactional +from app.models import InboundNumber + + +def dao_get_inbound_numbers(): + return InboundNumber.query.all() + + +def dao_get_available_inbound_numbers(): + return InboundNumber.query.filter(InboundNumber.active, InboundNumber.service_id.is_(None)).all() + + +def dao_get_inbound_number_for_service(service_id): + return InboundNumber.query.filter(InboundNumber.service_id == service_id).all() + + +@transactional +def dao_allocate_inbound_number_to_service(service_id): + available_numbers = InboundNumber.query.filter( + InboundNumber.active, InboundNumber.service_id.is_(None)).all() + + if len(available_numbers) > 0: + available_numbers[0].service_id = service_id + + db.session.add(available_numbers[0]) + else: + raise IndexError('No inbound numbers available') diff --git a/app/models.py b/app/models.py index 4ab486276..d81dfa4c7 100644 --- a/app/models.py +++ b/app/models.py @@ -242,6 +242,18 @@ class Service(db.Model, Versioned): return cls(**fields) +class InboundNumber(db.Model): + __tablename__ = "inbound_numbers" + + id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + number = db.Column(db.String(11), unique=True, nullable=False) + provider = db.Column(db.String(), nullable=False) + service_id = db.Column(UUID(as_uuid=True), db.ForeignKey('services.id'), unique=True, index=True, nullable=True) + service = db.relationship('Service') + active = db.Column(db.Boolean, index=False, unique=False, nullable=False, default=True) + created_at = db.Column(db.DateTime, default=datetime.datetime.utcnow, nullable=False) + + class ServicePermission(db.Model): __tablename__ = "service_permissions" diff --git a/migrations/versions/0113_add_inbound_numbers.py b/migrations/versions/0113_add_inbound_numbers.py new file mode 100644 index 000000000..6bcf5b52d --- /dev/null +++ b/migrations/versions/0113_add_inbound_numbers.py @@ -0,0 +1,34 @@ +"""empty message + +Revision ID: 0113_add_inbound_numbers +Revises: 0112_add_start_end_dates +Create Date: 2017-08-03 11:08:00.970476 + +""" + +# revision identifiers, used by Alembic. +revision = '0113_add_inbound_numbers' +down_revision = '0112_add_start_end_dates' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +def upgrade(): + op.create_table('inbound_numbers', + sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('number', sa.String(length=11), nullable=False), + sa.Column('provider', sa.String(), nullable=False), + sa.Column('service_id', postgresql.UUID(as_uuid=True), nullable=True), + sa.Column('active', sa.Boolean(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['service_id'], ['services.id'], ), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('number') + ) + op.create_index(op.f('ix_inbound_numbers_service_id'), 'inbound_numbers', ['service_id'], unique=True) + + +def downgrade(): + op.drop_index(op.f('ix_inbound_numbers_service_id'), table_name='inbound_numbers') + op.drop_table('inbound_numbers') diff --git a/tests/app/dao/test_inbound_numbers_dao.py b/tests/app/dao/test_inbound_numbers_dao.py new file mode 100644 index 000000000..f07b818e3 --- /dev/null +++ b/tests/app/dao/test_inbound_numbers_dao.py @@ -0,0 +1,60 @@ +import pytest + +from app.dao.inbound_numbers_dao import ( + dao_get_inbound_numbers, + dao_get_available_inbound_numbers, + dao_get_inbound_number_for_service, + dao_allocate_inbound_number_to_service +) +from app.models import InboundNumber + +from tests.app.db import create_inbound_number, create_service + + +@pytest.fixture +def service_1(notify_db, notify_db_session): + return create_service() + + +@pytest.fixture +def sample_inbound_numbers(notify_db, notify_db_session, service_1): + inbound_numbers = [] + inbound_numbers.append(create_inbound_number(number='1', provider='mmg')) + inbound_numbers.append(create_inbound_number(number='2', provider='mmg', active=False)) + inbound_numbers.append(create_inbound_number(number='3', provider='firetext', service_id=service_1.id)) + return inbound_numbers + + +def test_get_inbound_numbers(notify_db, notify_db_session, sample_inbound_numbers, service_1): + res = dao_get_inbound_numbers() + + assert len(res) == 3 + assert res == sample_inbound_numbers + + +def test_get_available_inbound_numbers(notify_db, notify_db_session, sample_inbound_numbers): + res = dao_get_available_inbound_numbers() + + assert len(res) == 1 + assert res[0] == sample_inbound_numbers[0] + + +def test_allocate_inbound_number_to_service( + notify_db, notify_db_session, sample_inbound_numbers): + service = create_service(service_name='test service') + + dao_allocate_inbound_number_to_service(service.id) + + res = InboundNumber.query.filter(InboundNumber.service_id == service.id).all() + + assert len(res) == 1 + assert res[0].service_id == service.id + + +def test_get_inbound_number_for_service(notify_db, notify_db_session, sample_inbound_numbers, service_1): + res = dao_get_inbound_number_for_service(service_1.id) + + assert len(res) == 1 + assert res[0].number == '3' + assert res[0].provider == 'firetext' + assert res[0].service_id == service_1.id diff --git a/tests/app/db.py b/tests/app/db.py index 71bf29bcb..51b06c78a 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -15,6 +15,7 @@ from app.models import ( Rate, Job, InboundSms, + InboundNumber, Organisation, EMAIL_TYPE, SMS_TYPE, @@ -276,3 +277,16 @@ def create_api_key(service, key_type=KEY_TYPE_NORMAL): db.session.add(api_key) db.session.commit() return api_key + + +def create_inbound_number(number, provider, active=True, service_id=None): + inbound_number = InboundNumber( + id=uuid.uuid4(), + number=number, + provider=provider, + active=active, + service_id=service_id + ) + db.session.add(inbound_number) + db.session.commit() + return inbound_number