demarches-normaliennes/spec/controllers/instructeurs/avis_controller_spec.rb
Pierre de La Morinerie 4cb747fdb6 specs: always require rails_helper
Test helpers are separated between two files: spec_helper and
rails_helper. This separation is meant to allow tests that do not
require Rails (like testing standalone libs) to boot faster.

The spec_helper file is always loaded, through `--require spec_helper`
in the `.rspec` config file. When needed, the rails_helper file is
expected to be required manually.

This is fine, but:
- Many test files have a redundant `require 'spec_helper'` line;
- Many test files should require `rails_helper`, but don't.

Not requiring `rails_helper` will cause the Rails-concerned section of
the test environment not to be configured–which may cause subtle bugs
(like the test database not being properly initialized).

Moreover, Spring loads all the Rails files on preloading anyway. So the
gains from using only `spec_helper` are thin.

To streamline this process, this commit:
- Configures `.rspec` to require `rails_helper` by default;
- Remove all manual requires to spec_helper or rails_helper.

Reference: https://stackoverflow.com/questions/24145329/how-is-spec-rails-helper-rb-different-from-spec-spec-helper-rb-do-i-need-it
2020-03-31 12:48:32 +02:00

378 lines
15 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

describe Instructeurs::AvisController, type: :controller do
context 'with a instructeur signed in' do
render_views
let(:claimant) { create(:instructeur) }
let(:instructeur) { create(:instructeur) }
let(:procedure) { create(:procedure, :published, instructeurs: [instructeur]) }
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
let!(:avis_without_answer) { Avis.create(dossier: dossier, claimant: claimant, instructeur: instructeur) }
let!(:avis_with_answer) { Avis.create(dossier: dossier, claimant: claimant, instructeur: instructeur, answer: 'yop') }
before { sign_in(instructeur.user) }
describe '#index' do
before { get :index }
it { expect(response).to have_http_status(:success) }
it { expect(assigns(:avis_a_donner)).to match([avis_without_answer]) }
it { expect(assigns(:avis_donnes)).to match([avis_with_answer]) }
it { expect(assigns(:statut)).to eq('a-donner') }
context 'with a statut equal to donnes' do
before { get :index, params: { statut: 'donnes' } }
it { expect(assigns(:statut)).to eq('donnes') }
end
end
describe '#show' do
before { get :show, params: { id: avis_without_answer.id } }
it { expect(response).to have_http_status(:success) }
it { expect(assigns(:avis)).to eq(avis_without_answer) }
it { expect(assigns(:dossier)).to eq(dossier) }
end
describe '#instruction' do
before { get :instruction, params: { id: avis_without_answer.id } }
it { expect(response).to have_http_status(:success) }
it { expect(assigns(:avis)).to eq(avis_without_answer) }
it { expect(assigns(:dossier)).to eq(dossier) }
end
describe '#messagerie' do
before { get :messagerie, params: { id: avis_without_answer.id } }
it { expect(response).to have_http_status(:success) }
it { expect(assigns(:avis)).to eq(avis_without_answer) }
it { expect(assigns(:dossier)).to eq(dossier) }
end
describe '#update' do
describe 'without attachment' do
before do
patch :update, params: { id: avis_without_answer.id, avis: { answer: 'answer' } }
avis_without_answer.reload
end
it 'should be ok' do
expect(response).to redirect_to(instruction_instructeur_avis_path(avis_without_answer))
expect(avis_without_answer.answer).to eq('answer')
expect(avis_without_answer.piece_justificative_file).to_not be_attached
expect(flash.notice).to eq('Votre réponse est enregistrée.')
end
end
describe 'with attachment' do
include ActiveJob::TestHelper
let(:file) { Rack::Test::UploadedFile.new("./spec/fixtures/files/piece_justificative_0.pdf", 'application/pdf') }
before do
expect(ClamavService).to receive(:safe_file?).and_return(true)
perform_enqueued_jobs do
post :update, params: { id: avis_without_answer.id, avis: { answer: 'answer', piece_justificative_file: file } }
end
avis_without_answer.reload
end
it 'should be ok' do
expect(response).to redirect_to(instruction_instructeur_avis_path(avis_without_answer))
expect(avis_without_answer.answer).to eq('answer')
expect(avis_without_answer.piece_justificative_file).to be_attached
expect(flash.notice).to eq('Votre réponse est enregistrée.')
end
end
end
describe '#create_commentaire' do
let(:file) { nil }
let(:scan_result) { true }
subject { post :create_commentaire, params: { id: avis_without_answer.id, commentaire: { body: 'commentaire body', piece_jointe: file } } }
before do
allow(ClamavService).to receive(:safe_file?).and_return(scan_result)
end
it do
subject
expect(response).to redirect_to(messagerie_instructeur_avis_path(avis_without_answer))
expect(dossier.commentaires.map(&:body)).to match(['commentaire body'])
end
context "with a file" do
let(:file) { Rack::Test::UploadedFile.new("./spec/fixtures/files/piece_justificative_0.pdf", 'application/pdf') }
it do
subject
expect(Commentaire.last.piece_jointe.filename).to eq("piece_justificative_0.pdf")
end
it { expect { subject }.to change(Commentaire, :count).by(1) }
end
end
describe '#create_avis' do
let!(:previous_avis) { Avis.create(dossier: dossier, claimant: claimant, instructeur: instructeur, confidentiel: previous_avis_confidentiel) }
let(:emails) { ['a@b.com'] }
let(:intro) { 'introduction' }
let(:created_avis) { Avis.last }
let!(:old_avis_count) { Avis.count }
let(:invite_linked_dossiers) { nil }
before do
@introduction_file = Rack::Test::UploadedFile.new("./spec/fixtures/files/piece_justificative_0.pdf", 'application/pdf')
post :create_avis, params: { id: previous_avis.id, avis: { emails: emails, introduction: intro, confidentiel: asked_confidentiel, invite_linked_dossiers: invite_linked_dossiers, introduction_file: @introduction_file } }
created_avis.reload
end
context 'when an invalid email' do
let(:previous_avis_confidentiel) { false }
let(:asked_confidentiel) { false }
let(:emails) { ["toto.fr"] }
it { expect(response).to render_template :instruction }
it { expect(flash.alert).to eq(["toto.fr : Email n'est pas valide"]) }
it { expect(Avis.last).to eq(previous_avis) }
end
context 'ask review with attachment' do
let(:previous_avis_confidentiel) { false }
let(:asked_confidentiel) { false }
let(:emails) { ["toto@totomail.com"] }
it { expect(created_avis.introduction_file).to be_attached }
it { expect(created_avis.introduction_file.filename).to eq("piece_justificative_0.pdf") }
it { expect(flash.notice).to eq("Une demande d'avis a été envoyée à toto@totomail.com") }
end
context 'with multiple emails' do
let(:asked_confidentiel) { false }
let(:previous_avis_confidentiel) { false }
let(:emails) { ["toto.fr,titi@titimail.com"] }
it { expect(response).to render_template :instruction }
it { expect(flash.alert).to eq(["toto.fr : Email n'est pas valide"]) }
it { expect(flash.notice).to eq("Une demande d'avis a été envoyée à titi@titimail.com") }
it { expect(Avis.count).to eq(old_avis_count + 1) }
it { expect(created_avis.email).to eq("titi@titimail.com") }
end
context 'when the previous avis is public' do
let(:previous_avis_confidentiel) { false }
context 'when the user asked for a public avis' do
let(:asked_confidentiel) { false }
it { expect(created_avis.confidentiel).to be(false) }
it { expect(created_avis.email).to eq(emails.last) }
it { expect(created_avis.introduction).to eq(intro) }
it { expect(created_avis.dossier).to eq(previous_avis.dossier) }
it { expect(created_avis.claimant).to eq(instructeur) }
it { expect(response).to redirect_to(instruction_instructeur_avis_path(previous_avis)) }
end
context 'when the user asked for a confidentiel avis' do
let(:asked_confidentiel) { true }
it { expect(created_avis.confidentiel).to be(true) }
end
end
context 'when the preivous avis is confidentiel' do
let(:previous_avis_confidentiel) { true }
context 'when the user asked for a public avis' do
let(:asked_confidentiel) { false }
it { expect(created_avis.confidentiel).to be(true) }
end
end
context 'with linked dossiers' do
let(:asked_confidentiel) { false }
let(:previous_avis_confidentiel) { false }
let(:dossier) { create(:dossier, :en_construction, :with_dossier_link, procedure: procedure) }
context 'when the expert doesnt share linked dossiers' do
let(:invite_linked_dossiers) { false }
it 'sends a single avis for the main dossier, but doesnt give access to the linked dossiers' do
expect(flash.notice).to eq("Une demande d'avis a été envoyée à a@b.com")
expect(Avis.count).to eq(old_avis_count + 1)
expect(created_avis.email).to eq("a@b.com")
expect(created_avis.dossier).to eq(dossier)
end
end
context 'when the expert also shares the linked dossiers' do
let(:invite_linked_dossiers) { true }
context 'and the expert can access the linked dossiers' do
let(:created_avis) { Avis.last(2).first }
let(:linked_avis) { Avis.last }
let(:linked_dossier) { Dossier.find_by(id: dossier.reload.champs.filter(&:dossier_link?).map(&:value).compact) }
let(:invite_linked_dossiers) do
instructeur.assign_to_procedure(linked_dossier.procedure)
true
end
it 'sends one avis for the main dossier' do
expect(flash.notice).to eq("Une demande d'avis a été envoyée à a@b.com")
expect(created_avis.email).to eq("a@b.com")
expect(created_avis.dossier).to eq(dossier)
end
it 'sends another avis for the linked dossiers' do
expect(Avis.count).to eq(old_avis_count + 2)
expect(linked_avis.dossier).to eq(linked_dossier)
end
end
context 'but the expert cant access the linked dossier' do
it 'sends a single avis for the main dossier, but doesnt give access to the linked dossiers' do
expect(flash.notice).to eq("Une demande d'avis a été envoyée à a@b.com")
expect(Avis.count).to eq(old_avis_count + 1)
expect(created_avis.email).to eq("a@b.com")
expect(created_avis.dossier).to eq(dossier)
end
end
end
end
end
end
context 'without a instructeur signed in' do
describe '#sign_up' do
let(:invited_email) { 'invited@avis.com' }
let(:dossier) { create(:dossier) }
let!(:avis) { create(:avis, email: invited_email, dossier: dossier) }
let(:invitations_email) { true }
context 'when the new instructeur has never signed up' do
before do
expect(Avis).to receive(:avis_exists_and_email_belongs_to_avis?)
.with(avis.id.to_s, invited_email)
.and_return(invitations_email)
get :sign_up, params: { id: avis.id, email: invited_email }
end
context 'when the email belongs to the invitation' do
it { expect(subject.status).to eq(200) }
it { expect(assigns(:email)).to eq(invited_email) }
it { expect(assigns(:dossier)).to eq(dossier) }
end
context 'when the email does not belong to the invitation' do
let(:invitations_email) { false }
it { is_expected.to redirect_to root_path }
end
end
context 'when the instructeur has already signed up and belongs to the invitation' do
let(:instructeur) { create(:instructeur, email: invited_email) }
let!(:avis) { create(:avis, dossier: dossier, instructeur: instructeur) }
context 'when the instructeur is authenticated' do
before do
sign_in(instructeur.user)
get :sign_up, params: { id: avis.id, email: invited_email }
end
it { is_expected.to redirect_to instructeur_avis_url(avis) }
end
context 'when the instructeur is not authenticated' do
before do
get :sign_up, params: { id: avis.id, email: invited_email }
end
it { is_expected.to redirect_to new_user_session_url }
end
end
context 'when the instructeur has already signed up / is authenticated and does not belong to the invitation' do
let(:instructeur) { create(:instructeur, email: 'other@gmail.com') }
let!(:avis) { create(:avis, email: invited_email, dossier: dossier) }
before do
sign_in(instructeur.user)
get :sign_up, params: { id: avis.id, email: invited_email }
end
# redirected to dossier but then the instructeur gonna be banished !
it { is_expected.to redirect_to instructeur_avis_url(avis) }
end
end
describe '#create_instructeur' do
let(:existing_user_mail) { 'dummy@example.org' }
let!(:existing_user) { create(:user, email: existing_user_mail) }
let(:invited_email) { 'invited@avis.com' }
let(:dossier) { create(:dossier) }
let!(:avis) { create(:avis, email: invited_email, dossier: dossier) }
let(:avis_id) { avis.id }
let(:password) { 'démarches-simplifiées-pwd' }
let(:created_instructeur) { Instructeur.by_email(invited_email) }
let(:invitations_email) { true }
before do
allow(Avis).to receive(:link_avis_to_instructeur)
expect(Avis).to receive(:avis_exists_and_email_belongs_to_avis?)
.with(avis_id.to_s, invited_email)
.and_return(invitations_email)
post :create_instructeur, params: {
id: avis_id,
email: invited_email,
user: {
password: password
}
}
end
context 'when the email does not belong to the invitation' do
let(:invitations_email) { false }
it { is_expected.to redirect_to root_path }
end
context 'when the email belongs to the invitation' do
context 'when the instructeur creation succeeds' do
it { expect(created_instructeur).to be_present }
it { expect(created_instructeur.user.valid_password?(password)).to be true }
it { expect(Avis).to have_received(:link_avis_to_instructeur) }
it { expect(subject.current_instructeur).to eq(created_instructeur) }
it { is_expected.to redirect_to instructeur_avis_index_path }
it 'creates a corresponding user account for the email' do
user = User.find_by(email: invited_email)
expect(user).to be_present
end
context 'when there already is a user account with the same email' do
let(:existing_user_mail) { invited_email }
it 'still creates a instructeur account' do
expect(created_instructeur).to be_present
end
end
end
context 'when the instructeur creation fails' do
let(:password) { '' }
it { expect(created_instructeur).to be_nil }
it { is_expected.to redirect_to sign_up_instructeur_avis_path(avis_id, invited_email) }
it { expect(flash.alert).to eq(['Le mot de passe doit être rempli']) }
end
end
end
end
end