User.ChangePassword.feature

unified user creation and logging in
This commit is contained in:
Ulf Gebhardt 2021-04-11 03:41:08 +02:00
parent c44cefa2f9
commit c08f173b50
No known key found for this signature in database
GPG Key ID: 81308EFE29ABFEBD
26 changed files with 187 additions and 145 deletions

View File

@ -1,24 +0,0 @@
Feature: Authentication
As an user
I want to sign in
In order to be able to posts and do other contributions as myself
Furthermore I want to be able to stay logged in and logout again
Background:
Given I have an user account
Scenario: Log in
When I navigate to page "login"
And I fill in my credentials
And I click on "submit button"
Then I am logged in as "Peter Pan"
Scenario: Refresh and stay logged in
Given I am logged in
When I refresh the page
Then I am logged in as "Peter Pan"
Scenario: Log out
Given I am logged in
When I log out
Then I am on page "login"

View File

@ -9,14 +9,14 @@ Feature: Persistent Links
| Name | yes | no | no | Search, self-description |
Background:
Given I have an user account
And I am logged in
And the following "users" are in the database:
| id | name | slug |
| MHNqce98y1 | Stephen Hawking | thehawk |
Given the following "users" are in the database:
| slug | email | password | id | name | termsAndConditionsAgreedVersion |
| thehawk | hawk@example.org | abcd | MHNqce98y1 | Stephen Hawking | 0.0.4 |
| narrator | narrator@example.org | 1234 | narrator | Nathan Narrator | 0.0.4 |
And the following "posts" are in the database:
| id | title | slug |
| bWBjpkTKZp | 101 Essays that will change the way you think | 101-essays |
And I am logged in as "narrator"
Scenario Outline: Link with healable information is valid and gets auto-completed
When I navigate to page "<url>"

View File

@ -4,14 +4,17 @@ Feature: Comments on post
To be able to express my thoughts and emotions about these, discuss, and add give further information.
Background:
Given I have an user account
And I am logged in
Given the following "users" are in the database:
| slug | email | password | id | name | termsAndConditionsAgreedVersion |
| peter-pan| peter@pan.com | abcd | id-of-peter-pan| Peter Pan | 0.0.4 |
| narrator | narrator@example.org | 1234 | narrator | Nathan Narrator | 0.0.4 |
And the following "posts" are in the database:
| id | title | slug | authorId |
| bWBjpkTKZp | 101 Essays that will change the way you think | 101-essays | id-of-peter-pan |
And the following "comments" are in the database:
| postId | content | authorId |
| bWBjpkTKZp | @peter-pan reply to me | id-of-peter-pan |
And I am logged in as "narrator"
Scenario: Comment creation
Given I navigate to page "post/bWBjpkTKZp/101-essays"

View File

@ -4,8 +4,10 @@ Feature: Create a post
To say something to everyone in the community
Background:
Given I have an user account
And I am logged in
Given the following "users" are in the database:
| slug | email | password | id | name | termsAndConditionsAgreedVersion |
| narrator | narrator@example.org | 1234 | narrator | Nathan Narrator | 0.0.4 |
And I am logged in as "narrator"
And I navigate to page "landing"
Scenario: Create a post

View File

