From 7311bd383871a0f5e8d6ef9a307cf174c56e3f5e Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 15 May 2020 20:32:29 +0200 Subject: [PATCH] Prepare Behat scenarios for User system refacto (#339) --- features/organization/assets.feature | 126 +++++++++++------- features/organization/children.feature | 66 +++++---- features/organization/forecast.feature | 4 - features/organization/home.feature | 41 ++++++ features/organization/login.feature | 28 ---- features/organization/mission_type.feature | 5 - features/organization/planning.feature | 5 - features/organization/search.feature | 37 ++--- features/organization/users.feature | 100 ++++++++++---- .../user/{edit.feature => account.feature} | 27 ++-- features/user/availabilities.feature | 15 ++- features/user/login.feature | 81 +++++++++-- features/user/password.feature | 102 ++++++++++++++ features/user/register.feature | 20 +-- fixtures/users.yaml | 73 +++++++++- symfony.lock | 6 + 16 files changed, 533 insertions(+), 203 deletions(-) create mode 100644 features/organization/home.feature delete mode 100644 features/organization/login.feature rename features/user/{edit.feature => account.feature} (89%) create mode 100644 features/user/password.feature diff --git a/features/organization/assets.feature b/features/organization/assets.feature index c4c1fa85..0a89d6a5 100644 --- a/features/organization/assets.feature +++ b/features/organization/assets.feature @@ -1,18 +1,13 @@ Feature: In order to manage the assets in my organization, - As an organization, + As an admin of an organization, I must be able to list, edit and delete assets in my organization. - Scenario: As anonymous, I cannot list the assets from an organization - When I go to "/organizations/201/assets" - Then I should be on "/organizations/login" - And the response status code should be 200 - - Scenario: As an organization, I can list the assets from my organization - Given I am authenticated as "DT75" - And I am on "/organizations/201" + Scenario: As an admin of an organization, I can list the assets from my organization + Given I am authenticated as "admin203@resop.com" + And I am on "/organizations/203" When I follow "Afficher la liste de mes véhicules" - Then I should be on "/organizations/201/assets/" + Then I should be on "/organizations/203/assets" And the response status code should be 200 And I should see "75992" And I should see "75996" @@ -20,8 +15,8 @@ Feature: And I should not see "7501" And I should not see "7710" - Scenario: As a parent organization, I can list the assets from my children organizations - Given I am authenticated as "DT75" + Scenario: As an admin of a parent organization, I can list the assets from my children organizations + Given I am authenticated as "admin201@resop.com" And I am on "/organizations/201" When I follow "Modifier mes structures" Then I should be on "/organizations/201/children/" @@ -35,81 +30,109 @@ Feature: And I should not see "7799" And I should not see "7710" - Scenario: As an organization, I cannot list the assets from an organization I don't have access to - Given I am authenticated as "DT75" + Scenario: As an admin of an organization, I cannot list the assets from an organization I don't have access to + Given I am authenticated as "admin201@resop.com" When I go to "/organizations/202/assets" Then the response status code should be 403 - Scenario Outline: As an authenticated parent organization, I can add an asset on my organization or children organizations + Scenario: As an admin of a child organization, I cannot list the assets from the parent organization + Given I am authenticated as "admin203@resop.com" + When I go to "/organizations/201/assets" + Then the response status code should be 403 + + Scenario Outline: As an admin of an organization, I can add an asset on my organization or children organizations Given I am authenticated as "" - When I go to "/organizations/203/assets" + When I go to "" And I follow "Ajouter un nouveau véhicule" Then the response status code should be 200 - And I should be on "/organizations/203/assets/preAdd" + And I should be on "" When I select "VL" from "type" And I press "Continuer" Then the response status code should be 200 - And I should be on "/organizations/203/assets/add" + And I should be on "" When I fill in the following: - | commissionable_asset[name] | new vehicule | + | commissionable_asset[type] | VL | + | commissionable_asset[name] | new vehicule | + | commissionable_asset[hasMobileRadio] | 1 | + | commissionable_asset[hasFirstAidKit] | 1 | + | commissionable_asset[parkingLocation] | some parking location | + | commissionable_asset[contact] | some contact | + | commissionable_asset[seatingCapacity] | 5 | + | commissionable_asset[licensePlate] | some license plate | + | commissionable_asset[comments] | some comments | And I press "Enregistrer" + Then I should be on "" + And the response status code should be 200 And I should see "Véhicule créé" - And I should see "new vehicule" + And I should see "VL - new vehicule" + When I follow the last "Modifier" + Then I should be on "/organizations/203/assets/1/edit" + And the response status code should be 200 + And the "commissionable_asset_type" field should contain "VL" + And the "commissionable_asset_name" field should contain "new vehicule" + And the "commissionable_asset_hasMobileRadio_0" checkbox is checked + And the "commissionable_asset_hasFirstAidKit_0" checkbox is checked + And the "commissionable_asset_parkingLocation" field should contain "some parking location" + And the "commissionable_asset_contact" field should contain "some contact" + And the "commissionable_asset_seatingCapacity" field should contain "5" + And the "commissionable_asset_licensePlate" field should contain "some license plate" + And the "commissionable_asset_comments" field should contain "some comments" Examples: - | login | + | login | list_url | preAdd_url | add_url | # todo: there is a bug when using parent organization: https://github.com/crf-devs/resop/issues/360 -# | DT75 | - | UL 01-02 | +# todo: how to create a new asset on a children organization (but not on current one)? +# | admin201@resop.com | /organizations/201/assets?organization=203 | /organizations/201/assets/preAdd | /organizations/201/assets/add | + | admin203@resop.com | /organizations/203/assets | /organizations/203/assets/preAdd | /organizations/203/assets/add | @javascript - Scenario: As an organization, I can display an asset modal - Given I am authenticated as "DT75" - When I go to "/organizations/203/assets" + Scenario: As an admin of an organization, I can display an asset modal + Given I am authenticated as "admin201@resop.com" + When I go to "/organizations/201/assets" And I press "Afficher" And I wait for ".modal-show-asset-inner" to be visible Then I should see "Modifier" And I follow "Modifier" Then I should be on "/organizations/201/assets/75012/edit?organizationId=203" - Scenario Outline: As an organization, I can update an asset from my organization or children organizations + Scenario Outline: As an admin of an organization, I can update an asset from my organization or children organizations Given I am authenticated as "" - When I go to "/organizations/203/assets/75012/edit" - Then I should be on "/organizations/203/assets/75012/edit" + When I go to "" + Then I should be on "" And the response status code should be 200 And the "commissionable_asset_name" field should contain "75012" When I fill in the following: | commissionable_asset[name] | new name | And I press "Enregistrer" - Then I should be on "/organizations/203/assets/" + Then I should be on "" And the response status code should be 200 And I should see "Véhicule \"VPSP - new name\" mis à jour avec succès" - When I go to "/organizations/203/assets/75012/edit" + When I go to "" And the "commissionable_asset_name" field should contain "new name" Examples: - | login | + | login | edit_url | list_url | # todo: there is a bug when using parent organization: https://github.com/crf-devs/resop/issues/360 -# | DT75 | - | UL 01-02 | +# | admin201@resop.com | /organizations/201/assets/75012/edit | /organizations/201/assets?organization=203 | + | admin203@resop.com | /organizations/203/assets/75012/edit | /organizations/203/assets | - Scenario: As a parent organization, I cannot update an asset from an organization I don't have access to - Given I am authenticated as "DT75" + Scenario: As an admin of a parent organization, I cannot update an asset from an organization I don't have access to + Given I am authenticated as "admin201@resop.com" When I go to "/organizations/202/assets/77992/edit" Then the response status code should be 403 Scenario: As an admin of a child organization, I cannot update an asset on the parent organization - Given I am authenticated as "UL 01-02" + Given I am authenticated as "admin203@resop.com" When I go to "/organizations/201/assets/75992/edit" Then the response status code should be 403 - Scenario: As a parent organization, I cannot update an invalid asset - Given I am authenticated as "DT75" + Scenario: As an admin of a parent organization, I cannot update an invalid asset + Given I am authenticated as "admin201@resop.com" When I go to "/organizations/201/assets/77102/edit" Then the response status code should be 404 @javascript - Scenario: As a parent organization, I can delete an asset from my organization or children organizations - Given I am authenticated as "DT75" - And I go to "/organizations/203/assets/75012/edit" + Scenario: As an admin of a parent organization, I can delete an asset from my organization or children organizations + Given I am authenticated as "admin201@resop.com" + And I go to "/organizations/201/assets/75012/edit" When I follow "Supprimer" And I wait for "#delete-item-modal" to be visible Then I should see "Vous êtes sur le point de supprimer le véhicule suivant et toutes ses disponibilités : VPSP - 75012" @@ -118,20 +141,25 @@ Feature: And I should see "Le véhicule a été supprimé avec succès." And I should not see "75012" - #https://github.com/crf-devs/resop/issues/348 -# Scenario: As a parent organization, I cannot directly delete an asset from my organization -# Given I am authenticated as "john.doe@resop.com" +# https://github.com/crf-devs/resop/issues/348 +# Scenario: As an admin of a parent organization, I cannot directly delete an asset from my organization +# Given I am authenticated as "admin201@resop.com" # When I go to "/organizations/201/assets/75992/delete" # Then the response status code should be 405 - Scenario: As a parent organization, I cannot delete an asset from another organization - Given I am authenticated as "DT75" + Scenario: As an admin of a parent organization, I cannot delete an asset from another organization + Given I am authenticated as "admin201@resop.com" When I go to "/organizations/202/assets" Then the response status code should be 403 When I go to "/organizations/202/assets/77992/delete" Then the response status code should be 403 - Scenario: As a parent organization, I cannot access availability of an invalid asset - Given I am authenticated as "DT75" + Scenario: As an admin of a parent organization, I cannot access availability of an invalid asset + Given I am authenticated as "admin201@resop.com" + When I go to "/organizations/201/availability/75012/2020-W10" + Then the response status code should be 404 + + Scenario: As an admin of an organization, I cannot access availability of an asset with a mismatched url + Given I am authenticated as "admin201@resop.com" When I go to "/organizations/201/availability/75012/2020-W10" Then the response status code should be 404 diff --git a/features/organization/children.feature b/features/organization/children.feature index a5de1fac..a6e0e7b2 100644 --- a/features/organization/children.feature +++ b/features/organization/children.feature @@ -1,36 +1,41 @@ Feature: In order to manage my children organizations, - As a parent organization, + As an admin of a parent organization, I must be able to list, edit and create them. - Scenario: As anonymous, I cannot list the children of an organization - When I go to "/organizations/201/children/" - Then I should be on "/organizations/login" - And the response status code should be 200 - - Scenario: As a parent organization, I can list the children of my organization - Given I am authenticated as "DT75" - When I go to "/organizations" + Scenario: As an admin of a parent organization, I can list the children of my organization + Given I am authenticated as "admin201@resop.com" + When I go to "/organizations/201" Then I should see "Modifier mes structures" When I follow "Modifier mes structures" Then I should be on "/organizations/201/children/" And the response status code should be 200 And I should see "UL 01-02" - Scenario: As an organization without children, I cannot list the children of my organization - Given I am authenticated as "UL 01-02" + Scenario: As an admin of an organization without children, I cannot list the children of my organization + Given I am authenticated as "admin203@resop.com" When I go to "/organizations/203" Then I should not see "Modifier mes structures" When I go to "/organizations/203/children/" And the response status code should be 403 - Scenario: As anonymous, I cannot create an organization - When I go to "/organizations/201/children/new" - Then I should be on "/organizations/login" - And the response status code should be 200 + Scenario: As an admin of an organization but without a password, I cannot list the children of my organization + Given I am authenticated as "admin203@resop.com" + When I go to "/organizations/203/children" + Then the response status code should be 403 + + Scenario Outline: As an admin of an organization, I cannot list the children of another organization + Given I am authenticated as "admin201@resop.com" + When I go to "" + Then the response status code should be 403 + Examples: + | url | + | /organizations/202/children | + | /organizations/203/children | + | /organizations/204/children | - Scenario: As a parent organization, I can create an organization - Given I am authenticated as "DT75" + Scenario: As an admin of a parent organization, I can create an organization + Given I am authenticated as "admin201@resop.com" And I am on "/organizations/201/children/" When I follow "Ajouter une structure" Then I should be on "/organizations/201/children/new" @@ -43,20 +48,20 @@ Feature: And I should see "La structure a été ajoutée avec succès." And I should see "Lorem ipsum" - Scenario: As a children organization, I cannot create an organization - Given I am authenticated as "UL 01-02" + Scenario: As an admin of a children organization, I cannot create an organization + Given I am authenticated as "admin203@resop.com" When I go to "/organizations/203" Then I should not see "Modifier mes structures" When I go to "/organizations/203/children/new" Then the response status code should be 403 - Scenario: As anonymous, I cannot update an organization - When I go to "/organizations/201/children/203/edit" - Then I should be on "/organizations/login" - And the response status code should be 200 + Scenario: As an admin of an organization, I cannot create an organization on another one + Given I am authenticated as "admin201@resop.com" + When I go to "/organizations/202/children/new" + Then the response status code should be 403 - Scenario: As a parent organization, I can update my children organizations - Given I am authenticated as "DT75" + Scenario: As an admin of a parent organization, I can update my children organizations + Given I am authenticated as "admin201@resop.com" And I am on "/organizations/201/children/" When I follow "Modifier" Then I should be on "/organizations/201/children/203/edit" @@ -70,7 +75,12 @@ Feature: And I should see "La structure a été mise à jour avec succès." And I should see "Lorem ipsum" - Scenario: As an organization, I cannot update an organization I don't have access to - Given I am authenticated as "DT75" - When I go to "/organizations/201/children/202/edit" + Scenario: As an admin of an organization, I cannot update an organization I don't have access to + Given I am authenticated as "admin201@resop.com" + When I go to "/organizations/201/children/204/edit" + Then the response status code should be 403 + + Scenario: As an admin of an organization, I cannot update my organization + Given I am authenticated as "admin203@resop.com" + When I go to "/organizations/201/children/203/edit" Then the response status code should be 403 diff --git a/features/organization/forecast.feature b/features/organization/forecast.feature index 0ed7eac7..0956020d 100644 --- a/features/organization/forecast.feature +++ b/features/organization/forecast.feature @@ -4,10 +4,6 @@ Feature: As an organization, I must be able to search for available users and assets. - Scenario: As anonymous, I cannot access to the forecast page - When I go to "/organizations/201/forecast/" - Then I should be on "/organizations/login" - Scenario: As an authenticated children organization, I cannot use the forecast search form Given I am authenticated as "UL 01-02" When I go to "/organizations/201/forecast/" diff --git a/features/organization/home.feature b/features/organization/home.feature new file mode 100644 index 00000000..aa46ffe3 --- /dev/null +++ b/features/organization/home.feature @@ -0,0 +1,41 @@ +Feature: + In order to manage an organization, + As an admin of an organization, + I must be able to log in to my organization. + + Scenario: As anonymous, I cannot manage an organization + When I go to "/organizations/201" + Then I should be on "/login" + And the response status code should be 200 + + Scenario: As an admin of an organization, I can go to the homepage of my organization + Given I am authenticated as "admin201@resop.com" + And I am on the homepage + When I follow "Gérer ma structure" + Then I should be on "/organizations/201" + And the response status code should be 200 + And I should see "DT75" + + Scenario Outline: As an admin of an organization but without a password, I cannot go to any page of my organization + Given I am authenticated as "admin203@resop.com" + When I go to "" + Then the response status code should be 403 + Examples: + | url | + | /organizations/203 | + | /organizations/203/new | + | /organizations/203/search | + | /organizations/203/edit | + | /organizations/203/assets | + | /organizations/203/users | + | /organizations/planning | + + Scenario Outline: As an admin of an organization, I cannot go to the homepage of another organization + Given I am authenticated as "admin201@resop.com" + When I go to "" + Then the response status code should be 403 + Examples: + | url | + | /organizations/2 | + | /organizations/203 | + | /organizations/204 | diff --git a/features/organization/login.feature b/features/organization/login.feature deleted file mode 100644 index adcc44c5..00000000 --- a/features/organization/login.feature +++ /dev/null @@ -1,28 +0,0 @@ -@login -Feature: - In order to manage my actions, - As an organization, - I must be able to log in. - - Scenario: As anonymous, I cannot access to the homepage - When I go to "/organizations" - Then I should be on "/organizations/login" - - Scenario Outline: As a registered organization, I can log in - Given I am on "/organizations/login" - When I select "" from "identifier" - And I fill in "password" with "covid19" - And I press "Je me connecte" - Then the response status code should be 200 - And I should be on "/organizations/" - And I should see "" - Examples: - | identifier | name | id | - | DT75 | DT75 | 201 | - | UL 01-02 | DT75 - UL 01-02 | 203 | - - Scenario: As an authenticated organization, I can log out - Given I am authenticated as "UL 01-02" - And I am on "/organizations/" - When I follow "Déconnexion" - Then I should be on "/organizations/login" diff --git a/features/organization/mission_type.feature b/features/organization/mission_type.feature index 04418622..fbb4d2dc 100644 --- a/features/organization/mission_type.feature +++ b/features/organization/mission_type.feature @@ -4,11 +4,6 @@ Feature: As an organization, I must be able to list, edit and delete mission types. - Scenario: As anonymous, I cannot list mission types from an organization - When I go to "/organizations/201/mission_type/new" - Then I should be on "/organizations/login" - And the response status code should be 200 - Scenario: As an organization, I can list my mission types Given I am authenticated as "DT75" And I am on "/organizations/201" diff --git a/features/organization/planning.feature b/features/organization/planning.feature index fcc50d94..74f1fca2 100644 --- a/features/organization/planning.feature +++ b/features/organization/planning.feature @@ -5,11 +5,6 @@ Feature: As an organization I must have access to the planning and I can filter what is displayed. - Scenario: As an anonymous, I cannot access the planning - Given I go to "/organizations/201/planning/" - Then I should be on "/organizations/login" - And the response status code should be 200 - Scenario: As an organization, I have access to the planning and I can see my resources Given I am authenticated as "UL 01-02" And I am on "/organizations/203" diff --git a/features/organization/search.feature b/features/organization/search.feature index 55d0bc4e..111d875d 100644 --- a/features/organization/search.feature +++ b/features/organization/search.feature @@ -4,12 +4,8 @@ Feature: As an organization I must be able to search users and assets - Scenario: As anonymous, I cannot access to the search page - When I go to "/organizations/201/search?query=foo" - Then I should be on "/organizations/login" - Scenario Outline: As an authenticated parent organization, I can search for a user even in my children - Given I am authenticated as "DT75" + Given I am authenticated as "admin201@resop.com" And I am on "/organizations/201" When I fill in "query" with " " And I press "Rechercher" @@ -20,36 +16,39 @@ Feature: And I should see "Aucun véhicule ne correspond à votre recherche." Examples: | search | email | identificationNumber | - | jOhN dOe reSOp | john.doe@resop.com | 990001A | - | jAnE dOe reSOp | jane.doe@resop.com | 990002A | + | jOhN dOe reSOp | admin201@resop.com | 990001A | + | jAnE dOe reSOp | admin203@resop.com | 990002A | - Scenario: As an authenticated children organization, I can search for a user in my organization - Given I am authenticated as "UL 01-02" + Scenario: As an admin of a children organization, I can search for a volunteer in my organization + Given I am authenticated as "admin203@resop.com" And I am on "/organizations/203" When I fill in "query" with " jAnE dOe reSOp " And I press "Rechercher" Then I should be on "/organizations/203/search" + And the response status code should be 200 And I should see "Rechercher \"jAnE dOe reSOp\"" And I should see "990002A" - And I should see "jane.doe@resop.com" + And I should see "admin203@resop.com" And I should see "Aucun véhicule ne correspond à votre recherche." - Scenario: As an authenticated organization, I cannot search for a user in another organization - Given I am authenticated as "UL 01-02" + Scenario: As an admin of an organization, I cannot search for a user in another organization + Given I am authenticated as "admin203@resop.com" And I am on "/organizations/203" When I fill in "query" with " cHuCk nOrRiS reSOp " And I press "Rechercher" Then I should be on "/organizations/203/search" + And the response status code should be 200 And I should see "Rechercher \"cHuCk nOrRiS reSOp\"" And I should see "Aucun bénévole ne correspond à votre recherche." And I should see "Aucun véhicule ne correspond à votre recherche." - Scenario Outline: As an authenticated parent organization, I can search for an asset even in my children - Given I am authenticated as "DT75" + Scenario Outline: As an admin of a parent organization, I can search for an asset even in my children + Given I am authenticated as "admin201@resop.com" And I am on "/organizations/201" When I fill in "query" with " " And I press "Rechercher" Then I should be on "/organizations/201/search" + And the response status code should be 200 And I should see "Rechercher \"\"" And I should see "" And I should see "" @@ -59,23 +58,25 @@ Feature: | 75992 | 75992 | VPSP | | 75012 | 75012 | VPSP | - Scenario: As an authenticated children organization, I can search for a user in my organization - Given I am authenticated as "UL 01-02" + Scenario: As an admin of a children organization, I can search for a user in my organization + Given I am authenticated as "admin203@resop.com" And I am on "/organizations/203" When I fill in "query" with " 75012 " And I press "Rechercher" Then I should be on "/organizations/203/search" + And the response status code should be 200 And I should see "Rechercher \"75012\"" And I should see "VPSP" And I should see "75012" And I should see "Aucun bénévole ne correspond à votre recherche." - Scenario: As an authenticated organization, I cannot search for a user in another organization - Given I am authenticated as "UL 01-02" + Scenario: As an admin of an organization, I cannot search for a user in another organization + Given I am authenticated as "admin203@resop.com" And I am on "/organizations/203" When I fill in "query" with " 77282 " And I press "Rechercher" Then I should be on "/organizations/203/search" + And the response status code should be 200 And I should see "Rechercher \"77282\"" And I should see "Aucun bénévole ne correspond à votre recherche." And I should see "Aucun véhicule ne correspond à votre recherche." diff --git a/features/organization/users.feature b/features/organization/users.feature index 7b0fb07e..76446193 100644 --- a/features/organization/users.feature +++ b/features/organization/users.feature @@ -1,28 +1,23 @@ @users Feature: In order to manage the users in my organization, - As an organization, + As an admin of an organization, I must be able to list, edit and delete users in my organization. - Scenario: As anonymous, I cannot list the users from an organization - When I go to "/organizations/1/users" - Then I should be on "/organizations/login" - And the response status code should be 200 - - Scenario: As an organization, I can list the users from my organization - Given I am authenticated as "DT75" + Scenario: As an admin of an organization, I can list the users from my organization + Given I am authenticated as "admin201@resop.com" And I am on "/organizations/201" When I follow "Afficher la liste de mes bénévoles inscrits" Then I should be on "/organizations/201/users/" And the response status code should be 200 - And I should see "john.doe@resop.com" - And I should not see "jane.doe@resop.com" + And I should see "admin201@resop.com" + And I should not see "admin203@resop.com" And I should not see "jill.doe@resop.com" And I should not see "chuck.norris@resop.com" - And I should not see "freddy.mercury@resop.com" + And I should not see "admin204@resop.com" - Scenario: As a parent organization, I can list the users from my children organizations - Given I am authenticated as "DT75" + Scenario: As an admin of a parent organization, I can list the users from my children organizations + Given I am authenticated as "admin201@resop.com" And I am on "/organizations/201" When I follow "Modifier mes structures" Then I should be on "/organizations/201/children/" @@ -30,18 +25,20 @@ Feature: When I follow "Liste des bénévoles" Then I should be on "/organizations/201/users/?organizationId=203" And the response status code should be 200 - And I should see "jane.doe@resop.com" - And I should not see "john.doe@resop.com" + And I should see "admin203@resop.com" + And I should see "jill.doe@resop.com" + And I should not see "admin201@resop.com" And I should not see "chuck.norris@resop.com" + And I should not see "admin204@resop.com" Scenario: As an admin of an organization, I cannot list the users from another organization - Given I am authenticated as "DT75" + Given I am authenticated as "admin201@resop.com" When I go to "/organizations/202/users" Then the response status code should be 403 @javascript - Scenario: As an organization, I can display a user modal - Given I am authenticated as "DT75" + Scenario: As an admin of an organization, I can display a user modal + Given I am authenticated as "admin201@resop.com" When I go to "/organizations/201/users/?organizationId=203" And I press "Afficher" And I wait for ".modal-show-user-inner" to be visible @@ -49,12 +46,14 @@ Feature: And I follow "Modifier" Then I should be on "/organizations/201/users/102/edit" - Scenario Outline: As an organization, I can update a user from my organization or children organizations + Scenario Outline: As an admin of an organization, I can update a user from my organization or children organizations Given I am authenticated as "" - When I go to "" + When I go to "" + And I follow "Modifier" + Then I should be on "" And the response status code should be 200 And the "user_identificationNumber" field should contain "990002A" - And the "user_emailAddress" field should contain "jane.doe@resop.com" + And the "user_emailAddress" field should contain "admin203@resop.com" And the "user_firstName" field should contain "Jane" And the "user_lastName" field should contain "DOE" When I fill in the following: @@ -96,10 +95,14 @@ Feature: | DT75 | /organizations/201/users/?organizationId=203 | /organizations/201/users/102/edit | | UL 01-02 | /organizations/203/users/ | /organizations/203/users/102/edit | - Scenario: As an admin of an organization, I cannot update a user from another organizations - Given I am authenticated as "DT75" - When I go to "/organizations/204/users/103/edit" + Scenario Outline: As an admin of an organization, I cannot update a user from another organizations + Given I am authenticated as "admin201@resop.com" + When I go to "" Then the response status code should be 403 + Examples: + | url | + | /organizations/201/users/103/edit | + | /organizations/204/users/103/edit | @javascript Scenario Outline: As an organization, I can delete a user from my organization or children organizations @@ -118,18 +121,61 @@ Feature: | UL 01-02 | /organizations/203/users/ | /organizations/203/users/102/edit | # Scenario: As an admin of an organization, I cannot directly delete a user from my organization -# Given I am authenticated as "john.doe@resop.com" +# Given I am authenticated as "admin201@resop.com" # When I go to "/organizations/201/users/3/delete?organizationId=203" # Then the response status code should be 405 Scenario: As an admin of an organization, I cannot delete a user from another organization - Given I am authenticated as "DT75" + Given I am authenticated as "admin201@resop.com" When I go to "/organizations/204/users" Then the response status code should be 403 When I go to "/organizations/204/users/103/delete" Then the response status code should be 403 Scenario: As an admin of an organization, I cannot access an invalid user - Given I am authenticated as "DT75" + Given I am authenticated as "admin201@resop.com" When I go to "/organizations/201/users/108/edit" Then the response status code should be 404 + + Scenario: As an admin of an organization, I cannot access a user with a mismatched url + Given I am authenticated as "admin201@resop.com" + When I go to "/organizations/201/users/2/edit" + Then the response status code should be 404 + + Scenario Outline: As an admin of an organization, I can promote a user as admin of an organization and this user has admin privilege + Given I am authenticated as "admin204@resop.com" + When I go to "" + And I follow "Promouvoir administrateur de UL DE BRIE ET CHANTEREINE" + Then I should be on "" + And the response status code should be 200 + And I should see "L'utilisateur \"\" a été promu administrateur de UL DE BRIE ET CHANTEREINE avec succès." + And I should see "Révoquer la fonction d'administrateur de UL DE BRIE ET CHANTEREINE" + Given I am authenticated as "" + When I go to "/organizations/204" + Then the response status code should be 200 + Examples: + | url | name | email | + | /organizations/204/users/105/edit | Chuck NORRIS | chuck.norris@resop.com | + | /organizations/204/users/101/edit | John DOE | admin201@resop.com | + + Scenario: As an admin of an organization, I can revoke user's admin privilege of an organization and this user doesn't have admin privilege anymore + Given I am authenticated as "admin202@resop.com" + When I go to "/organizations/204/users/4/edit" + And I follow "Révoquer la fonction d'administrateur de UL DE BRIE ET CHANTEREINE" + Then I should be on "/organizations/204/users/4/edit" + And the response status code should be 200 + And I should see "Le privilège d'administrateur pour la structure UL-DE-BRIE-ET-CHANTEREINE de \"Freddy MERCURY\" a été révoquée avec succès." + And I should see "Promouvoir administrateur de UL DE BRIE ET CHANTEREINE" + Given I am authenticated as "admin204@resop.com" + When I go to "/organizations/204" + Then the response status code should be 403 + + Scenario: As an admin of an organization, I cannot promote admin a user who is already admin + Given I am authenticated as "admin202@resop.com" + When I go to "/organizations/204/users/4/promote-admin" + Then the response status code should be 400 + + Scenario: As an admin of an organization, I cannot revoke a user who is not an admin + Given I am authenticated as "admin202@resop.com" + When I go to "/organizations/204/users/5/revoke-admin" + Then the response status code should be 400 diff --git a/features/user/edit.feature b/features/user/account.feature similarity index 89% rename from features/user/edit.feature rename to features/user/account.feature index 3899d265..8df47adf 100644 --- a/features/user/edit.feature +++ b/features/user/account.feature @@ -1,17 +1,20 @@ Feature: - In order to update my account - As a user - I must be able to edit my personal information + In order to update my account, + As a user, + I must be able to edit my personal information. Scenario: As anonymous, I cannot update an account When I go to "/user/edit" Then I should be on "/login" + And the response status code should be 200 Scenario: As a user, I can see my account - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin201@resop.com" When I go to "/user/edit" - Then the "user[identificationNumber]" field should contain "990001A" - And the "user[emailAddress]" field should contain "john.doe@resop.com" + Then I should be on "/user/edit" + And the response status code should be 200 + And the "user[identificationNumber]" field should contain "990001A" + And the "user[emailAddress]" field should contain "admin201@resop.com" And the "user[firstName]" field should contain "John" And the "user[lastName]" field should contain "DOE" And the "user[phoneNumber]" field should contain "06 12 34 56 78" @@ -25,7 +28,7 @@ Feature: And the "user[properties][occupation][choice]" field should contain "Pharmacien" Scenario: As a user, I cannot update my account with empty data - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin201@resop.com" And I am on "/user/edit" When I fill in the following: | user[identificationNumber] | | @@ -43,7 +46,7 @@ Feature: And I should see "Cette valeur ne doit pas être nulle." in the "label[for=user_phoneNumber] .form-error-message" element Scenario: As a user, I cannot update my account with invalid data - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin201@resop.com" And I am on "/user/edit" When I fill in the following: | user[identificationNumber] | invalid | @@ -57,7 +60,7 @@ Feature: And I should see "Cette valeur n'est pas un numéro de téléphone valide." in the "label[for=user_phoneNumber] .form-error-message" element Scenario: As a user, I can update my account - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin201@resop.com" And I am on "/user/edit" When I fill in the following: | user[identificationNumber] | 899999A | @@ -94,7 +97,7 @@ Feature: @javascript Scenario: As a user, I can update my occupation with a free text - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin201@resop.com" And I am on "/user/edit" When I check "Autre" Then I wait for "#user_properties_occupation_other" to be visible @@ -107,7 +110,7 @@ Feature: And the "user[properties][occupation][other]" field should contain "Plombier" Scenario Outline: As a user, I can update my email and login using the new email - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin201@resop.com" And I am on "/user/edit" When I fill in the following: | user[identificationNumber] | 899999A | @@ -115,6 +118,7 @@ Feature: | user[phoneNumber] | | And I press "Valider" Then I should be on "/" + And the response status code should be 200 And I should see "Vos informations ont été mises à jour avec succès." When I follow "Déconnexion" And I fill in the following: @@ -124,6 +128,7 @@ Feature: | user_login[birthday][year] | 1990 | And I press "Je me connecte" Then I should be on "/" + And the response status code should be 200 And I should see "NIVOL : 899999A" Examples: | login | phoneNumber | diff --git a/features/user/availabilities.feature b/features/user/availabilities.feature index 3769e880..1b8614ef 100644 --- a/features/user/availabilities.feature +++ b/features/user/availabilities.feature @@ -1,15 +1,16 @@ @availability Feature: - In order to fill in my availabilities - As a user - I must be able to create my account + In order to fill in my availabilities, + As a user, + I must be able to create my account. Scenario: As anonymous, I cannot go to user planning When I go to "/user/availability" Then I should be on "/login" + And the response status code should be 200 Scenario: As authenticated user, I can navigate through the planning weeks - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin203@resop.com" And I am on "/" When I follow "Semaine prochaine" Then the url should match "/user/availability" @@ -19,7 +20,7 @@ Feature: And the response status code should be 200 Scenario Outline: As authenticated user, I cannot add an availability on a booked/locked slot - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin203@resop.com" And I am on "/" When I follow "Semaine prochaine" Then the url should match "/user/availability" @@ -33,7 +34,7 @@ Feature: | next week monday 8 am | Scenario Outline: As authenticated user, I can add and remove an availability at any free slot in the future - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin203@resop.com" And I am on "/" When I follow "Semaine prochaine" # TODO Check the full url /user/availability/2020-W18 @@ -69,7 +70,7 @@ Feature: | next week sunday 10pm | Scenario Outline: As authenticated user, I can remove an availability at any available slot in the future - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin203@resop.com" And I am on "/" When I follow "Semaine prochaine" Then the url should match "/user/availability" diff --git a/features/user/login.feature b/features/user/login.feature index 502f2f68..9e6fab71 100644 --- a/features/user/login.feature +++ b/features/user/login.feature @@ -1,13 +1,58 @@ Feature: - In order to fill in my availabilities - As a user - I must be able to log in + In order to fill in my availabilities, + As a user, + I must be able to log in. - Scenario: As anonymous, I cannot access to the homepage + Scenario: As anonymous, I cannot go to the homepage When I go to the homepage Then I should be on "/login" + And the response status code should be 200 - Scenario Outline: As a registered user, I can log in + Scenario Outline: As a user with a password, I can log in with it + Given I am on "/login" + When I fill in the following: + | user_login[identifier] | | + | user_login[password] | covid19 | + And I press "Je me connecte" + Then I should be on "/" + And the response status code should be 200 + And I should see "NIVOL : 990001A" + Examples: + | login | + | admin201@resop.com | + | 990001A | + + Scenario Outline: As a user with a password, I cannot log in with an invalid one + Given I am on "/login" + When I fill in the following: + | user_login[identifier] | | + | user_login[password] | invalid | + And I press "Je me connecte" + Then I should be on "/login" + And the response status code should be 400 + And I should see "Veuillez saisir un numéro NIVOL ou une adresse e-mail valide, ou la date de naissance ne corresponds pas à ce NIVOL/email." + Examples: + | login | + | admin201@resop.com | + | 990001A | + + Scenario Outline: As a user with a password, I cannot log in with my birth date + Given I am on "/login" + When I fill in the following: + | user_login[identifier] | | + | user_login[birthday][day] | 01 | + | user_login[birthday][month] | 01 | + | user_login[birthday][year] | 1990 | + And I press "Je me connecte" + Then I should be on "/login" + And the response status code should be 400 + And I should see "Veuillez saisir un numéro NIVOL ou une adresse e-mail valide, ou la date de naissance ne corresponds pas à ce NIVOL/email." + Examples: + | login | + | admin201@resop.com | + | 990001A | + + Scenario Outline: As a user without a password, I can log in with my birth date Given I am on "/login" When I fill in the following: | user_login[identifier] | | @@ -16,17 +61,35 @@ Feature: | user_login[birthday][year] | 1990 | And I press "Je me connecte" Then I should be on "/" - And I should see "NIVOL : 990001A" + And the response status code should be 200 + And I should see "NIVOL : 990002A" + Examples: + | login | + | admin203@resop.com | + | 990001A | + + Scenario Outline: As a user without a password, I cannot log in with an invalid birth date + Given I am on "/login" + When I fill in the following: + | user_login[identifier] | | + | user_login[birthday][day] | 02 | + | user_login[birthday][month] | 02 | + | user_login[birthday][year] | 1992 | + And I press "Je me connecte" + Then I should be on "/login" + And the response status code should be 400 + And I should see "Veuillez saisir un numéro NIVOL ou une adresse e-mail valide, ou la date de naissance ne corresponds pas à ce NIVOL/email." Examples: | login | - | john.doe@resop.com | + | admin203@resop.com | | 990001A | Scenario: As an authenticated user, I can log out - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin201@resop.com" And I am on "/" When I follow "Déconnexion" Then I should be on "/login" + And the response status code should be 200 Scenario: As anonymous, when I try to log in with a non-existing account, I'm redirected to the registration page Given I am on "/login" @@ -37,9 +100,11 @@ Feature: | user_login[birthday][year] | 1990 | And I press "Je me connecte" Then I should be on "/user/new" + And the response status code should be 200 And the "user_emailAddress" field should contain "invalid@resop.com" Scenario: As anonymous, I cannot log in with empty data Given I am on "/login" When I press "Je me connecte" Then I should be on "/user/new" + And the response status code should be 200 diff --git a/features/user/password.feature b/features/user/password.feature new file mode 100644 index 00000000..d5d4c539 --- /dev/null +++ b/features/user/password.feature @@ -0,0 +1,102 @@ +Feature: + In order to update my password, + As a user, + I must be able to set my password. + + Scenario: As anonymous, I cannot set a password + When I go to "/user/password" + Then I should be on "/login" + And the response status code should be 200 + + Scenario: As an admin of an organization with no password set, I see a warning + Given I am authenticated as "admin203@resop.com" + When I go to "/" + Then I should see "Vous devez renseigner votre mot de passe afin d'administrer votre structure." + And the response status code should be 400 + + Scenario: As a user, I cannot update my password with empty data + Given I am authenticated as "admin203@resop.com" + And I am on "/user/password" + When I fill in the following: + | password[password][first] | | + | password[password][second] | | + And I press "Valider" + Then I should be on "/user/password" + And the response status code should be 400 + And I should see "Cette valeur ne doit pas être vide." in the "label[for=password_password_first] .form-error-message" element + And I should see "Cette valeur ne doit pas être vide." in the "label[for=password_password_second] .form-error-message" element + + Scenario: As a user, I cannot update my password with invalid data + Given I am authenticated as "admin203@resop.com" + And I am on "/user/password" + When I fill in the following: + | password[password][first] | foo | + | password[password][second] | bar | + And I press "Valider" + Then I should be on "/user/password" + And the response status code should be 400 + And I should see "Les mots de passe ne correspondent pas." in the "label[for=password_password_first] .form-error-message" element + + Scenario Outline: As a user with a password, I cannot update it with an empty or invalid current one + Given I am authenticated as "admin201@resop.com" + And I am on "/user/password" + When I fill in the following: + | password[current] | | + | password[password][first] | foo | + | password[password][second] | foo | + And I press "Valider" + Then I should be on "/user/password" + And the response status code should be 400 + And I should see "" in the "label[for=password_current] .form-error-message" element + Examples: + | value | message | + | | Cette valeur ne doit pas être vide. | + | invalid | Cette valeur est invalide. | + + Scenario Outline: As a user with a password, I can update it + Given I am authenticated as "admin201@resop.com" + And I am on "/user/password" + When I fill in the following: + | password[current] | covid19 | + | password[password][first] | covid20 | + | password[password][second] | covid20 | + And I press "Valider" + Then I should be on "/" + And the response status code should be 200 + And I should see "Votre mot de passe a été mis à jour avec succès." + When I follow "Déconnexion" + And I fill in the following: + | user_login[identifier] | | + | user_login[password] | covid20 | + And I press "Je me connecte" + Then I should be on "/" + And the response status code should be 200 + And I should see "NIVOL : 990001A" + Examples: + | login | + | admin201@resop.com | + | 990001A | + + Scenario Outline: As a user without a password, I can set it + Given I am authenticated as "admin203@resop.com" + And I am on "/user/password" + When I fill in the following: + | password[current] | | + | password[password][first] | covid20 | + | password[password][second] | covid20 | + And I press "Valider" + Then I should be on "/" + And the response status code should be 200 + And I should see "Votre mot de passe a été mis à jour avec succès." + When I follow "Déconnexion" + And I fill in the following: + | user_login[identifier] | | + | user_login[password] | covid20 | + And I press "Je me connecte" + Then I should be on "/" + And the response status code should be 200 + And I should see "NIVOL : 990002A" + Examples: + | login | + | admin203@resop.com | + | 990002A | diff --git a/features/user/register.feature b/features/user/register.feature index 06da263c..fd21d679 100644 --- a/features/user/register.feature +++ b/features/user/register.feature @@ -1,12 +1,13 @@ Feature: - In order to fill in my availabilities - As a user - I must be able to create my account + In order to fill in my availabilities, + As a user, + I must be able to create my account. Scenario: As authenticated user, I cannot create an account - Given I am authenticated as "john.doe@resop.com" + Given I am authenticated as "admin201@resop.com" When I go to "/user/new" Then I should be on "/" + And the response status code should be 200 Scenario: As anonymous, I cannot create an account with already registered email address Given I am on "/user/new" @@ -14,13 +15,13 @@ Feature: | user[identificationNumber] | 999999A | | user[firstName] | John | | user[lastName] | DOE | - | user[emailAddress] | john.doe@resop.com | + | user[emailAddress] | admin201@resop.com | | user[phoneNumber] | 0612345678 | And I select "UL 01-02" from "user[organization]" And I check "Maraudeur.se" And I press "Valider" - Then the response status code should be 400 - And I should be on "/user/new" + Then I should be on "/user/new" + And the response status code should be 400 And I should see "Cette valeur est déjà utilisée." Scenario: As anonymous, I cannot create an account with already registered identification number @@ -34,8 +35,8 @@ Feature: And I select "UL 01-02" from "user[organization]" And I check "Maraudeur.se" And I press "Valider" - Then the response status code should be 400 - And I should be on "/user/new" + Then I should be on "/user/new" + And the response status code should be 400 And I should see "Cette valeur est déjà utilisée." Scenario: As anonymous, I can create an account with valid data @@ -51,6 +52,7 @@ Feature: And I press "Valider" Then the response status code should be 200 And I should be on "/" + And the response status code should be 200 And I should see "Votre compte utilisateur a été créé avec succès." And I should see "Bienvenue, Archibald HADDOCK" And I should see "NIVOL : 999999A" diff --git a/fixtures/users.yaml b/fixtures/users.yaml index a44acb62..6f00266c 100644 --- a/fixtures/users.yaml +++ b/fixtures/users.yaml @@ -1,34 +1,99 @@ App\Entity\User: + # John DOE is admin of DT75. He is not volunteer. + # As organization admin, his password is required. User.john_doe: id: 101 firstName: John lastName: DOE organization: '@Organization.DT75' identificationNumber: 990001A - emailAddress (unique): john.doe@resop.com + emailAddress (unique): admin201@resop.com + plainPassword: covid19 phoneNumber: '' birthday: '1990-01-01' skillSet: '' properties: {"occupation": "Pharmacien", "organizationOccupation": "Secouriste", "vulnerable": true, "fullyEquipped": true, "drivingLicence": true} + organizations: ['@Organization.DT75'] + roles: ['ROLE_USER'] + + # Jane DOE is volunteer and admin of UL 01-02, an organization children of DT75 managed by John DOE. + # As organization admin, her password is required, but she didn't filled it yet. User.jane_doe: id: 102 firstName: Jane lastName: DOE organization: '@Organization.UL-01-02' identificationNumber: 990002A - emailAddress (unique): jane.doe@resop.com + emailAddress (unique): admin203@resop.com phoneNumber: '' birthday: '1990-01-01' skillSet: '' properties: {"occupation": "", "organizationOccupation": "Secouriste", "vulnerable": , "fullyEquipped": , "drivingLicence": } - User.chuck_norris: + organizations: ['@Organization.UL-01-02'] + roles: ['ROLE_VOLUNTEER'] + + # Jill DOE is volunteer of UL 01-02, an organization children of DT75 managed by John DOE. + # As volunteer, she doesn't any password, and connects using her birth date. + User.jill_doe: id: 103 + firstName: Jill + lastName: DOE + organization: '@Organization.UL-01-02' + identificationNumber: 990003A + emailAddress (unique): jill.doe@resop.com + phoneNumber: '' + birthday: '1990-01-01' + skillSet: '' + properties: {"occupation": "", "organizationOccupation": "Secouriste", "vulnerable": , "fullyEquipped": , "drivingLicence": } + roles: ['ROLE_VOLUNTEER'] + + # Freddy MERCURY is volunteer in Organization.UL-DE-BRIE-ET-CHANTEREINE, and admin of UL DE BRIE ET CHANTEREINE, + # an organization children of DT77 managed Lady GAGA. + # As organization admin, his password is required. + User.freddy_mercury: + id: 104 + firstName: Freddy + lastName: MERCURY + organization: '@Organization.UL-DE-BRIE-ET-CHANTEREINE' + identificationNumber: 990004A + emailAddress (unique): admin204@resop.com + plainPassword: covid19 + phoneNumber: '' + birthday: '1990-01-01' + skillSet: '' + properties: {"occupation": "", "organizationOccupation": "Secouriste", "vulnerable": , "fullyEquipped": , "drivingLicence": } + organizations: ['@Organization.UL-DE-BRIE-ET-CHANTEREINE'] + roles: ['ROLE_VOLUNTEER'] + + # Chuck NORRIS is volunteer in UL DE BRIE ET CHANTEREINE, an organization children of DT77 managed by Lady GAGA. + # Because he has a password, he has to connect using it. + User.chuck_norris: + id: 105 firstName: Chuck lastName: NORRIS organization: '@Organization.UL-DE-BRIE-ET-CHANTEREINE' - identificationNumber: 990003A + identificationNumber: 990005A emailAddress (unique): chuck.norris@resop.com + plainPassword: covid19 + phoneNumber: '' + birthday: '1990-01-01' + skillSet: '' + properties: {"occupation": "", "organizationOccupation": "Secouriste", "vulnerable": , "fullyEquipped": , "drivingLicence": } + roles: ['ROLE_VOLUNTEER'] + + # Lady GAGA is admin of DT77. She is not volunteer. + # As organization admin, her password is required. + User.lady.gaga: + id: 106 + firstName: Lady + lastName: GAGA + organization: '@Organization.DT77' + identificationNumber: 990006A + emailAddress (unique): admin202@resop.com + plainPassword: covid19 phoneNumber: '' birthday: '1990-01-01' skillSet: '' properties: {"occupation": "", "organizationOccupation": "Secouriste", "vulnerable": , "fullyEquipped": , "drivingLicence": } + organizations: ['@Organization.DT77'] + roles: ['ROLE_USER'] diff --git a/symfony.lock b/symfony.lock index c38243b0..b2abbc31 100644 --- a/symfony.lock +++ b/symfony.lock @@ -8,6 +8,9 @@ "behat/gherkin": { "version": "v4.6.2" }, + "behat/mink-selenium2-driver": { + "version": "v1.4.0" + }, "behat/transliterator": { "version": "v1.3.0" }, @@ -200,6 +203,9 @@ "fixtures/.gitignore" ] }, + "instaclick/php-webdriver": { + "version": "1.4.7" + }, "jdorn/sql-formatter": { "version": "v1.2.17" },