Merge pull request #8513 from demarches-simplifiees/feature/prefill_repetible

Prefill repeatable
This commit is contained in:
Damien Le Thiec 2023-02-27 09:58:53 +00:00 committed by GitHub
commit 67bbacbb05
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 589 additions and 289 deletions

View file

@ -12,6 +12,6 @@ class PrefillTypeDeChampsController < ApplicationController
end
def set_prefill_type_de_champ
@type_de_champ = TypesDeChamp::PrefillTypeDeChamp.build(@procedure.active_revision.types_de_champ_public.fillable.find(params[:id]))
@type_de_champ = TypesDeChamp::PrefillTypeDeChamp.build(@procedure.active_revision.types_de_champ.fillable.find(params[:id]), @procedure.active_revision)
end
end

View file

@ -142,7 +142,7 @@ module ApplicationHelper
end
def new_tab_suffix(title)
"#{title}#{t('utils.new_tab')}"
"#{title}#{I18n.t('utils.new_tab')}"
end
def download_details(attachment)

View file

@ -19,7 +19,19 @@ class ApplicationRecord < ActiveRecord::Base
GraphQL::Schema::UniqueWithinType.decode(id)[1]
end
def self.stable_id_from_typed_id(prefixed_typed_id)
return nil unless prefixed_typed_id.starts_with?("champ_")
self.id_from_typed_id(prefixed_typed_id.gsub("champ_", "")).to_i
rescue
nil
end
def to_typed_id
GraphQL::Schema::UniqueWithinType.encode(self.class.name, id)
end
def to_typed_id_for_query
to_typed_id.delete("==")
end
end

View file

@ -74,6 +74,10 @@ class Champ < ApplicationRecord
:refresh_after_update?,
to: :type_de_champ
delegate :to_typed_id, :to_typed_id_for_query, to: :type_de_champ, prefix: true
delegate :revision, to: :dossier, prefix: true
scope :updated_since?, -> (date) { where('champs.updated_at > ?', date) }
scope :public_only, -> { where(private: false) }
scope :private_only, -> { where(private: true) }

View file

@ -7,7 +7,7 @@ module DossierPrefillableConcern
return unless champs_public_attributes.any?
attr = { prefilled: true }
attr[:champs_public_attributes] = champs_public_attributes.map { |h| h.merge(prefilled: true) }
attr[:champs_public_all_attributes] = champs_public_attributes.map { |h| h.merge(prefilled: true) }
assign_attributes(attr)
save(validate: false)

View file

@ -15,7 +15,7 @@ class PrefillDescription < SimpleDelegator
end
def types_de_champ
TypesDeChamp::PrefillTypeDeChamp.wrap(active_revision.types_de_champ_public.fillable.partition(&:prefillable?).flatten)
TypesDeChamp::PrefillTypeDeChamp.wrap(active_revision.types_de_champ_public.fillable.partition(&:prefillable?).flatten, active_revision)
end
def include?(type_de_champ_id)
@ -27,7 +27,7 @@ class PrefillDescription < SimpleDelegator
end
def prefill_link
@prefill_link ||= commencer_url({ path: path }.merge(prefilled_champs_for_link))
@prefill_link ||= CGI.unescape(commencer_url({ path: path }.merge(prefilled_champs_as_params)))
end
def prefill_query
@ -35,12 +35,12 @@ class PrefillDescription < SimpleDelegator
<<~TEXT
curl --request POST '#{api_public_v1_dossiers_url(self)}' \\
--header 'Content-Type: application/json' \\
--data '{#{prefilled_champs_for_query}}'
--data '#{prefilled_champs_as_params.to_json}'
TEXT
end
def prefilled_champs
@prefilled_champs ||= TypesDeChamp::PrefillTypeDeChamp.wrap(active_fillable_public_types_de_champ.where(id: selected_type_de_champ_ids))
@prefilled_champs ||= TypesDeChamp::PrefillTypeDeChamp.wrap(active_fillable_public_types_de_champ.where(id: selected_type_de_champ_ids), active_revision)
end
private
@ -49,29 +49,7 @@ class PrefillDescription < SimpleDelegator
active_revision.types_de_champ_public.fillable
end
def prefilled_champs_for_link
prefilled_champs_as_params.map(&:to_a).to_h
end
def prefilled_champs_for_query
prefilled_champs_as_params.map(&:to_s).join(', ')
end
def prefilled_champs_as_params
prefilled_champs.map { |type_de_champ| Param.new(type_de_champ.to_typed_id, type_de_champ.example_value) }
end
Param = Struct.new(:key, :value) do
def to_a
["champ_#{key}", value]
end
def to_s
if value.is_a?(Array)
"\"champ_#{key}\": #{value}"
else
"\"champ_#{key}\": \"#{value}\""
end
end
prefilled_champs.map { |type_de_champ| ["champ_#{type_de_champ.to_typed_id_for_query}", type_de_champ.example_value] }.to_h
end
end

View file

@ -1,33 +1,27 @@
class PrefillParams
attr_reader :dossier, :params
def initialize(dossier, params)
@dossier = dossier
@params = params
end
def to_a
build_prefill_values.filter(&:prefillable?).map(&:to_h)
build_prefill_values.filter(&:prefillable?).map(&:champ_attributes).flatten
end
private
def build_prefill_values
value_by_stable_id = @params
.map { |prefixed_typed_id, value| [stable_id_from_typed_id(prefixed_typed_id), value] }
value_by_stable_id = params
.map { |prefixed_typed_id, value| [Champ.stable_id_from_typed_id(prefixed_typed_id), value] }
.filter { |stable_id, value| stable_id.present? && value.present? }
.to_h
@dossier
dossier
.find_champs_by_stable_ids(value_by_stable_id.keys)
.map { |champ| [champ, value_by_stable_id[champ.stable_id]] }
.map { |champ, value| PrefillValue.new(champ:, value:) }
end
def stable_id_from_typed_id(prefixed_typed_id)
return nil unless prefixed_typed_id.starts_with?("champ_")
Champ.id_from_typed_id(prefixed_typed_id.gsub("champ_", "")).to_i
rescue
nil
.map { |champ, value| PrefillValue.new(champ:, value:, dossier:) }
end
class PrefillValue
@ -46,19 +40,22 @@ class PrefillParams
TypeDeChamp.type_champs.fetch(:epci)
]
attr_reader :champ, :value
attr_reader :champ, :value, :dossier
def initialize(champ:, value:)
def initialize(champ:, value:, dossier:)
@champ = champ
@value = value
@dossier = dossier
end
def prefillable?
champ.prefillable? && valid?
champ.prefillable? && valid? && champ_attributes.present?
end
def to_h
{ id: champ.id }.merge(champ_attributes)
def champ_attributes
@champ_attributes ||= TypesDeChamp::PrefillTypeDeChamp
.build(champ.type_de_champ, dossier.revision)
.to_assignable_attributes(champ, value)
end
private
@ -69,11 +66,5 @@ class PrefillParams
champ.assign_attributes(champ_attributes)
champ.valid?(:prefill)
end
def champ_attributes
TypesDeChamp::PrefillTypeDeChamp
.build(champ.type_de_champ)
.transform_value_to_assignable_attributes(value)
end
end
end

View file

@ -32,6 +32,8 @@ class ProcedureRevision < ApplicationRecord
validate :conditions_are_valid?
delegate :path, to: :procedure, prefix: true
def build_champs_public
# reload: it can be out of sync in test if some tdcs are added wihtout using add_tdc
types_de_champ_public.reload.map(&:build_champ)

View file

@ -268,6 +268,7 @@ class TypeDeChamp < ApplicationRecord
TypeDeChamp.type_champs.fetch(:yes_no),
TypeDeChamp.type_champs.fetch(:checkbox),
TypeDeChamp.type_champs.fetch(:drop_down_list),
TypeDeChamp.type_champs.fetch(:repetition),
TypeDeChamp.type_champs.fetch(:departements),
TypeDeChamp.type_champs.fetch(:multiple_drop_down_list),
TypeDeChamp.type_champs.fetch(:epci)

View file

@ -1,5 +1,5 @@
class TypesDeChamp::PrefillDepartementTypeDeChamp < TypesDeChamp::PrefillTypeDeChamp
def possible_values
def all_possible_values
departements.map { |departement| "#{departement[:code]} (#{departement[:name]})" }
end

View file