@ -4,11 +4,13 @@ Feature: Upload/Delete images on posts
So that I can personalize my posts
Background:
Given I have an user account
And I am logged in
Given the following "users" are in the database:
| slug | email | password | id | name | termsAndConditionsAgreedVersion |
| narrator | narrator@example.org | 1234 | narrator | Nathan Narrator | 0.0.4 |
And the following "posts" are in the database:
| authorId | id | title | content |
| id-of-peter-pan | p1 | Post to be updated | successfully updated |
| authorId | id | title | content |
| narrator | p1 | Post to be updated | successfully updated |
And I am logged in as "narrator"
And I navigate to page "landing"
Scenario: Create a Post with a Teaser Image
@ -17,6 +19,7 @@ Feature: Upload/Delete images on posts
And I add all required fields
And I click on "save button"
Then I am on page ".../new-post"
And I wait for 750 milliseconds
And the post was saved successfully with the "new" teaser image
Scenario: Update a Post to add an image
@ -25,6 +28,7 @@ Feature: Upload/Delete images on posts
And I click on "save button"
Then I see a toaster with "Saved!"
And I am on page ".../post-to-be-updated"
And I wait for 750 milliseconds
Then the post was saved successfully with the "updated" teaser image
Scenario: Add image, then add a different image
@ -40,6 +44,7 @@ Feature: Upload/Delete images on posts
And I add all required fields
And I click on "save button"
Then I am on page ".../new-post"
And I wait for 750 milliseconds
And the "new" post was saved successfully without a teaser image
Scenario: Delete existing image
@ -48,4 +53,5 @@ Feature: Upload/Delete images on posts
Then I should be able to remove the image
And I click on "save button"
Then I am on page ".../post-to-be-updated"
And I wait for 750 milliseconds
And the "updated" post was saved successfully without a teaser image

View File

@ -4,11 +4,14 @@ Feature: See a post
And to see the whole content of it
Background:
Given I have an user account
And I am logged in
Given the following "users" are in the database:
| slug | email | password | id | name | termsAndConditionsAgreedVersion |
| peter-pan| peter@pan.com | abcd | id-of-peter-pan| Peter Pan | 0.0.4 |
| narrator | narrator@example.org | 1234 | narrator | Nathan Narrator | 0.0.4 |
And the following "posts" are in the database:
| id | title | slug | authorId | content |
| aBcDeFgHiJ | previously created post | previously-created-post | id-of-peter-pan | with some content |
And I am logged in as "narrator"
Scenario: See a post on the landing page
When I navigate to page "landing"

View File

@ -0,0 +1,26 @@
Feature: User authentication
As an user
I want to sign in
In order to be able to posts and do other contributions as myself
Furthermore I want to be able to stay logged in and logout again
Background:
Given the following "users" are in the database:
| email | password | id | name | slug | termsAndConditionsAgreedVersion |
| peterpan@example.org | 1234 | id-of-peter-pan | Peter Pan | peter-pan | 0.0.4 |
Scenario: Log in
When I navigate to page "login"
And I fill in my credentials "peterpan@example.org" "1234"
And I click on "submit button"
Then I am logged in with username "Peter Pan"
Scenario: Refresh and stay logged in
Given I am logged in as "peter-pan"
When I refresh the page
Then I am logged in with username "Peter Pan"
Scenario: Log out
Given I am logged in as "peter-pan"
When I log out
Then I am on page "login"

View File

