diff --git a/app/controllers/admin/procedures_controller.rb b/app/controllers/admin/procedures_controller.rb index 8159a9240..ad6cb6b2c 100644 --- a/app/controllers/admin/procedures_controller.rb +++ b/app/controllers/admin/procedures_controller.rb @@ -109,22 +109,15 @@ class Admin::ProceduresController < AdminController return redirect_to admin_procedures_path end - procedure_path = ProcedurePath.find_by(path: params[:procedure_path]) - if procedure_path - if procedure_path.administrateur_id == current_administrateur.id - procedure_path.procedure.archive - procedure_path.delete - else - @mine = false - return render '/admin/procedures/publish', formats: 'js' - end + if procedure.may_publish?(params[:procedure_path]) + procedure.publish!(params[:procedure_path]) + + flash.notice = "Procédure publiée" + redirect_to admin_procedures_path + else + @mine = false + render '/admin/procedures/publish', formats: 'js' end - - procedure.publish!(params[:procedure_path]) - - flash.notice = "Procédure publiée" - render js: "window.location = '#{admin_procedures_path}'" - rescue ActiveRecord::RecordNotFound flash.alert = 'Procédure inexistante' redirect_to admin_procedures_path @@ -149,7 +142,7 @@ class Admin::ProceduresController < AdminController def archive procedure = current_administrateur.procedures.find(params[:procedure_id]) - procedure.archive + procedure.archive! flash.notice = "Procédure archivée" redirect_to admin_procedures_path diff --git a/app/jobs/auto_archive_procedure_job.rb b/app/jobs/auto_archive_procedure_job.rb index 007eeb179..0d5665bee 100644 --- a/app/jobs/auto_archive_procedure_job.rb +++ b/app/jobs/auto_archive_procedure_job.rb @@ -7,7 +7,7 @@ class AutoArchiveProcedureJob < ApplicationJob dossier.en_instruction! end - procedure.archive + procedure.archive! end end end diff --git a/app/models/administrateur.rb b/app/models/administrateur.rb index fbf62a854..e1063b294 100644 --- a/app/models/administrateur.rb +++ b/app/models/administrateur.rb @@ -101,6 +101,10 @@ class Administrateur < ApplicationRecord save end + def owns?(procedure) + id == procedure.administrateur_id + end + private def generate_api_token diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 5b4dc03fc..a1927ca16 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -45,6 +45,77 @@ class Procedure < ApplicationRecord validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :description, presence: true, allow_blank: false, allow_nil: false + include AASM + + aasm whiny_persistence: true do + state :brouillon, initial: true + state :publiee + state :archivee + state :hidden + + event :publish, after: :after_publish, guard: :can_publish? do + transitions from: :brouillon, to: :publiee + transitions from: :archivee, to: :publiee + end + + event :archive, after: :after_archive do + transitions from: :publiee, to: :archivee + end + + event :hide, after: :after_hide do + transitions from: :brouillon, to: :hidden + transitions from: :publiee, to: :hidden + transitions from: :archivee, to: :hidden + end + end + + def after_publish(path) + now = Time.now + update( + test_started_at: now, + archived_at: nil, + published_at: now + ) + procedure_path = ProcedurePath.find_by(path: path) + + if procedure_path.present? + if procedure_path.procedure != self + procedure_path.procedure.archive! + procedure_path.update(procedure: self) + end + else + ProcedurePath.create(procedure: self, administrateur: administrateur, path: path) + end + end + + def after_archive + update(archived_at: Time.now) + end + + def after_hide + now = Time.now + update(hidden_at: now) + procedure_path&.hide!(self) + dossiers.update_all(hidden_at: now) + end + + def locked? + publiee_ou_archivee? + end + + def publiee_ou_archivee? + publiee? || archivee? + end + + def can_publish?(path) + procedure_path = ProcedurePath.find_by(path: path) + if procedure_path.present? + administrateur.owns?(procedure_path) + else + true + end + end + # Warning: dossier after_save build_default_champs must be removed # to save a dossier created from this method def new_dossier @@ -63,13 +134,6 @@ class Procedure < ApplicationRecord ProcedurePath.find_with_procedure(self) end - def hide! - now = DateTime.now - update(hidden_at: now, aasm_state: :hidden) - procedure_path&.hide!(self) - dossiers.update_all(hidden_at: now) - end - def path procedure_path.path if procedure_path.present? end @@ -120,10 +184,6 @@ class Procedure < ApplicationRecord end end - def locked? - publiee_ou_archivee? - end - def clone(admin, from_library) procedure = self.deep_clone(include: { @@ -161,32 +221,6 @@ class Procedure < ApplicationRecord procedure end - def brouillon? - published_at.nil? - end - - def publish!(path) - now = Time.now - self.update!({ test_started_at: now, published_at: now, archived_at: nil, aasm_state: :publiee }) - ProcedurePath.create!(path: path, procedure: self, administrateur: self.administrateur) - end - - def publiee? - published_at.present? && archived_at.nil? - end - - def archive - self.update!(archived_at: Time.now, aasm_state: :archivee) - end - - def archivee? - published_at.present? && archived_at.present? - end - - def publiee_ou_archivee? - publiee? || archivee? - end - def whitelisted? whitelisted_at.present? end diff --git a/spec/controllers/admin/pieces_justificatives_controller_spec.rb b/spec/controllers/admin/pieces_justificatives_controller_spec.rb index 2034cf2d3..9877752f5 100644 --- a/spec/controllers/admin/pieces_justificatives_controller_spec.rb +++ b/spec/controllers/admin/pieces_justificatives_controller_spec.rb @@ -2,8 +2,7 @@ require 'spec_helper' describe Admin::PiecesJustificativesController, type: :controller do let(:admin) { create(:administrateur) } - let(:published_at) { nil } - let(:procedure) { create(:procedure, administrateur: admin, published_at: published_at) } + let(:procedure) { create(:procedure, administrateur: admin) } before do sign_in admin end @@ -19,7 +18,7 @@ describe Admin::PiecesJustificativesController, type: :controller do end context 'when procedure is published' do - let(:published_at) { Time.now } + let(:procedure) { create(:procedure, :published, administrateur: admin) } it { is_expected.to redirect_to admin_procedure_path id: procedure_id } end diff --git a/spec/controllers/admin/procedures_controller_spec.rb b/spec/controllers/admin/procedures_controller_spec.rb index 77ed13327..89444b56b 100644 --- a/spec/controllers/admin/procedures_controller_spec.rb +++ b/spec/controllers/admin/procedures_controller_spec.rb @@ -92,8 +92,8 @@ describe Admin::ProceduresController, type: :controller do describe 'DELETE #destroy' do let(:procedure_draft) { create :procedure, administrateur: admin, published_at: nil, archived_at: nil } - let(:procedure_published) { create :procedure, administrateur: admin, published_at: Time.now, archived_at: nil } - let(:procedure_archived) { create :procedure, administrateur: admin, published_at: nil, archived_at: Time.now } + let(:procedure_published) { create :procedure, administrateur: admin, aasm_state: :publiee, published_at: Time.now, archived_at: nil } + let(:procedure_archived) { create :procedure, administrateur: admin, aasm_state: :archivee, published_at: nil, archived_at: Time.now } subject { delete :destroy, params: { id: procedure.id } } @@ -344,7 +344,7 @@ describe Admin::ProceduresController, type: :controller do it 'publish the given procedure' do expect(procedure.publiee?).to be_truthy expect(procedure.path).to eq(procedure_path) - expect(response.status).to eq 200 + expect(response.status).to eq 302 expect(flash[:notice]).to have_content 'Procédure publiée' end end @@ -355,7 +355,7 @@ describe Admin::ProceduresController, type: :controller do it 'publish the given procedure' do expect(procedure.publiee?).to be_truthy expect(procedure.path).to eq(procedure_path) - expect(response.status).to eq 200 + expect(response.status).to eq 302 expect(flash[:notice]).to have_content 'Procédure publiée' end @@ -432,8 +432,8 @@ describe Admin::ProceduresController, type: :controller do procedure.reload end - it { expect(procedure.archivee?).to be_falsey } - it { expect(response.status).to eq 200 } + it { expect(procedure.publiee?).to be_truthy } + it { expect(response.status).to eq 302 } it { expect(flash[:notice]).to have_content 'Procédure publiée' } end end diff --git a/spec/controllers/admin/types_de_champ_controller_spec.rb b/spec/controllers/admin/types_de_champ_controller_spec.rb index e14f11107..fa50a89fa 100644 --- a/spec/controllers/admin/types_de_champ_controller_spec.rb +++ b/spec/controllers/admin/types_de_champ_controller_spec.rb @@ -9,8 +9,7 @@ describe Admin::TypesDeChampController, type: :controller do end describe 'GET #show' do - let(:published_at) { nil } - let(:procedure) { create(:procedure, administrateur: admin, published_at: published_at) } + let(:procedure) { create(:procedure, :published, administrateur: admin) } let(:procedure_id) { procedure.id } subject { get :show, params: { procedure_id: procedure_id } } @@ -21,7 +20,6 @@ describe Admin::TypesDeChampController, type: :controller do end context 'when procedure is published' do - let(:published_at) { Time.now } it { is_expected.to redirect_to admin_procedure_path id: procedure_id } end diff --git a/spec/controllers/admin/types_de_champ_private_controller_spec.rb b/spec/controllers/admin/types_de_champ_private_controller_spec.rb index d3a48202b..60ac7b79a 100644 --- a/spec/controllers/admin/types_de_champ_private_controller_spec.rb +++ b/spec/controllers/admin/types_de_champ_private_controller_spec.rb @@ -9,8 +9,7 @@ describe Admin::TypesDeChampPrivateController, type: :controller do end describe 'GET #show' do - let(:published_at) { nil } - let(:procedure) { create(:procedure, administrateur: admin, published_at: published_at) } + let(:procedure) { create(:procedure, :published, administrateur: admin) } let(:procedure_id) { procedure.id } subject { get :show, params: { procedure_id: procedure_id } } @@ -21,7 +20,6 @@ describe Admin::TypesDeChampPrivateController, type: :controller do end context 'when procedure is published' do - let(:published_at) { Time.now } it { is_expected.to redirect_to admin_procedure_path id: procedure_id } end diff --git a/spec/controllers/new_gestionnaire/procedures_controller_spec.rb b/spec/controllers/new_gestionnaire/procedures_controller_spec.rb index e7c76b2a9..ac5fe7b55 100644 --- a/spec/controllers/new_gestionnaire/procedures_controller_spec.rb +++ b/spec/controllers/new_gestionnaire/procedures_controller_spec.rb @@ -99,7 +99,7 @@ describe NewGestionnaire::ProceduresController, type: :controller do context "with procedures assigned" do let(:procedure1) { create(:procedure, :published) } - let(:procedure2) { create(:procedure, :published, :archived) } + let(:procedure2) { create(:procedure, :archived) } let(:procedure3) { create(:procedure) } before do diff --git a/spec/controllers/users/description_controller_shared_example.rb b/spec/controllers/users/description_controller_shared_example.rb index d4ad3ed47..05354ccea 100644 --- a/spec/controllers/users/description_controller_shared_example.rb +++ b/spec/controllers/users/description_controller_shared_example.rb @@ -26,7 +26,7 @@ shared_examples 'description_controller_spec' do context 'procedure is archived' do render_views - let(:archived_at) { Time.now } + let(:archived) { true } it { expect(response).to have_http_status(:success) } it { expect(response.body).to_not have_content(I18n.t('errors.messages.procedure_archived')) } @@ -329,7 +329,7 @@ shared_examples 'description_controller_spec' do end context 'La procédure est archivée' do - let(:archived_at) { Time.now } + let(:archived) { true } before do post :update, params: { dossier_id: dossier.id } diff --git a/spec/controllers/users/description_controller_spec.rb b/spec/controllers/users/description_controller_spec.rb index fef283d04..6582209e0 100644 --- a/spec/controllers/users/description_controller_spec.rb +++ b/spec/controllers/users/description_controller_spec.rb @@ -5,10 +5,15 @@ require 'controllers/users/description_controller_shared_example' describe Users::DescriptionController, type: :controller, vcr: { cassette_name: 'controllers_users_description_controller' } do let(:owner_user) { create(:user) } let(:invite_by_user) { create :user, email: 'invite@plop.com' } - let(:archived_at) { nil } + let(:archived) { false } let(:state) { 'en_construction' } - - let(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, :with_type_de_champ, :with_datetime, cerfa_flag: true, published_at: Time.now, archived_at: archived_at) } + let(:procedure) do + if archived + create(:procedure, :archived, :with_two_type_de_piece_justificative, :with_type_de_champ, :with_datetime, cerfa_flag: true) + else + create(:procedure, :published, :with_two_type_de_piece_justificative, :with_type_de_champ, :with_datetime, cerfa_flag: true) + end + end let(:dossier) { create(:dossier, procedure: procedure, user: owner_user, state: state) } let(:dossier_id) { dossier.id } diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb index 216d82fa0..2208e04a7 100644 --- a/spec/controllers/users/dossiers_controller_spec.rb +++ b/spec/controllers/users/dossiers_controller_spec.rb @@ -159,17 +159,13 @@ describe Users::DossiersController, type: :controller do it { expect(subject).to redirect_to new_users_dossier_path(procedure_id: procedure.id) } context 'when procedure is archived' do - let(:procedure) { create(:procedure, :published, archived_at: Time.now) } - - before do - procedure.update_column :archived_at, Time.now - end + let(:procedure) { create(:procedure, :archived) } it { expect(subject.status).to eq 200 } end context 'when procedure is hidden' do - let(:procedure) { create(:procedure, :published, hidden_at: DateTime.now) } + let(:procedure) { create(:procedure, :hidden) } it { expect(subject).to redirect_to(root_path) } end diff --git a/spec/factories/procedure.rb b/spec/factories/procedure.rb index a48a054c8..26446239d 100644 --- a/spec/factories/procedure.rb +++ b/spec/factories/procedure.rb @@ -100,14 +100,22 @@ FactoryBot.define do end trait :published do - after(:create) do |procedure, _evaluator| + after(:build) do |procedure, _evaluator| procedure.publish!(generate(:published_path)) end end trait :archived do after(:build) do |procedure, _evaluator| - procedure.archived_at = Time.now + procedure.publish!(generate(:published_path)) + procedure.archive! + end + end + + trait :hidden do + after(:build) do |procedure, _evaluator| + procedure.publish!(generate(:published_path)) + procedure.hide! end end diff --git a/spec/jobs/auto_archive_procedure_job_spec.rb b/spec/jobs/auto_archive_procedure_job_spec.rb index bd2fcc02d..372845f90 100644 --- a/spec/jobs/auto_archive_procedure_job_spec.rb +++ b/spec/jobs/auto_archive_procedure_job_spec.rb @@ -1,10 +1,10 @@ require 'rails_helper' RSpec.describe AutoArchiveProcedureJob, type: :job do - let!(:procedure) { create(:procedure, published_at: Time.now, archived_at: nil, auto_archive_on: nil) } - let!(:procedure_hier) { create(:procedure, published_at: Time.now, archived_at: nil, auto_archive_on: 1.day.ago) } - let!(:procedure_aujourdhui) { create(:procedure, published_at: Time.now, archived_at: nil, auto_archive_on: Date.today) } - let!(:procedure_demain) { create(:procedure, published_at: Time.now, archived_at: nil, auto_archive_on: 1.day.from_now) } + let!(:procedure) { create(:procedure, :published, auto_archive_on: nil) } + let!(:procedure_hier) { create(:procedure, :published, auto_archive_on: 1.day.ago) } + let!(:procedure_aujourdhui) { create(:procedure, :published, auto_archive_on: Date.today) } + let!(:procedure_demain) { create(:procedure, :published, auto_archive_on: 1.day.from_now) } subject { AutoArchiveProcedureJob.new.perform } diff --git a/spec/models/procedure_spec.rb b/spec/models/procedure_spec.rb index 0f3aec2f7..bb861cacb 100644 --- a/spec/models/procedure_spec.rb +++ b/spec/models/procedure_spec.rb @@ -213,17 +213,17 @@ describe Procedure do end describe 'locked?' do - let(:procedure) { create(:procedure, published_at: published_at) } + let(:procedure) { create(:procedure, aasm_state: aasm_state) } subject { procedure.locked? } - context 'when procedure is in draft status' do - let(:published_at) { nil } + context 'when procedure is in brouillon status' do + let(:aasm_state) { :brouillon } it { is_expected.to be_falsey } end - context 'when procedure is in draft status' do - let(:published_at) { Time.now } + context 'when procedure is in publiee status' do + let(:aasm_state) { :publiee } it { is_expected.to be_truthy } end end @@ -379,8 +379,8 @@ describe Procedure do describe "#brouillon?" do let(:procedure_brouillon) { Procedure.new() } - let(:procedure_publiee) { Procedure.new(published_at: Time.now) } - let(:procedure_archivee) { Procedure.new(published_at: Time.now, archived_at: Time.now) } + let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.now) } + let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.now, archived_at: Time.now) } it { expect(procedure_brouillon.brouillon?).to be_truthy } it { expect(procedure_publiee.brouillon?).to be_falsey } @@ -389,8 +389,8 @@ describe Procedure do describe "#publiee?" do let(:procedure_brouillon) { Procedure.new() } - let(:procedure_publiee) { Procedure.new(published_at: Time.now) } - let(:procedure_archivee) { Procedure.new(published_at: Time.now, archived_at: Time.now) } + let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.now) } + let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.now, archived_at: Time.now) } it { expect(procedure_brouillon.publiee?).to be_falsey } it { expect(procedure_publiee.publiee?).to be_truthy } @@ -399,20 +399,18 @@ describe Procedure do describe "#archivee?" do let(:procedure_brouillon) { Procedure.new() } - let(:procedure_publiee) { Procedure.new(published_at: Time.now) } - let(:procedure_archivee) { Procedure.new(published_at: Time.now, archived_at: Time.now) } - let(:procedure_batarde) { Procedure.new(published_at: nil, archived_at: Time.now) } + let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.now) } + let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.now, archived_at: Time.now) } it { expect(procedure_brouillon.archivee?).to be_falsey } it { expect(procedure_publiee.archivee?).to be_falsey } it { expect(procedure_archivee.archivee?).to be_truthy } - it { expect(procedure_batarde.archivee?).to be_falsey } end describe "#publiee_ou_archivee?" do let(:procedure_brouillon) { Procedure.new() } - let(:procedure_publiee) { Procedure.new(published_at: Time.now) } - let(:procedure_archivee) { Procedure.new(published_at: Time.now, archived_at: Time.now) } + let(:procedure_publiee) { Procedure.new(aasm_state: :publiee, published_at: Time.now) } + let(:procedure_archivee) { Procedure.new(aasm_state: :archivee, published_at: Time.now, archived_at: Time.now) } it { expect(procedure_brouillon.publiee_ou_archivee?).to be_falsey } it { expect(procedure_publiee.publiee_ou_archivee?).to be_truthy } @@ -425,7 +423,7 @@ describe Procedure do let(:now) { Time.now.beginning_of_minute } before do Timecop.freeze(now) - procedure.archive + procedure.archive! procedure.reload end after { Timecop.return } diff --git a/spec/views/admin/_closed_mail_template_attestation_inconsistency_alert.html.haml_spec.rb b/spec/views/admin/_closed_mail_template_attestation_inconsistency_alert.html.haml_spec.rb index 1a2ae1573..45f1ba08d 100644 --- a/spec/views/admin/_closed_mail_template_attestation_inconsistency_alert.html.haml_spec.rb +++ b/spec/views/admin/_closed_mail_template_attestation_inconsistency_alert.html.haml_spec.rb @@ -1,8 +1,7 @@ require 'spec_helper' describe 'admin/_closed_mail_template_attestation_inconsistency_alert.html.haml', type: :view do - let(:procedure) { create(:procedure, closed_mail: closed_mail, published_at: published_at) } - let(:published_at) { nil } + let(:procedure) { create(:procedure, closed_mail: closed_mail) } def alert assign(:procedure, procedure) @@ -32,7 +31,7 @@ describe 'admin/_closed_mail_template_attestation_inconsistency_alert.html.haml' it { expect(alert).to include(edit_admin_procedure_mail_template_path(procedure, Mails::ClosedMail::SLUG)) } context 'when the procedure has been published, the attestation cannot be deactivated' do - let(:published_at) { Time.now } + let(:procedure) { create(:procedure, :published, closed_mail: closed_mail) } it { expect(procedure.locked?).to be_truthy } it { expect(alert).not_to include(edit_admin_procedure_attestation_template_path(procedure)) } diff --git a/spec/views/admin/procedures/show.html.haml_spec.rb b/spec/views/admin/procedures/show.html.haml_spec.rb index 9bb39e293..96e175ae3 100644 --- a/spec/views/admin/procedures/show.html.haml_spec.rb +++ b/spec/views/admin/procedures/show.html.haml_spec.rb @@ -61,7 +61,7 @@ describe 'admin/procedures/show.html.haml', type: :view do describe 'procedure is archived' do before do procedure.publish!('fake_path') - procedure.archive + procedure.archive! procedure.reload render end