def test_get_single(db, session):  # pylint: disable=unused-argument
    """Verify that the get_single() returns correct results as expected
    from database table.
    """
    # add a notification for user
    user_id = 'notf-user'
    request_id = 225
    request_type = 'registration'
    request_status = 3
    message = 'this is a test notification'
    notification = Notification(user_id=user_id,
                                request_id=request_id,
                                request_type=request_type,
                                request_status=request_status,
                                message=message)
    notification.add()
    notification_id = get_notification_id(session, request_id)
    notification_data = Notification.get_single(notification_id)
    notification_data_raw = get_single_notification(session, notification_id)

    # verify results of both
    assert notification_data_raw.id == notification_data.id
    assert notification_data_raw.user_id == notification_data.user_id
    assert notification_data_raw.request_id == notification_data.request_id
    assert notification_data_raw.request_status == notification_data.request_status
    assert notification_data_raw.message == notification_data.message
def test_with_existing_notification_data(flask_app, db):  # pylint: disable=unused-argument
    """Verify that the api responds correctly when notification data exists in table."""
    # generate a  registration request type notification
    user_id = 'test-user1'
    notification = Notification(user_id=user_id, request_id=1342, request_type='registration_request',
                                request_status=6, message='a test notification has been generated')
    notification.add()

    # get notification for user id = test-user1
    api_url = '{api}?user_id={user_id}'.format(api=NOTIFICATION_API, user_id=user_id)
    rv = flask_app.get(api_url)
    assert rv.status_code == 200
    data = json.loads(rv.data.decode('utf-8'))
    assert len(data.get('notifications')) == 1
    data = data.get('notifications')[0]
    assert data.get('request_id') == 1342
    assert data.get('request_status') == 6
    assert data.get('request_type') == 'registration_request'
    assert data.get('id') == 1
    assert data.get('message') == 'a test notification has been generated'

    # generate multiple notifications for the same user
    notification = Notification(user_id=user_id, request_id=1343, request_type='de_registration_request',
                                request_status=7, message='a test notification has been generated')
    notification.add()
    api_url = '{api}?user_id={user_id}'.format(api=NOTIFICATION_API, user_id=user_id)
    rv = flask_app.get(api_url)
    assert rv.status_code == 200
    data = json.loads(rv.data.decode('utf-8'))
    assert len(data.get('notifications')) == 2
def test_exist_users(db, session):  # pylint: disable=unused-argument
    """Verify that the exist_user() work correctly."""
    # add a notification for user
    user_id = 'notf-user'
    request_id = 223
    request_type = 'registration'
    request_status = 3
    message = 'this is a test notification'
    notification = Notification(user_id=user_id,
                                request_id=request_id,
                                request_type=request_type,
                                request_status=request_status,
                                message=message)
    notification.add()
    user_exists_bool = Notification.exist_users(user_id)

    # check if it really exists in db
    res = exists_user_notifications(session, user_id)
    assert res is user_exists_bool

    # remove the above notification and then check again
    assert delete_user_notifications(session, user_id)
    user_exists_bool = Notification.exist_users(user_id)
    res = exists_user_notifications(session, user_id)
    assert res is user_exists_bool
def test_mark_notification_as_read_api(flask_app, db):  # pylint: disable=unused-argument
    """Verify that a generated notification is not return when mark as read."""
    # generate a  registration request type notification
    user_id = 'test-user1'
    notification = Notification(
        user_id=user_id,
        request_id=1342,
        request_type='registration_request',
        request_status=6,
        message='a test notification has been generated')
    notification.add()

    api_url = '{api}?user_id={user_id}'.format(api=NOTIFICATION_API,
                                               user_id=user_id)
    rv = flask_app.get(api_url)
    assert rv.status_code == 200
    data = json.loads(rv.data.decode('utf-8'))
    notification_id = data['notifications'][0]['id']

    # mark notification as read
    body_data = {'notification_id': notification_id, 'user_id': user_id}
    headers = {'Content-Type': 'application/json'}
    rv = flask_app.put(NOTIFICATION_API,
                       data=json.dumps(body_data),
                       headers=headers)
    assert rv.status_code == 201
