예제 #1
0
def test_send_message(fake_app, recipients, sys_msg, resp, err):
    """
    The send message function is able to generate system messages
    by prepending the message with the organization name. It can
    broadcast the message to multiple recipients. If an error 
    occurs when using the SMS controller client, an internal 
    exception is raised, bubbles up and is tranformed to a 
    response for the client side. Database state is not rolled back
    in the event of a message send failure.
    """
    session_id = 'session_id'
    msg = 'hello'
    virtual_tn = '13334445555'
    from sms_proxy.api import send_message
    if resp is False:
        fake_app.sms_controller.resp.append(resp)
        with pytest.raises(err):
            send_message(recipients,
                         virtual_tn,
                         msg,
                         session_id,
                         is_system_msg=sys_msg)
    else:
        send_message(recipients,
                     virtual_tn,
                     msg,
                     session_id,
                     is_system_msg=sys_msg)
        assert len(fake_app.sms_controller.requests) == len(recipients)
        if sys_msg:
            msg = "[{}]: {}".format(ORG_NAME.upper(), msg)
        for sms in fake_app.sms_controller.requests:
            assert sms.to in recipients
            assert sms.mfrom == virtual_tn
            assert sms.content == msg
예제 #2
0
파일: api.py 프로젝트: tuxpowered/sms-proxy
def send_message(recipients, virtual_tn, msg, session_id, is_system_msg=False):
    """
    For each recipient, passes a Message to Flowroute's messaging controller.
    The message will be sent from the 'virtual_tn' number. If this is a system
    message, the message body will be prefixed with the org name for context.
    If an exception is raised by the controller, an error is logged, and an
    internal error is raised with the exception content.
    """
    if is_system_msg:
        msg = "[{}]: {}".format(ORG_NAME.upper(), msg)
    for recipient in recipients:
        message = Message(to=recipient, from_=virtual_tn, content=msg)
        try:
            app.sms_controller.create_message(message)
        except Exception as e:
            strerr = vars(e).get("response_body", None)
            log.critical(
                {
                    "message": "Raised an exception sending SMS",
                    "status": "failed",
                    "exc": e,
                    "strerr": vars(e).get("response_body", None),
                }
            )
            raise InternalSMSDispatcherError(
                "An error occured when requesting against Flowroute's API.",
                payload={"strerr": strerr, "reason": "InternalSMSDispatcherError"},
            )
        else:
            log.info(
                {"message": "Message sent to {} for session {}".format(recipient, session_id), "status": "succeeded"}
            )
예제 #3
0
def test_inbound_handler_expired_session(fake_app, valid_session):
    """
    An inbound message intended for a VirtualTN that is no longer
    in a session with the sender will no proxy to the other 
    participant. Asserts a system message is fired back to the 
    sender.
    """
    valid_session.expiry_date = datetime.utcnow()
    db_session.add(valid_session)
    db_session.commit()
    expired_session = valid_session
    client = fake_app.test_client()
    req = {
        'to': expired_session.virtual_TN,
        'from': expired_session.participant_a,
        'body': 'hello from participant a'
    }
    resp = client.post('/',
                       data=json.dumps(req),
                       content_type='application/json')
    # Indicating that we received the message from Flowroute
    assert resp.status_code == 200
    sms = fake_app.sms_controller.requests[0]
    msg = "[{}]: {}".format(ORG_NAME.upper(), NO_SESSION_MSG)
    assert sms.content == msg
    assert sms.to == expired_session.participant_a
    assert sms.mfrom == expired_session.virtual_TN
예제 #4
0
def test_send_message(fake_app, recipients, sys_msg, resp, err):
    """
    The send message function is able to generate system messages
    by prepending the message with the organization name. It can
    broadcast the message to multiple recipients. If an error 
    occurs when using the SMS controller client, an internal 
    exception is raised, bubbles up and is tranformed to a 
    response for the client side. Database state is not rolled back
    in the event of a message send failure.
    """
    session_id = 'session_id'
    msg = 'hello'
    virtual_tn = '13334445555'
    from sms_proxy.api import send_message
    if resp is False:
        fake_app.sms_controller.resp.append(resp)
        with pytest.raises(err):
            send_message(recipients, virtual_tn, msg, session_id,
                         is_system_msg=sys_msg)
    else:
        send_message(recipients, virtual_tn, msg, session_id,
                     is_system_msg=sys_msg)
        assert len(fake_app.sms_controller.requests) == len(recipients)
        if sys_msg:
            msg = "[{}]: {}".format(ORG_NAME.upper(), msg)
        for sms in fake_app.sms_controller.requests:
            assert sms.to in recipients
            assert sms.mfrom == virtual_tn
            assert sms.content == msg