@ -1,5 +1,5 @@
class TypesDeChamp::PrefillDropDownListTypeDeChamp < TypesDeChamp::PrefillTypeDeChamp
def possible_values
def all_possible_values
if drop_down_other?
drop_down_list_enabled_non_empty_options.insert(
0,
@ -11,6 +11,6 @@ class TypesDeChamp::PrefillDropDownListTypeDeChamp < TypesDeChamp::PrefillTypeDe
end
def example_value
possible_values.first
all_possible_values.first
end
end

View file

@ -11,10 +11,10 @@ class TypesDeChamp::PrefillEpciTypeDeChamp < TypesDeChamp::PrefillTypeDeChamp
[departement_code, epci_code]
end
def transform_value_to_assignable_attributes(value)
return { code_departement: nil, value: nil } if value.blank? || !value.is_a?(Array)
return { code_departement: value.first, value: nil } if value.one?
{ code_departement: value.first, value: value.second }
def to_assignable_attributes(champ, value)
return { id: champ.id, code_departement: nil, value: nil } if value.blank? || !value.is_a?(Array)
return { id: champ.id, code_departement: value.first, value: nil } if value.one?
{ id: champ.id, code_departement: value.first, value: value.second }
end
private

View file

@ -1,8 +1,8 @@
class TypesDeChamp::PrefillMultipleDropDownListTypeDeChamp < TypesDeChamp::PrefillDropDownListTypeDeChamp
def example_value
return nil if possible_values.empty?
return possible_values.first if possible_values.one?
return nil if all_possible_values.empty?
return all_possible_values.first if all_possible_values.one?
[possible_values.first, possible_values.second]
[all_possible_values.first, all_possible_values.second]
end
end

View file

@ -1,5 +1,5 @@
class TypesDeChamp::PrefillPaysTypeDeChamp < TypesDeChamp::PrefillTypeDeChamp
def possible_values
def all_possible_values
countries.map { |country| "#{country[:code]} (#{country[:name]})" }
end

View file

@ -1,5 +1,5 @@
class TypesDeChamp::PrefillRegionTypeDeChamp < TypesDeChamp::PrefillTypeDeChamp
def possible_values
def all_possible_values
regions.map { |region| "#{region[:code]} (#{region[:name]})" }
end

View file

@ -0,0 +1,69 @@
class TypesDeChamp::PrefillRepetitionTypeDeChamp < TypesDeChamp::PrefillTypeDeChamp
include ActionView::Helpers::UrlHelper
include ApplicationHelper
def possible_values
[
I18n.t("views.prefill_descriptions.edit.possible_values.#{type_champ}_html"),
subchamps_all_possible_values
].join("</br>").html_safe # rubocop:disable Rails/OutputSafety
end
def example_value
[row_values_format, row_values_format]
end
def to_assignable_attributes(champ, value)
return [] unless value.is_a?(Array)
value.map.with_index do |repetition, index|
PrefillRepetitionRow.new(champ, repetition, index, @revision).to_assignable_attributes
end.reject(&:blank?)
end
private
def subchamps_all_possible_values
"<ul>" + prefillable_subchamps.map do |prefill_type_de_champ|
"<li>champ_#{prefill_type_de_champ.to_typed_id_for_query}: #{prefill_type_de_champ.possible_values}</li>"
end.join + "</ul>"
end
def row_values_format
@row_example_value ||=
prefillable_subchamps.map do |prefill_type_de_champ|
["champ_#{prefill_type_de_champ.to_typed_id_for_query}", prefill_type_de_champ.example_value.to_s]
end.to_h
end
def prefillable_subchamps
@prefillable_subchamps ||=
TypesDeChamp::PrefillTypeDeChamp.wrap(@revision.children_of(self).filter(&:prefillable?), @revision)
end
class PrefillRepetitionRow
attr_reader :champ, :repetition, :index, :revision
def initialize(champ, repetition, index, revision)
@champ = champ
@repetition = repetition
@index = index
@revision = revision
end
def to_assignable_attributes
return unless repetition.is_a?(Hash)
row = champ.rows[index] || champ.add_row(champ.dossier_revision)
repetition.map do |key, value|
next unless key.is_a?(String) && key.starts_with?("champ_")
subchamp = row.find { |champ| champ.stable_id == Champ.stable_id_from_typed_id(key) }
next unless subchamp
TypesDeChamp::PrefillTypeDeChamp.build(subchamp.type_de_champ, revision).to_assignable_attributes(subchamp, value)
end.compact
end
end
end

View file

@ -1,30 +1,51 @@
class TypesDeChamp::PrefillTypeDeChamp < SimpleDelegator
include ActionView::Helpers::UrlHelper
include ApplicationHelper
POSSIBLE_VALUES_THRESHOLD = 5
def self.build(type_de_champ)
def initialize(type_de_champ, revision)
super(type_de_champ)
@revision = revision
end
def self.build(type_de_champ, revision)
case type_de_champ.type_champ
when TypeDeChamp.type_champs.fetch(:drop_down_list)
TypesDeChamp::PrefillDropDownListTypeDeChamp.new(type_de_champ)
TypesDeChamp::PrefillDropDownListTypeDeChamp.new(type_de_champ, revision)
when TypeDeChamp.type_champs.fetch(:multiple_drop_down_list)
TypesDeChamp::PrefillMultipleDropDownListTypeDeChamp.new(type_de_champ)
TypesDeChamp::PrefillMultipleDropDownListTypeDeChamp.new(type_de_champ, revision)
when TypeDeChamp.type_champs.fetch(:pays)
TypesDeChamp::PrefillPaysTypeDeChamp.new(type_de_champ)
TypesDeChamp::PrefillPaysTypeDeChamp.new(type_de_champ, revision)
when TypeDeChamp.type_champs.fetch(:regions)
TypesDeChamp::PrefillRegionTypeDeChamp.new(type_de_champ)
TypesDeChamp::PrefillRegionTypeDeChamp.new(type_de_champ, revision)
when TypeDeChamp.type_champs.fetch(:repetition)
TypesDeChamp::PrefillRepetitionTypeDeChamp.new(type_de_champ, revision)
when TypeDeChamp.type_champs.fetch(:departements)
TypesDeChamp::PrefillDepartementTypeDeChamp.new(type_de_champ)
TypesDeChamp::PrefillDepartementTypeDeChamp.new(type_de_champ, revision)
when TypeDeChamp.type_champs.fetch(:epci)
TypesDeChamp::PrefillEpciTypeDeChamp.new(type_de_champ)
TypesDeChamp::PrefillEpciTypeDeChamp.new(type_de_champ, revision)
else
new(type_de_champ)
new(type_de_champ, revision)
end
end
def self.wrap(collection)
collection.map { |type_de_champ| build(type_de_champ) }
def self.wrap(collection, revision)
collection.map { |type_de_champ| build(type_de_champ, revision) }
end
def possible_values
values = []
values << description if description.present?
if too_many_possible_values?
values << link_to_all_possible_values
else
values << all_possible_values.to_sentence
end
values.compact.join('<br>').html_safe # rubocop:disable Rails/OutputSafety
end
def all_possible_values
[]
end
@ -34,11 +55,28 @@ class TypesDeChamp::PrefillTypeDeChamp < SimpleDelegator
I18n.t("views.prefill_descriptions.edit.examples.#{type_champ}")
end
def too_many_possible_values?
possible_values.count > POSSIBLE_VALUES_THRESHOLD
def to_assignable_attributes(champ, value)
{ id: champ.id, value: value }
end
def transform_value_to_assignable_attributes(value)
{ value: value }
private
def link_to_all_possible_values
return unless prefillable?
link_to(
I18n.t("views.prefill_descriptions.edit.possible_values.link.text"),
Rails.application.routes.url_helpers.prefill_type_de_champ_path(revision.procedure_path, self),
title: new_tab_suffix(I18n.t("views.prefill_descriptions.edit.possible_values.link.title")),
**external_link_attributes
)
end
def too_many_possible_values?
all_possible_values.count > POSSIBLE_VALUES_THRESHOLD
end
def description
@description ||= I18n.t("views.prefill_descriptions.edit.possible_values.#{type_champ}_html", default: nil)&.html_safe # rubocop:disable Rails/OutputSafety
end
end

View file

@ -27,7 +27,7 @@
%th
= t("views.prefill_descriptions.edit.champ_id")
%td
= type_de_champ.to_typed_id
= type_de_champ.to_typed_id_for_query
%tr
%th
= t("views.prefill_descriptions.edit.champ_type")
@ -37,13 +37,7 @@
%th
= t("views.prefill_descriptions.edit.possible_values.title")
%td
- if I18n.exists?("views.prefill_descriptions.edit.possible_values.#{type_de_champ.type_champ}_html")
= t("views.prefill_descriptions.edit.possible_values.#{type_de_champ.type_champ}_html")
%br
- if type_de_champ.too_many_possible_values?
= link_to t("views.prefill_descriptions.edit.possible_values.link.text"), prefill_type_de_champ_path(prefill_description.path, type_de_champ), title: new_tab_suffix(t("views.prefill_descriptions.edit.possible_values.link.title")), **external_link_attributes
- else
= type_de_champ.possible_values.to_sentence
= type_de_champ.possible_values
%tr{ class: prefillable ? "" : "fr-text-mention--grey" }
%th
= t("views.prefill_descriptions.edit.examples.title")

View file

@ -15,7 +15,7 @@
%th
= t("views.prefill_descriptions.edit.champ_id")
%td
= @type_de_champ.to_typed_id
= @type_de_champ.to_typed_id_for_query
%tr
%th
= t("views.prefill_descriptions.edit.champ_type")
@ -26,7 +26,7 @@
= t("views.prefill_descriptions.edit.possible_values.title")
%td
.fr-grid-row.fr-grid-row--gutters.fr-py-5w
- @type_de_champ.possible_values.each do |possible_value|
- @type_de_champ.all_possible_values.each do |possible_value|
.fr-col-lg-3.fr-col-md-4.fr-col-sm-6.fr-col-12
= possible_value
%tr

View file

@ -130,10 +130,13 @@ en:
checkbox_html: '"true" to check, "false" to uncheck'
pays_html: An <a href="https://en.wikipedia.org/wiki/ISO_3166-2" target="_blank" rel="noopener noreferrer">ISO 3166-2 country code</a>
departements_html: A <a href="https://fr.wikipedia.org/wiki/Num%C3%A9rotation_des_d%C3%A9partements_fran%C3%A7ais" target="_blank">department number</a>
regions_html: An <a href="https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise" target="_blank" rel="noopener noreferrer">INSEE region code</a>
drop_down_list_html: A choice among those selected when the procedure was created
date_html: ISO8601 date
datetime_html: ISO8601 datetime
drop_down_list_other_html: Any value
repetition_html: A array of hashes with possible values for each field of the repetition.
regions_html: An <a href="https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise" target="_blank" rel="noopener noreferrer">INSEE region code</a>
regions_html: An <a href="https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise" target="_blank" rel="noopener noreferrer">INSEE region code</a>
epci_html: An array of the department code and the <a href="https://geo.api.gouv.fr/epcis" target="_blank" rel="noopener noreferrer">EPCI one</a>.
examples:
title: Example

View file

@ -121,10 +121,12 @@ fr:
checkbox_html: '"true" pour coché, "false" pour décoché'
pays_html: Un <a href="https://en.wikipedia.org/wiki/ISO_3166-2" target="_blank" rel="noopener noreferrer">code pays ISO 3166-2</a>
departements_html: Un <a href="https://fr.wikipedia.org/wiki/Num%C3%A9rotation_des_d%C3%A9partements_fran%C3%A7ais" target="_blank">numéro de département</a>
regions_html: Un <a href="https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise" target="_blank" rel="noopener noreferrer">code INSEE de région</a>
drop_down_list_html: Un choix parmi ceux sélectionnés à la création de la procédure
datetime_html: Datetime au format ISO8601
date_html: Date au format ISO8601
drop_down_list_other_html: Toute valeur
repetition_html: Un tableau de dictionnaires avec les valeurs possibles pour chaque champ de la répétition.
regions_html: Un <a href="https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise" target="_blank" rel="noopener noreferrer">code INSEE de région</a>
epci_html: Un tableau contenant le code de département et <a href="https://geo.api.gouv.fr/epcis" target="_blank" rel="noopener noreferrer">celui de l'EPCI</a>.
examples:
title: Exemple

View file

@ -50,8 +50,8 @@ RSpec.describe API::Public::V1::DossiersController, type: :controller do
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
"champ_#{type_de_champ_1.to_typed_id_for_query}" => value_1,
"champ_#{type_de_champ_2.to_typed_id_for_query}" => value_2
}
}

