Merge pull request #7462 from betagouv/US/invite-with-targeted-user-link
feat(invite): wrap invitations with targeted_user_links
This commit is contained in:
commit
73becb9c76
17 changed files with 251 additions and 70 deletions
|
@ -5,7 +5,6 @@ class InvitesController < ApplicationController
|
||||||
def create
|
def create
|
||||||
email = params[:invite_email].downcase
|
email = params[:invite_email].downcase
|
||||||
@dossier = current_user.dossiers.visible_by_user.find(params[:dossier_id])
|
@dossier = current_user.dossiers.visible_by_user.find(params[:dossier_id])
|
||||||
|
|
||||||
invite = Invite.create(
|
invite = Invite.create(
|
||||||
dossier: @dossier,
|
dossier: @dossier,
|
||||||
user: User.find_by(email: email),
|
user: User.find_by(email: email),
|
||||||
|
|
|
@ -11,6 +11,6 @@ class TargetedUserLinksController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_targeted_user_link
|
def set_targeted_user_link
|
||||||
@targeted_user_link = TargetedUserLink.find_by(id: params[:id])
|
@targeted_user_link = TargetedUserLink.find(params[:id])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,10 @@ class InviteMailer < ApplicationMailer
|
||||||
|
|
||||||
def invite_user(invite)
|
def invite_user(invite)
|
||||||
subject = "Participez à l'élaboration d’un dossier"
|
subject = "Participez à l'élaboration d’un dossier"
|
||||||
|
targeted_user_link = invite.targeted_user_link || invite.create_targeted_user_link(target_context: 'invite',
|
||||||
|
target_model: invite,
|
||||||
|
user: invite.user)
|
||||||
|
@url = targeted_user_link_url(targeted_user_link)
|
||||||
if invite.user.present?
|
if invite.user.present?
|
||||||
send_mail(invite, subject, invite.email_sender)
|
send_mail(invite, subject, invite.email_sender)
|
||||||
end
|
end
|
||||||
|
@ -12,6 +15,9 @@ class InviteMailer < ApplicationMailer
|
||||||
|
|
||||||
def invite_guest(invite)
|
def invite_guest(invite)
|
||||||
subject = "#{invite.email_sender} vous invite à consulter un dossier"
|
subject = "#{invite.email_sender} vous invite à consulter un dossier"
|
||||||
|
targeted_user_link = invite.targeted_user_link || invite.create_targeted_user_link(target_context: 'invite',
|
||||||
|
target_model: invite)
|
||||||
|
@url = targeted_user_link_url(targeted_user_link)
|
||||||
|
|
||||||
send_mail(invite, subject, invite.email_sender)
|
send_mail(invite, subject, invite.email_sender)
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,6 +16,7 @@ class Invite < ApplicationRecord
|
||||||
|
|
||||||
belongs_to :dossier, optional: false
|
belongs_to :dossier, optional: false
|
||||||
belongs_to :user, optional: true
|
belongs_to :user, optional: true
|
||||||
|
has_one :targeted_user_link, dependent: :destroy, inverse_of: :target_model, foreign_key: 'target_model_id'
|
||||||
|
|
||||||
before_validation -> { sanitize_email(:email) }
|
before_validation -> { sanitize_email(:email) }
|
||||||
|
|
||||||
|
|
|
@ -8,20 +8,36 @@
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# target_model_id :bigint not null
|
# target_model_id :bigint not null
|
||||||
# user_id :bigint not null
|
# user_id :bigint
|
||||||
#
|
#
|
||||||
class TargetedUserLink < ApplicationRecord
|
class TargetedUserLink < ApplicationRecord
|
||||||
belongs_to :user
|
belongs_to :user, optional: true
|
||||||
belongs_to :target_model, polymorphic: true, optional: false
|
belongs_to :target_model, polymorphic: true, optional: false
|
||||||
|
|
||||||
enum target_context: { :avis => 'avis' }
|
enum target_context: { avis: 'avis', invite: 'invite' }
|
||||||
|
|
||||||
def invalid_signed_in_user?(signed_in_user)
|
def invalid_signed_in_user?(signed_in_user)
|
||||||
signed_in_user && signed_in_user != self.user
|
signed_in_user && signed_in_user != self.user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def target_email
|
||||||
|
case target_context
|
||||||
|
when 'avis'
|
||||||
|
user.email
|
||||||
|
when 'invite'
|
||||||
|
target_model.user&.email || target_model.email
|
||||||
|
else
|
||||||
|
raise 'invalid target_context'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def redirect_url(url_helper)
|
def redirect_url(url_helper)
|
||||||
case target_context
|
case target_context
|
||||||
|
when "invite"
|
||||||
|
invite = target_model
|
||||||
|
invite.user&.active? ?
|
||||||
|
url_helper.invite_path(invite) :
|
||||||
|
url_helper.invite_path(invite, params: { email: invite.email })
|
||||||
when "avis"
|
when "avis"
|
||||||
avis = target_model
|
avis = target_model
|
||||||
avis.expert.user.active? ?
|
avis.expert.user.active? ?
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
Afin de répondre à cette invitation, merci de vous inscrire avec l'adresse email
|
Afin de répondre à cette invitation, merci de vous inscrire avec l'adresse email
|
||||||
= @invite.email
|
= @invite.email
|
||||||
sur
|
sur
|
||||||
- url_for_link = invite_url(@invite, params: { email: @invite.email })
|
= link_to @url, @url
|
||||||
= link_to url_for_link, url_for_link
|
|
||||||
|
|
||||||
= render partial: "layouts/mailers/signature"
|
= render partial: "layouts/mailers/signature"
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
%p
|
%p
|
||||||
Pour le consulter, merci de suivre ce lien :
|
Pour le consulter, merci de suivre ce lien :
|
||||||
- url_for_link = invite_url(@invite)
|
= link_to @url, @url
|
||||||
= link_to url_for_link, url_for_link
|
|
||||||
|
|
||||||
= render partial: "layouts/mailers/signature"
|
= render partial: "layouts/mailers/signature"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
%h1.mt-4.mb-3.mx-0 Attention, ce lien ne vous est pas destiné
|
%h1.mt-4.mb-3.mx-0 Attention, ce lien ne vous est pas destiné
|
||||||
%p.send.m-2.text-lg
|
%p.send.m-2.text-lg
|
||||||
L'invitation est à destination de
|
L'invitation est à destination de
|
||||||
%strong.test-target-email= @targeted_user_link.user.email
|
%strong.test-target-email= @targeted_user_link.target_email
|
||||||
%br
|
%br
|
||||||
Mais vous êtes connecté avec
|
Mais vous êtes connecté avec
|
||||||
%strong.test-current-email= current_user.email
|
%strong.test-current-email= current_user.email
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"type": "controller",
|
"type": "controller",
|
||||||
"class": "Users::DossiersController",
|
"class": "Users::DossiersController",
|
||||||
"method": "merci",
|
"method": "merci",
|
||||||
"line": 206,
|
"line": 204,
|
||||||
"file": "app/controllers/users/dossiers_controller.rb",
|
"file": "app/controllers/users/dossiers_controller.rb",
|
||||||
"rendered": {
|
"rendered": {
|
||||||
"name": "users/dossiers/merci",
|
"name": "users/dossiers/merci",
|
||||||
|
@ -95,20 +95,20 @@
|
||||||
{
|
{
|
||||||
"warning_type": "Redirect",
|
"warning_type": "Redirect",
|
||||||
"warning_code": 18,
|
"warning_code": 18,
|
||||||
"fingerprint": "8396f884c5596d6c1148c7326b63e7e7bfabf9b0c1daf6b3ce0c1ff127b59cb4",
|
"fingerprint": "589e457617e6ad3d35f454b4af8ed326817930d6a724febcf680d7e03c6aeaa2",
|
||||||
"check_name": "Redirect",
|
"check_name": "Redirect",
|
||||||
"message": "Possible unprotected redirect",
|
"message": "Possible unprotected redirect",
|
||||||
"file": "app/controllers/targeted_user_links_controller.rb",
|
"file": "app/controllers/targeted_user_links_controller.rb",
|
||||||
"line": 7,
|
"line": 7,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
|
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
|
||||||
"code": "redirect_to(TargetedUserLink.find_by(:id => params[:id]).redirect_url(Rails.application.routes.url_helpers))",
|
"code": "redirect_to(TargetedUserLink.find(params[:id]).redirect_url(Rails.application.routes.url_helpers))",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
"location": {
|
"location": {
|
||||||
"type": "method",
|
"type": "method",
|
||||||
"class": "TargetedUserLinksController",
|
"class": "TargetedUserLinksController",
|
||||||
"method": "show"
|
"method": "show"
|
||||||
},
|
},
|
||||||
"user_input": "TargetedUserLink.find_by(:id => params[:id]).redirect_url(Rails.application.routes.url_helpers)",
|
"user_input": "TargetedUserLink.find(params[:id]).redirect_url(Rails.application.routes.url_helpers)",
|
||||||
"confidence": "High",
|
"confidence": "High",
|
||||||
"note": ""
|
"note": ""
|
||||||
},
|
},
|
||||||
|
@ -119,7 +119,7 @@
|
||||||
"check_name": "SQL",
|
"check_name": "SQL",
|
||||||
"message": "Possible SQL injection",
|
"message": "Possible SQL injection",
|
||||||
"file": "app/models/concerns/dossier_filtering_concern.rb",
|
"file": "app/models/concerns/dossier_filtering_concern.rb",
|
||||||
"line": 18,
|
"line": 25,
|
||||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||||
"code": "where(\"#{values.count} OR #{\"(#{ProcedurePresentation.sanitized_column(table, column)} ILIKE ?)\"}\", *values.map do\n \"%#{value}%\"\n end)",
|
"code": "where(\"#{values.count} OR #{\"(#{ProcedurePresentation.sanitized_column(table, column)} ILIKE ?)\"}\", *values.map do\n \"%#{value}%\"\n end)",
|
||||||
"render_path": null,
|
"render_path": null,
|
||||||
|
@ -153,6 +153,6 @@
|
||||||
"note": ""
|
"note": ""
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"updated": "2022-05-23 16:40:50 +0200",
|
"updated": "2022-06-15 16:15:28 +0200",
|
||||||
"brakeman_version": "5.2.2"
|
"brakeman_version": "5.2.2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class ChangeColumnNullForTargetedUserLinks < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
safety_assured { change_column_null :targeted_user_links, :user_id, true }
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,8 @@
|
||||||
|
class AddTargetModelIdIndexToTargetedUserLinks < ActiveRecord::Migration[6.1]
|
||||||
|
include Database::MigrationHelpers
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def up
|
||||||
|
add_concurrent_index :targeted_user_links, :target_model_id
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2022_05_31_100040) do
|
ActiveRecord::Schema.define(version: 2022_06_17_142759) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pgcrypto"
|
enable_extension "pgcrypto"
|
||||||
|
@ -758,7 +758,8 @@ ActiveRecord::Schema.define(version: 2022_05_31_100040) do
|
||||||
t.bigint "target_model_id", null: false
|
t.bigint "target_model_id", null: false
|
||||||
t.string "target_model_type", null: false
|
t.string "target_model_type", null: false
|
||||||
t.datetime "updated_at", precision: 6, null: false
|
t.datetime "updated_at", precision: 6, null: false
|
||||||
t.bigint "user_id", null: false
|
t.bigint "user_id"
|
||||||
|
t.index ["target_model_id"], name: "index_targeted_user_links_on_target_model_id"
|
||||||
t.index ["user_id"], name: "index_targeted_user_links_on_user_id"
|
t.index ["user_id"], name: "index_targeted_user_links_on_user_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,32 +1,35 @@
|
||||||
describe TargetedUserLinksController, type: :controller do
|
describe TargetedUserLinksController, type: :controller do
|
||||||
describe '#show' do
|
describe '#show' do
|
||||||
let!(:expert) { create(:expert, user: expert_user) }
|
let!(:targeted_user_link) { create(:targeted_user_link, target_context: target_context, target_model: target_model, user: user) }
|
||||||
let!(:avis) { create(:avis, experts_procedure: expert_procedure) }
|
|
||||||
|
context 'avis' do
|
||||||
|
let(:target_context) { :avis }
|
||||||
|
let!(:expert) { create(:expert, user: user) }
|
||||||
|
let!(:target_model) { create(:avis, experts_procedure: expert_procedure) }
|
||||||
let!(:expert_procedure) { create(:experts_procedure, expert: expert) }
|
let!(:expert_procedure) { create(:experts_procedure, expert: expert) }
|
||||||
let!(:targeted_user_link) { create(:targeted_user_link, target_context: :avis, target_model: avis, user: expert_user) }
|
|
||||||
|
|
||||||
context 'not connected as active expert' do
|
context 'not connected as active expert' do
|
||||||
let(:expert_user) { create(:user, last_sign_in_at: 2.days.ago) }
|
let(:user) { create(:user, last_sign_in_at: 2.days.ago) }
|
||||||
|
|
||||||
before { get :show, params: { id: targeted_user_link.id } }
|
before { get :show, params: { id: targeted_user_link.id } }
|
||||||
|
|
||||||
it 'redirects to expert_avis_url' do
|
it 'redirects to expert_avis_url' do
|
||||||
expect(response).to redirect_to(expert_avis_path(avis.procedure, avis))
|
expect(response).to redirect_to(expert_avis_path(target_model.procedure, target_model))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'not connected as inactive expert' do
|
context 'not connected as inactive expert' do
|
||||||
let(:expert_user) { create(:user, last_sign_in_at: nil) }
|
let(:user) { create(:user, last_sign_in_at: nil) }
|
||||||
|
|
||||||
before { get :show, params: { id: targeted_user_link.id } }
|
before { get :show, params: { id: targeted_user_link.id } }
|
||||||
|
|
||||||
it 'redirects to sign_up_expert_avis_url' do
|
it 'redirects to sign_up_expert_avis_url' do
|
||||||
expect(response).to redirect_to(sign_up_expert_avis_path(avis.procedure, avis, email: expert_user.email))
|
expect(response).to redirect_to(sign_up_expert_avis_path(target_model.procedure, target_model, email: user.email))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'connected as expected user' do
|
context 'connected as expected user' do
|
||||||
let(:expert_user) { create(:user, last_sign_in_at: 2.days.ago) }
|
let(:user) { create(:user, last_sign_in_at: 2.days.ago) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in(targeted_user_link.user)
|
sign_in(targeted_user_link.user)
|
||||||
|
@ -34,12 +37,12 @@ describe TargetedUserLinksController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'redirects to expert_avis_url' do
|
it 'redirects to expert_avis_url' do
|
||||||
expect(response).to redirect_to(expert_avis_path(avis.procedure, avis))
|
expect(response).to redirect_to(expert_avis_path(target_model.procedure, target_model))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'connected as different user' do
|
context 'connected as different user' do
|
||||||
let(:expert_user) { create(:user, last_sign_in_at: 2.days.ago) }
|
let(:user) { create(:user, last_sign_in_at: 2.days.ago) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
sign_in(create(:expert).user)
|
sign_in(create(:expert).user)
|
||||||
|
@ -51,4 +54,42 @@ describe TargetedUserLinksController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with invite' do
|
||||||
|
let(:target_context) { 'invite' }
|
||||||
|
let(:target_model) { create(:invite, user: user) }
|
||||||
|
|
||||||
|
context 'connected with expected user' do
|
||||||
|
let(:user) { build(:user, last_sign_in_at: 2.days.ago) }
|
||||||
|
before do
|
||||||
|
sign_in(targeted_user_link.user)
|
||||||
|
get :show, params: { id: targeted_user_link.id }
|
||||||
|
end
|
||||||
|
it 'works' do
|
||||||
|
expect(response).to redirect_to(invite_path(target_model))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'connected as different user' do
|
||||||
|
let(:user) { create(:user, last_sign_in_at: 2.days.ago) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(create(:expert).user)
|
||||||
|
get :show, params: { id: targeted_user_link.id }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'renders error page ' do
|
||||||
|
expect(response).to have_http_status(200)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when invite user does not exists' do
|
||||||
|
let(:user) { nil }
|
||||||
|
before { get :show, params: { id: targeted_user_link.id } }
|
||||||
|
it 'works' do
|
||||||
|
expect(response).to redirect_to(invite_path(target_model, email: target_model.email))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,12 @@ FactoryBot.define do
|
||||||
user {}
|
user {}
|
||||||
end
|
end
|
||||||
after(:build) do |targeted_user_link|
|
after(:build) do |targeted_user_link|
|
||||||
|
case targeted_user_link.target_context
|
||||||
|
when 'avis'
|
||||||
targeted_user_link.user = targeted_user_link.target_model.expert.user
|
targeted_user_link.user = targeted_user_link.target_model.expert.user
|
||||||
|
when 'invite'
|
||||||
|
targeted_user_link.user = targeted_user_link.target_model&.user
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
51
spec/mailers/invite_mailer_spec.rb
Normal file
51
spec/mailers/invite_mailer_spec.rb
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
RSpec.describe InviteMailer, type: :mailer do
|
||||||
|
let(:deliver) { mailer.deliver_now }
|
||||||
|
|
||||||
|
describe '.invite_user' do
|
||||||
|
let(:mailer) { InviteMailer.invite_user(invite) }
|
||||||
|
|
||||||
|
let(:invite) { create(:invite, user: create(:user)) }
|
||||||
|
it 'creates a target_user_link' do
|
||||||
|
expect { deliver }
|
||||||
|
.to change { TargetedUserLink.where(target_model: invite, user: invite.user).count }
|
||||||
|
.from(0).to(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it fails' do
|
||||||
|
it 'creates only one target_user_link' do
|
||||||
|
send_mail_values = [:raise, true]
|
||||||
|
allow_any_instance_of(InviteMailer).to receive(:send_mail) do
|
||||||
|
v = send_mail_values.shift
|
||||||
|
v == :raise ? raise("boom") : v
|
||||||
|
end
|
||||||
|
mailer.body rescue nil
|
||||||
|
mailer.body
|
||||||
|
expect(TargetedUserLink.where(target_model: invite, user: invite.user).count).to eq(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.invite_guest' do
|
||||||
|
let(:mailer) { InviteMailer.invite_guest(invite) }
|
||||||
|
let(:invite) { create(:invite, user: nil, email: 'kikoo@lol.fr') }
|
||||||
|
|
||||||
|
it 'creates a target_user_link' do
|
||||||
|
expect { deliver }
|
||||||
|
.to change { TargetedUserLink.where(target_model: invite, user: nil).count }
|
||||||
|
.from(0).to(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when it fails' do
|
||||||
|
it 'creates only one target_user_link' do
|
||||||
|
send_mail_values = [:raise, true]
|
||||||
|
allow_any_instance_of(InviteMailer).to receive(:send_mail) do
|
||||||
|
v = send_mail_values.shift
|
||||||
|
v == :raise ? raise("boom") : v
|
||||||
|
end
|
||||||
|
mailer.body rescue nil
|
||||||
|
mailer.body
|
||||||
|
expect(TargetedUserLink.where(target_model: invite, user: invite.user).count).to eq(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -4,7 +4,7 @@ RSpec.describe TargetedUserLink, type: :model do
|
||||||
describe 'Validation' do
|
describe 'Validation' do
|
||||||
let(:targeted_user_link) { build(:targeted_user_link) }
|
let(:targeted_user_link) { build(:targeted_user_link) }
|
||||||
|
|
||||||
context 'target_context' do
|
describe 'target_context' do
|
||||||
it 'is bullet proof' do
|
it 'is bullet proof' do
|
||||||
expect { targeted_user_link.target_context = :kc }.to raise_error(ArgumentError, "'kc' is not a valid target_context")
|
expect { targeted_user_link.target_context = :kc }.to raise_error(ArgumentError, "'kc' is not a valid target_context")
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,6 +14,7 @@ describe 'Invitations' do
|
||||||
navigate_to_brouillon(dossier)
|
navigate_to_brouillon(dossier)
|
||||||
|
|
||||||
fill_in 'Texte obligatoire', with: 'Some edited value'
|
fill_in 'Texte obligatoire', with: 'Some edited value'
|
||||||
|
|
||||||
send_invite_to "user_invite@exemple.fr"
|
send_invite_to "user_invite@exemple.fr"
|
||||||
|
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
||||||
|
@ -26,23 +27,72 @@ describe 'Invitations' do
|
||||||
|
|
||||||
context 'when inviting someone without an existing account' do
|
context 'when inviting someone without an existing account' do
|
||||||
let(:invite) { create(:invite, dossier: dossier, user: nil) }
|
let(:invite) { create(:invite, dossier: dossier, user: nil) }
|
||||||
let(:user_password) { 'my-s3cure-p4ssword' }
|
|
||||||
|
|
||||||
scenario 'an invited user can register using the registration link sent in the invitation email' do
|
scenario 'an invited user can register using the targeted_user_link sent in the invitation email thru the ' do
|
||||||
# Click the invitation link
|
log_in(owner)
|
||||||
visit invite_path(invite, params: { email: invite.email })
|
navigate_to_brouillon(dossier)
|
||||||
expect(page).to have_current_path(new_user_registration_path, ignore_query: true)
|
|
||||||
expect(page).to have_field('user_email', with: invite.email)
|
|
||||||
|
|
||||||
# Create the account
|
fill_in 'Texte obligatoire', with: 'Some edited value'
|
||||||
sign_up_with invite.email, user_password
|
|
||||||
expect(page).to have_content('lien d’activation')
|
|
||||||
|
|
||||||
# Confirm the account
|
send_invite_to "user_invite@exemple.fr"
|
||||||
# (The user should be redirected to the dossier they was invited on)
|
|
||||||
click_confirmation_link_for invite.email
|
expect {
|
||||||
expect(page).to have_content('Votre compte a bien été confirmé.')
|
perform_enqueued_jobs
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
}.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
|
||||||
|
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}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue