rename components, add cypress tests, update hash

This commit is contained in:
Christian Cueni 2019-04-08 14:18:43 +02:00
parent 236afbeb4f
commit 13685b082e
9 changed files with 194 additions and 24 deletions

View File

@ -0,0 +1,95 @@
describe('Change Password Page', () => {
const validNewPassword = 'Abcd1234!';
const validOldPassword = 'test';
const validationTooShort = 'Das neue Passwort muss mindestens 8 Zeichen lang sein';
const validationErrorMsg = 'Das Passwort muss Grossbuchstaben, Zahlen und Sonderzeichen beinhalten';
const validationOldWrongMsg = 'Die Eingabe ist falsch';
after(function () {
cy.exec("python ../server/manage.py reset_testuser_password rahel.cueni");
});
it('shows an empty form', () => {
cy.login('rahel.cueni', 'test');
cy.visit('/password-change');
cy.get('[data-cy=password-change-success]').should('not.exist');
cy.get('[data-cy=old-password]').should('have.value', '');
cy.get('[data-cy=new-password]').should('have.value', '');
});
it('shows errors if old password is not entered', () => {
cy.login('rahel.cueni', 'test');
cy.visit('/password-change');
cy.changePassword('', validNewPassword);
cy.get('[data-cy=old-password-local-errors]').should('contain', 'Dein aktuelles Passwort fehlt')
});
it('shows errors if old password is not entered', () => {
cy.login('rahel.cueni', 'test');
cy.visit('/password-change');
cy.changePassword(validOldPassword, '');
cy.get('[data-cy=new-password-local-errors]').should('contain', 'Dein neues Passwort fehlt')
});
it('shows errors if new password is too short', () => {
cy.login('rahel.cueni', 'test');
cy.visit('/password-change');
cy.changePassword(validOldPassword, 'Abc1!');
cy.get('[data-cy=new-password-local-errors]').should('contain', validationTooShort)
});
it('shows errors if new password has no uppercase letter', () => {
cy.login('rahel.cueni', 'test');
cy.visit('/password-change');
cy.changePassword(validOldPassword, 'aabdddedddbc1!');
cy.get('[data-cy=new-password-local-errors]').should('contain', validationErrorMsg)
});
it('shows errors if new password has no lowercase letter', () => {
cy.login('rahel.cueni', 'test');
cy.visit('/password-change');
cy.changePassword(validOldPassword, 'ABCDDD334551!');
cy.get('[data-cy=new-password-local-errors]').should('contain', validationErrorMsg)
});
it('shows errors if new password has no digit', () => {
cy.login('rahel.cueni', 'test');
cy.visit('/password-change');
cy.changePassword(validOldPassword, 'AbcdEEDE!');
cy.get('[data-cy=new-password-local-errors]').should('contain', validationErrorMsg)
});
it('shows errors if new password has no special character', () => {
cy.login('rahel.cueni', 'test');
cy.visit('/password-change');
cy.changePassword(validOldPassword, 'AbcdEEDE09877');
cy.get('[data-cy=new-password-local-errors]').should('contain', validationErrorMsg)
});
it('shows errors if old password does not match', () => {
cy.login('rahel.cueni', 'test');
cy.visit('/password-change');
cy.changePassword('test12345', validNewPassword);
cy.get('[data-cy=old-password-remote-errors]').should('contain', validationOldWrongMsg)
});
it('shows success if change was successful', () => {
cy.login('rahel.cueni', 'test');
cy.visit('/password-change');
cy.changePassword('test', validNewPassword);
cy.get('[data-cy=password-change-success]').should('contain', 'Dein Password wurde erfolgreich geändert.');
cy.get('[data-cy=old-password]').should('have.value', '');
cy.get('[data-cy=new-password]').should('have.value', '');
});
});

View File

@ -68,3 +68,14 @@ Cypress.Commands.add('waitFor', operationName => {
}
});
});
Cypress.Commands.add('changePassword', (oldPassword, newPassword) => {
if (oldPassword) {
cy.get('[data-cy=old-password]').type(oldPassword);
}
if (newPassword) {
cy.get('[data-cy=new-password]').type(newPassword);
}
cy.get('[data-cy=change-password-button]').click();
});

View File

