Merge branch 'master' of github.com:alphagov/notifications-admin

This commit is contained in:
Martyn Inglis
2015-12-16 14:01:09 +00:00
31 changed files with 408 additions and 110 deletions

2
.gitignore vendored
View File

@@ -63,3 +63,5 @@ app/assets/stylesheets/govuk_template/.sass-cache/
.sass-cache/ .sass-cache/
cache/ cache/
app/static/* app/static/*
app/static/stylesheets/*.css

View File

@@ -44,4 +44,16 @@
#global-header #logo { #global-header #logo {
white-space: nowrap; white-space: nowrap;
}
.column-three-quarters {
@include grid-column(3/4);
}
a:visited {
color: #005ea5;
} }

View File

@@ -0,0 +1,23 @@
#navigation {
padding: 50px 0 0 0;
}
#navigation li {
@include core-16();
margin: 3px 0;
}
#navigation ul {
border-bottom: 1px solid #777;
margin: 0 20px 0 0;
list-style-type: none;
padding: 0;
}
#navigation a:link,a:visited {
text-decoration: none;
}
#navigation a:hover {
color: #2e8aca;
}

View File

@@ -33,6 +33,7 @@
@import "components/sms-message"; @import "components/sms-message";
@import "components/submit-form"; @import "components/submit-form";
@import "components/table"; @import "components/table";
@import "components/navigation";
// TODO: break this up // TODO: break this up
@import "app"; @import "app";

View File

@@ -3,4 +3,4 @@ from flask import Blueprint
main = Blueprint('main', __name__) main = Blueprint('main', __name__)
from app.main.views import index, sign_in, register, two_factor, verify, sms from app.main.views import index, sign_in, register, two_factor, verify, sms, add_service

View File

@@ -0,0 +1,41 @@
from datetime import datetime
from app import db
from app.models import Service
def insert_new_service(service_name, user):
service = Service(name=service_name,
created_at=datetime.now(),
limit=1000,
active=False,
restricted=True)
add_service(service)
service.users.append(user)
db.session.commit()
return service.id
def get_service_by_id(id):
return Service.query.get(id)
def unrestrict_service(service_id):
service = get_service_by_id(service_id)
service.restricted = False
add_service(service)
def activate_service(service_id):
service = get_service_by_id(service_id)
service.active = True
add_service(service)
def add_service(service):
db.session.add(service)
db.session.commit()
def find_service_by_service_name(service_name):
return Service.query.filter_by(name=service_name).first()

View File

@@ -5,7 +5,7 @@ from flask_wtf import Form
from wtforms import StringField, PasswordField from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, Email, Length, Regexp from wtforms.validators import DataRequired, Email, Length, Regexp
from app.main.dao import verify_codes_dao from app.main.dao import verify_codes_dao, services_dao
from app.main.encryption import check_hash from app.main.encryption import check_hash
from app.main.validators import Blacklist from app.main.validators import Blacklist
@@ -82,3 +82,14 @@ def validate_code(field, code):
return True return True
else: else:
return False return False
class AddServiceForm(Form):
service_name = StringField(validators=[DataRequired(message='Please enter your service name')])
def validate_service_name(self, a):
if services_dao.find_service_by_service_name(self.service_name.data) is not None:
self.service_name.errors.append('Duplicate service name')
return False
else:
return True

View File

@@ -0,0 +1,25 @@
from flask import render_template, jsonify, redirect, session
from flask_login import login_required
from app.main import main
from app.main.dao import services_dao, users_dao
from app.main.forms import AddServiceForm
@main.route("/add-service", methods=['GET'])
@login_required
def add_service():
return render_template('views/add-service.html', form=AddServiceForm())
@main.route("/add-service", methods=['POST'])
@login_required
def process_add_service():
form = AddServiceForm()
if form.validate_on_submit():
user = users_dao.get_user_by_id(session['user_id'])
services_dao.insert_new_service(form.service_name.data, user)
return redirect('/dashboard')
else:
return jsonify(form.errors), 400

View File

@@ -35,12 +35,6 @@ def dashboard():
return render_template('views/dashboard.html') return render_template('views/dashboard.html')
@main.route("/add-service")
@login_required
def addservice():
return render_template('views/add-service.html')
@main.route("/email-not-received") @main.route("/email-not-received")
def emailnotreceived(): def emailnotreceived():
return render_template('views/email-not-received.html') return render_template('views/email-not-received.html')

View File

@@ -78,6 +78,39 @@ class User(db.Model):
return True return True
user_to_service = db.Table(
'user_to_service',
db.Model.metadata,
db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
db.Column('service_id', db.Integer, db.ForeignKey('services.id'))
)
class Service(db.Model):
__tablename__ = 'services'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), nullable=False, unique=True)
created_at = db.Column(db.DateTime, index=False, unique=False, nullable=False)
active = db.Column(db.Boolean, index=False, unique=False, nullable=False)
limit = db.Column(db.BigInteger, index=False, unique=False, nullable=False)
users = db.relationship('User', secondary=user_to_service, backref=db.backref('user_to_service', lazy='dynamic'))
restricted = db.Column(db.Boolean, index=False, unique=False, nullable=False)
def serialize(self):
serialized = {
'id': self.id,
'name': self.name,
'createdAt': self.created_at.strftime(DATETIME_FORMAT),
'active': self.active,
'restricted': self.restricted,
'limit': self.limit,
'user': self.users.serialize()
}
return filter_null_value_fields(serialized)
def filter_null_value_fields(obj): def filter_null_value_fields(obj):
return dict( return dict(
filter(lambda x: x[1] is not None, obj.items()) filter(lambda x: x[1] is not None, obj.items())

View File

@@ -0,0 +1,21 @@
{% macro main_nav() %}
<div id="navigation">
<h3><a href="{{ url_for('.dashboard') }}">Service name</a></h3>
<ul>
<li><a href="{{ url_for('.sendsms') }}">Send text messages</a></li>
<li><a href="{{ url_for('.sendemail') }}">Send emails</a></li>
<li><a href="{{ url_for('.showjobs') }}">Activity</a></li>
</ul>
<ul>
<li><a href="{{ url_for('.apikeys') }}">API keys and documentation</a></li>
</ul>
<ul>
<li><a href="{{ url_for('.manageusers') }}">Manage users</a></li>
<li><a href="{{ url_for('.servicesettings') }}">Service settings</a></li>
</ul>
<ul>
<li><a href="/user-profile">Your details</a></li>
</ul>
</div>
{% endmacro %}

View File

@@ -16,15 +16,17 @@ GOV.UK Notify | Set up service
<li>as your email sender name</li> <li>as your email sender name</li>
</ul> </ul>
<p> <form autocomplete="off" action="" method="post">
<label class="form-label" for="emailverify">Service name</label> {{ form.hidden_tag() }}
<input class="form-control" id="emailverify" type="text"><br> <label class="form-label">Service name</label>
<span class="font-xsmall">For example, 'Vehicle tax' or 'Carer's allowance'</span> {{ form.service_name(class="form-control-2-3", autocomplete="off") }} <br>
</p> <span class="font-xsmall">For example, 'Vehicle tax' or 'Carer's allowance'</span>
<p> <p>
<a class="button" href="dashboard" role="button">Continue</a> <button class="button" href="dashboard" role="button">Continue</button>
</p> </p>
</form>
</div>
</div> </div>
</div> </div>

View File

@@ -1,20 +1,17 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | API keys and documentation GOV.UK Notify | API keys and documentation
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">API keys and documentation</h1> <h1 class="heading-xlarge">API keys and documentation</h1>
<p>Here's where developers can access information about the API and access keys</p> <p>Here's where developers can access information about the API and access keys</p>
<p><a href="dashboard">Back to dashboard</a></p> <p><a href="dashboard">Back to dashboard</a></p>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,13 +1,11 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | Send email GOV.UK Notify | Send email
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Send email</h1> <h1 class="heading-xlarge">Send email</h1>
<p>This page will be where we check the email messages we're about to send</p> <p>This page will be where we check the email messages we're about to send</p>
@@ -15,7 +13,6 @@ GOV.UK Notify | Send email
<p> <p>
<a class="button" href="dashboard" role="button">Send email messages</a> <a class="button" href="dashboard" role="button">Send email messages</a>
</p> </p>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,4 +1,4 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% from "components/sms-message.html" import sms_message %} {% from "components/sms-message.html" import sms_message %}
{% from "components/table.html" import table, field %} {% from "components/table.html" import table, field %}
{% from "components/placeholder.html" import placeholder %} {% from "components/placeholder.html" import placeholder %}
@@ -8,10 +8,9 @@
GOV.UK Notify | Send text messages GOV.UK Notify | Send text messages
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Send text messages</h1> <h1 class="heading-xlarge">Send text messages</h1>
<h2 class="heading-medium">Check and confirm</h2> <h2 class="heading-medium">Check and confirm</h2>
@@ -61,7 +60,6 @@
url_for(".sendsms") url_for(".sendsms")
) }} ) }}
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,26 +1,15 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | Dashboard GOV.UK Notify | Dashboard
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Dashboard</h1> <h1 class="heading-xlarge">Dashboard</h1>
<ul> <p>Dashboard goes here.</p>
<li><a href="{{ url_for('.sendsms') }}">Send text messages</a></li>
<li><a href="{{ url_for('.sendemail') }}">Send email messages</a></li>
<li><a href="{{ url_for('.showjobs') }}">View notifications activity</a></li>
<li><a href="{{ url_for('.userprofile') }}">User profile</a></li>
<li><a href="{{ url_for('.manageusers') }}">Manage users</a></li>
<li><a href="{{ url_for('.managetemplates')}}">Manage templates</a></li>
<li><a href="{{ url_for('.servicesettings') }}">Service settings</a></li>
<li><a href="{{ url_for('.apikeys') }}">API keys and documentation</a></li>
</ul>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,20 +1,18 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | Edit template GOV.UK Notify | Edit template
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Edit template</h1> <h1 class="heading-xlarge">Edit template</h1>
<p>Here's where you can edit an exiting template (including delete) or add a new one</p> <p>Here's where you can edit an exiting template (including delete) or add a new one</p>
<p><a href="manage-templates">Back to manage templates</a></p> <p><a href="manage-templates">Back to manage templates</a></p>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,13 +1,11 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | Notifications activity GOV.UK Notify | Notifications activity
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Notifications for a specific job</h1> <h1 class="heading-xlarge">Notifications for a specific job</h1>
<p>This page will be where we list the notifications for a specific job.</p> <p>This page will be where we list the notifications for a specific job.</p>
@@ -16,7 +14,6 @@ GOV.UK Notify | Notifications activity
<li><a href="/jobs/job/notification">view a specific notification</a></li> <li><a href="/jobs/job/notification">view a specific notification</a></li>
<li><a href="/jobs">view all the activity for this service</a></li> <li><a href="/jobs">view all the activity for this service</a></li>
</ul> </ul>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,13 +1,11 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | Notifications activity GOV.UK Notify | Notifications activity
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Notifications activity</h1> <h1 class="heading-xlarge">Notifications activity</h1>
<p>This page will be where we show the list of jobs that this service has processed</p> <p>This page will be where we show the list of jobs that this service has processed</p>
@@ -15,7 +13,6 @@ GOV.UK Notify | Notifications activity
<p> <p>
<a href="jobs/job">view a particular notification job</a> <a href="jobs/job">view a particular notification job</a>
</p> </p>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,13 +1,12 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | Manage templates GOV.UK Notify | Manage templates
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Manage templates</h1> <h1 class="heading-xlarge">Manage templates</h1>
<p>Here's where you can view templates, choose to add one, or edit/delete one.</p> <p>Here's where you can view templates, choose to add one, or edit/delete one.</p>
@@ -17,7 +16,6 @@ GOV.UK Notify | Manage templates
<p> <p>
<a class="button" href="edit-template" role="button">Add a new message template</a> <a class="button" href="edit-template" role="button">Add a new message template</a>
</p> </p>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,20 +1,17 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | Manage users GOV.UK Notify | Manage users
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Manage users</h1> <h1 class="heading-xlarge">Manage users</h1>
<p>Here's where you can add or remove users of a service.</p> <p>Here's where you can add or remove users of a service.</p>
<p><a href="dashboard">Back to dashboard</a></p> <p><a href="dashboard">Back to dashboard</a></p>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,13 +1,12 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | Notifications activity GOV.UK Notify | Notifications activity
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">A specific notification</h1> <h1 class="heading-xlarge">A specific notification</h1>
<p>This page will be where we show what happened for a specific notification.</p> <p>This page will be where we show what happened for a specific notification.</p>
@@ -15,7 +14,6 @@ GOV.UK Notify | Notifications activity
<p> <p>
<a href="/jobs/job">View other notifications in this job</a> <a href="/jobs/job">View other notifications in this job</a>
</p> </p>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,13 +1,12 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | Send email GOV.UK Notify | Send email
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Send email</h1> <h1 class="heading-xlarge">Send email</h1>
<p>This page will be where we construct email messages</p> <p>This page will be where we construct email messages</p>
@@ -15,7 +14,6 @@ GOV.UK Notify | Send email
<p> <p>
<a class="button" href="check-email" role="button">Continue</a> <a class="button" href="check-email" role="button">Continue</a>
</p> </p>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,14 +1,12 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% from "components/sms-message.html" import sms_message %} {% from "components/sms-message.html" import sms_message %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | Send text messages GOV.UK Notify | Send text messages
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<form method="POST" enctype="multipart/form-data"> <form method="POST" enctype="multipart/form-data">
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Send text messages</h1> <h1 class="heading-xlarge">Send text messages</h1>
@@ -46,8 +44,7 @@
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" /> <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input type="submit" class="button" value="Continue" /> <input type="submit" class="button" value="Continue" />
</p> </p>
</div>
</div>
</form> </form>
{% endblock %} {% endblock %}

View File

@@ -1,20 +1,17 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | Service settings GOV.UK Notify | Service settings
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">Service settings</h1> <h1 class="heading-xlarge">Service settings</h1>
<p>Here's where users can update their service profile.</p> <p>Here's where users can update their service profile.</p>
<p><a href="dashboard">Back to dashboard</a></p> <p><a href="dashboard">Back to dashboard</a></p>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -1,20 +1,16 @@
{% extends "admin_template.html" %} {% extends "withnav_template.html" %}
{% block page_title %} {% block page_title %}
GOV.UK Notify | User settings GOV.UK Notify | User settings
{% endblock %} {% endblock %}
{% block content %} {% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-xlarge">User profile</h1> <h1 class="heading-xlarge">User profile</h1>
<p>Here's where users can update their profile, password etc.</p> <p>Here's where users can update their profile, password etc.</p>
<p><a href="dashboard">Back to dashboard</a></p> <p><a href="dashboard">Back to dashboard</a></p>
</div>
</div>
{% endblock %} {% endblock %}

View File

@@ -0,0 +1,15 @@
{% extends "admin_template.html" %}
{% from "main_nav.html" import main_nav with context %}
{% block content %}
<div class="grid-row">
<div class="column-third">
{{ main_nav() }}
</div>
<div class="column-two-thirds">
{% block maincolumn_content %}{% endblock %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,42 @@
"""empty message
Revision ID: 60_add_service
Revises: 50_alter_verify_code_type
Create Date: 2015-12-15 09:25:09.000431
"""
# revision identifiers, used by Alembic.
revision = '60_add_service'
down_revision = '50_alter_verify_code_type'
from alembic import op
import sqlalchemy as sa
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_table('services',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=255), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('active', sa.Boolean(), nullable=False),
sa.Column('limit', sa.BigInteger(), nullable=False),
sa.Column('restricted', sa.Boolean(), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.create_table('user_to_service',
sa.Column('user_id', sa.Integer(), nullable=True),
sa.Column('service_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['service_id'], ['services.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], )
)
### end Alembic commands ###
def downgrade():
### commands auto generated by Alembic - please adjust! ###
op.drop_table('user_to_service')
op.drop_table('services')
### end Alembic commands ###

View File

@@ -0,0 +1,62 @@
import pytest
import sqlalchemy
from app.main.dao import services_dao
from tests.app.main import create_test_user
def test_can_insert_and_retrieve_new_service(notifications_admin, notifications_admin_db, notify_db_session):
user = create_test_user()
id = services_dao.insert_new_service('testing service', user)
saved_service = services_dao.get_service_by_id(id)
assert id == saved_service.id
assert saved_service.users == [user]
assert saved_service.name == 'testing service'
def test_unrestrict_service_updates_the_service(notifications_admin, notifications_admin_db, notify_db_session):
user = create_test_user()
id = services_dao.insert_new_service('unrestricted service', user)
saved_service = services_dao.get_service_by_id(id)
assert saved_service.restricted is True
services_dao.unrestrict_service(id)
unrestricted_service = services_dao.get_service_by_id(id)
assert unrestricted_service.restricted is False
def test_activate_service_update_service(notifications_admin, notifications_admin_db, notify_db_session):
user = create_test_user()
id = services_dao.insert_new_service('activated service', user)
service = services_dao.get_service_by_id(id)
assert service.active is False
services_dao.activate_service(id)
activated_service = services_dao.get_service_by_id(id)
assert activated_service.active is True
def test_get_service_returns_none_if_service_does_not_exist(notifications_admin,
notifications_admin_db,
notify_db_session):
service = services_dao.get_service_by_id(1)
assert service is None
def test_find_by_service_name_returns_right_service(notifications_admin,
notifications_admin_db,
notify_db_session):
user = create_test_user()
id = services_dao.insert_new_service('testing service', user)
another = services_dao.insert_new_service('Testing the Service', user)
found = services_dao.find_service_by_service_name('testing service')
assert found.id == id
assert found.name == 'testing service'
found_another = services_dao.find_service_by_service_name('Testing the Service')
assert found_another == services_dao.get_service_by_id(another)
def test_should_not_allow_two_services_of_the_same_name(notifications_admin, notifications_admin_db, notify_db_session):
user = create_test_user()
services_dao.insert_new_service('duplicate service', user)
with pytest.raises(sqlalchemy.exc.IntegrityError) as error:
services_dao.insert_new_service('duplicate service', user)
assert 'duplicate key value violates unique constraint "services_name_key' in error.value

View File

@@ -0,0 +1,18 @@
from app.main.dao import services_dao
from app.main.forms import AddServiceForm
from tests.app.main import create_test_user
def test_form_should_have_errors_when_duplicate_service_is_added(notifications_admin,
notifications_admin_db,
notify_db_session):
with notifications_admin.test_request_context(method='POST',
data={'service_name': 'some service'}) as req:
user = create_test_user()
services_dao.insert_new_service('some service', user)
req.session['user_id'] = user.id
form = AddServiceForm(req.request.form)
assert form.validate() is False
assert len(form.errors) == 1
expected = {'service_name': ['Duplicate service name']}
assert form.errors == expected

View File

@@ -0,0 +1,42 @@
from app.main.dao import verify_codes_dao, services_dao
from tests.app.main import create_test_user
def test_get_should_render_add_service_template(notifications_admin, notifications_admin_db, notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user()
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
client.post('/two-factor', data={'sms_code': '12345'})
response = client.get('/add-service')
assert response.status_code == 200
assert 'Set up notifications for your service' in response.get_data(as_text=True)
def test_should_add_service_and_redirect_to_next_page(notifications_admin, notifications_admin_db, notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user()
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
client.post('/two-factor', data={'sms_code': '12345'})
response = client.post('/add-service', data={'service_name': 'testing the post'})
assert response.status_code == 302
assert response.location == 'http://localhost/dashboard'
saved_service = services_dao.find_service_by_service_name('testing the post')
assert saved_service is not None
def test_should_return_form_errors_when_service_name_is_empty(notifications_admin,
notifications_admin_db,
notify_db_session):
with notifications_admin.test_client() as client:
with client.session_transaction() as session:
user = create_test_user()
session['user_id'] = user.id
verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms')
client.post('/two-factor', data={'sms_code': '12345'})
response = client.post('/add-service', data={})
assert response.status_code == 400
assert 'Please enter your service name' in response.get_data(as_text=True)