diff --git a/app/controllers/administrateurs/groupe_instructeurs_controller.rb b/app/controllers/administrateurs/groupe_instructeurs_controller.rb index fefcc681b..5229d8d6b 100644 --- a/app/controllers/administrateurs/groupe_instructeurs_controller.rb +++ b/app/controllers/administrateurs/groupe_instructeurs_controller.rb @@ -1,6 +1,9 @@ module Administrateurs class GroupeInstructeursController < AdministrateurController include ActiveSupport::NumberHelper + + before_action :ensure_not_super_admin!, only: [:add_instructeur] + ITEMS_PER_PAGE = 25 CSV_MAX_SIZE = 1.megabytes CSV_ACCEPTED_CONTENT_TYPES = [ @@ -10,6 +13,7 @@ module Administrateurs def index @procedure = procedure + @disabled_as_super_admin = is_administrateur_through_procedure_administration_as_manager? if procedure.routee? @groupes_instructeurs = paginated_groupe_instructeurs @@ -27,6 +31,7 @@ module Administrateurs @groupe_instructeur = groupe_instructeur @instructeurs = paginated_instructeurs @available_instructeur_emails = available_instructeur_emails + @disabled_as_super_admin = is_administrateur_through_procedure_administration_as_manager? end def create diff --git a/app/controllers/administrateurs/procedure_administrateurs_controller.rb b/app/controllers/administrateurs/procedure_administrateurs_controller.rb index 25b244929..06b063da2 100644 --- a/app/controllers/administrateurs/procedure_administrateurs_controller.rb +++ b/app/controllers/administrateurs/procedure_administrateurs_controller.rb @@ -2,6 +2,7 @@ module Administrateurs class ProcedureAdministrateursController < AdministrateurController before_action :retrieve_procedure, except: [:new] before_action :ensure_not_super_admin!, only: [:create] + def index @disabled_as_super_admin = is_administrateur_through_procedure_administration_as_manager? end diff --git a/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml b/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml index 657fb465b..ccd414e93 100644 --- a/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml +++ b/app/views/administrateurs/groupe_instructeurs/_instructeurs.html.haml @@ -5,15 +5,20 @@ .instructeur-wrapper - if !procedure.routee? %p.notice Entrez les adresses email des instructeurs que vous souhaitez affecter à cette démarche - = hidden_field_tag :emails, nil - = react_component("ComboMultiple", - options: available_instructeur_emails, selected: [], disabled: [], - group: '.instructeur-wrapper', - name: 'emails', - label: 'Emails', - acceptNewValues: true) - = f.submit 'Affecter', class: 'button primary send' + - if disabled_as_super_admin + = f.select :emails, available_instructeur_emails, {}, disabled: disabled_as_super_admin, id: 'instructeur_emails' + - else + = hidden_field_tag :emails, nil + = react_component("ComboMultiple", + options: available_instructeur_emails, selected: [], disabled: [], + group: '.instructeur-wrapper', + id: 'instructeur_emails', + name: 'emails', + label: 'Emails', + acceptNewValues: true) + + = f.submit 'Affecter', class: 'button primary send', disabled: disabled_as_super_admin %table.table.mt-2 %thead diff --git a/app/views/administrateurs/groupe_instructeurs/_routing.html.haml b/app/views/administrateurs/groupe_instructeurs/_routing.html.haml index 02f5ed9aa..75128b56c 100644 --- a/app/views/administrateurs/groupe_instructeurs/_routing.html.haml +++ b/app/views/administrateurs/groupe_instructeurs/_routing.html.haml @@ -1,6 +1,6 @@ .card - .card-title - = t('.title') + %h2.card-title= t('.title') + - if !procedure.routee? %p.notice= t('.notice_html') @@ -9,16 +9,16 @@ = link_to t('.button.routing_disable'), update_routing_enabled_admin_procedure_groupe_instructeurs_path(procedure, routing: :disable), class: 'button primary mt-1', method: 'patch' - else = link_to t('.button.routing_enable'), update_routing_enabled_admin_procedure_groupe_instructeurs_path(procedure, routing: :enable), class: 'button primary mt-1', method: 'patch' +.card + %h2.card-title L‘autogestion des instructeurs + %p.notice= t('.self_managment_notice_html') - .card-title.mt-4 L‘autogestion des instructeurs - %p.notice= t('.self_managment_notice_html') - - = form_for procedure, - method: :patch, - url: update_instructeurs_self_management_enabled_admin_procedure_groupe_instructeurs_path(procedure), - html: { class: 'form procedure-form__column--form no-background' } do |f| - %label.toggle-switch - = f.check_box :instructeurs_self_management_enabled, class: 'toggle-switch-checkbox', onchange: 'this.form.submit()' - %span.toggle-switch-control.round - %span.toggle-switch-label.on - %span.toggle-switch-label.off + = form_for procedure, + method: :patch, + url: update_instructeurs_self_management_enabled_admin_procedure_groupe_instructeurs_path(procedure), + html: { class: 'form procedure-form__column--form no-background' } do |f| + %label.toggle-switch + = f.check_box :instructeurs_self_management_enabled, class: 'toggle-switch-checkbox', onchange: 'this.form.submit()' + %span.toggle-switch-control.round + %span.toggle-switch-label.on + %span.toggle-switch-label.off diff --git a/app/views/administrateurs/groupe_instructeurs/index.html.haml b/app/views/administrateurs/groupe_instructeurs/index.html.haml index 80cdf9a22..5230f68d1 100644 --- a/app/views/administrateurs/groupe_instructeurs/index.html.haml +++ b/app/views/administrateurs/groupe_instructeurs/index.html.haml @@ -10,6 +10,8 @@ 'Instructeurs'] } .container.groupe-instructeur + %h1 Gérer les instructeurs et les options d'instruction de « #{@procedure.libelle} » + = render partial: 'administrateurs/groupe_instructeurs/routing', locals: { procedure: @procedure } - if @procedure.routee? @@ -19,4 +21,5 @@ locals: { procedure: @procedure, groupe_instructeur: @procedure.defaut_groupe_instructeur, instructeurs: @instructeurs, - available_instructeur_emails: @available_instructeur_emails } + available_instructeur_emails: @available_instructeur_emails, + disabled_as_super_admin: @disabled_as_super_admin } diff --git a/app/views/administrateurs/groupe_instructeurs/show.html.haml b/app/views/administrateurs/groupe_instructeurs/show.html.haml index aefd354ca..ce365c0e5 100644 --- a/app/views/administrateurs/groupe_instructeurs/show.html.haml +++ b/app/views/administrateurs/groupe_instructeurs/show.html.haml @@ -1,4 +1,3 @@ - = render partial: 'administrateurs/breadcrumbs', locals: { steps: [link_to('Démarches', admin_procedures_path), link_to(@procedure.libelle, admin_procedure_path(@procedure)), @@ -11,4 +10,5 @@ locals: { procedure: @procedure, groupe_instructeur: @groupe_instructeur, instructeurs: @instructeurs, - available_instructeur_emails: @available_instructeur_emails } + available_instructeur_emails: @available_instructeur_emails, + disabled_as_super_admin: @disabled_as_super_admin } diff --git a/spec/controllers/administrateurs/groupe_instructeurs_controller_spec.rb b/spec/controllers/administrateurs/groupe_instructeurs_controller_spec.rb index a8ddcc97b..cc2f34ceb 100644 --- a/spec/controllers/administrateurs/groupe_instructeurs_controller_spec.rb +++ b/spec/controllers/administrateurs/groupe_instructeurs_controller_spec.rb @@ -208,10 +208,11 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do end describe '#add_instructeur_procedure_non_routee' do - let(:procedure) { create :procedure, administrateur: admin } + let(:procedure) { create :procedure } + let!(:groupe_instructeur) { create(:administrateurs_procedure, procedure: procedure, administrateur: admin, manager: manager) } let(:emails) { ['instructeur_3@ministere_a.gouv.fr', 'instructeur_4@ministere_b.gouv.fr'].to_json } subject { post :add_instructeur, params: { emails: emails, procedure_id: procedure.id, id: gi_1_1.id } } - + let(:manager) { false } context 'when all emails are valid' do let(:emails) { ['test@b.gouv.fr', 'test2@b.gouv.fr'].to_json } it { expect(response.status).to eq(200) } @@ -233,18 +234,17 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do it { expect(subject.request.flash[:alert]).to be_present } it { expect(subject).to redirect_to admin_procedure_groupe_instructeurs_path(procedure) } end + + context 'when signed in admin comes from manager' do + let(:manager) { true } + it { is_expected.to have_http_status(:forbidden) } + end end describe '#add_instructeur' do let!(:instructeur) { create(:instructeur) } let(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') } - - before do - gi_1_2.instructeurs << instructeur - - allow(GroupeInstructeurMailer).to receive(:add_instructeurs) - .and_return(double(deliver_later: true)) - + let(:do_request) do post :add_instructeur, params: { procedure_id: procedure.id, @@ -252,10 +252,16 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do emails: new_instructeur_emails.to_json } end + before do + gi_1_2.instructeurs << instructeur + + allow(GroupeInstructeurMailer).to receive(:add_instructeurs) + .and_return(double(deliver_later: true)) + end context 'of a news instructeurs' do let(:new_instructeur_emails) { ['new_i1@mail.com', 'new_i2@mail.com'] } - + before { do_request } it { expect(gi_1_2.instructeurs.pluck(:email)).to include(*new_instructeur_emails) } it { expect(flash.notice).to be_present } it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) } @@ -271,22 +277,32 @@ describe Administrateurs::GroupeInstructeursController, type: :controller do context 'of an instructeur already in the group' do let(:new_instructeur_emails) { [instructeur.email] } - + before { do_request } it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) } end context 'of badly formed email' do let(:new_instructeur_emails) { ['badly_formed_email'] } - + before { do_request } it { expect(flash.alert).to be_present } it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) } end context 'of an empty string' do let(:new_instructeur_emails) { [''] } - + before { do_request } it { expect(response).to redirect_to(admin_procedure_groupe_instructeur_path(procedure, gi_1_2)) } end + + context 'when connected as an administrateur from manager' do + let(:new_instructeur_emails) { [instructeur.email] } + before do + admin.administrateurs_procedures.update_all(manager: true) + do_request + end + + it { expect(response).to have_http_status(:forbidden) } + end end describe '#remove_instructeur' do diff --git a/spec/system/administrateurs/procedure_administrateurs_spec.rb b/spec/system/administrateurs/procedure_administrateurs_spec.rb index 83b886a62..183f7f2bb 100644 --- a/spec/system/administrateurs/procedure_administrateurs_spec.rb +++ b/spec/system/administrateurs/procedure_administrateurs_spec.rb @@ -14,7 +14,7 @@ describe 'Administrateurs can manage administrateurs', js: true do scenario 'card is clickable' do visit admin_procedure_path(procedure) find('#administrateurs').click - expect(page).to have_css(:h1, text: "Administrateurs de « #{procedure.libelle} »") + expect(page).to have_css("h1", text: "Administrateurs de « #{procedure.libelle} »") end context 'as admin not flagged from manager' do diff --git a/spec/system/administrateurs/procedure_groupe_instructeur_spec.rb b/spec/system/administrateurs/procedure_groupe_instructeur_spec.rb new file mode 100644 index 000000000..5d76e6d69 --- /dev/null +++ b/spec/system/administrateurs/procedure_groupe_instructeur_spec.rb @@ -0,0 +1,47 @@ +require 'system/administrateurs/procedure_spec_helper' + +describe 'Manage procedure instructeurs', js: true do + include ProcedureSpecHelper + + let(:administrateur) { create(:administrateur) } + let!(:procedure) { create(:procedure) } + let!(:administrateurs_procedure) { create(:administrateurs_procedure, administrateur: administrateur, procedure: procedure, manager: manager) } + let(:manager) { false } + before do + login_as administrateur.user, scope: :user + end + + context 'is accessible via card' do + let(:manager) { false } + + scenario 'it works' do + visit admin_procedure_path(procedure) + byebug + find('#groupe-instructeurs').click + expect(page).to have_css("h1", text: "Gérer les instructeurs et les options d'instruction de « #{procedure.libelle} »") + end + end + + context 'as admin not from manager' do + let(:manager) { false } + + scenario 'can add instructeur' do + visit admin_procedure_groupe_instructeurs_path(procedure) + + expect { + fill_in "instructeur_emails", with: create(:instructeur).email + click_on "Affecter" + }.to change { procedure.instructeurs.count }.by(1) + end + end + + context 'as admin from manager' do + let(:manager) { true } + + scenario 'cannot add instructeur' do + visit admin_procedure_groupe_instructeurs_path(procedure) + + expect(page).to have_css("#instructeur_emails[disabled=\"disabled\"]") + end + end +end