View file

@ -286,9 +286,9 @@ describe API::V1::DossiersController do
it 'should have rows' do
expect(subject.size).to eq(2)
expect(subject[0][:id]).to eq(1)
expect(subject[0][:champs].size).to eq(1)
expect(subject[0][:champs].map { |c| c[:value] }).to eq(['text'])
expect(subject[0][:champs].map { |c| c[:type_de_champ][:type_champ] }).to eq(['text'])
expect(subject[0][:champs].size).to eq(2)
expect(subject[0][:champs].map { |c| c[:value] }).to eq(['text', 42])
expect(subject[0][:champs].map { |c| c[:type_de_champ][:type_champ] }).to eq(['text', 'integer_number'])
end
end
end

View file

@ -67,24 +67,19 @@ describe PrefillDescriptionsController, type: :controller do
it { expect(response).to render_template(:update) }
it "includes the prefill URL" do
type_de_champ_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
type_de_champ_to_add_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ_to_add.type_champ}")
expect(response.body).to include(commencer_path(path: procedure.path))
expect(response.body).to include(
{
"champ_#{type_de_champ.to_typed_id}" => I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
}.to_query
)
expect(response.body).to include({
"champ_#{type_de_champ_to_add.to_typed_id}" => I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ_to_add.type_champ}")
}.to_query)
expect(response.body).to include("champ_#{type_de_champ.to_typed_id_for_query}=#{type_de_champ_value}")
expect(response.body).to include("champ_#{type_de_champ_to_add.to_typed_id_for_query}=#{type_de_champ_to_add_value}")
end
it "includes the prefill query" do
type_de_champ_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
type_de_champ_to_add_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ_to_add.type_champ}")
expect(response.body).to include(api_public_v1_dossiers_path(procedure))
expect(response.body).to include(
"&quot;champ_#{type_de_champ.to_typed_id}&quot;: &quot;#{type_de_champ_value}&quot;, &quot;champ_#{type_de_champ_to_add.to_typed_id}&quot;: &quot;#{type_de_champ_to_add_value}&quot"
"&quot;champ_#{type_de_champ.to_typed_id_for_query}&quot;:&quot;#{type_de_champ_value}&quot;,&quot;champ_#{type_de_champ_to_add.to_typed_id_for_query}&quot;:&quot;#{type_de_champ_to_add_value}&quot"
)
end
end
@ -96,13 +91,11 @@ describe PrefillDescriptionsController, type: :controller do
it { expect(response).to render_template(:update) }
it "includes the prefill URL" do
type_de_champ_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
type_de_champ_to_remove_value = I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ_to_remove.type_champ}")
expect(response.body).to include(commencer_path(path: procedure.path))
expect(response.body).to include({
"champ_#{type_de_champ.to_typed_id}" => I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
}.to_query)
expect(response.body).not_to include({
"champ_#{type_de_champ_to_remove.to_typed_id}" => I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ_to_remove.type_champ}")
}.to_query)
expect(response.body).to include("champ_#{type_de_champ.to_typed_id_for_query}=#{type_de_champ_value}")
expect(response.body).not_to include("champ_#{type_de_champ_to_remove.to_typed_id_for_query}=#{type_de_champ_to_remove_value}")
end
it "includes the prefill query" do
@ -111,10 +104,10 @@ describe PrefillDescriptionsController, type: :controller do
expect(response.body).to include(api_public_v1_dossiers_path(procedure))
expect(response.body).to include(
"&quot;champ_#{type_de_champ.to_typed_id}&quot;: &quot;#{type_de_champ_value}&quot;"
"&quot;champ_#{type_de_champ.to_typed_id_for_query}&quot;:&quot;#{type_de_champ_value}&quot;"
)
expect(response.body).not_to include(
"&quot;champ_#{type_de_champ_to_remove.to_typed_id}&quot;: &quot;#{type_de_champ_to_remove_value}&quot;"
"&quot;champ_#{type_de_champ_to_remove.to_typed_id_for_query}&quot;:&quot;#{type_de_champ_to_remove_value}&quot;"
)
end
end

View file

@ -8,6 +8,8 @@ RSpec.describe PrefillTypeDeChampsController, type: :controller do
context 'when the procedure is found' do
context 'when the procedure is publiee' do
context 'when the procedure is opendata' do
render_views
let(:procedure) { create(:procedure, :published, opendata: true) }
it { expect(show_request).to render_template(:show) }

View file

@ -1077,8 +1077,8 @@ describe Users::DossiersController, type: :controller do
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
"champ_#{type_de_champ_1.to_typed_id_for_query}" => value_1,
"champ_#{type_de_champ_2.to_typed_id_for_query}" => value_2
}
}

View file

@ -198,6 +198,16 @@ FactoryBot.define do
parent = revision.revision_types_de_champ.find { |rtdc| rtdc.type_de_champ == type_de_champ_repetition }
build(:type_de_champ, procedure: evaluator.procedure, libelle: 'sub type de champ', parent: parent, position: 0)
build(:type_de_champ, type_champ: TypeDeChamp.type_champs.fetch(:integer_number), procedure: evaluator.procedure, libelle: 'sub type de champ2', parent: parent, position: 1)
end
end
trait :with_region_types_de_champ do
after(:build) do |type_de_champ_repetition, evaluator|
revision = evaluator.procedure.active_revision
parent = revision.revision_types_de_champ.find { |rtdc| rtdc.type_de_champ == type_de_champ_repetition }
build(:type_de_champ, type_champ: TypeDeChamp.type_champs.fetch(:regions), procedure: evaluator.procedure, libelle: 'region sub_champ', parent: parent, position: 10)
end
end
end

View file

@ -21,9 +21,9 @@ describe '20220705164551_remove_unused_champs' do
describe 'remove_unused_champs', vcr: { cassette_name: 'api_geo_all' } do
it "with bad champs" do
expect(Champ.where(dossier: dossier).count).to eq(38)
expect(Champ.where(dossier: dossier).count).to eq(40)
run_task
expect(Champ.where(dossier: dossier).count).to eq(37)
expect(Champ.where(dossier: dossier).count).to eq(39)
end
end
end

View file

@ -526,7 +526,7 @@ describe Champ do
expect(dossier.champs_public.size).to eq(2)
expect(champ.rows.size).to eq(2)
second_row = champ.rows.second
second_row = champ.reload.rows.second
expect(second_row.size).to eq(1)
expect(second_row.first.dossier).to eq(dossier)

View file

@ -1861,7 +1861,7 @@ describe Dossier do
let(:champ_repetition) { create(:champ_repetition, type_de_champ: type_de_champ_repetition, dossier: dossier) }
before { dossier.champs_public << champ_repetition }
it { expect(Champs::RepetitionChamp.where(dossier: new_dossier).first.champs.count).to eq(2) }
it { expect(Champs::RepetitionChamp.where(dossier: new_dossier).first.champs.count).to eq(4) }
it { expect(Champs::RepetitionChamp.where(dossier: new_dossier).first.champs.ids).not_to eq(champ_repetition.champs.ids) }
end

View file

@ -22,7 +22,7 @@ RSpec.describe PrefillDescription, type: :model do
it { expect(types_de_champ.count).to eq(1) }
it { expect(types_de_champ.first).to eql(TypesDeChamp::PrefillTypeDeChamp.build(type_de_champ)) }
it { expect(types_de_champ.first).to eql(TypesDeChamp::PrefillTypeDeChamp.build(type_de_champ, procedure.active_revision)) }
shared_examples "filters out non fillable types de champ" do |type_de_champ_name|
context "when the procedure has a #{type_de_champ_name} champ" do
@ -86,60 +86,61 @@ RSpec.describe PrefillDescription, type: :model do
end
end
describe '#prefill_link' do
describe '#prefill_link', vcr: { cassette_name: 'api_geo_regions' } do
let(:procedure) { create(:procedure) }
let(:type_de_champ) { create(:type_de_champ_text, procedure: procedure) }
let(:type_de_champ_text) { build(:type_de_champ_text, procedure: procedure) }
let(:type_de_champ_epci) { build(:type_de_champ_epci, procedure: procedure) }
let(:type_de_champ_repetition) { create(:type_de_champ_repetition, :with_types_de_champ, :with_region_types_de_champ, procedure: procedure) }
let(:prefillable_subchamps) { TypesDeChamp::PrefillRepetitionTypeDeChamp.new(type_de_champ_repetition, procedure.active_revision).send(:prefillable_subchamps) }
let(:region_repetition) { prefillable_subchamps.third }
let(:prefill_description) { described_class.new(procedure) }
before { prefill_description.update(selected_type_de_champ_ids: [type_de_champ.id]) }
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
before do
allow(Rails).to receive(:cache).and_return(memory_store)
Rails.cache.clear
VCR.insert_cassette('api_geo_departements')
VCR.insert_cassette('api_geo_epcis')
prefill_description.update(selected_type_de_champ_ids: [type_de_champ_text.id, type_de_champ_epci.id, type_de_champ_repetition.id])
end
after do
VCR.eject_cassette('api_geo_departements')
VCR.eject_cassette('api_geo_epcis')
end
it "builds the URL to create a new prefilled dossier" do
expect(prefill_description.prefill_link).to eq(
commencer_url(
path: procedure.path,
"champ_#{type_de_champ.to_typed_id}" => I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")
CGI.unescape(
commencer_url(
path: procedure.path,
"champ_#{type_de_champ_text.to_typed_id_for_query}" => TypesDeChamp::PrefillTypeDeChamp.build(type_de_champ_text, procedure.active_revision).example_value,
"champ_#{type_de_champ_epci.to_typed_id_for_query}" => TypesDeChamp::PrefillTypeDeChamp.build(type_de_champ_epci, procedure.active_revision).example_value,
"champ_#{type_de_champ_repetition.to_typed_id_for_query}" => TypesDeChamp::PrefillTypeDeChamp.build(type_de_champ_repetition, procedure.active_revision).example_value
)
)
)
end
context 'when the type de champ can have multiple values' do
let(:type_de_champ) { TypesDeChamp::PrefillTypeDeChamp.build(create(:type_de_champ_epci, procedure: procedure)) }
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
before do
allow(Rails).to receive(:cache).and_return(memory_store)
Rails.cache.clear
VCR.insert_cassette('api_geo_departements')
VCR.insert_cassette('api_geo_epcis')
end
after do
VCR.eject_cassette('api_geo_departements')
VCR.eject_cassette('api_geo_epcis')
end
it 'builds the URL with array parameter' do
expect(prefill_description.prefill_link).to eq(
commencer_url(
path: procedure.path,
"champ_#{type_de_champ.to_typed_id}": type_de_champ.example_value
)
)
end
end
end
describe '#prefill_query' do
describe '#prefill_query', vcr: { cassette_name: 'api_geo_regions' } do
let(:procedure) { create(:procedure) }
let(:type_de_champ) { create(:type_de_champ_text, procedure: procedure) }
let(:type_de_champ_text) { create(:type_de_champ_text, procedure: procedure) }
let(:type_de_champ_epci) { TypesDeChamp::PrefillTypeDeChamp.build(create(:type_de_champ_epci, procedure: procedure), procedure.active_revision) }
let(:type_de_champ_repetition) { build(:type_de_champ_repetition, :with_types_de_champ, :with_region_types_de_champ, procedure: procedure) }
let(:prefillable_subchamps) { TypesDeChamp::PrefillRepetitionTypeDeChamp.new(type_de_champ_repetition, procedure.active_revision).send(:prefillable_subchamps) }
let(:text_repetition) { prefillable_subchamps.first }
let(:integer_repetition) { prefillable_subchamps.second }
let(:region_repetition) { prefillable_subchamps.third }
let(:prefill_description) { described_class.new(procedure) }
let(:expected_query) do
<<~TEXT
curl --request POST '#{api_public_v1_dossiers_url(procedure)}' \\
--header 'Content-Type: application/json' \\
--data '{"champ_#{type_de_champ.to_typed_id}": "#{I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")}"}'
--data '{"champ_#{type_de_champ_text.to_typed_id_for_query}":"Texte court","champ_#{type_de_champ_epci.to_typed_id_for_query}":["01","200042935"],"champ_#{type_de_champ_repetition.to_typed_id_for_query}":[{"champ_#{text_repetition.to_typed_id_for_query}":"Texte court","champ_#{integer_repetition.to_typed_id_for_query}":"42","champ_#{region_repetition.to_typed_id_for_query}":"53"},{"champ_#{text_repetition.to_typed_id_for_query}":"Texte court","champ_#{integer_repetition.to_typed_id_for_query}":"42","champ_#{region_repetition.to_typed_id_for_query}":"53"}]}'
TEXT
end
@ -152,7 +153,7 @@ RSpec.describe PrefillDescription, type: :model do
VCR.insert_cassette('api_geo_departements')
VCR.insert_cassette('api_geo_epcis')
prefill_description.update(selected_type_de_champ_ids: [type_de_champ.id])
prefill_description.update(selected_type_de_champ_ids: [type_de_champ_text.id, type_de_champ_epci.id, type_de_champ_repetition.id])
end
after do
@ -163,20 +164,5 @@ RSpec.describe PrefillDescription, type: :model do
it "builds the query to create a new prefilled dossier" do
expect(prefill_description.prefill_query).to eq(expected_query)
end
context 'when the type de champ can have multiple values' do
let(:type_de_champ) { TypesDeChamp::PrefillTypeDeChamp.build(create(:type_de_champ_epci, procedure: procedure)) }
let(:expected_query) do
<<~TEXT
curl --request POST '#{api_public_v1_dossiers_url(procedure)}' \\
--header 'Content-Type: application/json' \\
--data '{"champ_#{type_de_champ.to_typed_id}": #{type_de_champ.example_value}}'
TEXT
end
it 'builds the query with array parameter' do
expect(prefill_description.prefill_query).to eq(expected_query)
end
end
end
end

View file

@ -36,8 +36,8 @@ RSpec.describe PrefillParams do
let(:params) {
{
"champ_#{type_de_champ_1.to_typed_id}" => value_1,
"champ_#{type_de_champ_2.to_typed_id}" => value_2
"champ_#{type_de_champ_1.to_typed_id_for_query}" => value_1,
"champ_#{type_de_champ_2.to_typed_id_for_query}" => value_2
}
}
@ -53,7 +53,7 @@ RSpec.describe PrefillParams do
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
let(:types_de_champ_public) { [{ type: :text }] }
let(:params) { { type_de_champ.to_typed_id => "value" } }
let(:params) { { type_de_champ.to_typed_id_for_query => "value" } }
it "filters out the champ" do
expect(prefill_params_array).to match([])
@ -71,7 +71,7 @@ RSpec.describe PrefillParams do
context 'when there is no Champ that matches the TypeDeChamp with the given stable id' do
let!(:type_de_champ) { create(:type_de_champ_text) } # goes to another procedure
let(:params) { { "champ_#{type_de_champ.to_typed_id}" => "value" } }
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => "value" } }
it "filters out the param" do
expect(prefill_params_array).to match([])
@ -84,7 +84,7 @@ RSpec.describe PrefillParams do
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
let(:champ) { find_champ_by_stable_id(dossier, type_de_champ.stable_id) }
let(:params) { { "champ_#{type_de_champ.to_typed_id}" => value } }
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => value } }
it "builds an array of hash matching the given params" do
expect(prefill_params_array).to match([{ id: champ.id }.merge(attributes(champ, value))])
@ -98,7 +98,7 @@ RSpec.describe PrefillParams do
let(:type_de_champ) { procedure.published_revision.types_de_champ_private.first }
let(:champ) { find_champ_by_stable_id(dossier, type_de_champ.stable_id) }
let(:params) { { "champ_#{type_de_champ.to_typed_id}" => value } }
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => value } }
it "builds an array of hash matching the given params" do
expect(prefill_params_array).to match([{ id: champ.id }.merge(attributes(champ, value))])
@ -110,7 +110,7 @@ RSpec.describe PrefillParams do
let(:types_de_champ_public) { [{ type: type_de_champ_type }] }
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
let(:params) { { "champ_#{type_de_champ.to_typed_id}" => value } }
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => value } }
context "when the type de champ is unauthorized (#{type_de_champ_type})" do
it "filters out the param" do
@ -140,6 +140,20 @@ RSpec.describe PrefillParams do
it_behaves_like "a champ public value that is authorized", :multiple_drop_down_list, ["val1", "val2"]
it_behaves_like "a champ public value that is authorized", :epci, ['01', '200042935']
context "when the public type de champ is authorized (repetition)" do
let(:types_de_champ_public) { [{ type: :repetition, children: [{ type: :text }] }] }
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
let(:type_de_champ_child) { procedure.published_revision.children_of(type_de_champ).first }
let(:type_de_champ_child_value) { "value" }
let(:type_de_champ_child_value2) { "value2" }
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => [{ "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value }, { "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value2 }] } }
it "builds an array of hash(id, value) matching the given params" do
expect(prefill_params_array).to match([{ id: type_de_champ_child.champ.first.id, value: type_de_champ_child_value }, { id: type_de_champ_child.champ.second.id, value: type_de_champ_child_value2 }])
end
end
it_behaves_like "a champ private value that is authorized", :text, "value"
it_behaves_like "a champ private value that is authorized", :textarea, "value"
it_behaves_like "a champ private value that is authorized", :decimal_number, "3.14"
@ -162,6 +176,20 @@ RSpec.describe PrefillParams do
it_behaves_like "a champ private value that is authorized", :multiple_drop_down_list, ["val1", "val2"]
it_behaves_like "a champ private value that is authorized", :epci, ['01', '200042935']
context "when the private type de champ is authorized (repetition)" do
let(:types_de_champ_private) { [{ type: :repetition, children: [{ type: :text }] }] }
let(:type_de_champ) { procedure.published_revision.types_de_champ_private.first }
let(:type_de_champ_child) { procedure.published_revision.children_of(type_de_champ).first }
let(:type_de_champ_child_value) { "value" }
let(:type_de_champ_child_value2) { "value2" }
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => [{ "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value }, { "champ_#{type_de_champ_child.to_typed_id_for_query}" => type_de_champ_child_value2 }] } }
it "builds an array of hash(id, value) matching the given params" do
expect(prefill_params_array).to match([{ id: type_de_champ_child.champ.first.id, value: type_de_champ_child_value }, { id: type_de_champ_child.champ.second.id, value: type_de_champ_child_value2 }])
end
end
it_behaves_like "a champ public value that is unauthorized", :decimal_number, "non decimal string"
it_behaves_like "a champ public value that is unauthorized", :integer_number, "non integer string"
it_behaves_like "a champ public value that is unauthorized", :number, "value"
@ -176,7 +204,6 @@ RSpec.describe PrefillParams do
it_behaves_like "a champ public value that is unauthorized", :header_section, "value"
it_behaves_like "a champ public value that is unauthorized", :explication, "value"
it_behaves_like "a champ public value that is unauthorized", :piece_justificative, "value"
it_behaves_like "a champ public value that is unauthorized", :repetition, "value"
it_behaves_like "a champ public value that is unauthorized", :cnaf, "value"
it_behaves_like "a champ public value that is unauthorized", :dgfip, "value"
it_behaves_like "a champ public value that is unauthorized", :pole_emploi, "value"
@ -190,6 +217,30 @@ RSpec.describe PrefillParams do
it_behaves_like "a champ public value that is unauthorized", :rna, "value"
it_behaves_like "a champ public value that is unauthorized", :annuaire_education, "value"
it_behaves_like "a champ public value that is unauthorized", :multiple_drop_down_list, ["value"]
context "when the public type de champ is unauthorized because of wrong value format (repetition)" do
let(:types_de_champ_public) { [{ type: :repetition, children: [{ type: :text }] }] }
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
let(:type_de_champ_child) { procedure.published_revision.children_of(type_de_champ).first }
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => "value" } }
it "builds an array of hash(id, value) matching the given params" do
expect(prefill_params_array).to match([])
end
end
context "when the public type de champ is unauthorized because of wrong value typed_id (repetition)" do
let(:types_de_champ_public) { [{ type: :repetition, children: [{ type: :text }] }] }
let(:type_de_champ) { procedure.published_revision.types_de_champ_public.first }
let(:type_de_champ_child) { procedure.published_revision.children_of(type_de_champ).first }
let(:params) { { "champ_#{type_de_champ.to_typed_id_for_query}" => ["{\"wrong\":\"value\"}", "{\"wrong\":\"value2\"}"] } }
it "builds an array of hash(id, value) matching the given params" do
expect(prefill_params_array).to match([])
end
end
end
private
@ -200,7 +251,7 @@ RSpec.describe PrefillParams do
def attributes(champ, value)
TypesDeChamp::PrefillTypeDeChamp
.build(champ.type_de_champ)
.transform_value_to_assignable_attributes(value)
.build(champ.type_de_champ, procedure.active_revision)
.to_assignable_attributes(champ, value)
end
end