예제 #5
0
def test_post_session():
    """
    Initially attempts to create a session when there are no VirtualTN's
    available. The service responds with a 400, and an appropriate message.
    Attempts again, when there is a VirtualTN in the pool, but reserved,
    the service will respond again with a 400. After releasing the 
    VirtualTN, the request succesfully posts, and the response is checked
    for appropriate values. Ensures both session initialization SMS messages
    have been fired off.
    """
    mock_controller = MockController()
    app.sms_controller = mock_controller
    client = app.test_client()
    test_num = '12223334444'
    resp = client.post('/session',
                       data=json.dumps({
                           'participant_a': '13334445555',
                           'participant_b': '14445556666'
                       }),
                       content_type='application/json')
    data = json.loads(resp.data)
    assert resp.status_code == 400
    assert 'Could not create a new session -- No virtual TNs available.' in data[
        'message']
    vnum = VirtualTN(test_num)
    vnum.session_id = 'fake_session_id'
    db_session.add(vnum)
    db_session.commit()
    resp = client.post('/session',
                       data=json.dumps({
                           'participant_a': '13334445555',
                           'participant_b': '14445556666'
                       }),
                       content_type='application/json')
    data = json.loads(resp.data)
    assert resp.status_code == 400
    vnum.session_id = None
    db_session.add(vnum)
    db_session.commit()
    resp = client.post('/session',
                       data=json.dumps({
                           'participant_a': '13334445555',
                           'participant_b': '14445556666'
                       }),
                       content_type='application/json')
    assert resp.status_code == 200
    data = json.loads(resp.data)
    assert 'Created new session' in data['message']
    assert data['virtual_tn'] == vnum.value
    assert len(mock_controller.requests) == 2
    msg = "[{}]: {}".format(ORG_NAME.upper(), SESSION_START_MSG)
    sms = mock_controller.requests[0]
    assert sms.content == msg
    assert data['session_id'] is not None
예제 #6
0
def test_post_session():
    """
    Initially attempts to create a session when there are no VirtualTN's
    available. The service responds with a 400, and an appropriate message.
    Attempts again, when there is a VirtualTN in the pool, but reserved,
    the service will respond again with a 400. After releasing the 
    VirtualTN, the request succesfully posts, and the response is checked
    for appropriate values. Ensures both session initialization SMS messages
    have been fired off.
    """
    mock_controller = MockController()
    app.sms_controller = mock_controller
    client = app.test_client()
    test_num = '12223334444'
    resp = client.post('/session', data=json.dumps({'participant_a': '13334445555',
                                                    'participant_b': '14445556666'}),
                       content_type='application/json')
    data = json.loads(resp.data)
    assert resp.status_code == 400
    assert 'Could not create a new session -- No virtual TNs available.' in data['message']
    vnum = VirtualTN(test_num)
    vnum.session_id = 'fake_session_id'
    db_session.add(vnum)
    db_session.commit()
    resp = client.post('/session', data=json.dumps({'participant_a': '13334445555',
                                                    'participant_b': '14445556666'}),
                       content_type='application/json')
    data = json.loads(resp.data)
    assert resp.status_code == 400
    vnum.session_id = None
    db_session.add(vnum)
    db_session.commit()
    resp = client.post('/session', data=json.dumps({'participant_a': '13334445555',
                                                    'participant_b': '14445556666'}),
                       content_type='application/json')
    assert resp.status_code == 200
    data = json.loads(resp.data)
    assert 'Created new session' in data['message']
    assert data['virtual_tn'] == vnum.value
    assert len(mock_controller.requests) == 2
    msg = "[{}]: {}".format(ORG_NAME.upper(), SESSION_START_MSG)
    sms = mock_controller.requests[0]
    assert sms.content == msg
    assert data['session_id'] is not None
