def update_service(service_id): try: service = get_model_services(service_id=service_id) except DataError: return jsonify(result="error", message="Invalid service id"), 400 except NoResultFound: return jsonify(result="error", message="Service not found"), 404 if request.method == 'DELETE': status_code = 202 delete_model_service(service) else: status_code = 200 # TODO there has got to be a better way to do the next three lines upd_serv, errors = service_schema.load(request.get_json()) if errors: return jsonify(result="error", message=errors), 400 update_dict, errors = service_schema.dump(upd_serv) # TODO FIX ME # Remove update_service model which is added to db.session db.session.rollback() try: save_model_service(service, update_dict=update_dict) except DAOException as e: return jsonify(result="error", message=str(e)), 400 return jsonify(data=service_schema.dump(service).data), status_code
def update_service(service_id): req_json = request.get_json() fetched_service = dao_fetch_service_by_id(service_id) # Capture the status change here as Marshmallow changes this later service_going_live = fetched_service.restricted and not req_json.get( 'restricted', True) current_data = dict(service_schema.dump(fetched_service).data.items()) current_data.update(request.get_json()) service = service_schema.load(current_data).data if 'email_branding' in req_json: email_branding_id = req_json['email_branding'] service.email_branding = None if not email_branding_id else EmailBranding.query.get( email_branding_id) if 'letter_branding' in req_json: letter_branding_id = req_json['letter_branding'] service.letter_branding = None if not letter_branding_id else LetterBranding.query.get( letter_branding_id) dao_update_service(service) if service_going_live: send_notification_to_service_users( service_id=service_id, template_id=current_app.config['SERVICE_NOW_LIVE_TEMPLATE_ID'], personalisation={ 'service_name': current_data['name'], 'message_limit': '{:,}'.format(current_data['message_limit']) }, include_user_fields=['name']) return jsonify(data=service_schema.dump(fetched_service).data), 200
def update_service(service_id): req_json = request.get_json() fetched_service = dao_fetch_service_by_id(service_id) # Capture the status change here as Marshmallow changes this later service_going_live = fetched_service.restricted and not req_json.get( "restricted", True) message_limit_changed = fetched_service.message_limit != req_json.get( "message_limit", fetched_service.message_limit) current_data = dict(service_schema.dump(fetched_service).data.items()) current_data.update(request.get_json()) service = service_schema.load(current_data).data if "email_branding" in req_json: email_branding_id = req_json["email_branding"] service.email_branding = None if not email_branding_id else EmailBranding.query.get( email_branding_id) if "letter_branding" in req_json: letter_branding_id = req_json["letter_branding"] service.letter_branding = None if not letter_branding_id else LetterBranding.query.get( letter_branding_id) dao_update_service(service) if message_limit_changed: redis_store.delete(daily_limit_cache_key(service_id)) redis_store.delete(near_daily_limit_cache_key(service_id)) redis_store.delete(over_daily_limit_cache_key(service_id)) if not fetched_service.restricted: _warn_service_users_about_message_limit_changed( service_id, current_data) if service_going_live: _warn_services_users_about_going_live(service_id, current_data) try: # Two scenarios, if there is a user that has requested to go live, we will use that user # to create a user-service/contact-deal pair between notify and zendesk sell # If by any chance there is no tracked request to a user, notify will try to identify the user # that created the service and then create a user-service/contact-deal relationship if service.go_live_user_id: user = get_user_by_id(service.go_live_user_id) else: user = dao_fetch_service_creator(service.id) ZenDeskSell().send_go_live_service(service, user) except Exception as e: current_app.logger.exception(e) return jsonify(data=service_schema.dump(fetched_service).data), 200
def update_service(service_id): req_json = request.get_json() fetched_service = dao_fetch_service_by_id(service_id) # Capture the status change here as Marshmallow changes this later service_going_live = fetched_service.restricted and not req_json.get('restricted', True) service_go_live_requested = 'go_live_user' in req_json current_data = dict(service_schema.dump(fetched_service).data.items()) current_data.update(request.get_json()) service = service_schema.load(current_data).data if 'email_branding' in req_json: email_branding_id = req_json['email_branding'] service.email_branding = None if not email_branding_id else EmailBranding.query.get(email_branding_id) if 'letter_branding' in req_json: letter_branding_id = req_json['letter_branding'] service.letter_branding = None if not letter_branding_id else LetterBranding.query.get(letter_branding_id) dao_update_service(service) if service_go_live_requested: template = dao_get_template_by_id(current_app.config['NOTIFY_ADMIN_OF_GO_LIVE_REQUEST_TEMPLATE_ID']) service_url = "{}/services/{}".format(current_app.config['ADMIN_BASE_URL'], str(service.id)) saved_notification = persist_notification( template_id=template.id, template_version=template.version, recipient=get_or_build_support_email_address(), service=template.service, personalisation={ 'service_name': service.name, 'service_dashboard_url': service_url }, notification_type=EMAIL_TYPE, api_key_id=None, key_type=KEY_TYPE_NORMAL, reply_to_text=get_or_build_support_email_address() ) send_notification_to_queue(saved_notification, research_mode=False, queue=QueueNames.NOTIFY) if service_going_live: send_notification_to_service_users( service_id=service_id, template_id=current_app.config['SERVICE_NOW_LIVE_TEMPLATE_ID'], personalisation={ 'service_name': current_data['name'], 'message_limit': '{:,}'.format(current_data['message_limit']) }, include_user_fields=['name'] ) return jsonify(data=service_schema.dump(fetched_service).data), 200
def get_services(): only_active = request.args.get('only_active') == 'True' detailed = request.args.get('detailed') == 'True' user_id = request.args.get('user_id', None) include_from_test_key = request.args.get('include_from_test_key', 'True') != 'False' # If start and end date are not set, we are expecting today's stats. today = str(datetime.utcnow().date()) start_date = datetime.strptime(request.args.get('start_date', today), '%Y-%m-%d').date() end_date = datetime.strptime(request.args.get('end_date', today), '%Y-%m-%d').date() if user_id: services = dao_fetch_all_services_by_user(user_id, only_active) elif detailed: result = jsonify(data=get_detailed_services( start_date=start_date, end_date=end_date, only_active=only_active, include_from_test_key=include_from_test_key)) return result else: services = dao_fetch_all_services(only_active) data = service_schema.dump(services, many=True).data return jsonify(data=data)
def test_send_sms_to_provider_should_return_template_if_found_in_redis( mocker, client, sample_template): from app.schemas import service_schema, template_schema service_dict = service_schema.dump(sample_template.service).data template_dict = template_schema.dump(sample_template).data mocker.patch( 'app.redis_store.get', side_effect=[ json.dumps({ 'data': service_dict }).encode('utf-8'), json.dumps({ 'data': template_dict }).encode('utf-8'), ], ) mock_get_template = mocker.patch( 'app.dao.templates_dao.dao_get_template_by_id_and_service_id') mock_get_service = mocker.patch( 'app.dao.services_dao.dao_fetch_service_by_id') send_mock = mocker.patch('app.mmg_client.send_sms') notification = create_notification(template=sample_template, to_field='+447700900855', normalised_to='447700900855') send_to_providers.send_sms_to_provider(notification) assert mock_get_template.called is False assert mock_get_service.called is False send_mock.assert_called_once_with(to=notification.normalised_to, content=ANY, reference=str(notification.id), sender=notification.reply_to_text)
def create_service(): data = request.get_json() if not data.get("user_id"): errors = {"user_id": ["Missing data for required field."]} raise InvalidRequest(errors, status_code=400) data.pop("service_domain", None) # validate json with marshmallow service_schema.load(data) user = get_user_by_id(data.pop("user_id")) # unpack valid json into service object valid_service = Service.from_json(data) dao_create_service(valid_service, user) try: # try-catch; just in case, we don't want to error here ZenDeskSell().send_create_service(valid_service, user) except Exception as e: current_app.logger.exception(e) return jsonify(data=service_schema.dump(valid_service).data), 201
def get_services(): only_active = request.args.get("only_active") == "True" detailed = request.args.get("detailed") == "True" user_id = request.args.get("user_id", None) include_from_test_key = request.args.get("include_from_test_key", "True") != "False" # If start and end date are not set, we are expecting today's stats. today = str(datetime.utcnow().date()) start_date = datetime.strptime(request.args.get("start_date", today), "%Y-%m-%d").date() end_date = datetime.strptime(request.args.get("end_date", today), "%Y-%m-%d").date() if user_id: services = dao_fetch_all_services_by_user(user_id, only_active) elif detailed: result = jsonify(data=get_detailed_services( start_date=start_date, end_date=end_date, only_active=only_active, include_from_test_key=include_from_test_key, )) return result else: services = dao_fetch_all_services(only_active) data = service_schema.dump(services, many=True).data return jsonify(data=data)
def get_service_by_id(service_id): if request.args.get('detailed') == 'True': data = get_detailed_service(service_id, today_only=request.args.get('today_only') == 'True') else: fetched = dao_fetch_service_by_id(service_id) data = service_schema.dump(fetched).data return jsonify(data=data)
def get_dict(service_id): from app.schemas import service_schema service_dict = service_schema.dump( dao_fetch_service_by_id(service_id)).data db.session.commit() return {'data': service_dict}
def get_service_by_id(service_id): if request.args.get("detailed") == "True": data = get_detailed_service( service_id, today_only=request.args.get("today_only") == "True") else: fetched = dao_fetch_service_by_id(service_id) data = service_schema.dump(fetched).data return jsonify(data=data)
def get_service(service_id=None): user_id = request.args.get('user_id', None) try: services = get_model_services(service_id=service_id, user_id=user_id) except DataError: return jsonify(result="error", message="Invalid service id"), 400 except NoResultFound: return jsonify(result="error", message="Service not found"), 404 data, errors = services_schema.dump(services) if isinstance(services, list) else service_schema.dump(services) return jsonify(data=data)
def get_service(service_id=None): user_id = request.args.get('user_id', None) try: services = get_model_services(service_id=service_id, user_id=user_id) except DataError: return jsonify(result="error", message="Invalid service id"), 400 except NoResultFound: return jsonify(result="error", message="Service not found"), 404 data, errors = services_schema.dump(services) if isinstance( services, list) else service_schema.dump(services) return jsonify(data=data)
def test_services_schema_includes_providers(sample_service, ses_provider, current_sms_provider): from app.schemas import service_schema sample_service.email_provider_id = ses_provider.id sample_service.sms_provider_id = current_sms_provider.id data = service_schema.dump(sample_service).data assert data assert data['email_provider_id'] == str(ses_provider.id) assert data['sms_provider_id'] == str(current_sms_provider.id)
def create_service(): # TODO what exceptions get passed from schema parsing? service, errors = service_schema.load(request.get_json()) if errors: return jsonify(result="error", message=errors), 400 # I believe service is already added to the session but just needs a # db.session.commit try: save_model_service(service) except DAOException as e: return jsonify(result="error", message=str(e)), 400 return jsonify(data=service_schema.dump(service).data), 201
def add_user_to_service(service_id, user_id): service = dao_fetch_service_by_id(service_id) user = get_user_by_id(user_id=user_id) if user in service.users: error = 'User id: {} already part of service id: {}'.format(user_id, service_id) raise InvalidRequest(error, status_code=400) permissions = permission_schema.load(request.get_json(), many=True).data dao_add_user_to_service(service, user, permissions) data = service_schema.dump(service).data return jsonify(data=data), 201
def test_should_cache_template_and_service_in_redis(mocker, client, sample_template): from app.schemas import service_schema, template_schema mock_redis_get = mocker.patch( 'app.redis_store.get', return_value=None, ) mock_redis_set = mocker.patch( 'app.redis_store.set', ) mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') data = { 'phone_number': '+447700900855', 'template_id': str(sample_template.id), } auth_header = create_authorization_header(service_id=sample_template.service_id) client.post( path='/v2/notifications/sms', data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header] ) expected_service_key = f'service-{sample_template.service_id}' expected_templates_key = f'service-{sample_template.service_id}-template-{sample_template.id}-version-None' assert mock_redis_get.call_args_list == [ call(expected_service_key), call(expected_templates_key), ] service_dict = service_schema.dump(sample_template.service).data template_dict = template_schema.dump(sample_template).data assert len(mock_redis_set.call_args_list) == 2 service_call, templates_call = mock_redis_set.call_args_list assert service_call[0][0] == expected_service_key assert json.loads(service_call[0][1]) == {'data': service_dict} assert service_call[1]['ex'] == 604_800 assert templates_call[0][0] == expected_templates_key assert json.loads(templates_call[0][1]) == {'data': template_dict} assert templates_call[1]['ex'] == 604_800
def get_service_by_user_id(user_id, service_id=None): try: user = get_model_users(user_id=user_id) except DataError: return jsonify(result="error", message="Invalid user id"), 400 except NoResultFound: return jsonify(result="error", message="User not found"), 404 try: services = get_model_services(user_id=user.id, service_id=service_id) except DataError: return jsonify(result="error", message="Invalid service id"), 400 except NoResultFound: return jsonify(result="error", message="Service not found"), 404 services, errors = services_schema.dump(services) if isinstance( services, list) else service_schema.dump(services) return jsonify(data=services)
def create_service(): data = request.get_json() if not data.get('user_id'): errors = {'user_id': ['Missing data for required field.']} raise InvalidRequest(errors, status_code=400) # validate json with marshmallow service_schema.load(data) user = get_user_by_id(data.pop('user_id')) # unpack valid json into service object valid_service = Service.from_json(data) dao_create_service(valid_service, user) return jsonify(data=service_schema.dump(valid_service).data), 201
def add_user_to_service(service_id, user_id): service = dao_fetch_service_by_id(service_id) user = get_user_by_id(user_id=user_id) if user in service.users: error = 'User id: {} already part of service id: {}'.format(user_id, service_id) raise InvalidRequest(error, status_code=400) data = request.get_json() validate(data, post_set_permissions_schema) permissions = [ Permission(service_id=service_id, user_id=user_id, permission=p['permission']) for p in data['permissions'] ] folder_permissions = data.get('folder_permissions', []) dao_add_user_to_service(service, user, permissions, folder_permissions) data = service_schema.dump(service).data return jsonify(data=data), 201
def set_as_broadcast_service(service_id): """ This route does the following - adds a service broadcast settings to define which channel broadcasts should go out on - removes all current service permissions and adds the broadcast service permission - sets the services `count_as_live` to false - adds the service to the broadcast organisation - puts the service into training mode or live mode """ data = validate(request.get_json(), service_broadcast_settings_schema) service = dao_fetch_service_by_id(service_id) set_broadcast_service_type( service, service_mode=data["service_mode"], broadcast_channel=data["broadcast_channel"], provider_restriction=data["provider_restriction"]) data = service_schema.dump(service).data return jsonify(data=data)
def create_service(): data = request.get_json() if not data.get('user_id'): errors = {'user_id': ['Missing data for required field.']} raise InvalidRequest(errors, status_code=400) data.pop('service_domain', None) # validate json with marshmallow service_schema.load(data) user = get_user_by_id(data.pop('user_id')) # unpack valid json into service object valid_service = Service.from_json(data) with transaction(): dao_create_service(valid_service, user) set_default_free_allowance_for_service(service=valid_service, year_start=None) return jsonify(data=service_schema.dump(valid_service).data), 201
def test_should_return_template_if_found_in_redis(mocker, client, sample_template): from app.schemas import service_schema, template_schema service_dict = service_schema.dump(sample_template.service).data template_dict = template_schema.dump(sample_template).data mocker.patch( 'app.redis_store.get', side_effect=[ json.dumps({ 'data': service_dict }).encode('utf-8'), json.dumps({ 'data': template_dict }).encode('utf-8'), ], ) mock_get_template = mocker.patch( 'app.dao.templates_dao.dao_get_template_by_id_and_service_id') mock_get_service = mocker.patch( 'app.dao.services_dao.dao_fetch_service_by_id') mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async') data = { 'phone_number': '+447700900855', 'template_id': str(sample_template.id), } auth_header = create_authorization_header( service_id=sample_template.service_id) response = client.post(path='/v2/notifications/sms', data=json.dumps(data), headers=[('Content-Type', 'application/json'), auth_header]) assert response.status_code == 201 assert mock_get_template.called is False assert mock_get_service.called is False
def test_send_email_to_provider_should_return_template_if_found_in_redis( mocker, client, sample_email_template): from app.schemas import service_schema, template_schema service_dict = service_schema.dump(sample_email_template.service).data template_dict = template_schema.dump(sample_email_template).data mocker.patch( 'app.redis_store.get', side_effect=[ json.dumps({ 'data': service_dict }).encode('utf-8'), json.dumps({ 'data': template_dict }).encode('utf-8'), ], ) mock_get_template = mocker.patch( 'app.dao.templates_dao.dao_get_template_by_id_and_service_id') mock_get_service = mocker.patch( 'app.dao.services_dao.dao_fetch_service_by_id') send_mock = mocker.patch('app.aws_ses_client.send_email', return_value='reference') notification = create_notification(template=sample_email_template, to_field='*****@*****.**', normalised_to='*****@*****.**') send_to_providers.send_email_to_provider(notification) assert mock_get_template.called is False assert mock_get_service.called is False send_mock.assert_called_once_with( ANY, notification.normalised_to, ANY, body=ANY, html_body=ANY, reply_to_address=notification.reply_to_text)
def get_service_by_user_id(user_id, service_id=None): try: user = get_model_users(user_id=user_id) except DataError: return jsonify(result="error", message="Invalid user id"), 400 except NoResultFound: return jsonify(result="error", message="User not found"), 404 try: services = get_model_services(user_id=user.id, service_id=service_id) except DataError: return jsonify(result="error", message="Invalid service id"), 400 except NoResultFound: return jsonify(result="error", message="Service not found"), 404 services, errors = services_schema.dump(services) if isinstance(services, list) else service_schema.dump(services) return jsonify(data=services)