def test_notification_put_api_with_invalid_data(flask_app, db):  # pylint: disable=unused-argument
    """Verify that the notification put api responds correctly in case of invalid input."""
    # invalid user id
    user_id = 'abcd-user'
    body_data = {'notification_id': 2, 'user_id': user_id}
    headers = {'Content-Type': 'application/json'}
    rv = flask_app.put(NOTIFICATION_API, data=json.dumps(body_data), headers=headers)
    assert rv.status_code == 400
    data = json.loads(rv.data.decode('utf-8'))
    assert data.get('error')[0] == 'user {0} does not exists'.format(user_id)

    # generate a notification with the same user id
    notification = Notification(user_id=user_id, request_id=1342, request_type='registration_request',
                                request_status=6, message='a test notification has been generated')
    notification.add()

    # invalid notification id test
    notification_id = 35
    body_data = {'notification_id': notification_id, 'user_id': user_id}
    rv = flask_app.put(NOTIFICATION_API, data=json.dumps(body_data), headers=headers)
    assert rv.status_code == 400
    data = json.loads(rv.data.decode('utf-8'))
    assert data.get('error')[0] == 'notification {0} does not exists'.format(notification_id)

    # wrong user for notification test
    user_id_2 = 'test-user1'
    notification = Notification(user_id=user_id_2, request_id=13, request_type='registration_request',
                                request_status=6, message='a test notification has been generated')
    notification.add()

    # get notification id
    rv = flask_app.get('{0}?user_id={1}'.format(NOTIFICATION_API, user_id_2))
    assert rv.status_code == 200
    data = json.loads(rv.data.decode('utf-8'))
    notification_id = data['notifications'][0]['id']

    # try to mark notification as read with wrong user
    body_data = {'notification_id': notification_id, 'user_id': user_id}
    rv = flask_app.put(NOTIFICATION_API, data=json.dumps(body_data), headers=headers)
    assert rv.status_code == 400
    data = json.loads(rv.data.decode('utf-8'))
    assert data.get('error')[0] == 'invalid user id'

    # string arguments test
    body_data = {'notification_id': '', 'user_id': ''}
    rv = flask_app.put(NOTIFICATION_API, data=json.dumps(body_data), headers=headers)
    assert rv.status_code == 422
    data = json.loads(rv.data.decode('utf-8'))
    assert data['notification_id'][0] == "Bad 'notification_id':'' argument format. Accepts only integer"
def test_add_notification(db, session):  # pylint: disable=unused-argument
    """Verify that the notifications model add functionality works correctly."""
    # add a notification using model
    user_id = 'test-user'
    request_id = 213
    request_type = 'registration'
    request_status = 3
    message = 'this is a test notification'
    notification = Notification(user_id=user_id,
                                request_id=request_id,
                                request_type=request_type,
                                request_status=request_status,
                                message=message)
    notification.add()

    # check entry in database
    res = session.execute(
        text("""SELECT * FROM public.notification
                                    WHERE request_id='213'""")).fetchone()
    assert res.user_id == user_id
    assert res.request_id == request_id
    assert res.request_type == request_type
    assert res.request_status == 3
    assert res.message == message
    # marked_read should be false initially
    assert not res.marked_read

    # notification is not added without committing to the db using add()
    user_id = 'test-user'
    request_id = 2100
    request_type = 'de_registration'
    request_status = 7
    message = 'this is a test notification'
    notification = Notification(user_id=user_id,
                                request_id=request_id,
                                request_type=request_type,
                                request_status=request_status,
                                message=message)
    res = session.execute(
        text("""SELECT * FROM public.notification
                                    WHERE request_id='2100'""")).fetchone()
    assert not res