View file

@ -134,15 +134,15 @@ describe ProcedureRevision do
end
it 'move down' do
expect(draft.children_of(type_de_champ_repetition).index(second_child)).to eq(1)
draft.move_type_de_champ(second_child.stable_id, 2)
expect(draft.children_of(type_de_champ_repetition).index(second_child)).to eq(2)
draft.move_type_de_champ(second_child.stable_id, 3)
expect(draft.children_of(type_de_champ_repetition).index(second_child)).to eq(3)
end
it 'move up' do
expect(draft.children_of(type_de_champ_repetition).index(last_child)).to eq(2)
expect(draft.children_of(type_de_champ_repetition).index(last_child)).to eq(3)
draft.move_type_de_champ(last_child.stable_id, 0)
@ -205,13 +205,13 @@ describe ProcedureRevision do
it 'reorders' do
children = draft.children_of(type_de_champ_repetition)
expect(children.pluck(:position)).to eq([0, 1, 2])
expect(children.pluck(:position)).to eq([0, 1, 2, 3])
draft.remove_type_de_champ(children[1].stable_id)
children.reload
expect(children.pluck(:position)).to eq([0, 1])
expect(children.pluck(:position)).to eq([0, 1, 2])
end
end
end
@ -242,8 +242,8 @@ describe ProcedureRevision do
new_draft.remove_type_de_champ(child.stable_id)
expect { child.reload }.not_to raise_error
expect(draft.children_of(type_de_champ_repetition).size).to eq(1)
expect(new_draft.children_of(type_de_champ_repetition)).to be_empty
expect(draft.children_of(type_de_champ_repetition).size).to eq(2)
expect(new_draft.children_of(type_de_champ_repetition).size).to eq(1)
end
it 'can remove the parent only in the new revision' do
@ -291,7 +291,7 @@ describe ProcedureRevision do
let(:procedure) { create(:procedure, :with_repetition) }
it 'should have the same tdcs with different links' do
expect(new_draft.types_de_champ.count).to eq(2)
expect(new_draft.types_de_champ.count).to eq(3)
expect(new_draft.types_de_champ).to eq(draft.types_de_champ)
new_repetition, new_child = new_draft.types_de_champ.partition(&:repetition?).map(&:first)
@ -320,7 +320,7 @@ describe ProcedureRevision do
it do
expect(procedure.revisions.size).to eq(2)
expect(draft.revision_types_de_champ.where.not(parent_id: nil).size).to eq(1)
expect(draft.revision_types_de_champ.where.not(parent_id: nil).size).to eq(2)
end
end
end
@ -639,9 +639,10 @@ describe ProcedureRevision do
context 'with a repetition tdc' do
let(:procedure) { create(:procedure, :with_repetition) }
let!(:parent) { draft.types_de_champ.find(&:repetition?) }
let!(:child) { draft.types_de_champ.reject(&:repetition?).first }
let!(:first_child) { draft.types_de_champ.reject(&:repetition?).first }
let!(:second_child) { draft.types_de_champ.reject(&:repetition?).second }
it { expect(draft.children_of(parent)).to match([child]) }
it { expect(draft.children_of(parent)).to match([first_child, second_child]) }
context 'with multiple child' do
let(:child_position_2) { create(:type_de_champ_text) }
@ -654,7 +655,7 @@ describe ProcedureRevision do
end
it 'returns the children in order' do
expect(draft.children_of(parent)).to eq([child, child_position_1, child_position_2])
expect(draft.children_of(parent)).to eq([first_child, second_child, child_position_1, child_position_2])
end
end
@ -668,13 +669,13 @@ describe ProcedureRevision do
before do
new_draft
.revision_types_de_champ
.where(type_de_champ: child)
.where(type_de_champ: first_child)
.update(type_de_champ: new_child)
end
it 'returns the children regarding the revision' do
expect(draft.children_of(parent)).to match([child])
expect(new_draft.children_of(parent)).to match([new_child])
expect(draft.children_of(parent)).to match([first_child, second_child])
expect(new_draft.children_of(parent)).to match([new_child, second_child])
end
end
end

View file

@ -246,10 +246,10 @@ describe TypeDeChamp do
it_behaves_like "a prefillable type de champ", :type_de_champ_datetime
it_behaves_like "a prefillable type de champ", :type_de_champ_civilite
it_behaves_like "a prefillable type de champ", :type_de_champ_pays
it_behaves_like "a prefillable type de champ", :type_de_champ_regions
it_behaves_like "a prefillable type de champ", :type_de_champ_yes_no
it_behaves_like "a prefillable type de champ", :type_de_champ_checkbox
it_behaves_like "a prefillable type de champ", :type_de_champ_drop_down_list
it_behaves_like "a prefillable type de champ", :type_de_champ_repetition
it_behaves_like "a prefillable type de champ", :type_de_champ_departements
it_behaves_like "a prefillable type de champ", :type_de_champ_multiple_drop_down_list
it_behaves_like "a prefillable type de champ", :type_de_champ_epci
@ -262,7 +262,6 @@ describe TypeDeChamp do
it_behaves_like "a non-prefillable type de champ", :type_de_champ_header_section
it_behaves_like "a non-prefillable type de champ", :type_de_champ_explication
it_behaves_like "a non-prefillable type de champ", :type_de_champ_piece_justificative
it_behaves_like "a non-prefillable type de champ", :type_de_champ_repetition
it_behaves_like "a non-prefillable type de champ", :type_de_champ_cnaf
it_behaves_like "a non-prefillable type de champ", :type_de_champ_dgfip
it_behaves_like "a non-prefillable type de champ", :type_de_champ_pole_emploi

View file

@ -1,7 +1,8 @@
# frozen_string_literal: true
RSpec.describe TypesDeChamp::PrefillDepartementTypeDeChamp, type: :model do
let(:type_de_champ) { build(:type_de_champ_departements) }
let(:procedure) { create(:procedure) }
let(:type_de_champ) { build(:type_de_champ_departements, procedure: procedure) }
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
before do
@ -10,16 +11,18 @@ RSpec.describe TypesDeChamp::PrefillDepartementTypeDeChamp, type: :model do
end
describe 'ancestors' do
subject { described_class.build(type_de_champ) }
subject { described_class.build(type_de_champ, procedure.active_revision) }
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
end
describe '#possible_values', vcr: { cassette_name: 'api_geo_departements' } do
let(:expected_values) {
APIGeoService.departements.sort_by { |departement| departement[:code] }.map { |departement| "#{departement[:code]} (#{departement[:name]})" }
"Un <a href=\"https://fr.wikipedia.org/wiki/Num%C3%A9rotation_des_d%C3%A9partements_fran%C3%A7ais\" target=\"_blank\">numéro de département</a><br><a title=\"Toutes les valeurs possibles — Nouvel onglet\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"/procedures/#{procedure.path}/prefill_type_de_champs/#{type_de_champ.id}\">Voir toutes les valeurs possibles</a>"
}
subject(:possible_values) { described_class.new(type_de_champ).possible_values }
subject(:possible_values) { described_class.new(type_de_champ, procedure.active_revision).possible_values }
before { type_de_champ.reload }
it { expect(possible_values).to match(expected_values) }
end

