20136b7ac8
* add base controller for public api * add dossiers controller with basic checks * create the dossier * ensure content-type is json * prefill dossier with given values * mark a dossier as prefilled When a dossier is prefilled, it's allowed not to have a user. Plus, we add a secure token to the dossier, which we will need later to set a user after sign in / sign up. * set user as owner of an orphan prefilled dossier When a visitor comes from the dossier_url answered by the public api, the dossier is orphan: - when the user is already authenticated: they become the owner - when the user is not authenticated: they can sign in / sign up / france_connect and then they become the owner So here is the procedure: - allow to sign in / sign up / france connect when user is unauthenticated - set dossier ownership when the dossier is orphan - check dossier ownership when the dossier is not - redirect to brouillon path when user is signed in and owner * mark the dossier as prefilled when it's prefilled (even with a GET request, because it will be useful later on, for exmample in order to cleanup the unused prefilled dossiers) * system spec: prefilling dossier with post request
135 lines
4.5 KiB
Ruby
135 lines
4.5 KiB
Ruby
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
|
|
|
|
it "responds with the brouillon dossier path" do
|
|
create_request
|
|
expect(JSON.parse(response.body)["dossier_url"]).to eq(
|
|
"http://test.host#{commencer_path(procedure.path, prefill_token: Dossier.last.prefill_token)}"
|
|
)
|
|
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" }
|
|
|
|
let(:params) {
|
|
{
|
|
id: procedure.id,
|
|
"champ_#{type_de_champ_1.to_typed_id}" => value_1,
|
|
"champ_#{type_de_champ_2.to_typed_id}" => value_2
|
|
}
|
|
}
|
|
|
|
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)
|
|
end
|
|
end
|
|
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
|
|
let(:procedure) { create(:procedure, :published) }
|
|
end
|
|
end
|
|
|
|
context 'when the procedure is brouillon' do
|
|
it_behaves_like 'the procedure is found' do
|
|
let(:procedure) { create(:procedure, :draft) }
|
|
end
|
|
end
|
|
|
|
context 'when the procedure is not publiee and not brouillon' do
|
|
it_behaves_like 'the procedure is not found' do
|
|
let(:procedure) { create(:procedure, :closed) }
|
|
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
|
|
|
|
private
|
|
|
|
def find_champ_by_stable_id(dossier, stable_id)
|
|
dossier.champs_public.joins(:type_de_champ).find_by(types_de_champ: { stable_id: stable_id })
|
|
end
|
|
end
|