From 26ece1d144963d847dbca998e80732fdfd1689c6 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Thu, 20 Sep 2018 18:46:32 +0200 Subject: [PATCH 01/16] [Fix #2613] Filter by date creation entreprise --- app/services/dossier_field_service.rb | 12 ++++----- spec/services/dossier_field_service_spec.rb | 29 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 spec/services/dossier_field_service_spec.rb diff --git a/app/services/dossier_field_service.rb b/app/services/dossier_field_service.rb index ba892e8d9ba..f5519c443e2 100644 --- a/app/services/dossier_field_service.rb +++ b/app/services/dossier_field_service.rb @@ -79,19 +79,19 @@ def filtered_ids(dossiers, filters) .includes(relation) .where("champs.type_de_champ_id = ?", filter['column'].to_i) .where("champs.value ILIKE ?", "%#{filter['value']}%") - when 'entreprise' - table = 'etablissement' - if filter['column'] == 'date_creation' + when 'etablissement' + table = filter['table'] + if filter['column'] == 'entreprise_date_creation' date = filter['value'].to_date rescue nil dossiers .includes(table) - .where("#{table.pluralize}.entreprise_#{filter['column']} = ?", date) + .where("#{table.pluralize}.#{filter['column']} = ?", date) else dossiers .includes(table) - .where("#{table.pluralize}.entreprise_#{filter['column']} ILIKE ?", "%#{filter['value']}%") + .where("#{table.pluralize}.#{filter['column']} ILIKE ?", "%#{filter['value']}%") end - when 'user', 'etablissement' + when 'user' dossiers .includes(filter['table']) .where("#{filter['table'].pluralize}.#{filter['column']} ILIKE ?", "%#{filter['value']}%") diff --git a/spec/services/dossier_field_service_spec.rb b/spec/services/dossier_field_service_spec.rb new file mode 100644 index 00000000000..cc0c0e975d3 --- /dev/null +++ b/spec/services/dossier_field_service_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +describe DossierFieldService do + describe '#filtered_ids' do + let(:procedure) { create(:procedure) } + + context 'for etablissement table' do + context 'for entreprise_date_creation column' do + let!(:kept_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, entreprise_date_creation: DateTime.new(2018, 6, 21))) } + let!(:discarded_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, entreprise_date_creation: DateTime.new(2008, 6, 21))) } + + subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'etablissement', 'column' => 'entreprise_date_creation', 'value' => '21/6/2018' }]) } + + it { is_expected.to contain_exactly(kept_dossier.id) } + end + + context 'for code_postal column' do + # All columns except entreprise_date_creation work exacly the same, just testing one + + let!(:kept_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '75017')) } + let!(:discarded_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '25000')) } + + subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'etablissement', 'column' => 'code_postal', 'value' => '75017' }]) } + + it { is_expected.to contain_exactly(kept_dossier.id) } + end + end + end +end From 112fdb71fb8350320c4ad17661703f6e161be960 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Thu, 20 Sep 2018 18:56:44 +0200 Subject: [PATCH 02/16] [#2613] Remove dead code --- app/services/dossier_field_service.rb | 2 -- spec/models/dossier_spec.rb | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/services/dossier_field_service.rb b/app/services/dossier_field_service.rb index f5519c443e2..08ce0d58b4d 100644 --- a/app/services/dossier_field_service.rb +++ b/app/services/dossier_field_service.rb @@ -51,8 +51,6 @@ def get_value(dossier, table, column) dossier.user.send(column) when 'france_connect_information' dossier.user.france_connect_information&.send(column) - when 'entreprise' - dossier.etablissement&.send(:"entreprise_#{column}") when 'etablissement' dossier.etablissement&.send(column) when 'type_de_champ' diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index f2a1be9749a..901599bfb8e 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -750,7 +750,7 @@ it { expect(dossier.get_value('self', 'created_at')).to eq(dossier.created_at) } it { expect(dossier.get_value('user', 'email')).to eq(user.email) } it { expect(dossier.get_value('france_connect_information', 'gender')).to eq(user.france_connect_information.gender) } - it { expect(dossier.get_value('entreprise', 'siren')).to eq(dossier.etablissement.entreprise_siren) } + it { expect(dossier.get_value('etablissement', 'entreprise_siren')).to eq(dossier.etablissement.entreprise_siren) } it { expect(dossier.get_value('etablissement', 'siret')).to eq(dossier.etablissement.siret) } it { expect(dossier.get_value('type_de_champ', @champ_public.type_de_champ.id.to_s)).to eq(dossier.champs.first.value) } it { expect(dossier.get_value('type_de_champ_private', @champ_private.type_de_champ.id.to_s)).to eq(dossier.champs_private.first.value) } From a48ffef9dc90ffa06e4b406988f88672fc20cc26 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Thu, 20 Sep 2018 20:18:45 +0200 Subject: [PATCH 03/16] [#2613] Clean up procedure presentation with entreprise table --- ..._20_procedure_presentation_entreprise.rake | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 lib/tasks/2018_09_20_procedure_presentation_entreprise.rake diff --git a/lib/tasks/2018_09_20_procedure_presentation_entreprise.rake b/lib/tasks/2018_09_20_procedure_presentation_entreprise.rake new file mode 100644 index 00000000000..ca2dd15c06a --- /dev/null +++ b/lib/tasks/2018_09_20_procedure_presentation_entreprise.rake @@ -0,0 +1,51 @@ +namespace :'2018_09_20_procedure_presentation_entreprise' do + task run: :environment do + Class.new do + def run + fix_displayed_fields + fix_sort + fix_filters + end + + def fix_displayed_fields + ProcedurePresentation.where(%q`displayed_fields @> '[{"table": "entreprise"}]'`).each do |procedure_presentation| + procedure_presentation.displayed_fields.each { |field| entreprise_to_etablissement(field) } + + procedure_presentation.save + end + end + + def fix_sort + ProcedurePresentation.where(%q`sort @> '{"table": "entreprise"}'`).each do |procedure_presentation| + entreprise_to_etablissement(procedure_presentation['sort']) + + procedure_presentation.save + end + end + + def fix_filters + ProcedurePresentation.find_by_sql( + <<~SQL + SELECT procedure_presentations.*, array_agg(key) as keys + FROM procedure_presentations, LATERAL jsonb_each_text(filters) + WHERE value::jsonb @> '[{"table": "entreprise"}]' + GROUP BY id; + SQL + ).each do |procedure_presentation| + procedure_presentation.keys.each do |key| + procedure_presentation.filters[key].each { |filter| entreprise_to_etablissement(filter) } + end + + procedure_presentation.save + end + end + + def entreprise_to_etablissement(field) + if field['table'] == 'entreprise' + field['table'] = 'etablissement' + field['column'] = "entreprise_#{field['column']}" + end + end + end.new.run + end +end From 9beaa293cd53183f82ab68c00105d8ca0333e13b Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 11 Sep 2018 18:57:51 +0200 Subject: [PATCH 04/16] [#1421] Use delegation rather than STI for TypeDeChamp --- .../champs/linked_drop_down_list_champ.rb | 2 +- app/models/type_de_champ.rb | 16 +++++++ .../types_de_champ/checkbox_type_de_champ.rb | 2 +- .../types_de_champ/civilite_type_de_champ.rb | 2 +- .../types_de_champ/date_type_de_champ.rb | 2 +- .../types_de_champ/datetime_type_de_champ.rb | 2 +- .../dossier_link_type_de_champ.rb | 2 +- .../drop_down_list_type_de_champ.rb | 2 +- .../header_section_type_de_champ.rb | 2 +- .../linked_drop_down_list_type_de_champ.rb | 4 +- .../multiple_drop_down_list_type_de_champ.rb | 2 +- .../types_de_champ/number_type_de_champ.rb | 2 +- .../piece_justificative_type_de_champ.rb | 2 +- .../types_de_champ/siret_type_de_champ.rb | 2 +- .../types_de_champ/text_type_de_champ.rb | 2 +- .../types_de_champ/type_de_champ_base.rb | 5 ++ app/services/types_de_champ_service.rb | 4 -- .../admin/types_de_champ/_fields.html.haml | 1 - ...14_add_annotation_privee_to_procedure.rake | 2 +- lib/tasks/2018_07_31_nutriscore.rake | 12 ++--- lib/tasks/dossier_procedure_migrator.rb | 5 +- spec/factories/type_de_champ.rb | 48 +++++++++---------- ...add_annotation_privee_to_procedure_spec.rb | 4 +- spec/lib/rake/2018_07_31_nutriscore_spec.rb | 6 +-- spec/models/type_de_champ_shared_example.rb | 2 +- ...inked_drop_down_list_type_de_champ_spec.rb | 12 +++-- 26 files changed, 82 insertions(+), 65 deletions(-) create mode 100644 app/models/types_de_champ/type_de_champ_base.rb diff --git a/app/models/champs/linked_drop_down_list_champ.rb b/app/models/champs/linked_drop_down_list_champ.rb index 060bfe81aa6..f965a472c0a 100644 --- a/app/models/champs/linked_drop_down_list_champ.rb +++ b/app/models/champs/linked_drop_down_list_champ.rb @@ -1,5 +1,5 @@ class Champs::LinkedDropDownListChamp < Champ - delegate :primary_options, :secondary_options, to: :type_de_champ + delegate :primary_options, :secondary_options, to: 'type_de_champ.dynamic_type' def primary_value if value.present? diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index f8aa85a4cfa..79aee06b49d 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -1,4 +1,7 @@ class TypeDeChamp < ApplicationRecord + # TODO drop next line when `type` column has been dropped from `types_de_champ` table + self.inheritance_column = nil + enum type_champs: { text: 'text', textarea: 'textarea', @@ -27,6 +30,10 @@ class TypeDeChamp < ApplicationRecord belongs_to :procedure + after_initialize :set_dynamic_type + + attr_reader :dynamic_type + scope :public_only, -> { where(private: false) } scope :private_only, -> { where(private: true) } scope :ordered, -> { order(order_place: :asc) } @@ -52,6 +59,15 @@ def create(params = {}) before_validation :check_mandatory before_save :remove_piece_justificative_template, if: -> { type_champ_changed? } + def set_dynamic_type + @dynamic_type = type_champ.present? ? self.class.type_champ_to_class_name(type_champ).constantize.new(self) : nil + end + + def type_champ=(value) + super(value) + set_dynamic_type + end + def params_for_champ { private: private?, diff --git a/app/models/types_de_champ/checkbox_type_de_champ.rb b/app/models/types_de_champ/checkbox_type_de_champ.rb index 498c2ef7d54..717cb92cf46 100644 --- a/app/models/types_de_champ/checkbox_type_de_champ.rb +++ b/app/models/types_de_champ/checkbox_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::CheckboxTypeDeChamp < TypeDeChamp +class TypesDeChamp::CheckboxTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/civilite_type_de_champ.rb b/app/models/types_de_champ/civilite_type_de_champ.rb index d252cf452b9..508c14f06ae 100644 --- a/app/models/types_de_champ/civilite_type_de_champ.rb +++ b/app/models/types_de_champ/civilite_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::CiviliteTypeDeChamp < TypeDeChamp +class TypesDeChamp::CiviliteTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/date_type_de_champ.rb b/app/models/types_de_champ/date_type_de_champ.rb index 8d87350ed47..65b0d5fc7e0 100644 --- a/app/models/types_de_champ/date_type_de_champ.rb +++ b/app/models/types_de_champ/date_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::DateTypeDeChamp < TypeDeChamp +class TypesDeChamp::DateTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/datetime_type_de_champ.rb b/app/models/types_de_champ/datetime_type_de_champ.rb index e2a9406b330..2ccfec18f4b 100644 --- a/app/models/types_de_champ/datetime_type_de_champ.rb +++ b/app/models/types_de_champ/datetime_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::DatetimeTypeDeChamp < TypeDeChamp +class TypesDeChamp::DatetimeTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/dossier_link_type_de_champ.rb b/app/models/types_de_champ/dossier_link_type_de_champ.rb index 1b3352998eb..5c91a820f9e 100644 --- a/app/models/types_de_champ/dossier_link_type_de_champ.rb +++ b/app/models/types_de_champ/dossier_link_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::DossierLinkTypeDeChamp < TypeDeChamp +class TypesDeChamp::DossierLinkTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/drop_down_list_type_de_champ.rb b/app/models/types_de_champ/drop_down_list_type_de_champ.rb index 94c77c016ef..c930f3ff711 100644 --- a/app/models/types_de_champ/drop_down_list_type_de_champ.rb +++ b/app/models/types_de_champ/drop_down_list_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::DropDownListTypeDeChamp < TypeDeChamp +class TypesDeChamp::DropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/header_section_type_de_champ.rb b/app/models/types_de_champ/header_section_type_de_champ.rb index 73f9112dd5a..d81baca291e 100644 --- a/app/models/types_de_champ/header_section_type_de_champ.rb +++ b/app/models/types_de_champ/header_section_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::HeaderSectionTypeDeChamp < TypeDeChamp +class TypesDeChamp::HeaderSectionTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb b/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb index 6e602a97f5b..c1aa269aaef 100644 --- a/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb +++ b/app/models/types_de_champ/linked_drop_down_list_type_de_champ.rb @@ -1,6 +1,8 @@ -class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypeDeChamp +class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBase PRIMARY_PATTERN = /^--(.*)--$/ + delegate :drop_down_list, to: :@type_de_champ + def primary_options primary_options = unpack_options.map(&:first) if primary_options.present? diff --git a/app/models/types_de_champ/multiple_drop_down_list_type_de_champ.rb b/app/models/types_de_champ/multiple_drop_down_list_type_de_champ.rb index 5a99093f379..f5028c30263 100644 --- a/app/models/types_de_champ/multiple_drop_down_list_type_de_champ.rb +++ b/app/models/types_de_champ/multiple_drop_down_list_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::MultipleDropDownListTypeDeChamp < TypeDeChamp +class TypesDeChamp::MultipleDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/number_type_de_champ.rb b/app/models/types_de_champ/number_type_de_champ.rb index c47c1347f73..9ff857f157d 100644 --- a/app/models/types_de_champ/number_type_de_champ.rb +++ b/app/models/types_de_champ/number_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::NumberTypeDeChamp < TypeDeChamp +class TypesDeChamp::NumberTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/piece_justificative_type_de_champ.rb b/app/models/types_de_champ/piece_justificative_type_de_champ.rb index 5fd09c4599b..d511407862c 100644 --- a/app/models/types_de_champ/piece_justificative_type_de_champ.rb +++ b/app/models/types_de_champ/piece_justificative_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::PieceJustificativeTypeDeChamp < TypeDeChamp +class TypesDeChamp::PieceJustificativeTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/siret_type_de_champ.rb b/app/models/types_de_champ/siret_type_de_champ.rb index 47be81287d5..6f869b8bd8f 100644 --- a/app/models/types_de_champ/siret_type_de_champ.rb +++ b/app/models/types_de_champ/siret_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::SiretTypeDeChamp < TypeDeChamp +class TypesDeChamp::SiretTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/text_type_de_champ.rb b/app/models/types_de_champ/text_type_de_champ.rb index 5d0a0a2f693..437a1ef8a8c 100644 --- a/app/models/types_de_champ/text_type_de_champ.rb +++ b/app/models/types_de_champ/text_type_de_champ.rb @@ -1,2 +1,2 @@ -class TypesDeChamp::TextTypeDeChamp < TypeDeChamp +class TypesDeChamp::TextTypeDeChamp < TypesDeChamp::TypeDeChampBase end diff --git a/app/models/types_de_champ/type_de_champ_base.rb b/app/models/types_de_champ/type_de_champ_base.rb new file mode 100644 index 00000000000..a04f9d86247 --- /dev/null +++ b/app/models/types_de_champ/type_de_champ_base.rb @@ -0,0 +1,5 @@ +class TypesDeChamp::TypeDeChampBase + def initialize(type_de_champ) + @type_de_champ = type_de_champ + end +end diff --git a/app/services/types_de_champ_service.rb b/app/services/types_de_champ_service.rb index 23dee3310ba..ccd1ab898dd 100644 --- a/app/services/types_de_champ_service.rb +++ b/app/services/types_de_champ_service.rb @@ -19,10 +19,6 @@ def self.create_update_procedure_params(params, private = false) parameters[attributes].each do |index, param| param[:private] = private - if param[:type_champ] - param[:type] = TypeDeChamp.type_champ_to_class_name(param[:type_champ]) - end - if param[:libelle].empty? parameters[attributes].delete(index.to_s) end diff --git a/app/views/admin/types_de_champ/_fields.html.haml b/app/views/admin/types_de_champ/_fields.html.haml index 3d16755147a..b157e895cb5 100644 --- a/app/views/admin/types_de_champ/_fields.html.haml +++ b/app/views/admin/types_de_champ/_fields.html.haml @@ -46,7 +46,6 @@ .form-group = ff.hidden_field :order_place, value: ff.index - = ff.hidden_field :type = ff.hidden_field :id - if ff.object.id.present? diff --git a/lib/tasks/2018_05_14_add_annotation_privee_to_procedure.rake b/lib/tasks/2018_05_14_add_annotation_privee_to_procedure.rake index 5db1d468a01..22d496dface 100644 --- a/lib/tasks/2018_05_14_add_annotation_privee_to_procedure.rake +++ b/lib/tasks/2018_05_14_add_annotation_privee_to_procedure.rake @@ -15,7 +15,7 @@ namespace :'2018_05_14_add_annotation_privee_to_procedure' do tdc.update_attribute(:order_place, tdc.order_place + 1) end - new_tdc = TypesDeChamp::TextTypeDeChamp.create( + new_tdc = TypeDeChamp.create( procedure_id: procedure_id, private: true, libelle: 'URL Espace de consultation', diff --git a/lib/tasks/2018_07_31_nutriscore.rake b/lib/tasks/2018_07_31_nutriscore.rake index 4f48664d35d..0f4b86793f7 100644 --- a/lib/tasks/2018_07_31_nutriscore.rake +++ b/lib/tasks/2018_07_31_nutriscore.rake @@ -34,7 +34,7 @@ namespace :'2018_07_31_nutriscore' do end discard_source_champ( - TypesDeChamp::TextTypeDeChamp.new( + TypeDeChamp.new( type_champ: 'text', order_place: siret_order_place, libelle: 'Numéro SIRET' @@ -42,7 +42,7 @@ namespace :'2018_07_31_nutriscore' do ) discard_source_champ( - TypesDeChamp::TextTypeDeChamp.new( + TypeDeChamp.new( type_champ: 'text', order_place: fonction_order_place, libelle: 'Fonction' @@ -50,7 +50,7 @@ namespace :'2018_07_31_nutriscore' do ) compute_destination_champ( - TypesDeChamp::TextTypeDeChamp.new( + TypeDeChamp.new( type_champ: 'text', order_place: fonction_order_place, libelle: 'Fonction', @@ -66,7 +66,7 @@ namespace :'2018_07_31_nutriscore' do end compute_destination_champ( - TypesDeChamp::SiretTypeDeChamp.new( + TypeDeChamp.new( type_champ: 'siret', order_place: siret_order_place, libelle: 'Numéro SIRET' @@ -80,7 +80,7 @@ namespace :'2018_07_31_nutriscore' do end compute_destination_champ( - TypesDeChamp::HeaderSectionTypeDeChamp.new( + TypeDeChamp.new( type_champ: 'header_section', order_place: 18, libelle: 'PARTIE 3 : ZONE GEOGRAPHIQUE' @@ -90,7 +90,7 @@ namespace :'2018_07_31_nutriscore' do end compute_destination_champ( - TypesDeChamp::MultipleDropDownListTypeDeChamp.new( + TypeDeChamp.new( type_champ: 'multiple_drop_down_list', order_place: 19, libelle: 'Pays de commercialisation', diff --git a/lib/tasks/dossier_procedure_migrator.rb b/lib/tasks/dossier_procedure_migrator.rb index f5833b52f66..ae4d77c122f 100644 --- a/lib/tasks/dossier_procedure_migrator.rb +++ b/lib/tasks/dossier_procedure_migrator.rb @@ -57,7 +57,7 @@ def compute_destination_champ(destination_type_de_champ, &block) def type_de_champ_to_expectation(tdc) if tdc.present? - expectation = tdc.as_json(only: [:libelle, :type, :type_champ, :mandatory]) + expectation = tdc.as_json(only: [:libelle, :type_champ, :mandatory]) expectation['drop_down'] = tdc.drop_down_list.presence&.options&.presence expectation else @@ -107,9 +107,6 @@ def check_champ_consistency(label, expected_tdc, actual_tdc) if actual_tdc.libelle != expected_tdc['libelle'] errors.append("incorrect libelle #{actual_tdc.libelle} (expected #{expected_tdc['libelle']})") end - if actual_tdc.type != expected_tdc['type'] - errors.append("incorrect type #{actual_tdc.type} (expected #{expected_tdc['type']})") - end if actual_tdc.type_champ != expected_tdc['type_champ'] errors.append("incorrect type champ #{actual_tdc.type_champ} (expected #{expected_tdc['type_champ']})") end diff --git a/spec/factories/type_de_champ.rb b/spec/factories/type_de_champ.rb index 2c66117be78..c208f5aacc1 100644 --- a/spec/factories/type_de_champ.rb +++ b/spec/factories/type_de_champ.rb @@ -1,5 +1,5 @@ FactoryBot.define do - factory :type_de_champ, class: 'TypesDeChamp::TextTypeDeChamp' do + factory :type_de_champ do private { false } # Previous line is kept blank so that rubocop does not complain @@ -9,79 +9,79 @@ order_place { 1 } mandatory { false } - factory :type_de_champ_text, class: 'TypesDeChamp::TextTypeDeChamp' do + factory :type_de_champ_text do type_champ { TypeDeChamp.type_champs.fetch(:text) } end - factory :type_de_champ_textarea, class: 'TypesDeChamp::TextareaTypeDeChamp' do + factory :type_de_champ_textarea do type_champ { TypeDeChamp.type_champs.fetch(:textarea) } end - factory :type_de_champ_number, class: 'TypesDeChamp::NumberTypeDeChamp' do + factory :type_de_champ_number do type_champ { TypeDeChamp.type_champs.fetch(:number) } end - factory :type_de_champ_checkbox, class: 'TypesDeChamp::CheckboxTypeDeChamp' do + factory :type_de_champ_checkbox do type_champ { TypeDeChamp.type_champs.fetch(:checkbox) } end - factory :type_de_champ_civilite, class: 'TypesDeChamp::CiviliteTypeDeChamp' do + factory :type_de_champ_civilite do type_champ { TypeDeChamp.type_champs.fetch(:civilite) } end - factory :type_de_champ_email, class: 'TypesDeChamp::EmailTypeDeChamp' do + factory :type_de_champ_email do type_champ { TypeDeChamp.type_champs.fetch(:email) } end - factory :type_de_champ_phone, class: 'TypesDeChamp::PhoneTypeDeChamp' do + factory :type_de_champ_phone do type_champ { TypeDeChamp.type_champs.fetch(:phone) } end - factory :type_de_champ_address, class: 'TypesDeChamp::AddressTypeDeChamp' do + factory :type_de_champ_address do type_champ { TypeDeChamp.type_champs.fetch(:address) } end - factory :type_de_champ_yes_no, class: 'TypesDeChamp::YesNoTypeDeChamp' do + factory :type_de_champ_yes_no do libelle { 'Yes/no' } type_champ { TypeDeChamp.type_champs.fetch(:yes_no) } end - factory :type_de_champ_date, class: 'TypesDeChamp::DateTypeDeChamp' do + factory :type_de_champ_date do type_champ { TypeDeChamp.type_champs.fetch(:date) } end - factory :type_de_champ_datetime, class: 'TypesDeChamp::DatetimeTypeDeChamp' do + factory :type_de_champ_datetime do type_champ { TypeDeChamp.type_champs.fetch(:datetime) } end - factory :type_de_champ_drop_down_list, class: 'TypesDeChamp::DropDownListTypeDeChamp' do + factory :type_de_champ_drop_down_list do libelle { 'Menu déroulant' } type_champ { TypeDeChamp.type_champs.fetch(:drop_down_list) } drop_down_list { create(:drop_down_list) } end - factory :type_de_champ_multiple_drop_down_list, class: 'TypesDeChamp::MultipleDropDownListTypeDeChamp' do + factory :type_de_champ_multiple_drop_down_list do type_champ { TypeDeChamp.type_champs.fetch(:multiple_drop_down_list) } drop_down_list { create(:drop_down_list) } end - factory :type_de_champ_linked_drop_down_list, class: 'TypesDeChamp::LinkedDropDownListTypeDeChamp' do + factory :type_de_champ_linked_drop_down_list do type_champ { TypeDeChamp.type_champs.fetch(:linked_drop_down_list) } drop_down_list { create(:drop_down_list) } end - factory :type_de_champ_pays, class: 'TypesDeChamp::PaysTypeDeChamp' do + factory :type_de_champ_pays do type_champ { TypeDeChamp.type_champs.fetch(:pays) } end - factory :type_de_champ_regions, class: 'TypesDeChamp::RegionTypeDeChamp' do + factory :type_de_champ_regions do type_champ { TypeDeChamp.type_champs.fetch(:regions) } end - factory :type_de_champ_departements, class: 'TypesDeChamp::DepartementTypeDeChamp' do + factory :type_de_champ_departements do type_champ { TypeDeChamp.type_champs.fetch(:departements) } end - factory :type_de_champ_engagement, class: 'TypesDeChamp::EngagementTypeDeChamp' do + factory :type_de_champ_engagement do type_champ { TypeDeChamp.type_champs.fetch(:engagement) } end - factory :type_de_champ_header_section, class: 'TypesDeChamp::HeaderSectionTypeDeChamp' do + factory :type_de_champ_header_section do type_champ { TypeDeChamp.type_champs.fetch(:header_section) } end - factory :type_de_champ_explication, class: 'TypesDeChamp::ExplicationTypeDeChamp' do + factory :type_de_champ_explication do type_champ { TypeDeChamp.type_champs.fetch(:explication) } end - factory :type_de_champ_dossier_link, class: 'TypesDeChamp::DossierLinkTypeDeChamp' do + factory :type_de_champ_dossier_link do libelle { 'Référence autre dossier' } type_champ { TypeDeChamp.type_champs.fetch(:dossier_link) } end - factory :type_de_champ_piece_justificative, class: 'TypesDeChamp::PieceJustificativeTypeDeChamp' do + factory :type_de_champ_piece_justificative do type_champ { TypeDeChamp.type_champs.fetch(:piece_justificative) } end - factory :type_de_champ_siret, class: 'TypesDeChamp::SiretTypeDeChamp' do + factory :type_de_champ_siret do type_champ { TypeDeChamp.type_champs.fetch(:siret) } end diff --git a/spec/lib/rake/2018_05_14_add_annotation_privee_to_procedure_spec.rb b/spec/lib/rake/2018_05_14_add_annotation_privee_to_procedure_spec.rb index 2817c47977d..e14e5401260 100644 --- a/spec/lib/rake/2018_05_14_add_annotation_privee_to_procedure_spec.rb +++ b/spec/lib/rake/2018_05_14_add_annotation_privee_to_procedure_spec.rb @@ -3,7 +3,7 @@ let!(:procedure) do procedure = create(:procedure) 10.times do |i| - TypesDeChamp::NumberTypeDeChamp.create( + TypeDeChamp.create( procedure: procedure, private: false, libelle: 'libelle', @@ -11,7 +11,7 @@ type_champ: 'number' ) - TypesDeChamp::NumberTypeDeChamp.create( + TypeDeChamp.create( procedure: procedure, private: true, libelle: 'libelle', diff --git a/spec/lib/rake/2018_07_31_nutriscore_spec.rb b/spec/lib/rake/2018_07_31_nutriscore_spec.rb index 4fda852aa19..7ce3ff97b4f 100644 --- a/spec/lib/rake/2018_07_31_nutriscore_spec.rb +++ b/spec/lib/rake/2018_07_31_nutriscore_spec.rb @@ -95,7 +95,7 @@ def run_task context 'with champ type mismatch' do let!(:type_champ_to) { create(:type_de_champ_text, order_place: 1, libelle: 'texte', procedure: proc_to) } - it { expect { run_task }.to raise_exception(/incorrect type TypesDeChamp::TextareaTypeDeChamp \(expected TypesDeChamp::TextTypeDeChamp\), incorrect type champ textarea \(expected text\)$/) } + it { expect { run_task }.to raise_exception(/incorrect type champ textarea \(expected text\)$/) } end context 'with champ mandatoriness mismatch' do @@ -114,13 +114,13 @@ def run_task context 'with siret mismatch on source' do let!(:type_champ_siret_from) { create(:type_de_champ_textarea, order_place: 2, libelle: 'Numéro SIRET', procedure: proc_from) } - it { expect { run_task }.to raise_exception(/incorrect type TypesDeChamp::TextareaTypeDeChamp \(expected TypesDeChamp::TextTypeDeChamp\), incorrect type champ textarea \(expected text\)$/) } + it { expect { run_task }.to raise_exception(/incorrect type champ textarea \(expected text\)$/) } end context 'with siret mismatch on destination' do let!(:type_champ_siret_to) { create(:type_de_champ_text, order_place: 2, libelle: 'Numéro SIRET', procedure: proc_to) } - it { expect { run_task }.to raise_exception(/incorrect type TypesDeChamp::TextTypeDeChamp \(expected TypesDeChamp::SiretTypeDeChamp\), incorrect type champ text \(expected siret\)$/) } + it { expect { run_task }.to raise_exception(/incorrect type champ text \(expected siret\)$/) } end end end diff --git a/spec/models/type_de_champ_shared_example.rb b/spec/models/type_de_champ_shared_example.rb index 7ee3faf0c2f..f23cf215692 100644 --- a/spec/models/type_de_champ_shared_example.rb +++ b/spec/models/type_de_champ_shared_example.rb @@ -21,7 +21,7 @@ type_de_champ = create(:"type_de_champ_#{type_champ}") champ = type_de_champ.champ.create - expect(type_de_champ.class.name).to match(/^TypesDeChamp::/) + expect(type_de_champ.dynamic_type.class.name).to match(/^TypesDeChamp::/) expect(champ.class.name).to match(/^Champs::/) end end diff --git a/spec/models/types_de_champ/linked_drop_down_list_type_de_champ_spec.rb b/spec/models/types_de_champ/linked_drop_down_list_type_de_champ_spec.rb index ab0fcf20373..f9bc0af6ae8 100644 --- a/spec/models/types_de_champ/linked_drop_down_list_type_de_champ_spec.rb +++ b/spec/models/types_de_champ/linked_drop_down_list_type_de_champ_spec.rb @@ -3,12 +3,14 @@ describe TypesDeChamp::LinkedDropDownListTypeDeChamp do describe '#unpack_options' do let(:drop_down_list) { build(:drop_down_list, value: menu_options) } - let(:type_de_champ) { described_class.new(drop_down_list: drop_down_list) } + let(:type_de_champ) { build(:type_de_champ_linked_drop_down_list, drop_down_list: drop_down_list) } + + subject { type_de_champ.dynamic_type } context 'with no options' do let(:menu_options) { '' } - it { expect(type_de_champ.secondary_options).to eq({}) } - it { expect(type_de_champ.primary_options).to eq([]) } + it { expect(subject.secondary_options).to eq({}) } + it { expect(subject.primary_options).to eq([]) } end context 'with two primary options' do @@ -25,7 +27,7 @@ end it do - expect(type_de_champ.secondary_options).to eq( + expect(subject.secondary_options).to eq( { '' => [], 'Primary 1' => [ '', 'secondary 1.1', 'secondary 1.2'], @@ -34,7 +36,7 @@ ) end - it { expect(type_de_champ.primary_options).to eq([ '', 'Primary 1', 'Primary 2' ]) } + it { expect(subject.primary_options).to eq([ '', 'Primary 1', 'Primary 2' ]) } end end end From 2b2dbcb112806a225e68af09441e7da7872b23da Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 25 Sep 2018 09:24:41 +0000 Subject: [PATCH 05/16] dossier spec: move visit_dossier to a `before` block --- .../features/new_user/dossier_details_spec.rb | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/spec/features/new_user/dossier_details_spec.rb b/spec/features/new_user/dossier_details_spec.rb index fb62483bfe4..32efd972908 100644 --- a/spec/features/new_user/dossier_details_spec.rb +++ b/spec/features/new_user/dossier_details_spec.rb @@ -8,11 +8,10 @@ before do Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, true) + visit_dossier dossier end scenario 'the user can see the summary of the dossier status' do - visit_dossier dossier - expect(page).to have_current_path(dossier_path(dossier)) expect(page).to have_content(dossier.id) expect(page).to have_selector('.status-explanation') @@ -20,30 +19,24 @@ end describe "the user can see the mean time they are expected to wait" do - context "the dossier is in construction" do + context "when the dossier is in construction" do before do other_dossier = create(:dossier, :accepte, :for_individual, procedure: simple_procedure, en_construction_at: 10.days.ago, en_instruction_at: Time.now) + visit dossier_path(dossier) end - it "show the proper wait time" do - visit_dossier dossier - - expect(page).to have_text("Le temps moyen de vérification pour cette démarche est de 10 jours.") - end + it { expect(page).to have_text("Le temps moyen de vérification pour cette démarche est de 10 jours.") } end - context "the dossier is in instruction" do + context "when the dossier is in instruction" do let(:dossier) { create(:dossier, :en_instruction, :for_individual, :with_commentaires, user: user, procedure: simple_procedure) } before do other_dossier = create(:dossier, :accepte, :for_individual, procedure: simple_procedure, en_instruction_at: 2.months.ago, processed_at: Time.now) + visit dossier_path(dossier) end - it "show the proper wait time" do - visit_dossier dossier - - expect(page).to have_text("Le temps moyen d’instruction pour cette démarche est de 2 mois.") - end + it { expect(page).to have_text("Le temps moyen d’instruction pour cette démarche est de 2 mois.") } end end From df2bbba201cc88daf4ab8b85c487e6cce1e6a745 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 24 Sep 2018 13:54:46 +0000 Subject: [PATCH 06/16] dossier spec: create a `simple_procedure` factory --- spec/factories/procedure.rb | 8 ++++++++ spec/features/new_user/dossier_details_spec.rb | 13 +++++-------- spec/features/new_user/invite_spec.rb | 12 ++++++------ 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/spec/factories/procedure.rb b/spec/factories/procedure.rb index 182103e72d9..2f548163d4e 100644 --- a/spec/factories/procedure.rb +++ b/spec/factories/procedure.rb @@ -22,6 +22,14 @@ end end + factory :simple_procedure do + after(:build) do |procedure, _evaluator| + procedure.for_individual = true + procedure.types_de_champ << create(:type_de_champ, libelle: 'Texte obligatoire', mandatory: true) + procedure.publish!(generate(:published_path)) + end + end + after(:build) do |procedure, _evaluator| if procedure.module_api_carto.nil? module_api_carto = create(:module_api_carto) diff --git a/spec/features/new_user/dossier_details_spec.rb b/spec/features/new_user/dossier_details_spec.rb index 32efd972908..5ac0f53a158 100644 --- a/spec/features/new_user/dossier_details_spec.rb +++ b/spec/features/new_user/dossier_details_spec.rb @@ -1,10 +1,7 @@ describe 'Dossier details:' do let(:user) { create(:user) } - let(:simple_procedure) do - tdcs = [create(:type_de_champ, libelle: 'texte obligatoire')] - create(:procedure, :published, :for_individual, types_de_champ: tdcs) - end - let(:dossier) { create(:dossier, :en_construction, :for_individual, :with_commentaires, user: user, procedure: simple_procedure) } + let(:procedure) { create(:simple_procedure) } + let(:dossier) { create(:dossier, :en_construction, :for_individual, :with_commentaires, user: user, procedure: procedure) } before do Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, true) @@ -21,7 +18,7 @@ describe "the user can see the mean time they are expected to wait" do context "when the dossier is in construction" do before do - other_dossier = create(:dossier, :accepte, :for_individual, procedure: simple_procedure, en_construction_at: 10.days.ago, en_instruction_at: Time.now) + other_dossier = create(:dossier, :accepte, :for_individual, procedure: procedure, en_construction_at: 10.days.ago, en_instruction_at: Time.now) visit dossier_path(dossier) end @@ -29,10 +26,10 @@ end context "when the dossier is in instruction" do - let(:dossier) { create(:dossier, :en_instruction, :for_individual, :with_commentaires, user: user, procedure: simple_procedure) } + let(:dossier) { create(:dossier, :en_instruction, :for_individual, :with_commentaires, user: user, procedure: procedure) } before do - other_dossier = create(:dossier, :accepte, :for_individual, procedure: simple_procedure, en_instruction_at: 2.months.ago, processed_at: Time.now) + other_dossier = create(:dossier, :accepte, :for_individual, procedure: procedure, en_instruction_at: 2.months.ago, processed_at: Time.now) visit dossier_path(dossier) end diff --git a/spec/features/new_user/invite_spec.rb b/spec/features/new_user/invite_spec.rb index 08c4d6385e4..fd1950f692b 100644 --- a/spec/features/new_user/invite_spec.rb +++ b/spec/features/new_user/invite_spec.rb @@ -3,7 +3,7 @@ feature 'Invitations' do let(:user) { create(:user) } let(:invited_user) { create(:user, email: 'user_invite@exemple.fr') } - let(:procedure) { create(:procedure, :published, :with_type_de_champ) } + let(:procedure) { create(:simple_procedure) } let(:invite) { create(:invite_user, user: invited_user, dossier: dossier) } context 'when the dossier is a brouillon' do @@ -13,7 +13,7 @@ log_in(user) navigate_to_brouillon(dossier) - fill_in 'Libelle du champ', with: 'Some edited value' + fill_in 'Texte obligatoire', with: 'Some edited value' send_invite_to "user_invite@exemple.fr" expect(page).to have_current_path(brouillon_dossier_path(dossier)) @@ -21,7 +21,7 @@ expect(page).to have_text("user_invite@exemple.fr") # Ensure unsaved edits to the form are not lost - expect(page).to have_field('Libelle du champ', with: 'Some edited value') + expect(page).to have_field('Texte obligatoire', with: 'Some edited value') end context 'when inviting someone without an existing account' do @@ -58,10 +58,10 @@ expect(page).to have_current_path(brouillon_dossier_path(dossier)) expect(page).to have_no_selector('.button.invite-user-action') - fill_in 'Libelle du champ', with: 'Some edited value' + fill_in 'Texte obligatoire', with: 'Some edited value' click_button 'Enregistrer le brouillon' expect(page).to have_text('Votre brouillon a bien été sauvegardé') - expect(page).to have_field('Libelle du champ', with: 'Some edited value') + expect(page).to have_field('Texte obligatoire', with: 'Some edited value') end scenario 'an invited user cannot submit the draft' do @@ -105,7 +105,7 @@ visit brouillon_dossier_path(dossier) expect(page).to have_current_path(brouillon_dossier_path(dossier)) - fill_in "Libelle du champ", with: "Some edited value" + fill_in "Texte obligatoire", with: "Some edited value" click_button "Enregistrer les modifications du dossier" expect(page).to have_current_path(users_dossiers_invite_path(invite)) From c534a9a7926744fd491e9d674e052d905984074a Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 24 Sep 2018 14:25:34 +0000 Subject: [PATCH 07/16] dossier spec: extract the dossier edition behaviors to a shared spec This will allow to test behavior for invited users. --- .../features/new_user/dossier_details_spec.rb | 39 ++---------------- .../new_user/dossier_shared_examples.rb | 41 +++++++++++++++++++ 2 files changed, 45 insertions(+), 35 deletions(-) create mode 100644 spec/features/new_user/dossier_shared_examples.rb diff --git a/spec/features/new_user/dossier_details_spec.rb b/spec/features/new_user/dossier_details_spec.rb index 5ac0f53a158..61218f8be89 100644 --- a/spec/features/new_user/dossier_details_spec.rb +++ b/spec/features/new_user/dossier_details_spec.rb @@ -1,3 +1,5 @@ +require 'features/new_user/dossier_shared_examples.rb' + describe 'Dossier details:' do let(:user) { create(:user) } let(:procedure) { create(:simple_procedure) } @@ -37,41 +39,8 @@ end end - scenario 'the user can see and edit dossier before instruction' do - visit_dossier dossier - click_on 'Demande' - - expect(page).to have_current_path(demande_dossier_path(dossier)) - click_on 'Modifier le dossier' - - expect(page).to have_current_path(modifier_dossier_path(dossier)) - fill_in('texte obligatoire', with: 'Nouveau texte') - click_on 'Enregistrer les modifications du dossier' - - expect(page).to have_current_path(demande_dossier_path(dossier)) - expect(page).to have_content('Nouveau texte') - end - - context 'with messages' do - let!(:commentaire) { create(:commentaire, dossier: dossier, email: 'instructeur@exemple.fr', body: 'Message envoyé à l’usager') } - let(:message_body) { 'Message envoyé à l’instructeur' } - - scenario 'the user can send a message' do - visit_dossier dossier - click_on 'Messagerie' - - expect(page).to have_current_path(messagerie_dossier_path(dossier)) - expect(page).to have_content(commentaire.body) - - fill_in 'commentaire_body', with: message_body - click_on 'Envoyer' - - expect(page).to have_current_path(messagerie_dossier_path(dossier)) - expect(page).to have_content('Message envoyé') - expect(page).to have_content(commentaire.body) - expect(page).to have_content(message_body) - end - end + it_behaves_like 'the user can edit the submitted demande' + it_behaves_like 'the user can send messages to the instructeur' private diff --git a/spec/features/new_user/dossier_shared_examples.rb b/spec/features/new_user/dossier_shared_examples.rb new file mode 100644 index 00000000000..7ff2b8c4ece --- /dev/null +++ b/spec/features/new_user/dossier_shared_examples.rb @@ -0,0 +1,41 @@ +RSpec.shared_examples 'the user can edit the submitted demande' do + scenario js: true do + visit dossier_path(dossier) + + expect(page).to have_current_path(dossier_path(dossier)) + click_on 'Demande' + + expect(page).to have_current_path(demande_dossier_path(dossier)) + click_on 'Modifier le dossier' + + expect(page).to have_current_path(modifier_dossier_path(dossier)) + fill_in('Texte obligatoire', with: 'Nouveau texte') + click_on 'Enregistrer les modifications du dossier' + + expect(page).to have_current_path(demande_dossier_path(dossier)) + expect(page).to have_content('Nouveau texte') + end +end + +RSpec.shared_examples 'the user can send messages to the instructeur' do + let!(:commentaire) { create(:commentaire, dossier: dossier, email: 'instructeur@exemple.fr', body: 'Message envoyé à l’usager') } + let(:message_body) { 'Message envoyé à l’instructeur' } + + scenario js: true do + visit dossier_path(dossier) + + expect(page).to have_current_path(dossier_path(dossier)) + click_on 'Messagerie' + + expect(page).to have_current_path(messagerie_dossier_path(dossier)) + expect(page).to have_content(commentaire.body) + + fill_in 'commentaire_body', with: message_body + click_on 'Envoyer' + + expect(page).to have_current_path(messagerie_dossier_path(dossier)) + expect(page).to have_content('Message envoyé') + expect(page).to have_content(commentaire.body) + expect(page).to have_content(message_body) + end +end From fe4921bf8ec9d3db53a7730beff5573d552fce5f Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 24 Sep 2018 16:01:59 +0200 Subject: [PATCH 08/16] dossier spec: deprecate the old UI tests --- spec/features/new_user/invite_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/new_user/invite_spec.rb b/spec/features/new_user/invite_spec.rb index fd1950f692b..7798e1d50c6 100644 --- a/spec/features/new_user/invite_spec.rb +++ b/spec/features/new_user/invite_spec.rb @@ -76,7 +76,7 @@ end end - context 'when the dossier is en_construction' do + context 'when the dossier is en_construction (legacy UI)' do let!(:dossier) { create(:dossier, :for_individual, :en_construction, user: user, procedure: procedure) } scenario 'on dossier details, a user can invite another user to collaborate on the dossier', js: true do From 1c7ad4d37bea702d5d71d3c95f3caf66c3291d38 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 24 Sep 2018 14:10:50 +0000 Subject: [PATCH 09/16] dossier spec: rename `user` to `owner` This makes the distinction between the invited user and the owner clearer. --- spec/features/new_user/invite_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/features/new_user/invite_spec.rb b/spec/features/new_user/invite_spec.rb index 7798e1d50c6..ea803078b72 100644 --- a/spec/features/new_user/invite_spec.rb +++ b/spec/features/new_user/invite_spec.rb @@ -1,16 +1,16 @@ require 'spec_helper' feature 'Invitations' do - let(:user) { create(:user) } + let(:owner) { create(:user) } let(:invited_user) { create(:user, email: 'user_invite@exemple.fr') } let(:procedure) { create(:simple_procedure) } let(:invite) { create(:invite_user, user: invited_user, dossier: dossier) } context 'when the dossier is a brouillon' do - let!(:dossier) { create(:dossier, :for_individual, state: Dossier.states.fetch(:brouillon), user: user, procedure: procedure) } + let!(:dossier) { create(:dossier, :for_individual, state: Dossier.states.fetch(:brouillon), user: owner, procedure: procedure) } - scenario 'on the form, a user can invite another user to collaborate on the dossier', js: true do - log_in(user) + scenario 'on the form, the owner of a dossier can invite another user to collaborate on the dossier', js: true do + log_in(owner) navigate_to_brouillon(dossier) fill_in 'Texte obligatoire', with: 'Some edited value' @@ -77,10 +77,10 @@ end context 'when the dossier is en_construction (legacy UI)' do - let!(:dossier) { create(:dossier, :for_individual, :en_construction, user: user, procedure: procedure) } + let!(:dossier) { create(:dossier, :for_individual, :en_construction, user: owner, procedure: procedure) } scenario 'on dossier details, a user can invite another user to collaborate on the dossier', js: true do - log_in(user) + log_in(owner) navigate_to_recapitulatif(dossier) legacy_send_invite_to "user_invite@exemple.fr" From 12ee9ba3ce00f6d69367af4a6798d53be4a6a691 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 24 Sep 2018 16:22:37 +0200 Subject: [PATCH 10/16] dossier spec: add `navigate_to_invited_dossier` helper --- spec/features/new_user/invite_spec.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/spec/features/new_user/invite_spec.rb b/spec/features/new_user/invite_spec.rb index ea803078b72..b2c77565c25 100644 --- a/spec/features/new_user/invite_spec.rb +++ b/spec/features/new_user/invite_spec.rb @@ -51,11 +51,9 @@ end scenario 'an invited user can see and edit the draft', js: true do - visit users_dossiers_invite_path(invite) - expect(page).to have_current_path(new_user_session_path) - - submit_login_form(invited_user.email, invited_user.password) + navigate_to_invited_dossier(invite) expect(page).to have_current_path(brouillon_dossier_path(dossier)) + expect(page).to have_no_selector('.button.invite-user-action') fill_in 'Texte obligatoire', with: 'Some edited value' @@ -65,10 +63,7 @@ end scenario 'an invited user cannot submit the draft' do - visit users_dossiers_invite_path(invite) - expect(page).to have_current_path(new_user_session_path) - - submit_login_form(invited_user.email, invited_user.password) + navigate_to_invited_dossier(invite) expect(page).to have_current_path(brouillon_dossier_path(dossier)) expect(page).to have_button('Soumettre le dossier', disabled: true) @@ -134,6 +129,12 @@ def navigate_to_brouillon(dossier) expect(page).to have_current_path(brouillon_dossier_path(dossier)) end + def navigate_to_invited_dossier(invite) + visit users_dossiers_invite_path(invite) + expect(page).to have_current_path(new_user_session_path) + submit_login_form(invited_user.email, invited_user.password) + end + def navigate_to_recapitulatif(dossier) expect(page).to have_current_path(dossiers_path) click_on(dossier.id) From 8a3f455aa3c5502933dbc42256535cbd3bf53606 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Mon, 24 Sep 2018 16:23:53 +0200 Subject: [PATCH 11/16] dossier spec: test invitation behavior with the new dossier UI --- spec/features/new_user/invite_spec.rb | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/spec/features/new_user/invite_spec.rb b/spec/features/new_user/invite_spec.rb index b2c77565c25..5eb7143b72c 100644 --- a/spec/features/new_user/invite_spec.rb +++ b/spec/features/new_user/invite_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' +require 'features/new_user/dossier_shared_examples.rb' feature 'Invitations' do let(:owner) { create(:user) } @@ -71,6 +72,35 @@ end end + context 'when the dossier is en_construction' do + let!(:dossier) { create(:dossier, :for_individual, :en_construction, user: owner, procedure: procedure) } + + before do + Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, true) + end + + scenario 'on dossier details, the owner of a dossier can invite another user to collaborate on the dossier', js: true do + log_in(owner) + navigate_to_dossier(dossier) + + send_invite_to "user_invite@exemple.fr" + + expect(page).to have_current_path(dossier_path(dossier)) + expect(page).to have_text("Une invitation a été envoyée à user_invite@exemple.fr.") + expect(page).to have_text("user_invite@exemple.fr") + end + + context 'as an invited user' do + before do + navigate_to_invited_dossier(invite) + expect(page).to have_current_path(dossier_path(invite.dossier)) + end + + it_behaves_like 'the user can edit the submitted demande' + it_behaves_like 'the user can send messages to the instructeur' + end + end + context 'when the dossier is en_construction (legacy UI)' do let!(:dossier) { create(:dossier, :for_individual, :en_construction, user: owner, procedure: procedure) } @@ -129,6 +159,12 @@ def navigate_to_brouillon(dossier) expect(page).to have_current_path(brouillon_dossier_path(dossier)) end + def navigate_to_dossier(dossier) + expect(page).to have_current_path(dossiers_path) + click_on(dossier.id) + expect(page).to have_current_path(dossier_path(dossier)) + end + def navigate_to_invited_dossier(invite) visit users_dossiers_invite_path(invite) expect(page).to have_current_path(new_user_session_path) From c92b0b163c94e3e51a608dfb177a217f799c5ef6 Mon Sep 17 00:00:00 2001 From: gregoirenovel Date: Tue, 25 Sep 2018 09:48:32 +0200 Subject: [PATCH 12/16] Add a banner about the Tour de France on the administration landing page --- app/assets/stylesheets/new_design/landing.scss | 13 +++++++++++++ app/views/root/administration.html.haml | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/app/assets/stylesheets/new_design/landing.scss b/app/assets/stylesheets/new_design/landing.scss index 3b9f35a0d9a..bf02238f040 100644 --- a/app/assets/stylesheets/new_design/landing.scss +++ b/app/assets/stylesheets/new_design/landing.scss @@ -424,3 +424,16 @@ $cta-panel-button-border-size: 2px; text-decoration: none; } } + +.tour-de-france-banner { + padding-top: 15px; + padding-bottom: 15px; + background-color: $blue; + color: #FFFFFF; + text-align: center; + + a { + color: #FFFFFF; + text-decoration: underline; + } +} diff --git a/app/views/root/administration.html.haml b/app/views/root/administration.html.haml index bae00f1017b..238015f70b2 100644 --- a/app/views/root/administration.html.haml +++ b/app/views/root/administration.html.haml @@ -1,6 +1,12 @@ - content_for :footer do = render partial: "root/footer" +.tour-de-france-banner + .container + L'équipe demarches-simplifiees.fr vient à votre rencontre cet automne. + = succeed '.' do + = link_to "En savoir plus", tour_de_france_path + .landing .landing-panel.hero-panel .container From 904f75a963f5108bd87e9eb786776d03b82be3dd Mon Sep 17 00:00:00 2001 From: gregoirenovel Date: Mon, 24 Sep 2018 09:44:24 +0200 Subject: [PATCH 13/16] [Fix #1722] Drop the entreprises table --- db/migrate/20180924074121_drop_entreprises.rb | 5 +++++ db/schema.rb | 21 +------------------ 2 files changed, 6 insertions(+), 20 deletions(-) create mode 100644 db/migrate/20180924074121_drop_entreprises.rb diff --git a/db/migrate/20180924074121_drop_entreprises.rb b/db/migrate/20180924074121_drop_entreprises.rb new file mode 100644 index 00000000000..d15bb323ba6 --- /dev/null +++ b/db/migrate/20180924074121_drop_entreprises.rb @@ -0,0 +1,5 @@ +class DropEntreprises < ActiveRecord::Migration[5.2] + def change + drop_table :entreprises + end +end diff --git a/db/schema.rb b/db/schema.rb index c4326d89f23..71b130a6421 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_09_19_084403) do +ActiveRecord::Schema.define(version: 2018_09_24_074121) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -251,25 +251,6 @@ t.index ["type_de_champ_id"], name: "index_drop_down_lists_on_type_de_champ_id" end - create_table "entreprises", id: :serial, force: :cascade do |t| - t.string "siren" - t.bigint "capital_social" - t.string "numero_tva_intracommunautaire" - t.string "forme_juridique" - t.string "forme_juridique_code" - t.string "nom_commercial" - t.string "raison_sociale" - t.string "siret_siege_social" - t.string "code_effectif_entreprise" - t.datetime "date_creation" - t.string "nom" - t.string "prenom" - t.integer "dossier_id" - t.datetime "created_at" - t.datetime "updated_at" - t.index ["dossier_id"], name: "index_entreprises_on_dossier_id" - end - create_table "etablissements", id: :serial, force: :cascade do |t| t.string "siret" t.boolean "siege_social" From 3681cead8126c2313b5abb706b6d83154f78913c Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 25 Sep 2018 08:22:47 +0200 Subject: [PATCH 14/16] =?UTF-8?q?Fix=20cosm=C3=A9tique?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/tasks/2018_09_20_procedure_presentation_entreprise.rake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tasks/2018_09_20_procedure_presentation_entreprise.rake b/lib/tasks/2018_09_20_procedure_presentation_entreprise.rake index ca2dd15c06a..811d9fc49d0 100644 --- a/lib/tasks/2018_09_20_procedure_presentation_entreprise.rake +++ b/lib/tasks/2018_09_20_procedure_presentation_entreprise.rake @@ -27,8 +27,8 @@ namespace :'2018_09_20_procedure_presentation_entreprise' do ProcedurePresentation.find_by_sql( <<~SQL SELECT procedure_presentations.*, array_agg(key) as keys - FROM procedure_presentations, LATERAL jsonb_each_text(filters) - WHERE value::jsonb @> '[{"table": "entreprise"}]' + FROM procedure_presentations, LATERAL jsonb_each(filters) + WHERE value @> '[{"table": "entreprise"}]' GROUP BY id; SQL ).each do |procedure_presentation| From 7631bde16a08c2916b26ff7cb7eeedf6ef422706 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 25 Sep 2018 15:53:57 +0200 Subject: [PATCH 15/16] [#2550] Generate attestation on auto-accepted dossier --- ...auto_receive_dossiers_for_procedure_job.rb | 22 ++++++++++--------- ...receive_dossiers_for_procedure_job_spec.rb | 3 +++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/app/jobs/auto_receive_dossiers_for_procedure_job.rb b/app/jobs/auto_receive_dossiers_for_procedure_job.rb index d5d3ac22b0d..330fd90e5a1 100644 --- a/app/jobs/auto_receive_dossiers_for_procedure_job.rb +++ b/app/jobs/auto_receive_dossiers_for_procedure_job.rb @@ -3,22 +3,24 @@ class AutoReceiveDossiersForProcedureJob < ApplicationJob def perform(procedure_id, state) procedure = Procedure.find(procedure_id) - attrs = case state + case state when Dossier.states.fetch(:en_instruction) - { + procedure.dossiers.state_en_construction.update_all( state: Dossier.states.fetch(:en_instruction), en_instruction_at: DateTime.now - } + ) when Dossier.states.fetch(:accepte) - { - state: Dossier.states.fetch(:accepte), - en_instruction_at: DateTime.now, - processed_at: DateTime.now - } + procedure.dossiers.state_en_construction.find_each do |dossier| + dossier.update( + state: Dossier.states.fetch(:accepte), + en_instruction_at: DateTime.now, + processed_at: DateTime.now + ) + dossier.attestation = dossier.build_attestation + dossier.save + end else raise "Receiving Procedure##{procedure_id} in invalid state \"#{state}\"" end - - procedure.dossiers.state_en_construction.update_all(attrs) end end diff --git a/spec/jobs/auto_receive_dossiers_for_procedure_job_spec.rb b/spec/jobs/auto_receive_dossiers_for_procedure_job_spec.rb index e7fa7b6f41f..fa22ab6b5c0 100644 --- a/spec/jobs/auto_receive_dossiers_for_procedure_job_spec.rb +++ b/spec/jobs/auto_receive_dossiers_for_procedure_job_spec.rb @@ -7,6 +7,7 @@ before do Timecop.freeze(date) + create(:attestation_template, procedure: nouveau_dossier1.procedure) AutoReceiveDossiersForProcedureJob.new.perform(procedure_id, state) end @@ -41,10 +42,12 @@ it { expect(nouveau_dossier1.reload.accepte?).to be true } it { expect(nouveau_dossier1.reload.en_instruction_at).to eq(date) } it { expect(nouveau_dossier1.reload.processed_at).to eq(date) } + it { expect(nouveau_dossier1.reload.attestation).to be_present } it { expect(nouveau_dossier2.reload.accepte?).to be true } it { expect(nouveau_dossier2.reload.en_instruction_at).to eq(date) } it { expect(nouveau_dossier2.reload.processed_at).to eq(date) } + it { expect(nouveau_dossier2.reload.attestation).to be_present } it { expect(dossier_recu.reload.en_instruction?).to be true } it { expect(dossier_recu.reload.en_instruction_at).to eq(instruction_date) } From 40bc6208f06a24166d4f2840633fee946f34162b Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 25 Sep 2018 15:57:07 +0200 Subject: [PATCH 16/16] [Fix #2550] Also send mail notification when accepting dossier --- app/jobs/auto_receive_dossiers_for_procedure_job.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/jobs/auto_receive_dossiers_for_procedure_job.rb b/app/jobs/auto_receive_dossiers_for_procedure_job.rb index 330fd90e5a1..eff580dddc6 100644 --- a/app/jobs/auto_receive_dossiers_for_procedure_job.rb +++ b/app/jobs/auto_receive_dossiers_for_procedure_job.rb @@ -18,6 +18,7 @@ def perform(procedure_id, state) ) dossier.attestation = dossier.build_attestation dossier.save + NotificationMailer.send_closed_notification(dossier).deliver_later end else raise "Receiving Procedure##{procedure_id} in invalid state \"#{state}\""