From 0b642623fb6b3d9347c5755a8b7f640a02628172 Mon Sep 17 00:00:00 2001 From: Rebecca Law Date: Wed, 31 May 2017 13:34:54 +0100 Subject: [PATCH 1/5] Added table and model for letter rates. The rates for the letters are per page, therefore it seemed better to build a different table. --- app/models.py | 17 ++++++++ migrations/versions/0088_letter_billing.py | 50 ++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 migrations/versions/0088_letter_billing.py diff --git a/app/models.py b/app/models.py index 8c1e22e79..153ef57e8 100644 --- a/app/models.py +++ b/app/models.py @@ -1141,3 +1141,20 @@ class JobStatistics(db.Model): ) the_string += "created at {}".format(self.created_at) return the_string + + +class LetterRate(db.Model): + __tablename__ = 'letter_rates' + + id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + valid_from = valid_from = db.Column(db.DateTime, nullable=False) + + +class LetterRateDetail(db.Model): + __tablename__ = 'letter_rate_details' + + id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + letter_rate_id = db.Column(UUID(as_uuid=True), db.ForeignKey('letter_rates.id'), index=True, nullable=False) + letter_rate = db.relationship('LetterRate', backref='letter_rates') + page_total = db.Column(db.Integer, nullable=False) + rate = db.Column(db.Numeric(), nullable=False) diff --git a/migrations/versions/0088_letter_billing.py b/migrations/versions/0088_letter_billing.py new file mode 100644 index 000000000..9c184d10a --- /dev/null +++ b/migrations/versions/0088_letter_billing.py @@ -0,0 +1,50 @@ +"""empty message + +Revision ID: 0088_letter_billing +Revises: 0087_scheduled_notifications +Create Date: 2017-05-31 11:43:55.744631 + +""" +import uuid +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +revision = '0088_letter_billing' +down_revision = '0087_scheduled_notifications' + + +def upgrade(): + op.create_table('letter_rates', + sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('valid_from', sa.DateTime(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.create_table('letter_rate_details', + sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('letter_rate_id', postgresql.UUID(as_uuid=True), nullable=False), + sa.Column('page_total', sa.Integer(), nullable=False), + sa.Column('rate', sa.Numeric(), nullable=False), + sa.ForeignKeyConstraint(['letter_rate_id'], ['letter_rates.id'], ), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_letter_rate_details_letter_rate_id'), 'letter_rate_details', ['letter_rate_id'], + unique=False) + + op.get_bind() + letter_id = uuid.uuid4() + op.execute("insert into letter_rates(id, valid_from) values('{}', '2017-03-31 23:00:00')".format(letter_id)) + insert_details = "insert into letter_rate_details(id, letter_rate_id, page_total, rate) values('{}', '{}', {}, {})" + op.execute( + insert_details.format(uuid.uuid4(), letter_id, 1, 29.3)) + op.execute( + insert_details.format(uuid.uuid4(), letter_id, 2, 32)) + op.execute( + insert_details.format(uuid.uuid4(), letter_id, 3, 35)) + + +def downgrade(): + op.get_bind() + op.drop_index('ix_letter_rate_details_letter_rate_id') + op.drop_table('letter_rate_details') + op.drop_table('letter_rates') From d89cb2c120487b54f3b01d2dcbfe3511be3a848e Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Mon, 22 May 2017 15:05:05 +0100 Subject: [PATCH 2/5] add an admin_request fixture this gets rid of some boilerplate around mocking requests from the front-end --- tests/app/conftest.py | 46 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/tests/app/conftest.py b/tests/app/conftest.py index 5b1d32144..d49c527aa 100644 --- a/tests/app/conftest.py +++ b/tests/app/conftest.py @@ -1,11 +1,12 @@ -import requests_mock -import pytest +import json import uuid from datetime import (datetime, date, timedelta) +import requests_mock +import pytest from sqlalchemy import asc from sqlalchemy.orm.session import make_transient -from flask import current_app +from flask import current_app, url_for from app import db from app.models import ( @@ -35,6 +36,7 @@ from app.dao.invited_user_dao import save_invited_user from app.dao.provider_rates_dao import create_provider_rates from app.clients.sms.firetext import FiretextClient +from tests import create_authorization_header from tests.app.db import create_user, create_template, create_notification @@ -976,3 +978,41 @@ def restore_provider_details(notify_db, notify_db_session): notify_db.session.add_all(existing_provider_details) notify_db.session.add_all(existing_provider_details_history) notify_db.session.commit() + + +@pytest.fixture +def admin_request(client): + class AdminRequest: + + @staticmethod + def get(endpoint, endpoint_kwargs=None, expected_status=200): + resp = client.get( + url_for(endpoint, **(endpoint_kwargs or {})), + headers=[create_authorization_header()] + ) + json_resp = json.loads(resp.get_data(as_text=True)) + assert resp.status_code == expected_status + return json_resp + + @staticmethod + def post(endpoint, endpoint_kwargs=None, data=None, expected_status=200): + resp = client.post( + url_for(endpoint, **(endpoint_kwargs or {})), + data=json.dumps(data), + headers=[('Content-Type', 'application/json'), create_authorization_header()] + ) + json_resp = json.loads(resp.get_data(as_text=True)) + assert resp.status_code == expected_status + return json_resp + + @staticmethod + def delete(endpoint, endpoint_kwargs=None, expected_status=204): + resp = client.delete( + url_for(endpoint, **(endpoint_kwargs or {})), + headers=[create_authorization_header()] + ) + json_resp = json.loads(resp.get_data(as_text=True)) + assert resp.status_code == expected_status + return json_resp + + return AdminRequest From ef52337d851146fb8e1662f708155c9d189a63ff Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Wed, 31 May 2017 14:49:14 +0100 Subject: [PATCH 3/5] add inbound sms api two endpoints: * get all inbound sms for a service (you can limit to the X most recent, or filter by user's phone number [which will be normalised]) * get a summary of inbound sms for a service - returns the count of inbound sms in the database, and the date that the most recent was sent --- app/__init__.py | 4 ++ app/dao/inbound_sms_dao.py | 23 +++++++ app/inbound_sms/__init__.py | 0 app/inbound_sms/rest.py | 41 ++++++++++++ app/models.py | 12 ++++ tests/app/dao/test_inbound_sms_dao.py | 59 +++++++++++++++++ tests/app/db.py | 23 +++++++ tests/app/inbound_sms/__init__.py | 0 tests/app/inbound_sms/test_rest.py | 93 +++++++++++++++++++++++++++ 9 files changed, 255 insertions(+) create mode 100644 app/inbound_sms/__init__.py create mode 100644 app/inbound_sms/rest.py create mode 100644 tests/app/dao/test_inbound_sms_dao.py create mode 100644 tests/app/inbound_sms/__init__.py create mode 100644 tests/app/inbound_sms/test_rest.py diff --git a/app/__init__.py b/app/__init__.py index c5b509f30..f8fefbe15 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -93,6 +93,7 @@ def register_blueprint(application): from app.organisation.rest import organisation_blueprint from app.dvla_organisation.rest import dvla_organisation_blueprint from app.delivery.rest import delivery_blueprint + from app.inbound_sms.rest import inbound_sms as inbound_sms_blueprint from app.notifications.receive_notifications import receive_notifications_blueprint from app.notifications.notifications_ses_callback import ses_callback_blueprint from app.notifications.notifications_sms_callback import sms_callback_blueprint @@ -133,6 +134,9 @@ def register_blueprint(application): delivery_blueprint.before_request(requires_admin_auth) application.register_blueprint(delivery_blueprint) + inbound_sms_blueprint.before_request(requires_admin_auth) + application.register_blueprint(inbound_sms_blueprint) + accept_invite.before_request(requires_admin_auth) application.register_blueprint(accept_invite, url_prefix='/invite') diff --git a/app/dao/inbound_sms_dao.py b/app/dao/inbound_sms_dao.py index 92f1c79e0..597748731 100644 --- a/app/dao/inbound_sms_dao.py +++ b/app/dao/inbound_sms_dao.py @@ -1,7 +1,30 @@ from app import db from app.dao.dao_utils import transactional +from app.models import InboundSms @transactional def dao_create_inbound_sms(inbound_sms): db.session.add(inbound_sms) + + +def dao_get_inbound_sms_for_service(service_id, limit=None, user_number=None): + q = InboundSms.query.filter( + InboundSms.service_id == service_id + ).order_by( + InboundSms.created_at.desc() + ) + + if user_number: + q = q.filter(InboundSms.user_number == user_number) + + if limit: + q = q.limit(limit) + + return q.all() + + +def dao_count_inbound_sms_for_service(service_id): + return InboundSms.query.filter( + InboundSms.service_id == service_id + ).count() diff --git a/app/inbound_sms/__init__.py b/app/inbound_sms/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/app/inbound_sms/rest.py b/app/inbound_sms/rest.py new file mode 100644 index 000000000..0ee2b9e90 --- /dev/null +++ b/app/inbound_sms/rest.py @@ -0,0 +1,41 @@ +from flask import ( + Blueprint, + jsonify, + request +) +from notifications_utils.recipients import normalise_phone_number + +from app.dao.inbound_sms_dao import dao_get_inbound_sms_for_service, dao_count_inbound_sms_for_service +from app.errors import register_errors + +inbound_sms = Blueprint( + 'inbound_sms', + __name__, + url_prefix='/service//inbound-sms' +) + +register_errors(inbound_sms) + + +@inbound_sms.route('') +def get_inbound_sms_for_service(service_id): + limit = request.args.get('limit') + user_number = request.args.get('user_number') + + if user_number: + user_number = normalise_phone_number(user_number) + + results = dao_get_inbound_sms_for_service(service_id, limit, user_number) + + return jsonify(data=[row.serialize() for row in results]) + + +@inbound_sms.route('/summary') +def get_inbound_sms_summary_for_service(service_id): + count = dao_count_inbound_sms_for_service(service_id) + most_recent = dao_get_inbound_sms_for_service(service_id, limit=1) + + return jsonify( + count=count, + most_recent=most_recent[0].created_at.isoformat() if most_recent else None + ) diff --git a/app/models.py b/app/models.py index 4680b6274..29272c380 100644 --- a/app/models.py +++ b/app/models.py @@ -1175,6 +1175,18 @@ class InboundSms(db.Model): def content(self, content): self._content = encryption.encrypt(content) + def serialize(self): + return { + 'id': str(self.id), + 'created_at': self.created_at.isoformat(), + 'service_id': str(self.service_id), + 'notify_number': self.notify_number, + 'user_number': self.user_number, + 'content': self.content, + 'provider_date': self.provider_date and self.provider_date.isoformat(), + 'provider_reference': self.provider_reference + } + class LetterRate(db.Model): __tablename__ = 'letter_rates' diff --git a/tests/app/dao/test_inbound_sms_dao.py b/tests/app/dao/test_inbound_sms_dao.py new file mode 100644 index 000000000..f0fc6d8b3 --- /dev/null +++ b/tests/app/dao/test_inbound_sms_dao.py @@ -0,0 +1,59 @@ +from datetime import datetime + +from freezegun import freeze_time + +from app.dao.inbound_sms_dao import dao_get_inbound_sms_for_service, dao_count_inbound_sms_for_service + +from tests.app.db import create_inbound_sms, create_service + + +def test_get_all_inbound_sms(sample_service): + inbound = create_inbound_sms(sample_service) + + res = dao_get_inbound_sms_for_service(sample_service.id) + assert len(res) == 1 + assert res[0] == inbound + + +def test_get_all_inbound_sms_when_none_exist(sample_service): + res = dao_get_inbound_sms_for_service(sample_service.id) + assert len(res) == 0 + + +def test_get_all_inbound_sms_limits_and_orders(sample_service): + with freeze_time('2017-01-01'): + one = create_inbound_sms(sample_service) + with freeze_time('2017-01-03'): + three = create_inbound_sms(sample_service) + with freeze_time('2017-01-02'): + two = create_inbound_sms(sample_service) + + res = dao_get_inbound_sms_for_service(sample_service.id, limit=2) + assert len(res) == 2 + assert res[0] == three + assert res[0].created_at == datetime(2017, 1, 3) + assert res[1] == two + assert res[1].created_at == datetime(2017, 1, 2) + + +def test_get_all_inbound_sms_filters_on_service(notify_db_session): + service_one = create_service(service_name='one') + service_two = create_service(service_name='two') + + sms_one = create_inbound_sms(service_one) + sms_two = create_inbound_sms(service_two) + + res = dao_get_inbound_sms_for_service(service_one.id) + assert len(res) == 1 + assert res[0] == sms_one + + +def test_count_inbound_sms_for_service(notify_db_session): + service_one = create_service(service_name='one') + service_two = create_service(service_name='two') + + create_inbound_sms(service_one) + create_inbound_sms(service_one) + create_inbound_sms(service_two) + + assert dao_count_inbound_sms_for_service(service_one.id) == 2 diff --git a/tests/app/db.py b/tests/app/db.py index 76b458dd9..cdc0d7a79 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -4,6 +4,7 @@ import uuid from app.dao.jobs_dao import dao_create_job from app.models import ( + InboundSms, Service, User, Template, @@ -20,6 +21,7 @@ from app.dao.notifications_dao import dao_create_notification, dao_created_sched from app.dao.templates_dao import dao_create_template from app.dao.services_dao import dao_create_service from app.dao.service_permissions_dao import dao_add_service_permission +from app.dao.inbound_sms_dao import dao_create_inbound_sms def create_user(mobile_number="+447700900986", email="notify@digital.cabinet-office.gov.uk", state='active'): @@ -183,3 +185,24 @@ def create_service_permission(service_id, permission=EMAIL_TYPE): service_permissions = ServicePermission.query.all() return service_permissions + + +def create_inbound_sms( + service, + notify_number=None, + user_number='7700900111', + provider_date=None, + provider_reference=None, + content='Hello' +): + inbound = InboundSms( + service=service, + created_at=datetime.utcnow(), + notify_number=notify_number or service.sms_sender, + user_number=user_number, + provider_date=provider_date or datetime.utcnow(), + provider_reference=provider_reference or 'foo', + content=content, + ) + dao_create_inbound_sms(inbound) + return inbound diff --git a/tests/app/inbound_sms/__init__.py b/tests/app/inbound_sms/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/app/inbound_sms/test_rest.py b/tests/app/inbound_sms/test_rest.py new file mode 100644 index 000000000..70acaddd2 --- /dev/null +++ b/tests/app/inbound_sms/test_rest.py @@ -0,0 +1,93 @@ +from datetime import datetime + +from freezegun import freeze_time + +from tests.app.db import create_inbound_sms, create_service + + +def test_get_inbound_sms(admin_request, sample_service): + one = create_inbound_sms(sample_service) + two = create_inbound_sms(sample_service) + + json_resp = admin_request.get( + 'inbound_sms.get_inbound_sms_for_service', + endpoint_kwargs={'service_id': sample_service.id} + ) + + sms = json_resp['data'] + + assert len(sms) == 2 + assert {inbound['id'] for inbound in sms} == {str(one.id), str(two.id)} + assert sms[0]['content'] == 'Hello' + assert set(sms[0].keys()) == { + 'id', + 'created_at', + 'service_id', + 'notify_number', + 'user_number', + 'content', + 'provider_date', + 'provider_reference' + } + + +def test_get_inbound_sms_limits(admin_request, sample_service): + with freeze_time('2017-01-01'): + one = create_inbound_sms(sample_service) + with freeze_time('2017-01-02'): + two = create_inbound_sms(sample_service) + + sms = admin_request.get( + 'inbound_sms.get_inbound_sms_for_service', + endpoint_kwargs={'service_id': sample_service.id, 'limit': 1} + ) + + assert len(sms['data']) == 1 + assert sms['data'][0]['id'] == str(two.id) + + +def test_get_inbound_sms_filters_user_number(admin_request, sample_service): + # user_number in the db is normalised + one = create_inbound_sms(sample_service, user_number='7700900001') + two = create_inbound_sms(sample_service, user_number='7700900002') + + sms = admin_request.get( + 'inbound_sms.get_inbound_sms_for_service', + endpoint_kwargs={'service_id': sample_service.id, 'user_number': '(07700) 900-001'} + ) + + assert len(sms['data']) == 1 + assert sms['data'][0]['id'] == str(one.id) + assert sms['data'][0]['user_number'] == str(one.user_number) + + +def test_get_inbound_sms_summary(admin_request, sample_service): + other_service = create_service(service_name='other_service') + with freeze_time('2017-01-01'): + create_inbound_sms(sample_service) + with freeze_time('2017-01-02'): + create_inbound_sms(sample_service) + with freeze_time('2017-01-03'): + create_inbound_sms(other_service) + + summary = admin_request.get( + 'inbound_sms.get_inbound_sms_summary_for_service', + endpoint_kwargs={'service_id': sample_service.id} + ) + + assert summary == { + 'count': 2, + 'most_recent': datetime(2017, 1, 2).isoformat() + } + + +def test_get_inbound_sms_summary_with_no_inbound(admin_request, sample_service): + summary = admin_request.get( + 'inbound_sms.get_inbound_sms_summary_for_service', + endpoint_kwargs={'service_id': sample_service.id} + ) + + assert summary == { + 'count': 0, + 'most_recent': None + } From bf18b179b06fdb47cad1885150a3c9b5a572b84c Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Fri, 2 Jun 2017 12:57:28 +0100 Subject: [PATCH 4/5] ensure the user_number in inbound sms is international rather than using the `normalise_phone_number` function, use the `validate_and_format_phone_number` function - this will also convert all numbers to international format, which means we won't need to worry about whether the user enters internaional or UK phone numbers when searching --- app/inbound_sms/rest.py | 5 +++-- app/notifications/receive_notifications.py | 6 +++--- tests/app/db.py | 2 +- tests/app/inbound_sms/test_rest.py | 16 +++++++++++----- .../notifications/test_receive_notification.py | 2 +- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/app/inbound_sms/rest.py b/app/inbound_sms/rest.py index 0ee2b9e90..8ebcff298 100644 --- a/app/inbound_sms/rest.py +++ b/app/inbound_sms/rest.py @@ -3,7 +3,7 @@ from flask import ( jsonify, request ) -from notifications_utils.recipients import normalise_phone_number +from notifications_utils.recipients import validate_and_format_phone_number from app.dao.inbound_sms_dao import dao_get_inbound_sms_for_service, dao_count_inbound_sms_for_service from app.errors import register_errors @@ -23,7 +23,8 @@ def get_inbound_sms_for_service(service_id): user_number = request.args.get('user_number') if user_number: - user_number = normalise_phone_number(user_number) + # we use this to normalise to an international phone number + user_number = validate_and_format_phone_number(user_number) results = dao_get_inbound_sms_for_service(service_id, limit, user_number) diff --git a/app/notifications/receive_notifications.py b/app/notifications/receive_notifications.py index cbe17e09e..d053a4198 100644 --- a/app/notifications/receive_notifications.py +++ b/app/notifications/receive_notifications.py @@ -2,7 +2,7 @@ from urllib.parse import unquote import iso8601 from flask import jsonify, Blueprint, current_app, request -from notifications_utils.recipients import normalise_phone_number +from notifications_utils.recipients import validate_and_format_phone_number from app import statsd_client from app.dao.services_dao import dao_fetch_services_by_sms_sender @@ -64,8 +64,8 @@ def format_mmg_datetime(date): def create_inbound_mmg_sms_object(service, json): - message = format_mmg_message(json['Message']) - user_number = normalise_phone_number(json['MSISDN']) + message = format_message(json['Message']) + user_number = validate_and_format_phone_number(json['MSISDN']) provider_date = json.get('DateRecieved') if provider_date: diff --git a/tests/app/db.py b/tests/app/db.py index cdc0d7a79..8fcced1b1 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -190,7 +190,7 @@ def create_service_permission(service_id, permission=EMAIL_TYPE): def create_inbound_sms( service, notify_number=None, - user_number='7700900111', + user_number='447700900111', provider_date=None, provider_reference=None, content='Hello' diff --git a/tests/app/inbound_sms/test_rest.py b/tests/app/inbound_sms/test_rest.py index 70acaddd2..25f5d7cff 100644 --- a/tests/app/inbound_sms/test_rest.py +++ b/tests/app/inbound_sms/test_rest.py @@ -1,5 +1,6 @@ from datetime import datetime +import pytest from freezegun import freeze_time from tests.app.db import create_inbound_sms, create_service @@ -46,14 +47,19 @@ def test_get_inbound_sms_limits(admin_request, sample_service): assert sms['data'][0]['id'] == str(two.id) -def test_get_inbound_sms_filters_user_number(admin_request, sample_service): - # user_number in the db is normalised - one = create_inbound_sms(sample_service, user_number='7700900001') - two = create_inbound_sms(sample_service, user_number='7700900002') +@pytest.mark.parametrize('user_number', [ + '(07700) 900-001', + '+4407700900001', + '447700900001', +]) +def test_get_inbound_sms_filters_user_number(admin_request, sample_service, user_number): + # user_number in the db is international and normalised + one = create_inbound_sms(sample_service, user_number='447700900001') + two = create_inbound_sms(sample_service, user_number='447700900002') sms = admin_request.get( 'inbound_sms.get_inbound_sms_for_service', - endpoint_kwargs={'service_id': sample_service.id, 'user_number': '(07700) 900-001'} + endpoint_kwargs={'service_id': sample_service.id, 'user_number': user_number} ) assert len(sms['data']) == 1 diff --git a/tests/app/notifications/test_receive_notification.py b/tests/app/notifications/test_receive_notification.py index 5d93e5fd3..317d9452e 100644 --- a/tests/app/notifications/test_receive_notification.py +++ b/tests/app/notifications/test_receive_notification.py @@ -63,7 +63,7 @@ def test_create_inbound_mmg_sms_object(sample_service): assert inbound_sms.service_id == sample_service.id assert inbound_sms.notify_number == 'foo' - assert inbound_sms.user_number == '7700900001' + assert inbound_sms.user_number == '447700900001' assert inbound_sms.provider_date == datetime(2017, 1, 2, 3, 4, 5) assert inbound_sms.provider_reference == 'bar' assert inbound_sms._content != 'hello there 📩' From 69c299dd6c7a233c02d674e721643f2bc3fb21fa Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Fri, 2 Jun 2017 13:34:02 +0100 Subject: [PATCH 5/5] ensure international numbers are handled correctly the international flag semantically means 'Should we throw an error if an international number is passed in?' (and the answer is no. We should not.) --- app/inbound_sms/rest.py | 2 +- app/notifications/receive_notifications.py | 4 ++-- tests/app/inbound_sms/test_rest.py | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/inbound_sms/rest.py b/app/inbound_sms/rest.py index 8ebcff298..d4072dea3 100644 --- a/app/inbound_sms/rest.py +++ b/app/inbound_sms/rest.py @@ -24,7 +24,7 @@ def get_inbound_sms_for_service(service_id): if user_number: # we use this to normalise to an international phone number - user_number = validate_and_format_phone_number(user_number) + user_number = validate_and_format_phone_number(user_number, international=True) results = dao_get_inbound_sms_for_service(service_id, limit, user_number) diff --git a/app/notifications/receive_notifications.py b/app/notifications/receive_notifications.py index d053a4198..0ed644904 100644 --- a/app/notifications/receive_notifications.py +++ b/app/notifications/receive_notifications.py @@ -64,8 +64,8 @@ def format_mmg_datetime(date): def create_inbound_mmg_sms_object(service, json): - message = format_message(json['Message']) - user_number = validate_and_format_phone_number(json['MSISDN']) + message = format_mmg_message(json['Message']) + user_number = validate_and_format_phone_number(json['MSISDN'], international=True) provider_date = json.get('DateRecieved') if provider_date: diff --git a/tests/app/inbound_sms/test_rest.py b/tests/app/inbound_sms/test_rest.py index 25f5d7cff..da10ecb6b 100644 --- a/tests/app/inbound_sms/test_rest.py +++ b/tests/app/inbound_sms/test_rest.py @@ -67,6 +67,21 @@ def test_get_inbound_sms_filters_user_number(admin_request, sample_service, user assert sms['data'][0]['user_number'] == str(one.user_number) +def test_get_inbound_sms_filters_international_user_number(admin_request, sample_service): + # user_number in the db is international and normalised + one = create_inbound_sms(sample_service, user_number='12025550104') + two = create_inbound_sms(sample_service) + + sms = admin_request.get( + 'inbound_sms.get_inbound_sms_for_service', + endpoint_kwargs={'service_id': sample_service.id, 'user_number': '+1 (202) 555-0104'} + ) + + assert len(sms['data']) == 1 + assert sms['data'][0]['id'] == str(one.id) + assert sms['data'][0]['user_number'] == str(one.user_number) + + def test_get_inbound_sms_summary(admin_request, sample_service): other_service = create_service(service_name='other_service') with freeze_time('2017-01-01'):