View file

@ -2,28 +2,32 @@
RSpec.describe TypesDeChamp::PrefillDropDownListTypeDeChamp do
describe '#possible_values' do
subject(:possible_values) { described_class.new(type_de_champ).possible_values }
let(:procedure) { create(:procedure) }
subject(:possible_values) { described_class.new(type_de_champ, procedure.active_revision).possible_values }
before { type_de_champ.reload }
context "when the drop down list accepts 'other'" do
let(:type_de_champ) { build(:type_de_champ_drop_down_list, :with_other) }
let(:type_de_champ) { build(:type_de_champ_drop_down_list, :with_other, procedure: procedure) }
it {
expect(possible_values).to match(
[I18n.t("views.prefill_descriptions.edit.possible_values.drop_down_list_other_html")] + type_de_champ.drop_down_list_enabled_non_empty_options
([I18n.t("views.prefill_descriptions.edit.possible_values.drop_down_list_other_html")] + type_de_champ.drop_down_list_enabled_non_empty_options).to_sentence
)
}
end
context "when the drop down list does not accept 'other'" do
let(:type_de_champ) { build(:type_de_champ_drop_down_list) }
let(:type_de_champ) { build(:type_de_champ_drop_down_list, procedure:) }
it { expect(possible_values).to match(type_de_champ.drop_down_list_enabled_non_empty_options) }
it { expect(possible_values).to match(type_de_champ.drop_down_list_enabled_non_empty_options.to_sentence) }
end
end
describe '#example_value' do
let(:type_de_champ) { build(:type_de_champ_drop_down_list) }
subject(:example_value) { described_class.new(type_de_champ).example_value }
let(:procedure) { create(:procedure) }
let(:type_de_champ) { build(:type_de_champ_drop_down_list, procedure: procedure) }
subject(:example_value) { described_class.new(type_de_champ, procedure.active_revision).example_value }
it { expect(example_value).to eq(type_de_champ.drop_down_list_enabled_non_empty_options.first) }
end

View file

@ -1,7 +1,9 @@
# frozen_string_literal: true
RSpec.describe TypesDeChamp::PrefillEpciTypeDeChamp do
let(:type_de_champ) { build(:type_de_champ_epci) }
let(:procedure) { create(:procedure) }
let(:type_de_champ) { build(:type_de_champ_epci, procedure: procedure) }
let(:champ) { create(:champ_epci, type_de_champ: type_de_champ) }
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
before do
@ -10,7 +12,7 @@ RSpec.describe TypesDeChamp::PrefillEpciTypeDeChamp do
end
describe 'ancestors' do
subject { described_class.new(type_de_champ) }
subject { described_class.new(type_de_champ, procedure.active_revision) }
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
end
@ -19,7 +21,7 @@ RSpec.describe TypesDeChamp::PrefillEpciTypeDeChamp do
let(:expected_values) do
departements.map { |departement| "#{departement[:code]} (#{departement[:name]}) : https://geo.api.gouv.fr/epcis?codeDepartement=#{departement[:code]}" }
end
subject(:possible_values) { described_class.new(type_de_champ).possible_values }
subject(:possible_values) { described_class.new(type_de_champ, procedure.active_revision).possible_values }
before do
VCR.insert_cassette('api_geo_departements')
@ -37,7 +39,7 @@ RSpec.describe TypesDeChamp::PrefillEpciTypeDeChamp do
describe '#example_value' do
let(:departement_code) { departements.pick(:code) }
let(:epci_code) { APIGeoService.epcis(departement_code).pick(:code) }
subject(:example_value) { described_class.new(type_de_champ).example_value }
subject(:example_value) { described_class.new(type_de_champ, procedure.active_revision).example_value }
before do
VCR.insert_cassette('api_geo_departements')
@ -52,40 +54,46 @@ RSpec.describe TypesDeChamp::PrefillEpciTypeDeChamp do
it { is_expected.to eq([departement_code, epci_code]) }
end
describe '#transform_value_to_assignable_attributes' do
subject(:transform_value_to_assignable_attributes) { described_class.build(type_de_champ).transform_value_to_assignable_attributes(value) }
describe '#to_assignable_attributes' do
subject(:to_assignable_attributes) { described_class.build(type_de_champ, procedure.active_revision).to_assignable_attributes(champ, value) }
shared_examples "a transformation to" do |code_departement, value|
it { is_expected.to match({ code_departement: code_departement, value: value }) }
it { is_expected.to match({ code_departement: code_departement, value: value, id: champ.id }) }
end
context 'when the value is nil' do
let(:value) { nil }
it_behaves_like "a transformation to", nil, nil
end
context 'when the value is empty' do
let(:value) { '' }
it_behaves_like "a transformation to", nil, nil
end
context 'when the value is a string' do
let(:value) { 'hello' }
it_behaves_like "a transformation to", nil, nil
end
context 'when the value is an array of one element' do
let(:value) { ['01'] }
it_behaves_like "a transformation to", '01', nil
end
context 'when the value is an array of two elements' do
let(:value) { ['01', '200042935'] }
it_behaves_like "a transformation to", '01', '200042935'
end
context 'when the value is an array of three or more elements' do
let(:value) { ['01', '200042935', 'hello'] }
it_behaves_like "a transformation to", '01', '200042935'
end
end

View file

@ -1,15 +1,17 @@
# frozen_string_literal: true
RSpec.describe TypesDeChamp::PrefillMultipleDropDownListTypeDeChamp do
let(:procedure) { create(:procedure) }
describe 'ancestors' do
subject { described_class.new(build(:type_de_champ_multiple_drop_down_list)) }
subject { described_class.new(build(:type_de_champ_multiple_drop_down_list, procedure: procedure), procedure.active_revision) }
it { is_expected.to be_kind_of(TypesDeChamp::PrefillDropDownListTypeDeChamp) }
end
describe '#example_value' do
let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list, drop_down_list_value: drop_down_list_value) }
subject(:example_value) { described_class.new(type_de_champ).example_value }
let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list, drop_down_list_value: drop_down_list_value, procedure: procedure) }
subject(:example_value) { described_class.new(type_de_champ, procedure.active_revision).example_value }
context 'when the multiple drop down list has no option' do
let(:drop_down_list_value) { "" }

View file

