2024-04-29 00:17:15 +02:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2023-01-03 14:46:10 +01:00
|
|
|
RSpec.describe API::Public::V1::DossiersController, type: :controller do
|
|
|
|
include Rails.application.routes.url_helpers
|
|
|
|
|
|
|
|
describe '#create' do
|
|
|
|
# Request prototype:
|
|
|
|
# curl --request POST 'http://localhost:3000/api/public/v1/demarches/2/dossiers' \
|
|
|
|
# --header 'Content-Type: application/json' \
|
|
|
|
# --data '{"champ_Q2hhbXAtMjI=": "personne@fournisseur.fr"}'
|
|
|
|
|
|
|
|
context 'when the request content type is json' do
|
|
|
|
let(:params) { { id: procedure.id } }
|
|
|
|
subject(:create_request) do
|
|
|
|
request.headers["Content-Type"] = "application/json"
|
|
|
|
post :create, params: params
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples 'the procedure is found' do
|
|
|
|
context 'when the dossier can be saved' do
|
|
|
|
it { expect(create_request).to have_http_status(:created) }
|
|
|
|
|
|
|
|
it { expect { create_request }.to change { Dossier.count }.by(1) }
|
|
|
|
|
|
|
|
it "marks the created dossier as prefilled" do
|
|
|
|
create_request
|
|
|
|
expect(Dossier.last.prefilled).to eq(true)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "creates the dossier without a user" do
|
|
|
|
create_request
|
|
|
|
expect(Dossier.last.user).to eq(nil)
|
|
|
|
end
|
|
|
|
|
2023-01-06 14:46:27 +01:00
|
|
|
it "responds with the brouillon dossier url and id" do
|
2023-01-03 14:46:10 +01:00
|
|
|
create_request
|
2023-01-06 14:46:27 +01:00
|
|
|
|
|
|
|
dossier = Dossier.last
|
|
|
|
dossier_url = "http://test.host#{commencer_path(procedure.path, prefill_token: dossier.prefill_token)}"
|
2023-04-19 11:00:18 +02:00
|
|
|
expect(response.parsed_body["dossier_url"]).to eq(dossier_url)
|
|
|
|
expect(response.parsed_body["dossier_id"]).to eq(dossier.to_typed_id)
|
|
|
|
expect(response.parsed_body["dossier_number"]).to eq(dossier.id)
|
2023-01-03 14:46:10 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'when prefill values are given' 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" }
|
|
|
|
|
2023-09-07 10:10:07 +02:00
|
|
|
let(:prenom_value) { "John" }
|
|
|
|
let(:genre_value) { "M." }
|
|
|
|
|
2023-01-03 14:46:10 +01:00
|
|
|
let(:params) {
|
|
|
|
{
|
|
|
|
id: procedure.id,
|
2023-02-22 19:32:25 +01:00
|
|
|
"champ_#{type_de_champ_1.to_typed_id_for_query}" => value_1,
|
2023-09-07 10:10:07 +02:00
|
|
|
"champ_#{type_de_champ_2.to_typed_id_for_query}" => value_2,
|
|
|
|
"identite_prenom" => prenom_value,
|
|
|
|
"identite_genre" => genre_value
|
2023-01-03 14:46:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
it "prefills the dossier's champs with the given values" do
|
|
|
|
create_request
|
|
|
|
|
|
|
|
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)
|
2023-09-07 10:10:07 +02:00
|
|
|
expect(dossier.individual.prenom).to eq(prenom_value)
|
|
|
|
expect(dossier.individual.gender).to eq(genre_value)
|
2023-01-03 14:46:10 +01:00
|
|
|
end
|
|
|
|
end
|
2024-12-06 17:29:50 +01:00
|
|
|
|
|
|
|
context 'when prefill given values contains more than one rows for repetitions' do
|
|
|
|
let(:procedure) { create(:procedure, :published, types_de_champ_public:) }
|
|
|
|
let(:types_de_champ_public) do
|
|
|
|
[
|
|
|
|
type: :repetition,
|
|
|
|
children: [
|
|
|
|
{ type: :text, libelle: 'child of repet text' }
|
|
|
|
]
|
|
|
|
]
|
|
|
|
end
|
|
|
|
let(:prefilled_champs) { TypesDeChamp::PrefillTypeDeChamp.wrap(procedure.published_revision.types_de_champ, procedure.active_revision) }
|
|
|
|
let(:prefilled_champs_as_params) { prefilled_champs.map { |type_de_champ| ["champ_#{type_de_champ.to_typed_id_for_query}", type_de_champ.example_value] }.to_h }
|
|
|
|
let(:params) do
|
|
|
|
prefilled_champs_as_params.merge(id: procedure.id)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "updates the champs with the new values and mark them as prefilled" do
|
|
|
|
expect { create_request }.not_to raise_error(ActiveRecord::RecordNotFound)
|
|
|
|
end
|
|
|
|
end
|
2023-01-03 14:46:10 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the dossier can not be saved' do
|
|
|
|
before do
|
|
|
|
allow_any_instance_of(Dossier).to receive(:save).and_return(false)
|
|
|
|
allow_any_instance_of(Dossier).to receive(:errors).and_return(
|
|
|
|
ActiveModel::Errors.new(Dossier.new).tap { |e| e.add(:base, "something went wrong") }
|
|
|
|
)
|
|
|
|
|
|
|
|
create_request
|
|
|
|
end
|
|
|
|
|
|
|
|
it { expect(response).to have_http_status(:bad_request) }
|
|
|
|
|
|
|
|
it { expect(response).to have_failed_with("something went wrong") }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
shared_examples 'the procedure is not found' do
|
|
|
|
before { create_request }
|
|
|
|
|
|
|
|
it { expect(response).to have_http_status(:not_found) }
|
|
|
|
|
|
|
|
it { expect(response).to have_failed_with("procedure #{procedure.id} is not found") }
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the procedure is found' do
|
|
|
|
context 'when the procedure is publiee' do
|
|
|
|
it_behaves_like 'the procedure is found' do
|
2023-09-07 10:10:07 +02:00
|
|
|
let(:procedure) { create(:procedure, :for_individual, :published) }
|
2023-01-03 14:46:10 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the procedure is brouillon' do
|
|
|
|
it_behaves_like 'the procedure is found' do
|
2023-09-07 10:10:07 +02:00
|
|
|
let(:procedure) { create(:procedure, :for_individual, :draft) }
|
2023-01-03 14:46:10 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the procedure is not publiee and not brouillon' do
|
|
|
|
it_behaves_like 'the procedure is not found' do
|
2023-09-07 10:10:07 +02:00
|
|
|
let(:procedure) { create(:procedure, :for_individual, :closed) }
|
2023-01-03 14:46:10 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the procedure is not found' do
|
|
|
|
it_behaves_like 'the procedure is not found' do
|
|
|
|
let(:procedure) { double(Procedure, id: -1) }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when the request content type is not json' do
|
|
|
|
subject(:create_request) do
|
|
|
|
request.headers["Content-Type"] = "application/xhtml+xml"
|
|
|
|
post :create, params: { id: 0 }
|
|
|
|
end
|
|
|
|
|
|
|
|
before { create_request }
|
|
|
|
|
|
|
|
it { expect(response).to have_http_status(:bad_request) }
|
|
|
|
|
|
|
|
it { expect(response).to have_failed_with("Content-Type should be json") }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-02-23 21:55:03 +01:00
|
|
|
describe '#index' do
|
|
|
|
let(:procedure) { dossier.procedure }
|
|
|
|
let(:dossier) { create(:dossier, prefilled: true, user: nil) }
|
|
|
|
let(:prefill_token) { dossier.prefill_token }
|
|
|
|
let(:params) { { id: procedure.id, prefill_token: } }
|
|
|
|
|
|
|
|
subject(:create_request) do
|
|
|
|
request.headers["Content-Type"] = "application/json"
|
|
|
|
get :index, params:
|
|
|
|
end
|
|
|
|
|
2023-04-19 11:00:18 +02:00
|
|
|
let(:body) { response.parsed_body.map(&:deep_symbolize_keys) }
|
2023-02-23 21:55:03 +01:00
|
|
|
|
|
|
|
before { create_request }
|
|
|
|
|
|
|
|
context 'not found' do
|
|
|
|
let(:prefill_token) { 'invalid_token' }
|
|
|
|
it 'should respond with and empty array' do
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
expect(body).to eq([])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when dossier prefilled' do
|
|
|
|
it 'should respond with dossier state' do
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
expect(body.first[:state]).to eq('prefilled')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when dossier brouillon' do
|
|
|
|
let(:dossier) { create(:dossier, prefilled: true) }
|
|
|
|
it 'should respond with dossier state' do
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
expect(body.first[:state]).to eq('brouillon')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'when dossier en_construction' do
|
|
|
|
let(:dossier) { create(:dossier, :en_construction, prefilled: true) }
|
|
|
|
it 'should respond with dossier state' do
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
expect(body.first[:state]).to eq('en_construction')
|
|
|
|
expect(body.first[:submitted_at]).to eq(dossier.depose_at.iso8601)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'with multiple tokens' do
|
|
|
|
let(:dossier) { create(:dossier, prefilled: true, user: nil) }
|
|
|
|
let(:other_dossier) { create(:dossier, prefilled: true, user: nil, procedure:) }
|
|
|
|
let(:prefill_token) { [dossier.prefill_token, other_dossier.prefill_token] }
|
|
|
|
|
|
|
|
it 'should respond with dossiers state' do
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
expect(body.map { _1[:dossier_number] }).to match_array([dossier.id, other_dossier.id])
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'comma separated tokens' do
|
|
|
|
let(:prefill_token) { [dossier.prefill_token, other_dossier.prefill_token].join(',') }
|
|
|
|
|
|
|
|
it 'should respond with dossiers state' do
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
|
|
expect(body.map { _1[:dossier_number] }).to match_array([dossier.id, other_dossier.id])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-01-03 14:46:10 +01:00
|
|
|
private
|
|
|
|
|
|
|
|
def find_champ_by_stable_id(dossier, stable_id)
|
2024-07-01 15:31:32 +02:00
|
|
|
dossier.champs.find_by(stable_id:)
|
2023-01-03 14:46:10 +01:00
|
|
|
end
|
|
|
|
end
|