diff --git a/app/assets/stylesheets/components/table.scss b/app/assets/stylesheets/components/table.scss index 37478ad6d..ed749b6e3 100644 --- a/app/assets/stylesheets/components/table.scss +++ b/app/assets/stylesheets/components/table.scss @@ -41,3 +41,10 @@ @extend .table-field; text-align: right; } + +.table-empty-message { + @include core-16; + color: $secondary-text-colour; + border-bottom: 1px solid $border-colour; + padding: 5px 0 8px 0; +} diff --git a/app/main/dao/services_dao.py b/app/main/dao/services_dao.py index aea05e075..cf4c096be 100644 --- a/app/main/dao/services_dao.py +++ b/app/main/dao/services_dao.py @@ -1,9 +1,5 @@ from flask import url_for -from datetime import datetime -from client.errors import HTTPError, InvalidResponse -from sqlalchemy.orm import load_only -from flask.ext.login import current_user -from app import (db, notifications_api_client) +from app import notifications_api_client from app.main.utils import BrowsableItem diff --git a/app/main/dao/templates_dao.py b/app/main/dao/templates_dao.py new file mode 100644 index 000000000..461af615c --- /dev/null +++ b/app/main/dao/templates_dao.py @@ -0,0 +1,49 @@ +from flask import url_for +from app import notifications_api_client +from app.main.utils import BrowsableItem + + +def insert_service_template(name, type_, content, service_id): + return notifications_api_client.create_service_template( + name, type_, content, service_id) + + +def update_service_template(id_, name, type_, content, service_id): + return notifications_api_client.update_service_template( + id_, name, type_, content, service_id) + + +def get_service_templates(service_id): + return notifications_api_client.get_service_templates(service_id) + + +def get_service_template(service_id, template_id): + return notifications_api_client.get_service_template( + service_id, template_id) + + +def delete_service_template(service_id, template_id): + return notifications_api_client.delete_service_template( + service_id, template_id) + + +class TemplatesBrowsableItem(BrowsableItem): + + @property + def title(self): + return self._item['name'] + + @property + def link(self): + return url_for( + 'main.edit_service_template', + service_id=self._item['service'], + template_id=self._item['id']) + + @property + def destructive(self): + return False + + @property + def hint(self): + return "Some service template hint here" diff --git a/app/main/forms.py b/app/main/forms.py index 11b201402..df9515a5c 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -6,7 +6,8 @@ from wtforms import ( PasswordField, ValidationError, TextAreaField, - FileField + FileField, + SelectField ) from wtforms.validators import DataRequired, Email, Length, Regexp @@ -187,8 +188,13 @@ class ConfirmPasswordForm(Form): class TemplateForm(Form): - template_name = StringField(u'Template name') - template_body = TextAreaField(u'Message') + name = StringField( + u'Template name', + validators=[DataRequired(message="Template name cannot be empty")]) + template_type = SelectField(u'Template type', choices=[('sms', 'SMS')]) + content = TextAreaField( + u'Message', + validators=[DataRequired(message="Template content cannot be empty")]) class ForgotPasswordForm(Form): diff --git a/app/main/views/dashboard.py b/app/main/views/dashboard.py index 1c8842d4a..419e2cca5 100644 --- a/app/main/views/dashboard.py +++ b/app/main/views/dashboard.py @@ -19,6 +19,6 @@ def service_dashboard(service_id): return render_template( 'views/service_dashboard.html', jobs=jobs, - free_text_messages_remaining=560, + free_text_messages_remaining='25,000', spent_this_month='0.00', service_id=service_id) diff --git a/app/main/views/jobs.py b/app/main/views/jobs.py index c548cb44c..ae653d405 100644 --- a/app/main/views/jobs.py +++ b/app/main/views/jobs.py @@ -50,7 +50,7 @@ messages = [ def view_jobs(service_id): return render_template( 'views/jobs.html', - jobs=jobs, + jobs=[], # use `jobs` for placeholder data service_id=service_id ) diff --git a/app/main/views/register.py b/app/main/views/register.py index 2ca7d8faa..7b4100cd8 100644 --- a/app/main/views/register.py +++ b/app/main/views/register.py @@ -1,12 +1,21 @@ from datetime import datetime, timedelta -from flask import render_template, redirect, session +from flask import ( + render_template, + redirect, + session, + current_app, + abort +) + +from client.errors import HTTPError from app.main import main +from app.models import User from app.main.dao import users_dao from app.main.forms import RegisterUserForm -from app.models import User +from app.notify_client.user_api_client import UserApiClient # TODO how do we handle duplicate unverifed email addresses? # malicious or otherwise. @@ -18,6 +27,8 @@ def register(): form = RegisterUserForm(users_dao.get_user_by_email) if form.validate_on_submit(): + + # TODO remove once all api integrations done user = User(name=form.name.data, email_address=form.email_address.data, mobile_number=form.mobile_number.data, @@ -25,6 +36,21 @@ def register(): created_at=datetime.now(), role_id=1) users_dao.insert_user(user) + + user_api_client = UserApiClient(current_app.config['API_HOST_NAME'], + current_app.config['ADMIN_CLIENT_USER_NAME'], + current_app.config['ADMIN_CLIENT_SECRET']) + try: + user_api_client.register_user(form.name.data, + form.email_address.data, + form.mobile_number.data, + form.password.data) + except HTTPError as e: + if e.status_code == 404: + abort(404) + else: + raise e + # TODO possibly there should be some exception handling # for sending sms and email codes. # How do we report to the user there is a problem with diff --git a/app/main/views/templates.py b/app/main/views/templates.py index fdba437fe..f075601e9 100644 --- a/app/main/views/templates.py +++ b/app/main/views/templates.py @@ -3,80 +3,99 @@ from flask_login import login_required from app.main import main from app.main.forms import TemplateForm - -from ._templates import templates +from app.main.dao.services_dao import get_service_by_id +from app.main.dao import templates_dao as dao +from client.errors import HTTPError @main.route("/services//templates") @login_required -def manage_templates(service_id): +def manage_service_templates(service_id): + try: + templates = dao.get_service_templates(service_id)['data'] + except HTTPError as e: + if e.status_code == 404: + abort(404) + else: + raise e return render_template( 'views/manage-templates.html', service_id=service_id, - templates=templates, - ) + templates=templates) @main.route("/services//templates/add", methods=['GET', 'POST']) @login_required -def add_template(service_id): +def add_service_template(service_id): + try: + service = dao.get_service_by_id(service_id)['data'] + except HTTPError as e: + if e.status_code == 404: + abort(404) + else: + raise e form = TemplateForm() - if request.method == 'GET': - return render_template( - 'views/edit-template.html', - h1='Add template', - form=form, - service_id=service_id - ) - elif request.method == 'POST': - return redirect(url_for('.manage_templates', service_id=service_id)) + if form.validate_on_submit(): + dao.insert_service_template( + form.name.data, form.template_type.data, form.content.data, service_id) + return redirect(url_for( + '.manage_service_templates', service_id=service_id)) + return render_template( + 'views/edit-template.html', + h1='Add template', + form=form, + service_id=service_id) @main.route("/services//templates/", methods=['GET', 'POST']) @login_required -def edit_template(service_id, template_id): +def edit_service_template(service_id, template_id): + try: + template = dao.get_service_template(service_id, template_id)['data'] + except HTTPError as e: + if e.status_code == 404: + abort(404) + else: + raise e + form = TemplateForm(form_data=template) - form = TemplateForm() + if form.validate_on_submit(): + dao.update_service_template( + template_id, form.name.data, form.template_type.data, + form.content.data, service_id) + return redirect(url_for('.manage_service_templates', service_id=service_id)) - form.template_name.data = templates[template_id - 1]['name'] - form.template_body.data = templates[template_id - 1]['body'] - - if request.method == 'GET': - return render_template( - 'views/edit-template.html', - h1='Edit template', - form=form, - service_id=service_id, - template_id=template_id - ) - elif request.method == 'POST': - return redirect(url_for('.manage_templates', service_id=service_id)) + return render_template( + 'views/edit-template.html', + h1='Edit template', + form=form, + service_id=service_id, + template_id=template_id) @main.route("/services//templates//delete", methods=['GET', 'POST']) @login_required -def delete_template(service_id, template_id): - - form = TemplateForm() - - form.template_name.data = templates[template_id - 1]['name'] - form.template_body.data = templates[template_id - 1]['body'] - - if request.method == 'GET': - - flash('Are you sure you want to delete ‘{}’?'.format(form.template_name.data), 'delete') - - return render_template( - 'views/edit-template.html', - h1='Edit template', - form=form, - service_id=service_id, - template_id=template_id - ) - elif request.method == 'POST': - if request.form.get('delete'): - return redirect(url_for('.manage_templates', service_id=service_id)) +def delete_service_template(service_id, template_id): + try: + template = dao.get_service_template(service_id, template_id)['data'] + except HTTPError as e: + if e.status_code == 404: + abort(404) else: - return redirect(url_for('.manage_templates', service_id=service_id)) + raise e + + form = TemplateForm(form_data=template) + + if form.validate_on_submit(): + dao.delete_service_template(service_id, template_id) + return redirect(url_for('.manage_service_templates', service_id=service_id)) + + flash('Are you sure you want to delete ‘{}’?'.format(form.name.data), 'delete') + return render_template( + 'views/edit-template.html', + h1='Edit template', + form=form, + service_id=service_id, + template_id=template_id) diff --git a/app/notify_client/api_client.py b/app/notify_client/api_client.py index 50217721b..0c49bd806 100644 --- a/app/notify_client/api_client.py +++ b/app/notify_client/api_client.py @@ -12,7 +12,7 @@ class NotificationsAdminAPIClient(NotificationsAPIClient): "secret") def init_app(self, application): - self.base_url = application.config['NOTIFY_API_URL'] + self.base_url = application.config['API_HOST_NAME'] self.client_id = application.config['NOTIFY_API_CLIENT'] self.secret = application.config['NOTIFY_API_SECRET'] @@ -83,6 +83,20 @@ class NotificationsAdminAPIClient(NotificationsAPIClient): endpoint = "/service/{0}/template".format(service_id) return self.post(endpoint, data) + def update_service_template(self, id_, name, type_, content, service_id): + """ + Update a service template. + """ + data = { + 'id': id_, + 'name': name, + 'template_type': type_, + 'content': content, + 'service': service_id + } + endpoint = "/service/{0}/template/{1}".format(service_id, id_) + return self.put(endpoint, data) + def get_service_template(self, service_id, template_id, *params): """ Retrieve a service template. diff --git a/app/notify_client/user_api_client.py b/app/notify_client/user_api_client.py new file mode 100644 index 000000000..bc6a70096 --- /dev/null +++ b/app/notify_client/user_api_client.py @@ -0,0 +1,18 @@ +from client.notifications import BaseAPIClient + + +class UserApiClient(BaseAPIClient): + + def __init__(self, base_url, client_id, secret): + super(self.__class__, self).__init__(base_url=base_url, + client_id=client_id, + secret=secret) + + def register_user(self, name, email_address, mobile_number, password): + data = { + "name": name, + "email_address": email_address, + "mobile_number": mobile_number, + "password": password} + + return self.post("/user", data) diff --git a/app/templates/components/table.html b/app/templates/components/table.html index bfa53232d..fb41a6aa7 100644 --- a/app/templates/components/table.html +++ b/app/templates/components/table.html @@ -23,20 +23,21 @@ {%- endmacro %} {% macro list_table(items, caption='', empty_message='', field_headings=[], field_headings_visible=True, caption_visible=True) -%} - {% if items %} - {% set parent_caller = caller %} - {% call mapping_table(caption, field_headings, field_headings_visible, caption_visible) %} - {% for item in items %} - {% call row() %} - {{ parent_caller(item) }} - {% endcall %} - {% endfor %} - {%- endcall %} - {% else %} -

+ + {% set parent_caller = caller %} + {% call mapping_table(caption, field_headings, field_headings_visible, caption_visible) %} + {% for item in items %} + {% call row() %} + {{ parent_caller(item) }} + {% endcall %} + {% endfor %} + {%- endcall %} + {% if not items %} +

{{ empty_message }}

{% endif %} + {%- endmacro %} {% macro row() -%} diff --git a/app/templates/main_nav.html b/app/templates/main_nav.html index d4000984b..65cc28c57 100644 --- a/app/templates/main_nav.html +++ b/app/templates/main_nav.html @@ -6,7 +6,7 @@
  • Send text messages
  • Send emails
  • Activity
  • -
  • Templates
  • +
  • Templates
    • API keys and documentation
    • diff --git a/app/templates/views/edit-template.html b/app/templates/views/edit-template.html index 20cc74482..07155a454 100644 --- a/app/templates/views/edit-template.html +++ b/app/templates/views/edit-template.html @@ -11,12 +11,12 @@ GOV.UK Notify | Edit template

      {{ h1 }}

      - {{ textbox(form.template_name) }} - {{ textbox(form.template_body, highlight_tags=True) }} + {{ textbox(form.name) }} + {{ textbox(form.content, highlight_tags=True) }} {{ page_footer( 'Save', - delete_link=url_for('.delete_template', service_id=service_id, template_id=template_id) if template_id or None, - back_link=url_for('.manage_templates', service_id=service_id), + delete_link=url_for('.delete_service_template', service_id=service_id, template_id=template_id) if template_id or None, + back_link=url_for('.manage_service_templates', service_id=service_id), back_link_text='Back to templates' ) }}
      diff --git a/app/templates/views/job.html b/app/templates/views/job.html index b5970e947..01916ea24 100644 --- a/app/templates/views/job.html +++ b/app/templates/views/job.html @@ -38,7 +38,7 @@ GOV.UK Notify | Notifications activity

    - Sent with template {{ template_used }} at {{ uploaded_file_time }} + Sent with template {{ template_used }} at {{ uploaded_file_time }}

    {% call(item) list_table( diff --git a/app/templates/views/jobs.html b/app/templates/views/jobs.html index 0879fee7a..6d321c433 100644 --- a/app/templates/views/jobs.html +++ b/app/templates/views/jobs.html @@ -13,6 +13,7 @@ GOV.UK Notify | Notifications activity jobs, caption="Recent activity", caption_visible=False, + empty_message='You haven’t sent any notifications yet', field_headings=['Job', 'File', 'Time', 'Status'] ) %} {% call field() %} diff --git a/app/templates/views/manage-templates.html b/app/templates/views/manage-templates.html index dbdbed51f..50e541959 100644 --- a/app/templates/views/manage-templates.html +++ b/app/templates/views/manage-templates.html @@ -15,21 +15,21 @@ GOV.UK Notify | Manage templates

    Templates

    - Create new template + Create new template {% for template in templates %} {% if template.type == 'sms' %} {{ sms_message( - template.body, + template.content, name=template.name, - edit_link=url_for('.edit_template', service_id=service_id, template_id=loop.index) + edit_link=url_for('.edit_service_template', service_id=template.service, template_id=template.id) ) }} {% elif template.type == 'email' %} {{ email_message( - template.subject, - template.body, + "template subject", + template.content, name=template.name, - edit_link=url_for('.edit_template', service_id=service_id, template_id=loop.index) + edit_link=url_for('.edit_service_template', service_id=template.service, template_id=template.id) ) }} {% endif %} {% endfor %} diff --git a/app/templates/views/send-sms.html b/app/templates/views/send-sms.html index ebfa317cc..338497756 100644 --- a/app/templates/views/send-sms.html +++ b/app/templates/views/send-sms.html @@ -23,7 +23,7 @@

    - or create a new template + or create a new template

    2. Add recipients

    diff --git a/app/templates/views/service_dashboard.html b/app/templates/views/service_dashboard.html index 9e5510795..9ed330140 100644 --- a/app/templates/views/service_dashboard.html +++ b/app/templates/views/service_dashboard.html @@ -24,9 +24,9 @@ {% call(item) list_table( - jobs[:3], + [], caption="Recent text messages", - empty_message="No recent text messages", + empty_message='You haven’t sent any text messages yet', field_headings=['Job', 'File', 'Time', 'Status'] ) %} {% call field() %} @@ -42,9 +42,5 @@ {{ item.status }} {% endcall %} {% endcall %} -

    - See all notifications activity -

    - {% endblock %} diff --git a/app/templates/views/styleguide.html b/app/templates/views/styleguide.html index 2231b1173..40669cbbf 100644 --- a/app/templates/views/styleguide.html +++ b/app/templates/views/styleguide.html @@ -148,6 +148,21 @@ {% endcall %} {% endcall %} + {% call(item) list_table( + [], + caption='Jobs', + field_headings=['Job', 'Time'], + caption_visible=True, + empty_message='You haven’t scheduled any jobs yet' + ) %} + {% call field() %} + {{ item.job }} + {% endcall %} + {% call field() %} + {{ item.time }} + {% endcall %} + {% endcall %} +

    Textbox

    {{ textbox(form.username) }} {{ textbox(form.password) }} diff --git a/config.py b/config.py index 9f98b37aa..eb417cd7e 100644 --- a/config.py +++ b/config.py @@ -22,10 +22,13 @@ class Config(object): SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SECURE = True - NOTIFY_API_URL = os.getenv('NOTIFY_API_URL', "http://localhost:6001") + API_HOST_NAME = os.getenv('API_HOST_NAME') NOTIFY_API_SECRET = os.getenv('NOTIFY_API_SECRET', "dev-secret") NOTIFY_API_CLIENT = os.getenv('NOTIFY_API_CLIENT', "admin") + ADMIN_CLIENT_USER_NAME = os.getenv('ADMIN_CLIENT_USER_NAME') + ADMIN_CLIENT_SECRET = os.getenv('ADMIN_CLIENT_SECRET') + WTF_CSRF_ENABLED = True SECRET_KEY = 'secret-key' HTTP_PROTOCOL = 'http' @@ -38,10 +41,12 @@ class Config(object): class Development(Config): DEBUG = True + API_HOST_NAME = 'http://localhost:6011' + ADMIN_CLIENT_USER_NAME = 'dev-notify-admin' + ADMIN_CLIENT_SECRET = 'dev-notify-secret-key' -class Test(Config): - DEBUG = True +class Test(Development): SQLALCHEMY_DATABASE_URI = 'postgresql://localhost/test_notifications_admin' WTF_CSRF_ENABLED = False diff --git a/tests/__init__.py b/tests/__init__.py index 4bd8718e9..339886b10 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -29,6 +29,16 @@ def service_json(id_, name, users, limit=1000, active=False, restricted=True): } +def template_json(id_, name, type_, content, service_id): + return { + 'id': id_, + 'name': name, + 'template_type': type_, + 'content': content, + 'service': service_id + } + + TEST_USER_EMAIL = 'test@user.gov.uk' diff --git a/tests/app/main/views/test_dashboard.py b/tests/app/main/views/test_dashboard.py index e0d163f99..4af4b63ac 100644 --- a/tests/app/main/views/test_dashboard.py +++ b/tests/app/main/views/test_dashboard.py @@ -13,5 +13,4 @@ def test_should_show_recent_jobs_on_dashboard(app_, response = client.get(url_for('main.service_dashboard', service_id=123)) assert response.status_code == 200 - assert 'Test message 1' in response.get_data(as_text=True) - assert 'Asdfgg' in response.get_data(as_text=True) + assert 'You haven’t sent any text messages yet' in response.get_data(as_text=True) diff --git a/tests/app/main/views/test_jobs.py b/tests/app/main/views/test_jobs.py index 039d47dbf..aa900dd8b 100644 --- a/tests/app/main/views/test_jobs.py +++ b/tests/app/main/views/test_jobs.py @@ -11,8 +11,7 @@ def test_should_return_list_of_all_jobs(app_, db_, db_session, service_one): response = client.get(url_for('main.view_jobs', service_id=101)) assert response.status_code == 200 - assert 'Test message 1' in response.get_data(as_text=True) - assert 'Final reminder' in response.get_data(as_text=True) + assert 'You haven’t sent any notifications yet' in response.get_data(as_text=True) def test_should_show_page_for_one_job(app_, db_, db_session, service_one): diff --git a/tests/app/main/views/test_register.py b/tests/app/main/views/test_register.py index e23362fcf..2a3c78536 100644 --- a/tests/app/main/views/test_register.py +++ b/tests/app/main/views/test_register.py @@ -1,5 +1,7 @@ from flask import url_for +from tests.conftest import mock_register_user + def test_render_register_returns_template_with_form(app_, db_, db_session): response = app_.test_client().get('/register') @@ -12,13 +14,21 @@ def test_process_register_creates_new_user(app_, db_, db_session, mock_send_sms, - mock_send_email): + mock_send_email, + mocker): + + user_data = { + 'name': 'Some One Valid', + 'email_address': 'someone@example.gov.uk', + 'mobile_number': '+4407700900460', + 'password': 'validPassword!' + } + + mock_register_user(mocker, user_data) + with app_.test_request_context(): response = app_.test_client().post('/register', - data={'name': 'Some One Valid', - 'email_address': 'someone@example.gov.uk', - 'mobile_number': '+4407700900460', - 'password': 'validPassword!'}) + data=user_data) assert response.status_code == 302 assert response.location == url_for('main.verify', _external=True) @@ -57,13 +67,19 @@ def test_should_add_verify_codes_on_session(app_, db_, db_session, mock_send_sms, - mock_send_email): + mock_send_email, + mocker): + user_data = { + 'name': 'Test Codes', + 'email_address': 'test@example.gov.uk', + 'mobile_number': '+4407700900460', + 'password': 'validPassword!' + } + + mock_register_user(mocker, user_data) with app_.test_client() as client: response = client.post('/register', - data={'name': 'Test Codes', - 'email_address': 'test_codes@example.gov.uk', - 'mobile_number': '+4407700900460', - 'password': 'validPassword!'}) + data=user_data) assert response.status_code == 302 assert 'notify_admin_session' in response.headers.get('Set-Cookie') diff --git a/tests/app/main/views/test_templates.py b/tests/app/main/views/test_templates.py index da0489c7d..d010be260 100644 --- a/tests/app/main/views/test_templates.py +++ b/tests/app/main/views/test_templates.py @@ -1,49 +1,128 @@ +import json from flask import url_for -def test_should_return_list_of_all_templates(app_, db_, db_session, active_user): +def test_should_return_list_of_all_templates(app_, + db_, + db_session, + active_user, + mock_get_service_templates): with app_.test_request_context(): with app_.test_client() as client: client.login(active_user) - response = client.get(url_for('.manage_templates', service_id=123)) + service_id = 123 + response = client.get(url_for( + '.manage_service_templates', service_id=service_id)) assert response.status_code == 200 + mock_get_service_templates.assert_called_with(service_id) -def test_should_show_page_for_one_templates(app_, db_, db_session, active_user): +def test_should_show_page_for_one_templates(app_, + db_, + db_session, + active_user, + mock_get_service_template): with app_.test_request_context(): with app_.test_client() as client: client.login(active_user) - response = client.get(url_for('.edit_template', service_id=123, template_id=1)) + service_id = 123 + template_id = 456 + response = client.get(url_for( + '.edit_service_template', + service_id=service_id, + template_id=template_id)) assert response.status_code == 200 + mock_get_service_template.assert_called_with( + service_id, template_id) -def test_should_redirect_when_saving_a_template(app_, db_, db_session, active_user): +def test_should_redirect_when_saving_a_template(app_, + db_, + db_session, + active_user, + mock_get_service_template, + mock_update_service_template): with app_.test_request_context(): with app_.test_client() as client: client.login(active_user) - response = client.post(url_for('.edit_template', service_id=123, template_id=1)) + service_id = 123 + template_id = 456 + name = "new name" + type_ = "sms" + content = "template content" + data = { + 'id': template_id, + 'name': name, + 'template_type': type_, + "content": content, + "service": service_id + } + response = client.post(url_for( + '.edit_service_template', + service_id=service_id, + template_id=template_id), data=data) assert response.status_code == 302 - assert response.location == url_for('.manage_templates', service_id=123, _external=True) + assert response.location == url_for( + '.manage_service_templates', service_id=service_id, _external=True) + mock_update_service_template.assert_called_with( + template_id, name, type_, content, service_id) -def test_should_show_delete_template_page(app_, db_, db_session, active_user): +def test_should_show_delete_template_page(app_, + db_, + db_session, + active_user, + mock_get_service_template): with app_.test_request_context(): with app_.test_client() as client: client.login(active_user) - response = client.get(url_for('.delete_template', service_id=123, template_id=1)) + service_id = 123 + template_id = 456 + response = client.get(url_for( + '.delete_service_template', + service_id=service_id, + template_id=template_id)) assert response.status_code == 200 assert 'Are you sure' in response.get_data(as_text=True) + mock_get_service_template.assert_called_with( + service_id, template_id) -def test_should_redirect_when_deleting_a_template(app_, db_, db_session, active_user): +def test_should_redirect_when_deleting_a_template(app_, + db_, + db_session, + active_user, + mock_get_service_template, + mock_delete_service_template): with app_.test_request_context(): with app_.test_client() as client: client.login(active_user) - response = client.post(url_for('.delete_template', service_id=123, template_id=1)) + service_id = 123 + template_id = 456 + name = "new name" + type_ = "sms" + content = "template content" + data = { + 'id': template_id, + 'name': name, + 'template_type': type_, + 'content': content, + 'service': service_id + } + response = client.post(url_for( + '.delete_service_template', + service_id=service_id, + template_id=template_id), data=data) assert response.status_code == 302 - assert response.location == url_for('.manage_templates', service_id=123, _external=True) + assert response.location == url_for( + '.manage_service_templates', + service_id=service_id, _external=True) + mock_get_service_template.assert_called_with( + service_id, template_id) + mock_delete_service_template.assert_called_with( + service_id, template_id) diff --git a/tests/conftest.py b/tests/conftest.py index 7776cd767..599b5670b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,7 +7,7 @@ from flask.ext.script import Manager from sqlalchemy.schema import MetaData from . import ( create_test_user, create_another_test_user, service_json, TestClient, - get_test_user) + get_test_user, template_json) from app import create_app, db @@ -94,12 +94,11 @@ def mock_get_service(mocker, active_user): @pytest.fixture(scope='function') def mock_create_service(mocker): - # TODO fix token generation def _create(service_name, active, limit, restricted, user_id): service = service_json( 101, service_name, [user_id], limit=limit, active=active, restricted=restricted) - return {'data': service, 'token': 1} + return {'data': service} mock_class = mocker.patch( 'app.notifications_api_client.create_service', side_effect=_create) return mock_class @@ -142,3 +141,76 @@ def mock_delete_service(mocker, mock_get_service): mock_class = mocker.patch( 'app.notifications_api_client.delete_service', side_effect=_delete) return mock_class + + +@pytest.fixture(scope='function') +def mock_get_service_template(mocker): + def _create(service_id, template_id): + template = template_json( + template_id, "Template Name", "sms", "template content", service_id) + return {'data': template} + return mocker.patch( + 'app.notifications_api_client.get_service_template', + side_effect=_create) + + +@pytest.fixture(scope='function') +def mock_create_service_template(mocker): + def _create(name, type_, content, service): + template = template_json( + 101, name, type_, content, service) + return {'data': template} + mock_class = mocker.patch( + 'app.notifications_api_client.create_service_template', + side_effect=_create) + return mock_class + + +@pytest.fixture(scope='function') +def mock_update_service_template(mocker): + def _update(id_, name, type_, content, service): + template = template_json( + id_, name, type_, content, service) + return {'data': template} + mock_class = mocker.patch( + 'app.notifications_api_client.update_service_template', + side_effect=_update) + return mock_class + + +@pytest.fixture(scope='function') +def mock_get_service_templates(mocker): + def _create(service_id): + template_one = template_json( + 1, "template_one", "sms", "template one content", service_id) + template_two = template_json( + 2, "template_two", "sms", "template two content", service_id) + return {'data': [template_one, template_two]} + mock_class = mocker.patch( + 'app.notifications_api_client.get_service_templates', + side_effect=_create) + return mock_class + + +@pytest.fixture(scope='function') +def mock_delete_service_template(mocker): + def _delete(service_id, template_id): + template = template_json( + template_id, "Template to delete", + "sms", "content to be deleted", service_id) + return {'data': template} + return mocker.patch( + 'app.notifications_api_client.delete_service_template', side_effect=_delete) + + +def mock_register_user(mocker, user_data): + data = { + "email_address": user_data['email_address'], + "failed_login_count": 0, + "mobile_number": user_data['mobile_number'], + "name": user_data['name'], + "state": "pending" + } + mock_class = mocker.patch('app.main.views.register.UserApiClient') + mock_class.register_user.return_value = data + return mock_class