예제 #7
0
def test_delete_session():
    """
    Initially tries to delete a session from an id that is unknown. The service
    responds with a 404, and helpful message. A session is created an persisted
    to the database. A delete request for that session is executed, and SMS's
    are dispatched to the participants.
    """
    mock_controller = MockController()
    app.sms_controller = mock_controller
    client = app.test_client()
    resp = client.delete('/session',
                         data=json.dumps({'session_id': 'fake_id'}),
                         content_type='application/json')
    data = json.loads(resp.data)
    assert resp.status_code == 404
    msg = ("ProxySession {} could not be deleted because"
           " it does not exist".format('fake_id'))
    assert data['message'] == msg
    test_num_1 = '12223334444'
    vnum_1 = VirtualTN(test_num_1)
    sess_1 = ProxySession(test_num_1, 'cust_1_num', 'cust_2_num')
    vnum_1.session_id = sess_1.id
    db_session.add(sess_1)
    db_session.add(vnum_1)
    db_session.commit()
    resp = client.delete('/session',
                         data=json.dumps({'session_id': sess_1.id}),
                         content_type='application/json')
    assert resp.status_code == 200
    data = json.loads(resp.data)
    assert data['message'] == 'Successfully ended the session.'
    assert data['session_id'] == sess_1.id
    sms = mock_controller.requests[0]
    msg = "[{}]: {}".format(ORG_NAME.upper(), SESSION_END_MSG)
    assert sms.content == msg
    assert len(mock_controller.requests) == 2
예제 #8
0
def send_message(recipients, virtual_tn, msg, session_id, is_system_msg=False):
    """
    For each recipient, passes a Message to Flowroute's messaging controller.
    The message will be sent from the 'virtual_tn' number. If this is a system
    message, the message body will be prefixed with the org name for context.
    If an exception is raised by the controller, an error is logged, and an
    internal error is raised with the exception content.
    """
    if is_system_msg:
        msg = "[{}]: {}".format(ORG_NAME.upper(), msg)
    for recipient in recipients:
        message = Message(to=recipient, from_=virtual_tn, content=msg)
        try:
            app.sms_controller.create_message(message)
        except Exception as e:
            strerr = vars(e).get('response_body', None)
            log.critical({
                "message": "Raised an exception sending SMS",
                "status": "failed",
                "exc": e,
                "strerr": vars(e).get('response_body', None)
            })
            raise InternalSMSDispatcherError(
                "An error occured when requesting against Flowroute's API.",
                payload={
                    "strerr": strerr,
                    "reason": "InternalSMSDispatcherError"
                })
        else:
            log.info({
                "message":
                "Message sent to {} for session {}".format(
                    recipient, session_id),
                "status":
                "succeeded"
            })
예제 #9
0
def test_inbound_handler_expired_session(fake_app, valid_session):
    """
    An inbound message intended for a VirtualTN that is no longer
    in a session with the sender will no proxy to the other 
    participant. Asserts a system message is fired back to the 
    sender.
    """
    valid_session.expiry_date = datetime.utcnow()
    db_session.add(valid_session)
    db_session.commit()
    expired_session = valid_session
    client = fake_app.test_client()
    req = {'to': expired_session.virtual_TN,
           'from': expired_session.participant_a,
           'body': 'hello from participant a'}
    resp = client.post('/', data=json.dumps(req),
                       content_type='application/json')
    # Indicating that we received the message from Flowroute
    assert resp.status_code == 200
    sms = fake_app.sms_controller.requests[0]
    msg = "[{}]: {}".format(ORG_NAME.upper(), NO_SESSION_MSG)
    assert sms.content == msg
    assert sms.to == expired_session.participant_a
    assert sms.mfrom == expired_session.virtual_TN
예제 #10
0
def test_delete_session():
    """
    Initially tries to delete a session from an id that is unknown. The service
    responds with a 404, and helpful message. A session is created an persisted
    to the database. A delete request for that session is executed, and SMS's
    are dispatched to the participants.
    """
    mock_controller = MockController()
    app.sms_controller = mock_controller
    client = app.test_client()
    resp = client.delete('/session',
                         data=json.dumps({'session_id': 'fake_id'}),
                         content_type='application/json')
    data = json.loads(resp.data)
    assert resp.status_code == 404
    msg = ("ProxySession {} could not be deleted because"
           " it does not exist".format('fake_id'))
    assert data['message'] == msg
    test_num_1 = '12223334444'
    vnum_1 = VirtualTN(test_num_1)
    sess_1 = ProxySession(test_num_1, 'cust_1_num', 'cust_2_num')
    vnum_1.session_id = sess_1.id
    db_session.add(sess_1)
    db_session.add(vnum_1)
    db_session.commit()
    resp = client.delete('/session',
                         data=json.dumps({'session_id': sess_1.id}),
                         content_type='application/json')
    assert resp.status_code == 200
    data = json.loads(resp.data)
    assert data['message'] == 'Successfully ended the session.'
    assert data['session_id'] == sess_1.id
    sms = mock_controller.requests[0]
    msg = "[{}]: {}".format(ORG_NAME.upper(), SESSION_END_MSG)
    assert sms.content == msg
    assert len(mock_controller.requests) == 2