Merge branch 'dev'
This commit is contained in:
commit
a05a129c76
40 changed files with 332 additions and 181 deletions
|
@ -424,3 +424,16 @@ $cta-panel-button-border-size: 2px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tour-de-france-banner {
|
||||||
|
padding-top: 15px;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
background-color: $blue;
|
||||||
|
color: #FFFFFF;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #FFFFFF;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,22 +3,25 @@ class AutoReceiveDossiersForProcedureJob < ApplicationJob
|
||||||
|
|
||||||
def perform(procedure_id, state)
|
def perform(procedure_id, state)
|
||||||
procedure = Procedure.find(procedure_id)
|
procedure = Procedure.find(procedure_id)
|
||||||
attrs = case state
|
case state
|
||||||
when Dossier.states.fetch(:en_instruction)
|
when Dossier.states.fetch(:en_instruction)
|
||||||
{
|
procedure.dossiers.state_en_construction.update_all(
|
||||||
state: Dossier.states.fetch(:en_instruction),
|
state: Dossier.states.fetch(:en_instruction),
|
||||||
en_instruction_at: DateTime.now
|
en_instruction_at: DateTime.now
|
||||||
}
|
)
|
||||||
when Dossier.states.fetch(:accepte)
|
when Dossier.states.fetch(:accepte)
|
||||||
{
|
procedure.dossiers.state_en_construction.find_each do |dossier|
|
||||||
state: Dossier.states.fetch(:accepte),
|
dossier.update(
|
||||||
en_instruction_at: DateTime.now,
|
state: Dossier.states.fetch(:accepte),
|
||||||
processed_at: DateTime.now
|
en_instruction_at: DateTime.now,
|
||||||
}
|
processed_at: DateTime.now
|
||||||
|
)
|
||||||
|
dossier.attestation = dossier.build_attestation
|
||||||
|
dossier.save
|
||||||
|
NotificationMailer.send_closed_notification(dossier).deliver_later
|
||||||
|
end
|
||||||
else
|
else
|
||||||
raise "Receiving Procedure##{procedure_id} in invalid state \"#{state}\""
|
raise "Receiving Procedure##{procedure_id} in invalid state \"#{state}\""
|
||||||
end
|
end
|
||||||
|
|
||||||
procedure.dossiers.state_en_construction.update_all(attrs)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
class Champs::LinkedDropDownListChamp < Champ
|
class Champs::LinkedDropDownListChamp < Champ
|
||||||
delegate :primary_options, :secondary_options, to: :type_de_champ
|
delegate :primary_options, :secondary_options, to: 'type_de_champ.dynamic_type'
|
||||||
|
|
||||||
def primary_value
|
def primary_value
|
||||||
if value.present?
|
if value.present?
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
class TypeDeChamp < ApplicationRecord
|
class TypeDeChamp < ApplicationRecord
|
||||||
|
# TODO drop next line when `type` column has been dropped from `types_de_champ` table
|
||||||
|
self.inheritance_column = nil
|
||||||
|
|
||||||
enum type_champs: {
|
enum type_champs: {
|
||||||
text: 'text',
|
text: 'text',
|
||||||
textarea: 'textarea',
|
textarea: 'textarea',
|
||||||
|
@ -27,6 +30,10 @@ class TypeDeChamp < ApplicationRecord
|
||||||
|
|
||||||
belongs_to :procedure
|
belongs_to :procedure
|
||||||
|
|
||||||
|
after_initialize :set_dynamic_type
|
||||||
|
|
||||||
|
attr_reader :dynamic_type
|
||||||
|
|
||||||
scope :public_only, -> { where(private: false) }
|
scope :public_only, -> { where(private: false) }
|
||||||
scope :private_only, -> { where(private: true) }
|
scope :private_only, -> { where(private: true) }
|
||||||
scope :ordered, -> { order(order_place: :asc) }
|
scope :ordered, -> { order(order_place: :asc) }
|
||||||
|
@ -52,6 +59,15 @@ class TypeDeChamp < ApplicationRecord
|
||||||
before_validation :check_mandatory
|
before_validation :check_mandatory
|
||||||
before_save :remove_piece_justificative_template, if: -> { type_champ_changed? }
|
before_save :remove_piece_justificative_template, if: -> { type_champ_changed? }
|
||||||
|
|
||||||
|
def set_dynamic_type
|
||||||
|
@dynamic_type = type_champ.present? ? self.class.type_champ_to_class_name(type_champ).constantize.new(self) : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def type_champ=(value)
|
||||||
|
super(value)
|
||||||
|
set_dynamic_type
|
||||||
|
end
|
||||||
|
|
||||||
def params_for_champ
|
def params_for_champ
|
||||||
{
|
{
|
||||||
private: private?,
|
private: private?,
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::CheckboxTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::CheckboxTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::CiviliteTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::CiviliteTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::DateTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::DateTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::DatetimeTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::DatetimeTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::DossierLinkTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::DossierLinkTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::DropDownListTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::DropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::HeaderSectionTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::HeaderSectionTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::LinkedDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
PRIMARY_PATTERN = /^--(.*)--$/
|
PRIMARY_PATTERN = /^--(.*)--$/
|
||||||
|
|
||||||
|
delegate :drop_down_list, to: :@type_de_champ
|
||||||
|
|
||||||
def primary_options
|
def primary_options
|
||||||
primary_options = unpack_options.map(&:first)
|
primary_options = unpack_options.map(&:first)
|
||||||
if primary_options.present?
|
if primary_options.present?
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::MultipleDropDownListTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::MultipleDropDownListTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::NumberTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::NumberTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::PieceJustificativeTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::PieceJustificativeTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::SiretTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::SiretTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
class TypesDeChamp::TextTypeDeChamp < TypeDeChamp
|
class TypesDeChamp::TextTypeDeChamp < TypesDeChamp::TypeDeChampBase
|
||||||
end
|
end
|
||||||
|
|
5
app/models/types_de_champ/type_de_champ_base.rb
Normal file
5
app/models/types_de_champ/type_de_champ_base.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class TypesDeChamp::TypeDeChampBase
|
||||||
|
def initialize(type_de_champ)
|
||||||
|
@type_de_champ = type_de_champ
|
||||||
|
end
|
||||||
|
end
|
|
@ -51,8 +51,6 @@ class DossierFieldService
|
||||||
dossier.user.send(column)
|
dossier.user.send(column)
|
||||||
when 'france_connect_information'
|
when 'france_connect_information'
|
||||||
dossier.user.france_connect_information&.send(column)
|
dossier.user.france_connect_information&.send(column)
|
||||||
when 'entreprise'
|
|
||||||
dossier.etablissement&.send(:"entreprise_#{column}")
|
|
||||||
when 'etablissement'
|
when 'etablissement'
|
||||||
dossier.etablissement&.send(column)
|
dossier.etablissement&.send(column)
|
||||||
when 'type_de_champ'
|
when 'type_de_champ'
|
||||||
|
@ -79,19 +77,19 @@ class DossierFieldService
|
||||||
.includes(relation)
|
.includes(relation)
|
||||||
.where("champs.type_de_champ_id = ?", filter['column'].to_i)
|
.where("champs.type_de_champ_id = ?", filter['column'].to_i)
|
||||||
.where("champs.value ILIKE ?", "%#{filter['value']}%")
|
.where("champs.value ILIKE ?", "%#{filter['value']}%")
|
||||||
when 'entreprise'
|
when 'etablissement'
|
||||||
table = 'etablissement'
|
table = filter['table']
|
||||||
if filter['column'] == 'date_creation'
|
if filter['column'] == 'entreprise_date_creation'
|
||||||
date = filter['value'].to_date rescue nil
|
date = filter['value'].to_date rescue nil
|
||||||
dossiers
|
dossiers
|
||||||
.includes(table)
|
.includes(table)
|
||||||
.where("#{table.pluralize}.entreprise_#{filter['column']} = ?", date)
|
.where("#{table.pluralize}.#{filter['column']} = ?", date)
|
||||||
else
|
else
|
||||||
dossiers
|
dossiers
|
||||||
.includes(table)
|
.includes(table)
|
||||||
.where("#{table.pluralize}.entreprise_#{filter['column']} ILIKE ?", "%#{filter['value']}%")
|
.where("#{table.pluralize}.#{filter['column']} ILIKE ?", "%#{filter['value']}%")
|
||||||
end
|
end
|
||||||
when 'user', 'etablissement'
|
when 'user'
|
||||||
dossiers
|
dossiers
|
||||||
.includes(filter['table'])
|
.includes(filter['table'])
|
||||||
.where("#{filter['table'].pluralize}.#{filter['column']} ILIKE ?", "%#{filter['value']}%")
|
.where("#{filter['table'].pluralize}.#{filter['column']} ILIKE ?", "%#{filter['value']}%")
|
||||||
|
|
|
@ -19,10 +19,6 @@ class TypesDeChampService
|
||||||
|
|
||||||
parameters[attributes].each do |index, param|
|
parameters[attributes].each do |index, param|
|
||||||
param[:private] = private
|
param[:private] = private
|
||||||
if param[:type_champ]
|
|
||||||
param[:type] = TypeDeChamp.type_champ_to_class_name(param[:type_champ])
|
|
||||||
end
|
|
||||||
|
|
||||||
if param[:libelle].empty?
|
if param[:libelle].empty?
|
||||||
parameters[attributes].delete(index.to_s)
|
parameters[attributes].delete(index.to_s)
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
|
|
||||||
.form-group
|
.form-group
|
||||||
= ff.hidden_field :order_place, value: ff.index
|
= ff.hidden_field :order_place, value: ff.index
|
||||||
= ff.hidden_field :type
|
|
||||||
= ff.hidden_field :id
|
= ff.hidden_field :id
|
||||||
|
|
||||||
- if ff.object.id.present?
|
- if ff.object.id.present?
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
- content_for :footer do
|
- content_for :footer do
|
||||||
= render partial: "root/footer"
|
= render partial: "root/footer"
|
||||||
|
|
||||||
|
.tour-de-france-banner
|
||||||
|
.container
|
||||||
|
L'équipe demarches-simplifiees.fr vient à votre rencontre cet automne.
|
||||||
|
= succeed '.' do
|
||||||
|
= link_to "En savoir plus", tour_de_france_path
|
||||||
|
|
||||||
.landing
|
.landing
|
||||||
.landing-panel.hero-panel
|
.landing-panel.hero-panel
|
||||||
.container
|
.container
|
||||||
|
|
5
db/migrate/20180924074121_drop_entreprises.rb
Normal file
5
db/migrate/20180924074121_drop_entreprises.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class DropEntreprises < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
drop_table :entreprises
|
||||||
|
end
|
||||||
|
end
|
21
db/schema.rb
21
db/schema.rb
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2018_09_19_084403) do
|
ActiveRecord::Schema.define(version: 2018_09_24_074121) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -251,25 +251,6 @@ ActiveRecord::Schema.define(version: 2018_09_19_084403) do
|
||||||
t.index ["type_de_champ_id"], name: "index_drop_down_lists_on_type_de_champ_id"
|
t.index ["type_de_champ_id"], name: "index_drop_down_lists_on_type_de_champ_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "entreprises", id: :serial, force: :cascade do |t|
|
|
||||||
t.string "siren"
|
|
||||||
t.bigint "capital_social"
|
|
||||||
t.string "numero_tva_intracommunautaire"
|
|
||||||
t.string "forme_juridique"
|
|
||||||
t.string "forme_juridique_code"
|
|
||||||
t.string "nom_commercial"
|
|
||||||
t.string "raison_sociale"
|
|
||||||
t.string "siret_siege_social"
|
|
||||||
t.string "code_effectif_entreprise"
|
|
||||||
t.datetime "date_creation"
|
|
||||||
t.string "nom"
|
|
||||||
t.string "prenom"
|
|
||||||
t.integer "dossier_id"
|
|
||||||
t.datetime "created_at"
|
|
||||||
t.datetime "updated_at"
|
|
||||||
t.index ["dossier_id"], name: "index_entreprises_on_dossier_id"
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table "etablissements", id: :serial, force: :cascade do |t|
|
create_table "etablissements", id: :serial, force: :cascade do |t|
|
||||||
t.string "siret"
|
t.string "siret"
|
||||||
t.boolean "siege_social"
|
t.boolean "siege_social"
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace :'2018_05_14_add_annotation_privee_to_procedure' do
|
||||||
tdc.update_attribute(:order_place, tdc.order_place + 1)
|
tdc.update_attribute(:order_place, tdc.order_place + 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
new_tdc = TypesDeChamp::TextTypeDeChamp.create(
|
new_tdc = TypeDeChamp.create(
|
||||||
procedure_id: procedure_id,
|
procedure_id: procedure_id,
|
||||||
private: true,
|
private: true,
|
||||||
libelle: 'URL Espace de consultation',
|
libelle: 'URL Espace de consultation',
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace :'2018_07_31_nutriscore' do
|
||||||
end
|
end
|
||||||
|
|
||||||
discard_source_champ(
|
discard_source_champ(
|
||||||
TypesDeChamp::TextTypeDeChamp.new(
|
TypeDeChamp.new(
|
||||||
type_champ: 'text',
|
type_champ: 'text',
|
||||||
order_place: siret_order_place,
|
order_place: siret_order_place,
|
||||||
libelle: 'Numéro SIRET'
|
libelle: 'Numéro SIRET'
|
||||||
|
@ -42,7 +42,7 @@ namespace :'2018_07_31_nutriscore' do
|
||||||
)
|
)
|
||||||
|
|
||||||
discard_source_champ(
|
discard_source_champ(
|
||||||
TypesDeChamp::TextTypeDeChamp.new(
|
TypeDeChamp.new(
|
||||||
type_champ: 'text',
|
type_champ: 'text',
|
||||||
order_place: fonction_order_place,
|
order_place: fonction_order_place,
|
||||||
libelle: 'Fonction'
|
libelle: 'Fonction'
|
||||||
|
@ -50,7 +50,7 @@ namespace :'2018_07_31_nutriscore' do
|
||||||
)
|
)
|
||||||
|
|
||||||
compute_destination_champ(
|
compute_destination_champ(
|
||||||
TypesDeChamp::TextTypeDeChamp.new(
|
TypeDeChamp.new(
|
||||||
type_champ: 'text',
|
type_champ: 'text',
|
||||||
order_place: fonction_order_place,
|
order_place: fonction_order_place,
|
||||||
libelle: 'Fonction',
|
libelle: 'Fonction',
|
||||||
|
@ -66,7 +66,7 @@ namespace :'2018_07_31_nutriscore' do
|
||||||
end
|
end
|
||||||
|
|
||||||
compute_destination_champ(
|
compute_destination_champ(
|
||||||
TypesDeChamp::SiretTypeDeChamp.new(
|
TypeDeChamp.new(
|
||||||
type_champ: 'siret',
|
type_champ: 'siret',
|
||||||
order_place: siret_order_place,
|
order_place: siret_order_place,
|
||||||
libelle: 'Numéro SIRET'
|
libelle: 'Numéro SIRET'
|
||||||
|
@ -80,7 +80,7 @@ namespace :'2018_07_31_nutriscore' do
|
||||||
end
|
end
|
||||||
|
|
||||||
compute_destination_champ(
|
compute_destination_champ(
|
||||||
TypesDeChamp::HeaderSectionTypeDeChamp.new(
|
TypeDeChamp.new(
|
||||||
type_champ: 'header_section',
|
type_champ: 'header_section',
|
||||||
order_place: 18,
|
order_place: 18,
|
||||||
libelle: 'PARTIE 3 : ZONE GEOGRAPHIQUE'
|
libelle: 'PARTIE 3 : ZONE GEOGRAPHIQUE'
|
||||||
|
@ -90,7 +90,7 @@ namespace :'2018_07_31_nutriscore' do
|
||||||
end
|
end
|
||||||
|
|
||||||
compute_destination_champ(
|
compute_destination_champ(
|
||||||
TypesDeChamp::MultipleDropDownListTypeDeChamp.new(
|
TypeDeChamp.new(
|
||||||
type_champ: 'multiple_drop_down_list',
|
type_champ: 'multiple_drop_down_list',
|
||||||
order_place: 19,
|
order_place: 19,
|
||||||
libelle: 'Pays de commercialisation',
|
libelle: 'Pays de commercialisation',
|
||||||
|
|
51
lib/tasks/2018_09_20_procedure_presentation_entreprise.rake
Normal file
51
lib/tasks/2018_09_20_procedure_presentation_entreprise.rake
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
namespace :'2018_09_20_procedure_presentation_entreprise' do
|
||||||
|
task run: :environment do
|
||||||
|
Class.new do
|
||||||
|
def run
|
||||||
|
fix_displayed_fields
|
||||||
|
fix_sort
|
||||||
|
fix_filters
|
||||||
|
end
|
||||||
|
|
||||||
|
def fix_displayed_fields
|
||||||
|
ProcedurePresentation.where(%q`displayed_fields @> '[{"table": "entreprise"}]'`).each do |procedure_presentation|
|
||||||
|
procedure_presentation.displayed_fields.each { |field| entreprise_to_etablissement(field) }
|
||||||
|
|
||||||
|
procedure_presentation.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fix_sort
|
||||||
|
ProcedurePresentation.where(%q`sort @> '{"table": "entreprise"}'`).each do |procedure_presentation|
|
||||||
|
entreprise_to_etablissement(procedure_presentation['sort'])
|
||||||
|
|
||||||
|
procedure_presentation.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fix_filters
|
||||||
|
ProcedurePresentation.find_by_sql(
|
||||||
|
<<~SQL
|
||||||
|
SELECT procedure_presentations.*, array_agg(key) as keys
|
||||||
|
FROM procedure_presentations, LATERAL jsonb_each(filters)
|
||||||
|
WHERE value @> '[{"table": "entreprise"}]'
|
||||||
|
GROUP BY id;
|
||||||
|
SQL
|
||||||
|
).each do |procedure_presentation|
|
||||||
|
procedure_presentation.keys.each do |key|
|
||||||
|
procedure_presentation.filters[key].each { |filter| entreprise_to_etablissement(filter) }
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure_presentation.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def entreprise_to_etablissement(field)
|
||||||
|
if field['table'] == 'entreprise'
|
||||||
|
field['table'] = 'etablissement'
|
||||||
|
field['column'] = "entreprise_#{field['column']}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end.new.run
|
||||||
|
end
|
||||||
|
end
|
|
@ -57,7 +57,7 @@ module Tasks
|
||||||
|
|
||||||
def type_de_champ_to_expectation(tdc)
|
def type_de_champ_to_expectation(tdc)
|
||||||
if tdc.present?
|
if tdc.present?
|
||||||
expectation = tdc.as_json(only: [:libelle, :type, :type_champ, :mandatory])
|
expectation = tdc.as_json(only: [:libelle, :type_champ, :mandatory])
|
||||||
expectation['drop_down'] = tdc.drop_down_list.presence&.options&.presence
|
expectation['drop_down'] = tdc.drop_down_list.presence&.options&.presence
|
||||||
expectation
|
expectation
|
||||||
else
|
else
|
||||||
|
@ -107,9 +107,6 @@ module Tasks
|
||||||
if actual_tdc.libelle != expected_tdc['libelle']
|
if actual_tdc.libelle != expected_tdc['libelle']
|
||||||
errors.append("incorrect libelle #{actual_tdc.libelle} (expected #{expected_tdc['libelle']})")
|
errors.append("incorrect libelle #{actual_tdc.libelle} (expected #{expected_tdc['libelle']})")
|
||||||
end
|
end
|
||||||
if actual_tdc.type != expected_tdc['type']
|
|
||||||
errors.append("incorrect type #{actual_tdc.type} (expected #{expected_tdc['type']})")
|
|
||||||
end
|
|
||||||
if actual_tdc.type_champ != expected_tdc['type_champ']
|
if actual_tdc.type_champ != expected_tdc['type_champ']
|
||||||
errors.append("incorrect type champ #{actual_tdc.type_champ} (expected #{expected_tdc['type_champ']})")
|
errors.append("incorrect type champ #{actual_tdc.type_champ} (expected #{expected_tdc['type_champ']})")
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,6 +22,14 @@ FactoryBot.define do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :simple_procedure do
|
||||||
|
after(:build) do |procedure, _evaluator|
|
||||||
|
procedure.for_individual = true
|
||||||
|
procedure.types_de_champ << create(:type_de_champ, libelle: 'Texte obligatoire', mandatory: true)
|
||||||
|
procedure.publish!(generate(:published_path))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
after(:build) do |procedure, _evaluator|
|
after(:build) do |procedure, _evaluator|
|
||||||
if procedure.module_api_carto.nil?
|
if procedure.module_api_carto.nil?
|
||||||
module_api_carto = create(:module_api_carto)
|
module_api_carto = create(:module_api_carto)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
FactoryBot.define do
|
FactoryBot.define do
|
||||||
factory :type_de_champ, class: 'TypesDeChamp::TextTypeDeChamp' do
|
factory :type_de_champ do
|
||||||
private { false }
|
private { false }
|
||||||
|
|
||||||
# Previous line is kept blank so that rubocop does not complain
|
# Previous line is kept blank so that rubocop does not complain
|
||||||
|
@ -9,79 +9,79 @@ FactoryBot.define do
|
||||||
order_place { 1 }
|
order_place { 1 }
|
||||||
mandatory { false }
|
mandatory { false }
|
||||||
|
|
||||||
factory :type_de_champ_text, class: 'TypesDeChamp::TextTypeDeChamp' do
|
factory :type_de_champ_text do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:text) }
|
type_champ { TypeDeChamp.type_champs.fetch(:text) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_textarea, class: 'TypesDeChamp::TextareaTypeDeChamp' do
|
factory :type_de_champ_textarea do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:textarea) }
|
type_champ { TypeDeChamp.type_champs.fetch(:textarea) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_number, class: 'TypesDeChamp::NumberTypeDeChamp' do
|
factory :type_de_champ_number do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:number) }
|
type_champ { TypeDeChamp.type_champs.fetch(:number) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_checkbox, class: 'TypesDeChamp::CheckboxTypeDeChamp' do
|
factory :type_de_champ_checkbox do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:checkbox) }
|
type_champ { TypeDeChamp.type_champs.fetch(:checkbox) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_civilite, class: 'TypesDeChamp::CiviliteTypeDeChamp' do
|
factory :type_de_champ_civilite do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:civilite) }
|
type_champ { TypeDeChamp.type_champs.fetch(:civilite) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_email, class: 'TypesDeChamp::EmailTypeDeChamp' do
|
factory :type_de_champ_email do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:email) }
|
type_champ { TypeDeChamp.type_champs.fetch(:email) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_phone, class: 'TypesDeChamp::PhoneTypeDeChamp' do
|
factory :type_de_champ_phone do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:phone) }
|
type_champ { TypeDeChamp.type_champs.fetch(:phone) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_address, class: 'TypesDeChamp::AddressTypeDeChamp' do
|
factory :type_de_champ_address do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:address) }
|
type_champ { TypeDeChamp.type_champs.fetch(:address) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_yes_no, class: 'TypesDeChamp::YesNoTypeDeChamp' do
|
factory :type_de_champ_yes_no do
|
||||||
libelle { 'Yes/no' }
|
libelle { 'Yes/no' }
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:yes_no) }
|
type_champ { TypeDeChamp.type_champs.fetch(:yes_no) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_date, class: 'TypesDeChamp::DateTypeDeChamp' do
|
factory :type_de_champ_date do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:date) }
|
type_champ { TypeDeChamp.type_champs.fetch(:date) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_datetime, class: 'TypesDeChamp::DatetimeTypeDeChamp' do
|
factory :type_de_champ_datetime do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:datetime) }
|
type_champ { TypeDeChamp.type_champs.fetch(:datetime) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_drop_down_list, class: 'TypesDeChamp::DropDownListTypeDeChamp' do
|
factory :type_de_champ_drop_down_list do
|
||||||
libelle { 'Menu déroulant' }
|
libelle { 'Menu déroulant' }
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:drop_down_list) }
|
type_champ { TypeDeChamp.type_champs.fetch(:drop_down_list) }
|
||||||
drop_down_list { create(:drop_down_list) }
|
drop_down_list { create(:drop_down_list) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_multiple_drop_down_list, class: 'TypesDeChamp::MultipleDropDownListTypeDeChamp' do
|
factory :type_de_champ_multiple_drop_down_list do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:multiple_drop_down_list) }
|
type_champ { TypeDeChamp.type_champs.fetch(:multiple_drop_down_list) }
|
||||||
drop_down_list { create(:drop_down_list) }
|
drop_down_list { create(:drop_down_list) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_linked_drop_down_list, class: 'TypesDeChamp::LinkedDropDownListTypeDeChamp' do
|
factory :type_de_champ_linked_drop_down_list do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:linked_drop_down_list) }
|
type_champ { TypeDeChamp.type_champs.fetch(:linked_drop_down_list) }
|
||||||
drop_down_list { create(:drop_down_list) }
|
drop_down_list { create(:drop_down_list) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_pays, class: 'TypesDeChamp::PaysTypeDeChamp' do
|
factory :type_de_champ_pays do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:pays) }
|
type_champ { TypeDeChamp.type_champs.fetch(:pays) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_regions, class: 'TypesDeChamp::RegionTypeDeChamp' do
|
factory :type_de_champ_regions do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:regions) }
|
type_champ { TypeDeChamp.type_champs.fetch(:regions) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_departements, class: 'TypesDeChamp::DepartementTypeDeChamp' do
|
factory :type_de_champ_departements do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:departements) }
|
type_champ { TypeDeChamp.type_champs.fetch(:departements) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_engagement, class: 'TypesDeChamp::EngagementTypeDeChamp' do
|
factory :type_de_champ_engagement do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:engagement) }
|
type_champ { TypeDeChamp.type_champs.fetch(:engagement) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_header_section, class: 'TypesDeChamp::HeaderSectionTypeDeChamp' do
|
factory :type_de_champ_header_section do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:header_section) }
|
type_champ { TypeDeChamp.type_champs.fetch(:header_section) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_explication, class: 'TypesDeChamp::ExplicationTypeDeChamp' do
|
factory :type_de_champ_explication do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:explication) }
|
type_champ { TypeDeChamp.type_champs.fetch(:explication) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_dossier_link, class: 'TypesDeChamp::DossierLinkTypeDeChamp' do
|
factory :type_de_champ_dossier_link do
|
||||||
libelle { 'Référence autre dossier' }
|
libelle { 'Référence autre dossier' }
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:dossier_link) }
|
type_champ { TypeDeChamp.type_champs.fetch(:dossier_link) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_piece_justificative, class: 'TypesDeChamp::PieceJustificativeTypeDeChamp' do
|
factory :type_de_champ_piece_justificative do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:piece_justificative) }
|
type_champ { TypeDeChamp.type_champs.fetch(:piece_justificative) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_siret, class: 'TypesDeChamp::SiretTypeDeChamp' do
|
factory :type_de_champ_siret do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:siret) }
|
type_champ { TypeDeChamp.type_champs.fetch(:siret) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
|
require 'features/new_user/dossier_shared_examples.rb'
|
||||||
|
|
||||||
describe 'Dossier details:' do
|
describe 'Dossier details:' do
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:simple_procedure) do
|
let(:procedure) { create(:simple_procedure) }
|
||||||
tdcs = [create(:type_de_champ, libelle: 'texte obligatoire')]
|
let(:dossier) { create(:dossier, :en_construction, :for_individual, :with_commentaires, user: user, procedure: procedure) }
|
||||||
create(:procedure, :published, :for_individual, types_de_champ: tdcs)
|
|
||||||
end
|
|
||||||
let(:dossier) { create(:dossier, :en_construction, :for_individual, :with_commentaires, user: user, procedure: simple_procedure) }
|
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, true)
|
Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, true)
|
||||||
|
visit_dossier dossier
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'the user can see the summary of the dossier status' do
|
scenario 'the user can see the summary of the dossier status' do
|
||||||
visit_dossier dossier
|
|
||||||
|
|
||||||
expect(page).to have_current_path(dossier_path(dossier))
|
expect(page).to have_current_path(dossier_path(dossier))
|
||||||
expect(page).to have_content(dossier.id)
|
expect(page).to have_content(dossier.id)
|
||||||
expect(page).to have_selector('.status-explanation')
|
expect(page).to have_selector('.status-explanation')
|
||||||
|
@ -20,68 +18,29 @@ describe 'Dossier details:' do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "the user can see the mean time they are expected to wait" do
|
describe "the user can see the mean time they are expected to wait" do
|
||||||
context "the dossier is in construction" do
|
context "when the dossier is in construction" do
|
||||||
before do
|
before do
|
||||||
other_dossier = create(:dossier, :accepte, :for_individual, procedure: simple_procedure, en_construction_at: 10.days.ago, en_instruction_at: Time.now)
|
other_dossier = create(:dossier, :accepte, :for_individual, procedure: procedure, en_construction_at: 10.days.ago, en_instruction_at: Time.now)
|
||||||
|
visit dossier_path(dossier)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "show the proper wait time" do
|
it { expect(page).to have_text("Le temps moyen de vérification pour cette démarche est de 10 jours.") }
|
||||||
visit_dossier dossier
|
|
||||||
|
|
||||||
expect(page).to have_text("Le temps moyen de vérification pour cette démarche est de 10 jours.")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "the dossier is in instruction" do
|
context "when the dossier is in instruction" do
|
||||||
let(:dossier) { create(:dossier, :en_instruction, :for_individual, :with_commentaires, user: user, procedure: simple_procedure) }
|
let(:dossier) { create(:dossier, :en_instruction, :for_individual, :with_commentaires, user: user, procedure: procedure) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
other_dossier = create(:dossier, :accepte, :for_individual, procedure: simple_procedure, en_instruction_at: 2.months.ago, processed_at: Time.now)
|
other_dossier = create(:dossier, :accepte, :for_individual, procedure: procedure, en_instruction_at: 2.months.ago, processed_at: Time.now)
|
||||||
|
visit dossier_path(dossier)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "show the proper wait time" do
|
it { expect(page).to have_text("Le temps moyen d’instruction pour cette démarche est de 2 mois.") }
|
||||||
visit_dossier dossier
|
|
||||||
|
|
||||||
expect(page).to have_text("Le temps moyen d’instruction pour cette démarche est de 2 mois.")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'the user can see and edit dossier before instruction' do
|
it_behaves_like 'the user can edit the submitted demande'
|
||||||
visit_dossier dossier
|
it_behaves_like 'the user can send messages to the instructeur'
|
||||||
click_on 'Demande'
|
|
||||||
|
|
||||||
expect(page).to have_current_path(demande_dossier_path(dossier))
|
|
||||||
click_on 'Modifier le dossier'
|
|
||||||
|
|
||||||
expect(page).to have_current_path(modifier_dossier_path(dossier))
|
|
||||||
fill_in('texte obligatoire', with: 'Nouveau texte')
|
|
||||||
click_on 'Enregistrer les modifications du dossier'
|
|
||||||
|
|
||||||
expect(page).to have_current_path(demande_dossier_path(dossier))
|
|
||||||
expect(page).to have_content('Nouveau texte')
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with messages' do
|
|
||||||
let!(:commentaire) { create(:commentaire, dossier: dossier, email: 'instructeur@exemple.fr', body: 'Message envoyé à l’usager') }
|
|
||||||
let(:message_body) { 'Message envoyé à l’instructeur' }
|
|
||||||
|
|
||||||
scenario 'the user can send a message' do
|
|
||||||
visit_dossier dossier
|
|
||||||
click_on 'Messagerie'
|
|
||||||
|
|
||||||
expect(page).to have_current_path(messagerie_dossier_path(dossier))
|
|
||||||
expect(page).to have_content(commentaire.body)
|
|
||||||
|
|
||||||
fill_in 'commentaire_body', with: message_body
|
|
||||||
click_on 'Envoyer'
|
|
||||||
|
|
||||||
expect(page).to have_current_path(messagerie_dossier_path(dossier))
|
|
||||||
expect(page).to have_content('Message envoyé')
|
|
||||||
expect(page).to have_content(commentaire.body)
|
|
||||||
expect(page).to have_content(message_body)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
|
41
spec/features/new_user/dossier_shared_examples.rb
Normal file
41
spec/features/new_user/dossier_shared_examples.rb
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
RSpec.shared_examples 'the user can edit the submitted demande' do
|
||||||
|
scenario js: true do
|
||||||
|
visit dossier_path(dossier)
|
||||||
|
|
||||||
|
expect(page).to have_current_path(dossier_path(dossier))
|
||||||
|
click_on 'Demande'
|
||||||
|
|
||||||
|
expect(page).to have_current_path(demande_dossier_path(dossier))
|
||||||
|
click_on 'Modifier le dossier'
|
||||||
|
|
||||||
|
expect(page).to have_current_path(modifier_dossier_path(dossier))
|
||||||
|
fill_in('Texte obligatoire', with: 'Nouveau texte')
|
||||||
|
click_on 'Enregistrer les modifications du dossier'
|
||||||
|
|
||||||
|
expect(page).to have_current_path(demande_dossier_path(dossier))
|
||||||
|
expect(page).to have_content('Nouveau texte')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
RSpec.shared_examples 'the user can send messages to the instructeur' do
|
||||||
|
let!(:commentaire) { create(:commentaire, dossier: dossier, email: 'instructeur@exemple.fr', body: 'Message envoyé à l’usager') }
|
||||||
|
let(:message_body) { 'Message envoyé à l’instructeur' }
|
||||||
|
|
||||||
|
scenario js: true do
|
||||||
|
visit dossier_path(dossier)
|
||||||
|
|
||||||
|
expect(page).to have_current_path(dossier_path(dossier))
|
||||||
|
click_on 'Messagerie'
|
||||||
|
|
||||||
|
expect(page).to have_current_path(messagerie_dossier_path(dossier))
|
||||||
|
expect(page).to have_content(commentaire.body)
|
||||||
|
|
||||||
|
fill_in 'commentaire_body', with: message_body
|
||||||
|
click_on 'Envoyer'
|
||||||
|
|
||||||
|
expect(page).to have_current_path(messagerie_dossier_path(dossier))
|
||||||
|
expect(page).to have_content('Message envoyé')
|
||||||
|
expect(page).to have_content(commentaire.body)
|
||||||
|
expect(page).to have_content(message_body)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,19 +1,20 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
require 'features/new_user/dossier_shared_examples.rb'
|
||||||
|
|
||||||
feature 'Invitations' do
|
feature 'Invitations' do
|
||||||
let(:user) { create(:user) }
|
let(:owner) { create(:user) }
|
||||||
let(:invited_user) { create(:user, email: 'user_invite@exemple.fr') }
|
let(:invited_user) { create(:user, email: 'user_invite@exemple.fr') }
|
||||||
let(:procedure) { create(:procedure, :published, :with_type_de_champ) }
|
let(:procedure) { create(:simple_procedure) }
|
||||||
let(:invite) { create(:invite_user, user: invited_user, dossier: dossier) }
|
let(:invite) { create(:invite_user, user: invited_user, dossier: dossier) }
|
||||||
|
|
||||||
context 'when the dossier is a brouillon' do
|
context 'when the dossier is a brouillon' do
|
||||||
let!(:dossier) { create(:dossier, :for_individual, state: Dossier.states.fetch(:brouillon), user: user, procedure: procedure) }
|
let!(:dossier) { create(:dossier, :for_individual, state: Dossier.states.fetch(:brouillon), user: owner, procedure: procedure) }
|
||||||
|
|
||||||
scenario 'on the form, a user can invite another user to collaborate on the dossier', js: true do
|
scenario 'on the form, the owner of a dossier can invite another user to collaborate on the dossier', js: true do
|
||||||
log_in(user)
|
log_in(owner)
|
||||||
navigate_to_brouillon(dossier)
|
navigate_to_brouillon(dossier)
|
||||||
|
|
||||||
fill_in 'Libelle du champ', with: 'Some edited value'
|
fill_in 'Texte obligatoire', with: 'Some edited value'
|
||||||
send_invite_to "user_invite@exemple.fr"
|
send_invite_to "user_invite@exemple.fr"
|
||||||
|
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
||||||
|
@ -21,7 +22,7 @@ feature 'Invitations' do
|
||||||
expect(page).to have_text("user_invite@exemple.fr")
|
expect(page).to have_text("user_invite@exemple.fr")
|
||||||
|
|
||||||
# Ensure unsaved edits to the form are not lost
|
# Ensure unsaved edits to the form are not lost
|
||||||
expect(page).to have_field('Libelle du champ', with: 'Some edited value')
|
expect(page).to have_field('Texte obligatoire', with: 'Some edited value')
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when inviting someone without an existing account' do
|
context 'when inviting someone without an existing account' do
|
||||||
|
@ -51,24 +52,19 @@ feature 'Invitations' do
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'an invited user can see and edit the draft', js: true do
|
scenario 'an invited user can see and edit the draft', js: true do
|
||||||
visit users_dossiers_invite_path(invite)
|
navigate_to_invited_dossier(invite)
|
||||||
expect(page).to have_current_path(new_user_session_path)
|
|
||||||
|
|
||||||
submit_login_form(invited_user.email, invited_user.password)
|
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
||||||
|
|
||||||
expect(page).to have_no_selector('.button.invite-user-action')
|
expect(page).to have_no_selector('.button.invite-user-action')
|
||||||
|
|
||||||
fill_in 'Libelle du champ', with: 'Some edited value'
|
fill_in 'Texte obligatoire', with: 'Some edited value'
|
||||||
click_button 'Enregistrer le brouillon'
|
click_button 'Enregistrer le brouillon'
|
||||||
expect(page).to have_text('Votre brouillon a bien été sauvegardé')
|
expect(page).to have_text('Votre brouillon a bien été sauvegardé')
|
||||||
expect(page).to have_field('Libelle du champ', with: 'Some edited value')
|
expect(page).to have_field('Texte obligatoire', with: 'Some edited value')
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'an invited user cannot submit the draft' do
|
scenario 'an invited user cannot submit the draft' do
|
||||||
visit users_dossiers_invite_path(invite)
|
navigate_to_invited_dossier(invite)
|
||||||
expect(page).to have_current_path(new_user_session_path)
|
|
||||||
|
|
||||||
submit_login_form(invited_user.email, invited_user.password)
|
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
||||||
|
|
||||||
expect(page).to have_button('Soumettre le dossier', disabled: true)
|
expect(page).to have_button('Soumettre le dossier', disabled: true)
|
||||||
|
@ -77,10 +73,39 @@ feature 'Invitations' do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the dossier is en_construction' do
|
context 'when the dossier is en_construction' do
|
||||||
let!(:dossier) { create(:dossier, :for_individual, :en_construction, user: user, procedure: procedure) }
|
let!(:dossier) { create(:dossier, :for_individual, :en_construction, user: owner, procedure: procedure) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
Flipflop::FeatureSet.current.test!.switch!(:new_dossier_details, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'on dossier details, the owner of a dossier can invite another user to collaborate on the dossier', js: true do
|
||||||
|
log_in(owner)
|
||||||
|
navigate_to_dossier(dossier)
|
||||||
|
|
||||||
|
send_invite_to "user_invite@exemple.fr"
|
||||||
|
|
||||||
|
expect(page).to have_current_path(dossier_path(dossier))
|
||||||
|
expect(page).to have_text("Une invitation a été envoyée à user_invite@exemple.fr.")
|
||||||
|
expect(page).to have_text("user_invite@exemple.fr")
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'as an invited user' do
|
||||||
|
before do
|
||||||
|
navigate_to_invited_dossier(invite)
|
||||||
|
expect(page).to have_current_path(dossier_path(invite.dossier))
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'the user can edit the submitted demande'
|
||||||
|
it_behaves_like 'the user can send messages to the instructeur'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the dossier is en_construction (legacy UI)' do
|
||||||
|
let!(:dossier) { create(:dossier, :for_individual, :en_construction, user: owner, procedure: procedure) }
|
||||||
|
|
||||||
scenario 'on dossier details, a user can invite another user to collaborate on the dossier', js: true do
|
scenario 'on dossier details, a user can invite another user to collaborate on the dossier', js: true do
|
||||||
log_in(user)
|
log_in(owner)
|
||||||
navigate_to_recapitulatif(dossier)
|
navigate_to_recapitulatif(dossier)
|
||||||
|
|
||||||
legacy_send_invite_to "user_invite@exemple.fr"
|
legacy_send_invite_to "user_invite@exemple.fr"
|
||||||
|
@ -105,7 +130,7 @@ feature 'Invitations' do
|
||||||
visit brouillon_dossier_path(dossier)
|
visit brouillon_dossier_path(dossier)
|
||||||
|
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
||||||
fill_in "Libelle du champ", with: "Some edited value"
|
fill_in "Texte obligatoire", with: "Some edited value"
|
||||||
click_button "Enregistrer les modifications du dossier"
|
click_button "Enregistrer les modifications du dossier"
|
||||||
|
|
||||||
expect(page).to have_current_path(users_dossiers_invite_path(invite))
|
expect(page).to have_current_path(users_dossiers_invite_path(invite))
|
||||||
|
@ -134,6 +159,18 @@ feature 'Invitations' do
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def navigate_to_dossier(dossier)
|
||||||
|
expect(page).to have_current_path(dossiers_path)
|
||||||
|
click_on(dossier.id)
|
||||||
|
expect(page).to have_current_path(dossier_path(dossier))
|
||||||
|
end
|
||||||
|
|
||||||
|
def navigate_to_invited_dossier(invite)
|
||||||
|
visit users_dossiers_invite_path(invite)
|
||||||
|
expect(page).to have_current_path(new_user_session_path)
|
||||||
|
submit_login_form(invited_user.email, invited_user.password)
|
||||||
|
end
|
||||||
|
|
||||||
def navigate_to_recapitulatif(dossier)
|
def navigate_to_recapitulatif(dossier)
|
||||||
expect(page).to have_current_path(dossiers_path)
|
expect(page).to have_current_path(dossiers_path)
|
||||||
click_on(dossier.id)
|
click_on(dossier.id)
|
||||||
|
|
|
@ -7,6 +7,7 @@ RSpec.describe AutoReceiveDossiersForProcedureJob, type: :job do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Timecop.freeze(date)
|
Timecop.freeze(date)
|
||||||
|
create(:attestation_template, procedure: nouveau_dossier1.procedure)
|
||||||
AutoReceiveDossiersForProcedureJob.new.perform(procedure_id, state)
|
AutoReceiveDossiersForProcedureJob.new.perform(procedure_id, state)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -41,10 +42,12 @@ RSpec.describe AutoReceiveDossiersForProcedureJob, type: :job do
|
||||||
it { expect(nouveau_dossier1.reload.accepte?).to be true }
|
it { expect(nouveau_dossier1.reload.accepte?).to be true }
|
||||||
it { expect(nouveau_dossier1.reload.en_instruction_at).to eq(date) }
|
it { expect(nouveau_dossier1.reload.en_instruction_at).to eq(date) }
|
||||||
it { expect(nouveau_dossier1.reload.processed_at).to eq(date) }
|
it { expect(nouveau_dossier1.reload.processed_at).to eq(date) }
|
||||||
|
it { expect(nouveau_dossier1.reload.attestation).to be_present }
|
||||||
|
|
||||||
it { expect(nouveau_dossier2.reload.accepte?).to be true }
|
it { expect(nouveau_dossier2.reload.accepte?).to be true }
|
||||||
it { expect(nouveau_dossier2.reload.en_instruction_at).to eq(date) }
|
it { expect(nouveau_dossier2.reload.en_instruction_at).to eq(date) }
|
||||||
it { expect(nouveau_dossier2.reload.processed_at).to eq(date) }
|
it { expect(nouveau_dossier2.reload.processed_at).to eq(date) }
|
||||||
|
it { expect(nouveau_dossier2.reload.attestation).to be_present }
|
||||||
|
|
||||||
it { expect(dossier_recu.reload.en_instruction?).to be true }
|
it { expect(dossier_recu.reload.en_instruction?).to be true }
|
||||||
it { expect(dossier_recu.reload.en_instruction_at).to eq(instruction_date) }
|
it { expect(dossier_recu.reload.en_instruction_at).to eq(instruction_date) }
|
||||||
|
|
|
@ -3,7 +3,7 @@ describe '2018_05_14_add_annotation_privee_to_procedure' do
|
||||||
let!(:procedure) do
|
let!(:procedure) do
|
||||||
procedure = create(:procedure)
|
procedure = create(:procedure)
|
||||||
10.times do |i|
|
10.times do |i|
|
||||||
TypesDeChamp::NumberTypeDeChamp.create(
|
TypeDeChamp.create(
|
||||||
procedure: procedure,
|
procedure: procedure,
|
||||||
private: false,
|
private: false,
|
||||||
libelle: 'libelle',
|
libelle: 'libelle',
|
||||||
|
@ -11,7 +11,7 @@ describe '2018_05_14_add_annotation_privee_to_procedure' do
|
||||||
type_champ: 'number'
|
type_champ: 'number'
|
||||||
)
|
)
|
||||||
|
|
||||||
TypesDeChamp::NumberTypeDeChamp.create(
|
TypeDeChamp.create(
|
||||||
procedure: procedure,
|
procedure: procedure,
|
||||||
private: true,
|
private: true,
|
||||||
libelle: 'libelle',
|
libelle: 'libelle',
|
||||||
|
|
|
@ -95,7 +95,7 @@ describe '2018_07_31_nutriscore' do
|
||||||
context 'with champ type mismatch' do
|
context 'with champ type mismatch' do
|
||||||
let!(:type_champ_to) { create(:type_de_champ_text, order_place: 1, libelle: 'texte', procedure: proc_to) }
|
let!(:type_champ_to) { create(:type_de_champ_text, order_place: 1, libelle: 'texte', procedure: proc_to) }
|
||||||
|
|
||||||
it { expect { run_task }.to raise_exception(/incorrect type TypesDeChamp::TextareaTypeDeChamp \(expected TypesDeChamp::TextTypeDeChamp\), incorrect type champ textarea \(expected text\)$/) }
|
it { expect { run_task }.to raise_exception(/incorrect type champ textarea \(expected text\)$/) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with champ mandatoriness mismatch' do
|
context 'with champ mandatoriness mismatch' do
|
||||||
|
@ -114,13 +114,13 @@ describe '2018_07_31_nutriscore' do
|
||||||
context 'with siret mismatch on source' do
|
context 'with siret mismatch on source' do
|
||||||
let!(:type_champ_siret_from) { create(:type_de_champ_textarea, order_place: 2, libelle: 'Numéro SIRET', procedure: proc_from) }
|
let!(:type_champ_siret_from) { create(:type_de_champ_textarea, order_place: 2, libelle: 'Numéro SIRET', procedure: proc_from) }
|
||||||
|
|
||||||
it { expect { run_task }.to raise_exception(/incorrect type TypesDeChamp::TextareaTypeDeChamp \(expected TypesDeChamp::TextTypeDeChamp\), incorrect type champ textarea \(expected text\)$/) }
|
it { expect { run_task }.to raise_exception(/incorrect type champ textarea \(expected text\)$/) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with siret mismatch on destination' do
|
context 'with siret mismatch on destination' do
|
||||||
let!(:type_champ_siret_to) { create(:type_de_champ_text, order_place: 2, libelle: 'Numéro SIRET', procedure: proc_to) }
|
let!(:type_champ_siret_to) { create(:type_de_champ_text, order_place: 2, libelle: 'Numéro SIRET', procedure: proc_to) }
|
||||||
|
|
||||||
it { expect { run_task }.to raise_exception(/incorrect type TypesDeChamp::TextTypeDeChamp \(expected TypesDeChamp::SiretTypeDeChamp\), incorrect type champ text \(expected siret\)$/) }
|
it { expect { run_task }.to raise_exception(/incorrect type champ text \(expected siret\)$/) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -750,7 +750,7 @@ describe Dossier do
|
||||||
it { expect(dossier.get_value('self', 'created_at')).to eq(dossier.created_at) }
|
it { expect(dossier.get_value('self', 'created_at')).to eq(dossier.created_at) }
|
||||||
it { expect(dossier.get_value('user', 'email')).to eq(user.email) }
|
it { expect(dossier.get_value('user', 'email')).to eq(user.email) }
|
||||||
it { expect(dossier.get_value('france_connect_information', 'gender')).to eq(user.france_connect_information.gender) }
|
it { expect(dossier.get_value('france_connect_information', 'gender')).to eq(user.france_connect_information.gender) }
|
||||||
it { expect(dossier.get_value('entreprise', 'siren')).to eq(dossier.etablissement.entreprise_siren) }
|
it { expect(dossier.get_value('etablissement', 'entreprise_siren')).to eq(dossier.etablissement.entreprise_siren) }
|
||||||
it { expect(dossier.get_value('etablissement', 'siret')).to eq(dossier.etablissement.siret) }
|
it { expect(dossier.get_value('etablissement', 'siret')).to eq(dossier.etablissement.siret) }
|
||||||
it { expect(dossier.get_value('type_de_champ', @champ_public.type_de_champ.id.to_s)).to eq(dossier.champs.first.value) }
|
it { expect(dossier.get_value('type_de_champ', @champ_public.type_de_champ.id.to_s)).to eq(dossier.champs.first.value) }
|
||||||
it { expect(dossier.get_value('type_de_champ_private', @champ_private.type_de_champ.id.to_s)).to eq(dossier.champs_private.first.value) }
|
it { expect(dossier.get_value('type_de_champ_private', @champ_private.type_de_champ.id.to_s)).to eq(dossier.champs_private.first.value) }
|
||||||
|
|
|
@ -21,7 +21,7 @@ shared_examples 'type_de_champ_spec' do
|
||||||
type_de_champ = create(:"type_de_champ_#{type_champ}")
|
type_de_champ = create(:"type_de_champ_#{type_champ}")
|
||||||
champ = type_de_champ.champ.create
|
champ = type_de_champ.champ.create
|
||||||
|
|
||||||
expect(type_de_champ.class.name).to match(/^TypesDeChamp::/)
|
expect(type_de_champ.dynamic_type.class.name).to match(/^TypesDeChamp::/)
|
||||||
expect(champ.class.name).to match(/^Champs::/)
|
expect(champ.class.name).to match(/^Champs::/)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,12 +3,14 @@ require 'spec_helper'
|
||||||
describe TypesDeChamp::LinkedDropDownListTypeDeChamp do
|
describe TypesDeChamp::LinkedDropDownListTypeDeChamp do
|
||||||
describe '#unpack_options' do
|
describe '#unpack_options' do
|
||||||
let(:drop_down_list) { build(:drop_down_list, value: menu_options) }
|
let(:drop_down_list) { build(:drop_down_list, value: menu_options) }
|
||||||
let(:type_de_champ) { described_class.new(drop_down_list: drop_down_list) }
|
let(:type_de_champ) { build(:type_de_champ_linked_drop_down_list, drop_down_list: drop_down_list) }
|
||||||
|
|
||||||
|
subject { type_de_champ.dynamic_type }
|
||||||
|
|
||||||
context 'with no options' do
|
context 'with no options' do
|
||||||
let(:menu_options) { '' }
|
let(:menu_options) { '' }
|
||||||
it { expect(type_de_champ.secondary_options).to eq({}) }
|
it { expect(subject.secondary_options).to eq({}) }
|
||||||
it { expect(type_de_champ.primary_options).to eq([]) }
|
it { expect(subject.primary_options).to eq([]) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with two primary options' do
|
context 'with two primary options' do
|
||||||
|
@ -25,7 +27,7 @@ describe TypesDeChamp::LinkedDropDownListTypeDeChamp do
|
||||||
end
|
end
|
||||||
|
|
||||||
it do
|
it do
|
||||||
expect(type_de_champ.secondary_options).to eq(
|
expect(subject.secondary_options).to eq(
|
||||||
{
|
{
|
||||||
'' => [],
|
'' => [],
|
||||||
'Primary 1' => [ '', 'secondary 1.1', 'secondary 1.2'],
|
'Primary 1' => [ '', 'secondary 1.1', 'secondary 1.2'],
|
||||||
|
@ -34,7 +36,7 @@ describe TypesDeChamp::LinkedDropDownListTypeDeChamp do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect(type_de_champ.primary_options).to eq([ '', 'Primary 1', 'Primary 2' ]) }
|
it { expect(subject.primary_options).to eq([ '', 'Primary 1', 'Primary 2' ]) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
29
spec/services/dossier_field_service_spec.rb
Normal file
29
spec/services/dossier_field_service_spec.rb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe DossierFieldService do
|
||||||
|
describe '#filtered_ids' do
|
||||||
|
let(:procedure) { create(:procedure) }
|
||||||
|
|
||||||
|
context 'for etablissement table' do
|
||||||
|
context 'for entreprise_date_creation column' do
|
||||||
|
let!(:kept_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, entreprise_date_creation: DateTime.new(2018, 6, 21))) }
|
||||||
|
let!(:discarded_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, entreprise_date_creation: DateTime.new(2008, 6, 21))) }
|
||||||
|
|
||||||
|
subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'etablissement', 'column' => 'entreprise_date_creation', 'value' => '21/6/2018' }]) }
|
||||||
|
|
||||||
|
it { is_expected.to contain_exactly(kept_dossier.id) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'for code_postal column' do
|
||||||
|
# All columns except entreprise_date_creation work exacly the same, just testing one
|
||||||
|
|
||||||
|
let!(:kept_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '75017')) }
|
||||||
|
let!(:discarded_dossier) { create(:dossier, procedure: procedure, etablissement: create(:etablissement, code_postal: '25000')) }
|
||||||
|
|
||||||
|
subject { described_class.filtered_ids(procedure.dossiers, [{ 'table' => 'etablissement', 'column' => 'code_postal', 'value' => '75017' }]) }
|
||||||
|
|
||||||
|
it { is_expected.to contain_exactly(kept_dossier.id) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue