Add cypress testing #243

This commit is contained in:
Daniel Grams 2021-08-03 22:55:33 +02:00
parent f903ea963b
commit 942e3d9b09
11 changed files with 195 additions and 60 deletions

3
.coveragerc Normal file
View File

@ -0,0 +1,3 @@
[run]
omit =
project/cli/database.py

View File

@ -0,0 +1,28 @@
describe('Login', () => {
it('user log in', () => {
cy.visit('/login')
// Blank
cy.get('#submit').click()
cy.assertRequired('email')
cy.assertRequired('password')
// Email
cy.get('#email').type("invalidmail")
cy.assertInvalid('email', 'Geben Sie bitte eine gültige E-Mail-Adresse ein.')
cy.get('#email').clear().type("test@test.de")
cy.assertValid('email')
// Password
cy.get('#password').type("password")
cy.assertValid('password')
// Submit
cy.get('#submit').click()
cy.url().should('include', '/manage')
cy.get('h1').should('contain', 'Organisationen')
cy.getCookie('session').should('exist')
})
})

View File

@ -0,0 +1,7 @@
describe('Profile', () => {
it('profile', () => {
cy.login()
cy.visit('/profile')
cy.get('h1').should('contain', 'test@test.de')
})
})

View File

@ -1,15 +1,41 @@
describe('Register', () => {
beforeEach(() => {
cy.logexec('flask database reset --seed')
})
it('registers user', () => {
cy.visit('/register')
cy.get('input[name=email]').type("firstname.lastname@gmail.com")
cy.get('input[name=password]').type("iloveoveda{enter}")
cy.get('input[name=password_confirm]').type("iloveoveda{enter}")
cy.get('input[name=accept_tos]').check()
cy.get('input[name=submit]').click()
// Blank
cy.get('#submit').click()
cy.assertRequired('email')
cy.assertRequired('password')
cy.assertRequired('password_confirm')
cy.assertRequired('accept_tos')
// Email
cy.get('#email').type("invalidmail")
cy.assertInvalid('email', 'Geben Sie bitte eine gültige E-Mail-Adresse ein.')
cy.get('#email').clear().type("test@test.de")
cy.assertInvalid('email', 'Mit dieser E-Mail existiert bereits ein Account.')
cy.get('#email').clear().type("firstname.lastname@gmail.com")
cy.assertValid('email')
// Password
cy.get('#password').type("short")
cy.assertInvalid('password', 'Geben Sie bitte mindestens 8 Zeichen ein.')
cy.get('#password').clear().type("iloveoveda")
cy.assertValid('password')
// Confirm password
cy.get('#password_confirm').type("different")
cy.assertInvalid('password_confirm', 'Wiederholen Sie bitte denselben Wert.')
cy.get('#password_confirm').clear().type("iloveoveda")
cy.assertValid('password_confirm')
// Submit
cy.get('#accept_tos').check()
cy.get('#submit').click()
cy.url().should('eq', Cypress.config().baseUrl + '/')
cy.get('div.alert').should('contain', 'Bestätigungsanleitung')

View File

@ -1,28 +1,3 @@
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
Cypress.Commands.add('logexec', (command) => {
cy.exec(command, { failOnNonZeroExit: false }).then(result => {
if (result.code) {
@ -32,4 +7,33 @@ Cypress.Commands.add('logexec', (command) => {
Stderr:\n${result.stderr}`);
}
})
})
})
Cypress.Commands.add('setup', () => {
cy.logexec('flask database reset --seed')
cy.logexec('flask user create test@test.de password --confirm')
})
Cypress.Commands.add('assertValid', (fieldId) => {
cy.get('#' + fieldId).should('have.class', 'is-valid')
cy.get('#' + fieldId + '-error').should('be.empty')
})
Cypress.Commands.add('assertInvalid', (fieldId, msg) => {
cy.get('#' + fieldId).should('have.class', 'is-invalid')
cy.get('#' + fieldId + '-error').should('contain', msg)
})
Cypress.Commands.add('assertRequired', (fieldId) => {
cy.assertInvalid(fieldId, 'Pflichtfeld')
})
Cypress.Commands.add('login', (email = "test@test.de", password = "password") => {
cy.visit('/login')
cy.get('#email').type(email)
cy.get('#password').type(password)
cy.get('#submit').click()
cy.url().should('include', '/manage')
cy.getCookie('session').should('exist')
})

View File

@ -1,20 +1,5 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
beforeEach(() => {
cy.setup()
})

View File

@ -1,4 +1,3 @@
# pragma: no cover
import click
from flask.cli import AppGroup
from sqlalchemy import MetaData

View File

@ -1,8 +1,13 @@
import click
from flask.cli import AppGroup
from flask_security.confirmable import confirm_user
from project import app, db
from project.services.user import add_admin_roles_to_user
from project.services.user import (
add_admin_roles_to_user,
create_user,
find_user_by_email,
)
user_cli = AppGroup("user")
@ -15,4 +20,27 @@ def add_admin_roles(email):
click.echo(f"Admin roles were added to {email}.")
@user_cli.command("create")
@click.argument("email")
@click.argument("password")
@click.option("--confirm/--no-confirm", default=False)
def create(email, password, confirm):
user = create_user(email, password)
if confirm:
confirm_user(user)
db.session.commit()
click.echo(f"Created user {email}.")
@user_cli.command("confirm")
@click.argument("email")
def confirm(email):
user = find_user_by_email(email)
confirm_user(user)
db.session.commit()
click.echo(f"Confirmed user {email}.")
app.cli.add_command(user_cli)

View File

@ -1,11 +1,23 @@
{% extends "layout.html" %}
{% from "_macros.html" import render_field_with_errors, render_field, render_field_errors %}
{% from "_macros.html" import render_jquery_steps_header, render_field_with_errors, render_field, render_field_errors %}
{% block header %}
{{ render_jquery_steps_header() }}
<script>
$( function() {
var form = $("#main-form");
form.validate();
});
</script>
{% endblock %}
{% block content %}
<h1>{{ _fsdomain('Login') }}</h1>
{% set next = request.args['next'] if 'next' in request.args and 'authorize' in request.args['next'] else 'manage_after_login' %}
<form action="{{ url_for_security('login', next=next) }}" method="POST" name="login_user_form">
<form id="main-form" action="{{ url_for_security('login', next=next) }}" method="POST" name="login_user_form">
{{ login_user_form.hidden_tag() }}
{{ render_field_with_errors(login_user_form.email) }}
{{ render_field_with_errors(login_user_form.password) }}

View File

@ -26,7 +26,8 @@
required: true,
minlength: 8,
equalTo: "#password"
}
},
accept_tos: "required",
}
});
});
@ -45,8 +46,10 @@
{% endif %}
<div class="form-group form-check">
{{ register_user_form.accept_tos(class="form-check-input")|safe }}
{{ register_user_form.accept_tos.label(class="form-check-label") }}
<div class="input-group">
{{ register_user_form.accept_tos(class="form-check-input")|safe }}
{{ register_user_form.accept_tos.label(class="form-check-label") }}
</div>
</div>
{{ render_field(register_user_form.submit) }}

View File

@ -26,3 +26,43 @@ def test_add_admin_roles_UserDoesNotExist(client, seeder, app):
result = runner.invoke(args=["user", "add-admin-roles", "unknown@test.de"])
assert result.exit_code == 1
assert "User with given email does not exist." in result.exception.args[0]
def test_create(client, seeder, app):
with app.app_context():
from project.services.user import find_user_by_email
user = find_user_by_email("test@test.de")
assert not user
runner = app.test_cli_runner()
result = runner.invoke(
args=["user", "create", "test@test.de", "password", "--confirm"]
)
assert "Created user test@test.de." in result.output
with app.app_context():
from project.services.user import find_user_by_email
user = find_user_by_email("test@test.de")
assert user.confirmed_at is not None
def test_confirm(client, seeder, app):
runner = app.test_cli_runner()
result = runner.invoke(args=["user", "create", "test@test.de", "password"])
with app.app_context():
from project.services.user import find_user_by_email
user = find_user_by_email("test@test.de")
assert user.confirmed_at is None
result = runner.invoke(args=["user", "confirm", "test@test.de"])
assert "Confirmed user test@test.de." in result.output
with app.app_context():
from project.services.user import find_user_by_email
user = find_user_by_email("test@test.de")
assert user.confirmed_at is not None