Merge branch 'dev'
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
29
app/models/champs/carte_champ.rb
Normal file
|
@ -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
|
26
app/models/geo_area.rb
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
2
app/models/types_de_champ/carte_type_de_champ.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
class TypesDeChamp::CarteTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||
end
|
15
app/views/dossier_mailer/notify_undelete_to_user.html.haml
Normal file
|
@ -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
|
26
app/views/dossier_mailer/notify_unmigrated_to_user.html.haml
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
14
db/migrate/20181010183331_create_geo_areas.rb
Normal file
|
@ -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
|
13
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"
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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'
|
||||
|
||||
|
|
|
@ -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: '')
|
||||
|
||||
|
|
|
@ -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: '')
|
||||
|
||||
|
|
|
@ -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: '')
|
||||
|
||||
|
|
Before Width: | Height: | Size: 67 B After Width: | Height: | Size: 67 B |
Before Width: | Height: | Size: 214 B After Width: | Height: | Size: 214 B |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 165 B After Width: | Height: | Size: 165 B |
Before Width: | Height: | Size: 67 B After Width: | Height: | Size: 67 B |
|
@ -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 }
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) }
|
||||
|
|
|
@ -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) }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|