@ -1,17 +1,22 @@
RSpec.describe TypesDeChamp::PrefillPaysTypeDeChamp, type: :model do
let(:type_de_champ) { build(:type_de_champ_pays) }
let(:procedure) { create(:procedure) }
let(:type_de_champ) { build(:type_de_champ_pays, procedure: procedure) }
describe 'ancestors' do
subject { described_class.build(type_de_champ) }
subject { described_class.build(type_de_champ, procedure.active_revision) }
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
end
describe '#possible_values' do
let(:expected_values) { APIGeoService.countries.sort_by { |country| country[:code] }.map { |country| "#{country[:code]} (#{country[:name]})" } }
subject(:possible_values) { described_class.new(type_de_champ).possible_values }
let(:expected_values) { "Un <a href=\"https://en.wikipedia.org/wiki/ISO_3166-2\" target=\"_blank\" rel=\"noopener noreferrer\">code pays ISO 3166-2</a><br><a title=\"Toutes les valeurs possibles — Nouvel onglet\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"/procedures/#{procedure.path}/prefill_type_de_champs/#{type_de_champ.id}\">Voir toutes les valeurs possibles</a>" }
subject(:possible_values) { described_class.new(type_de_champ, procedure.active_revision).possible_values }
it { expect(possible_values).to match(expected_values) }
before { type_de_champ.reload }
it {
expect(possible_values).to match(expected_values)
}
end
end

View file

@ -1,7 +1,8 @@
# frozen_string_literal: true
RSpec.describe TypesDeChamp::PrefillRegionTypeDeChamp, type: :model do
let(:type_de_champ) { build(:type_de_champ_regions) }
let(:procedure) { create(:procedure) }
let(:type_de_champ) { create(:type_de_champ_regions, procedure: procedure) }
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
before do
@ -10,15 +11,19 @@ RSpec.describe TypesDeChamp::PrefillRegionTypeDeChamp, type: :model do
end
describe 'ancestors' do
subject { described_class.build(type_de_champ) }
subject { described_class.build(type_de_champ, procedure.active_revision) }
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
end
describe '#possible_values', vcr: { cassette_name: 'api_geo_regions' } do
let(:expected_values) { APIGeoService.regions.sort_by { |region| region[:code] }.map { |region| "#{region[:code]} (#{region[:name]})" } }
subject(:possible_values) { described_class.new(type_de_champ).possible_values }
let(:expected_values) { "Un <a href=\"https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise\" target=\"_blank\" rel=\"noopener noreferrer\">code INSEE de région</a><br><a title=\"Toutes les valeurs possibles — Nouvel onglet\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"/procedures/#{procedure.path}/prefill_type_de_champs/#{type_de_champ.id}\">Voir toutes les valeurs possibles</a>" }
subject(:possible_values) { described_class.new(type_de_champ, procedure.active_revision).possible_values }
it { expect(possible_values).to match(expected_values) }
before { type_de_champ.reload }
it {
expect(possible_values).to eq(expected_values)
}
end
end

View file

@ -0,0 +1,78 @@
# frozen_string_literal: true
RSpec.describe TypesDeChamp::PrefillRepetitionTypeDeChamp, type: :model, vcr: { cassette_name: 'api_geo_regions' } do
let(:procedure) { create(:procedure) }
let(:type_de_champ) { build(:type_de_champ_repetition, :with_types_de_champ, :with_region_types_de_champ, procedure: procedure) }
let(:champ) { create(:champ_repetition, type_de_champ: type_de_champ) }
let(:prefillable_subchamps) { TypesDeChamp::PrefillRepetitionTypeDeChamp.new(type_de_champ, procedure.active_revision).send(:prefillable_subchamps) }
let(:text_repetition) { prefillable_subchamps.first }
let(:integer_repetition) { prefillable_subchamps.second }
let(:region_repetition) { prefillable_subchamps.third }
let(:memory_store) { ActiveSupport::Cache.lookup_store(:memory_store) }
before do
allow(Rails).to receive(:cache).and_return(memory_store)
Rails.cache.clear
end
describe 'ancestors' do
subject { described_class.build(type_de_champ, procedure.active_revision) }
it { is_expected.to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
end
describe '#possible_values' do
subject(:possible_values) { described_class.new(type_de_champ, procedure.active_revision).possible_values }
let(:expected_value) {
"Un tableau de dictionnaires avec les valeurs possibles pour chaque champ de la répétition.</br><ul><li>champ_#{text_repetition.to_typed_id_for_query}: Un texte court<br></li><li>champ_#{integer_repetition.to_typed_id_for_query}: Un nombre entier<br></li><li>champ_#{region_repetition.to_typed_id_for_query}: Un <a href=\"https://fr.wikipedia.org/wiki/R%C3%A9gion_fran%C3%A7aise\" target=\"_blank\" rel=\"noopener noreferrer\">code INSEE de région</a><br><a title=\"Toutes les valeurs possibles — Nouvel onglet\" target=\"_blank\" rel=\"noopener noreferrer\" href=\"/procedures/#{procedure.path}/prefill_type_de_champs/#{region_repetition.id}\">Voir toutes les valeurs possibles</a></li></ul>"
}
it {
expect(possible_values).to eq(expected_value)
}
end
describe '#example_value' do
subject(:example_value) { described_class.new(type_de_champ, procedure.active_revision).example_value }
let(:expected_value) { [{ "champ_#{text_repetition.to_typed_id_for_query}" => "Texte court", "champ_#{integer_repetition.to_typed_id_for_query}" => "42", "champ_#{region_repetition.to_typed_id_for_query}" => "53" }, { "champ_#{text_repetition.to_typed_id_for_query}" => "Texte court", "champ_#{integer_repetition.to_typed_id_for_query}" => "42", "champ_#{region_repetition.to_typed_id_for_query}" => "53" }] }
it { expect(example_value).to eq(expected_value) }
end
describe '#to_assignable_attributes' do
subject(:to_assignable_attributes) { described_class.build(type_de_champ, procedure.active_revision).to_assignable_attributes(champ, value) }
context 'when the value is nil' do
let(:value) { nil }
it { is_expected.to match([]) }
end
context 'when the value is empty' do
let(:value) { '' }
it { is_expected.to match([]) }
end
context 'when the value is a string' do
let(:value) { 'hello' }
it { is_expected.to match([]) }
end
context 'when the value is an array with wrong keys' do
let(:value) { ["{\"blabla\":\"value\"}", "{\"blabla\":\"value2\"}"] }
it { is_expected.to match([]) }
end
context 'when the value is an array with some wrong keys' do
let(:value) { [{ "champ_#{text_repetition.to_typed_id_for_query}" => "value", "blabla" => "value2" }, { "champ_#{integer_repetition.to_typed_id_for_query}" => "value3" }, { "blabla" => "false" }] }
it { is_expected.to match([[{ id: text_repetition.champ.first.id, value: "value" }], [{ id: integer_repetition.champ.second.id, value: "value3" }]]) }
end
context 'when the value is an array with right keys' do
let(:value) { [{ "champ_#{text_repetition.to_typed_id_for_query}" => "value" }, { "champ_#{text_repetition.to_typed_id_for_query}" => "value2" }] }
it { is_expected.to match([[{ id: text_repetition.champ.first.id, value: "value" }], [{ id: text_repetition.champ.second.id, value: "value2" }]]) }
end
end
end

View file

@ -1,54 +1,65 @@
# frozen_string_literal: true
RSpec.describe TypesDeChamp::PrefillTypeDeChamp, type: :model do
include ActionView::Helpers::UrlHelper
include ApplicationHelper
let(:procedure) { create(:procedure) }
describe '.build' do
subject(:built) { described_class.build(type_de_champ) }
subject(:built) { described_class.build(type_de_champ, procedure.active_revision) }
context 'when the type de champ is a drop_down_list' do
let(:type_de_champ) { build(:type_de_champ_drop_down_list) }
let(:type_de_champ) { build(:type_de_champ_drop_down_list, procedure: procedure) }
it { expect(built).to be_kind_of(TypesDeChamp::PrefillDropDownListTypeDeChamp) }
end
context 'when the type de champ is a multiple_drop_down_list' do
let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list) }
let(:type_de_champ) { build(:type_de_champ_multiple_drop_down_list, procedure: procedure) }
it { expect(built).to be_kind_of(TypesDeChamp::PrefillMultipleDropDownListTypeDeChamp) }
end
context 'when the type de champ is a pays' do
let(:type_de_champ) { build(:type_de_champ_pays) }
let(:type_de_champ) { build(:type_de_champ_pays, procedure: procedure) }
it { expect(built).to be_kind_of(TypesDeChamp::PrefillPaysTypeDeChamp) }
end
context 'when the type de champ is a regions' do
let(:type_de_champ) { build(:type_de_champ_regions) }
let(:type_de_champ) { build(:type_de_champ_regions, procedure: procedure) }
it { expect(built).to be_kind_of(TypesDeChamp::PrefillRegionTypeDeChamp) }
end
context 'when the type de champ is a repetition' do
let(:type_de_champ) { build(:type_de_champ_repetition, procedure: procedure) }
it { expect(built).to be_kind_of(TypesDeChamp::PrefillRepetitionTypeDeChamp) }
end
context 'when the type de champ is a departements' do
let(:type_de_champ) { build(:type_de_champ_departements) }
let(:type_de_champ) { build(:type_de_champ_departements, procedure: procedure) }
it { expect(built).to be_kind_of(TypesDeChamp::PrefillDepartementTypeDeChamp) }
end
context 'when the type de champ is a epci' do
let(:type_de_champ) { build(:type_de_champ_epci) }
let(:type_de_champ) { build(:type_de_champ_epci, procedure: procedure) }
it { expect(built).to be_kind_of(TypesDeChamp::PrefillEpciTypeDeChamp) }
end
context 'when any other type de champ' do
let(:type_de_champ) { build(:type_de_champ_date) }
let(:type_de_champ) { build(:type_de_champ_date, procedure: procedure) }
it { expect(built).to be_kind_of(TypesDeChamp::PrefillTypeDeChamp) }
end
end
describe '.wrap' do
subject(:wrapped) { described_class.wrap([build(:type_de_champ_drop_down_list), build(:type_de_champ_email)]) }
subject(:wrapped) { described_class.wrap([build(:type_de_champ_drop_down_list, procedure: procedure), build(:type_de_champ_email, procedure: procedure)], procedure.active_revision) }
it 'wraps the collection' do
expect(wrapped.first).to be_kind_of(TypesDeChamp::PrefillDropDownListTypeDeChamp)
@ -57,59 +68,81 @@ RSpec.describe TypesDeChamp::PrefillTypeDeChamp, type: :model do
end
describe '#possible_values' do
subject(:possible_values) { described_class.build(type_de_champ).possible_values }
context 'when the type de champ is not prefillable' do
let(:type_de_champ) { build(:type_de_champ_mesri) }
it { expect(possible_values).to be_empty }
end
let(:built) { described_class.build(type_de_champ, procedure.active_revision) }
subject(:possible_values) { built.possible_values }
context 'when the type de champ is prefillable' do
let(:type_de_champ) { build(:type_de_champ_email) }
context 'when the type de champ has a description' do
let(:type_de_champ) { build(:type_de_champ_text) }
it { expect(possible_values).to match([]) }
it { expect(possible_values).to include(I18n.t("views.prefill_descriptions.edit.possible_values.#{type_de_champ.type_champ}_html")) }
end
context 'when the type de champ does not have a description' do
let(:type_de_champ) { build(:type_de_champ_mesri) }
it { expect(possible_values).not_to include(I18n.t("views.prefill_descriptions.edit.possible_values.#{type_de_champ.type_champ}_html")) }
end
describe 'too many possible values or not' do
let!(:procedure) { create(:procedure, :with_drop_down_list) }
let(:type_de_champ) { procedure.draft_types_de_champ_public.first }
let(:link_to_all_possible_values) {
link_to(
I18n.t("views.prefill_descriptions.edit.possible_values.link.text"),
Rails.application.routes.url_helpers.prefill_type_de_champ_path(procedure.path, type_de_champ),
title: new_tab_suffix(I18n.t("views.prefill_descriptions.edit.possible_values.link.title")),
**external_link_attributes
)
}
context 'when there is too many possible values' do
before { type_de_champ.drop_down_options = (1..described_class::POSSIBLE_VALUES_THRESHOLD + 1).map(&:to_s) }
it { expect(possible_values).to include(link_to_all_possible_values) }
it { expect(possible_values).not_to include(built.all_possible_values.to_sentence) }
end
context 'when there is not too many possible values' do
before { type_de_champ.drop_down_options = (1..described_class::POSSIBLE_VALUES_THRESHOLD - 1).map(&:to_s) }
it { expect(possible_values).not_to include(link_to_all_possible_values) }
it { expect(possible_values).to include(built.all_possible_values.to_sentence) }
end
end
end
context 'when the type de champ is not prefillable' do
let(:type_de_champ) { build(:type_de_champ_mesri, procedure: procedure) }
it { expect(possible_values).to be_empty }
end
end
describe '#example_value' do
subject(:example_value) { described_class.build(type_de_champ).example_value }
subject(:example_value) { described_class.build(type_de_champ, procedure.active_revision).example_value }
context 'when the type de champ is not prefillable' do
let(:type_de_champ) { build(:type_de_champ_mesri) }
let(:type_de_champ) { build(:type_de_champ_mesri, procedure: procedure) }
it { expect(example_value).to be_nil }
end
context 'when the type de champ is prefillable' do
let(:type_de_champ) { build(:type_de_champ_email) }
let(:type_de_champ) { build(:type_de_champ_email, procedure: procedure) }
it { expect(example_value).to eq(I18n.t("views.prefill_descriptions.edit.examples.#{type_de_champ.type_champ}")) }
end
end
describe '#too_many_possible_values?' do
let(:type_de_champ) { build(:type_de_champ_drop_down_list) }
subject(:too_many_possible_values) { described_class.build(type_de_champ).too_many_possible_values? }
context 'when there are too many possible values' do
before { type_de_champ.drop_down_options = (1..described_class::POSSIBLE_VALUES_THRESHOLD + 1).map(&:to_s) }
it { expect(too_many_possible_values).to eq(true) }
end
context 'when there are not too many possible values' do
before { type_de_champ.drop_down_options = (1..described_class::POSSIBLE_VALUES_THRESHOLD).map(&:to_s) }
it { expect(too_many_possible_values).to eq(false) }
end
end
describe '#transform_value_to_assignable_attributes' do
let(:type_de_champ) { build(:type_de_champ_email) }
describe '#to_assignable_attributes' do
let(:type_de_champ) { build(:type_de_champ_email, procedure: procedure) }
let(:champ) { build(:champ, type_de_champ: type_de_champ) }
let(:value) { "any@email.org" }
subject(:transform_value_to_assignable_attributes) { described_class.build(type_de_champ).transform_value_to_assignable_attributes(value) }
subject(:to_assignable_attributes) { described_class.build(type_de_champ, procedure.active_revision).to_assignable_attributes(champ, value) }
it { is_expected.to match({ value: value }) }
it { is_expected.to match({ id: champ.id, value: value }) }
end
end

View file

@ -18,6 +18,9 @@ shared_examples "the user has got a prefilled dossier, owned by themselves" do
expect(page).to have_field(type_de_champ_text.libelle, with: text_value)
expect(page).to have_field(type_de_champ_phone.libelle, with: phone_value)
expect(page).to have_css('label', text: type_de_champ_phone.libelle)
expect(page).to have_css('h3', text: type_de_champ_repetition.libelle)
expect(page).to have_field(text_repetition_libelle, with: text_repetition_value)
expect(page).to have_field(integer_repetition_libelle, with: integer_repetition_value)
expect(page).to have_field(type_de_champ_datetime.libelle, with: datetime_value)
expect(page).to have_css('label', text: type_de_champ_multiple_drop_down_list.libelle)
expect(page).to have_content(multiple_drop_down_list_values.first)

View file

@ -5,7 +5,7 @@ describe 'As an integrator:', js: true do
before { visit "/preremplir/#{procedure.path}" }
scenario 'I can read the procedure prefilling (aka public champs)' do
expect(page).to have_content(type_de_champ.to_typed_id)
expect(page).to have_content(type_de_champ.to_typed_id_for_query)
expect(page).to have_content(I18n.t("activerecord.attributes.type_de_champ.type_champs.#{type_de_champ.type_champ}"))
expect(page).to have_content(type_de_champ.libelle)
expect(page).to have_content(type_de_champ.description)

View file

@ -11,6 +11,7 @@ describe 'Prefilling a dossier (with a GET request):' do
let(:type_de_champ_datetime) { create(:type_de_champ_datetime, procedure: procedure) }
let(:type_de_champ_multiple_drop_down_list) { create(:type_de_champ_multiple_drop_down_list, procedure: procedure) }
let(:type_de_champ_epci) { create(:type_de_champ_epci, procedure: procedure) }
let(:type_de_champ_repetition) { create(:type_de_champ_repetition, :with_types_de_champ, procedure: procedure) }
let(:text_value) { "My Neighbor Totoro is the best movie ever" }
let(:phone_value) { "invalid phone value" }
let(:datetime_value) { "2023-02-01T10:32" }
@ -21,15 +22,26 @@ describe 'Prefilling a dossier (with a GET request):' do
]
}
let(:epci_value) { ['01', '200029999'] }
let(:sub_type_de_champs_repetition) { procedure.active_revision.children_of(type_de_champ_repetition) }
let(:text_repetition_libelle) { sub_type_de_champs_repetition.first.libelle }
let(:integer_repetition_libelle) { sub_type_de_champs_repetition.second.libelle }
let(:text_repetition_value) { "First repetition text" }
let(:integer_repetition_value) { "42" }
let(:entry_path) {
commencer_path(
path: procedure.path,
"champ_#{type_de_champ_text.to_typed_id}" => text_value,
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value,
"champ_#{type_de_champ_datetime.to_typed_id}" => datetime_value,
"champ_#{type_de_champ_multiple_drop_down_list.to_typed_id}" => multiple_drop_down_list_values,
"champ_#{type_de_champ_epci.to_typed_id}" => epci_value
"champ_#{type_de_champ_text.to_typed_id_for_query}" => text_value,
"champ_#{type_de_champ_phone.to_typed_id_for_query}" => phone_value,
"champ_#{type_de_champ_datetime.to_typed_id_for_query}" => datetime_value,
"champ_#{type_de_champ_multiple_drop_down_list.to_typed_id_for_query}" => multiple_drop_down_list_values,
"champ_#{type_de_champ_epci.to_typed_id_for_query}" => epci_value,
"champ_#{type_de_champ_repetition.to_typed_id_for_query}" => [
{
"champ_#{sub_type_de_champs_repetition.first.to_typed_id_for_query}": text_repetition_value,
"champ_#{sub_type_de_champs_repetition.second.to_typed_id_for_query}": integer_repetition_value
}
]
)
}
@ -53,7 +65,6 @@ describe 'Prefilling a dossier (with a GET request):' do
before do
visit "/users/sign_in"
sign_in_with user.email, password
visit entry_path
click_on "Poursuivre mon dossier prérempli"

