mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-11 10:28:41 -04:00
Merge with master again.
This commit is contained in:
+20
-3
@@ -3,7 +3,24 @@ from flask import Blueprint
|
|||||||
main = Blueprint('main', __name__)
|
main = Blueprint('main', __name__)
|
||||||
|
|
||||||
from app.main.views import (
|
from app.main.views import (
|
||||||
index, sign_in, sign_out, register, two_factor, verify, send, add_service,
|
index,
|
||||||
code_not_received, jobs, dashboard, templates, service_settings, forgot_password,
|
sign_in,
|
||||||
new_password, styleguide, user_profile, choose_service, api_keys, manage_users
|
sign_out,
|
||||||
|
register,
|
||||||
|
two_factor,
|
||||||
|
verify,
|
||||||
|
send,
|
||||||
|
add_service,
|
||||||
|
code_not_received,
|
||||||
|
jobs, dashboard,
|
||||||
|
templates,
|
||||||
|
service_settings,
|
||||||
|
forgot_password,
|
||||||
|
new_password,
|
||||||
|
styleguide,
|
||||||
|
user_profile,
|
||||||
|
choose_service,
|
||||||
|
api_keys,
|
||||||
|
manage_users,
|
||||||
|
invites
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
from flask import (
|
||||||
|
redirect,
|
||||||
|
url_for,
|
||||||
|
abort
|
||||||
|
)
|
||||||
|
|
||||||
|
from notifications_python_client.errors import HTTPError
|
||||||
|
|
||||||
|
from app.main import main
|
||||||
|
from app import (
|
||||||
|
invite_api_client,
|
||||||
|
user_api_client
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@main.route("/invitation/<token>")
|
||||||
|
def accept_invite(token):
|
||||||
|
try:
|
||||||
|
invited_user = invite_api_client.accept_invite(token)
|
||||||
|
existing_user = user_api_client.get_user_by_email(invited_user.email_address)
|
||||||
|
|
||||||
|
if existing_user:
|
||||||
|
user_api_client.add_user_to_service(invited_user.service,
|
||||||
|
existing_user.id)
|
||||||
|
|
||||||
|
return redirect(url_for('main.service_dashboard', service_id=invited_user.service))
|
||||||
|
else:
|
||||||
|
# TODO implement registration flow for new users
|
||||||
|
abort(404)
|
||||||
|
except HTTPError as e:
|
||||||
|
if e.status_code == 404:
|
||||||
|
abort(404)
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
@@ -58,8 +58,8 @@ def invite_user(service_id):
|
|||||||
email_address = form.email_address.data
|
email_address = form.email_address.data
|
||||||
permissions = _get_permissions(request.form)
|
permissions = _get_permissions(request.form)
|
||||||
try:
|
try:
|
||||||
resp = invite_api_client.create_invite(current_user.id, service_id, email_address, permissions)
|
invited_user = invite_api_client.create_invite(current_user.id, service_id, email_address, permissions)
|
||||||
flash('Invite sent to {}'.format(resp['email_address']), 'default_with_tick')
|
flash('Invite sent to {}'.format(invited_user.email_address), 'default_with_tick')
|
||||||
return redirect(url_for('.manage_users', service_id=service_id))
|
return redirect(url_for('.manage_users', service_id=service_id))
|
||||||
|
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
|
|||||||
+27
-15
@@ -28,6 +28,7 @@ from app.main.dao import services_dao
|
|||||||
from app import job_api_client
|
from app import job_api_client
|
||||||
from app.utils import (
|
from app.utils import (
|
||||||
validate_recipient, InvalidPhoneError, InvalidEmailError, user_has_permissions)
|
validate_recipient, InvalidPhoneError, InvalidEmailError, user_has_permissions)
|
||||||
|
from utils.process_csv import first_column_heading
|
||||||
|
|
||||||
|
|
||||||
manage_service_page_headings = {
|
manage_service_page_headings = {
|
||||||
@@ -115,11 +116,12 @@ def send_messages(service_id, template_id):
|
|||||||
templates_dao.get_service_template_or_404(service_id, template_id)['data'],
|
templates_dao.get_service_template_or_404(service_id, template_id)['data'],
|
||||||
prefix=service['name']
|
prefix=service['name']
|
||||||
)
|
)
|
||||||
|
recipient_column = first_column_heading[template.template_type]
|
||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'views/send.html',
|
'views/send.html',
|
||||||
template=template,
|
template=template,
|
||||||
column_headers=['to'] + template.placeholders_as_markup,
|
recipient_column=first_column_heading[template.template_type],
|
||||||
form=form,
|
form=form,
|
||||||
service=service,
|
service=service,
|
||||||
service_id=service_id
|
service_id=service_id
|
||||||
@@ -130,17 +132,19 @@ def send_messages(service_id, template_id):
|
|||||||
@login_required
|
@login_required
|
||||||
@user_has_permissions('send_messages', 'manage_templates', or_=True)
|
@user_has_permissions('send_messages', 'manage_templates', or_=True)
|
||||||
def get_example_csv(service_id, template_id):
|
def get_example_csv(service_id, template_id):
|
||||||
template = templates_dao.get_service_template_or_404(service_id, template_id)['data']
|
template = Template(templates_dao.get_service_template_or_404(service_id, template_id)['data'])
|
||||||
placeholders = list(Template(template).placeholders)
|
|
||||||
output = io.StringIO()
|
output = io.StringIO()
|
||||||
writer = csv.writer(output)
|
writer = csv.writer(output)
|
||||||
writer.writerow(['to'] + placeholders)
|
writer.writerow(
|
||||||
|
[first_column_heading[template.template_type]] +
|
||||||
|
list(template.placeholders)
|
||||||
|
)
|
||||||
writer.writerow([
|
writer.writerow([
|
||||||
{
|
{
|
||||||
'email': current_user.email_address,
|
'email': current_user.email_address,
|
||||||
'sms': current_user.mobile_number
|
'sms': current_user.mobile_number
|
||||||
}[template['template_type']]
|
}[template.template_type]
|
||||||
] + ["test {}".format(header) for header in placeholders])
|
] + ["test {}".format(header) for header in template.placeholders])
|
||||||
return output.getvalue(), 200, {'Content-Type': 'text/csv; charset=utf-8'}
|
return output.getvalue(), 200, {'Content-Type': 'text/csv; charset=utf-8'}
|
||||||
|
|
||||||
|
|
||||||
@@ -148,12 +152,17 @@ def get_example_csv(service_id, template_id):
|
|||||||
@login_required
|
@login_required
|
||||||
@user_has_permissions('send_messages')
|
@user_has_permissions('send_messages')
|
||||||
def send_message_to_self(service_id, template_id):
|
def send_message_to_self(service_id, template_id):
|
||||||
template = templates_dao.get_service_template_or_404(service_id, template_id)['data']
|
template = Template(templates_dao.get_service_template_or_404(service_id, template_id)['data'])
|
||||||
placeholders = list(Template(template).placeholders)
|
|
||||||
output = io.StringIO()
|
output = io.StringIO()
|
||||||
writer = csv.writer(output)
|
writer = csv.writer(output)
|
||||||
writer.writerow(['to'] + placeholders)
|
writer.writerow(
|
||||||
writer.writerow([current_user.mobile_number] + ["test {}".format(header) for header in placeholders])
|
[first_column_heading[template.template_type]] +
|
||||||
|
list(template.placeholders)
|
||||||
|
)
|
||||||
|
writer.writerow(
|
||||||
|
[current_user.mobile_number] +
|
||||||
|
["test {}".format(header) for header in template.placeholders]
|
||||||
|
)
|
||||||
filedata = {
|
filedata = {
|
||||||
'file_name': 'Test run',
|
'file_name': 'Test run',
|
||||||
'data': output.getvalue().splitlines()
|
'data': output.getvalue().splitlines()
|
||||||
@@ -187,7 +196,7 @@ def check_messages(service_id, upload_id):
|
|||||||
template = Template(
|
template = Template(
|
||||||
raw_template,
|
raw_template,
|
||||||
values=upload_result['rows'][0] if upload_result['valid'] else {},
|
values=upload_result['rows'][0] if upload_result['valid'] else {},
|
||||||
drop_values={'to'},
|
drop_values={first_column_heading[raw_template['template_type']]},
|
||||||
prefix=service['name']
|
prefix=service['name']
|
||||||
)
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
@@ -195,7 +204,7 @@ def check_messages(service_id, upload_id):
|
|||||||
upload_result=upload_result,
|
upload_result=upload_result,
|
||||||
template=template,
|
template=template,
|
||||||
page_heading=get_page_headings(template.template_type),
|
page_heading=get_page_headings(template.template_type),
|
||||||
column_headers=['to'] + list(template.placeholders_as_markup),
|
column_headers=[first_column_heading[template.template_type]] + list(template.placeholders_as_markup),
|
||||||
original_file_name=upload_data.get('original_file_name'),
|
original_file_name=upload_data.get('original_file_name'),
|
||||||
service_id=service_id,
|
service_id=service_id,
|
||||||
service=service,
|
service=service,
|
||||||
@@ -257,10 +266,13 @@ def _get_rows(contents, raw_template):
|
|||||||
rows.append(row)
|
rows.append(row)
|
||||||
try:
|
try:
|
||||||
validate_recipient(
|
validate_recipient(
|
||||||
row.get('to', ''),
|
row, template_type=raw_template['template_type']
|
||||||
template_type=raw_template['template_type']
|
|
||||||
)
|
)
|
||||||
Template(raw_template, values=row, drop_values={'to'}).replaced
|
Template(
|
||||||
|
raw_template,
|
||||||
|
values=row,
|
||||||
|
drop_values={first_column_heading[raw_template['template_type']]}
|
||||||
|
).replaced
|
||||||
except (InvalidEmailError, InvalidPhoneError, NeededByTemplateError, NoPlaceholderForDataError):
|
except (InvalidEmailError, InvalidPhoneError, NeededByTemplateError, NoPlaceholderForDataError):
|
||||||
valid = False
|
valid = False
|
||||||
return {"valid": valid, "rows": rows}
|
return {"valid": valid, "rows": rows}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
from notifications_python_client.base import BaseAPIClient
|
from notifications_python_client.base import BaseAPIClient
|
||||||
from app.notify_client.models import User
|
from app.notify_client.models import InvitedUser
|
||||||
|
|
||||||
|
|
||||||
class InviteApiClient(BaseAPIClient):
|
class InviteApiClient(BaseAPIClient):
|
||||||
@@ -22,9 +21,23 @@ class InviteApiClient(BaseAPIClient):
|
|||||||
'permissions': permissions
|
'permissions': permissions
|
||||||
}
|
}
|
||||||
resp = self.post(url='/service/{}/invite'.format(service_id), data=data)
|
resp = self.post(url='/service/{}/invite'.format(service_id), data=data)
|
||||||
return resp['data']
|
return InvitedUser(**resp['data'])
|
||||||
|
|
||||||
def get_invites_for_service(self, service_id):
|
def get_invites_for_service(self, service_id):
|
||||||
endpoint = '/service/{}/invite'.format(service_id)
|
endpoint = '/service/{}/invite'.format(service_id)
|
||||||
resp = self.get(endpoint)
|
resp = self.get(endpoint)
|
||||||
return [User(data) for data in resp['data']]
|
invites = resp['data']
|
||||||
|
invited_users = _get_invited_users(invites)
|
||||||
|
return invited_users
|
||||||
|
|
||||||
|
def accept_invite(self, token):
|
||||||
|
resp = self.get(url='/invite/{}'.format(token))
|
||||||
|
return InvitedUser(**resp['data'])
|
||||||
|
|
||||||
|
|
||||||
|
def _get_invited_users(invites):
|
||||||
|
invited_users = []
|
||||||
|
for invite in invites:
|
||||||
|
invited_user = InvitedUser(**invite)
|
||||||
|
invited_users.append(invited_user)
|
||||||
|
return invited_users
|
||||||
|
|||||||
@@ -114,3 +114,18 @@ class User(UserMixin):
|
|||||||
|
|
||||||
def set_password(self, pwd):
|
def set_password(self, pwd):
|
||||||
self._password = pwd
|
self._password = pwd
|
||||||
|
|
||||||
|
|
||||||
|
class InvitedUser(object):
|
||||||
|
|
||||||
|
def __init__(self, id, service, from_user, email_address, permissions, status, created_at):
|
||||||
|
self.id = id
|
||||||
|
self.service = str(service)
|
||||||
|
self.from_user = from_user
|
||||||
|
self.email_address = email_address
|
||||||
|
self.permissions = permissions.split(',')
|
||||||
|
self.status = status
|
||||||
|
self.created_at = created_at
|
||||||
|
|
||||||
|
def has_permissions(self, permission):
|
||||||
|
return permission in self.permissions
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
from notifications_python_client.notifications import BaseAPIClient
|
from notifications_python_client.notifications import BaseAPIClient
|
||||||
from notifications_python_client.errors import HTTPError
|
from notifications_python_client.errors import HTTPError
|
||||||
|
|
||||||
@@ -85,3 +87,8 @@ class UserApiClient(BaseAPIClient):
|
|||||||
endpoint = '/service/{}/users'.format(service_id)
|
endpoint = '/service/{}/users'.format(service_id)
|
||||||
resp = self.get(endpoint)
|
resp = self.get(endpoint)
|
||||||
return [User(data) for data in resp['data']]
|
return [User(data) for data in resp['data']]
|
||||||
|
|
||||||
|
def add_user_to_service(self, service_id, user_id):
|
||||||
|
endpoint = '/service/{}/users/{}'.format(service_id, user_id)
|
||||||
|
resp = self.post(endpoint, data={})
|
||||||
|
return User(resp['data'], max_failed_login_count=self.max_failed_login_count)
|
||||||
|
|||||||
@@ -61,13 +61,17 @@
|
|||||||
caption=original_file_name,
|
caption=original_file_name,
|
||||||
field_headings=column_headers
|
field_headings=column_headers
|
||||||
) %}
|
) %}
|
||||||
{% if item.to or ''|valid_phone_number %}
|
{% if item.get('phone number', '')|valid_phone_number %}
|
||||||
{% call field() %}
|
{% call field() %}
|
||||||
{{ item.to }}
|
{{ item['phone number'] }}
|
||||||
|
{% endcall %}
|
||||||
|
{% elif item.get('email address') %}
|
||||||
|
{% call field() %}
|
||||||
|
{{ item['email address'] }}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% call field(status='missing') %}
|
{% call field(status='missing') %}
|
||||||
{{ item.to }}
|
{{ item['phone number'] }}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for column in template.placeholders %}
|
{% for column in template.placeholders %}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
{% from "components/big-number.html" import big_number %}
|
{% from "components/big-number.html" import big_number %}
|
||||||
{% from "components/banner.html" import banner %}
|
{% from "components/banner.html" import banner %}
|
||||||
{% from "components/sms-message.html" import sms_message %}
|
{% from "components/sms-message.html" import sms_message %}
|
||||||
|
{% from "components/email-message.html" import email_message %}
|
||||||
|
|
||||||
{% block page_title %}
|
{% block page_title %}
|
||||||
{{ uploaded_file_name }} – GOV.UK Notify
|
{{ uploaded_file_name }} – GOV.UK Notify
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ Manage users – GOV.UK Notify
|
|||||||
{% call field() %}
|
{% call field() %}
|
||||||
{{ item.email_address }}
|
{{ item.email_address }}
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
{{ boolean_field(item.has_permissions(service_id, 'send_messages')) }}
|
{{ boolean_field(item.has_permissions('send_messages')) }}
|
||||||
{{ boolean_field(item.has_permissions(service_id, 'manage_service')) }}
|
{{ boolean_field(item.has_permissions('manage_service')) }}
|
||||||
{{ boolean_field(item.has_permissions(service_id, 'api_keys')) }}
|
{{ boolean_field(item.has_permissions('manage_api_keys')) }}
|
||||||
{% call field(align='right') %}
|
{% call field(align='right') %}
|
||||||
<a href="{{ url_for('.edit_user', service_id=service_id, user_id=item.id)}}">Change</a>
|
<a href="{{ url_for('.edit_user', service_id=service_id, user_id=item.id)}}">Change</a>
|
||||||
{% endcall %}
|
{% endcall %}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
<p class="bottom-gutter-2-3">
|
<p class="bottom-gutter-2-3">
|
||||||
<span class='placeholder'>to</span>
|
<span class='placeholder'>{{ recipient_column }}</span>
|
||||||
{{ template.placeholders_as_markup|join(" ") }}
|
{{ template.placeholders_as_markup|join(" ") }}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
+4
-2
@@ -3,6 +3,8 @@ import re
|
|||||||
from functools import wraps
|
from functools import wraps
|
||||||
from flask import (abort, session)
|
from flask import (abort, session)
|
||||||
|
|
||||||
|
from utils.process_csv import get_recipient_from_row
|
||||||
|
|
||||||
|
|
||||||
class BrowsableItem(object):
|
class BrowsableItem(object):
|
||||||
"""
|
"""
|
||||||
@@ -87,11 +89,11 @@ def validate_email_address(email_address):
|
|||||||
raise InvalidEmailError('Not a valid email address')
|
raise InvalidEmailError('Not a valid email address')
|
||||||
|
|
||||||
|
|
||||||
def validate_recipient(recipient, template_type):
|
def validate_recipient(row, template_type):
|
||||||
return {
|
return {
|
||||||
'email': validate_email_address,
|
'email': validate_email_address,
|
||||||
'sms': validate_phone_number
|
'sms': validate_phone_number
|
||||||
}[template_type](recipient)
|
}[template_type](get_recipient_from_row(row, template_type))
|
||||||
|
|
||||||
|
|
||||||
def user_has_permissions(*permissions, or_=False):
|
def user_has_permissions(*permissions, or_=False):
|
||||||
|
|||||||
+1
-1
@@ -14,4 +14,4 @@ Pygments==2.0.2
|
|||||||
|
|
||||||
git+https://github.com/alphagov/notifications-python-client.git@0.3.1#egg=notifications-python-client==0.3.1
|
git+https://github.com/alphagov/notifications-python-client.git@0.3.1#egg=notifications-python-client==0.3.1
|
||||||
|
|
||||||
git+https://github.com/alphagov/notifications-utils.git@0.1.2#egg=notifications-utils==0.1.2
|
git+https://github.com/alphagov/notifications-utils.git@1.0.0#egg=notifications-utils==1.0.0
|
||||||
|
|||||||
+5
-2
@@ -48,12 +48,15 @@ def api_key_json(id_, name, expiry_date=None):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def invite_json(id, from_user, service_id, email_address):
|
def invite_json(id, from_user, service_id, email_address, permissions, created_at):
|
||||||
return {'id': id,
|
return {'id': id,
|
||||||
'from_user': from_user,
|
'from_user': from_user,
|
||||||
'service': service_id,
|
'service': service_id,
|
||||||
'email_address': email_address,
|
'email_address': email_address,
|
||||||
'status': 'pending'}
|
'status': 'pending',
|
||||||
|
'permissions': permissions,
|
||||||
|
'created_at': created_at
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_USER_EMAIL = 'test@user.gov.uk'
|
TEST_USER_EMAIL = 'test@user.gov.uk'
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
from flask import url_for
|
||||||
|
|
||||||
|
from app.notify_client.models import InvitedUser
|
||||||
|
from notifications_python_client.errors import HTTPError
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def test_existing_user_accept_invite_calls_api_and_redirects_to_dashboard(app_,
|
||||||
|
service_one,
|
||||||
|
api_user_active,
|
||||||
|
sample_invite,
|
||||||
|
mock_accept_invite,
|
||||||
|
mock_get_user_by_email,
|
||||||
|
mock_add_user_to_service):
|
||||||
|
|
||||||
|
expected_service = service_one['id']
|
||||||
|
expected_redirect_location = 'http://localhost/services/{}/dashboard'.format(expected_service)
|
||||||
|
|
||||||
|
with app_.test_request_context():
|
||||||
|
with app_.test_client() as client:
|
||||||
|
|
||||||
|
response = client.get(url_for('main.accept_invite', token='thisisnotarealtoken'))
|
||||||
|
|
||||||
|
mock_accept_invite.assert_called_with('thisisnotarealtoken')
|
||||||
|
mock_get_user_by_email.assert_called_with('invited_user@test.gov.uk')
|
||||||
|
mock_add_user_to_service.assert_called_with(expected_service, api_user_active.id)
|
||||||
|
|
||||||
|
assert response.status_code == 302
|
||||||
|
assert response.location == expected_redirect_location
|
||||||
@@ -3,22 +3,22 @@ from flask import url_for
|
|||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
|
||||||
# def test_should_show_overview_page(
|
def test_should_show_overview_page(
|
||||||
# app_,
|
app_,
|
||||||
# api_user_active,
|
api_user_active,
|
||||||
# mock_login,
|
mock_login,
|
||||||
# mock_get_service,
|
mock_get_service,
|
||||||
# mock_get_users_by_service,
|
mock_get_users_by_service,
|
||||||
# mock_get_invites_for_service
|
mock_get_invites_for_service
|
||||||
# ):
|
):
|
||||||
# with app_.test_request_context():
|
with app_.test_request_context():
|
||||||
# with app_.test_client() as client:
|
with app_.test_client() as client:
|
||||||
# client.login(api_user_active)
|
client.login(api_user_active)
|
||||||
# response = client.get(url_for('main.manage_users', service_id=55555))
|
response = client.get(url_for('main.manage_users', service_id=55555))
|
||||||
#
|
|
||||||
# assert 'Manage team' in response.get_data(as_text=True)
|
assert 'Manage team' in response.get_data(as_text=True)
|
||||||
# assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
# mock_get_users_by_service.assert_called_once_with(service_id='55555')
|
mock_get_users_by_service.assert_called_once_with(service_id='55555')
|
||||||
|
|
||||||
|
|
||||||
def test_should_show_page_for_one_user(
|
def test_should_show_page_for_one_user(
|
||||||
@@ -70,37 +70,37 @@ def test_should_show_page_for_inviting_user(
|
|||||||
assert 'Add a new team member' in response.get_data(as_text=True)
|
assert 'Add a new team member' in response.get_data(as_text=True)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
|
|
||||||
#
|
|
||||||
# def test_invite_user(
|
def test_invite_user(
|
||||||
# app_,
|
app_,
|
||||||
# service_one,
|
service_one,
|
||||||
# api_user_active,
|
api_user_active,
|
||||||
# mock_login,
|
mock_login,
|
||||||
# mock_get_users_by_service,
|
mock_get_users_by_service,
|
||||||
# mock_create_invite,
|
mock_create_invite,
|
||||||
# mock_get_invites_for_service
|
mock_get_invites_for_service
|
||||||
# ):
|
):
|
||||||
# from_user = api_user_active.id
|
from_user = api_user_active.id
|
||||||
# service_id = service_one['id']
|
service_id = service_one['id']
|
||||||
# email_address = 'test@example.gov.uk'
|
email_address = 'test@example.gov.uk'
|
||||||
# permissions = 'send_messages,manage_service,manage_api_keys'
|
permissions = 'send_messages,manage_service,manage_api_keys'
|
||||||
#
|
|
||||||
# with app_.test_request_context():
|
with app_.test_request_context():
|
||||||
# with app_.test_client() as client:
|
with app_.test_client() as client:
|
||||||
# client.login(api_user_active)
|
client.login(api_user_active)
|
||||||
# response = client.post(
|
response = client.post(
|
||||||
# url_for('main.invite_user', service_id=service_id),
|
url_for('main.invite_user', service_id=service_id),
|
||||||
# data={'email_address': email_address,
|
data={'email_address': email_address,
|
||||||
# 'send_messages': 'yes',
|
'send_messages': 'yes',
|
||||||
# 'manage_service': 'yes',
|
'manage_service': 'yes',
|
||||||
# 'manage_api_keys': 'yes'},
|
'manage_api_keys': 'yes'},
|
||||||
# follow_redirects=True
|
follow_redirects=True
|
||||||
# )
|
)
|
||||||
#
|
|
||||||
# assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
# mock_create_invite.assert_called_with(from_user, service_id, email_address, permissions)
|
mock_create_invite.assert_called_with(from_user, service_id, email_address, permissions)
|
||||||
# mock_get_invites_for_service.assert_called_with(service_id=service_id)
|
mock_get_invites_for_service.assert_called_with(service_id=service_id)
|
||||||
# page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||||
# assert page.h1.string.strip() == 'Manage team'
|
assert page.h1.string.strip() == 'Manage team'
|
||||||
# flash_banner = page.find('div', class_='banner-default-with-tick').string.strip()
|
flash_banner = page.find('div', class_='banner-default-with-tick').string.strip()
|
||||||
# assert flash_banner == 'Invite sent to test@example.gov.uk'
|
assert flash_banner == 'Invite sent to test@example.gov.uk'
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ def test_upload_csvfile_with_invalid_phone_shows_check_page_with_errors(
|
|||||||
mock_has_permissions
|
mock_has_permissions
|
||||||
):
|
):
|
||||||
|
|
||||||
contents = 'to,name\n+44 123,test1\n+44 456,test2'
|
contents = 'phone number,name\n+44 123,test1\n+44 456,test2'
|
||||||
file_data = (BytesIO(contents.encode('utf-8')), 'invalid.csv')
|
file_data = (BytesIO(contents.encode('utf-8')), 'invalid.csv')
|
||||||
mocker.patch('app.main.views.send.s3download', return_value=contents)
|
mocker.patch('app.main.views.send.s3download', return_value=contents)
|
||||||
|
|
||||||
@@ -102,14 +102,14 @@ def test_upload_csvfile_removes_empty_lines_and_trailing_commas(
|
|||||||
mock_has_permissions
|
mock_has_permissions
|
||||||
):
|
):
|
||||||
|
|
||||||
contents = 'to,name,,,\n++44 7700 900981,test1,,,\n+44 7700 900981,test2,,,\n ,,, \n ,,, \t \t \n'
|
contents = 'phone number,name,,,\n++44 7700 900981,test1,,,\n+44 7700 900981,test2,,,\n ,,, \n ,,, \t \t \n'
|
||||||
file_data = (BytesIO(contents.encode('utf-8')), 'invalid.csv')
|
file_data = (BytesIO(contents.encode('utf-8')), 'invalid.csv')
|
||||||
|
|
||||||
expected_data = {'data': ['to,name', '++44 7700 900981,test1', '+44 7700 900981,test2'],
|
expected_data = {'data': ['phone number,name', '++44 7700 900981,test1', '+44 7700 900981,test2'],
|
||||||
'file_name': 'invalid.csv'}
|
'file_name': 'invalid.csv'}
|
||||||
|
|
||||||
mocker.patch('app.main.views.send.s3download',
|
mocker.patch('app.main.views.send.s3download',
|
||||||
return_value='to,name\n++44 7700 900981,test1\n+44 7700 900981,test2')
|
return_value='phone number,name\n++44 7700 900981,test1\n+44 7700 900981,test2')
|
||||||
|
|
||||||
with app_.test_request_context():
|
with app_.test_request_context():
|
||||||
with app_.test_client() as client:
|
with app_.test_client() as client:
|
||||||
@@ -135,8 +135,8 @@ def test_send_test_message_to_self(
|
|||||||
mock_has_permissions
|
mock_has_permissions
|
||||||
):
|
):
|
||||||
|
|
||||||
expected_data = {'data': ['to', '+4412341234'], 'file_name': 'Test run'}
|
expected_data = {'data': ['phone number', '+4412341234'], 'file_name': 'Test run'}
|
||||||
mocker.patch('app.main.views.send.s3download', return_value='to\r\n+4412341234')
|
mocker.patch('app.main.views.send.s3download', return_value='phone number\r\n+4412341234')
|
||||||
|
|
||||||
with app_.test_request_context():
|
with app_.test_request_context():
|
||||||
with app_.test_client() as client:
|
with app_.test_client() as client:
|
||||||
@@ -167,7 +167,7 @@ def test_download_example_csv(
|
|||||||
follow_redirects=True
|
follow_redirects=True
|
||||||
)
|
)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert response.get_data(as_text=True) == 'to\r\n+4412341234\r\n'
|
assert response.get_data(as_text=True) == 'phone number\r\n+4412341234\r\n'
|
||||||
assert 'text/csv' in response.headers['Content-Type']
|
assert 'text/csv' in response.headers['Content-Type']
|
||||||
|
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ def test_upload_csvfile_with_valid_phone_shows_all_numbers(
|
|||||||
mock_has_permissions
|
mock_has_permissions
|
||||||
):
|
):
|
||||||
|
|
||||||
contents = 'to\n+44 7700 900981\n+44 7700 900982\n+44 7700 900983\n+44 7700 900984\n+44 7700 900985\n+44 7700 900986' # noqa
|
contents = 'phone number\n+44 7700 900981\n+44 7700 900982\n+44 7700 900983\n+44 7700 900984\n+44 7700 900985\n+44 7700 900986' # noqa
|
||||||
file_data = (BytesIO(contents.encode('utf-8')), 'valid.csv')
|
file_data = (BytesIO(contents.encode('utf-8')), 'valid.csv')
|
||||||
mocker.patch('app.main.views.send.s3download', return_value=contents)
|
mocker.patch('app.main.views.send.s3download', return_value=contents)
|
||||||
|
|
||||||
|
|||||||
+44
-15
@@ -12,7 +12,10 @@ from . import (
|
|||||||
job_json,
|
job_json,
|
||||||
invite_json
|
invite_json
|
||||||
)
|
)
|
||||||
from app.notify_client.models import User
|
from app.notify_client.models import (
|
||||||
|
User,
|
||||||
|
InvitedUser
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
@@ -551,27 +554,53 @@ def mock_s3_upload(mocker):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='function')
|
@pytest.fixture(scope='function')
|
||||||
def mock_create_invite(mocker):
|
def sample_invite(mocker, service_one):
|
||||||
|
import datetime
|
||||||
|
id = str(uuid.uuid4())
|
||||||
|
from_user = service_one['users'][0]
|
||||||
|
email_address = 'invited_user@test.gov.uk'
|
||||||
|
service_id = service_one['id']
|
||||||
|
permissions = 'send_messages,manage_service,manage_api_keys'
|
||||||
|
created_at = datetime.datetime.now()
|
||||||
|
return invite_json(id, from_user, service_id, email_address, permissions, created_at)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='function')
|
||||||
|
def mock_create_invite(mocker, sample_invite):
|
||||||
|
|
||||||
def _create_invite(from_user, service_id, email_address, permissions):
|
def _create_invite(from_user, service_id, email_address, permissions):
|
||||||
data = {'id': uuid.uuid4(),
|
sample_invite['from_user'] = from_user
|
||||||
'from_user': from_user,
|
sample_invite['service'] = service_id
|
||||||
'service': service_id,
|
sample_invite['email_address'] = email_address
|
||||||
'email_address': email_address,
|
sample_invite['status'] = 'pending'
|
||||||
'status': 'pending',
|
sample_invite['permissions'] = permissions
|
||||||
'permissions': permissions}
|
return InvitedUser(**sample_invite)
|
||||||
return data
|
|
||||||
return mocker.patch('app.invite_api_client.create_invite', side_effect=_create_invite)
|
return mocker.patch('app.invite_api_client.create_invite', side_effect=_create_invite)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='function')
|
@pytest.fixture(scope='function')
|
||||||
def mock_get_invites_for_service(mocker, service_one):
|
def mock_get_invites_for_service(mocker, service_one, sample_invite):
|
||||||
|
import copy
|
||||||
|
|
||||||
def _get_invites(service_id):
|
def _get_invites(service_id):
|
||||||
data = []
|
data = []
|
||||||
from_user = service_one['users'][0]
|
|
||||||
service_id = service_one['id']
|
|
||||||
for i in range(0, 5):
|
for i in range(0, 5):
|
||||||
email_address = 'user_{}@testnotify.gov.uk'.format(i)
|
invite = copy.copy(sample_invite)
|
||||||
invite = invite_json(uuid.uuid4(), from_user, service_id, email_address)
|
invite['email_address'] = 'user_{}@testnotify.gov.uk'.format(i)
|
||||||
data.append(invite)
|
data.append(InvitedUser(**invite))
|
||||||
return data
|
return data
|
||||||
return mocker.patch('app.invite_api_client.get_invites_for_service', side_effect=_get_invites)
|
return mocker.patch('app.invite_api_client.get_invites_for_service', side_effect=_get_invites)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='function')
|
||||||
|
def mock_accept_invite(mocker, sample_invite):
|
||||||
|
def _accept_token(token):
|
||||||
|
return InvitedUser(**sample_invite)
|
||||||
|
return mocker.patch('app.invite_api_client.accept_invite', side_effect=_accept_token)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='function')
|
||||||
|
def mock_add_user_to_service(mocker, service_one, api_user_active):
|
||||||
|
def _add_user(service_id, user_id):
|
||||||
|
return api_user_active
|
||||||
|
return mocker.patch('app.user_api_client.add_user_to_service', side_effect=_add_user)
|
||||||
|
|||||||
Reference in New Issue
Block a user