@ -1,6 +1,7 @@
import { Then } from "cypress-cucumber-preprocessor/steps";
Then("I am logged in as {string}", name => {
Then("I am logged in with username {string}", name => {
cy.get(".avatar-menu").click();
cy.get(".avatar-menu-popover").contains(name);
cy.get(".avatar-menu").click(); // Close menu again
});

View File

@ -0,0 +1,55 @@
Feature: User change password
As a user
I want to change my password in my settings
For security, e.g. if I exposed my password by accident
Login via email and password is a well-known authentication procedure and you
can assure to the server that you are who you claim to be. Either if you
exposed your password by acccident and you want to invalidate the exposed
password or just out of an good habit, you want to change your password.
Background:
Given the following "users" are in the database:
| email | password | id | name | slug | termsAndConditionsAgreedVersion |
| peterpan@example.org | exposed | id-of-peter-pan | Peter Pan | peter-pan | 0.0.4 |
And I am logged in as "peter-pan"
And I navigate to page "settings"
And I click on "security menu"
Scenario: Incorrect Old Password
When I fill the password form with:
| Your old password | incorrect |
| Your new password | secure |
| Confirm new password | secure |
And I submit the form
And I see a "failure toaster" message:
"""
Old password is not correct
"""
Scenario: Incorrect Password Repeat
When I fill the password form with:
| Your old password | exposed |
| Your new password | secure |
| Confirm new password | eruces |
And I cannot submit the form
Scenario: Change my password
Given I navigate to page "settings"
And I click on "security menu"
When I fill the password form with:
| Your old password | exposed |
| Your new password | secure |
| Confirm new password | secure |
And I submit the form
And I see a "success toaster" message:
"""
Password successfully changed!
"""
And I log out
Then I fill in my credentials "peterpan@example.org" "exposed"
And I click on "submit button"
And I cannot login anymore
But I fill in my credentials "peterpan@example.org" "secure"
And I click on "submit button"
And I can login successfully

View File

@ -0,0 +1,7 @@
import { Then } from "cypress-cucumber-preprocessor/steps";
Then("I can login successfully", () => {
// cy.reload();
cy.get(".iziToast-wrapper")
.should("contain", "You are logged in!");
});

View File

@ -0,0 +1,7 @@
import { Then } from "cypress-cucumber-preprocessor/steps";
Then("I cannot login anymore", password => {
//cy.reload();
cy.get(".iziToast-wrapper")
.should("contain", "Incorrect email address or password.");
});

View File

@ -0,0 +1,6 @@
import { When } from "cypress-cucumber-preprocessor/steps";
When("I cannot submit the form", () => {
cy.get("button[type=submit]")
.should('be.disabled');
});

View File

@ -0,0 +1,11 @@
import { When } from "cypress-cucumber-preprocessor/steps";
When("I fill the password form with:", table => {
table = table.rowsHash();
cy.get("input[id=oldPassword]")
.type(table["Your old password"])
.get("input[id=password]")
.type(table["Your new password"])
.get("input[id=passwordConfirmation]")
.type(table["Confirm new password"]);
});

View File

@ -0,0 +1,5 @@
import { Then } from "cypress-cucumber-preprocessor/steps";
Then("I see a {string} message:", (type, message) => {
cy.contains(message);
});

View File

@ -0,0 +1,5 @@
import { When } from "cypress-cucumber-preprocessor/steps";
When("I submit the form", () => {
cy.get("form").submit();
});

View File

@ -88,7 +88,7 @@ Given("my user account has the role {string}", role => {
cy.factory().build("user", {
role,
...termsAndConditionsAgreedVersion,
}, loginCredentials);
}, /*loginCredentials*/ 'TODO');
});
When("I log out", cy.logout);
@ -157,10 +157,6 @@ Given("we have the following posts in our database:", table => {
})
})
Then("I see a success message:", message => {
cy.contains(message);
});
When("I click on the avatar menu in the top right corner", () => {
cy.get(".avatar-menu").click();
});
@ -189,52 +185,6 @@ Then(
}
);
Given("I am logged in with these credentials:", table => {
loginCredentials = table.hashes()[0];
cy.factory().build("user", {
...termsAndConditionsAgreedVersion,
name: loginCredentials.email,
}, loginCredentials);
cy.neode()
.first("User", {
name: loginCredentials.email,
})
.then(user => {
return new Cypress.Promise((resolve, reject) => {
return user.toJson().then((user) => resolve(user))
})
})
.then(user => cy.login(user))
});
When("I fill the password form with:", table => {
table = table.rowsHash();
cy.get("input[id=oldPassword]")
.type(table["Your old password"])
.get("input[id=password]")
.type(table["Your new passsword"])
.get("input[id=passwordConfirmation]")
.type(table["Confirm new password"]);
});
When("submit the form", () => {
cy.get("form").submit();
});
Then("I cannot login anymore with password {string}", password => {
cy.reload();
const { email } = loginCredentials
cy.manualLogin({ email, password })
.get(".iziToast-wrapper").should("contain", "Incorrect email address or password.");
});
Then("I can login successfully with password {string}", password => {
cy.reload();
const { email } = loginCredentials
cy.manualLogin({ email, password })
.get(".iziToast-wrapper").should("contain", "You are logged in!");
});
When("open the notification menu and click on the first item", () => {
cy.get(".notifications-menu").invoke('show').click(); // "invoke('show')" because of the delay for show the menu
cy.get(".notification .link")

View File

@ -1,13 +0,0 @@
import { Given } from "cypress-cucumber-preprocessor/steps";
import narrator from "../data/narrator";
Given("I am logged in", () => {
cy.neode()
.first("User", { name: narrator.name })
.then(user => {
return new Cypress.Promise((resolve, reject) => {
return user.toJson().then((user) => resolve(user))
})
})
.then(user => cy.login(user))
});

View File

@ -0,0 +1,18 @@
import { Given } from "cypress-cucumber-preprocessor/steps";
import encode from '../../../backend/src/jwt/encode'
Given("I am logged in as {string}", slug => {
cy.neode()
.first("User", { slug })
.then(user => {
return new Cypress.Promise((resolve, reject) => {
if(!user) {
return reject(`User ${email} not found in database`)
}
return user.toJson().then((user) => resolve(user))
})
})
.then(user => {
cy.setCookie('ocelot-social-token', encode(user))
})
});

View File

@ -8,6 +8,7 @@ When("I click on {string}", element => {
'the first post': '.post-teaser:first-child',
'comment button': 'button[type=submit]',
'reply button': '.reply-button',
'security menu': 'a[href="/settings/security"]',
}
cy.get(elementSelectors[element])

View File

@ -0,0 +1,12 @@
import { When } from "cypress-cucumber-preprocessor/steps";
When("I fill in my credentials {string} {string}", (email,password) => {
cy.get("input[name=email]")
.trigger("focus")
.type('{selectall}{backspace}')
.type(email)
.get("input[name=password]")
.trigger("focus")
.type('{selectall}{backspace}')
.type(password);
});

View File

@ -1,7 +0,0 @@
import { Given } from "cypress-cucumber-preprocessor/steps";
import narrator from '../data/narrator'
import loginCredentials from '../data/loginCredentials'
Given("I have an user account", () => {
cy.factory().build("user", narrator, loginCredentials);
});

View File

@ -1,7 +1,8 @@
import { When } from "cypress-cucumber-preprocessor/steps";
When("I log out", () => {
// cy.get(".avatar-menu").click();
cy.get(".avatar-menu")
.click();
cy.get(".avatar-menu-popover")
.find('a[href="/logout"]')
.click();

View File

@ -1,6 +0,0 @@
const loginCredentials = {
email: "peterpan@example.org",
password: "1234"
}
export default loginCredentials

View File

@ -1,8 +0,0 @@
const narrator = {
id: 'id-of-peter-pan',
name: "Peter Pan",
slug: "peter-pan",
termsAndConditionsAgreedVersion: '0.0.4',
}
export default narrator

View File

@ -18,7 +18,6 @@ import helpers from "./helpers";
import { GraphQLClient, request } from 'graphql-request'
import { gql } from '../../backend/src/helpers/jest'
import config from '../../backend/src/config'
import encode from '../../backend/src/jwt/encode'
const switchLang = name => {
cy.get(".locale-menu").click();
@ -51,24 +50,6 @@ Cypress.Commands.add("switchLanguage", (name, force) => {
}
});
Cypress.Commands.add("login", user => {
const token = encode(user)
cy.setCookie('ocelot-social-token', token)
});
/*Cypress.Commands.add("manualLogin", ({ email, password }) => {
cy.visit(`/login`)
.get("input[name=email]")
.trigger("focus")
.type(email)
.get("input[name=password]")
.trigger("focus")
.type(password)
.get("button[name=submit]")
.as("submitButton")
.click();
});*/
Cypress.Commands.add("logout", () => {
cy.visit(`/logout`);
cy.location("pathname").should("contain", "/login"); // we're out