commit
7587a9910b
37 changed files with 442 additions and 204 deletions
18
.rubocop.yml
18
.rubocop.yml
|
@ -1,15 +1,15 @@
|
||||||
require:
|
require:
|
||||||
- rubocop/rspec/focused
|
- rubocop-performance
|
||||||
|
- rubocop-rails
|
||||||
|
- rubocop-rspec
|
||||||
- ./lib/cops/add_concurrent_index.rb
|
- ./lib/cops/add_concurrent_index.rb
|
||||||
- ./lib/cops/application_name.rb
|
- ./lib/cops/application_name.rb
|
||||||
- ./lib/cops/unscoped.rb
|
- ./lib/cops/unscoped.rb
|
||||||
|
|
||||||
inherit_gem:
|
|
||||||
rubocop-rails_config:
|
|
||||||
- config/rails.yml
|
|
||||||
|
|
||||||
AllCops:
|
AllCops:
|
||||||
TargetRubyVersion: 2.7
|
TargetRubyVersion: 3.0
|
||||||
|
DisabledByDefault: true
|
||||||
|
SuggestExtensions: false
|
||||||
Exclude:
|
Exclude:
|
||||||
- "db/schema.rb"
|
- "db/schema.rb"
|
||||||
- "db/migrate/20190730153555_recreate_structure.rb"
|
- "db/migrate/20190730153555_recreate_structure.rb"
|
||||||
|
@ -644,6 +644,9 @@ Performance/RedundantMatch:
|
||||||
Performance/RedundantMerge:
|
Performance/RedundantMerge:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
|
Style/HashTransformValues:
|
||||||
|
Enabled: true
|
||||||
|
|
||||||
Style/RedundantSortBy:
|
Style/RedundantSortBy:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
|
@ -874,7 +877,7 @@ Rails/WhereExists:
|
||||||
Rails/WhereNot:
|
Rails/WhereNot:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
RSpec/Focused:
|
RSpec/Focus:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
Security/Eval:
|
Security/Eval:
|
||||||
|
@ -1373,4 +1376,3 @@ Style/YodaCondition:
|
||||||
|
|
||||||
Style/ZeroLengthPredicate:
|
Style/ZeroLengthPredicate:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
|
|
5
Gemfile
5
Gemfile
|
@ -111,8 +111,9 @@ group :development do
|
||||||
gem 'rack-mini-profiler'
|
gem 'rack-mini-profiler'
|
||||||
gem 'rails-erd', require: false # generates `doc/database_models.pdf`
|
gem 'rails-erd', require: false # generates `doc/database_models.pdf`
|
||||||
gem 'rubocop', require: false
|
gem 'rubocop', require: false
|
||||||
gem 'rubocop-rails_config'
|
gem 'rubocop-performance', require: false
|
||||||
gem 'rubocop-rspec-focused', require: false
|
gem 'rubocop-rails', require: false
|
||||||
|
gem 'rubocop-rspec', require: false
|
||||||
gem 'scss_lint', require: false
|
gem 'scss_lint', require: false
|
||||||
gem 'web-console'
|
gem 'web-console'
|
||||||
end
|
end
|
||||||
|
|
19
Gemfile.lock
19
Gemfile.lock
|
@ -620,8 +620,6 @@ GEM
|
||||||
unicode-display_width (>= 1.4.0, < 3.0)
|
unicode-display_width (>= 1.4.0, < 3.0)
|
||||||
rubocop-ast (1.4.1)
|
rubocop-ast (1.4.1)
|
||||||
parser (>= 2.7.1.5)
|
parser (>= 2.7.1.5)
|
||||||
rubocop-packaging (0.5.1)
|
|
||||||
rubocop (>= 0.89, < 2.0)
|
|
||||||
rubocop-performance (1.9.2)
|
rubocop-performance (1.9.2)
|
||||||
rubocop (>= 0.90.0, < 2.0)
|
rubocop (>= 0.90.0, < 2.0)
|
||||||
rubocop-ast (>= 0.4.0)
|
rubocop-ast (>= 0.4.0)
|
||||||
|
@ -629,15 +627,9 @@ GEM
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
rack (>= 1.1)
|
rack (>= 1.1)
|
||||||
rubocop (>= 0.90.0, < 2.0)
|
rubocop (>= 0.90.0, < 2.0)
|
||||||
rubocop-rails_config (1.3.1)
|
rubocop-rspec (2.4.0)
|
||||||
railties (>= 5.0)
|
rubocop (~> 1.0)
|
||||||
rubocop (>= 1.8)
|
rubocop-ast (>= 1.1.0)
|
||||||
rubocop-ast (>= 1.0.1)
|
|
||||||
rubocop-packaging (~> 0.5)
|
|
||||||
rubocop-performance (~> 1.3)
|
|
||||||
rubocop-rails (~> 2.0)
|
|
||||||
rubocop-rspec-focused (1.0.0)
|
|
||||||
rubocop (>= 0.51)
|
|
||||||
ruby-graphviz (1.2.5)
|
ruby-graphviz (1.2.5)
|
||||||
rexml
|
rexml
|
||||||
ruby-progressbar (1.11.0)
|
ruby-progressbar (1.11.0)
|
||||||
|
@ -874,8 +866,9 @@ DEPENDENCIES
|
||||||
rspec-rails
|
rspec-rails
|
||||||
rspec_junit_formatter
|
rspec_junit_formatter
|
||||||
rubocop
|
rubocop
|
||||||
rubocop-rails_config
|
rubocop-performance
|
||||||
rubocop-rspec-focused
|
rubocop-rails
|
||||||
|
rubocop-rspec
|
||||||
ruby-saml-idp
|
ruby-saml-idp
|
||||||
sanitize-url
|
sanitize-url
|
||||||
sassc-rails
|
sassc-rails
|
||||||
|
|
|
@ -295,7 +295,6 @@ $users-breakpoint: 950px;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-top: 13px;
|
margin-top: 13px;
|
||||||
color: #FFFFFF;
|
|
||||||
|
|
||||||
&.grey {
|
&.grey {
|
||||||
color: $g700;
|
color: $g700;
|
||||||
|
@ -303,15 +302,19 @@ $users-breakpoint: 950px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cta-panel-explanation {
|
.cta-panel-explanation {
|
||||||
font-size: 24px;
|
font-size: 22px;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
color: #FFFFFF;
|
|
||||||
|
|
||||||
&.grey {
|
&.grey {
|
||||||
color: $g700;
|
color: $g700;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.half .cta-panel-title,
|
||||||
|
.half .cta-panel-explanation {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.role-panel-title {
|
.role-panel-title {
|
||||||
font-size: 30px;
|
font-size: 30px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@ -357,7 +360,7 @@ $cta-panel-button-border-size: 2px;
|
||||||
@include vertical-padding(15px);
|
@include vertical-padding(15px);
|
||||||
display: block;
|
display: block;
|
||||||
border-radius: 100px;
|
border-radius: 100px;
|
||||||
font-size: 24px;
|
font-size: 22px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
|
|
@ -3,12 +3,17 @@ module Administrateurs
|
||||||
before_action :retrieve_procedure
|
before_action :retrieve_procedure
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@attestation_template = @procedure.attestation_template || AttestationTemplate.new(procedure: @procedure)
|
@attestation_template = build_attestation
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
attestation_template = @procedure.attestation_template
|
attestation_template = @procedure.draft_attestation_template.revise!
|
||||||
|
|
||||||
if attestation_template.update(activated_attestation_params)
|
if attestation_template.update(activated_attestation_params)
|
||||||
|
AttestationTemplate
|
||||||
|
.where(id: @procedure.revisions.pluck(:attestation_template_id).compact)
|
||||||
|
.update_all(activated: attestation_template.activated?)
|
||||||
|
|
||||||
flash.notice = "L'attestation a bien été modifiée"
|
flash.notice = "L'attestation a bien été modifiée"
|
||||||
else
|
else
|
||||||
flash.alert = attestation_template.errors.full_messages.join('<br>')
|
flash.alert = attestation_template.errors.full_messages.join('<br>')
|
||||||
|
@ -18,7 +23,7 @@ module Administrateurs
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
attestation_template = AttestationTemplate.new(activated_attestation_params.merge(procedure_id: @procedure.id))
|
attestation_template = build_attestation(activated_attestation_params)
|
||||||
|
|
||||||
if attestation_template.save
|
if attestation_template.save
|
||||||
flash.notice = "L'attestation a bien été sauvegardée"
|
flash.notice = "L'attestation a bien été sauvegardée"
|
||||||
|
@ -30,14 +35,19 @@ module Administrateurs
|
||||||
end
|
end
|
||||||
|
|
||||||
def preview
|
def preview
|
||||||
attestation = @procedure.attestation_template || AttestationTemplate.new
|
@attestation = build_attestation.render_attributes_for({})
|
||||||
@attestation = attestation.render_attributes_for({})
|
|
||||||
|
|
||||||
render 'administrateurs/attestation_templates/show', formats: [:pdf]
|
render 'administrateurs/attestation_templates/show', formats: [:pdf]
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def build_attestation(attributes = {})
|
||||||
|
attestation_template = @procedure.draft_attestation_template || @procedure.draft_revision.build_attestation_template
|
||||||
|
attestation_template.attributes = attributes
|
||||||
|
attestation_template
|
||||||
|
end
|
||||||
|
|
||||||
def activated_attestation_params
|
def activated_attestation_params
|
||||||
# cache result to avoid multiple uninterlaced computations
|
# cache result to avoid multiple uninterlaced computations
|
||||||
if @activated_attestation_params.nil?
|
if @activated_attestation_params.nil?
|
||||||
|
|
38
app/lib/balancer_delivery_method.rb
Normal file
38
app/lib/balancer_delivery_method.rb
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# A Mail delivery method that randomly balances the actual delivery between different
|
||||||
|
# methods.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
#
|
||||||
|
# ```ruby
|
||||||
|
# ActionMailer::Base.add_delivery_method :balancer, BalancerDeliveryMethod
|
||||||
|
# config.action_mailer.balancer_settings = {
|
||||||
|
# smtp: 25,
|
||||||
|
# sendmail: 75
|
||||||
|
# }
|
||||||
|
# config.action_mailer.delivery_method = :balancer
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
# Be sure to restart your server when you modify this file.
|
||||||
|
class BalancerDeliveryMethod
|
||||||
|
# Allows configuring the random number generator used for selecting a delivery method,
|
||||||
|
# mostly for testing purposes.
|
||||||
|
mattr_accessor :random, default: Random.new
|
||||||
|
|
||||||
|
def initialize(settings)
|
||||||
|
@delivery_methods = settings
|
||||||
|
end
|
||||||
|
|
||||||
|
def deliver!(mail)
|
||||||
|
balanced_delivery_method = delivery_method(mail)
|
||||||
|
ApplicationMailer.wrap_delivery_behavior(mail, balanced_delivery_method)
|
||||||
|
mail.deliver
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def delivery_method(mail)
|
||||||
|
@delivery_methods
|
||||||
|
.flat_map { |delivery_method, weight| [delivery_method] * weight }
|
||||||
|
.sample(random: self.class.random)
|
||||||
|
end
|
||||||
|
end
|
|
@ -15,7 +15,8 @@ class AttestationTemplate < ApplicationRecord
|
||||||
include ActionView::Helpers::NumberHelper
|
include ActionView::Helpers::NumberHelper
|
||||||
include TagsSubstitutionConcern
|
include TagsSubstitutionConcern
|
||||||
|
|
||||||
belongs_to :procedure, optional: false
|
belongs_to :procedure, optional: true
|
||||||
|
has_many :revisions, class_name: 'ProcedureRevision', inverse_of: :attestation_template, dependent: :nullify
|
||||||
|
|
||||||
has_one_attached :logo
|
has_one_attached :logo
|
||||||
has_one_attached :signature
|
has_one_attached :signature
|
||||||
|
@ -103,6 +104,25 @@ class AttestationTemplate < ApplicationRecord
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def revise!
|
||||||
|
if revisions.size > 1
|
||||||
|
attestation_template = dup
|
||||||
|
attestation_template.save!
|
||||||
|
revisions
|
||||||
|
.last
|
||||||
|
.procedure
|
||||||
|
.draft_revision
|
||||||
|
.update!(attestation_template: attestation_template)
|
||||||
|
attestation_template
|
||||||
|
else
|
||||||
|
self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def procedure
|
||||||
|
revisions.last&.procedure || super
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def used_tags
|
def used_tags
|
||||||
|
|
|
@ -720,9 +720,11 @@ class Dossier < ApplicationRecord
|
||||||
{ lon: lon, lat: lat, zoom: zoom }
|
{ lon: lon, lat: lat, zoom: zoom }
|
||||||
end
|
end
|
||||||
|
|
||||||
def unspecified_attestation_champs
|
def attestation_template
|
||||||
attestation_template = procedure.attestation_template
|
revision.attestation_template
|
||||||
|
end
|
||||||
|
|
||||||
|
def unspecified_attestation_champs
|
||||||
if attestation_template&.activated?
|
if attestation_template&.activated?
|
||||||
attestation_template.unspecified_champs_for_dossier(self)
|
attestation_template.unspecified_champs_for_dossier(self)
|
||||||
else
|
else
|
||||||
|
@ -731,8 +733,8 @@ class Dossier < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_attestation
|
def build_attestation
|
||||||
if procedure.attestation_template&.activated?
|
if attestation_template&.activated?
|
||||||
procedure.attestation_template.attestation_for(self)
|
attestation_template.attestation_for(self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -77,12 +77,15 @@ class Procedure < ApplicationRecord
|
||||||
has_many :published_types_de_champ_private, through: :published_revision, source: :types_de_champ_private
|
has_many :published_types_de_champ_private, through: :published_revision, source: :types_de_champ_private
|
||||||
has_many :draft_types_de_champ, through: :draft_revision, source: :types_de_champ
|
has_many :draft_types_de_champ, through: :draft_revision, source: :types_de_champ
|
||||||
has_many :draft_types_de_champ_private, through: :draft_revision, source: :types_de_champ_private
|
has_many :draft_types_de_champ_private, through: :draft_revision, source: :types_de_champ_private
|
||||||
|
has_one :draft_attestation_template, through: :draft_revision, source: :attestation_template
|
||||||
|
has_one :published_attestation_template, through: :published_revision, source: :attestation_template
|
||||||
|
|
||||||
has_many :experts_procedures, dependent: :destroy
|
has_many :experts_procedures, dependent: :destroy
|
||||||
has_many :experts, through: :experts_procedures
|
has_many :experts, through: :experts_procedures
|
||||||
|
|
||||||
has_one :module_api_carto, dependent: :destroy
|
has_one :module_api_carto, dependent: :destroy
|
||||||
has_one :attestation_template, dependent: :destroy
|
has_one :attestation_template, dependent: :destroy
|
||||||
|
has_many :attestation_templates, through: :revisions, source: :attestation_template
|
||||||
|
|
||||||
belongs_to :parent_procedure, class_name: 'Procedure', optional: true
|
belongs_to :parent_procedure, class_name: 'Procedure', optional: true
|
||||||
belongs_to :canonical_procedure, class_name: 'Procedure', optional: true
|
belongs_to :canonical_procedure, class_name: 'Procedure', optional: true
|
||||||
|
@ -438,7 +441,8 @@ class Procedure < ApplicationRecord
|
||||||
},
|
},
|
||||||
revision_types_de_champ_private: {
|
revision_types_de_champ_private: {
|
||||||
type_de_champ: :types_de_champ
|
type_de_champ: :types_de_champ
|
||||||
}
|
},
|
||||||
|
attestation_template: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
include_list[:groupe_instructeurs] = :instructeurs if !is_different_admin
|
include_list[:groupe_instructeurs] = :instructeurs if !is_different_admin
|
||||||
|
@ -576,13 +580,17 @@ class Procedure < ApplicationRecord
|
||||||
touch(:whitelisted_at)
|
touch(:whitelisted_at)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def active_attestation_template
|
||||||
|
published_attestation_template || draft_attestation_template
|
||||||
|
end
|
||||||
|
|
||||||
def closed_mail_template_attestation_inconsistency_state
|
def closed_mail_template_attestation_inconsistency_state
|
||||||
# As an optimization, don’t check the predefined templates (they are presumed correct)
|
# As an optimization, don’t check the predefined templates (they are presumed correct)
|
||||||
if closed_mail.present?
|
if closed_mail.present?
|
||||||
tag_present = closed_mail.body.to_s.include?("--lien attestation--")
|
tag_present = closed_mail.body.to_s.include?("--lien attestation--")
|
||||||
if attestation_template&.activated? && !tag_present
|
if active_attestation_template&.activated? && !tag_present
|
||||||
:missing_tag
|
:missing_tag
|
||||||
elsif !attestation_template&.activated? && tag_present
|
elsif !active_attestation_template&.activated? && tag_present
|
||||||
:extraneous_tag
|
:extraneous_tag
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,15 +2,17 @@
|
||||||
#
|
#
|
||||||
# Table name: procedure_revisions
|
# Table name: procedure_revisions
|
||||||
#
|
#
|
||||||
# id :bigint not null, primary key
|
# id :bigint not null, primary key
|
||||||
# published_at :datetime
|
# published_at :datetime
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# procedure_id :bigint not null
|
# attestation_template_id :bigint
|
||||||
|
# procedure_id :bigint not null
|
||||||
#
|
#
|
||||||
class ProcedureRevision < ApplicationRecord
|
class ProcedureRevision < ApplicationRecord
|
||||||
self.implicit_order_column = :created_at
|
self.implicit_order_column = :created_at
|
||||||
belongs_to :procedure, -> { with_discarded }, inverse_of: :revisions, optional: false
|
belongs_to :procedure, -> { with_discarded }, inverse_of: :revisions, optional: false
|
||||||
|
belongs_to :attestation_template, inverse_of: :revisions, optional: true, dependent: :destroy
|
||||||
|
|
||||||
has_many :dossiers, inverse_of: :revision, foreign_key: :revision_id
|
has_many :dossiers, inverse_of: :revision, foreign_key: :revision_id
|
||||||
|
|
||||||
|
@ -125,6 +127,10 @@ class ProcedureRevision < ApplicationRecord
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def attestation_template
|
||||||
|
super || procedure.attestation_template
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def compare_types_de_champ(from_tdc, to_tdc)
|
def compare_types_de_champ(from_tdc, to_tdc)
|
||||||
|
|
|
@ -138,7 +138,7 @@
|
||||||
.procedure-grid
|
.procedure-grid
|
||||||
|
|
||||||
= link_to edit_admin_procedure_attestation_template_path(@procedure), class: 'card-admin' do
|
= link_to edit_admin_procedure_attestation_template_path(@procedure), class: 'card-admin' do
|
||||||
- if @procedure.attestation_template.present? && @procedure.attestation_template.activated
|
- if @procedure.draft_attestation_template&.activated?
|
||||||
%div
|
%div
|
||||||
%span.icon.accept
|
%span.icon.accept
|
||||||
%p.card-admin-status-accept Activée
|
%p.card-admin-status-accept Activée
|
||||||
|
|
|
@ -70,28 +70,33 @@ MATOMO_ENABLED="disabled"
|
||||||
MATOMO_ID=""
|
MATOMO_ID=""
|
||||||
MATOMO_HOST="matomo.organisme.fr"
|
MATOMO_HOST="matomo.organisme.fr"
|
||||||
|
|
||||||
# SMTP Provider: Send In Blue
|
# Default SMTP Provider: Mailjet
|
||||||
|
MAILJET_API_KEY=""
|
||||||
|
MAILJET_SECRET_KEY=""
|
||||||
|
|
||||||
|
# Alternate SMTP Provider: SendInBlue
|
||||||
SENDINBLUE_ENABLED="disabled"
|
SENDINBLUE_ENABLED="disabled"
|
||||||
SENDINBLUE_BALANCING=""
|
|
||||||
SENDINBLUE_BALANCING_VALUE=""
|
|
||||||
SENDINBLUE_CLIENT_KEY=""
|
SENDINBLUE_CLIENT_KEY=""
|
||||||
SENDINBLUE_SMTP_KEY=""
|
SENDINBLUE_SMTP_KEY=""
|
||||||
SENDINBLUE_USER_NAME=""
|
SENDINBLUE_USER_NAME=""
|
||||||
# SENDINBLUE_LOGIN_URL="https://app.sendinblue.com/account/saml/login/truc"
|
# SENDINBLUE_LOGIN_URL="https://app.sendinblue.com/account/saml/login/truc"
|
||||||
|
|
||||||
# SMTP Provider: Mailjet
|
# Ratio of emails sent using SendInBlue
|
||||||
MAILJET_API_KEY=""
|
# When enabled, N % of emails will be sent using SendInBlue
|
||||||
MAILJET_SECRET_KEY=""
|
# (and the others using the default SMTP provider)
|
||||||
|
SENDINBLUE_BALANCING="disabled"
|
||||||
|
SENDINBLUE_BALANCING_VALUE="50"
|
||||||
|
|
||||||
|
# Alternate SMTP Provider: Mailtrap (mail catcher for staging environments)
|
||||||
|
# When enabled, all emails will be sent using this provided
|
||||||
|
MAILTRAP_ENABLED="disabled"
|
||||||
|
MAILTRAP_USERNAME=""
|
||||||
|
MAILTRAP_PASSWORD=""
|
||||||
|
|
||||||
# External service: live chat for admins (specific to démarches-simplifiées.fr)
|
# External service: live chat for admins (specific to démarches-simplifiées.fr)
|
||||||
CRISP_ENABLED="disabled"
|
CRISP_ENABLED="disabled"
|
||||||
CRISP_CLIENT_KEY=""
|
CRISP_CLIENT_KEY=""
|
||||||
|
|
||||||
# External service: mail catcher for staging environments (specific to démarches-simplifiées.fr)
|
|
||||||
MAILTRAP_ENABLED="disabled"
|
|
||||||
MAILTRAP_USERNAME=""
|
|
||||||
MAILTRAP_PASSWORD=""
|
|
||||||
|
|
||||||
# API Entreprise credentials
|
# API Entreprise credentials
|
||||||
# https://api.gouv.fr/api/api-entreprise.html
|
# https://api.gouv.fr/api/api-entreprise.html
|
||||||
API_ENTREPRISE_KEY=""
|
API_ENTREPRISE_KEY=""
|
||||||
|
|
|
@ -75,40 +75,13 @@ Rails.application.configure do
|
||||||
config.assets.raise_runtime_errors = true
|
config.assets.raise_runtime_errors = true
|
||||||
|
|
||||||
# Action Mailer settings
|
# Action Mailer settings
|
||||||
|
config.action_mailer.delivery_method = :letter_opener
|
||||||
|
|
||||||
if ENV['SENDINBLUE_ENABLED'] == 'enabled'
|
config.action_mailer.default_url_options = {
|
||||||
config.action_mailer.delivery_method = :smtp
|
host: 'localhost',
|
||||||
config.action_mailer.smtp_settings = {
|
port: 3000
|
||||||
user_name: Rails.application.secrets.sendinblue[:username],
|
}
|
||||||
password: Rails.application.secrets.sendinblue[:smtp_key],
|
config.action_mailer.asset_host = "http://" + ENV['APP_HOST']
|
||||||
address: 'smtp-relay.sendinblue.com',
|
|
||||||
domain: 'smtp-relay.sendinblue.com',
|
|
||||||
port: '587',
|
|
||||||
authentication: :cram_md5
|
|
||||||
}
|
|
||||||
else
|
|
||||||
# https://usehelo.com
|
|
||||||
if ENV['HELO_ENABLED'] == 'enabled'
|
|
||||||
config.action_mailer.delivery_method = :smtp
|
|
||||||
config.action_mailer.smtp_settings = {
|
|
||||||
user_name: 'demarches-simplifiees',
|
|
||||||
password: '',
|
|
||||||
address: '127.0.0.1',
|
|
||||||
domain: '127.0.0.1',
|
|
||||||
port: ENV.fetch('HELO_PORT', '2525'),
|
|
||||||
authentication: :plain
|
|
||||||
}
|
|
||||||
else
|
|
||||||
config.action_mailer.delivery_method = :letter_opener_web
|
|
||||||
end
|
|
||||||
|
|
||||||
config.action_mailer.default_url_options = {
|
|
||||||
host: 'localhost',
|
|
||||||
port: 3000
|
|
||||||
}
|
|
||||||
|
|
||||||
config.action_mailer.asset_host = "http://" + ENV['APP_HOST']
|
|
||||||
end
|
|
||||||
|
|
||||||
Rails.application.routes.default_url_options = {
|
Rails.application.routes.default_url_options = {
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
require "active_support/core_ext/integer/time"
|
require "active_support/core_ext/integer/time"
|
||||||
|
require Rails.root.join("app/lib/balancer_delivery_method")
|
||||||
|
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
# Settings specified here will take precedence over those in config/application.rb.
|
# Settings specified here will take precedence over those in config/application.rb.
|
||||||
|
@ -76,25 +77,19 @@ Rails.application.configure do
|
||||||
# config.action_mailer.raise_delivery_errors = false
|
# config.action_mailer.raise_delivery_errors = false
|
||||||
|
|
||||||
if ENV['MAILTRAP_ENABLED'] == 'enabled'
|
if ENV['MAILTRAP_ENABLED'] == 'enabled'
|
||||||
config.action_mailer.delivery_method = :smtp
|
config.action_mailer.delivery_method = :mailtrap
|
||||||
config.action_mailer.smtp_settings = {
|
|
||||||
user_name: Rails.application.secrets.mailtrap[:username],
|
elsif ENV['SENDINBLUE_ENABLED'] == 'enabled' && ENV['SENDINBLUE_BALANCING'] == 'enabled'
|
||||||
password: Rails.application.secrets.mailtrap[:password],
|
ActionMailer::Base.add_delivery_method :balancer, BalancerDeliveryMethod
|
||||||
address: 'smtp.mailtrap.io',
|
config.action_mailer.balancer_settings = {
|
||||||
domain: 'smtp.mailtrap.io',
|
sendinblue: ENV.fetch('SENDINBLUE_BALANCING_VALUE').to_i,
|
||||||
port: '2525',
|
mailjet: 100 - ENV.fetch('SENDINBLUE_BALANCING_VALUE').to_i
|
||||||
authentication: :cram_md5
|
|
||||||
}
|
}
|
||||||
|
config.action_mailer.delivery_method = :balancer
|
||||||
|
|
||||||
elsif ENV['SENDINBLUE_ENABLED'] == 'enabled'
|
elsif ENV['SENDINBLUE_ENABLED'] == 'enabled'
|
||||||
config.action_mailer.delivery_method = :smtp
|
config.action_mailer.delivery_method = :sendinblue
|
||||||
config.action_mailer.smtp_settings = {
|
|
||||||
user_name: Rails.application.secrets.sendinblue[:username],
|
|
||||||
password: Rails.application.secrets.sendinblue[:smtp_key],
|
|
||||||
address: 'smtp-relay.sendinblue.com',
|
|
||||||
domain: 'smtp-relay.sendinblue.com',
|
|
||||||
port: '587',
|
|
||||||
authentication: :cram_md5
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
config.action_mailer.delivery_method = :mailjet
|
config.action_mailer.delivery_method = :mailjet
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
# rubocop:disable DS/ApplicationName
|
# rubocop:disable DS/ApplicationName
|
||||||
# API URLs
|
# API URLs
|
||||||
|
API_ADRESSE_URL = ENV.fetch("API_ADRESSE_URL", "https://api-adresse.data.gouv.fr")
|
||||||
API_ENTREPRISE_URL = ENV.fetch("API_ENTREPRISE_URL", "https://entreprise.api.gouv.fr/v2")
|
API_ENTREPRISE_URL = ENV.fetch("API_ENTREPRISE_URL", "https://entreprise.api.gouv.fr/v2")
|
||||||
API_EDUCATION_URL = ENV.fetch("API_EDUCATION_URL", "https://data.education.gouv.fr/api/records/1.0")
|
API_EDUCATION_URL = ENV.fetch("API_EDUCATION_URL", "https://data.education.gouv.fr/api/records/1.0")
|
||||||
|
API_GEO_URL = ENV.fetch("API_GEO_URL", "https://geo.api.gouv.fr")
|
||||||
API_PARTICULIER_URL = ENV.fetch("API_PARTICULIER_URL", "https://particulier.api.gouv.fr/api")
|
API_PARTICULIER_URL = ENV.fetch("API_PARTICULIER_URL", "https://particulier.api.gouv.fr/api")
|
||||||
HELPSCOUT_API_URL = ENV.fetch("HELPSCOUT_API_URL", "https://api.helpscout.net/v2")
|
HELPSCOUT_API_URL = ENV.fetch("HELPSCOUT_API_URL", "https://api.helpscout.net/v2")
|
||||||
PIPEDRIVE_API_URL = ENV.fetch("PIPEDRIVE_API_URL", "https://api.pipedrive.com/v1")
|
PIPEDRIVE_API_URL = ENV.fetch("PIPEDRIVE_API_URL", "https://api.pipedrive.com/v1")
|
||||||
|
@ -11,7 +13,7 @@ UNIVERSIGN_API_URL = ENV.fetch("UNIVERSIGN_API_URL", "https://ws.universign.eu/t
|
||||||
FEATURE_UPVOTE_URL = ENV.fetch("FEATURE_UPVOTE_URL", "https://demarches-simplifiees.featureupvote.com")
|
FEATURE_UPVOTE_URL = ENV.fetch("FEATURE_UPVOTE_URL", "https://demarches-simplifiees.featureupvote.com")
|
||||||
|
|
||||||
# Internal URLs
|
# Internal URLs
|
||||||
FOG_BASE_URL = "https://static.demarches-simplifiees.fr"
|
FOG_OPENSTACK_URL = ENV.fetch("FOG_OPENSTACK_URL", "https://static.demarches-simplifiees.fr")
|
||||||
|
|
||||||
# External services URLs
|
# External services URLs
|
||||||
WEBINAIRE_URL = "https://app.livestorm.co/demarches-simplifiees"
|
WEBINAIRE_URL = "https://app.livestorm.co/demarches-simplifiees"
|
|
@ -4,30 +4,45 @@
|
||||||
# For further information see the following documentation
|
# For further information see the following documentation
|
||||||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
||||||
|
|
||||||
# rubocop:disable DS/ApplicationName
|
|
||||||
Rails.application.config.content_security_policy do |policy|
|
Rails.application.config.content_security_policy do |policy|
|
||||||
# Whitelist image
|
# Whitelist image
|
||||||
policy.img_src :self, "*.openstreetmap.org", "static.demarches-simplifiees.fr", "*.cloud.ovh.net", "stats.data.gouv.fr", "*", :data, :blob
|
images_whitelist = ["*.openstreetmap.org", "*.cloud.ovh.net", "*"]
|
||||||
|
images_whitelist << URI(FOG_OPENSTACK_URL).host if FOG_OPENSTACK_URL.present?
|
||||||
|
images_whitelist << URI(MATOMO_IFRAME_URL).host if MATOMO_IFRAME_URL.present?
|
||||||
|
policy.img_src(:self, :data, :blob, *images_whitelist)
|
||||||
|
|
||||||
# Whitelist JS: nous, sendinblue et matomo
|
# Whitelist JS: nous, sendinblue et matomo
|
||||||
# miniprofiler et nous avons quelques boutons inline :(
|
# miniprofiler et nous avons quelques boutons inline :(
|
||||||
policy.script_src :self, "stats.data.gouv.fr", "*.sendinblue.com", "*.crisp.chat", "crisp.chat", "*.sibautomation.com", "sibautomation.com", 'cdn.jsdelivr.net', 'maxcdn.bootstrapcdn.com', 'code.jquery.com', :unsafe_eval, :unsafe_inline, :blob
|
scripts_whitelist = ["*.sendinblue.com", "*.crisp.chat", "crisp.chat", "*.sibautomation.com", "sibautomation.com", "cdn.jsdelivr.net", "maxcdn.bootstrapcdn.com", "code.jquery.com"]
|
||||||
|
scripts_whitelist << URI(MATOMO_IFRAME_URL).host if MATOMO_IFRAME_URL.present?
|
||||||
|
policy.script_src(:self, :unsafe_eval, :unsafe_inline, :blob, *scripts_whitelist)
|
||||||
|
|
||||||
# Pour les CSS, on a beaucoup de style inline et quelques balises <style>
|
# Pour les CSS, on a beaucoup de style inline et quelques balises <style>
|
||||||
# c'est trop compliqué pour être rectifié immédiatement (et sans valeur ajoutée:
|
# c'est trop compliqué pour être rectifié immédiatement (et sans valeur ajoutée:
|
||||||
# c'est hardcodé dans les vues, donc pas injectable).
|
# c'est hardcodé dans les vues, donc pas injectable).
|
||||||
policy.style_src :self, "*.crisp.chat", "crisp.chat", 'cdn.jsdelivr.net', 'maxcdn.bootstrapcdn.com', :unsafe_inline
|
policy.style_src(:self, "*.crisp.chat", "crisp.chat", 'cdn.jsdelivr.net', 'maxcdn.bootstrapcdn.com', :unsafe_inline)
|
||||||
policy.connect_src :self, "wss://*.crisp.chat", "*.crisp.chat", "*.demarches-simplifiees.fr", "in-automate.sendinblue.com", "app.franceconnect.gouv.fr", "sentry.io", "geo.api.gouv.fr", "api-adresse.data.gouv.fr", "openmaptiles.geo.data.gouv.fr", "openmaptiles.github.io", "tiles.geo.api.gouv.fr", "wxs.ign.fr", "data.education.gouv.fr"
|
|
||||||
|
connect_whitelist = ["wss://*.crisp.chat", "*.crisp.chat", "in-automate.sendinblue.com", "app.franceconnect.gouv.fr", "sentry.io", "openmaptiles.geo.data.gouv.fr", "openmaptiles.github.io", "tiles.geo.api.gouv.fr", "wxs.ign.fr"]
|
||||||
|
connect_whitelist << URI(API_ADRESSE_URL).host if API_ADRESSE_URL.present?
|
||||||
|
connect_whitelist << URI(API_EDUCATION_URL).host if API_EDUCATION_URL.present?
|
||||||
|
connect_whitelist << URI(API_GEO_URL).host if API_GEO_URL.present?
|
||||||
|
connect_whitelist << "*.#{ENV.fetch('APP_HOST', 'localhost:3000')}"
|
||||||
|
policy.connect_src(:self, *connect_whitelist)
|
||||||
|
|
||||||
# Pour tout le reste, par défaut on accepte uniquement ce qui vient de chez nous
|
# Pour tout le reste, par défaut on accepte uniquement ce qui vient de chez nous
|
||||||
# et dans la notification on inclue la source de l'erreur
|
# et dans la notification on inclue la source de l'erreur
|
||||||
policy.default_src :self, :data, :blob, :report_sample, "fonts.gstatic.com", "in-automate.sendinblue.com", "player.vimeo.com", "app.franceconnect.gouv.fr", "sentry.io", "static.demarches-simplifiees.fr", "*.crisp.chat", "crisp.chat", "*.crisp.help", "*.sibautomation.com", "sibautomation.com", "data"
|
default_whitelist = ["fonts.gstatic.com", "in-automate.sendinblue.com", "player.vimeo.com", "app.franceconnect.gouv.fr", "sentry.io", "*.crisp.chat", "crisp.chat", "*.crisp.help", "*.sibautomation.com", "sibautomation.com", "data"]
|
||||||
|
default_whitelist << URI(FOG_OPENSTACK_URL).host if FOG_OPENSTACK_URL.present?
|
||||||
|
policy.default_src(:self, :data, :blob, :report_sample, *default_whitelist)
|
||||||
|
|
||||||
if Rails.env.development?
|
if Rails.env.development?
|
||||||
# Les CSP ne sont pas appliquées en dev: on notifie cependant une url quelconque de la violation
|
# Les CSP ne sont pas appliquées en dev: on notifie cependant une url quelconque de la violation
|
||||||
# pour détecter les erreurs lors de l'ajout d'une nouvelle brique externe durant le développement
|
# pour détecter les erreurs lors de l'ajout d'une nouvelle brique externe durant le développement
|
||||||
policy.report_uri "http://#{ENV['APP_HOST']}/csp/"
|
policy.report_uri "http://#{ENV.fetch('APP_HOST', 'localhost:3000')}/csp/"
|
||||||
# En développement, quand bin/webpack-dev-server est utilisé, on autorise les requêtes faites par le live-reload
|
# En développement, quand bin/webpack-dev-server est utilisé, on autorise les requêtes faites par le live-reload
|
||||||
policy.connect_src(*policy.connect_src, "ws://localhost:3035", "http://localhost:3035")
|
policy.connect_src(*policy.connect_src, "ws://localhost:3035", "http://localhost:3035")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
# rubocop:enable DS/ApplicationName
|
|
||||||
|
|
||||||
# If you are using UJS then enable automatic nonce generation
|
# If you are using UJS then enable automatic nonce generation
|
||||||
# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
|
# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
# We want to register an interceptor, but we can't make the action idempotent
|
|
||||||
# (because there's no way to peek at the currently registered interceptors).
|
|
||||||
#
|
|
||||||
# To make zeitwerk happy, instead signal that we don't want the
|
|
||||||
# DynamicSmtpSettingsInterceptor constant to be auto-loaded, by:
|
|
||||||
# - adding it to a non-autoloaded-path (/lib),
|
|
||||||
# - requiring it explicitely.
|
|
||||||
#
|
|
||||||
# See https://guides.rubyonrails.org/autoloading_and_reloading_constants.html#autoloading-when-the-application-boots
|
|
||||||
require 'action_mailer/dynamic_smtp_settings_interceptor'
|
|
||||||
|
|
||||||
ActiveSupport.on_load(:action_mailer) do
|
|
||||||
ActionMailer::Base.register_interceptor DynamicSmtpSettingsInterceptor
|
|
||||||
end
|
|
17
config/initializers/helo.rb
Normal file
17
config/initializers/helo.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
if ENV['HELO_ENABLED'] == 'enabled'
|
||||||
|
ActiveSupport.on_load(:action_mailer) do
|
||||||
|
module Helo
|
||||||
|
class SMTP < ::Mail::SMTP; end
|
||||||
|
end
|
||||||
|
|
||||||
|
ActionMailer::Base.add_delivery_method :helo, Helo::SMTP
|
||||||
|
ActionMailer::Base.helo_settings = {
|
||||||
|
user_name: 'demarches-simplifiees',
|
||||||
|
password: '',
|
||||||
|
address: '127.0.0.1',
|
||||||
|
domain: '127.0.0.1',
|
||||||
|
port: ENV.fetch('HELO_PORT', '2525'),
|
||||||
|
authentication: :plain
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
17
config/initializers/mailtrap.rb
Normal file
17
config/initializers/mailtrap.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
if ENV.fetch('MAILTRAP_ENABLED') == 'enabled'
|
||||||
|
ActiveSupport.on_load(:action_mailer) do
|
||||||
|
module Mailtrap
|
||||||
|
class SMTP < ::Mail::SMTP; end
|
||||||
|
end
|
||||||
|
|
||||||
|
ActionMailer::Base.add_delivery_method :mailtrap, Mailtrap::SMTP
|
||||||
|
ActionMailer::Base.mailtrap_settings = {
|
||||||
|
user_name: Rails.application.secrets.mailtrap[:username],
|
||||||
|
password: Rails.application.secrets.mailtrap[:password],
|
||||||
|
address: 'smtp.mailtrap.io',
|
||||||
|
domain: 'smtp.mailtrap.io',
|
||||||
|
port: '2525',
|
||||||
|
authentication: :cram_md5
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,23 @@
|
||||||
require 'sib-api-v3-sdk'
|
if ENV.fetch('SENDINBLUE_ENABLED') == 'enabled'
|
||||||
|
require 'sib-api-v3-sdk'
|
||||||
|
|
||||||
SibApiV3Sdk.configure do |config|
|
ActiveSupport.on_load(:action_mailer) do
|
||||||
config.api_key['api-key'] = ENV.fetch('SENDINBLUE_API_V3_KEY', '')
|
module Sendinblue
|
||||||
|
class SMTP < ::Mail::SMTP; end
|
||||||
|
end
|
||||||
|
|
||||||
|
ActionMailer::Base.add_delivery_method :sendinblue, Sendinblue::SMTP
|
||||||
|
ActionMailer::Base.sendinblue_settings = {
|
||||||
|
user_name: Rails.application.secrets.sendinblue[:username],
|
||||||
|
password: Rails.application.secrets.sendinblue[:smtp_key],
|
||||||
|
address: 'smtp-relay.sendinblue.com',
|
||||||
|
domain: 'smtp-relay.sendinblue.com',
|
||||||
|
port: '587',
|
||||||
|
authentication: :cram_md5
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
SibApiV3Sdk.configure do |config|
|
||||||
|
config.api_key['api-key'] = Rails.application.secrets.sendinblue[:api_v3_key]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddAttestationTemplateIdToProcedureRevisions < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
add_reference :procedure_revisions, :attestation_template, foreign_key: { to_table: :attestation_templates }, null: true, index: true
|
||||||
|
end
|
||||||
|
end
|
|
@ -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: 2022_01_27_135056) do
|
ActiveRecord::Schema.define(version: 2022_01_28_135056) 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"
|
||||||
|
@ -593,6 +593,8 @@ ActiveRecord::Schema.define(version: 2022_01_27_135056) do
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.datetime "published_at"
|
t.datetime "published_at"
|
||||||
|
t.bigint "attestation_template_id"
|
||||||
|
t.index ["attestation_template_id"], name: "index_procedure_revisions_on_attestation_template_id"
|
||||||
t.index ["procedure_id"], name: "index_procedure_revisions_on_procedure_id"
|
t.index ["procedure_id"], name: "index_procedure_revisions_on_procedure_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -872,6 +874,7 @@ ActiveRecord::Schema.define(version: 2022_01_27_135056) do
|
||||||
add_foreign_key "procedure_revision_types_de_champ", "procedure_revision_types_de_champ", column: "parent_id"
|
add_foreign_key "procedure_revision_types_de_champ", "procedure_revision_types_de_champ", column: "parent_id"
|
||||||
add_foreign_key "procedure_revision_types_de_champ", "procedure_revisions", column: "revision_id"
|
add_foreign_key "procedure_revision_types_de_champ", "procedure_revisions", column: "revision_id"
|
||||||
add_foreign_key "procedure_revision_types_de_champ", "types_de_champ"
|
add_foreign_key "procedure_revision_types_de_champ", "types_de_champ"
|
||||||
|
add_foreign_key "procedure_revisions", "attestation_templates"
|
||||||
add_foreign_key "procedure_revisions", "procedures"
|
add_foreign_key "procedure_revisions", "procedures"
|
||||||
add_foreign_key "procedures", "procedure_revisions", column: "draft_revision_id"
|
add_foreign_key "procedures", "procedure_revisions", column: "draft_revision_id"
|
||||||
add_foreign_key "procedures", "procedure_revisions", column: "published_revision_id"
|
add_foreign_key "procedures", "procedure_revisions", column: "published_revision_id"
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
# Note: this class is instanciated when being added as an interceptor
|
|
||||||
# during the app initialization.
|
|
||||||
#
|
|
||||||
# If you edit this file in development env, you will need to restart
|
|
||||||
# the app to see the changes.
|
|
||||||
|
|
||||||
class DynamicSmtpSettingsInterceptor
|
|
||||||
def self.delivering_email(message)
|
|
||||||
if ENV['SENDINBLUE_BALANCING'] == 'enabled'
|
|
||||||
if rand(0..99) < ENV['SENDINBLUE_BALANCING_VALUE'].to_i
|
|
||||||
message.delivery_method.settings = {
|
|
||||||
user_name: ENV['SENDINBLUE_USER_NAME'],
|
|
||||||
password: ENV['SENDINBLUE_SMTP_KEY'],
|
|
||||||
address: 'smtp-relay.sendinblue.com',
|
|
||||||
domain: 'smtp-relay.sendinblue.com',
|
|
||||||
port: '587',
|
|
||||||
authentication: :cram_md5
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,20 +1,26 @@
|
||||||
namespace :after_party do
|
namespace :after_party do
|
||||||
desc 'Deployment task: backfill_expert_id_on_avis_table'
|
desc 'Deployment task: backfill_expert_id_on_avis_table'
|
||||||
task backfill_experts_procedure_id_on_avis_table: :environment do
|
task backfill_experts_procedure_id_on_avis_table: :environment do
|
||||||
puts "Running deploy task 'backfill_expert_id_on_avis_table'"
|
puts "Running deploy task 'backfill_experts_procedure_id_on_avis_table'"
|
||||||
# rubocop:disable DS/Unscoped
|
# rubocop:disable DS/Unscoped
|
||||||
# rubocop:disable Rails/PluckInWhere
|
# rubocop:disable Rails/PluckInWhere
|
||||||
|
|
||||||
Instructeur.includes(:user)
|
instructeurs = Instructeur.includes(:user).where.not(users: { instructeur_id: nil })
|
||||||
.where(id: Avis.unscoped.pluck(:instructeur_id))
|
|
||||||
.where.not(users: { instructeur_id: nil })
|
instructeurs =
|
||||||
.find_each do |instructeur|
|
if Avis.column_names.include?("instructeur_id")
|
||||||
|
instructeurs.where(id: Avis.unscoped.pluck(:instructeur_id))
|
||||||
|
else
|
||||||
|
instructeurs.where(id: Avis.unscoped.where(claimant_type: [nil, "Instructeur"]).pluck(:claimant_id))
|
||||||
|
end
|
||||||
|
|
||||||
|
instructeurs.find_each do |instructeur|
|
||||||
user = instructeur.user
|
user = instructeur.user
|
||||||
User.create_or_promote_to_expert(user.email, SecureRandom.hex)
|
User.create_or_promote_to_expert(user.email, SecureRandom.hex)
|
||||||
user.reload
|
user.reload
|
||||||
# rubocop:enable DS/Unscoped
|
# rubocop:enable DS/Unscoped
|
||||||
# rubocop:enable Rails/PluckInWhere
|
# rubocop:enable Rails/PluckInWhere
|
||||||
instructeur.avis.each do |avis|
|
Avis.where(claimant: instructeur).each do |avis|
|
||||||
experts_procedure = ExpertsProcedure.find_or_create_by(expert: user.expert, procedure: avis.procedure)
|
experts_procedure = ExpertsProcedure.find_or_create_by(expert: user.expert, procedure: avis.procedure)
|
||||||
avis.update_column(:experts_procedure_id, experts_procedure.id)
|
avis.update_column(:experts_procedure_id, experts_procedure.id)
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,8 @@ namespace :after_party do
|
||||||
|
|
||||||
BATCH_SIZE = 20000
|
BATCH_SIZE = 20000
|
||||||
|
|
||||||
with_dossiers = Avis.where(claimant_type: nil).includes(claimant: :assign_to).where.not(claimant: { assign_tos: { id: nil } })
|
without_assign_to_ids = Instructeur.includes(:assign_to).where(assign_tos: { id: nil }).pluck(:id)
|
||||||
|
with_dossiers = Avis.where(claimant_type: nil).where.not(claimant_id: without_assign_to_ids)
|
||||||
|
|
||||||
((with_dossiers.count / BATCH_SIZE).ceil + 1).times do
|
((with_dossiers.count / BATCH_SIZE).ceil + 1).times do
|
||||||
with_dossiers
|
with_dossiers
|
||||||
|
@ -13,10 +14,9 @@ namespace :after_party do
|
||||||
.update_all(claimant_type: 'Instructeur')
|
.update_all(claimant_type: 'Instructeur')
|
||||||
end
|
end
|
||||||
|
|
||||||
without_dossiers = Avis.where(claimant_type: nil).includes(claimant: :assign_to).where(claimant: { assign_tos: { id: nil } })
|
without_dossiers = Avis.where(claimant_type: nil).where(claimant_id: without_assign_to_ids)
|
||||||
without_dossiers.find_each do |avis|
|
without_dossiers.find_each do |avis|
|
||||||
claimant = avis.claimant.user
|
instructeur = Instructeur.find(avis.claimant_id)
|
||||||
instructeur = avis.instructeur
|
|
||||||
|
|
||||||
if instructeur && avis.experts_procedure_id.blank?
|
if instructeur && avis.experts_procedure_id.blank?
|
||||||
User.create_or_promote_to_expert(instructeur.user.email, SecureRandom.hex)
|
User.create_or_promote_to_expert(instructeur.user.email, SecureRandom.hex)
|
||||||
|
@ -33,7 +33,7 @@ namespace :after_party do
|
||||||
elsif avis.experts_procedure_id.present?
|
elsif avis.experts_procedure_id.present?
|
||||||
avis.update_column(:claimant_type, 'Expert')
|
avis.update_column(:claimant_type, 'Expert')
|
||||||
|
|
||||||
elsif claimant.blank?
|
elsif instructeur && instructeur.user.nil?
|
||||||
avis.destroy
|
avis.destroy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,8 @@ namespace :after_party do
|
||||||
task backfill_claimant_id_for_experts_on_avis_table: :environment do
|
task backfill_claimant_id_for_experts_on_avis_table: :environment do
|
||||||
puts "Running deploy task 'backfill_claimant_id_for_experts_on_avis_table'"
|
puts "Running deploy task 'backfill_claimant_id_for_experts_on_avis_table'"
|
||||||
|
|
||||||
avis_experts_claimant = Avis.where(claimant_type: 'Expert', tmp_expert_migrated: false)
|
avis_experts_claimant = Avis.where(claimant_type: 'Expert')
|
||||||
|
avis_experts_claimant = avis_experts_claimant.where(tmp_expert_migrated: false) if Avis.column_names.include?("tmp_expert_migrated")
|
||||||
progress = ProgressReport.new(avis_experts_claimant.count)
|
progress = ProgressReport.new(avis_experts_claimant.count)
|
||||||
|
|
||||||
avis_experts_claimant.find_each do |avis|
|
avis_experts_claimant.find_each do |avis|
|
||||||
|
@ -15,7 +16,10 @@ namespace :after_party do
|
||||||
claimant_expert = claimant_instructeur.reload.user.expert
|
claimant_expert = claimant_instructeur.reload.user.expert
|
||||||
ExpertsProcedure.find_or_create_by(procedure: avis.procedure, expert: claimant_expert)
|
ExpertsProcedure.find_or_create_by(procedure: avis.procedure, expert: claimant_expert)
|
||||||
end
|
end
|
||||||
avis.update_columns(claimant_id: claimant_expert.id, tmp_expert_migrated: true)
|
|
||||||
|
if Avis.column_names.include?("tmp_expert_migrated")
|
||||||
|
avis.update_columns(claimant_id: claimant_expert.id, tmp_expert_migrated: true)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
# Avis associated to an Instructeur with no user are bad data: delete it
|
# Avis associated to an Instructeur with no user are bad data: delete it
|
||||||
avis.destroy!
|
avis.destroy!
|
||||||
|
@ -23,6 +27,7 @@ namespace :after_party do
|
||||||
progress.inc
|
progress.inc
|
||||||
end
|
end
|
||||||
progress.finish
|
progress.finish
|
||||||
|
|
||||||
# Update task as completed. If you remove the line below, the task will
|
# Update task as completed. If you remove the line below, the task will
|
||||||
# run with every deploy (or every time you call after_party:run).
|
# run with every deploy (or every time you call after_party:run).
|
||||||
AfterParty::TaskRecord
|
AfterParty::TaskRecord
|
||||||
|
|
|
@ -3,8 +3,19 @@ namespace :after_party do
|
||||||
task backfill_experts_procedure_id_on_avis_table_again: :environment do
|
task backfill_experts_procedure_id_on_avis_table_again: :environment do
|
||||||
puts "Running deploy task 'backfill_experts_procedure_id_on_avis_table_again'"
|
puts "Running deploy task 'backfill_experts_procedure_id_on_avis_table_again'"
|
||||||
|
|
||||||
without_instructeur = Avis.where(experts_procedure_id: nil, instructeur_id: nil).where.not(email: nil)
|
if Avis.column_names.include?("instructeur_id")
|
||||||
with_instructeur = Avis.where(experts_procedure_id: nil, email: nil).where.not(instructeur_id: nil)
|
without_instructeur = Avis.where(experts_procedure_id: nil, instructeur_id: nil).where.not(email: nil)
|
||||||
|
with_instructeur = Avis.where(experts_procedure_id: nil, email: nil).where.not(instructeur_id: nil)
|
||||||
|
else
|
||||||
|
without_instructeur = Avis
|
||||||
|
.where(experts_procedure_id: nil, claimant_type: [nil, "Instructeur"])
|
||||||
|
.where.not(email: nil)
|
||||||
|
|
||||||
|
with_instructeur = Avis
|
||||||
|
.where(experts_procedure_id: nil, email: nil, claimant_type: [nil, "Instructeur"])
|
||||||
|
.where.not(claimant_id: nil)
|
||||||
|
end
|
||||||
|
|
||||||
progress = ProgressReport.new(without_instructeur.count)
|
progress = ProgressReport.new(without_instructeur.count)
|
||||||
progress2 = ProgressReport.new(with_instructeur.count)
|
progress2 = ProgressReport.new(with_instructeur.count)
|
||||||
|
|
||||||
|
@ -22,7 +33,8 @@ namespace :after_party do
|
||||||
progress.finish
|
progress.finish
|
||||||
|
|
||||||
with_instructeur.find_each do |avis|
|
with_instructeur.find_each do |avis|
|
||||||
instructeur = avis.instructeur
|
instructeur = avis.respond_to?(:instructeur) ? avis.instructeur : avis.claimant
|
||||||
|
|
||||||
if instructeur && instructeur.user
|
if instructeur && instructeur.user
|
||||||
user = User.create_or_promote_to_expert(instructeur.user.email, SecureRandom.hex)
|
user = User.create_or_promote_to_expert(instructeur.user.email, SecureRandom.hex)
|
||||||
user.reload
|
user.reload
|
||||||
|
|
|
@ -3,14 +3,16 @@ namespace :after_party do
|
||||||
task revise_attestation_templates: :environment do
|
task revise_attestation_templates: :environment do
|
||||||
rake_puts "Running deploy task 'revise_attestation_templates'"
|
rake_puts "Running deploy task 'revise_attestation_templates'"
|
||||||
|
|
||||||
attestation_templates = AttestationTemplate.where.not(procedure_id: nil)
|
revisions = ProcedureRevision
|
||||||
progress = ProgressReport.new(attestation_templates.count)
|
.joins(procedure: :attestation_template)
|
||||||
|
.where(attestation_template_id: nil)
|
||||||
|
|
||||||
|
progress = ProgressReport.new(revisions.count)
|
||||||
|
|
||||||
|
revisions.find_each do |revision|
|
||||||
|
attestation_template_id = revision.procedure.attestation_template.id
|
||||||
|
revision.update_column(:attestation_template_id, attestation_template_id)
|
||||||
|
|
||||||
attestation_templates.find_each do |attestation_template|
|
|
||||||
ProcedureRevision
|
|
||||||
.where(procedure_id: attestation_template.procedure_id, attestation_template_id: nil)
|
|
||||||
.update_all(attestation_template_id: attestation_template)
|
|
||||||
attestation_template.update_column(:procedure_id, nil)
|
|
||||||
progress.inc
|
progress.inc
|
||||||
end
|
end
|
||||||
progress.finish
|
progress.finish
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
include ActionDispatch::TestProcess
|
include ActionDispatch::TestProcess
|
||||||
|
|
||||||
describe Administrateurs::AttestationTemplatesController, type: :controller do
|
describe Administrateurs::AttestationTemplatesController, type: :controller do
|
||||||
let!(:attestation_template) { create(:attestation_template) }
|
|
||||||
let(:admin) { create(:administrateur) }
|
let(:admin) { create(:administrateur) }
|
||||||
|
let(:attestation_template) { build(:attestation_template) }
|
||||||
let!(:procedure) { create :procedure, administrateur: admin, attestation_template: attestation_template }
|
let!(:procedure) { create :procedure, administrateur: admin, attestation_template: attestation_template }
|
||||||
let(:logo) { fixture_file_upload('spec/fixtures/files/white.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(:logo2) { fixture_file_upload('spec/fixtures/files/white.png', 'image/png') }
|
||||||
|
@ -41,7 +41,7 @@ describe Administrateurs::AttestationTemplatesController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'if an attestation template exists on the procedure' do
|
context 'if an attestation template exists on the procedure' do
|
||||||
after { procedure.attestation_template.destroy }
|
after { procedure.draft_revision.attestation_template&.destroy }
|
||||||
|
|
||||||
context 'with images' do
|
context 'with images' do
|
||||||
let!(:attestation_template) do
|
let!(:attestation_template) do
|
||||||
|
@ -115,14 +115,14 @@ describe Administrateurs::AttestationTemplatesController, type: :controller do
|
||||||
procedure.reload
|
procedure.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect(procedure.attestation_template).to have_attributes(attestation_params) }
|
it { expect(procedure.draft_attestation_template).to have_attributes(attestation_params) }
|
||||||
it { expect(procedure.attestation_template.activated).to be true }
|
it { expect(procedure.draft_attestation_template.activated).to be true }
|
||||||
it { expect(procedure.attestation_template.logo.download).to eq(logo2.read) }
|
it { expect(procedure.draft_attestation_template.logo.download).to eq(logo2.read) }
|
||||||
it { expect(procedure.attestation_template.signature.download).to eq(signature2.read) }
|
it { expect(procedure.draft_attestation_template.signature.download).to eq(signature2.read) }
|
||||||
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
|
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
|
||||||
it { expect(flash.notice).to eq("L'attestation a bien été sauvegardée") }
|
it { expect(flash.notice).to eq("L'attestation a bien été sauvegardée") }
|
||||||
|
|
||||||
after { procedure.attestation_template.destroy }
|
after { procedure.draft_attestation_template.destroy }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when something wrong happens in the attestation template creation' do
|
context 'when something wrong happens in the attestation template creation' do
|
||||||
|
@ -140,7 +140,7 @@ describe Administrateurs::AttestationTemplatesController, type: :controller do
|
||||||
|
|
||||||
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
|
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
|
||||||
it { expect(flash.alert).to be_present }
|
it { expect(flash.alert).to be_present }
|
||||||
it { expect(procedure.attestation_template).to be nil }
|
it { expect(procedure.draft_attestation_template).to be nil }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -158,13 +158,13 @@ describe Administrateurs::AttestationTemplatesController, type: :controller do
|
||||||
procedure.reload
|
procedure.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
it { expect(procedure.attestation_template).to have_attributes(attestation_params) }
|
it { expect(procedure.draft_attestation_template).to have_attributes(attestation_params) }
|
||||||
it { expect(procedure.attestation_template.logo.download).to eq(logo2.read) }
|
it { expect(procedure.draft_attestation_template.logo.download).to eq(logo2.read) }
|
||||||
it { expect(procedure.attestation_template.signature.download).to eq(signature2.read) }
|
it { expect(procedure.draft_attestation_template.signature.download).to eq(signature2.read) }
|
||||||
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
|
it { expect(response).to redirect_to edit_admin_procedure_attestation_template_path(procedure) }
|
||||||
it { expect(flash.notice).to eq("L'attestation a bien été modifiée") }
|
it { expect(flash.notice).to eq("L'attestation a bien été modifiée") }
|
||||||
|
|
||||||
after { procedure.attestation_template.destroy }
|
after { procedure.draft_attestation_template&.destroy }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when something wrong happens in the attestation template creation' do
|
context 'when something wrong happens in the attestation template creation' do
|
||||||
|
|
|
@ -4,8 +4,6 @@ FactoryBot.define do
|
||||||
body { 'body' }
|
body { 'body' }
|
||||||
footer { 'footer' }
|
footer { 'footer' }
|
||||||
activated { true }
|
activated { true }
|
||||||
|
|
||||||
association :procedure
|
|
||||||
end
|
end
|
||||||
|
|
||||||
trait :with_files do
|
trait :with_files do
|
||||||
|
|
|
@ -18,15 +18,16 @@ FactoryBot.define do
|
||||||
administrateurs { administrateur.present? ? [administrateur] : [association(:administrateur)] }
|
administrateurs { administrateur.present? ? [administrateur] : [association(:administrateur)] }
|
||||||
|
|
||||||
transient do
|
transient do
|
||||||
administrateur { }
|
administrateur {}
|
||||||
instructeurs { [] }
|
instructeurs { [] }
|
||||||
types_de_champ { [] }
|
types_de_champ { [] }
|
||||||
types_de_champ_private { [] }
|
types_de_champ_private { [] }
|
||||||
updated_at { nil }
|
updated_at { nil }
|
||||||
|
attestation_template { nil }
|
||||||
end
|
end
|
||||||
|
|
||||||
after(:build) do |procedure, evaluator|
|
after(:build) do |procedure, evaluator|
|
||||||
initial_revision = build(:procedure_revision, procedure: procedure)
|
initial_revision = build(:procedure_revision, procedure: procedure, attestation_template: evaluator.attestation_template)
|
||||||
add_types_de_champs(evaluator.types_de_champ, to: initial_revision, scope: :public)
|
add_types_de_champs(evaluator.types_de_champ, to: initial_revision, scope: :public)
|
||||||
add_types_de_champs(evaluator.types_de_champ_private, to: initial_revision, scope: :private)
|
add_types_de_champs(evaluator.types_de_champ_private, to: initial_revision, scope: :private)
|
||||||
|
|
||||||
|
|
93
spec/lib/balancer_delivery_method_spec.rb
Normal file
93
spec/lib/balancer_delivery_method_spec.rb
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
RSpec.describe BalancerDeliveryMethod do
|
||||||
|
class ExampleMailer < ApplicationMailer
|
||||||
|
def greet(name)
|
||||||
|
mail(to: "smtp_to", from: "smtp_from", body: "Hello #{name}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class TestMail
|
||||||
|
def self.deliveries
|
||||||
|
@deliveries ||= []
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.deliveries=(val)
|
||||||
|
@deliveries = val
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_accessor :settings
|
||||||
|
|
||||||
|
def initialize(values)
|
||||||
|
@settings = values.dup
|
||||||
|
end
|
||||||
|
|
||||||
|
def deliver!(mail)
|
||||||
|
Mail::CheckDeliveryParams.check(mail)
|
||||||
|
self.class.deliveries << mail
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class MockSmtp < TestMail; end
|
||||||
|
|
||||||
|
class MockSendmail < TestMail; end
|
||||||
|
|
||||||
|
class FixedSequence
|
||||||
|
def initialize(sequence)
|
||||||
|
@enumerator = sequence.each
|
||||||
|
end
|
||||||
|
|
||||||
|
def rand(_)
|
||||||
|
@enumerator.next
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
ActionMailer::Base.add_delivery_method :mock_smtp, MockSmtp
|
||||||
|
ActionMailer::Base.add_delivery_method :mock_sendmail, MockSendmail
|
||||||
|
ActionMailer::Base.add_delivery_method :balancer, BalancerDeliveryMethod
|
||||||
|
|
||||||
|
ExampleMailer.delivery_method = :balancer
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when a single delivery method is provided' do
|
||||||
|
before do
|
||||||
|
ActionMailer::Base.balancer_settings = { mock_smtp: 10 }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sends emails to the selected delivery method' do
|
||||||
|
mail = ExampleMailer.greet('Joshua').deliver_now
|
||||||
|
expect(mail).to have_been_delivered_using(MockSmtp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when multiple delivery methods are provided' do
|
||||||
|
before do
|
||||||
|
ActionMailer::Base.balancer_settings = { mock_smtp: 10, mock_sendmail: 5 }
|
||||||
|
|
||||||
|
rng_sequence = [3, 14, 1]
|
||||||
|
BalancerDeliveryMethod.random = FixedSequence.new(rng_sequence)
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
BalancerDeliveryMethod.random = Random.new
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sends emails randomly, given the provided weights' do
|
||||||
|
mail1 = ExampleMailer.greet('Lucia').deliver_now
|
||||||
|
expect(mail1).to have_been_delivered_using(MockSmtp)
|
||||||
|
|
||||||
|
mail2 = ExampleMailer.greet('Damian').deliver_now
|
||||||
|
expect(mail2).to have_been_delivered_using(MockSendmail)
|
||||||
|
|
||||||
|
mail3 = ExampleMailer.greet('Rahwa').deliver_now
|
||||||
|
expect(mail3).to have_been_delivered_using(MockSmtp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Helpers
|
||||||
|
|
||||||
|
def have_been_delivered_using(delivery_class)
|
||||||
|
satisfy("have been delivered using #{delivery_class}") do |mail|
|
||||||
|
delivery_class.deliveries.include?(mail)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,22 @@
|
||||||
|
describe '20220112184331_revise_attestation_templates' do
|
||||||
|
let(:rake_task) { Rake::Task['after_party:revise_attestation_templates'] }
|
||||||
|
let(:procedure) { create(:procedure) }
|
||||||
|
let(:attestation_template) { create(:attestation_template, procedure: procedure) }
|
||||||
|
|
||||||
|
subject(:run_task) do
|
||||||
|
attestation_template
|
||||||
|
rake_task.invoke
|
||||||
|
attestation_template.reload
|
||||||
|
end
|
||||||
|
|
||||||
|
after { rake_task.reenable }
|
||||||
|
|
||||||
|
describe 'revise_attestation_templates' do
|
||||||
|
it 'attaches the attestation_template to the latest revision (without removing the link between attestation_template and procedure for now)' do
|
||||||
|
expect(attestation_template.procedure.revisions.first.attestation_template_id).to be_nil
|
||||||
|
run_task
|
||||||
|
expect(attestation_template.procedure_id).to eq(procedure.id)
|
||||||
|
expect(attestation_template.procedure.revisions.first.attestation_template_id).to eq(attestation_template.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -4,6 +4,10 @@ describe Universign::API do
|
||||||
|
|
||||||
let(:digest) { Digest::SHA256.hexdigest("CECI EST UN HASH") }
|
let(:digest) { Digest::SHA256.hexdigest("CECI EST UN HASH") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
stub_const("UNIVERSIGN_API_URL", "https://ws.universign.eu/tsa/post/")
|
||||||
|
end
|
||||||
|
|
||||||
it { is_expected.not_to be_nil }
|
it { is_expected.not_to be_nil }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -66,16 +66,12 @@ describe Procedure do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#closed_mail_template_attestation_inconsistency_state' do
|
describe '#closed_mail_template_attestation_inconsistency_state' do
|
||||||
let(:procedure_without_attestation) { create(:procedure, closed_mail: closed_mail) }
|
let(:procedure_without_attestation) { create(:procedure, closed_mail: closed_mail, attestation_template: nil) }
|
||||||
let(:procedure_with_active_attestation) do
|
let(:procedure_with_active_attestation) do
|
||||||
procedure = create(:procedure, closed_mail: closed_mail)
|
create(:procedure, closed_mail: closed_mail, attestation_template: build(:attestation_template, activated: true))
|
||||||
create(:attestation_template, procedure: procedure, activated: true)
|
|
||||||
procedure
|
|
||||||
end
|
end
|
||||||
let(:procedure_with_inactive_attestation) do
|
let(:procedure_with_inactive_attestation) do
|
||||||
procedure = create(:procedure, closed_mail: closed_mail)
|
create(:procedure, closed_mail: closed_mail, attestation_template: build(:attestation_template, activated: false))
|
||||||
create(:attestation_template, procedure: procedure, activated: false)
|
|
||||||
procedure
|
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { procedure.closed_mail_template_attestation_inconsistency_state }
|
subject { procedure.closed_mail_template_attestation_inconsistency_state }
|
||||||
|
|
|
@ -9,6 +9,7 @@ end
|
||||||
|
|
||||||
Capybara.register_driver :headless_chrome do |app|
|
Capybara.register_driver :headless_chrome do |app|
|
||||||
options = Selenium::WebDriver::Chrome::Options.new
|
options = Selenium::WebDriver::Chrome::Options.new
|
||||||
|
options.add_argument('--no-sandbox') unless ENV['SANDBOX']
|
||||||
options.add_argument('--headless') unless ENV['NO_HEADLESS']
|
options.add_argument('--headless') unless ENV['NO_HEADLESS']
|
||||||
options.add_argument('--window-size=1440,900')
|
options.add_argument('--window-size=1440,900')
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
describe 'admin/_closed_mail_template_attestation_inconsistency_alert.html.haml', type: :view do
|
describe 'admin/_closed_mail_template_attestation_inconsistency_alert.html.haml', type: :view do
|
||||||
let(:procedure) { create(:procedure, closed_mail: closed_mail) }
|
let(:procedure) { create(:procedure, closed_mail: closed_mail, attestation_template: attestation_template) }
|
||||||
|
let(:attestation_template) { nil }
|
||||||
|
|
||||||
def alert
|
def alert
|
||||||
assign(:procedure, procedure)
|
assign(:procedure, procedure)
|
||||||
|
@ -23,7 +24,7 @@ describe 'admin/_closed_mail_template_attestation_inconsistency_alert.html.haml'
|
||||||
|
|
||||||
context 'when there is an active attestation but the closed mail template does not mention it' do
|
context 'when there is an active attestation but the closed mail template does not mention it' do
|
||||||
let(:closed_mail) { create(:closed_mail) }
|
let(:closed_mail) { create(:closed_mail) }
|
||||||
let!(:attestation_template) { create(:attestation_template, procedure: procedure, activated: true) }
|
let(:attestation_template) { build(:attestation_template) }
|
||||||
|
|
||||||
it { expect(alert).to include("Cette démarche comporte une attestation, mais l’accusé d’acceptation ne la mentionne pas") }
|
it { expect(alert).to include("Cette démarche comporte une attestation, mais l’accusé d’acceptation ne la mentionne pas") }
|
||||||
it { expect(alert).to include(edit_admin_procedure_mail_template_path(procedure, Mails::ClosedMail::SLUG)) }
|
it { expect(alert).to include(edit_admin_procedure_mail_template_path(procedure, Mails::ClosedMail::SLUG)) }
|
||||||
|
|
Loading…
Reference in a new issue