diff --git a/app/helpers/type_de_champ_helper.rb b/app/helpers/type_de_champ_helper.rb index f569382dd..d102ac3b6 100644 --- a/app/helpers/type_de_champ_helper.rb +++ b/app/helpers/type_de_champ_helper.rb @@ -2,7 +2,8 @@ module TypeDeChampHelper TOGGLES = { TypeDeChamp.type_champs.fetch(:piece_justificative) => :champ_pj?, TypeDeChamp.type_champs.fetch(:siret) => :champ_siret?, - TypeDeChamp.type_champs.fetch(:linked_drop_down_list) => :champ_linked_dropdown? + TypeDeChamp.type_champs.fetch(:linked_drop_down_list) => :champ_linked_dropdown?, + TypeDeChamp.type_champs.fetch(:carte) => :champ_carte? } def tdc_options diff --git a/app/mailers/dossier_mailer.rb b/app/mailers/dossier_mailer.rb index 03147e8b9..65d7e68e6 100644 --- a/app/mailers/dossier_mailer.rb +++ b/app/mailers/dossier_mailer.rb @@ -21,4 +21,21 @@ class DossierMailer < ApplicationMailer mail(to: dossier.user.email, subject: subject) end + + def notify_undelete_to_user(dossier) + @dossier = dossier + @dossier_kind = dossier.brouillon? ? 'brouillon' : 'dossier' + @subject = "Votre #{@dossier_kind} n° #{@dossier.id} est à nouveau accessible" + + mail(to: dossier.user.email, subject: @subject) + end + + def notify_unmigrated_to_user(dossier, new_procedure) + @dossier = dossier + @dossier_kind = dossier.brouillon? ? 'brouillon' : 'dossier' + @subject = "Changement de procédure pour votre #{@dossier_kind} n° #{@dossier.id}" + @new_procedure = new_procedure + + mail(to: dossier.user.email, subject: @subject) + end end diff --git a/app/models/champs/carte_champ.rb b/app/models/champs/carte_champ.rb new file mode 100644 index 000000000..8928501e6 --- /dev/null +++ b/app/models/champs/carte_champ.rb @@ -0,0 +1,29 @@ +class Champs::CarteChamp < Champ + has_many :geo_areas, dependent: :destroy + + # We are not using scopes here as we want to access + # the following collections on unsaved records. + def cadastres + geo_areas.select do |area| + area.source == GeoArea.sources.fetch(:cadastre) + end + end + + def quartiers_prioritaires + geo_areas.select do |area| + area.source == GeoArea.sources.fetch(:quartier_prioritaire) + end + end + + def position + if dossier.present? + dossier.geo_position + else + lon = "2.428462" + lat = "46.538192" + zoom = "13" + + { lon: lon, lat: lat, zoom: zoom } + end + end +end diff --git a/app/models/geo_area.rb b/app/models/geo_area.rb new file mode 100644 index 000000000..92de3100b --- /dev/null +++ b/app/models/geo_area.rb @@ -0,0 +1,26 @@ +class GeoArea < ApplicationRecord + belongs_to :champ + + store :properties, accessors: [ + :surface_intersection, + :surface_parcelle, + :numero, + :feuille, + :section, + :code_dep, + :nom_com, + :code_com, + :code_arr, + :code, + :nom, + :commune + ] + + enum source: { + quartier_prioritaire: 'quartier_prioritaire', + cadastre: 'cadastre' + } + + scope :quartiers_prioritaires, -> { where(source: sources.fetch(:quartier_prioritaire)) } + scope :cadastres, -> { where(source: sources.fetch(:cadastre)) } +end diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 33cfd914a..59e154075 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -25,11 +25,14 @@ class TypeDeChamp < ApplicationRecord explication: 'explication', dossier_link: 'dossier_link', piece_justificative: 'piece_justificative', - siret: 'siret' + siret: 'siret', + carte: 'carte' } belongs_to :procedure + store :options, accessors: [:cadastres, :quartiers_prioritaires] + after_initialize :set_dynamic_type attr_reader :dynamic_type diff --git a/app/models/types_de_champ/carte_type_de_champ.rb b/app/models/types_de_champ/carte_type_de_champ.rb new file mode 100644 index 000000000..193db82d2 --- /dev/null +++ b/app/models/types_de_champ/carte_type_de_champ.rb @@ -0,0 +1,2 @@ +class TypesDeChamp::CarteTypeDeChamp < TypesDeChamp::TypeDeChampBase +end diff --git a/app/views/dossier_mailer/notify_undelete_to_user.html.haml b/app/views/dossier_mailer/notify_undelete_to_user.html.haml new file mode 100644 index 000000000..e61846dda --- /dev/null +++ b/app/views/dossier_mailer/notify_undelete_to_user.html.haml @@ -0,0 +1,15 @@ +- content_for(:title, @subject) + +%h1 Bonjour, + +%p + En raison d’un incident, votre + = link_to("#{@dossier_kind} n° #{@dossier.id}", dossier_url(@dossier)) + sur la procédure « #{@dossier.procedure.libelle} » a été inaccessible pendant quelques jours. + + L’accès est à présent à nouveau possible. Nous vous présentons nos excuses pour toute gène occasionnée. +%p + Bonne journée, + +%p + L'équipe demarches-simplifiees.fr diff --git a/app/views/dossier_mailer/notify_unmigrated_to_user.html.haml b/app/views/dossier_mailer/notify_unmigrated_to_user.html.haml new file mode 100644 index 000000000..0bf06540c --- /dev/null +++ b/app/views/dossier_mailer/notify_unmigrated_to_user.html.haml @@ -0,0 +1,26 @@ +- content_for(:title, @subject) + +%h1 Bonjour, + +%p + Vous avez commencé un #{@dossier_kind}, + = link_to("n° #{@dossier.id}", dossier_url(@dossier)) + sur la procédure « #{@dossier.procedure.libelle} ». + En raison d’un changement dans la procédure, votre #{@dossier_kind} a été inaccessible pendant quelques jours. + L’accès est à présent à nouveau possible. + +%p + Malheureusement, en raison des changements dans le procédure, vous ne pourrez pas mener à terme le #{@dossier_kind} commencé. + Si votre démarche est toujours d’actualité, nous vous invitons à la recommencer sur + = link_to("la nouvelle procédure", commencer_url(@new_procedure.path)) + \. + +%p + Nous avons pris des mesures pour nous assurer qu’un tel désagrément ne se reproduise pas, + et vous présentons nos excuses pour la gène occasionnée. + +%p + Bonne journée, + +%p + L'équipe demarches-simplifiees.fr diff --git a/config/features.rb b/config/features.rb index fcc8384c7..1158926e2 100644 --- a/config/features.rb +++ b/config/features.rb @@ -13,6 +13,8 @@ Flipflop.configure do title: "Champ SIRET" feature :champ_linked_dropdown, title: "Champ double menu déroulant" + feature :champ_carte, + title: "Champ Carte" end feature :web_hook diff --git a/db/migrate/20181010183331_create_geo_areas.rb b/db/migrate/20181010183331_create_geo_areas.rb new file mode 100644 index 000000000..b634e5c67 --- /dev/null +++ b/db/migrate/20181010183331_create_geo_areas.rb @@ -0,0 +1,14 @@ +class CreateGeoAreas < ActiveRecord::Migration[5.2] + def change + create_table :geo_areas do |t| + t.string :source, index: true + + t.jsonb :geometry + t.jsonb :properties + + t.references :champ, foreign_key: true, index: true + end + + add_column :types_de_champ, :options, :jsonb + end +end diff --git a/db/schema.rb b/db/schema.rb index bc277e782..d74aeec41 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_10_10_070424) do +ActiveRecord::Schema.define(version: 2018_10_10_183331) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -342,6 +342,15 @@ ActiveRecord::Schema.define(version: 2018_10_10_070424) do t.index ["user_id"], name: "index_france_connect_informations_on_user_id" end + create_table "geo_areas", force: :cascade do |t| + t.string "source" + t.jsonb "geometry" + t.jsonb "properties" + t.bigint "champ_id" + t.index ["champ_id"], name: "index_geo_areas_on_champ_id" + t.index ["source"], name: "index_geo_areas_on_source" + end + create_table "gestionnaires", id: :serial, force: :cascade do |t| t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false @@ -544,6 +553,7 @@ ActiveRecord::Schema.define(version: 2018_10_10_070424) do t.boolean "private", default: false, null: false t.datetime "created_at" t.datetime "updated_at" + t.jsonb "options" t.index ["private"], name: "index_types_de_champ_on_private" end @@ -608,6 +618,7 @@ ActiveRecord::Schema.define(version: 2018_10_10_070424) do add_foreign_key "commentaires", "dossiers" add_foreign_key "dossiers", "users" add_foreign_key "feedbacks", "users" + add_foreign_key "geo_areas", "champs" add_foreign_key "initiated_mails", "procedures" add_foreign_key "procedure_paths", "administrateurs" add_foreign_key "procedure_paths", "procedures" diff --git a/lib/tasks/2018_07_31_nutriscore.rake b/lib/tasks/2018_07_31_nutriscore.rake index 0f4b86793..76cb7dc47 100644 --- a/lib/tasks/2018_07_31_nutriscore.rake +++ b/lib/tasks/2018_07_31_nutriscore.rake @@ -9,12 +9,7 @@ namespace :'2018_07_31_nutriscore' do destination_procedure = Procedure.find(destination_procedure_id) mapping = Class.new(Tasks::DossierProcedureMigrator::ChampMapping) do - def initialize(source_procedure, destination_procedure) - super - setup_champ_mapping - end - - def setup_champ_mapping + def setup_mapping siret_order_place = 2 fonction_order_place = 9 zone_geographique_header_order_place = 18 @@ -100,7 +95,7 @@ namespace :'2018_07_31_nutriscore' do target_tdc.champ.create(dossier: d, value: JSON.unparse(['FRANCE'])) end end - end.new(source_procedure, destination_procedure) + end Tasks::DossierProcedureMigrator.new(source_procedure, destination_procedure, mapping).migrate_procedure AutoReceiveDossiersForProcedureJob.set(cron: "* * * * *").perform_later(destination_procedure_id, 'accepte') diff --git a/lib/tasks/deployment/20181009130216_restore_deleted_dossiers.rake b/lib/tasks/deployment/20181009130216_restore_deleted_dossiers.rake new file mode 100644 index 000000000..387d5cf99 --- /dev/null +++ b/lib/tasks/deployment/20181009130216_restore_deleted_dossiers.rake @@ -0,0 +1,209 @@ +require Rails.root.join("lib", "tasks", "task_helper") + +namespace :after_party do + desc 'Deployment task: restore_deleted_dossiers' + task restore_deleted_dossiers: :environment do + Class.new do + def run + rake_puts "Running deploy task 'restore_deleted_dossiers'" + restore_candidats_libres_deleted_dossiers + restore_neph_deleted_dossiers + AfterParty::TaskRecord.create version: '20181009130216' + end + + def restore_candidats_libres_deleted_dossiers + mapping = Class.new(Tasks::DossierProcedureMigrator::ChampMapping) do + def setup_mapping + champ_opts = { + 16 => { + source_overrides: { 'libelle' => 'Adresse postale du candidat' }, + destination_overrides: { 'libelle' => 'Adresse postale complète du candidat' } + } + } + (0..23).each do |i| + map_source_to_destination_champ(i, i, **(champ_opts[i] || {})) + end + end + end + + private_mapping = Class.new(Tasks::DossierProcedureMigrator::ChampMapping) do + def setup_mapping + compute_destination_champ( + TypeDeChamp.new( + type_champ: 'datetime', + order_place: 0, + libelle: 'Date et heure de convocation', + mandatory: false + ) + ) do |d, target_tdc| + target_tdc.champ.create(dossier: d) + end + compute_destination_champ( + TypeDeChamp.new( + type_champ: 'text', + order_place: 1, + libelle: 'Lieu de convocation', + mandatory: false + ) + ) do |d, target_tdc| + target_tdc.champ.create(dossier: d) + end + compute_destination_champ( + TypeDeChamp.new( + type_champ: 'address', + order_place: 2, + libelle: 'Adresse centre examen', + mandatory: false + ) + ) do |d, target_tdc| + target_tdc.champ.create(dossier: d) + end + end + end + + pj_mapping = Class.new(Tasks::DossierProcedureMigrator::PieceJustificativeMapping) do + def setup_mapping + (0..3).each do |i| + map_source_to_destination_pj(i, i + 2) + end + leave_destination_pj_blank( + TypeDePieceJustificative.new( + order_place: 0, + libelle: "Télécharger la Charte de l'accompagnateur" + ) + ) + leave_destination_pj_blank( + TypeDePieceJustificative.new( + order_place: 1, + libelle: "Télécharger l'attestation d'assurance" + ) + ) + end + end + + restore_deleted_dossiers(4860, 8603, mapping, private_mapping, pj_mapping) + end + + def restore_neph_deleted_dossiers + mapping = Class.new(Tasks::DossierProcedureMigrator::ChampMapping) do + def can_migrate?(dossier) + !(dossier.termine? || + dossier.champs.joins(:type_de_champ).find_by(types_de_champ: { order_place: 3 }).value&.include?('"Demande de duplicata de dossier d\'inscription (suite perte)"')) + end + + def setup_mapping + champ_opts = { + 3 => { + source_overrides: { 'drop_down' => ["", "Demande de réactualisation du numéro NEPH", "Demande de communication du numéro NEPH", "Demande de duplicata de dossier d'inscription (suite perte)", "Demande de correction sur le Fichier National des Permis de conduire"] }, + destination_overrides: { 'drop_down' => ["", "Demande de réactualisation du numéro NEPH", "Demande de communication du numéro NEPH", "Demande de correction sur le Fichier National des Permis de conduire"] } + } + } + (0..14).each do |i| + map_source_to_destination_champ(i, i, **(champ_opts[i] || {})) + end + (16..22).each do |i| + map_source_to_destination_champ(i, i + 2, **(champ_opts[i] || {})) + end + + discard_source_champ( + TypeDeChamp.new( + type_champ: 'address', + order_place: 15, + libelle: 'Adresse du candidat' + ) + ) + + compute_destination_champ( + TypeDeChamp.new( + type_champ: 'address', + order_place: 15, + libelle: 'Adresse du candidat', + mandatory: true + ) + ) do |d, target_tdc| + value = d.champs.joins(:type_de_champ).find_by(types_de_champ: { order_place: 3 }).value + if !d.brouillon? + value ||= 'non renseigné' + end + target_tdc.champ.create(dossier: d, value: value) + end + + compute_destination_champ( + TypeDeChamp.new( + type_champ: 'address', + order_place: 16, + libelle: 'Code postal', + mandatory: true + ) + ) do |d, target_tdc| + target_tdc.champ.create(dossier: d, value: d.brouillon? ? nil : 'non renseigné') + end + + compute_destination_champ( + TypeDeChamp.new( + type_champ: 'address', + order_place: 17, + libelle: 'Ville', + mandatory: true + ) + ) do |d, target_tdc| + target_tdc.champ.create(dossier: d, value: d.brouillon? ? nil : 'non renseigné') + end + end + end + + private_mapping = Class.new(Tasks::DossierProcedureMigrator::ChampMapping) do + def setup_mapping + (0..2).each do |i| + map_source_to_destination_champ(i, i) + end + end + end + + pj_mapping = Class.new(Tasks::DossierProcedureMigrator::PieceJustificativeMapping) do + def setup_mapping + (0..3).each do |i| + map_source_to_destination_pj(i, i) + end + end + end + + restore_deleted_dossiers(6388, 8770, mapping, private_mapping, pj_mapping) + end + + def restore_deleted_dossiers(deleted_procedure_id, new_procedure_id, champ_mapping, champ_private_mapping, pj_mapping) + source_procedure = Procedure.unscoped.find(deleted_procedure_id) + destination_procedure = Procedure.find(new_procedure_id) + + deleted_dossiers = Dossier.unscoped + .where(procedure_id: deleted_procedure_id) + .where('dossiers.hidden_at >= ?', source_procedure.hidden_at) + + deleted_dossier_ids = deleted_dossiers.pluck(:id).to_a + deleted_dossiers.update_all(hidden_at: nil) + + source_procedure + .update_columns( + hidden_at: nil, + archived_at: source_procedure.hidden_at, + aasm_state: :archivee + ) + + migrator = Tasks::DossierProcedureMigrator.new(source_procedure, destination_procedure, champ_mapping, champ_private_mapping, pj_mapping) do |dossier| + DossierMailer.notify_undelete_to_user(dossier).deliver_later + end + migrator.check_consistency + migrator.migrate_dossiers + + source_procedure.dossiers.where(id: deleted_dossier_ids).find_each do |dossier| + if dossier.termine? + DossierMailer.notify_undelete_to_user(dossier).deliver_later + else + rake_puts "Dossier #{dossier.id} non migré\n" + DossierMailer.notify_unmigrated_to_user(dossier, destination_procedure).deliver_later + end + end + end + end.new.run + end +end diff --git a/lib/tasks/dossier_procedure_migrator.rb b/lib/tasks/dossier_procedure_migrator.rb index ae4d77c12..0d5a57073 100644 --- a/lib/tasks/dossier_procedure_migrator.rb +++ b/lib/tasks/dossier_procedure_migrator.rb @@ -3,18 +3,54 @@ module Tasks # Migrates dossiers from an old source procedure to a revised destination procedure. class ChampMapping - attr_reader :expected_source_types_de_champ - attr_reader :expected_destination_types_de_champ - - def initialize(source_procedure, destination_procedure) + def initialize(source_procedure, destination_procedure, is_private) @source_procedure = source_procedure @destination_procedure = destination_procedure + @is_private = is_private @expected_source_types_de_champ = {} @expected_destination_types_de_champ = {} @source_to_destination_mapping = {} @source_champs_to_discard = Set[] @destination_champ_computations = [] + + setup_mapping + end + + def check_source_destination_consistency + check_champs_consistency("#{privacy_label}source", @expected_source_types_de_champ, types_de_champ(@source_procedure)) + check_champs_consistency("#{privacy_label}destination", @expected_destination_types_de_champ, types_de_champ(@destination_procedure)) + end + + def can_migrate?(dossier) + true + end + + def migrate(dossier) + # Since we’re going to iterate and change the champs at the same time, + # we use to_a to make the list static and avoid nasty surprises + original_champs = champs(dossier).to_a + + compute_new_champs(dossier) + + original_champs.each do |c| + tdc_to = destination_type_de_champ(c) + if tdc_to.present? + c.update_columns(type_de_champ_id: tdc_to.id) + elsif discard_champ?(c) + champs(dossier).destroy(c) + else + fail "Unhandled source #{privacy_label}type de champ #{c.type_de_champ.order_place}" + end + end + end + + private + + def compute_new_champs(dossier) + @destination_champ_computations.each do |tdc, block| + champs(dossier) << block.call(dossier, tdc) + end end def destination_type_de_champ(champ) @@ -25,21 +61,55 @@ module Tasks @source_champs_to_discard.member?(champ.type_de_champ.order_place) end - def compute_new_champs(dossier) - @destination_champ_computations.each do |tdc, block| - dossier.champs << block.call(dossier, tdc) + def setup_mapping + end + + def champs(dossier) + @is_private ? dossier.champs_private : dossier.champs + end + + def types_de_champ(procedure) + @is_private ? procedure.types_de_champ_private : procedure.types_de_champ + end + + def privacy_label + @is_private ? 'private ' : '' + end + + def check_champs_consistency(label, expected_tdcs, actual_tdcs) + if actual_tdcs.size != expected_tdcs.size + raise "Incorrect #{label} size #{actual_tdcs.size} (expected #{expected_tdcs.size})" + end + actual_tdcs.each { |tdc| check_champ_consistency(label, expected_tdcs[tdc.order_place], tdc) } + end + + def check_champ_consistency(label, expected_tdc, actual_tdc) + errors = [] + if actual_tdc.libelle != expected_tdc['libelle'] + errors.append("incorrect libelle #{actual_tdc.libelle} (expected #{expected_tdc['libelle']})") + 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 + if (!actual_tdc.mandatory) && expected_tdc['mandatory'] + errors.append("champ should be mandatory") + end + drop_down = actual_tdc.drop_down_list.presence&.options&.presence + if drop_down != expected_tdc['drop_down'] + errors.append("incorrect drop down list #{drop_down} (expected #{expected_tdc['drop_down']})") + end + if errors.present? + fail "On #{label} type de champ #{actual_tdc.order_place} (#{actual_tdc.libelle}) " + errors.join(', ') end end - private - def map_source_to_destination_champ(source_order_place, destination_order_place, source_overrides: {}, destination_overrides: {}) - destination_type_de_champ = @destination_procedure.types_de_champ.find_by(order_place: destination_order_place) + destination_type_de_champ = types_de_champ(@destination_procedure).find_by(order_place: destination_order_place) @expected_source_types_de_champ[source_order_place] = type_de_champ_to_expectation(destination_type_de_champ) .merge!(source_overrides) @expected_destination_types_de_champ[destination_order_place] = - type_de_champ_to_expectation(@source_procedure.types_de_champ.find_by(order_place: source_order_place)) + type_de_champ_to_expectation(types_de_champ(@source_procedure).find_by(order_place: source_order_place)) .merge!({ "mandatory" => false }) # Even if the source was mandatory, it’s ok for the destination to be optional .merge!(destination_overrides) @source_to_destination_mapping[source_order_place] = destination_type_de_champ @@ -52,7 +122,7 @@ module Tasks def compute_destination_champ(destination_type_de_champ, &block) @expected_destination_types_de_champ[destination_type_de_champ.order_place] = type_de_champ_to_expectation(destination_type_de_champ) - @destination_champ_computations << [@destination_procedure.types_de_champ.find_by(order_place: destination_type_de_champ.order_place), block] + @destination_champ_computations << [types_de_champ(@destination_procedure).find_by(order_place: destination_type_de_champ.order_place), block] end def type_de_champ_to_expectation(tdc) @@ -66,10 +136,113 @@ module Tasks end end - def initialize(source_procedure, destination_procedure, champ_mapping) + class PieceJustificativeMapping + def initialize(source_procedure, destination_procedure) + @source_procedure = source_procedure + @destination_procedure = destination_procedure + + @expected_source_pj = {} + @expected_destination_pj = {} + @source_to_destination_mapping = {} + + setup_mapping + end + + def check_source_destination_consistency + check_pjs_consistency('source', @expected_source_pj, @source_procedure.types_de_piece_justificative) + check_pjs_consistency('destination', @expected_destination_pj, @destination_procedure.types_de_piece_justificative) + end + + def can_migrate?(dossier) + true + end + + def migrate(dossier) + # Since we’re going to iterate and change the pjs at the same time, + # we use to_a to make the list static and avoid nasty surprises + original_pjs = dossier.pieces_justificatives.to_a + + original_pjs.each do |pj| + pj_to = destination_pj(pj) + if pj_to.present? + pj.update_columns(type_de_piece_justificative_id: pj_to.id) + elsif discard_pj?(pj) + dossier.pieces_justificatives.destroy(pj) + else + fail "Unhandled source pièce justificative #{c.type_de_piece_justificative.order_place}" + end + end + end + + private + + def destination_pj(pj) + @source_to_destination_mapping[pj.order_place] + end + + def discard_pj?(champ) + @source_pjs_to_discard.member?(pj.order_place) + end + + def setup_mapping + end + + def map_source_to_destination_pj(source_order_place, destination_order_place, source_overrides: {}, destination_overrides: {}) + destination_pj = @destination_procedure.types_de_piece_justificative.find_by(order_place: destination_order_place) + @expected_source_pj[source_order_place] = + pj_to_expectation(destination_pj) + .merge!(source_overrides) + @expected_destination_pj[destination_order_place] = + pj_to_expectation(@source_procedure.types_de_piece_justificative.find_by(order_place: source_order_place)) + .merge!({ "mandatory" => false }) # Even if the source was mandatory, it’s ok for the destination to be optional + .merge!(destination_overrides) + @source_to_destination_mapping[source_order_place] = destination_pj + end + + def discard_source_pj(source_pj) + @expected_source_pj[source_pj.order_place] = pj_to_expectation(source_pj) + @source_pjs_to_discard << source_pj.order_place + end + + def leave_destination_pj_blank(destination_pj) + @expected_destination_pj[destination_pj.order_place] = pj_to_expectation(destination_pj) + end + + def pj_to_expectation(pj) + pj&.as_json(only: [:libelle, :mandatory]) || {} + end + + def check_pjs_consistency(label, expected_pjs, actual_pjs) + if actual_pjs.size != expected_pjs.size + raise "Incorrect #{label} pièce justificative count #{actual_pjs.size} (expected #{expected_pjs.size})" + end + actual_pjs.each { |pj| check_pj_consistency(label, expected_pjs[pj.order_place], pj) } + end + + def check_pj_consistency(label, expected_pj, actual_pj) + errors = [] + if actual_pj.libelle != expected_pj['libelle'] + errors.append("incorrect libelle #{actual_pj.libelle} (expected #{expected_pj['libelle']})") + end + if (!actual_pj.mandatory) && expected_pj['mandatory'] + errors.append("pj should be mandatory") + end + if errors.present? + fail "On #{label} type de pièce justificative #{actual_pj.order_place} (#{actual_pj.libelle}) " + errors.join(', ') + end + end + end + + def initialize(source_procedure, destination_procedure, champ_mapping, private_champ_mapping = ChampMapping, piece_justificative_mapping = PieceJustificativeMapping, &block) @source_procedure = source_procedure @destination_procedure = destination_procedure - @champ_mapping = champ_mapping + @champ_mapping = champ_mapping.new(source_procedure, destination_procedure, false) + @private_champ_mapping = private_champ_mapping.new(source_procedure, destination_procedure, true) + @piece_justificative_mapping = piece_justificative_mapping.new(source_procedure, destination_procedure) + + if block_given? + @on_dossier_migration = block + end end def migrate_procedure @@ -81,7 +254,9 @@ module Tasks def check_consistency check_same_administrateur - check_source_destination_champs_consistency + @champ_mapping.check_source_destination_consistency + @private_champ_mapping.check_source_destination_consistency + @piece_justificative_mapping.check_source_destination_consistency end def check_same_administrateur @@ -90,59 +265,17 @@ module Tasks end end - def check_source_destination_champs_consistency - check_champs_consistency('source', @champ_mapping.expected_source_types_de_champ, @source_procedure.types_de_champ) - check_champs_consistency('destination', @champ_mapping.expected_destination_types_de_champ, @destination_procedure.types_de_champ) - end - - def check_champs_consistency(label, expected_tdcs, actual_tdcs) - if actual_tdcs.size != expected_tdcs.size - raise "Incorrect #{label} size #{actual_tdcs.size} (expected #{expected_tdcs.size})" - end - actual_tdcs.each { |tdc| check_champ_consistency(label, expected_tdcs[tdc.order_place], tdc) } - end - - def check_champ_consistency(label, expected_tdc, actual_tdc) - errors = [] - if actual_tdc.libelle != expected_tdc['libelle'] - errors.append("incorrect libelle #{actual_tdc.libelle} (expected #{expected_tdc['libelle']})") - 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 - if (!actual_tdc.mandatory) && expected_tdc['mandatory'] - errors.append("champ should be mandatory") - end - drop_down = actual_tdc.drop_down_list.presence&.options&.presence - if drop_down != expected_tdc['drop_down'] - errors.append("incorrect drop down list #{drop_down} (expected #{expected_tdc['drop_down']})") - end - if errors.present? - fail "On #{label} type de champ #{actual_tdc.order_place} (#{actual_tdc.libelle}) " + errors.join(', ') - end - end - def migrate_dossiers @source_procedure.dossiers.find_each(batch_size: 100) do |d| - # Since we’re going to iterate and change the champs at the same time, - # we use to_a to make the list static and avoid nasty surprises - original_champs = d.champs.to_a + if @champ_mapping.can_migrate?(d) && @private_champ_mapping.can_migrate?(d) && @piece_justificative_mapping.can_migrate?(d) + @champ_mapping.migrate(d) + @private_champ_mapping.migrate(d) + @piece_justificative_mapping.migrate(d) - @champ_mapping.compute_new_champs(d) - - original_champs.each do |c| - tdc_to = @champ_mapping.destination_type_de_champ(c) - if tdc_to.present? - c.update(type_de_champ: tdc_to) - elsif @champ_mapping.discard_champ?(c) - d.champs.destroy(c) - else - fail "Unhandled source type de champ #{c.type_de_champ.order_place}" - end + # Use update_columns to avoid triggering build_default_champs + d.update_columns(procedure_id: @destination_procedure.id) + @on_dossier_migration&.call(d) end - - # Use update_columns to avoid triggering build_default_champs - d.update_columns(procedure_id: @destination_procedure.id) end end diff --git a/spec/controllers/admin/attestation_templates_controller_spec.rb b/spec/controllers/admin/attestation_templates_controller_spec.rb index 6939e477e..f72e07227 100644 --- a/spec/controllers/admin/attestation_templates_controller_spec.rb +++ b/spec/controllers/admin/attestation_templates_controller_spec.rb @@ -3,12 +3,12 @@ describe Admin::AttestationTemplatesController, type: :controller do let!(:attestation_template) { create(:attestation_template) } let(:admin) { create(:administrateur) } let!(:procedure) { create :procedure, administrateur: admin, attestation_template: attestation_template } - let(:logo) { fixture_file_upload('spec/fixtures/white.png', 'image/png') } - let(:logo2) { fixture_file_upload('spec/fixtures/white.png', 'image/png') } - let(:signature) { fixture_file_upload('spec/fixtures/black.png', 'image/png') } - let(:signature2) { fixture_file_upload('spec/fixtures/black.png', 'image/png') } - let(:interlaced_logo) { fixture_file_upload('spec/fixtures/interlaced-black.png', 'image/png') } - let(:uninterlaced_logo) { fixture_file_upload('spec/fixtures/uninterlaced-black.png', 'image/png') } + let(:logo) { fixture_file_upload('spec/fixtures/files/white.png', 'image/png') } + let(:logo2) { fixture_file_upload('spec/fixtures/files/white.png', 'image/png') } + let(:signature) { fixture_file_upload('spec/fixtures/files/black.png', 'image/png') } + let(:signature2) { fixture_file_upload('spec/fixtures/files/black.png', 'image/png') } + let(:interlaced_logo) { fixture_file_upload('spec/fixtures/files/interlaced-black.png', 'image/png') } + let(:uninterlaced_logo) { fixture_file_upload('spec/fixtures/files/uninterlaced-black.png', 'image/png') } before do sign_in admin diff --git a/spec/controllers/new_gestionnaire/avis_controller_spec.rb b/spec/controllers/new_gestionnaire/avis_controller_spec.rb index 09de77c53..08c0f980c 100644 --- a/spec/controllers/new_gestionnaire/avis_controller_spec.rb +++ b/spec/controllers/new_gestionnaire/avis_controller_spec.rb @@ -81,7 +81,7 @@ describe NewGestionnaire::AvisController, type: :controller do end context "with a file" do - let(:file) { Rack::Test::UploadedFile.new("./spec/support/files/piece_justificative_0.pdf", 'application/pdf') } + let(:file) { Rack::Test::UploadedFile.new("./spec/fixtures/files/piece_justificative_0.pdf", 'application/pdf') } it do subject diff --git a/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb b/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb index 6509895ac..8df4828d7 100644 --- a/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb +++ b/spec/controllers/new_gestionnaire/dossiers_controller_spec.rb @@ -267,7 +267,7 @@ describe NewGestionnaire::DossiersController, type: :controller do describe "#create_commentaire" do let(:saved_commentaire) { dossier.commentaires.first } let(:body) { "avant\napres" } - let(:file) { Rack::Test::UploadedFile.new("./spec/support/files/piece_justificative_0.pdf", 'application/pdf') } + let(:file) { Rack::Test::UploadedFile.new("./spec/fixtures/files/piece_justificative_0.pdf", 'application/pdf') } let(:scan_result) { true } subject { diff --git a/spec/controllers/new_user/dossiers_controller_spec.rb b/spec/controllers/new_user/dossiers_controller_spec.rb index 361386ddc..ba818a0eb 100644 --- a/spec/controllers/new_user/dossiers_controller_spec.rb +++ b/spec/controllers/new_user/dossiers_controller_spec.rb @@ -617,7 +617,7 @@ describe NewUser::DossiersController, type: :controller do let(:dossier) { create(:dossier, :en_construction, user: user) } let(:saved_commentaire) { dossier.commentaires.first } let(:body) { "avant\napres" } - let(:file) { Rack::Test::UploadedFile.new("./spec/support/files/piece_justificative_0.pdf", 'application/pdf') } + let(:file) { Rack::Test::UploadedFile.new("./spec/fixtures/files/piece_justificative_0.pdf", 'application/pdf') } let(:scan_result) { true } subject { diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb index 5d952d491..6201d9de0 100644 --- a/spec/controllers/users/dossiers_controller_spec.rb +++ b/spec/controllers/users/dossiers_controller_spec.rb @@ -15,7 +15,7 @@ describe Users::DossiersController, type: :controller do let(:user) { create :user } let(:exercices_status) { 200 } - let(:exercices_body) { File.read('spec/support/files/api_entreprise/exercices.json') } + let(:exercices_body) { File.read('spec/fixtures/files/api_entreprise/exercices.json') } let(:siren) { '440117620' } let(:siret) { '44011762001530' } @@ -199,10 +199,10 @@ describe Users::DossiersController, type: :controller do .to_return(status: 404, body: 'fake body') stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/) - .to_return(status: status_entreprise_call, body: File.read('spec/support/files/api_entreprise/etablissements.json')) + .to_return(status: status_entreprise_call, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json')) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=/) - .to_return(status: status_entreprise_call, body: File.read('spec/support/files/api_entreprise/entreprises.json')) + .to_return(status: status_entreprise_call, body: File.read('spec/fixtures/files/api_entreprise/entreprises.json')) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/exercices\/#{siret}?.*token=/) .to_return(status: exercices_status, body: exercices_body) @@ -280,7 +280,7 @@ describe Users::DossiersController, type: :controller do context 'when siren have rna informations' do let(:rna_status) { 200 } - let(:rna_body) { File.read('spec/support/files/api_entreprise/associations.json') } + let(:rna_body) { File.read('spec/fixtures/files/api_entreprise/associations.json') } it 'creates rna information for entreprise' do subject diff --git a/spec/factories/piece_justificative.rb b/spec/factories/piece_justificative.rb index e204bdba4..d60b935f0 100644 --- a/spec/factories/piece_justificative.rb +++ b/spec/factories/piece_justificative.rb @@ -1,11 +1,11 @@ FactoryBot.define do factory :piece_justificative do trait :rib do - content { Rack::Test::UploadedFile.new("./spec/support/files/RIB.pdf", 'application/pdf') } + content { Rack::Test::UploadedFile.new("./spec/fixtures/files/RIB.pdf", 'application/pdf') } end trait :contrat do - content { Rack::Test::UploadedFile.new("./spec/support/files/Contrat.pdf", 'application/pdf') } + content { Rack::Test::UploadedFile.new("./spec/fixtures/files/Contrat.pdf", 'application/pdf') } end end end diff --git a/spec/factories/type_de_champ.rb b/spec/factories/type_de_champ.rb index 363b79476..27fb88c01 100644 --- a/spec/factories/type_de_champ.rb +++ b/spec/factories/type_de_champ.rb @@ -84,6 +84,9 @@ FactoryBot.define do factory :type_de_champ_siret do type_champ { TypeDeChamp.type_champs.fetch(:siret) } end + factory :type_de_champ_carte do + type_champ { TypeDeChamp.type_champs.fetch(:carte) } + end trait :private do private { true } diff --git a/spec/features/new_user/brouillon_spec.rb b/spec/features/new_user/brouillon_spec.rb index 4ffe73bae..cfe5f6185 100644 --- a/spec/features/new_user/brouillon_spec.rb +++ b/spec/features/new_user/brouillon_spec.rb @@ -39,7 +39,7 @@ feature 'The user' do check('engagement') fill_in('dossier_link', with: '123') # do not know how to make it work... - # find('form input[type="file"]').set(Rails.root.join('spec/fixtures/white.png')) + # find('form input[type="file"]').set(Rails.root.join('spec/fixtures/files/white.png')) click_on 'Enregistrer le brouillon' diff --git a/spec/features/users/complete_demande_spec.rb b/spec/features/users/complete_demande_spec.rb index 2de695d97..725e5135f 100644 --- a/spec/features/users/complete_demande_spec.rb +++ b/spec/features/users/complete_demande_spec.rb @@ -31,12 +31,12 @@ feature 'user path for dossier creation' do context 'sets siret' do before do stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/) - .to_return(body: File.read('spec/support/files/api_entreprise/etablissements.json', status: 200)) + .to_return(body: File.read('spec/fixtures/files/api_entreprise/etablissements.json', status: 200)) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=/) - .to_return(status: 200, body: File.read('spec/support/files/api_entreprise/entreprises.json')) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/entreprises.json')) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/exercices\/#{siret}?.*token=/) - .to_return(status: 200, body: File.read('spec/support/files/api_entreprise/exercices.json')) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/exercices.json')) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/associations\/#{siret}?.*token=/) .to_return(status: 404, body: '') diff --git a/spec/features/users/dossier_creation_spec.rb b/spec/features/users/dossier_creation_spec.rb index 8db07b62e..adc24535f 100644 --- a/spec/features/users/dossier_creation_spec.rb +++ b/spec/features/users/dossier_creation_spec.rb @@ -67,11 +67,11 @@ feature 'As a User I wanna create a dossier' do expect(page).to have_current_path(users_dossier_path(procedure_with_siret.dossiers.last.id.to_s)) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/) - .to_return(status: 200, body: File.read('spec/support/files/api_entreprise/etablissements.json')) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json')) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=/) - .to_return(status: 200, body: File.read('spec/support/files/api_entreprise/entreprises.json')) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/entreprises.json')) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/exercices\/#{siret}?.*token=/) - .to_return(status: 200, body: File.read('spec/support/files/api_entreprise/exercices.json')) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/exercices.json')) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/associations\/#{siret}?.*token=/) .to_return(status: 404, body: '') diff --git a/spec/features/users/start_demande_spec.rb b/spec/features/users/start_demande_spec.rb index ad7937318..5cd48a6b4 100644 --- a/spec/features/users/start_demande_spec.rb +++ b/spec/features/users/start_demande_spec.rb @@ -27,11 +27,11 @@ feature 'user arrive on siret page' do context 'when enter a siret', js: true do before do stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/) - .to_return(status: 200, body: File.read('spec/support/files/api_entreprise/etablissements.json')) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/etablissements.json')) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=/) - .to_return(status: 200, body: File.read('spec/support/files/api_entreprise/entreprises.json')) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/entreprises.json')) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/exercices\/#{siret}?.*token=/) - .to_return(status: 200, body: File.read('spec/support/files/api_entreprise/exercices.json')) + .to_return(status: 200, body: File.read('spec/fixtures/files/api_entreprise/exercices.json')) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/associations\/#{siret}?.*token=/) .to_return(status: 404, body: '') diff --git a/spec/support/files/Contrat.pdf b/spec/fixtures/files/Contrat.pdf similarity index 100% rename from spec/support/files/Contrat.pdf rename to spec/fixtures/files/Contrat.pdf diff --git a/spec/support/files/RIB.pdf b/spec/fixtures/files/RIB.pdf similarity index 100% rename from spec/support/files/RIB.pdf rename to spec/fixtures/files/RIB.pdf diff --git a/spec/support/files/api_adresse/search_no_results.json b/spec/fixtures/files/api_adresse/search_no_results.json similarity index 100% rename from spec/support/files/api_adresse/search_no_results.json rename to spec/fixtures/files/api_adresse/search_no_results.json diff --git a/spec/support/files/api_adresse/search_results.json b/spec/fixtures/files/api_adresse/search_results.json similarity index 100% rename from spec/support/files/api_adresse/search_results.json rename to spec/fixtures/files/api_adresse/search_results.json diff --git a/spec/support/files/api_carto/request_cadastre.json b/spec/fixtures/files/api_carto/request_cadastre.json similarity index 100% rename from spec/support/files/api_carto/request_cadastre.json rename to spec/fixtures/files/api_carto/request_cadastre.json diff --git a/spec/support/files/api_carto/request_qp.json b/spec/fixtures/files/api_carto/request_qp.json similarity index 100% rename from spec/support/files/api_carto/request_qp.json rename to spec/fixtures/files/api_carto/request_qp.json diff --git a/spec/support/files/api_carto/response_cadastre.json b/spec/fixtures/files/api_carto/response_cadastre.json similarity index 100% rename from spec/support/files/api_carto/response_cadastre.json rename to spec/fixtures/files/api_carto/response_cadastre.json diff --git a/spec/support/files/api_carto/response_qp.json b/spec/fixtures/files/api_carto/response_qp.json similarity index 100% rename from spec/support/files/api_carto/response_qp.json rename to spec/fixtures/files/api_carto/response_qp.json diff --git a/spec/support/files/api_entreprise/associations.json b/spec/fixtures/files/api_entreprise/associations.json similarity index 100% rename from spec/support/files/api_entreprise/associations.json rename to spec/fixtures/files/api_entreprise/associations.json diff --git a/spec/support/files/api_entreprise/entreprises.json b/spec/fixtures/files/api_entreprise/entreprises.json similarity index 100% rename from spec/support/files/api_entreprise/entreprises.json rename to spec/fixtures/files/api_entreprise/entreprises.json diff --git a/spec/support/files/api_entreprise/etablissements.json b/spec/fixtures/files/api_entreprise/etablissements.json similarity index 100% rename from spec/support/files/api_entreprise/etablissements.json rename to spec/fixtures/files/api_entreprise/etablissements.json diff --git a/spec/support/files/api_entreprise/exercices.json b/spec/fixtures/files/api_entreprise/exercices.json similarity index 100% rename from spec/support/files/api_entreprise/exercices.json rename to spec/fixtures/files/api_entreprise/exercices.json diff --git a/spec/fixtures/black.png b/spec/fixtures/files/black.png similarity index 100% rename from spec/fixtures/black.png rename to spec/fixtures/files/black.png diff --git a/spec/support/files/dossierPDF.pdf b/spec/fixtures/files/dossierPDF.pdf similarity index 100% rename from spec/support/files/dossierPDF.pdf rename to spec/fixtures/files/dossierPDF.pdf diff --git a/spec/fixtures/file.pdf b/spec/fixtures/files/file.pdf similarity index 100% rename from spec/fixtures/file.pdf rename to spec/fixtures/files/file.pdf diff --git a/spec/fixtures/interlaced-black.png b/spec/fixtures/files/interlaced-black.png similarity index 100% rename from spec/fixtures/interlaced-black.png rename to spec/fixtures/files/interlaced-black.png diff --git a/spec/support/files/logo_test_procedure.png b/spec/fixtures/files/logo_test_procedure.png similarity index 100% rename from spec/support/files/logo_test_procedure.png rename to spec/fixtures/files/logo_test_procedure.png diff --git a/spec/support/files/piece_justificative_0.pdf b/spec/fixtures/files/piece_justificative_0.pdf similarity index 100% rename from spec/support/files/piece_justificative_0.pdf rename to spec/fixtures/files/piece_justificative_0.pdf diff --git a/spec/support/files/piece_justificative_1.pdf b/spec/fixtures/files/piece_justificative_1.pdf similarity index 100% rename from spec/support/files/piece_justificative_1.pdf rename to spec/fixtures/files/piece_justificative_1.pdf diff --git a/spec/support/files/piece_justificative_388.pdf b/spec/fixtures/files/piece_justificative_388.pdf similarity index 100% rename from spec/support/files/piece_justificative_388.pdf rename to spec/fixtures/files/piece_justificative_388.pdf diff --git a/spec/support/files/qp_geometry_value.txt b/spec/fixtures/files/qp_geometry_value.txt similarity index 100% rename from spec/support/files/qp_geometry_value.txt rename to spec/fixtures/files/qp_geometry_value.txt diff --git a/spec/fixtures/uninterlaced-black.png b/spec/fixtures/files/uninterlaced-black.png similarity index 100% rename from spec/fixtures/uninterlaced-black.png rename to spec/fixtures/files/uninterlaced-black.png diff --git a/spec/fixtures/white.png b/spec/fixtures/files/white.png similarity index 100% rename from spec/fixtures/white.png rename to spec/fixtures/files/white.png diff --git a/spec/lib/api_adresse/address_adapter_spec.rb b/spec/lib/api_adresse/address_adapter_spec.rb index f94a3caa1..31a1d7bc3 100644 --- a/spec/lib/api_adresse/address_adapter_spec.rb +++ b/spec/lib/api_adresse/address_adapter_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe ApiAdresse::AddressAdapter do describe '#get_suggestions' do let(:request) { 'Paris' } - let(:response) { File.open('spec/support/files/api_adresse/search_results.json') } + let(:response) { File.open('spec/fixtures/files/api_adresse/search_results.json') } let(:status) { 200 } subject { described_class.new(request).get_suggestions } @@ -19,7 +19,7 @@ describe ApiAdresse::AddressAdapter do end context 'when address return an empty list' do - let(:response) { File.open('spec/support/files/api_adresse/search_no_results.json') } + let(:response) { File.open('spec/fixtures/files/api_adresse/search_no_results.json') } it { expect(subject.size).to eq 0 } it { is_expected.to be_an_instance_of Array } diff --git a/spec/lib/api_carto/api_spec.rb b/spec/lib/api_carto/api_spec.rb index f7cc8ed42..900debfda 100644 --- a/spec/lib/api_carto/api_spec.rb +++ b/spec/lib/api_carto/api_spec.rb @@ -21,7 +21,7 @@ describe ApiCarto::API do end context 'when request return 500' do - let(:geojson) { File.read('spec/support/files/api_carto/request_qp.json') } + let(:geojson) { File.read('spec/fixtures/files/api_carto/request_qp.json') } let(:status) { 500 } let(:body) { 'toto' } @@ -31,7 +31,7 @@ describe ApiCarto::API do end context 'when geojson exist' do - let(:geojson) { File.read('spec/support/files/api_carto/request_qp.json') } + let(:geojson) { File.read('spec/fixtures/files/api_carto/request_qp.json') } let(:status) { 200 } let(:body) { 'toto' } @@ -40,7 +40,7 @@ describe ApiCarto::API do end context 'when geojson is at format JSON' do - let(:geojson) { JSON.parse(File.read('spec/support/files/api_carto/request_qp.json')) } + let(:geojson) { JSON.parse(File.read('spec/fixtures/files/api_carto/request_qp.json')) } it 'returns response body' do expect(subject).to eq(body) @@ -69,7 +69,7 @@ describe ApiCarto::API do end context 'when geojson exist' do - let(:geojson) { File.read('spec/support/files/api_carto/request_cadastre.json') } + let(:geojson) { File.read('spec/fixtures/files/api_carto/request_cadastre.json') } let(:status) { 200 } let(:body) { 'toto' } @@ -78,7 +78,7 @@ describe ApiCarto::API do end context 'when geojson is at format JSON' do - let(:geojson) { JSON.parse(File.read('spec/support/files/api_carto/request_cadastre.json')) } + let(:geojson) { JSON.parse(File.read('spec/fixtures/files/api_carto/request_cadastre.json')) } it 'returns response body' do expect(subject).to eq(body) diff --git a/spec/lib/api_carto/cadastre_adapter_spec.rb b/spec/lib/api_carto/cadastre_adapter_spec.rb index 2dba88a82..6aa2858ca 100644 --- a/spec/lib/api_carto/cadastre_adapter_spec.rb +++ b/spec/lib/api_carto/cadastre_adapter_spec.rb @@ -13,7 +13,7 @@ describe ApiCarto::CadastreAdapter do context 'coordinates are filled' do let(:coordinates) { '[[2.252728, 43.27151][2.323223, 32.835332]]' } let(:status) { 200 } - let(:body) { File.read('spec/support/files/api_carto/response_cadastre.json') } + let(:body) { File.read('spec/fixtures/files/api_carto/response_cadastre.json') } it { expect(subject).to be_a_instance_of(Array) } it { expect(subject.size).to eq(16) } diff --git a/spec/lib/api_carto/quartiers_prioritaires_adapter_spec.rb b/spec/lib/api_carto/quartiers_prioritaires_adapter_spec.rb index 24ffcc5e8..b4ac7ef3a 100644 --- a/spec/lib/api_carto/quartiers_prioritaires_adapter_spec.rb +++ b/spec/lib/api_carto/quartiers_prioritaires_adapter_spec.rb @@ -13,7 +13,7 @@ describe ApiCarto::QuartiersPrioritairesAdapter do context 'coordinates are filled' do let(:coordinates) { '[[2.252728, 43.27151][2.323223, 32.835332]]' } let(:status) { 200 } - let(:body) { File.read('spec/support/files/api_carto/response_qp.json') } + let(:body) { File.read('spec/fixtures/files/api_carto/response_qp.json') } it { expect(subject).to be_a_instance_of(Array) } diff --git a/spec/lib/api_entreprise/api_spec.rb b/spec/lib/api_entreprise/api_spec.rb index 2dffe6ae6..c0dcaeb84 100644 --- a/spec/lib/api_entreprise/api_spec.rb +++ b/spec/lib/api_entreprise/api_spec.rb @@ -20,7 +20,7 @@ describe ApiEntreprise::API do context 'when siret exist' do let(:siren) { '418166096' } let(:status) { 200 } - let(:body) { File.read('spec/support/files/api_entreprise/entreprises.json') } + let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises.json') } it 'returns response body' do expect(subject).to eq(JSON.parse(body, symbolize_names: true)) @@ -48,7 +48,7 @@ describe ApiEntreprise::API do context 'when siret exists' do let(:siret) { '41816609600051' } let(:status) { 200 } - let(:body) { File.read('spec/support/files/api_entreprise/etablissements.json') } + let(:body) { File.read('spec/fixtures/files/api_entreprise/etablissements.json') } it 'returns body' do expect(subject).to eq(JSON.parse(body, symbolize_names: true)) @@ -79,7 +79,7 @@ describe ApiEntreprise::API do let(:siret) { '41816609600051' } let(:status) { 200 } - let(:body) { File.read('spec/support/files/api_entreprise/exercices.json') } + let(:body) { File.read('spec/fixtures/files/api_entreprise/exercices.json') } it 'raises RestClient::Unauthorized' do expect(subject).to eq(JSON.parse(body, symbolize_names: true)) @@ -108,7 +108,7 @@ describe ApiEntreprise::API do context 'when siren exists' do let(:siren) { '418166096' } let(:status) { 200 } - let(:body) { File.read('spec/support/files/api_entreprise/associations.json') } + let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') } it { expect(subject).to eq(JSON.parse(body, symbolize_names: true)) } end diff --git a/spec/lib/api_entreprise/entreprise_adapter_spec.rb b/spec/lib/api_entreprise/entreprise_adapter_spec.rb index 75328fe9c..a8559c024 100644 --- a/spec/lib/api_entreprise/entreprise_adapter_spec.rb +++ b/spec/lib/api_entreprise/entreprise_adapter_spec.rb @@ -8,7 +8,7 @@ describe ApiEntreprise::EntrepriseAdapter do before do stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=/) - .to_return(body: File.read('spec/support/files/api_entreprise/entreprises.json', status: 200)) + .to_return(body: File.read('spec/fixtures/files/api_entreprise/entreprises.json', status: 200)) end it '#to_params class est une Hash ?' do diff --git a/spec/lib/api_entreprise/etablissement_adapter_spec.rb b/spec/lib/api_entreprise/etablissement_adapter_spec.rb index e2224bdbe..86646148f 100644 --- a/spec/lib/api_entreprise/etablissement_adapter_spec.rb +++ b/spec/lib/api_entreprise/etablissement_adapter_spec.rb @@ -9,7 +9,7 @@ describe ApiEntreprise::EtablissementAdapter do before do stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/) - .to_return(body: File.read('spec/support/files/api_entreprise/etablissements.json', status: 200)) + .to_return(body: File.read('spec/fixtures/files/api_entreprise/etablissements.json', status: 200)) end it '#to_params class est une Hash ?' do diff --git a/spec/lib/api_entreprise/exercices_adapter_spec.rb b/spec/lib/api_entreprise/exercices_adapter_spec.rb index 36c5cbb8b..d7cfb7aca 100644 --- a/spec/lib/api_entreprise/exercices_adapter_spec.rb +++ b/spec/lib/api_entreprise/exercices_adapter_spec.rb @@ -7,7 +7,7 @@ describe ApiEntreprise::ExercicesAdapter do before do stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/exercices\/.*token=/) - .to_return(body: File.read('spec/support/files/api_entreprise/exercices.json', status: 200)) + .to_return(body: File.read('spec/fixtures/files/api_entreprise/exercices.json', status: 200)) end it '#to_params class est un Hash ?' do diff --git a/spec/lib/api_entreprise/rna_adapter_spec.rb b/spec/lib/api_entreprise/rna_adapter_spec.rb index 2b246d54f..6e54eb058 100644 --- a/spec/lib/api_entreprise/rna_adapter_spec.rb +++ b/spec/lib/api_entreprise/rna_adapter_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe ApiEntreprise::RNAAdapter do let(:siret) { '50480511000013' } let(:procedure_id) { 22 } - let(:body) { File.read('spec/support/files/api_entreprise/associations.json') } + let(:body) { File.read('spec/fixtures/files/api_entreprise/associations.json') } let(:status) { 200 } let(:adapter) { described_class.new(siret, procedure_id) } diff --git a/spec/models/attestation_template_spec.rb b/spec/models/attestation_template_spec.rb index 0a0ff4dcc..f5b6786f4 100644 --- a/spec/models/attestation_template_spec.rb +++ b/spec/models/attestation_template_spec.rb @@ -57,8 +57,8 @@ describe AttestationTemplate, type: :model do describe 'dup' do before do - @logo = File.open('spec/fixtures/white.png') - @signature = File.open('spec/fixtures/black.png') + @logo = File.open('spec/fixtures/files/white.png') + @signature = File.open('spec/fixtures/files/black.png') end after do @@ -113,8 +113,8 @@ describe AttestationTemplate, type: :model do end before do - @logo = File.open('spec/fixtures/white.png') - @signature = File.open('spec/fixtures/black.png') + @logo = File.open('spec/fixtures/files/white.png') + @signature = File.open('spec/fixtures/files/black.png') Timecop.freeze(Time.now) end diff --git a/spec/models/piece_justificative_spec.rb b/spec/models/piece_justificative_spec.rb index 0cfd6aee2..f6113af24 100644 --- a/spec/models/piece_justificative_spec.rb +++ b/spec/models/piece_justificative_spec.rb @@ -13,7 +13,7 @@ describe PieceJustificative do subject { piece_justificative.empty? } context 'when content exist' do - let(:content) { File.open('./spec/support/files/piece_justificative_388.pdf') } + let(:content) { File.open('./spec/fixtures/files/piece_justificative_388.pdf') } it { is_expected.to be_falsey } end end diff --git a/spec/models/procedure_spec.rb b/spec/models/procedure_spec.rb index d97829d03..cffd74f0d 100644 --- a/spec/models/procedure_spec.rb +++ b/spec/models/procedure_spec.rb @@ -345,8 +345,8 @@ describe Procedure do let(:from_library) { false } before do - @logo = File.open('spec/fixtures/white.png') - @signature = File.open('spec/fixtures/black.png') + @logo = File.open('spec/fixtures/files/white.png') + @signature = File.open('spec/fixtures/files/black.png') @attestation_template = create(:attestation_template, procedure: procedure, logo: @logo, signature: @signature) @procedure = procedure.clone(procedure.administrateur, from_library) @procedure.save diff --git a/spec/models/quartier_prioritaire_spec.rb b/spec/models/quartier_prioritaire_spec.rb index 6295ad74e..fa84ab8ed 100644 --- a/spec/models/quartier_prioritaire_spec.rb +++ b/spec/models/quartier_prioritaire_spec.rb @@ -10,7 +10,7 @@ describe QuartierPrioritaire do describe 'geometry' do let(:qp) { create :quartier_prioritaire, geometry: qp_geometry } - let(:qp_geometry) { File.open('spec/support/files/qp_geometry_value.txt').read } + let(:qp_geometry) { File.open('spec/fixtures/files/qp_geometry_value.txt').read } subject { qp.geometry } diff --git a/spec/services/commentaire_service_spec.rb b/spec/services/commentaire_service_spec.rb index 7029d0c47..55e5f3115 100644 --- a/spec/services/commentaire_service_spec.rb +++ b/spec/services/commentaire_service_spec.rb @@ -32,7 +32,7 @@ describe CommentaireService do end context 'when it has a file' do - let(:file) { Rack::Test::UploadedFile.new("./spec/support/files/piece_justificative_0.pdf", 'application/pdf') } + let(:file) { Rack::Test::UploadedFile.new("./spec/fixtures/files/piece_justificative_0.pdf", 'application/pdf') } it 'saves the attached file' do expect(commentaire.file).to be_present diff --git a/spec/views/admin/procedures/edit.html.haml_spec.rb b/spec/views/admin/procedures/edit.html.haml_spec.rb index 3e928fe08..28d4cc71b 100644 --- a/spec/views/admin/procedures/edit.html.haml_spec.rb +++ b/spec/views/admin/procedures/edit.html.haml_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'admin/procedures/edit.html.haml', type: :view, vcr: { cassette_name: 'admin_procedure_edit' } do - let(:logo) { Rack::Test::UploadedFile.new("./spec/support/files/logo_test_procedure.png", 'image/png') } + let(:logo) { Rack::Test::UploadedFile.new("./spec/fixtures/files/logo_test_procedure.png", 'image/png') } let(:procedure) { create(:procedure, logo: logo) } before do