2017-06-29 14:18:12 +02:00
|
|
|
require 'spec_helper'
|
|
|
|
|
|
|
|
describe NewUser::DossiersController, type: :controller do
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
|
2018-03-29 16:49:01 +02:00
|
|
|
describe 'before_actions' do
|
|
|
|
it 'are present' do
|
2017-06-29 14:18:12 +02:00
|
|
|
before_actions = NewUser::DossiersController
|
|
|
|
._process_action_callbacks
|
2018-01-15 21:54:40 +01:00
|
|
|
.find_all{ |process_action_callbacks| process_action_callbacks.kind == :before }
|
2017-06-29 14:18:12 +02:00
|
|
|
.map(&:filter)
|
|
|
|
|
2018-03-29 16:49:01 +02:00
|
|
|
expect(before_actions).to include(:ensure_ownership!, :ensure_ownership_or_invitation!, :forbid_invite_submission!)
|
2017-06-29 14:18:12 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-03-29 15:25:05 +02:00
|
|
|
shared_examples_for 'does not redirect nor flash' do
|
|
|
|
before { @controller.send(ensure_authorized) }
|
|
|
|
|
|
|
|
it { expect(@controller).not_to have_received(:redirect_to) }
|
|
|
|
it { expect(flash.alert).to eq(nil) }
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples_for 'redirects and flashes' do
|
|
|
|
before { @controller.send(ensure_authorized) }
|
|
|
|
|
|
|
|
it { expect(@controller).to have_received(:redirect_to).with(root_path) }
|
|
|
|
it { expect(flash.alert).to eq("Vous n'avez pas accès à ce dossier") }
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#ensure_ownership!' do
|
2017-06-29 14:18:12 +02:00
|
|
|
let(:user) { create(:user) }
|
2018-03-29 15:25:05 +02:00
|
|
|
let(:asked_dossier) { create(:dossier) }
|
|
|
|
let(:ensure_authorized) { :ensure_ownership! }
|
2017-06-29 14:18:12 +02:00
|
|
|
|
|
|
|
before do
|
2018-01-23 18:28:09 +01:00
|
|
|
@controller.params = @controller.params.merge(dossier_id: asked_dossier.id)
|
2017-06-29 14:18:12 +02:00
|
|
|
expect(@controller).to receive(:current_user).and_return(user)
|
|
|
|
allow(@controller).to receive(:redirect_to)
|
2018-03-29 15:25:05 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a user asks for their own dossier' do
|
|
|
|
let(:asked_dossier) { create(:dossier, user: user) }
|
|
|
|
|
|
|
|
it_behaves_like 'does not redirect nor flash'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a user asks for another dossier' do
|
|
|
|
it_behaves_like 'redirects and flashes'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when an invite asks for a dossier where they were invited' do
|
|
|
|
before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') }
|
|
|
|
|
|
|
|
it_behaves_like 'redirects and flashes'
|
|
|
|
end
|
2017-06-29 14:18:12 +02:00
|
|
|
|
2018-03-29 15:25:05 +02:00
|
|
|
context 'when an invite asks for another dossier' do
|
|
|
|
before { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') }
|
|
|
|
|
|
|
|
it_behaves_like 'redirects and flashes'
|
2017-06-29 14:18:12 +02:00
|
|
|
end
|
2018-03-29 15:25:05 +02:00
|
|
|
end
|
2017-06-29 14:18:12 +02:00
|
|
|
|
2018-03-29 15:25:05 +02:00
|
|
|
describe '#ensure_ownership_or_invitation!' do
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
let(:asked_dossier) { create(:dossier) }
|
|
|
|
let(:ensure_authorized) { :ensure_ownership_or_invitation! }
|
|
|
|
|
|
|
|
before do
|
|
|
|
@controller.params = @controller.params.merge(dossier_id: asked_dossier.id)
|
|
|
|
expect(@controller).to receive(:current_user).and_return(user)
|
|
|
|
allow(@controller).to receive(:redirect_to)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a user asks for their own dossier' do
|
2017-06-29 14:18:12 +02:00
|
|
|
let(:asked_dossier) { create(:dossier, user: user) }
|
|
|
|
|
2018-03-29 15:25:05 +02:00
|
|
|
it_behaves_like 'does not redirect nor flash'
|
2017-06-29 14:18:12 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a user asks for another dossier' do
|
2018-03-29 15:25:05 +02:00
|
|
|
it_behaves_like 'redirects and flashes'
|
|
|
|
end
|
2017-06-29 14:18:12 +02:00
|
|
|
|
2018-03-29 15:25:05 +02:00
|
|
|
context 'when an invite asks for a dossier where they were invited' do
|
|
|
|
before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') }
|
|
|
|
|
|
|
|
it_behaves_like 'does not redirect nor flash'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when an invite asks for another dossier' do
|
|
|
|
before { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') }
|
|
|
|
|
2018-07-31 17:25:39 +02:00
|
|
|
it_behaves_like 'redirects and flashes'
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "#forbid_invite_submission!" do
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
let(:asked_dossier) { create(:dossier) }
|
|
|
|
let(:ensure_authorized) { :forbid_invite_submission! }
|
2018-08-02 15:49:14 +02:00
|
|
|
let(:draft) { false }
|
2018-07-31 17:25:39 +02:00
|
|
|
|
|
|
|
before do
|
2018-08-02 15:49:14 +02:00
|
|
|
@controller.params = @controller.params.merge(dossier_id: asked_dossier.id, save_draft: draft)
|
2018-07-31 17:25:39 +02:00
|
|
|
allow(@controller).to receive(:current_user).and_return(user)
|
|
|
|
allow(@controller).to receive(:redirect_to)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a user save their own draft' do
|
|
|
|
let(:asked_dossier) { create(:dossier, user: user) }
|
2018-08-02 15:49:14 +02:00
|
|
|
let(:draft) { true }
|
2018-07-31 17:25:39 +02:00
|
|
|
|
|
|
|
it_behaves_like 'does not redirect nor flash'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a user submit their own dossier' do
|
|
|
|
let(:asked_dossier) { create(:dossier, user: user) }
|
2018-08-02 15:49:14 +02:00
|
|
|
let(:draft) { false }
|
2018-07-31 17:25:39 +02:00
|
|
|
|
|
|
|
it_behaves_like 'does not redirect nor flash'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when an invite save the draft for a dossier where they where invited' do
|
|
|
|
before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') }
|
2018-08-02 15:49:14 +02:00
|
|
|
let(:draft) { true }
|
2018-07-31 17:25:39 +02:00
|
|
|
|
|
|
|
it_behaves_like 'does not redirect nor flash'
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when an invite submit a dossier where they where invited' do
|
|
|
|
before { create(:invite, dossier: asked_dossier, user: user, type: 'InviteUser') }
|
2018-08-02 15:49:14 +02:00
|
|
|
let(:draft) { false }
|
2018-07-31 17:25:39 +02:00
|
|
|
|
2018-03-29 15:25:05 +02:00
|
|
|
it_behaves_like 'redirects and flashes'
|
2017-06-29 14:18:12 +02:00
|
|
|
end
|
|
|
|
end
|
2017-06-29 14:18:59 +02:00
|
|
|
|
|
|
|
describe 'attestation' do
|
|
|
|
before { sign_in(user) }
|
|
|
|
|
|
|
|
context 'when a dossier has an attestation' do
|
|
|
|
let(:fake_pdf) { double(read: 'pdf content') }
|
|
|
|
let!(:dossier) { create(:dossier, attestation: Attestation.new, user: user) }
|
|
|
|
|
|
|
|
it 'returns the attestation pdf' do
|
|
|
|
allow_any_instance_of(Attestation).to receive(:pdf).and_return(fake_pdf)
|
|
|
|
|
|
|
|
expect(controller).to receive(:send_data)
|
|
|
|
.with('pdf content', filename: 'attestation.pdf', type: 'application/pdf') do
|
2018-01-24 14:44:28 +01:00
|
|
|
controller.head :ok
|
2017-06-29 14:18:59 +02:00
|
|
|
end
|
|
|
|
|
2018-07-17 11:26:41 +02:00
|
|
|
get :attestation, params: { id: dossier.id }
|
2017-06-29 14:18:59 +02:00
|
|
|
expect(response).to have_http_status(:success)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-02-08 17:13:15 +01:00
|
|
|
|
|
|
|
describe 'update_identite' do
|
|
|
|
let(:procedure) { create(:procedure, :for_individual) }
|
|
|
|
let(:dossier) { create(:dossier, user: user, procedure: procedure) }
|
|
|
|
|
|
|
|
subject { post :update_identite, params: { id: dossier.id, individual: individual_params, dossier: dossier_params } }
|
|
|
|
|
|
|
|
before do
|
|
|
|
sign_in(user)
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with correct individual and dossier params' do
|
|
|
|
let(:individual_params) { { gender: 'M', nom: 'Mouse', prenom: 'Mickey' } }
|
|
|
|
let(:dossier_params) { { autorisation_donnees: true } }
|
|
|
|
|
|
|
|
it do
|
2018-09-06 09:09:23 +02:00
|
|
|
expect(response).to redirect_to(brouillon_dossier_path(dossier))
|
2018-02-08 17:13:15 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'on a procedure with carto' do
|
|
|
|
let(:procedure) { create(:procedure, :for_individual, :with_api_carto) }
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(response).to redirect_to(users_dossier_carte_path(dossier))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-06-08 15:51:46 +02:00
|
|
|
context 'when the identite cannot be updated by the user' do
|
|
|
|
let(:dossier) { create(:dossier, :for_individual, :en_instruction, user: user, procedure: procedure) }
|
|
|
|
let(:individual_params) { { gender: 'M', nom: 'Mouse', prenom: 'Mickey' } }
|
|
|
|
let(:dossier_params) { { autorisation_donnees: true } }
|
|
|
|
|
2018-06-27 14:47:02 +02:00
|
|
|
it 'redirects to the dossiers list' do
|
|
|
|
expect(response).to redirect_to(dossiers_path)
|
2018-06-08 15:51:46 +02:00
|
|
|
expect(flash.alert).to eq('Votre dossier ne peut plus être modifié')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-02-08 17:13:15 +01:00
|
|
|
context 'with incorrect individual and dossier params' do
|
|
|
|
let(:individual_params) { { gender: '', nom: '', prenom: '' } }
|
|
|
|
let(:dossier_params) { { autorisation_donnees: nil } }
|
|
|
|
|
|
|
|
it do
|
|
|
|
expect(response).not_to have_http_status(:redirect)
|
|
|
|
expect(flash[:alert]).to include("Civilité doit être rempli", "Nom doit être rempli", "Prénom doit être rempli", "Acceptation des CGU doit être coché")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2018-02-21 18:32:07 +01:00
|
|
|
|
2018-09-06 09:09:23 +02:00
|
|
|
describe '#brouillon' do
|
2018-02-21 18:32:07 +01:00
|
|
|
before { sign_in(user) }
|
|
|
|
let!(:dossier) { create(:dossier, user: user, autorisation_donnees: true) }
|
|
|
|
|
2018-09-06 09:09:23 +02:00
|
|
|
subject { get :brouillon, params: { id: dossier.id } }
|
2018-02-21 18:32:07 +01:00
|
|
|
|
|
|
|
context 'when autorisation_donnees is checked' do
|
2018-09-06 09:09:23 +02:00
|
|
|
it { is_expected.to render_template(:brouillon) }
|
2018-02-21 18:32:07 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'when autorisation_donnees is not checked' do
|
|
|
|
before { dossier.update_columns(autorisation_donnees: false) }
|
|
|
|
|
|
|
|
context 'when the dossier is for personne morale' do
|
|
|
|
it { is_expected.to redirect_to(users_dossier_path(dossier)) }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the dossier is for an personne physique' do
|
2018-03-02 16:27:03 +01:00
|
|
|
before { dossier.procedure.update(for_individual: true) }
|
2018-02-21 18:32:07 +01:00
|
|
|
|
|
|
|
it { is_expected.to redirect_to(identite_dossier_path(dossier)) }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe '#edit' do
|
|
|
|
before { sign_in(user) }
|
|
|
|
let!(:dossier) { create(:dossier, user: user) }
|
|
|
|
|
|
|
|
it 'returns the edit page' do
|
2018-09-06 09:09:23 +02:00
|
|
|
get :brouillon, params: { id: dossier.id }
|
2018-02-21 18:32:07 +01:00
|
|
|
expect(response).to have_http_status(:success)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-09-06 10:49:26 +02:00
|
|
|
describe '#update_brouillon' do
|
2018-02-21 18:32:07 +01:00
|
|
|
before { sign_in(user) }
|
|
|
|
let!(:dossier) { create(:dossier, user: user) }
|
|
|
|
let(:first_champ) { dossier.champs.first }
|
|
|
|
let(:value) { 'beautiful value' }
|
|
|
|
let(:submit_payload) do
|
|
|
|
{
|
|
|
|
id: dossier.id,
|
|
|
|
dossier: {
|
|
|
|
champs_attributes: {
|
|
|
|
id: first_champ.id,
|
|
|
|
value: value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
let(:payload) { submit_payload }
|
|
|
|
|
2018-09-06 10:49:26 +02:00
|
|
|
subject { patch :update_brouillon, params: payload }
|
2018-02-21 18:32:07 +01:00
|
|
|
|
2018-06-08 15:51:46 +02:00
|
|
|
context 'when the dossier cannot be updated by the user' do
|
|
|
|
let!(:dossier) { create(:dossier, :en_instruction, user: user) }
|
|
|
|
|
2018-06-27 14:47:02 +02:00
|
|
|
it 'redirects to the dossiers list' do
|
2018-06-08 15:51:46 +02:00
|
|
|
subject
|
|
|
|
|
2018-06-27 14:47:02 +02:00
|
|
|
expect(response).to redirect_to(dossiers_path)
|
2018-06-08 15:51:46 +02:00
|
|
|
expect(flash.alert).to eq('Votre dossier ne peut plus être modifié')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-06-25 18:07:16 +02:00
|
|
|
context 'when dossier can be updated by the owner' do
|
|
|
|
it 'updates the champs' do
|
|
|
|
subject
|
|
|
|
|
|
|
|
expect(response).to redirect_to(merci_dossier_path(dossier))
|
|
|
|
expect(first_champ.reload.value).to eq('beautiful value')
|
2018-08-28 14:10:55 +02:00
|
|
|
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction))
|
2018-06-25 18:07:16 +02:00
|
|
|
end
|
2018-02-21 18:32:07 +01:00
|
|
|
|
2018-06-25 18:07:16 +02:00
|
|
|
context "on an archived procedure" do
|
|
|
|
before { dossier.procedure.archive }
|
|
|
|
|
|
|
|
it "it does not change state" do
|
|
|
|
subject
|
|
|
|
|
|
|
|
expect(response).not_to redirect_to(merci_dossier_path(dossier))
|
2018-08-28 14:10:55 +02:00
|
|
|
expect(dossier.reload.state).to eq(Dossier.states.fetch(:brouillon))
|
2018-06-25 18:07:16 +02:00
|
|
|
end
|
|
|
|
end
|
2018-02-21 18:32:07 +01:00
|
|
|
end
|
|
|
|
|
2018-09-06 10:49:26 +02:00
|
|
|
it 'sends an email only on the first #update_brouillon' do
|
2018-03-05 17:59:45 +01:00
|
|
|
delivery = double
|
2018-05-25 18:05:28 +02:00
|
|
|
expect(delivery).to receive(:deliver_later).with(no_args)
|
2018-03-05 17:59:45 +01:00
|
|
|
|
2018-05-25 23:08:47 +02:00
|
|
|
expect(NotificationMailer).to receive(:send_initiated_notification)
|
2018-03-05 17:59:45 +01:00
|
|
|
.and_return(delivery)
|
|
|
|
|
|
|
|
subject
|
|
|
|
|
2018-05-25 23:08:47 +02:00
|
|
|
expect(NotificationMailer).not_to receive(:send_initiated_notification)
|
2018-03-05 17:59:45 +01:00
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
2018-02-21 18:32:07 +01:00
|
|
|
context 'when the update fails' do
|
|
|
|
before do
|
2018-04-03 17:53:14 +02:00
|
|
|
expect_any_instance_of(Dossier).to receive(:save).and_return(false)
|
2018-02-21 18:32:07 +01:00
|
|
|
expect_any_instance_of(Dossier).to receive(:errors)
|
|
|
|
.and_return(double(full_messages: ['nop']))
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
2018-09-06 09:09:23 +02:00
|
|
|
it { expect(response).to render_template(:brouillon) }
|
2018-02-21 18:32:07 +01:00
|
|
|
it { expect(flash.alert).to eq(['nop']) }
|
2018-03-05 17:59:45 +01:00
|
|
|
|
|
|
|
it 'does not send an email' do
|
2018-05-30 17:07:29 +02:00
|
|
|
expect(NotificationMailer).not_to receive(:send_initiated_notification)
|
2018-03-05 17:59:45 +01:00
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
2018-02-21 18:32:07 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the pj service returns an error' do
|
|
|
|
before do
|
|
|
|
expect(PiecesJustificativesService).to receive(:upload!).and_return(['nop'])
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
2018-09-06 09:09:23 +02:00
|
|
|
it { expect(response).to render_template(:brouillon) }
|
2018-02-21 18:32:07 +01:00
|
|
|
it { expect(flash.alert).to eq(['nop']) }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a mandatory champ is missing' do
|
|
|
|
let(:value) { nil }
|
|
|
|
|
|
|
|
before do
|
2018-03-02 16:27:03 +01:00
|
|
|
first_champ.type_de_champ.update(mandatory: true, libelle: 'l')
|
2018-02-21 18:32:07 +01:00
|
|
|
allow(PiecesJustificativesService).to receive(:missing_pj_error_messages).and_return(['pj'])
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
2018-09-06 09:09:23 +02:00
|
|
|
it { expect(response).to render_template(:brouillon) }
|
2018-02-21 18:32:07 +01:00
|
|
|
it { expect(flash.alert).to eq(['Le champ l doit être rempli.', 'pj']) }
|
|
|
|
|
|
|
|
context 'and the user saves a draft' do
|
2018-08-02 15:49:14 +02:00
|
|
|
let(:payload) { submit_payload.merge(save_draft: true) }
|
2018-02-21 18:32:07 +01:00
|
|
|
|
2018-09-06 09:09:23 +02:00
|
|
|
it { expect(response).to render_template(:brouillon) }
|
2018-02-21 18:32:07 +01:00
|
|
|
it { expect(flash.notice).to eq('Votre brouillon a bien été sauvegardé.') }
|
2018-08-28 14:10:55 +02:00
|
|
|
it { expect(dossier.reload.state).to eq(Dossier.states.fetch(:brouillon)) }
|
2018-02-21 18:32:07 +01:00
|
|
|
end
|
|
|
|
end
|
2018-02-27 17:25:45 +01:00
|
|
|
|
|
|
|
context 'when dossier has no champ' do
|
|
|
|
let(:submit_payload) { { id: dossier.id } }
|
|
|
|
|
|
|
|
it 'does not raise any errors' do
|
|
|
|
subject
|
|
|
|
|
2018-02-27 09:49:58 +01:00
|
|
|
expect(response).to redirect_to(merci_dossier_path(dossier))
|
2018-02-27 17:25:45 +01:00
|
|
|
end
|
|
|
|
end
|
2018-03-29 16:45:24 +02:00
|
|
|
|
|
|
|
context 'when the user has an invitation but is not the owner' do
|
|
|
|
let(:dossier) { create(:dossier) }
|
|
|
|
let!(:invite) { create(:invite, dossier: dossier, user: user, type: 'InviteUser') }
|
|
|
|
|
|
|
|
context 'and the invite saves a draft' do
|
2018-08-02 15:49:14 +02:00
|
|
|
let(:payload) { submit_payload.merge(save_draft: true) }
|
2018-03-29 16:45:24 +02:00
|
|
|
|
|
|
|
before do
|
|
|
|
first_champ.type_de_champ.update(mandatory: true, libelle: 'l')
|
|
|
|
allow(PiecesJustificativesService).to receive(:missing_pj_error_messages).and_return(['pj'])
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
2018-09-06 09:09:23 +02:00
|
|
|
it { expect(response).to render_template(:brouillon) }
|
2018-03-29 16:45:24 +02:00
|
|
|
it { expect(flash.notice).to eq('Votre brouillon a bien été sauvegardé.') }
|
2018-08-28 14:10:55 +02:00
|
|
|
it { expect(dossier.reload.state).to eq(Dossier.states.fetch(:brouillon)) }
|
2018-03-29 16:45:24 +02:00
|
|
|
end
|
|
|
|
|
2018-03-29 16:49:01 +02:00
|
|
|
context 'and the invite tries to submit the dossier' do
|
|
|
|
before { subject }
|
|
|
|
|
|
|
|
it { expect(response).to redirect_to(root_path) }
|
|
|
|
it { expect(flash.alert).to eq("Vous n'avez pas accès à ce dossier") }
|
|
|
|
end
|
2018-03-29 16:45:24 +02:00
|
|
|
end
|
2018-02-21 18:32:07 +01:00
|
|
|
end
|
2018-04-03 10:49:16 +02:00
|
|
|
|
2018-09-06 11:39:46 +02:00
|
|
|
describe '#update' do
|
|
|
|
before { sign_in(user) }
|
|
|
|
let!(:dossier) { create(:dossier, :en_construction, user: user) }
|
|
|
|
let(:first_champ) { dossier.champs.first }
|
|
|
|
let(:value) { 'beautiful value' }
|
|
|
|
let(:submit_payload) do
|
|
|
|
{
|
|
|
|
id: dossier.id,
|
|
|
|
dossier: {
|
|
|
|
champs_attributes: {
|
|
|
|
id: first_champ.id,
|
|
|
|
value: value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
let(:payload) { submit_payload }
|
|
|
|
|
|
|
|
subject { patch :update, params: payload }
|
|
|
|
|
|
|
|
context 'when the dossier cannot be updated by the user' do
|
|
|
|
let!(:dossier) { create(:dossier, :en_instruction, user: user) }
|
|
|
|
|
|
|
|
it 'redirects to the dossiers list' do
|
|
|
|
subject
|
|
|
|
|
|
|
|
expect(response).to redirect_to(dossiers_path)
|
|
|
|
expect(flash.alert).to eq('Votre dossier ne peut plus être modifié')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when dossier can be updated by the owner' do
|
|
|
|
it 'updates the champs' do
|
|
|
|
subject
|
|
|
|
|
|
|
|
expect(response).to redirect_to(users_dossier_recapitulatif_path(dossier))
|
|
|
|
expect(first_champ.reload.value).to eq('beautiful value')
|
|
|
|
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the update fails' do
|
|
|
|
before do
|
|
|
|
expect_any_instance_of(Dossier).to receive(:save).and_return(false)
|
|
|
|
expect_any_instance_of(Dossier).to receive(:errors)
|
|
|
|
.and_return(double(full_messages: ['nop']))
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(response).to render_template(:modifier) }
|
|
|
|
it { expect(flash.alert).to eq(['nop']) }
|
|
|
|
|
|
|
|
it 'does not send an email' do
|
|
|
|
expect(NotificationMailer).not_to receive(:send_initiated_notification)
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the pj service returns an error' do
|
|
|
|
before do
|
|
|
|
expect(PiecesJustificativesService).to receive(:upload!).and_return(['nop'])
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(response).to render_template(:modifier) }
|
|
|
|
it { expect(flash.alert).to eq(['nop']) }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when a mandatory champ is missing' do
|
|
|
|
let(:value) { nil }
|
|
|
|
|
|
|
|
before do
|
|
|
|
first_champ.type_de_champ.update(mandatory: true, libelle: 'l')
|
|
|
|
allow(PiecesJustificativesService).to receive(:missing_pj_error_messages).and_return(['pj'])
|
|
|
|
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(response).to render_template(:modifier) }
|
|
|
|
it { expect(flash.alert).to eq(['Le champ l doit être rempli.', 'pj']) }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when dossier has no champ' do
|
|
|
|
let(:submit_payload) { { id: dossier.id } }
|
|
|
|
|
|
|
|
it 'does not raise any errors' do
|
|
|
|
subject
|
|
|
|
|
|
|
|
expect(response).to redirect_to(users_dossier_recapitulatif_path(dossier))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the user has an invitation but is not the owner' do
|
|
|
|
let(:dossier) { create(:dossier) }
|
|
|
|
let!(:invite) { create(:invite, dossier: dossier, user: user, type: 'InviteUser') }
|
|
|
|
|
|
|
|
before do
|
|
|
|
dossier.en_construction!
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(first_champ.reload.value).to eq('beautiful value') }
|
|
|
|
it { expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction)) }
|
|
|
|
it { expect(response).to redirect_to(users_dossiers_invite_path(invite)) }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-04-03 10:49:16 +02:00
|
|
|
describe '#index' do
|
|
|
|
before { sign_in(user) }
|
|
|
|
|
|
|
|
context 'when the user does not have any dossiers' do
|
|
|
|
before { get(:index) }
|
|
|
|
|
|
|
|
it { expect(assigns(:current_tab)).to eq('mes-dossiers') }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the user only have its own dossiers' do
|
|
|
|
let!(:own_dossier) { create(:dossier, user: user) }
|
|
|
|
|
|
|
|
before { get(:index) }
|
|
|
|
|
|
|
|
it { expect(assigns(:current_tab)).to eq('mes-dossiers') }
|
|
|
|
it { expect(assigns(:dossiers)).to match([own_dossier]) }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the user only have some dossiers invites' do
|
|
|
|
let!(:invite) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') }
|
|
|
|
|
|
|
|
before { get(:index) }
|
|
|
|
|
|
|
|
it { expect(assigns(:current_tab)).to eq('dossiers-invites') }
|
|
|
|
it { expect(assigns(:dossiers)).to match([invite.dossier]) }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the user has both' do
|
|
|
|
let!(:own_dossier) { create(:dossier, user: user) }
|
|
|
|
let!(:invite) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') }
|
|
|
|
|
|
|
|
context 'and there is no current_tab param' do
|
|
|
|
before { get(:index) }
|
|
|
|
|
|
|
|
it { expect(assigns(:current_tab)).to eq('mes-dossiers') }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'and there is "dossiers-invites" param' do
|
|
|
|
before { get(:index, params: { current_tab: 'dossiers-invites' }) }
|
|
|
|
|
|
|
|
it { expect(assigns(:current_tab)).to eq('dossiers-invites') }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'and there is "mes-dossiers" param' do
|
|
|
|
before { get(:index, params: { current_tab: 'mes-dossiers' }) }
|
|
|
|
|
|
|
|
it { expect(assigns(:current_tab)).to eq('mes-dossiers') }
|
|
|
|
end
|
|
|
|
end
|
2018-06-27 17:03:13 +02:00
|
|
|
|
|
|
|
describe 'sort order' do
|
|
|
|
before do
|
|
|
|
Timecop.freeze(4.days.ago) { create(:dossier, user: user) }
|
|
|
|
Timecop.freeze(2.days.ago) { create(:dossier, user: user) }
|
|
|
|
Timecop.freeze(4.days.ago) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') }
|
|
|
|
Timecop.freeze(2.days.ago) { create(:invite, dossier: create(:dossier), user: user, type: 'InviteUser') }
|
|
|
|
get(:index)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'displays the most recently updated dossiers first' do
|
|
|
|
expect(assigns(:user_dossiers).first.updated_at.to_date).to eq(2.days.ago.to_date)
|
|
|
|
expect(assigns(:user_dossiers).second.updated_at.to_date).to eq(4.days.ago.to_date)
|
|
|
|
expect(assigns(:dossiers_invites).first.updated_at.to_date).to eq(2.days.ago.to_date)
|
|
|
|
expect(assigns(:dossiers_invites).second.updated_at.to_date).to eq(4.days.ago.to_date)
|
|
|
|
end
|
|
|
|
end
|
2018-04-03 10:49:16 +02:00
|
|
|
end
|
2018-05-24 15:55:47 +02:00
|
|
|
|
2018-08-07 11:58:10 +02:00
|
|
|
describe '#show' do
|
2018-08-07 16:32:11 +02:00
|
|
|
let(:new_dossier_details_enabled) { false }
|
|
|
|
|
|
|
|
before do
|
|
|
|
Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, new_dossier_details_enabled)
|
|
|
|
sign_in(user)
|
|
|
|
end
|
|
|
|
|
2018-09-07 10:31:39 +02:00
|
|
|
after do
|
|
|
|
Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, false)
|
|
|
|
end
|
|
|
|
|
2018-08-07 11:58:10 +02:00
|
|
|
subject! { get(:show, params: { id: dossier.id }) }
|
|
|
|
|
|
|
|
context 'when the dossier is a brouillon' do
|
|
|
|
let(:dossier) { create(:dossier, user: user) }
|
2018-09-06 09:09:23 +02:00
|
|
|
it { is_expected.to redirect_to(brouillon_dossier_path(dossier)) }
|
2018-08-07 11:58:10 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the dossier has been submitted' do
|
|
|
|
let(:dossier) { create(:dossier, :en_construction, user: user) }
|
2018-08-07 16:32:11 +02:00
|
|
|
|
|
|
|
context 'and the new dossier details page is disabled' do
|
|
|
|
let(:new_dossier_details_enabled) { false }
|
|
|
|
it { is_expected.to redirect_to(users_dossier_recapitulatif_path(dossier)) }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'and the new dossier details page is enabled' do
|
|
|
|
let(:new_dossier_details_enabled) { true }
|
|
|
|
it { expect(assigns(:dossier)).to eq(dossier) }
|
|
|
|
it { is_expected.to render_template(:show) }
|
|
|
|
end
|
2018-08-07 11:58:10 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-08-14 15:06:44 +02:00
|
|
|
describe '#formulaire' do
|
|
|
|
let(:dossier) { create(:dossier, :en_construction, user: user) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, true)
|
|
|
|
sign_in(user)
|
|
|
|
end
|
|
|
|
|
2018-09-07 10:31:39 +02:00
|
|
|
after do
|
|
|
|
Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, false)
|
|
|
|
end
|
|
|
|
|
2018-08-29 16:57:01 +02:00
|
|
|
subject! { get(:demande, params: { id: dossier.id }) }
|
2018-08-14 15:06:44 +02:00
|
|
|
|
|
|
|
it { expect(assigns(:dossier)).to eq(dossier) }
|
2018-08-29 16:57:01 +02:00
|
|
|
it { is_expected.to render_template(:demande) }
|
2018-08-14 15:06:44 +02:00
|
|
|
end
|
|
|
|
|
2018-09-05 13:56:12 +02:00
|
|
|
describe "#create_commentaire" do
|
|
|
|
let(:dossier) { create(:dossier, :en_construction, user: user) }
|
|
|
|
let(:saved_commentaire) { dossier.commentaires.first }
|
|
|
|
let(:body) { "avant\napres" }
|
|
|
|
let(:file) { Rack::Test::UploadedFile.new("./spec/support/files/piece_justificative_0.pdf", 'application/pdf') }
|
|
|
|
let(:scan_result) { true }
|
|
|
|
|
|
|
|
subject {
|
|
|
|
post :create_commentaire, params: {
|
|
|
|
id: dossier.id,
|
|
|
|
commentaire: {
|
|
|
|
body: body,
|
|
|
|
file: file
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
before do
|
|
|
|
sign_in(user)
|
|
|
|
allow(ClamavService).to receive(:safe_file?).and_return(scan_result)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "creates a commentaire" do
|
|
|
|
expect { subject }.to change(Commentaire, :count).by(1)
|
|
|
|
|
|
|
|
expect(response).to redirect_to(messagerie_dossier_path(dossier))
|
|
|
|
expect(flash.notice).to be_present
|
|
|
|
end
|
|
|
|
|
|
|
|
context "when the commentaire creation fails" do
|
|
|
|
let(:scan_result) { false }
|
|
|
|
|
|
|
|
it "renders the messagerie page with the invalid commentaire" do
|
|
|
|
expect { subject }.not_to change(Commentaire, :count)
|
|
|
|
|
|
|
|
expect(response).to render_template :messagerie
|
|
|
|
expect(flash.alert).to be_present
|
|
|
|
expect(assigns(:commentaire).body).to eq("<p>avant\n<br />apres</p>")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-05-24 15:55:47 +02:00
|
|
|
describe '#ask_deletion' do
|
|
|
|
before { sign_in(user) }
|
|
|
|
|
|
|
|
subject { post :ask_deletion, params: { id: dossier.id } }
|
|
|
|
|
2018-06-13 13:58:14 +02:00
|
|
|
shared_examples_for "the dossier can not be deleted" do
|
|
|
|
it do
|
|
|
|
expect(DossierMailer).not_to receive(:notify_deletion_to_administration)
|
|
|
|
expect(DossierMailer).not_to receive(:notify_deletion_to_user)
|
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
|
|
|
it do
|
|
|
|
subject
|
|
|
|
expect(Dossier.find_by(id: dossier.id)).not_to eq(nil)
|
|
|
|
expect(dossier.procedure.deleted_dossiers.count).to eq(0)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-05-24 15:55:47 +02:00
|
|
|
context 'when dossier is owned by signed in user' do
|
2018-08-02 16:36:50 +02:00
|
|
|
let(:dossier) { create(:dossier, :en_construction, user: user, autorisation_donnees: true) }
|
2018-05-24 15:55:47 +02:00
|
|
|
|
|
|
|
it do
|
2018-05-30 11:36:48 +02:00
|
|
|
expect(DossierMailer).to receive(:notify_deletion_to_administration).with(kind_of(DeletedDossier), dossier.procedure.administrateur.email).and_return(double(deliver_later: nil))
|
|
|
|
expect(DossierMailer).to receive(:notify_deletion_to_user).with(kind_of(DeletedDossier), dossier.user.email).and_return(double(deliver_later: nil))
|
2018-05-24 15:55:47 +02:00
|
|
|
subject
|
|
|
|
end
|
|
|
|
|
2018-05-30 11:36:48 +02:00
|
|
|
it do
|
|
|
|
procedure = dossier.procedure
|
|
|
|
dossier_id = dossier.id
|
|
|
|
subject
|
|
|
|
expect(Dossier.find_by(id: dossier_id)).to eq(nil)
|
|
|
|
expect(procedure.deleted_dossiers.count).to eq(1)
|
|
|
|
expect(procedure.deleted_dossiers.first.dossier_id).to eq(dossier_id)
|
|
|
|
end
|
2018-06-13 13:58:14 +02:00
|
|
|
|
2018-06-27 14:47:02 +02:00
|
|
|
it { is_expected.to redirect_to(dossiers_path) }
|
2018-06-13 13:58:14 +02:00
|
|
|
|
|
|
|
context "and the instruction has started" do
|
|
|
|
let(:dossier) { create(:dossier, :en_instruction, user: user, autorisation_donnees: true) }
|
|
|
|
|
|
|
|
it_behaves_like "the dossier can not be deleted"
|
|
|
|
it { is_expected.to redirect_to(users_dossier_path(dossier)) }
|
|
|
|
end
|
2018-05-24 15:55:47 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'when dossier is not owned by signed in user' do
|
|
|
|
let(:user2) { create(:user) }
|
|
|
|
let(:dossier) { create(:dossier, user: user2, autorisation_donnees: true) }
|
|
|
|
|
2018-06-13 13:58:14 +02:00
|
|
|
it_behaves_like "the dossier can not be deleted"
|
2018-05-24 15:55:47 +02:00
|
|
|
it { is_expected.to redirect_to(root_path) }
|
|
|
|
end
|
|
|
|
end
|
2017-06-29 14:18:12 +02:00
|
|
|
end
|