diff --git a/Gemfile b/Gemfile index 708603839..b7f37a435 100644 --- a/Gemfile +++ b/Gemfile @@ -98,6 +98,7 @@ group :test do gem 'capybara-screenshot' # Save a dump of the page when an integration test fails gem 'factory_bot' gem 'launchy' + gem 'rack_session_access' gem 'rails-controller-testing' gem 'rspec_junit_formatter' gem 'selenium-devtools' diff --git a/Gemfile.lock b/Gemfile.lock index 14db486bd..872388057 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -513,6 +513,9 @@ GEM rack rack-test (2.0.2) rack (>= 1.3) + rack_session_access (0.2.0) + builder (>= 2.0.0) + rack (>= 1.0.0) rails (6.1.7.1) actioncable (= 6.1.7.1) actionmailbox (= 6.1.7.1) @@ -887,6 +890,7 @@ DEPENDENCIES pundit rack-attack rack-mini-profiler + rack_session_access rails rails-controller-testing rails-erd diff --git a/config/environments/test.rb b/config/environments/test.rb index ccaba8feb..4a01914e6 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -87,4 +87,6 @@ Rails.application.configure do silence_warnings do BCrypt::Engine::DEFAULT_COST = BCrypt::Engine::MIN_COST end + + config.middleware.use RackSessionAccess::Middleware end diff --git a/spec/controllers/users/commencer_controller_spec.rb b/spec/controllers/users/commencer_controller_spec.rb index 1f4035d9c..8ca93cac3 100644 --- a/spec/controllers/users/commencer_controller_spec.rb +++ b/spec/controllers/users/commencer_controller_spec.rb @@ -63,7 +63,7 @@ describe Users::CommencerController, type: :controller do end end - context 'when a dossier has been prefilled' do + context 'when a dossier has been prefilled by POST before' do let(:dossier) { create(:dossier, :brouillon, :prefilled, user: user) } let(:path) { dossier.procedure.path } @@ -141,6 +141,85 @@ describe Users::CommencerController, type: :controller do end end end + + context 'when a dossier is being prefilled by GET' do + let(:type_de_champ_text) { create(:type_de_champ_text, procedure: published_procedure) } + let(:path) { published_procedure.path } + let(:user) { create(:user) } + + context "when the dossier does not exists yet" do + subject { get :commencer, params: { path: path, "champ_#{type_de_champ_text.to_typed_id}" => "blabla" } } + + shared_examples 'a prefilled brouillon dossier creator' do + it 'creates a dossier' do + subject + expect(Dossier.count).to eq(1) + expect(session[:prefill_token]).to eq(Dossier.last.prefill_token) + expect(session[:prefill_params]).to eq({ "action" => "commencer", "champ_#{type_de_champ_text.to_typed_id}" => "blabla", "controller" => "users/commencer", "path" => path.to_s }) + expect(Dossier.last.champs.where(type_de_champ: type_de_champ_text).first.value).to eq("blabla") + end + end + + context 'when the user is unauthenticated' do + it_behaves_like 'a prefilled brouillon dossier creator' + end + + context 'when the user is authenticated' do + before { sign_in user } + + it_behaves_like 'a prefilled brouillon dossier creator' + + it { expect { subject }.to change { Dossier.last&.user }.from(nil).to(user) } + + it 'sends the notify_new_draft email' do + expect { perform_enqueued_jobs { subject } }.to change { ActionMailer::Base.deliveries.count }.by(1) + + dossier = Dossier.last + mail = ActionMailer::Base.deliveries.last + expect(mail.subject).to eq("Retrouvez votre brouillon pour la démarche « #{dossier.procedure.libelle} »") + expect(mail.html_part.body).to include(dossier_path(dossier)) + end + end + end + context "when prefilled params are passed" do + subject { get :commencer, params: { path: path, prefill_token: "token", "champ_#{type_de_champ_text.to_typed_id}" => "blabla" } } + + context "when the associated dossier exists" do + let!(:dossier) { create(:dossier, :prefilled, prefill_token: "token") } + let!(:champ_text) { create(:champ_text, dossier: dossier, type_de_champ: type_de_champ_text) } + + it "does not create a new dossier" do + subject + expect(Dossier.count).to eq(1) + expect(assigns(:prefilled_dossier)).to eq(dossier) + end + end + context "when the associated dossier does not exists" do + it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) } + end + end + context "when session params exists" do + subject { get :commencer, params: { path: path, "champ_#{type_de_champ_text.to_typed_id}" => "blabla" } } + + before do + session[:prefill_token] = "token" + session[:prefill_params] = { "action" => "commencer", "champ_#{type_de_champ_text.to_typed_id}" => "blabla", "controller" => "users/commencer", "path" => path.to_s } + end + + context "when the associated dossier exists" do + let!(:dossier) { create(:dossier, :prefilled, prefill_token: "token") } + + it "does not create a new dossier" do + subject + expect(Dossier.count).to eq(1) + expect(assigns(:prefilled_dossier)).to eq(dossier) + end + end + context "when the associated dossier does not exists" do + it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) } + end + end + end end describe '#commencer_test' do diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb index f834508c8..fd100a5fc 100644 --- a/spec/controllers/users/dossiers_controller_spec.rb +++ b/spec/controllers/users/dossiers_controller_spec.rb @@ -1066,56 +1066,6 @@ describe Users::DossiersController, type: :controller do it { is_expected.to redirect_to dossiers_path } end - - context 'when prefill values have been stored in session before' do - let!(:type_de_champ_1) { create(:type_de_champ_text, procedure: procedure) } - let(:value_1) { "any value" } - - let!(:type_de_champ_2) { create(:type_de_champ_textarea, procedure: procedure) } - let(:value_2) { "another value" } - - let(:params) { - { - procedure_id: procedure_id, - "champ_#{type_de_champ_1.to_typed_id}" => value_1, - "champ_#{type_de_champ_2.to_typed_id}" => value_2 - } - } - - it { expect { subject }.to change { Dossier.count }.by(1) } - - it "prefills the dossier's champs with the given values" do - subject - - dossier = Dossier.last - expect(find_champ_by_stable_id(dossier, type_de_champ_1.stable_id).value).to eq(value_1) - expect(find_champ_by_stable_id(dossier, type_de_champ_2.stable_id).value).to eq(value_2) - end - - it { is_expected.to redirect_to siret_dossier_path(id: Dossier.last) } - - context 'when prefill values contain a hash' do - let(:value_2) { { evil: "payload" } } - - it "prefills the dossier's champ with the hash stored as a string" do - subject - - dossier = Dossier.last - expect(find_champ_by_stable_id(dossier, type_de_champ_2.stable_id).value).to eq("{\"evil\"=>\"payload\"}") - end - end - - context 'when prefill values contain an array' do - let(:value_2) { ["a", "b", "c"] } - - it "prefills the dossier's champ with the array stored as a string" do - subject - - dossier = Dossier.last - expect(find_champ_by_stable_id(dossier, type_de_champ_2.stable_id).value).to eq("[\"a\", \"b\", \"c\"]") - end - end - end end context 'when user is not logged' do it { is_expected.to have_http_status(302) } diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 340d3d75d..6e1b9fb87 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -14,6 +14,7 @@ require 'axe-rspec' require 'devise' require 'shoulda-matchers' require 'view_component/test_helpers' +require "rack_session_access/capybara" # Requires supporting ruby files with custom matchers and macros, etc, in # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are diff --git a/spec/system/users/dossier_prefill_get_spec.rb b/spec/system/users/dossier_prefill_get_spec.rb index 62aca4e4a..72d212b32 100644 --- a/spec/system/users/dossier_prefill_get_spec.rb +++ b/spec/system/users/dossier_prefill_get_spec.rb @@ -31,6 +31,39 @@ describe 'Prefilling a dossier (with a GET request):' do end end + context 'when authenticated with existing dossier and session params (ie: reload the page)' do + let(:user) { create(:user, password: password) } + let(:dossier) { create(:dossier, :prefilled, procedure: procedure, prefill_token: "token", user: nil) } + + before do + create(:champ_text, dossier: dossier, type_de_champ: type_de_champ_text, value: text_value) + + page.set_rack_session(prefill_token: "token") + page.set_rack_session(prefill_params: { "action" => "commencer", "champ_#{type_de_champ_text.to_typed_id}" => text_value, "controller" => "users/commencer", "path" => procedure.path }) + + visit "/users/sign_in" + sign_in_with user.email, password + + visit commencer_path( + path: procedure.path, + "champ_#{type_de_champ_text.to_typed_id}" => text_value + ) + + click_on "Poursuivre mon dossier prérempli" + end + + it "should not create a new dossier" do + expect(Dossier.count).to eq(1) + expect(dossier.reload.user).to eq(user) + + expect(page).to have_current_path(brouillon_dossier_path(dossier)) + expect(page).to have_field(type_de_champ_text.libelle, with: text_value) + + expect(page.get_rack_session[:prefill_token]).to be_nil + expect(page.get_rack_session[:prefill_params]).to be_nil + end + end + context 'when unauthenticated' do before do visit commencer_path(