2024-04-29 00:17:15 +02:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2021-10-26 11:44:53 +02:00
|
|
|
require 'system/users/dossier_shared_examples.rb'
|
2018-08-01 17:27:50 +02:00
|
|
|
|
2021-10-26 11:44:53 +02:00
|
|
|
describe 'Invitations' do
|
2018-09-24 16:10:50 +02:00
|
|
|
let(:owner) { create(:user) }
|
2018-08-01 17:27:50 +02:00
|
|
|
let(:invited_user) { create(:user, email: 'user_invite@exemple.fr') }
|
2018-09-24 15:54:46 +02:00
|
|
|
let(:procedure) { create(:simple_procedure) }
|
2018-10-10 09:23:08 +02:00
|
|
|
let(:invite) { create(:invite, user: invited_user, dossier: dossier) }
|
2018-08-01 17:27:50 +02:00
|
|
|
|
|
|
|
context 'when the dossier is a brouillon' do
|
2020-01-07 17:47:22 +01:00
|
|
|
let!(:dossier) { create(:dossier, :with_individual, state: Dossier.states.fetch(:brouillon), user: owner, procedure: procedure) }
|
2018-08-01 17:27:50 +02:00
|
|
|
|
2023-11-06 15:15:51 +01:00
|
|
|
scenario 'on the form, the owner of a dossier can invite another user to collaborate on the dossier', js: true do
|
2018-09-24 16:10:50 +02:00
|
|
|
log_in(owner)
|
2018-08-01 17:27:50 +02:00
|
|
|
navigate_to_brouillon(dossier)
|
2018-09-24 15:54:46 +02:00
|
|
|
fill_in 'Texte obligatoire', with: 'Some edited value'
|
2018-08-01 17:27:50 +02:00
|
|
|
send_invite_to "user_invite@exemple.fr"
|
2018-09-06 09:09:23 +02:00
|
|
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
2018-08-01 17:27:50 +02:00
|
|
|
expect(page).to have_text("Une invitation a été envoyée à user_invite@exemple.fr.")
|
|
|
|
expect(page).to have_text("user_invite@exemple.fr")
|
2018-07-31 17:26:08 +02:00
|
|
|
|
|
|
|
# Ensure unsaved edits to the form are not lost
|
2018-09-24 15:54:46 +02:00
|
|
|
expect(page).to have_field('Texte obligatoire', with: 'Some edited value')
|
2018-08-01 17:27:50 +02:00
|
|
|
end
|
|
|
|
|
2018-09-18 16:54:37 +02:00
|
|
|
context 'when inviting someone without an existing account' do
|
2018-10-10 09:23:08 +02:00
|
|
|
let(:invite) { create(:invite, dossier: dossier, user: nil) }
|
2022-06-13 16:00:41 +02:00
|
|
|
|
|
|
|
scenario 'an invited user can register using the targeted_user_link sent in the invitation email thru the ' do
|
|
|
|
log_in(owner)
|
|
|
|
navigate_to_brouillon(dossier)
|
|
|
|
|
|
|
|
fill_in 'Texte obligatoire', with: 'Some edited value'
|
|
|
|
|
|
|
|
send_invite_to "user_invite@exemple.fr"
|
|
|
|
|
|
|
|
expect {
|
|
|
|
perform_enqueued_jobs
|
|
|
|
}.to change { TargetedUserLink.count }.from(0).to(1)
|
|
|
|
|
|
|
|
invitation_email = open_email("user_invite@exemple.fr")
|
|
|
|
targeted_user_link = TargetedUserLink.last
|
|
|
|
expect(invitation_email).to have_link(targeted_user_link_url(targeted_user_link))
|
|
|
|
invitation_email.click_on targeted_user_link_url(targeted_user_link)
|
|
|
|
expect(page).to have_current_path("/users/sign_up?user%5Bemail%5D=user_invite%40exemple.fr")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when inviting someone with an existing account' do
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
|
|
|
|
scenario 'an invited user can sign in using the targeted_user_link link sent in the invitation email' do
|
|
|
|
log_in(owner)
|
|
|
|
navigate_to_brouillon(dossier)
|
|
|
|
|
|
|
|
fill_in 'Texte obligatoire', with: 'Some edited value'
|
|
|
|
send_invite_to user.email
|
|
|
|
|
|
|
|
expect {
|
|
|
|
perform_enqueued_jobs
|
|
|
|
}.to change { TargetedUserLink.count }.from(0).to(1)
|
|
|
|
|
|
|
|
invitation_email = open_email(user.email)
|
|
|
|
targeted_user_link = TargetedUserLink.last
|
2023-01-31 15:51:30 +01:00
|
|
|
expect(targeted_user_link.user.email).to eq(user.email)
|
2022-06-13 16:00:41 +02:00
|
|
|
expect(invitation_email).to have_link(targeted_user_link_url(targeted_user_link))
|
|
|
|
invitation_email.click_on targeted_user_link_url(targeted_user_link)
|
|
|
|
expect(page).to have_current_path("/users/sign_in")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when visiting targeted_user_link having an invite without user, but signed with another account' do
|
|
|
|
let(:invite) { create(:invite, user: nil, email: 'target@email.com') }
|
|
|
|
let!(:targeted_user_link) { create(:targeted_user_link, target_context: 'invite', target_model: invite) }
|
|
|
|
let!(:another_user) { create(:user) }
|
|
|
|
|
|
|
|
scenario 'the connected user is alterted he is not using the expected account' do
|
|
|
|
log_in(another_user)
|
|
|
|
visit targeted_user_link_path(targeted_user_link)
|
|
|
|
expect(page).to have_current_path(targeted_user_link_path(targeted_user_link))
|
|
|
|
expect(page).to have_content("L'invitation est à destination de #{targeted_user_link.target_email}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when visiting targeted_user_link having an invite with user, but signed with another account' do
|
|
|
|
let(:invite) { create(:invite, user: create(:user)) }
|
|
|
|
let!(:targeted_user_link) { create(:targeted_user_link, target_context: 'invite', target_model: invite, user: invite.user) }
|
|
|
|
let!(:another_user) { create(:user) }
|
|
|
|
|
|
|
|
scenario 'the connected user is alterted he is not using the expected account' do
|
|
|
|
log_in(another_user)
|
|
|
|
visit targeted_user_link_path(targeted_user_link)
|
|
|
|
expect(page).to have_current_path(targeted_user_link_path(targeted_user_link))
|
|
|
|
expect(page).to have_content("L'invitation est à destination de #{targeted_user_link.target_email}")
|
2018-09-18 16:54:37 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-11-06 15:15:51 +01:00
|
|
|
scenario 'an invited user can see and edit the draft', js: true do
|
2018-09-24 16:22:37 +02:00
|
|
|
navigate_to_invited_dossier(invite)
|
2018-09-06 09:09:23 +02:00
|
|
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
2018-09-24 16:22:37 +02:00
|
|
|
|
2018-08-01 17:27:50 +02:00
|
|
|
expect(page).to have_no_selector('.button.invite-user-action')
|
|
|
|
|
2018-09-24 15:54:46 +02:00
|
|
|
fill_in 'Texte obligatoire', with: 'Some edited value'
|
2020-09-15 13:38:45 +02:00
|
|
|
blur
|
2018-09-24 15:54:46 +02:00
|
|
|
expect(page).to have_field('Texte obligatoire', with: 'Some edited value')
|
2018-08-01 17:27:50 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
scenario 'an invited user cannot submit the draft' do
|
2018-09-24 16:22:37 +02:00
|
|
|
navigate_to_invited_dossier(invite)
|
2018-09-06 09:09:23 +02:00
|
|
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
2018-08-01 17:27:50 +02:00
|
|
|
|
2019-07-15 16:10:34 +02:00
|
|
|
expect(page).to have_button('Déposer le dossier', disabled: true)
|
2018-08-01 17:27:50 +02:00
|
|
|
expect(page).to have_selector('.invite-cannot-submit')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-09-24 16:23:53 +02:00
|
|
|
context 'when the dossier is en_construction' do
|
2020-01-07 17:47:22 +01:00
|
|
|
let!(:dossier) { create(:dossier, :with_individual, :en_construction, user: owner, procedure: procedure) }
|
2018-09-24 16:23:53 +02:00
|
|
|
|
2023-11-06 15:15:51 +01:00
|
|
|
scenario 'on dossier details, the owner of a dossier can invite another user to collaborate on the dossier', js: true do
|
2018-09-24 16:23:53 +02:00
|
|
|
log_in(owner)
|
|
|
|
navigate_to_dossier(dossier)
|
|
|
|
|
|
|
|
send_invite_to "user_invite@exemple.fr"
|
|
|
|
|
|
|
|
expect(page).to have_current_path(dossier_path(dossier))
|
|
|
|
expect(page).to have_text("Une invitation a été envoyée à user_invite@exemple.fr.")
|
|
|
|
expect(page).to have_text("user_invite@exemple.fr")
|
|
|
|
end
|
|
|
|
|
2023-11-06 15:15:51 +01:00
|
|
|
context 'as an invited user', js: true do
|
2018-09-24 16:23:53 +02:00
|
|
|
before do
|
|
|
|
navigate_to_invited_dossier(invite)
|
|
|
|
expect(page).to have_current_path(dossier_path(invite.dossier))
|
|
|
|
end
|
|
|
|
|
|
|
|
it_behaves_like 'the user can edit the submitted demande'
|
|
|
|
it_behaves_like 'the user can send messages to the instructeur'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-07-11 11:03:02 +02:00
|
|
|
describe 'recherche' do
|
|
|
|
context "when user has one invited dossier" do
|
|
|
|
let!(:dossier) { create(:dossier, :with_individual, :en_construction, user: owner, procedure: procedure) }
|
|
|
|
let!(:invite) { create(:invite, user: invited_user, dossier: dossier) }
|
|
|
|
before do
|
|
|
|
navigate_to_invited_dossier(invite)
|
|
|
|
visit dossiers_path
|
|
|
|
end
|
|
|
|
|
|
|
|
it "does not have access to search bar" do
|
|
|
|
expect(page).not_to have_selector('#q')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when user has multiple invited dossiers" do
|
|
|
|
let(:dossier) { create(:dossier, :with_individual, :en_construction, user: owner, procedure: procedure) }
|
|
|
|
let!(:dossier_2) { create(:dossier, :with_individual, :with_populated_champs, :en_construction, user: owner, procedure: procedure) }
|
|
|
|
let!(:invite_2) { create(:invite, user: invited_user, dossier: dossier_2) }
|
|
|
|
let!(:dossier_3) { create(:dossier, :with_individual, :en_construction, user: owner, procedure: procedure) }
|
|
|
|
let!(:invite_3) { create(:invite, user: invited_user, dossier: dossier_3) }
|
|
|
|
before do
|
|
|
|
navigate_to_invited_dossier(invite)
|
|
|
|
visit dossiers_path
|
2024-04-25 17:57:55 +02:00
|
|
|
perform_enqueued_jobs(only: DossierIndexSearchTermsJob)
|
2023-07-11 11:03:02 +02:00
|
|
|
end
|
|
|
|
|
2023-07-27 10:01:59 +02:00
|
|
|
it "can search by id and it displays the dossier" do
|
2023-07-11 11:03:02 +02:00
|
|
|
page.find_by_id('q').set(dossier.id)
|
|
|
|
find('.fr-search-bar .fr-btn').click
|
2023-07-27 10:01:59 +02:00
|
|
|
expect(current_path).to eq(dossiers_path)
|
|
|
|
expect(page).to have_link(dossier.procedure.libelle)
|
2023-07-11 11:03:02 +02:00
|
|
|
end
|
|
|
|
|
2023-07-27 10:01:59 +02:00
|
|
|
it "can search something inside the dossier and it displays the dossier" do
|
2023-07-11 11:03:02 +02:00
|
|
|
page.find_by_id('q').set(dossier_2.champs_public.first.value)
|
|
|
|
find('.fr-search-bar .fr-btn').click
|
2023-07-27 10:01:59 +02:00
|
|
|
expect(current_path).to eq(dossiers_path)
|
|
|
|
expect(page).to have_link(dossier.procedure.libelle)
|
2023-07-11 11:03:02 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-08-01 17:27:50 +02:00
|
|
|
private
|
|
|
|
|
|
|
|
def log_in(user)
|
2022-08-31 12:44:00 +02:00
|
|
|
visit new_user_session_path
|
2018-11-06 17:06:45 +01:00
|
|
|
sign_in_with(user.email, user.password)
|
2018-08-01 17:27:50 +02:00
|
|
|
expect(page).to have_current_path(dossiers_path)
|
|
|
|
end
|
|
|
|
|
|
|
|
def navigate_to_brouillon(dossier)
|
|
|
|
expect(page).to have_current_path(dossiers_path)
|
2023-06-28 12:48:47 +02:00
|
|
|
click_on(dossier.procedure.libelle)
|
2018-09-06 09:09:23 +02:00
|
|
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
2018-09-24 16:23:53 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def navigate_to_dossier(dossier)
|
|
|
|
expect(page).to have_current_path(dossiers_path)
|
2023-06-28 12:48:47 +02:00
|
|
|
click_on(dossier.procedure.libelle)
|
2018-09-24 16:23:53 +02:00
|
|
|
expect(page).to have_current_path(dossier_path(dossier))
|
2018-08-01 17:27:50 +02:00
|
|
|
end
|
|
|
|
|
2018-09-24 16:22:37 +02:00
|
|
|
def navigate_to_invited_dossier(invite)
|
2018-11-13 16:18:52 +01:00
|
|
|
visit invite_path(invite)
|
2018-09-24 16:22:37 +02:00
|
|
|
expect(page).to have_current_path(new_user_session_path)
|
2018-11-06 17:06:45 +01:00
|
|
|
sign_in_with(invited_user.email, invited_user.password)
|
2018-09-24 16:22:37 +02:00
|
|
|
end
|
|
|
|
|
2018-08-01 17:27:50 +02:00
|
|
|
def send_invite_to(invited_email)
|
2018-09-11 17:51:44 +02:00
|
|
|
click_on "Inviter une personne à modifier ce dossier"
|
2018-08-01 17:27:50 +02:00
|
|
|
expect(page).to have_button("Envoyer une invitation", visible: true)
|
|
|
|
|
|
|
|
fill_in 'invite_email', with: invited_email
|
|
|
|
click_on "Envoyer une invitation"
|
|
|
|
end
|
|
|
|
end
|