def test_exists(db, session):  # pylint: disable=unused-argument
    """Verify that exists() responds correctly while checking for existence of notifications."""
    # add a new notification
    user_id = 'notf-user'
    request_id = 224
    request_type = 'registration'
    request_status = 7
    message = 'this is a test notification'
    notification = Notification(user_id=user_id,
                                request_id=request_id,
                                request_type=request_type,
                                request_status=request_status,
                                message=message)
    notification.add()

    # get notification id
    notification_id = get_notification_id(session, request_id)
    notification_bool = Notification.exists(notification_id)

    # check if it really exists
    res = exists_notification(session, notification_id)
    assert res is notification_bool
def test_mark_read(db, session):  # pylint: disable=unused-argument
    """Verify that mark_read() mark marked_read column as True."""
    # add a notification
    user_id = 'notf-user'
    request_id = 226
    request_type = 'registration'
    request_status = 3
    message = 'this is a test notification'
    notification = Notification(user_id=user_id,
                                request_id=request_id,
                                request_type=request_type,
                                request_status=request_status,
                                message=message)
    notification.add()

    # get notification id
    notification_id = get_notification_id(session, request_id)
    notification_data = get_single_notification(session, notification_id)
    assert notification_data.marked_read is False

    # call mark_read()
    Notification.mark_read(notification_id)
    notification_data = get_single_notification(session, notification_id)
    assert notification_data.marked_read is True
    def put():
        """PUT method handler, updates documents."""
        reg_id = request.form.to_dict().get('reg_id', None)
        if not reg_id or not reg_id.isdigit() or not RegDetails.exists(reg_id):
            return Response(app.json_encoder.encode(REG_NOT_FOUND_MSG),
                            status=CODES.get("UNPROCESSABLE_ENTITY"),
                            mimetype=MIME_TYPES.get("APPLICATION_JSON"))

        try:
            schema = RegistrationDocumentsUpdateSchema()
            time = datetime.now().strftime('%Y%m%d%H%M%S')
            args = request.form.to_dict()
            args = Utilities.update_args_with_file(request.files, args)
            reg_details = RegDetails.get_by_id(reg_id)
            if reg_details:
                args.update({
                    'reg_details_id': reg_details.id,
                    'status': reg_details.status
                })
            else:
                args.update({'reg_details_id': ''})
            validation_errors = schema.validate(args)
            if validation_errors:
                return Response(app.json_encoder.encode(validation_errors),
                                status=CODES.get("UNPROCESSABLE_ENTITY"),
                                mimetype=MIME_TYPES.get("APPLICATION_JSON"))

            tracking_id = reg_details.tracking_id
            updated = RegDocuments.bulk_update(request.files, reg_details,
                                               time)
            response = Utilities.store_files(request.files, tracking_id, time)
            if response:
                return Response(json.dumps(response),
                                status=CODES.get("UNPROCESSABLE_ENTITY"),
                                mimetype=MIME_TYPES.get("APPLICATION_JSON"))
            if reg_details.status == Status.get_status_id(
                    'Information Requested'):
                reg_details.update_status('In Review')
                message = 'The request {id} has been updated.'.format(
                    id=reg_details.id)
                notification = Notification(reg_details.reviewer_id,
                                            reg_details.id,
                                            'registration_request',
                                            reg_details.status, message)
                notification.add()
            else:
                reg_details.update_status('Pending Review')
            response = schema.dump(updated, many=True).data
            db.session.commit()
            return Response(json.dumps(response),
                            status=CODES.get("OK"),
                            mimetype=MIME_TYPES.get("APPLICATION_JSON"))
        except Exception as e:  # pragma: no cover
            db.session.rollback()
            app.logger.exception(e)

            data = {
                'message':
                _('request document updation failed, please try again later.')
            }

            return Response(app.json_encoder.encode(data),
                            status=CODES.get('INTERNAL_SERVER_ERROR'),
                            mimetype=MIME_TYPES.get('APPLICATION_JSON'))
        finally:
            db.session.close()