From 350ccda20833161b99bcfb875c706fed664c8e7d Mon Sep 17 00:00:00 2001 From: Rebecca Law Date: Mon, 14 Dec 2015 17:12:28 +0000 Subject: [PATCH] 110067722: Added endpoints for add-service Post is not complete as of yet. --- app/main/__init__.py | 2 +- app/main/dao/services_dao.py | 4 ++++ app/main/forms.py | 4 ++++ app/main/views/add_service.py | 23 +++++++++++++++++++++ app/main/views/index.py | 6 ------ app/models.py | 2 +- migrations/versions/60_add_service.py | 5 +++-- tests/app/main/dao/test_service_dao.py | 25 ++++++++++++++++++++++- tests/app/main/views/test_add_service.py | 26 ++++++++++++++++++++++++ 9 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 app/main/views/add_service.py create mode 100644 tests/app/main/views/test_add_service.py diff --git a/app/main/__init__.py b/app/main/__init__.py index 2f617456e..4025b6dd1 100644 --- a/app/main/__init__.py +++ b/app/main/__init__.py @@ -3,4 +3,4 @@ from flask import Blueprint 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 diff --git a/app/main/dao/services_dao.py b/app/main/dao/services_dao.py index 53a9f64f6..6d1f11aeb 100644 --- a/app/main/dao/services_dao.py +++ b/app/main/dao/services_dao.py @@ -36,3 +36,7 @@ def activate_service(service_id): 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() diff --git a/app/main/forms.py b/app/main/forms.py index 8d94fdaf7..21352a7f4 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -82,3 +82,7 @@ def validate_code(field, code): return True else: return False + + +class AddServiceForm(Form): + service_name = StringField(validators=[DataRequired(message='Name can not be empty')]) diff --git a/app/main/views/add_service.py b/app/main/views/add_service.py new file mode 100644 index 000000000..4d91f97f0 --- /dev/null +++ b/app/main/views/add_service.py @@ -0,0 +1,23 @@ +from flask import render_template, jsonify, redirect +from flask_login import login_required + +from app.main import main +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(): + + return redirect('/dashboard') + else: + return jsonify(form.errors), 400 diff --git a/app/main/views/index.py b/app/main/views/index.py index f1525d4cd..485b4d2d6 100644 --- a/app/main/views/index.py +++ b/app/main/views/index.py @@ -35,12 +35,6 @@ def dashboard(): 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") def emailnotreceived(): return render_template('views/email-not-received.html') diff --git a/app/models.py b/app/models.py index ba4492874..f7b21e81a 100644 --- a/app/models.py +++ b/app/models.py @@ -90,7 +90,7 @@ class Service(db.Model): __tablename__ = 'services' id = db.Column(db.Integer, primary_key=True) - name = db.Column(db.String(255), nullable=False) + name = db.Column(db.String(255), nullable=False, unique=True) token_id = db.Column(db.BigInteger, index=True, unique=True) created_at = db.Column(db.DateTime, index=False, unique=False, nullable=False) diff --git a/migrations/versions/60_add_service.py b/migrations/versions/60_add_service.py index 8e366e504..eca5d0b72 100644 --- a/migrations/versions/60_add_service.py +++ b/migrations/versions/60_add_service.py @@ -2,7 +2,7 @@ Revision ID: 60_add_service Revises: 50_alter_verify_code_type -Create Date: 2015-12-14 15:22:55.938819 +Create Date: 2015-12-14 16:55:56.612005 """ @@ -24,7 +24,8 @@ def upgrade(): 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.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('name') ) op.create_index(op.f('ix_services_token_id'), 'services', ['token_id'], unique=True) op.create_table('user_to_service', diff --git a/tests/app/main/dao/test_service_dao.py b/tests/app/main/dao/test_service_dao.py index 661cc0cad..e8918eb1f 100644 --- a/tests/app/main/dao/test_service_dao.py +++ b/tests/app/main/dao/test_service_dao.py @@ -1,10 +1,12 @@ +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 @@ -37,3 +39,24 @@ def test_get_service_returns_none_if_service_does_not_exist(notifications_admin, 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 diff --git a/tests/app/main/views/test_add_service.py b/tests/app/main/views/test_add_service.py new file mode 100644 index 000000000..3083e5180 --- /dev/null +++ b/tests/app/main/views/test_add_service.py @@ -0,0 +1,26 @@ +from app.main.dao import verify_codes_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'