@ -1,7 +1,7 @@
<template>
<div class="pw-reset">
<form class="pw-reset__form reset-form" novalidate @submit.prevent="validateBeforeSubmit">
<div class="reset-form__field sbform-input">
<div class="pw-change">
<form class="pw-change__form change-form" novalidate @submit.prevent="validateBeforeSubmit">
<div class="change-form__field sbform-input">
<label for="old-pw" class="sbform-input__label">Aktuells Passwort</label>
<input id="old-pw"
name="oldPassword"
@ -9,11 +9,13 @@
v-model="oldPassword"
v-validate="'required'"
:class="{ 'sbform-input__input--error': errors.has('oldPassword') }"
class="reset-form__old skillbox-input sbform-input__input">
<small v-if="errors.has('oldPassword') && submitted" class="sbform-input__error">{{ errors.first('oldPassword') }}</small>
<small v-for="error in oldPasswordErrors" :key="error" class=" sbform-input__error">{{ error }}</small>
class="change-form__old skillbox-input sbform-input__input"
autocomplete="off"
data-cy="old-password">
<small v-if="errors.has('oldPassword') && submitted" class="sbform-input__error" data-cy="old-password-local-errors">{{ errors.first('oldPassword') }}</small>
<small v-for="error in oldPasswordErrors" :key="error" class=" sbform-input__error" data-cy="old-password-remote-errors">{{ error }}</small>
</div>
<div class="reset-form__field sbform-input">
<div class="change-form__field sbform-input">
<label for="new-pw" class="sbform-input__label">Neues Passwort</label>
<input id="new-pw"
name="newPassword"
@ -21,11 +23,13 @@
v-model="newPassword"
v-validate="'required|min:8|strongPassword'"
:class="{ 'sbform-input__input--error': errors.has('newPassword') }"
class="reset-form__new skillbox-input sbform-input__input">
<small v-if="errors.has('newPassword') && submitted" class=" sbform-input__error">{{ errors.first('newPassword') }}</small>
<small v-for="error in newPasswordErrors" :key="error" class=" sbform-input__error">{{ error }}</small>
class="change-form__new skillbox-input sbform-input__input"
autocomplete="off"
data-cy="new-password">
<small v-if="errors.has('newPassword') && submitted" class=" sbform-input__error" data-cy="new-password-local-errors">{{ errors.first('newPassword') }}</small>
<small v-for="error in newPasswordErrors" :key="error" class=" sbform-input__error" data-cy="new-password-remote-errors">{{ error }}</small>
</div>
<button class="button button--primary reset-form__submit">Zurücksetzen</button>
<button class="button button--primary change-form__submit" data-cy="change-password-button">Zurücksetzen</button>
</form>
</div>
</template>
@ -49,8 +53,19 @@
});
}
})
},
resetForm () {
this.oldPassword = '';
this.newPassword = '';
this.submitted = false;
this.$validator.reset();
}
}
},
mounted() {
this.$root.$on('reset-password-form', () => {
this.resetForm();
})
}
}
</script>
@ -58,7 +73,7 @@
@import "@/styles/_variables.scss";
@import "@/styles/_buttons.scss";
.reset-form {
.change-form {
width: 50%;
@media screen and (max-width: 1024px) {

View File

@ -82,7 +82,7 @@ Validator.extend('min', min);
const dict = {
custom: {
oldPassword: {
required: 'Dein jetztiges Passwort fehlt'
required: 'Dein aktuelles Passwort fehlt'
},
newPassword: {
required: 'Dein neues Passwort fehlt',

View File

@ -1,7 +1,10 @@
<template>
<div class="password-reset">
<h1 class="password-reset__header">Passwort Zurücksetzen</h1>
<password-reset
<h1 class="password-reset__header">Passwort ändern</h1>
<div v-if="showSuccess" class="success-message">
<p class="success-message__msg" data-cy="password-change-success">Dein Password wurde erfolgreich geändert.</p>
</div>
<password-change
@passwordSubmited="resetPassword"
:oldPasswordErrors="oldPasswordErrors"
:newPasswordErrors="newPasswordErrors" />
@ -11,17 +14,18 @@
<script>
import UPDATE_PASSWORD_MUTATION from '@/graphql/gql/mutations/updatePassword.gql';
import PasswordReset from '@/components/PasswordReset'
import PasswordChange from '@/components/PasswordChange'
export default {
components: {
PasswordReset
PasswordChange
},
data() {
return {
oldPasswordErrors: [],
newPasswordErrors: []
newPasswordErrors: [],
showSuccess: false
}
},
methods: {
@ -37,6 +41,8 @@
if (data.updatePassword.success) {
this.oldPasswordErrors = [];
this.newPasswordErrors = [];
this.showSuccess = true;
this.$root.$emit('reset-password-form')
} else {
// currently we just have one error per field
const error = data.updatePassword.errors[0]
@ -82,4 +88,14 @@
}
}
.success-message {
margin-bottom: 20px;
&__msg {
color: $color-accent-4-dark;
font-family: $sans-serif-font-family;
}
}
</style>

View File

@ -19,7 +19,7 @@ import submission from '@/pages/studentSubmission'
import portfolio from '@/pages/portfolio'
import project from '@/pages/project'
import profilePage from '@/pages/profile'
import passwordReset from '@/pages/passwordReset'
import passwordChange from '@/pages/passwordChange'
const routes = [
{path: '/', component: start, meta: {layout: 'blank'}},
@ -65,7 +65,7 @@ const routes = [
]
},
{path: '/me', name: 'profile', component: profilePage},
{path: '/password-reset', name: 'pw-reset', component: passwordReset},
{path: '/password-change', name: 'pw-change', component: passwordChange},
{path: '*', component: p404}
];

View File

@ -0,0 +1,34 @@
# -*- coding: utf-8 -*-
#
# ITerativ GmbH
# http://www.iterativ.ch/
#
# Copyright (c) 2019 ITerativ GmbH. All rights reserved.
#
# Created on 2019-04-08
# @author: chrigu <christian.cueni@iterativ.ch>
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.management import BaseCommand
from books.models import Module
class Command(BaseCommand):
def add_arguments(self, parser):
# Positional arguments
parser.add_argument('username', nargs='+', type=str)
def handle(self, *args, **options):
self.stdout.write("Reset Testuser Password")
email = "{}@skillbox.example".format(options['username'][0])
try:
user = get_user_model().objects.get(email=email)
user.set_password('test')
user.save()
self.stdout.write("Password reset successful")
except get_user_model().DoesNotExist:
self.stdout.write("No user found!")

View File

@ -1,4 +1,5 @@
import graphene
from django.contrib.auth import update_session_auth_hash
from graphene import relay
from users.inputs import PasswordUpdateInput
from users.serializers import PasswordSerialzer
@ -30,6 +31,7 @@ class UpdatePassword(relay.ClientIDMutation):
if serializer.is_valid():
user.set_password(password_data['new_password'])
user.save()
update_session_auth_hash(info.context, user)
return cls(success=True)
errors = []

View File

@ -34,9 +34,6 @@ def create_users(data=None):
name='second_class'
)
else:
for school_class in data:
first, last = school_class.get('teacher')