View file

@ -11,6 +11,7 @@ describe 'Prefilling a dossier (with a POST request):' do
let(:type_de_champ_datetime) { create(:type_de_champ_datetime, procedure: procedure) }
let(:type_de_champ_multiple_drop_down_list) { create(:type_de_champ_multiple_drop_down_list, procedure: procedure) }
let(:type_de_champ_epci) { create(:type_de_champ_epci, procedure: procedure) }
let(:type_de_champ_repetition) { create(:type_de_champ_repetition, :with_types_de_champ, procedure: procedure) }
let(:text_value) { "My Neighbor Totoro is the best movie ever" }
let(:phone_value) { "invalid phone value" }
let(:datetime_value) { "2023-02-01T10:32" }
@ -21,6 +22,11 @@ describe 'Prefilling a dossier (with a POST request):' do
]
}
let(:epci_value) { ['01', '200029999'] }
let(:sub_type_de_champs_repetition) { procedure.active_revision.children_of(type_de_champ_repetition) }
let(:text_repetition_libelle) { sub_type_de_champs_repetition.first.libelle }
let(:integer_repetition_libelle) { sub_type_de_champs_repetition.second.libelle }
let(:text_repetition_value) { "First repetition text" }
let(:integer_repetition_value) { "42" }
before do
allow(Rails).to receive(:cache).and_return(memory_store)
@ -120,11 +126,17 @@ describe 'Prefilling a dossier (with a POST request):' do
session.post api_public_v1_dossiers_path(procedure),
headers: { "Content-Type" => "application/json" },
params: {
"champ_#{type_de_champ_text.to_typed_id}" => text_value,
"champ_#{type_de_champ_phone.to_typed_id}" => phone_value,
"champ_#{type_de_champ_datetime.to_typed_id}" => datetime_value,
"champ_#{type_de_champ_multiple_drop_down_list.to_typed_id}" => multiple_drop_down_list_values,
"champ_#{type_de_champ_epci.to_typed_id}" => epci_value
"champ_#{type_de_champ_text.to_typed_id_for_query}" => text_value,
"champ_#{type_de_champ_phone.to_typed_id_for_query}" => phone_value,
"champ_#{type_de_champ_repetition.to_typed_id_for_query}" => [
{
"champ_#{sub_type_de_champs_repetition.first.to_typed_id_for_query}": text_repetition_value,
"champ_#{sub_type_de_champs_repetition.second.to_typed_id_for_query}": integer_repetition_value
}
],
"champ_#{type_de_champ_datetime.to_typed_id_for_query}" => datetime_value,
"champ_#{type_de_champ_multiple_drop_down_list.to_typed_id_for_query}" => multiple_drop_down_list_values,
"champ_#{type_de_champ_epci.to_typed_id_for_query}" => epci_value
}.to_json
JSON.parse(session.response.body)["dossier_url"].gsub("http://www.example.com", "")
end