commit
d23b2026c6
38 changed files with 339 additions and 345 deletions
1
Gemfile
1
Gemfile
|
@ -109,6 +109,7 @@ group :development do
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
|
gem 'axe-matchers' # accessibility rspec matchers
|
||||||
gem 'byebug' # Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
gem 'byebug' # Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
||||||
gem 'graphql-schema_comparator'
|
gem 'graphql-schema_comparator'
|
||||||
gem 'mina', git: 'https://github.com/mina-deploy/mina.git', require: false # Deploy
|
gem 'mina', git: 'https://github.com/mina-deploy/mina.git', require: false # Deploy
|
||||||
|
|
20
Gemfile.lock
20
Gemfile.lock
|
@ -97,6 +97,13 @@ GEM
|
||||||
attr_required (1.0.1)
|
attr_required (1.0.1)
|
||||||
autoprefixer-rails (9.7.4)
|
autoprefixer-rails (9.7.4)
|
||||||
execjs
|
execjs
|
||||||
|
axe-matchers (2.6.1)
|
||||||
|
dumb_delegator (~> 0.8)
|
||||||
|
virtus (~> 1.0)
|
||||||
|
axiom-types (0.1.1)
|
||||||
|
descendants_tracker (~> 0.0.4)
|
||||||
|
ice_nine (~> 0.11.0)
|
||||||
|
thread_safe (~> 0.3, >= 0.3.1)
|
||||||
axlsx_styler (1.0.0)
|
axlsx_styler (1.0.0)
|
||||||
activesupport (>= 3.1)
|
activesupport (>= 3.1)
|
||||||
caxlsx (>= 2.0.2)
|
caxlsx (>= 2.0.2)
|
||||||
|
@ -146,6 +153,8 @@ GEM
|
||||||
chunky_png (1.3.11)
|
chunky_png (1.3.11)
|
||||||
clamav-client (3.1.0)
|
clamav-client (3.1.0)
|
||||||
coderay (1.1.2)
|
coderay (1.1.2)
|
||||||
|
coercible (1.0.0)
|
||||||
|
descendants_tracker (~> 0.0.1)
|
||||||
coffee-rails (4.2.2)
|
coffee-rails (4.2.2)
|
||||||
coffee-script (>= 2.2.0)
|
coffee-script (>= 2.2.0)
|
||||||
railties (>= 4.0.0)
|
railties (>= 4.0.0)
|
||||||
|
@ -179,6 +188,8 @@ GEM
|
||||||
delayed_job (> 2.0.3)
|
delayed_job (> 2.0.3)
|
||||||
rack-protection (>= 1.5.5)
|
rack-protection (>= 1.5.5)
|
||||||
sinatra (>= 1.4.4)
|
sinatra (>= 1.4.4)
|
||||||
|
descendants_tracker (0.0.4)
|
||||||
|
thread_safe (~> 0.3, >= 0.3.1)
|
||||||
devise (4.7.1)
|
devise (4.7.1)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
|
@ -198,9 +209,11 @@ GEM
|
||||||
dotenv (= 2.7.5)
|
dotenv (= 2.7.5)
|
||||||
railties (>= 3.2, < 6.1)
|
railties (>= 3.2, < 6.1)
|
||||||
dry-inflector (0.2.0)
|
dry-inflector (0.2.0)
|
||||||
|
dumb_delegator (0.8.1)
|
||||||
em-websocket (0.5.1)
|
em-websocket (0.5.1)
|
||||||
eventmachine (>= 0.12.9)
|
eventmachine (>= 0.12.9)
|
||||||
http_parser.rb (~> 0.6.0)
|
http_parser.rb (~> 0.6.0)
|
||||||
|
equalizer (0.0.11)
|
||||||
erubi (1.9.0)
|
erubi (1.9.0)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
et-orbi (1.2.4)
|
et-orbi (1.2.4)
|
||||||
|
@ -319,6 +332,7 @@ GEM
|
||||||
httpclient (2.8.3)
|
httpclient (2.8.3)
|
||||||
i18n (1.8.3)
|
i18n (1.8.3)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
|
ice_nine (0.11.2)
|
||||||
ipaddress (0.8.3)
|
ipaddress (0.8.3)
|
||||||
jaro_winkler (1.5.4)
|
jaro_winkler (1.5.4)
|
||||||
jquery-rails (4.3.5)
|
jquery-rails (4.3.5)
|
||||||
|
@ -678,6 +692,11 @@ GEM
|
||||||
activemodel (>= 3.0.0)
|
activemodel (>= 3.0.0)
|
||||||
addressable
|
addressable
|
||||||
vcr (4.0.0)
|
vcr (4.0.0)
|
||||||
|
virtus (1.0.5)
|
||||||
|
axiom-types (~> 0.1)
|
||||||
|
coercible (~> 1.0)
|
||||||
|
descendants_tracker (~> 0.0, >= 0.0.3)
|
||||||
|
equalizer (~> 0.0, >= 0.0.9)
|
||||||
warden (1.2.8)
|
warden (1.2.8)
|
||||||
rack (>= 2.0.6)
|
rack (>= 2.0.6)
|
||||||
web-console (3.7.0)
|
web-console (3.7.0)
|
||||||
|
@ -728,6 +747,7 @@ DEPENDENCIES
|
||||||
administrate
|
administrate
|
||||||
after_party
|
after_party
|
||||||
anchored
|
anchored
|
||||||
|
axe-matchers
|
||||||
bcrypt
|
bcrypt
|
||||||
bootstrap-sass (>= 3.4.1)
|
bootstrap-sass (>= 3.4.1)
|
||||||
bootstrap-wysihtml5-rails (~> 0.3.3.8)
|
bootstrap-wysihtml5-rails (~> 0.3.3.8)
|
||||||
|
|
|
@ -16,3 +16,17 @@ $new-p-margin-bottom: 3 * $default-space;
|
||||||
.new-p {
|
.new-p {
|
||||||
margin-bottom: $new-p-margin-bottom;
|
margin-bottom: $new-p-margin-bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A class to make elements only accessible to screen-readers
|
||||||
|
.sr-only {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
opacity: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: -1px;
|
||||||
|
overflow: hidden;
|
||||||
|
clip: rect(0, 0, 0, 0);
|
||||||
|
white-space: nowrap;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@
|
||||||
.label {
|
.label {
|
||||||
width: 110px;
|
width: 110px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
margin: 0 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
class Admin::AssignsController < AdminController
|
|
||||||
include SmartListing::Helper::ControllerExtensions
|
|
||||||
helper SmartListing::Helper
|
|
||||||
|
|
||||||
before_action :retrieve_procedure
|
|
||||||
|
|
||||||
ASSIGN = 'assign'
|
|
||||||
NOT_ASSIGN = 'not_assign'
|
|
||||||
|
|
||||||
def show
|
|
||||||
assign_scope = @procedure.defaut_groupe_instructeur.instructeurs
|
|
||||||
|
|
||||||
@instructeurs_assign = smart_listing_create :instructeurs_assign,
|
|
||||||
assign_scope,
|
|
||||||
partial: "admin/assigns/list_assign",
|
|
||||||
array: true
|
|
||||||
|
|
||||||
not_assign_scope = current_administrateur.instructeurs.where.not(id: assign_scope.ids)
|
|
||||||
|
|
||||||
if params[:filter].present?
|
|
||||||
filter = params[:filter].downcase.strip
|
|
||||||
not_assign_scope = not_assign_scope.where('users.email LIKE ?', "%#{filter}%")
|
|
||||||
end
|
|
||||||
|
|
||||||
@instructeurs_not_assign = smart_listing_create :instructeurs_not_assign,
|
|
||||||
not_assign_scope,
|
|
||||||
partial: "admin/assigns/list_not_assign",
|
|
||||||
array: true
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
instructeur = Instructeur.find(params[:instructeur_id])
|
|
||||||
procedure = Procedure.find(params[:procedure_id])
|
|
||||||
to = params[:to]
|
|
||||||
|
|
||||||
case to
|
|
||||||
when ASSIGN
|
|
||||||
if instructeur.assign_to_procedure(procedure)
|
|
||||||
flash.notice = "L'instructeur a bien été affecté"
|
|
||||||
else
|
|
||||||
flash.alert = "L'instructeur a déjà été affecté"
|
|
||||||
end
|
|
||||||
when NOT_ASSIGN
|
|
||||||
if instructeur.remove_from_procedure(procedure)
|
|
||||||
flash.notice = "L'instructeur a bien été désaffecté"
|
|
||||||
else
|
|
||||||
flash.alert = "L'instructeur a déjà été désaffecté"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
redirect_to admin_procedure_assigns_path, procedure_id: params[:procedure_id]
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -13,6 +13,7 @@ class Admin::InstructeursController < AdminController
|
||||||
email = params[:instructeur][:email].downcase
|
email = params[:instructeur][:email].downcase
|
||||||
@instructeur = Instructeur.by_email(email)
|
@instructeur = Instructeur.by_email(email)
|
||||||
procedure_id = params[:procedure_id]
|
procedure_id = params[:procedure_id]
|
||||||
|
procedure = Procedure.find_by(id: procedure_id)
|
||||||
|
|
||||||
if @instructeur.nil?
|
if @instructeur.nil?
|
||||||
invite_instructeur(email)
|
invite_instructeur(email)
|
||||||
|
@ -21,7 +22,7 @@ class Admin::InstructeursController < AdminController
|
||||||
end
|
end
|
||||||
|
|
||||||
if procedure_id.present?
|
if procedure_id.present?
|
||||||
redirect_to admin_procedure_assigns_path(procedure_id: procedure_id)
|
redirect_to procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur)
|
||||||
else
|
else
|
||||||
redirect_to admin_instructeurs_path
|
redirect_to admin_instructeurs_path
|
||||||
end
|
end
|
||||||
|
|
|
@ -100,16 +100,27 @@ module NewAdministrateur
|
||||||
create_instructeur(instructeur_email)
|
create_instructeur(instructeur_email)
|
||||||
end
|
end
|
||||||
|
|
||||||
groupe_instructeur.instructeurs << instructeurs
|
if procedure.routee?
|
||||||
|
groupe_instructeur.instructeurs << instructeurs
|
||||||
|
|
||||||
GroupeInstructeurMailer
|
GroupeInstructeurMailer
|
||||||
.add_instructeurs(groupe_instructeur, instructeurs, current_user.email)
|
.add_instructeurs(groupe_instructeur, instructeurs, current_user.email)
|
||||||
.deliver_later
|
.deliver_later
|
||||||
|
|
||||||
flash[:notice] = t('.assignment',
|
flash[:notice] = t('.assignment',
|
||||||
count: email_to_adds.count,
|
count: email_to_adds.count,
|
||||||
value: email_to_adds.join(', '),
|
value: email_to_adds.join(', '),
|
||||||
groupe: groupe_instructeur.label)
|
groupe: groupe_instructeur.label)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if instructeurs.present?
|
||||||
|
instructeurs.each do |instructeur|
|
||||||
|
instructeur.assign_to_procedure(procedure)
|
||||||
|
end
|
||||||
|
flash[:notice] = "Les instructeurs ont bien été affectés à la démarche"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_to procedure_groupe_instructeur_path(procedure, groupe_instructeur)
|
redirect_to procedure_groupe_instructeur_path(procedure, groupe_instructeur)
|
||||||
|
@ -120,14 +131,23 @@ module NewAdministrateur
|
||||||
flash[:alert] = "Suppression impossible : il doit y avoir au moins un instructeur dans le groupe"
|
flash[:alert] = "Suppression impossible : il doit y avoir au moins un instructeur dans le groupe"
|
||||||
|
|
||||||
else
|
else
|
||||||
@instructeur = Instructeur.find(instructeur_id)
|
if procedure.routee?
|
||||||
groupe_instructeur.instructeurs.destroy(@instructeur)
|
@instructeur = Instructeur.find(instructeur_id)
|
||||||
flash[:notice] = "L’instructeur « #{@instructeur.email} » a été retiré du groupe."
|
groupe_instructeur.instructeurs.destroy(@instructeur)
|
||||||
GroupeInstructeurMailer
|
flash[:notice] = "L’instructeur « #{@instructeur.email} » a été retiré du groupe."
|
||||||
.remove_instructeur(groupe_instructeur, @instructeur, current_user.email)
|
GroupeInstructeurMailer
|
||||||
.deliver_later
|
.remove_instructeur(groupe_instructeur, @instructeur, current_user.email)
|
||||||
end
|
.deliver_later
|
||||||
|
else
|
||||||
|
|
||||||
|
instructeur = Instructeur.find(instructeur_id)
|
||||||
|
if instructeur.remove_from_procedure(procedure)
|
||||||
|
flash[:notice] = "L'instructeur a bien été désaffecté de la démarche"
|
||||||
|
else
|
||||||
|
flash[:alert] = "Suppression impossible : il doit y avoir au moins un instructeur dans le groupe"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
redirect_to procedure_groupe_instructeur_path(procedure, groupe_instructeur)
|
redirect_to procedure_groupe_instructeur_path(procedure, groupe_instructeur)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1177,7 +1177,7 @@ enum TypeDeChamp {
|
||||||
dossier_link
|
dossier_link
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Menu déroulant
|
Choix parmi une liste
|
||||||
"""
|
"""
|
||||||
drop_down_list
|
drop_down_list
|
||||||
|
|
||||||
|
@ -1212,7 +1212,7 @@ enum TypeDeChamp {
|
||||||
linked_drop_down_list
|
linked_drop_down_list
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Menu déroulant à choix multiples
|
Choix multiples
|
||||||
"""
|
"""
|
||||||
multiple_drop_down_list
|
multiple_drop_down_list
|
||||||
|
|
||||||
|
@ -1317,4 +1317,4 @@ type ValidationError {
|
||||||
A description of the error
|
A description of the error
|
||||||
"""
|
"""
|
||||||
message: String!
|
message: String!
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,4 +40,7 @@ if (enabled) {
|
||||||
'session:event',
|
'session:event',
|
||||||
[[['PAGE_VIEW', { URL: window.location.pathname }]]]
|
[[['PAGE_VIEW', { URL: window.location.pathname }]]]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Prevent Crisp to log warnings about Sentry overriding document.addEventListener
|
||||||
|
window.$crisp.push(['safe', true]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,6 @@
|
||||||
class AdministrationMailer < ApplicationMailer
|
class AdministrationMailer < ApplicationMailer
|
||||||
layout 'mailers/layout'
|
layout 'mailers/layout'
|
||||||
|
|
||||||
def new_admin_email(admin, administration)
|
|
||||||
@admin = admin
|
|
||||||
@administration = administration
|
|
||||||
subject = "Création d'un compte admininistrateur"
|
|
||||||
|
|
||||||
mail(to: TECH_EMAIL,
|
|
||||||
subject: subject)
|
|
||||||
end
|
|
||||||
|
|
||||||
def invite_admin(admin, reset_password_token, administration_id)
|
def invite_admin(admin, reset_password_token, administration_id)
|
||||||
@reset_password_token = reset_password_token
|
@reset_password_token = reset_password_token
|
||||||
@admin = admin
|
@admin = admin
|
||||||
|
|
|
@ -11,7 +11,6 @@ class Administration < ApplicationRecord
|
||||||
user = User.create_or_promote_to_administrateur(email, SecureRandom.hex)
|
user = User.create_or_promote_to_administrateur(email, SecureRandom.hex)
|
||||||
|
|
||||||
if user.valid?
|
if user.valid?
|
||||||
AdministrationMailer.new_admin_email(user.administrateur, self).deliver_later
|
|
||||||
user.invite_administrateur!(id)
|
user.invite_administrateur!(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
.row{ style: 'height: 34px;' }
|
|
||||||
|
|
||||||
- if smart_listing.present?
|
|
||||||
%table.table#liste-instructeur
|
|
||||||
%thead
|
|
||||||
%th Enlever
|
|
||||||
%th#email{ style: 'text-align: right;' } Email
|
|
||||||
|
|
||||||
- @instructeurs_assign.each do |instructeur|
|
|
||||||
%tr
|
|
||||||
%td.col-md-1.col-lg-1.col-sm-1.col-xs-1.col-sm-1.col-xs-1.center
|
|
||||||
= link_to "#{admin_procedure_assigns_path(procedure_id: @procedure.id, instructeur_id: instructeur.id, to: Admin::AssignsController::NOT_ASSIGN)}", class: "btn btn-primary", 'data-method' => 'put' do
|
|
||||||
.fa.fa-arrow-left
|
|
||||||
%td{ style: 'padding-top: 11px; font-size: 15px; text-align: right;' }= instructeur.email
|
|
||||||
|
|
||||||
= smart_listing.paginate
|
|
||||||
= smart_listing.pagination_per_page_links
|
|
||||||
- else
|
|
||||||
%h4.center
|
|
||||||
Aucun d'affecté
|
|
|
@ -1,27 +0,0 @@
|
||||||
= smart_listing_controls_for(:instructeurs_not_assign, { class: "form-inline text-right" }) do
|
|
||||||
.form-group.filter.input-append
|
|
||||||
= text_field_tag :filter, '', class: "search form-control",
|
|
||||||
placeholder: "Recherche...", autocomplete: :off
|
|
||||||
%button.btn.btn-primary{ type: :submit }
|
|
||||||
%span.fa.fa-search
|
|
||||||
|
|
||||||
- if smart_listing.present?
|
|
||||||
|
|
||||||
%table.table#liste-instructeur
|
|
||||||
%thead
|
|
||||||
%th#email Email
|
|
||||||
%th Ajouter
|
|
||||||
|
|
||||||
- @instructeurs_not_assign.each do |instructeur|
|
|
||||||
%tr
|
|
||||||
%td.col-xs-11{ style: 'padding-top: 11px; font-size: 15px;' }= instructeur.email
|
|
||||||
%td.center
|
|
||||||
= link_to "#{admin_procedure_assigns_path(procedure_id: @procedure.id, instructeur_id: instructeur.id, to: Admin::AssignsController::ASSIGN)}", class: "btn btn-success instructeur-affectation", 'data-method' => 'put' do
|
|
||||||
.fa.fa-arrow-right
|
|
||||||
|
|
||||||
|
|
||||||
= smart_listing.paginate
|
|
||||||
= smart_listing.pagination_per_page_links
|
|
||||||
- else
|
|
||||||
%h4.center
|
|
||||||
Aucun de disponible
|
|
|
@ -1,23 +0,0 @@
|
||||||
.row.white-back
|
|
||||||
#instructeur_form
|
|
||||||
.row
|
|
||||||
.col-xs-6
|
|
||||||
%h3.text-info Disponibles
|
|
||||||
= smart_listing_render :instructeurs_not_assign
|
|
||||||
|
|
||||||
%br
|
|
||||||
%h3
|
|
||||||
= t('dynamics.admin.procedure.onglet_instructeurs.add.title')
|
|
||||||
#procedure_new.section.section-label
|
|
||||||
= form_with url: { controller: 'admin/instructeurs', action: :create } do
|
|
||||||
.row
|
|
||||||
.col-xs-5
|
|
||||||
= hidden_field_tag :procedure_id, params[:procedure_id]
|
|
||||||
= render partial: 'admin/instructeurs/informations'
|
|
||||||
.col-xs-2
|
|
||||||
%br
|
|
||||||
%br
|
|
||||||
= submit_tag 'Ajouter', class: 'btn btn-info', style: 'float: left;', id: 'add-instructeur-email'
|
|
||||||
.col-xs-6
|
|
||||||
%h3.text-success Affectés
|
|
||||||
= smart_listing_render :instructeurs_assign
|
|
|
@ -1,3 +0,0 @@
|
||||||
<%= smart_listing_update :instructeurs_not_assign %>
|
|
||||||
|
|
||||||
<%= smart_listing_update :instructeurs_assign %>
|
|
|
@ -1,4 +1,4 @@
|
||||||
.form-group
|
.form-group
|
||||||
%h4
|
%p.notice
|
||||||
= 'Email *'
|
= 'Email *'
|
||||||
= text_field_tag 'instructeur[email]', nil, class: 'form-control', placeholder: 'laura.azema@exemple.gouv.fr'
|
= text_field_tag 'instructeur[email]', nil, class: 'form-control', placeholder: 'ex : laura.azema@exemple.gouv.fr'
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
.alert.alert-info
|
.alert.alert-info
|
||||||
Pour pouvoir tester cette démarche, vous devez d’abord lui affecter
|
Pour pouvoir tester cette démarche, vous devez d’abord lui affecter
|
||||||
- if @procedure.missing_instructeurs?
|
- if @procedure.missing_instructeurs?
|
||||||
= link_to("des instructeurs", admin_procedure_assigns_path(@procedure))
|
= link_to("des instructeurs", procedure_groupe_instructeur_path(@procedure, @procedure.defaut_groupe_instructeur))
|
||||||
- if @procedure.missing_instructeurs? && @procedure.service.nil?
|
- if @procedure.missing_instructeurs? && @procedure.service.nil?
|
||||||
et
|
et
|
||||||
- if @procedure.service.nil?
|
- if @procedure.service.nil?
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
- if @procedure.missing_steps.include?(:instructeurs)
|
- if @procedure.missing_steps.include?(:instructeurs)
|
||||||
%p.alert.alert-danger
|
%p.alert.alert-danger
|
||||||
Vous devez affecter des instructeurs avant de pouvoir publier votre démarche.
|
Vous devez affecter des instructeurs avant de pouvoir publier votre démarche.
|
||||||
= link_to 'Cliquez ici.', admin_procedure_assigns_path(@procedure)
|
= link_to 'Cliquez ici.', procedure_groupe_instructeur_path(@procedure, @procedure.defaut_groupe_instructeur)
|
||||||
|
|
||||||
%p.alert.alert-info
|
%p.alert.alert-info
|
||||||
Cette démarche n’a pas encore de lien, et n’est pas accessible par le public.
|
Cette démarche n’a pas encore de lien, et n’est pas accessible par le public.
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
Administrateurs
|
Administrateurs
|
||||||
|
|
||||||
- if !feature_enabled?(:administrateur_routage)
|
- if !feature_enabled?(:administrateur_routage)
|
||||||
%a#onglet-instructeurs{ href: url_for(admin_procedure_assigns_path(@procedure)) }
|
%a#onglet-instructeurs{ href: url_for(procedure_groupe_instructeur_path(@procedure, @procedure.defaut_groupe_instructeur)) }
|
||||||
.procedure-list-element{ class: ('active' if active == 'Instructeurs') }
|
.procedure-list-element{ class: ('active' if active == 'Instructeurs') }
|
||||||
Instructeurs
|
Instructeurs
|
||||||
- if @procedure.missing_steps.include?(:instructeurs)
|
- if @procedure.missing_steps.include?(:instructeurs)
|
||||||
|
|
9
app/views/new_administrateur/_groups_header.haml
Normal file
9
app/views/new_administrateur/_groups_header.haml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
%h1 Groupe « #{@groupe_instructeur.label} »
|
||||||
|
.card.mt-2
|
||||||
|
= form_for @groupe_instructeur,
|
||||||
|
url: procedure_groupe_instructeur_path(@procedure, @groupe_instructeur),
|
||||||
|
html: { class: 'form' } do |f|
|
||||||
|
|
||||||
|
= f.label :label, 'Nom du groupe'
|
||||||
|
= f.text_field :label, placeholder: 'Ville de Bordeaux', required: true
|
||||||
|
= f.submit 'Renommer', class: 'button primary send'
|
|
@ -1,20 +1,20 @@
|
||||||
= render partial: 'new_administrateur/breadcrumbs',
|
|
||||||
locals: { steps: [link_to('Démarches', admin_procedures_path),
|
- if feature_enabled?(:administrateur_routage)
|
||||||
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
|
= render partial: 'new_administrateur/breadcrumbs',
|
||||||
link_to('Groupes d’instructeurs', procedure_groupe_instructeurs_path(@procedure)),
|
locals: { steps: [link_to('Démarches', admin_procedures_path),
|
||||||
@groupe_instructeur.label] }
|
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
|
||||||
|
link_to('Groupes d’instructeurs', procedure_groupe_instructeurs_path(@procedure)),
|
||||||
|
@groupe_instructeur.label] }
|
||||||
|
- else
|
||||||
|
= render partial: 'new_administrateur/breadcrumbs',
|
||||||
|
locals: { steps: [link_to('Démarches', admin_procedures_path),
|
||||||
|
link_to(@procedure.libelle, admin_procedure_path(@procedure)),
|
||||||
|
'Instructeurs'] }
|
||||||
|
|
||||||
.container.groupe-instructeur
|
.container.groupe-instructeur
|
||||||
%h1 Groupe « #{@groupe_instructeur.label} »
|
|
||||||
|
|
||||||
.card.mt-2
|
- if feature_enabled?(:administrateur_routage)
|
||||||
= form_for @groupe_instructeur,
|
= render partial: 'new_administrateur/groups_header'
|
||||||
url: procedure_groupe_instructeur_path(@procedure, @groupe_instructeur),
|
|
||||||
html: { class: 'form' } do |f|
|
|
||||||
|
|
||||||
= f.label :label, 'Nom du groupe'
|
|
||||||
= f.text_field :label, placeholder: 'Ville de Bordeaux', required: true
|
|
||||||
= f.submit 'Renommer', class: 'button primary send'
|
|
||||||
|
|
||||||
.card
|
.card
|
||||||
.card-title Affectation des instructeurs
|
.card-title Affectation des instructeurs
|
||||||
|
@ -23,6 +23,8 @@
|
||||||
html: { class: 'form' } do |f|
|
html: { class: 'form' } do |f|
|
||||||
|
|
||||||
.instructeur-wrapper
|
.instructeur-wrapper
|
||||||
|
- if !@procedure.routee?
|
||||||
|
%p.notice Entrez les adresses email des instructeurs que vous souhaitez affecter à cette démarche
|
||||||
= select_tag :emails,
|
= select_tag :emails,
|
||||||
options_for_select(@available_instructeur_emails),
|
options_for_select(@available_instructeur_emails),
|
||||||
multiple: true,
|
multiple: true,
|
||||||
|
@ -43,7 +45,7 @@
|
||||||
%td.actions= button_to 'retirer',
|
%td.actions= button_to 'retirer',
|
||||||
{ action: :remove_instructeur },
|
{ action: :remove_instructeur },
|
||||||
{ method: :delete,
|
{ method: :delete,
|
||||||
data: { confirm: "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » du groupe « #{@groupe_instructeur.label} » ?" },
|
data: { confirm: feature_enabled?(:administrateur_routage) ? "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » du groupe « #{@groupe_instructeur.label} » ?" : "Êtes-vous sûr de vouloir retirer l’instructeur « #{instructeur.email} » de la démarche ?" },
|
||||||
params: { instructeur: { id: instructeur.id }},
|
params: { instructeur: { id: instructeur.id }},
|
||||||
class: 'button' }
|
class: 'button' }
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
= render partial: "shared/attachment/show", locals: { attachment: attachment, user_can_upload: true }
|
= render partial: "shared/attachment/show", locals: { attachment: attachment, user_can_upload: true }
|
||||||
- if user_can_destroy
|
- if user_can_destroy
|
||||||
.attachment-action
|
.attachment-action
|
||||||
= link_to 'Supprimer', attachment_url(attachment.id, { signed_id: attachment.blob.signed_id }), remote: true, method: :delete, class: 'button small danger'
|
= link_to 'Supprimer', attachment_url(attachment.id, { signed_id: attachment.blob.signed_id }), remote: true, method: :delete, class: 'button small danger', data: { disable: true }
|
||||||
.attachment-action
|
.attachment-action
|
||||||
= button_tag 'Remplacer', type: 'button', class: 'button small', data: { 'toggle-target': ".attachment-input-#{attachment_id}" }
|
= button_tag 'Remplacer', type: 'button', class: 'button small', data: { 'toggle-target': ".attachment-input-#{attachment_id}" }
|
||||||
|
|
||||||
|
|
|
@ -29,36 +29,31 @@
|
||||||
%table.table.dossiers-table.hoverable
|
%table.table.dossiers-table.hoverable
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th.notification-col
|
|
||||||
%th.number-col Nº dossier
|
%th.number-col Nº dossier
|
||||||
%th Démarche
|
%th Démarche
|
||||||
- if @dossiers.count > 1
|
- if @dossiers.count > 1
|
||||||
%th Demandeur
|
%th Demandeur
|
||||||
%th.status-col Statut
|
%th.status-col Statut
|
||||||
%th.updated-at-col Mis à jour
|
%th.updated-at-col Mis à jour
|
||||||
%th
|
%th.sr-only Actions
|
||||||
%tbody
|
%tbody
|
||||||
- @dossiers.each do |dossier|
|
- @dossiers.each do |dossier|
|
||||||
%tr{ data: { 'dossier-id': dossier.id } }
|
%tr{ data: { 'dossier-id': dossier.id } }
|
||||||
%td.folder-col
|
|
||||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
|
||||||
%span.icon.folder
|
|
||||||
%td.number-col
|
%td.number-col
|
||||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
= link_to(url_for_dossier(dossier), class: 'cell-link', tabindex: -1) do
|
||||||
|
%span.icon.folder
|
||||||
= dossier.id
|
= dossier.id
|
||||||
%td
|
%td
|
||||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
||||||
= procedure_libelle(dossier.procedure)
|
= procedure_libelle(dossier.procedure)
|
||||||
- if @dossiers.count > 1
|
- if @dossiers.count > 1
|
||||||
%td.number-col
|
%td.cell-link
|
||||||
= demandeur_dossier(dossier)
|
= demandeur_dossier(dossier)
|
||||||
%td.status-col
|
%td.status-col
|
||||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
= status_badge(dossier.state)
|
||||||
= status_badge(dossier.state)
|
%td.updated-at-col.cell-link
|
||||||
%td.updated-at-col
|
= try_format_date(dossier.updated_at)
|
||||||
= link_to(url_for_dossier(dossier), class: 'cell-link') do
|
%td.action-col
|
||||||
= try_format_date(dossier.updated_at)
|
|
||||||
%td.action-col.action-col
|
|
||||||
= render partial: 'dossier_actions', locals: { dossier: dossier }
|
= render partial: 'dossier_actions', locals: { dossier: dossier }
|
||||||
= paginate(@dossiers)
|
= paginate(@dossiers)
|
||||||
|
|
||||||
|
|
5
bors.toml
Normal file
5
bors.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
status = [
|
||||||
|
"ci/circleci: build",
|
||||||
|
"ci/circleci: test",
|
||||||
|
"ci/circleci: lint"
|
||||||
|
]
|
|
@ -18,8 +18,8 @@ fr:
|
||||||
phone: 'Téléphone'
|
phone: 'Téléphone'
|
||||||
address: 'Adresse'
|
address: 'Adresse'
|
||||||
yes_no: 'Oui/Non'
|
yes_no: 'Oui/Non'
|
||||||
drop_down_list: 'Menu déroulant'
|
drop_down_list: 'Choix parmi une liste'
|
||||||
multiple_drop_down_list: 'Menu déroulant à choix multiples'
|
multiple_drop_down_list: 'Choix multiples'
|
||||||
linked_drop_down_list: 'Deux menus déroulants liés'
|
linked_drop_down_list: 'Deux menus déroulants liés'
|
||||||
pays: 'Pays'
|
pays: 'Pays'
|
||||||
regions: 'Régions'
|
regions: 'Régions'
|
||||||
|
|
|
@ -202,8 +202,6 @@ Rails.application.routes.draw do
|
||||||
post 'transfer' => 'procedures#transfer', as: :transfer
|
post 'transfer' => 'procedures#transfer', as: :transfer
|
||||||
put 'clone' => 'procedures#clone', as: :clone
|
put 'clone' => 'procedures#clone', as: :clone
|
||||||
|
|
||||||
resource :assigns, only: [:show, :update], path: 'instructeurs'
|
|
||||||
|
|
||||||
resource :attestation_template, only: [:edit, :update, :create]
|
resource :attestation_template, only: [:edit, :update, :create]
|
||||||
|
|
||||||
post 'attestation_template/disactivate' => 'attestation_templates#disactivate'
|
post 'attestation_template/disactivate' => 'attestation_templates#disactivate'
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
describe Admin::AssignsController, type: :controller do
|
|
||||||
let(:admin) { create(:administrateur) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
sign_in(admin.user)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'GET #show' do
|
|
||||||
let(:procedure) { create :procedure, administrateur: admin, instructeurs: [instructeur_assigned_1, instructeur_assigned_2] }
|
|
||||||
let!(:instructeur_assigned_1) { create :instructeur, email: 'instructeur_1@ministere_a.gouv.fr', administrateurs: [admin] }
|
|
||||||
let!(:instructeur_assigned_2) { create :instructeur, email: 'instructeur_2@ministere_b.gouv.fr', administrateurs: [admin] }
|
|
||||||
let!(:instructeur_not_assigned_1) { create :instructeur, email: 'instructeur_3@ministere_a.gouv.fr', administrateurs: [admin] }
|
|
||||||
let!(:instructeur_not_assigned_2) { create :instructeur, email: 'instructeur_4@ministere_b.gouv.fr', administrateurs: [admin] }
|
|
||||||
let(:filter) { nil }
|
|
||||||
|
|
||||||
subject! { get :show, params: { procedure_id: procedure.id, filter: filter } }
|
|
||||||
|
|
||||||
it { expect(response.status).to eq(200) }
|
|
||||||
|
|
||||||
it 'sets the assigned and not assigned instructeurs' do
|
|
||||||
expect(assigns(:instructeurs_assign)).to match_array([instructeur_assigned_1, instructeur_assigned_2])
|
|
||||||
expect(assigns(:instructeurs_not_assign)).to match_array([instructeur_not_assigned_1, instructeur_not_assigned_2])
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with a search filter' do
|
|
||||||
let(:filter) { '@ministere_a.gouv.fr' }
|
|
||||||
|
|
||||||
it 'filters the unassigned instructeurs' do
|
|
||||||
expect(assigns(:instructeurs_not_assign)).to match_array([instructeur_not_assigned_1])
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not filter the assigned instructeurs' do
|
|
||||||
expect(assigns(:instructeurs_assign)).to match_array([instructeur_assigned_1, instructeur_assigned_2])
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the filter has spaces or a mixed case' do
|
|
||||||
let(:filter) { ' @ministere_A.gouv.fr ' }
|
|
||||||
|
|
||||||
it 'trims spaces and ignores the case' do
|
|
||||||
expect(assigns(:instructeurs_not_assign)).to match_array([instructeur_not_assigned_1])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'PUT #update' do
|
|
||||||
let(:procedure) { create :procedure, administrateur: admin }
|
|
||||||
let(:instructeur) { create :instructeur, administrateurs: [admin] }
|
|
||||||
|
|
||||||
subject { put :update, params: { instructeur_id: instructeur.id, procedure_id: procedure.id, to: 'assign' } }
|
|
||||||
|
|
||||||
it { expect(subject).to redirect_to admin_procedure_assigns_path(procedure_id: procedure.id) }
|
|
||||||
|
|
||||||
context 'when assignement is valid' do
|
|
||||||
before do
|
|
||||||
subject
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(flash[:notice]).to be_present }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -42,9 +42,8 @@ describe Admin::InstructeursController, type: :controller do
|
||||||
context 'when procedure_id params is not null' do
|
context 'when procedure_id params is not null' do
|
||||||
let(:procedure) { create :procedure }
|
let(:procedure) { create :procedure }
|
||||||
let(:procedure_id) { procedure.id }
|
let(:procedure_id) { procedure.id }
|
||||||
|
|
||||||
it { expect(response.status).to eq(302) }
|
it { expect(response.status).to eq(302) }
|
||||||
it { expect(response).to redirect_to admin_procedure_assigns_path(procedure_id: procedure_id) }
|
it { expect(response).to redirect_to procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'Instructeur attributs in database' do
|
describe 'Instructeur attributs in database' do
|
||||||
|
|
|
@ -36,8 +36,6 @@ describe Manager::AdministrateursController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'alert new mail are send' do
|
it 'alert new mail are send' do
|
||||||
expect(AdministrationMailer).to receive(:new_admin_email).and_return(AdministrationMailer)
|
|
||||||
expect(AdministrationMailer).to receive(:deliver_later)
|
|
||||||
expect(AdministrationMailer).to receive(:invite_admin).and_return(AdministrationMailer)
|
expect(AdministrationMailer).to receive(:invite_admin).and_return(AdministrationMailer)
|
||||||
expect(AdministrationMailer).to receive(:deliver_later)
|
expect(AdministrationMailer).to receive(:deliver_later)
|
||||||
subject
|
subject
|
||||||
|
|
|
@ -31,6 +31,22 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
|
|
||||||
it { expect(response).to have_http_status(:ok) }
|
it { expect(response).to have_http_status(:ok) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when the routage is not activated on the procedure' do
|
||||||
|
let(:procedure) { create :procedure, administrateur: admin, instructeurs: [instructeur_assigned_1, instructeur_assigned_2] }
|
||||||
|
let!(:instructeur_assigned_1) { create :instructeur, email: 'instructeur_1@ministere_a.gouv.fr', administrateurs: [admin] }
|
||||||
|
let!(:instructeur_assigned_2) { create :instructeur, email: 'instructeur_2@ministere_b.gouv.fr', administrateurs: [admin] }
|
||||||
|
let!(:instructeur_not_assigned_1) { create :instructeur, email: 'instructeur_3@ministere_a.gouv.fr', administrateurs: [admin] }
|
||||||
|
let!(:instructeur_not_assigned_2) { create :instructeur, email: 'instructeur_4@ministere_b.gouv.fr', administrateurs: [admin] }
|
||||||
|
subject! { get :show, params: { procedure_id: procedure.id, id: gi_1_1.id } }
|
||||||
|
|
||||||
|
it { expect(response.status).to eq(200) }
|
||||||
|
|
||||||
|
it 'sets the assigned and not assigned instructeurs' do
|
||||||
|
expect(assigns(:instructeurs)).to match_array([instructeur_assigned_1, instructeur_assigned_2])
|
||||||
|
expect(assigns(:available_instructeur_emails)).to match_array(['instructeur_3@ministere_a.gouv.fr', 'instructeur_4@ministere_b.gouv.fr'])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#create' do
|
describe '#create' do
|
||||||
|
@ -189,10 +205,40 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#add_instructeur_procedure_non_routee' do
|
||||||
|
let(:procedure) { create :procedure, administrateur: admin }
|
||||||
|
let(:emails) { ['instructeur_3@ministere_a.gouv.fr', 'instructeur_4@ministere_b.gouv.fr'] }
|
||||||
|
subject { post :add_instructeur, params: { emails: emails, procedure_id: procedure.id, id: gi_1_1.id } }
|
||||||
|
|
||||||
|
context 'when all emails are valid' do
|
||||||
|
let(:emails) { ['test@b.gouv.fr', 'test2@b.gouv.fr'] }
|
||||||
|
it { expect(response.status).to eq(200) }
|
||||||
|
it { expect(subject.request.flash[:alert]).to be_nil }
|
||||||
|
it { expect(subject.request.flash[:notice]).to be_present }
|
||||||
|
it { expect(subject).to redirect_to procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when there is at least one bad email' do
|
||||||
|
let(:emails) { ['badmail', 'instructeur2@gmail.com'] }
|
||||||
|
it { expect(response.status).to eq(200) }
|
||||||
|
it { expect(subject.request.flash[:alert]).to be_present }
|
||||||
|
it { expect(subject.request.flash[:notice]).to be_present }
|
||||||
|
it { expect(subject).to redirect_to procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the admin wants to assign an instructor who is already assigned on this procedure' do
|
||||||
|
let(:emails) { ['instructeur_1@ministere_a.gouv.fr'] }
|
||||||
|
it { expect(subject.request.flash[:alert]).to be_present }
|
||||||
|
it { expect(subject).to redirect_to procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#add_instructeur' do
|
describe '#add_instructeur' do
|
||||||
let!(:instructeur) { create(:instructeur) }
|
let!(:instructeur) { create(:instructeur) }
|
||||||
|
let(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
gi_1_1.instructeurs << instructeur
|
gi_1_2.instructeurs << instructeur
|
||||||
|
|
||||||
allow(GroupeInstructeurMailer).to receive(:add_instructeurs)
|
allow(GroupeInstructeurMailer).to receive(:add_instructeurs)
|
||||||
.and_return(double(deliver_later: true))
|
.and_return(double(deliver_later: true))
|
||||||
|
@ -200,7 +246,7 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
post :add_instructeur,
|
post :add_instructeur,
|
||||||
params: {
|
params: {
|
||||||
procedure_id: procedure.id,
|
procedure_id: procedure.id,
|
||||||
id: gi_1_1.id,
|
id: gi_1_2.id,
|
||||||
emails: new_instructeur_emails
|
emails: new_instructeur_emails
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -208,12 +254,13 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
context 'of a news instructeurs' do
|
context 'of a news instructeurs' do
|
||||||
let(:new_instructeur_emails) { ['new_i1@mail.com', 'new_i2@mail.com'] }
|
let(:new_instructeur_emails) { ['new_i1@mail.com', 'new_i2@mail.com'] }
|
||||||
|
|
||||||
it { expect(gi_1_1.instructeurs.pluck(:email)).to include(*new_instructeur_emails) }
|
it { expect(gi_1_2.instructeurs.pluck(:email)).to include(*new_instructeur_emails) }
|
||||||
it { expect(flash.notice).to be_present }
|
it { expect(flash.notice).to be_present }
|
||||||
it { expect(response).to redirect_to(procedure_groupe_instructeur_path(procedure, gi_1_1)) }
|
it { expect(response).to redirect_to(procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
||||||
|
it { expect(procedure.routee?).to be_truthy }
|
||||||
it "calls GroupeInstructeurMailer with the right groupe and instructeurs" do
|
it "calls GroupeInstructeurMailer with the right groupe and instructeurs" do
|
||||||
expect(GroupeInstructeurMailer).to have_received(:add_instructeurs).with(
|
expect(GroupeInstructeurMailer).to have_received(:add_instructeurs).with(
|
||||||
gi_1_1,
|
gi_1_2,
|
||||||
satisfy { |instructeurs| instructeurs.all? { |i| new_instructeur_emails.include?(i.email) } },
|
satisfy { |instructeurs| instructeurs.all? { |i| new_instructeur_emails.include?(i.email) } },
|
||||||
admin.email
|
admin.email
|
||||||
)
|
)
|
||||||
|
@ -223,20 +270,20 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
context 'of an instructeur already in the group' do
|
context 'of an instructeur already in the group' do
|
||||||
let(:new_instructeur_emails) { [instructeur.email] }
|
let(:new_instructeur_emails) { [instructeur.email] }
|
||||||
|
|
||||||
it { expect(response).to redirect_to(procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur)) }
|
it { expect(response).to redirect_to(procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'of badly formed email' do
|
context 'of badly formed email' do
|
||||||
let(:new_instructeur_emails) { ['badly_formed_email'] }
|
let(:new_instructeur_emails) { ['badly_formed_email'] }
|
||||||
|
|
||||||
it { expect(flash.alert).to be_present }
|
it { expect(flash.alert).to be_present }
|
||||||
it { expect(response).to redirect_to(procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur)) }
|
it { expect(response).to redirect_to(procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'of an empty string' do
|
context 'of an empty string' do
|
||||||
let(:new_instructeur_emails) { '' }
|
let(:new_instructeur_emails) { '' }
|
||||||
|
|
||||||
it { expect(response).to redirect_to(procedure_groupe_instructeur_path(procedure, procedure.defaut_groupe_instructeur)) }
|
it { expect(response).to redirect_to(procedure_groupe_instructeur_path(procedure, gi_1_2)) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -275,6 +322,33 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#remove_instructeur_procedure_non_routee' do
|
||||||
|
let(:procedure) { create :procedure, administrateur: admin, instructeurs: [instructeur_assigned_1, instructeur_assigned_2] }
|
||||||
|
let!(:instructeur_assigned_1) { create :instructeur, email: 'instructeur_1@ministere_a.gouv.fr', administrateurs: [admin] }
|
||||||
|
let!(:instructeur_assigned_2) { create :instructeur, email: 'instructeur_2@ministere_b.gouv.fr', administrateurs: [admin] }
|
||||||
|
let!(:instructeur_assigned_3) { create :instructeur, email: 'instructeur_3@ministere_a.gouv.fr', administrateurs: [admin] }
|
||||||
|
subject! { get :show, params: { procedure_id: procedure.id, id: gi_1_1.id } }
|
||||||
|
it 'sets the assigned instructeurs' do
|
||||||
|
expect(assigns(:instructeurs)).to match_array([instructeur_assigned_1, instructeur_assigned_2])
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the instructor is assigned to the procedure' do
|
||||||
|
subject { delete :remove_instructeur, params: { instructeur: { id: instructeur_assigned_1.id }, procedure_id: procedure.id, id: gi_1_1.id } }
|
||||||
|
it { expect(subject.request.flash[:notice]).to be_present }
|
||||||
|
it { expect(subject.request.flash[:alert]).to be_nil }
|
||||||
|
it { expect(response.status).to eq(302) }
|
||||||
|
it { expect(subject).to redirect_to procedure_groupe_instructeur_path(procedure, gi_1_1) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the instructor is not assigned to the procedure' do
|
||||||
|
subject { delete :remove_instructeur, params: { instructeur: { id: instructeur_assigned_3.id }, procedure_id: procedure.id, id: gi_1_1.id } }
|
||||||
|
it { expect(subject.request.flash[:alert]).to be_present }
|
||||||
|
it { expect(subject.request.flash[:notice]).to be_nil }
|
||||||
|
it { expect(response.status).to eq(302) }
|
||||||
|
it { expect(subject).to redirect_to procedure_groupe_instructeur_path(procedure, gi_1_1) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#update_routing_criteria_name' do
|
describe '#update_routing_criteria_name' do
|
||||||
before do
|
before do
|
||||||
patch :update_routing_criteria_name,
|
patch :update_routing_criteria_name,
|
||||||
|
|
|
@ -50,7 +50,7 @@ FactoryBot.define do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:datetime) }
|
type_champ { TypeDeChamp.type_champs.fetch(:datetime) }
|
||||||
end
|
end
|
||||||
factory :type_de_champ_drop_down_list do
|
factory :type_de_champ_drop_down_list do
|
||||||
libelle { 'Menu déroulant' }
|
libelle { 'Choix parmi une liste' }
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:drop_down_list) }
|
type_champ { TypeDeChamp.type_champs.fetch(:drop_down_list) }
|
||||||
drop_down_list_value { "val1\r\nval2\r\n--separateur--\r\nval3" }
|
drop_down_list_value { "val1\r\nval2\r\n--separateur--\r\nval3" }
|
||||||
trait :long do
|
trait :long do
|
||||||
|
|
124
spec/features/accessibilite/wcag_usager_spec.rb
Normal file
124
spec/features/accessibilite/wcag_usager_spec.rb
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
feature 'wcag rules for usager', js: true do
|
||||||
|
let(:procedure) { create(:procedure, :with_type_de_champ, :with_all_champs, :with_service, :for_individual, :published) }
|
||||||
|
let(:password) { 'a very complicated password' }
|
||||||
|
let(:litteraire_user) { create(:user, password: password) }
|
||||||
|
|
||||||
|
context 'pages without the need to be logged in' do
|
||||||
|
scenario 'homepage' do
|
||||||
|
visit root_path
|
||||||
|
expect(page).to be_accessible.excluding ".footer-logo"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'sign_up page' do
|
||||||
|
visit new_user_registration_path
|
||||||
|
expect(page).to be_accessible.excluding ".footer-logo"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'account confirmation page' do
|
||||||
|
visit new_user_registration_path
|
||||||
|
|
||||||
|
fill_in :user_email, with: "some@email.com"
|
||||||
|
fill_in :user_password, with: "epeciusetuir"
|
||||||
|
|
||||||
|
perform_enqueued_jobs do
|
||||||
|
click_button 'Créer un compte'
|
||||||
|
expect(page).to be_accessible.skipping(:'page-has-heading-one', :'role-img-alt', :label)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'sign_in page' do
|
||||||
|
visit new_user_session_path
|
||||||
|
expect(page).to be_accessible.excluding ".footer-logo", '#user_email'
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'contact page' do
|
||||||
|
visit contact_path
|
||||||
|
expect(page).to be_accessible.excluding ".footer-logo"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'commencer page' do
|
||||||
|
visit commencer_path(path: procedure.reload.path)
|
||||||
|
expect(page).to be_accessible
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "logged in, depot d'un dossier as individual" do
|
||||||
|
before do
|
||||||
|
login_as litteraire_user, scope: :user
|
||||||
|
visit commencer_path(path: procedure.reload.path)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'écran identité usager' do
|
||||||
|
click_on 'Commencer la démarche'
|
||||||
|
expect(page).to be_accessible
|
||||||
|
end
|
||||||
|
|
||||||
|
# with no surprise, there's a lot of work on this one
|
||||||
|
scenario "dépot d'un dossier" do
|
||||||
|
click_on 'Commencer la démarche'
|
||||||
|
|
||||||
|
choose 'M.'
|
||||||
|
fill_in('individual_prenom', with: 'prenom')
|
||||||
|
fill_in('individual_nom', with: 'nom')
|
||||||
|
click_on 'Continuer'
|
||||||
|
|
||||||
|
expect(page).to be_accessible.skipping :'aria-input-field-name', :'heading-order', :label
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "logged in, depot d'un dossier entreprise" do
|
||||||
|
let(:procedure) { create(:procedure, :with_type_de_champ, :with_all_champs, :with_service, :published) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
login_as litteraire_user, scope: :user
|
||||||
|
visit commencer_path(path: procedure.reload.path)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "écran identification de l'entreprise" do
|
||||||
|
click_on 'Commencer la démarche'
|
||||||
|
expect(page).to be_accessible.skipping :label
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "logged in, avec des dossiers dossiers déposés" do
|
||||||
|
let(:dossier) { create(:dossier, procedure: procedure, user: litteraire_user) }
|
||||||
|
before do
|
||||||
|
login_as litteraire_user, scope: :user
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'liste des dossiers' do
|
||||||
|
visit dossiers_path
|
||||||
|
expect(page).to be_accessible
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'dossier' do
|
||||||
|
visit dossier_path(dossier)
|
||||||
|
expect(page).to be_accessible.skipping :'heading-order', :label, :'aria-input-field-name'
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'merci' do
|
||||||
|
visit merci_dossier_path(dossier)
|
||||||
|
expect(page).to be_accessible
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'demande' do
|
||||||
|
visit demande_dossier_path(dossier)
|
||||||
|
expect(page).to be_accessible
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'messagerie' do
|
||||||
|
visit messagerie_dossier_path(dossier)
|
||||||
|
expect(page).to be_accessible
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'modifier' do
|
||||||
|
visit modifier_dossier_path(dossier)
|
||||||
|
expect(page).to be_accessible.skipping :'aria-input-field-name', :'heading-order', :label
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'brouillon' do
|
||||||
|
visit brouillon_dossier_path(dossier)
|
||||||
|
expect(page).to be_accessible.skipping :'aria-input-field-name', :'heading-order', :label
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,7 +5,7 @@ feature 'As an instructeur', js: true do
|
||||||
|
|
||||||
before do
|
before do
|
||||||
login_as administrateur.user, scope: :user
|
login_as administrateur.user, scope: :user
|
||||||
visit admin_procedure_assigns_path(procedure)
|
visit admin_instructeurs_path
|
||||||
|
|
||||||
fill_in :instructeur_email, with: instructeur_email
|
fill_in :instructeur_email, with: instructeur_email
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ feature 'As an administrateur I can edit types de champ', js: true do
|
||||||
it "Add dropdown champ" do
|
it "Add dropdown champ" do
|
||||||
add_champ
|
add_champ
|
||||||
|
|
||||||
select('Menu déroulant', from: 'champ-0-type_champ')
|
select('Choix parmi une liste', from: 'champ-0-type_champ')
|
||||||
fill_in 'champ-0-libelle', with: 'Libellé de champ menu déroulant', fill_options: { clear: :backspace }
|
fill_in 'champ-0-libelle', with: 'Libellé de champ menu déroulant', fill_options: { clear: :backspace }
|
||||||
fill_in 'champ-0-drop_down_list_value', with: 'Un menu', fill_options: { clear: :backspace }
|
fill_in 'champ-0-drop_down_list_value', with: 'Un menu', fill_options: { clear: :backspace }
|
||||||
|
|
||||||
|
|
|
@ -32,14 +32,14 @@ feature 'The routing', js: true do
|
||||||
# add victor to littéraire groupe
|
# add victor to littéraire groupe
|
||||||
find('input.select2-search__field').send_keys('victor@inst.com', :enter)
|
find('input.select2-search__field').send_keys('victor@inst.com', :enter)
|
||||||
perform_enqueued_jobs { click_on 'Affecter' }
|
perform_enqueued_jobs { click_on 'Affecter' }
|
||||||
expect(page).to have_text("L’instructeur victor@inst.com a été affecté")
|
expect(page).to have_text("Les instructeurs ont bien été affectés à la démarche")
|
||||||
|
|
||||||
victor = User.find_by(email: 'victor@inst.com').instructeur
|
victor = User.find_by(email: 'victor@inst.com').instructeur
|
||||||
|
|
||||||
# add superwoman to littéraire groupe
|
# add superwoman to littéraire groupe
|
||||||
find('input.select2-search__field').send_keys('superwoman@inst.com', :enter)
|
find('input.select2-search__field').send_keys('superwoman@inst.com', :enter)
|
||||||
perform_enqueued_jobs { click_on 'Affecter' }
|
perform_enqueued_jobs { click_on 'Affecter' }
|
||||||
expect(page).to have_text("L’instructeur superwoman@inst.com a été affecté")
|
expect(page).to have_text("Les instructeurs ont bien été affectés à la démarche")
|
||||||
|
|
||||||
superwoman = User.find_by(email: 'superwoman@inst.com').instructeur
|
superwoman = User.find_by(email: 'superwoman@inst.com').instructeur
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,4 @@
|
||||||
RSpec.describe AdministrationMailer, type: :mailer do
|
RSpec.describe AdministrationMailer, type: :mailer do
|
||||||
describe '#new_admin_email' do
|
|
||||||
let(:admin) { create(:administrateur) }
|
|
||||||
let(:administration) { create(:administration) }
|
|
||||||
|
|
||||||
subject { described_class.new_admin_email(admin, administration) }
|
|
||||||
|
|
||||||
it { expect(subject.subject).not_to be_empty }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#invite_admin' do
|
describe '#invite_admin' do
|
||||||
let(:admin) { create(:administrateur) }
|
let(:admin) { create(:administrateur) }
|
||||||
let(:token) { "Toc toc toc" }
|
let(:token) { "Toc toc toc" }
|
||||||
|
|
|
@ -19,11 +19,6 @@ class AdministrationMailerPreview < ActionMailer::Preview
|
||||||
AdministrationMailer.refuse_admin('bad_admin@pipo.com')
|
AdministrationMailer.refuse_admin('bad_admin@pipo.com')
|
||||||
end
|
end
|
||||||
|
|
||||||
def new_admin
|
|
||||||
administration = Administration.new(email: 'superadmin@demarches-simplifiees.fr')
|
|
||||||
AdministrationMailer.new_admin_email(administrateur, administration)
|
|
||||||
end
|
|
||||||
|
|
||||||
def dossier_expiration_summary
|
def dossier_expiration_summary
|
||||||
expiring_dossiers = [Dossier.new(id: 100, procedure: procedure_1)]
|
expiring_dossiers = [Dossier.new(id: 100, procedure: procedure_1)]
|
||||||
expired_dossiers = [Dossier.new(id: 100, procedure: procedure_2)]
|
expired_dossiers = [Dossier.new(id: 100, procedure: procedure_2)]
|
||||||
|
|
|
@ -26,6 +26,7 @@ require 'webmock/rspec'
|
||||||
require 'shoulda-matchers'
|
require 'shoulda-matchers'
|
||||||
require 'devise'
|
require 'devise'
|
||||||
require 'factory_bot'
|
require 'factory_bot'
|
||||||
|
require 'axe/rspec'
|
||||||
|
|
||||||
require 'selenium/webdriver'
|
require 'selenium/webdriver'
|
||||||
Capybara.javascript_driver = :headless_chrome
|
Capybara.javascript_driver = :headless_chrome
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
describe 'admin/assigns/show.html.haml', type: :view do
|
|
||||||
let(:admin) { create(:administrateur) }
|
|
||||||
let(:procedure) { create :procedure, administrateur: admin }
|
|
||||||
|
|
||||||
let(:assign_instructeurs) { procedure.defaut_groupe_instructeur.instructeurs }
|
|
||||||
let(:not_assign_instructeurs) { admin.instructeurs.where.not(id: assign_instructeurs.ids) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
assign(:procedure, procedure)
|
|
||||||
assign(:instructeur, create(:instructeur))
|
|
||||||
|
|
||||||
assign(:instructeurs_assign, (smart_listing_create :instructeurs_assign,
|
|
||||||
assign_instructeurs,
|
|
||||||
partial: "admin/assigns/list_assign",
|
|
||||||
array: true))
|
|
||||||
|
|
||||||
assign(:instructeurs_not_assign, (smart_listing_create :instructeurs_not_assign,
|
|
||||||
not_assign_instructeurs,
|
|
||||||
partial: "admin/assigns/list_not_assign",
|
|
||||||
array: true))
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when admin have none instructeur ' do
|
|
||||||
before do
|
|
||||||
render
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(rendered).to have_content('Aucun de disponible') }
|
|
||||||
|
|
||||||
context 'when administrateur have none instructeur assign' do
|
|
||||||
it { expect(rendered).to have_content('Aucun d\'affecté') }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when administrateur have two instructeur' do
|
|
||||||
let!(:instructeur_1) { create :instructeur, email: 'plop@plop.com', administrateurs: [admin] }
|
|
||||||
let!(:instructeur_2) { create :instructeur, email: 'plip@plop.com', administrateurs: [admin] }
|
|
||||||
|
|
||||||
before do
|
|
||||||
not_assign_instructeurs.reload
|
|
||||||
assign_instructeurs.reload
|
|
||||||
|
|
||||||
assign(:instructeurs_assign, (smart_listing_create :instructeurs_assign,
|
|
||||||
assign_instructeurs,
|
|
||||||
partial: "admin/assigns/list_assign",
|
|
||||||
array: true))
|
|
||||||
|
|
||||||
assign(:instructeurs_not_assign, (smart_listing_create :instructeurs_not_assign,
|
|
||||||
not_assign_instructeurs,
|
|
||||||
partial: "admin/assigns/list_not_assign",
|
|
||||||
array: true))
|
|
||||||
|
|
||||||
render
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(rendered).to have_content(instructeur_1.email) }
|
|
||||||
it { expect(rendered).to have_content(instructeur_2.email) }
|
|
||||||
end
|
|
||||||
end
|
|
Loading…
Reference in a new issue