From b94bc654c9a122c7d88354920723be4606f50cca Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 6 Nov 2018 16:04:13 +0000 Subject: [PATCH 01/22] config: remove duplicated line The line is duplicated above in the same file. --- config/environments/test.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/config/environments/test.rb b/config/environments/test.rb index 5043e3677..1b9f30460 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -39,7 +39,6 @@ Rails.application.configure do # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr - config.action_mailer.delivery_method = :test config.action_mailer.default_url_options = { :host => 'localhost:3000' } Rails.application.routes.default_url_options = { host: 'localhost:3000', From d4b2b0487509ffcc3379fc0f8c45c20fd8c7132c Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 6 Nov 2018 17:05:23 +0100 Subject: [PATCH 02/22] spec: clear deliveries before every example --- spec/features/new_gestionnaire/gestionnaire_spec.rb | 3 --- spec/models/dossier_spec.rb | 4 ---- spec/spec_helper.rb | 2 ++ 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/spec/features/new_gestionnaire/gestionnaire_spec.rb b/spec/features/new_gestionnaire/gestionnaire_spec.rb index 7c1b95f2c..1461b0ae0 100644 --- a/spec/features/new_gestionnaire/gestionnaire_spec.rb +++ b/spec/features/new_gestionnaire/gestionnaire_spec.rb @@ -73,9 +73,6 @@ feature 'The gestionnaire part' do end scenario 'A gestionnaire can use avis' do - ActionMailer::Base.deliveries = [] - ActiveJob::Base.queue_adapter = :test - log_in(gestionnaire.email, password) click_on procedure.libelle diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index af9a43678..0b089438f 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -600,10 +600,6 @@ describe Dossier do let(:procedure) { create(:procedure) } let(:user) { create(:user) } - before do - ActionMailer::Base.deliveries.clear - end - it "send an email when the dossier is created for the very first time" do dossier = nil ActiveJob::Base.queue_adapter = :test diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 09cb95014..5a10b253f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -137,6 +137,8 @@ RSpec.configure do |config| Typhoeus::Expectation.clear + ActionMailer::Base.deliveries.clear + if Flipflop.remote_storage? VCR.use_cassette("ovh_storage_init") do CarrierWave.configure do |config| From 0fb9c123c971d95035f40849df9a4db0d3180bd6 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 6 Nov 2018 17:06:45 +0100 Subject: [PATCH 03/22] invite: mutualize feature helper for signing in --- spec/features/new_user/invite_spec.rb | 10 ++-------- spec/support/feature_helpers.rb | 6 ++++++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/features/new_user/invite_spec.rb b/spec/features/new_user/invite_spec.rb index 31e876e1e..e92f1ba3e 100644 --- a/spec/features/new_user/invite_spec.rb +++ b/spec/features/new_user/invite_spec.rb @@ -102,16 +102,10 @@ feature 'Invitations' do def log_in(user) visit '/' click_on 'Connexion' - submit_login_form(user.email, user.password) + sign_in_with(user.email, user.password) expect(page).to have_current_path(dossiers_path) end - def submit_login_form(email, password) - fill_in 'user_email', with: email - fill_in 'user_password', with: password - click_on 'Se connecter' - end - def navigate_to_brouillon(dossier) expect(page).to have_current_path(dossiers_path) click_on(dossier.id) @@ -127,7 +121,7 @@ feature 'Invitations' do def navigate_to_invited_dossier(invite) visit users_dossiers_invite_path(invite) expect(page).to have_current_path(new_user_session_path) - submit_login_form(invited_user.email, invited_user.password) + sign_in_with(invited_user.email, invited_user.password) end def send_invite_to(invited_email) diff --git a/spec/support/feature_helpers.rb b/spec/support/feature_helpers.rb index 2e59ec736..9ef96c624 100644 --- a/spec/support/feature_helpers.rb +++ b/spec/support/feature_helpers.rb @@ -14,6 +14,12 @@ module FeatureHelpers dossier = FactoryBot.create(:dossier) dossier end + + def sign_in_with(email, password) + fill_in :user_email, with: email + fill_in :user_password, with: password + click_on 'Se connecter' + end end RSpec.configure do |config| From b0541fba79cca20d59e5fa02e2178256779523a4 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 6 Nov 2018 10:22:17 +0000 Subject: [PATCH 04/22] users: sign-in after confirming an account within a short time --- Gemfile | 2 + Gemfile.lock | 4 ++ .../users/confirmations_controller.rb | 22 ++++++- .../users/confirmations_controller_spec.rb | 57 +++++++++++++++++++ spec/factories/user.rb | 4 ++ spec/features/new_user/invite_spec.rb | 16 ++---- spec/spec_helper.rb | 1 + spec/support/feature_helpers.rb | 18 ++++++ 8 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 spec/controllers/users/confirmations_controller_spec.rb diff --git a/Gemfile b/Gemfile index 8b19a11d5..3b09033c4 100644 --- a/Gemfile +++ b/Gemfile @@ -145,6 +145,8 @@ group :test do gem 'capybara-selenium' # Save a dump of the page when an integration test fails gem 'capybara-screenshot' + # Access emails during integration tests + gem 'capybara-email' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 7ac384d39..a1653a099 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -120,6 +120,9 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (>= 2.0, < 4.0) + capybara-email (3.0.1) + capybara (>= 2.4, < 4.0) + mail capybara-screenshot (1.0.21) capybara (>= 1.0, < 4) launchy @@ -812,6 +815,7 @@ DEPENDENCIES browser byebug capybara + capybara-email capybara-screenshot capybara-selenium carrierwave diff --git a/app/controllers/users/confirmations_controller.rb b/app/controllers/users/confirmations_controller.rb index 8aae938f1..927f44bc9 100644 --- a/app/controllers/users/confirmations_controller.rb +++ b/app/controllers/users/confirmations_controller.rb @@ -25,8 +25,24 @@ class Users::ConfirmationsController < Devise::ConfirmationsController # super(resource_name) # end + # If the user clicks the confirmation link before the maximum delay, + # they will be signed in directly. + def sign_in_after_confirmation?(resource) + # Avoid keeping auto-sign-in links in users inboxes for too long. + # 95% of users confirm their account within two hours. + auto_sign_in_timeout = 2.hours + resource.confirmation_sent_at + auto_sign_in_timeout > DateTime.current + end + # The path used after confirmation. - # def after_confirmation_path_for(resource_name, resource) - # super(resource_name, resource) - # end + def after_confirmation_path_for(resource_name, resource) + if sign_in_after_confirmation?(resource) + resource.remember_me = true + sign_in(resource) + resource.force_sync_credentials + after_sign_in_path_for(resource_name) + else + super(resource_name, resource) + end + end end diff --git a/spec/controllers/users/confirmations_controller_spec.rb b/spec/controllers/users/confirmations_controller_spec.rb new file mode 100644 index 000000000..9e49989ee --- /dev/null +++ b/spec/controllers/users/confirmations_controller_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' + +describe Users::ConfirmationsController, type: :controller do + let!(:user) { create(:user, :unconfirmed) } + let(:confirmation_token) { user.confirmation_token } + + before do + @request.env["devise.mapping"] = Devise.mappings[:user] + end + + describe '#show' do + context 'when confirming within the auto-sign-in delay' do + before do + Timecop.travel(1.hour.from_now) { + get :show, params: { confirmation_token: confirmation_token } + } + end + + it 'confirms the user' do + expect(user.reload).to be_confirmed + end + + it 'signs in the user after confirming its token' do + expect(controller.current_user).to eq(user) + expect(controller.current_gestionnaire).to be(nil) + expect(controller.current_administrateur).to be(nil) + end + + it 'redirects the user to the root page' do + # NB: the root page may redirect the user again to the stored procedure path + expect(controller).to redirect_to(root_path) + end + end + + context 'when the auto-sign-in delay has expired' do + before do + Timecop.travel(3.hours.from_now) { + get :show, params: { confirmation_token: confirmation_token } + } + end + + it 'confirms the user' do + expect(user.reload).to be_confirmed + end + + it 'doesn’t sign in the user' do + expect(subject.current_user).to be(nil) + expect(subject.current_gestionnaire).to be(nil) + expect(subject.current_administrateur).to be(nil) + end + + it 'redirects the user to the sign-in path' do + expect(subject).to redirect_to(new_user_session_path) + end + end + end +end diff --git a/spec/factories/user.rb b/spec/factories/user.rb index df6666652..d08db5919 100644 --- a/spec/factories/user.rb +++ b/spec/factories/user.rb @@ -4,5 +4,9 @@ FactoryBot.define do email { generate(:user_email) } password { 'password' } confirmed_at { Time.zone.now } + + trait :unconfirmed do + confirmed_at { nil } + end end end diff --git a/spec/features/new_user/invite_spec.rb b/spec/features/new_user/invite_spec.rb index e92f1ba3e..e5774c883 100644 --- a/spec/features/new_user/invite_spec.rb +++ b/spec/features/new_user/invite_spec.rb @@ -32,21 +32,17 @@ feature 'Invitations' do scenario 'an invited user can register using the registration link sent in the invitation email' do # Click the invitation link visit users_dossiers_invite_path(invite.id, params: { email: invite.email }) - - # Create the account expect(page).to have_current_path(new_user_registration_path, ignore_query: true) expect(page).to have_field('user_email', with: invite.email) - fill_in 'user_password', with: user_password - click_on 'Créer un compte' + # Create the account + sign_up_with invite.email, user_password expect(page).to have_content("lien d'activation") - # Confirm the email - user = User.find_by(email: invite.email) - visit Rails.application.routes.url_helpers.user_confirmation_path(confirmation_token: user.confirmation_token) - submit_login_form(user.email, user_password) - - # The user should be redirected to the dossier they was invited on + # Confirm the account + # (The user should be redirected to the dossier they was invited on) + click_confirmation_link_for invite.email + expect(page).to have_content('Votre compte a été activé') expect(page).to have_current_path(brouillon_dossier_path(dossier)) end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5a10b253f..ecbeb2e08 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -23,6 +23,7 @@ require File.expand_path('../config/environment', __dir__) require 'rspec/rails' require 'capybara/rspec' require 'capybara-screenshot/rspec' +require 'capybara/email/rspec' require 'database_cleaner' require 'webmock/rspec' require 'shoulda-matchers' diff --git a/spec/support/feature_helpers.rb b/spec/support/feature_helpers.rb index 9ef96c624..0f0504446 100644 --- a/spec/support/feature_helpers.rb +++ b/spec/support/feature_helpers.rb @@ -1,4 +1,6 @@ module FeatureHelpers + include ActiveJob::TestHelper + def login_admin user = create :user login_as user, scope: :user @@ -20,6 +22,22 @@ module FeatureHelpers fill_in :user_password, with: password click_on 'Se connecter' end + + def sign_up_with(email, password = 'testpassword') + fill_in :user_email, with: email + fill_in :user_password, with: password + + perform_enqueued_jobs do + click_button 'Créer un compte' + end + end + + def click_confirmation_link_for(email) + confirmation_email = open_email(email) + token_params = confirmation_email.body.match(/confirmation_token=[^"]+/) + + visit "/users/confirmation?#{token_params}" + end end RSpec.configure do |config| From 8355b690f03e9961e28256465ba15d8ce89a8b42 Mon Sep 17 00:00:00 2001 From: Pierre de La Morinerie Date: Tue, 6 Nov 2018 16:07:44 +0000 Subject: [PATCH 05/22] users: add integration tests for sign-up --- spec/features/sessions/sign_up_spec.rb | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 spec/features/sessions/sign_up_spec.rb diff --git a/spec/features/sessions/sign_up_spec.rb b/spec/features/sessions/sign_up_spec.rb new file mode 100644 index 000000000..54750eb01 --- /dev/null +++ b/spec/features/sessions/sign_up_spec.rb @@ -0,0 +1,36 @@ +require 'spec_helper' + +feature 'Signin up:' do + scenario 'a new user can sign-up' do + visit root_path + click_on 'Connexion' + click_on 'Créer un compte' + + sign_up_with 'testuser@exemple.fr' + expect(page).to have_content "Nous vous avons envoyé un email contenant un lien d'activation" + + click_confirmation_link_for 'testuser@exemple.fr' + expect(page).to have_content 'Votre compte a été activé' + expect(page).to have_current_path dossiers_path + end + + context 'when visiting a procedure' do + let(:procedure) { create :simple_procedure } + + before do + visit commencer_path(path: procedure.path) + end + + scenario 'a new user can sign-up and fill the procedure' do + expect(page).to have_current_path new_user_session_path + click_on 'Créer un compte' + + sign_up_with 'testuser@exemple.fr' + expect(page).to have_content "Nous vous avons envoyé un email contenant un lien d'activation" + + click_confirmation_link_for 'testuser@exemple.fr' + expect(page).to have_content 'Votre compte a été activé' + expect(page).to have_content procedure.libelle + end + end +end From 62c01706df6170b70ad8a1c28b895a8add41ee96 Mon Sep 17 00:00:00 2001 From: Mathieu Magnin Date: Tue, 6 Nov 2018 18:32:35 +0100 Subject: [PATCH 06/22] [Fix #2867] fix default sort for administrate --- app/controllers/manager/application_controller.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/manager/application_controller.rb b/app/controllers/manager/application_controller.rb index 4e76a2af1..b913664fc 100644 --- a/app/controllers/manager/application_controller.rb +++ b/app/controllers/manager/application_controller.rb @@ -4,8 +4,10 @@ module Manager before_action :default_params def default_params - params[:order] ||= "created_at" - params[:direction] ||= "desc" + params[resource_name] ||= { + order: "created_at", + direction: "desc" + } end protected From 9acb1950a4299e8ff1c3d67893a39b27a806deb7 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 1 Nov 2018 11:02:18 +0100 Subject: [PATCH 07/22] Remove dossier facade --- app/facades/dossier_facades.rb | 55 ---------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 app/facades/dossier_facades.rb diff --git a/app/facades/dossier_facades.rb b/app/facades/dossier_facades.rb deleted file mode 100644 index 3e73def9e..000000000 --- a/app/facades/dossier_facades.rb +++ /dev/null @@ -1,55 +0,0 @@ -class DossierFacades - # TODO rechercher en fonction de la personne/email - def initialize(dossier_id, email, champ_id = nil) - @dossier = Dossier.find(dossier_id) - @champ_id = champ_id - end - - def dossier - @dossier.decorate - end - - def champs - @dossier.champs - end - - def etablissement - @dossier.etablissement - end - - def types_de_pieces_justificatives - @dossier.types_de_piece_justificative.order('order_place ASC') - end - - def champ_id - @champ_id - end - - def commentaires - @dossier.commentaires.where(champ_id: @champ_id).decorate - end - - def procedure - @dossier.procedure - end - - def invites - @dossier.invites - end - - def champs_private - @dossier.champs_private - end - - def individual - @dossier.individual - end - - def commentaires_files - PieceJustificative.where(dossier_id: @dossier.id, type_de_piece_justificative_id: nil) - end - - def followers - @dossier.followers_gestionnaires - end -end From 2d647f9fa7dca2f5fb09d88b9e346101c6fec937 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 6 Nov 2018 14:59:07 +0100 Subject: [PATCH 08/22] Move types_de_champ facade to service --- app/facades/admin_types_de_champ_facades.rb | 48 --------------- app/services/types_de_champ_service.rb | 62 +++++++++++++++++--- spec/services/types_de_champ_service_spec.rb | 6 +- 3 files changed, 58 insertions(+), 58 deletions(-) delete mode 100644 app/facades/admin_types_de_champ_facades.rb diff --git a/app/facades/admin_types_de_champ_facades.rb b/app/facades/admin_types_de_champ_facades.rb deleted file mode 100644 index 6570e5bef..000000000 --- a/app/facades/admin_types_de_champ_facades.rb +++ /dev/null @@ -1,48 +0,0 @@ -class AdminTypesDeChampFacades - include Rails.application.routes.url_helpers - - def initialize(private, procedure) - @private = private - @procedure = procedure - end - - def private - @private - end - - def active - @private ? 'Annotations privées' : 'Champs' - end - - def url - @private ? admin_procedure_types_de_champ_private_path(@procedure) : admin_procedure_types_de_champ_path(@procedure) - end - - def types_de_champ - @private ? @procedure.types_de_champ_private_ordered.decorate : @procedure.types_de_champ_ordered.decorate - end - - def new_type_de_champ - TypeDeChamp.new(private: @private).decorate - end - - def fields_for_var - @private ? :types_de_champ_private : :types_de_champ - end - - def move_up_url(ff) - @private ? move_up_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_up_admin_procedure_types_de_champ_path(@procedure, ff.index) - end - - def move_down_url(ff) - @private ? move_down_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_down_admin_procedure_types_de_champ_path(@procedure, ff.index) - end - - def delete_url(ff) - @private ? admin_procedure_type_de_champ_private_path(@procedure, ff.object.id) : admin_procedure_type_de_champ_path(@procedure, ff.object.id) - end - - def add_button_id - @private ? :add_type_de_champ_private : :add_type_de_champ - end -end diff --git a/app/services/types_de_champ_service.rb b/app/services/types_de_champ_service.rb index c30a8c08d..7e7e8db4a 100644 --- a/app/services/types_de_champ_service.rb +++ b/app/services/types_de_champ_service.rb @@ -1,7 +1,53 @@ class TypesDeChampService - def self.create_update_procedure_params(params, private = false) - attributes = (private ? 'types_de_champ_private_attributes' : 'types_de_champ_attributes') + include Rails.application.routes.url_helpers + def initialize(procedure, private_type_de_champ = false) + @procedure = procedure + @private_type_de_champ = private_type_de_champ + end + + def private? + @private_type_de_champ + end + + def active + private? ? 'Annotations privées' : 'Champs' + end + + def url + private? ? admin_procedure_types_de_champ_private_path(@procedure) : admin_procedure_types_de_champ_path(@procedure) + end + + def types_de_champ + private? ? @procedure.types_de_champ_private_ordered.decorate : @procedure.types_de_champ_ordered.decorate + end + + def new_type_de_champ + TypeDeChamp.new(private: private?).decorate + end + + def fields_for_var + private? ? :types_de_champ_private : :types_de_champ + end + + def move_up_url(ff) + private? ? move_up_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_up_admin_procedure_types_de_champ_path(@procedure, ff.index) + end + + def move_down_url(ff) + private? ? move_down_admin_procedure_types_de_champ_private_path(@procedure, ff.index) : move_down_admin_procedure_types_de_champ_path(@procedure, ff.index) + end + + def delete_url(ff) + private? ? admin_procedure_type_de_champ_private_path(@procedure, ff.object.id) : admin_procedure_type_de_champ_path(@procedure, ff.object.id) + end + + def add_button_id + private? ? :add_type_de_champ_private : :add_type_de_champ + end + + def create_update_procedure_params(params) + attributes = "#{fields_for_var}_attributes" params_with_ordered_champs = order_champs(params, attributes) parameters = params_with_ordered_champs @@ -21,13 +67,13 @@ class TypesDeChampService ]) parameters[attributes].each do |index, param| - param[:private] = private + param[:private] = private? if param[:libelle].empty? parameters[attributes].delete(index.to_s) end if param['drop_down_list_attributes'] && param['drop_down_list_attributes']['value'] - param['drop_down_list_attributes']['value'] = self.clean_value (param['drop_down_list_attributes']['value']) + param['drop_down_list_attributes']['value'] = clean_value(param['drop_down_list_attributes']['value']) end end @@ -36,7 +82,7 @@ class TypesDeChampService private - def self.order_champs(params, attributes) + def order_champs(params, attributes) # It's OK to use an unsafe hash here because the params will then go through # require / permit methods in #create_update_procedure_params tdcas = params[:procedure][attributes].to_unsafe_hash.to_a @@ -64,15 +110,15 @@ class TypesDeChampService params end - def self.is_number?(value) + def is_number?(value) (value =~ /^[0-9]+$/) == 0 end - def self.tdca_order_changed?(tdca) + def tdca_order_changed?(tdca) (tdca[:order_place].to_i + 1) != tdca[:custom_order_place].to_i end - def self.clean_value(value) + def clean_value(value) value.split("\r\n").map(&:strip).join("\r\n") end end diff --git a/spec/services/types_de_champ_service_spec.rb b/spec/services/types_de_champ_service_spec.rb index f08072542..81fe0e611 100644 --- a/spec/services/types_de_champ_service_spec.rb +++ b/spec/services/types_de_champ_service_spec.rb @@ -2,10 +2,12 @@ require 'spec_helper' describe TypesDeChampService do let(:params) { ActionController::Parameters.new({ procedure: { types_de_champ_attributes: types_de_champ_attributes } }) } + let(:procedure) { create(:procedure) } + let(:service) { TypesDeChampService.new(procedure) } - let(:result) { TypesDeChampService.create_update_procedure_params(params) } + describe 'create_update_procedure_params' do + let(:result) { service.create_update_procedure_params(params) } - describe 'self.create_update_procedure_params' do describe 'the drop down list attributes' do let(:types_de_champ_attributes) do { From 1c87eda6e1f0354dd86a3b2d5bbddb183f16c530 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 6 Nov 2018 14:59:31 +0100 Subject: [PATCH 09/22] Move types_de_champ helper to service --- app/helpers/type_de_champ_helper.rb | 19 --------------- app/services/types_de_champ_service.rb | 18 ++++++++++++++ spec/helpers/type_de_champ_helper_spec.rb | 25 -------------------- spec/services/types_de_champ_service_spec.rb | 22 +++++++++++++++++ 4 files changed, 40 insertions(+), 44 deletions(-) delete mode 100644 app/helpers/type_de_champ_helper.rb delete mode 100644 spec/helpers/type_de_champ_helper_spec.rb diff --git a/app/helpers/type_de_champ_helper.rb b/app/helpers/type_de_champ_helper.rb deleted file mode 100644 index e8c4584ae..000000000 --- a/app/helpers/type_de_champ_helper.rb +++ /dev/null @@ -1,19 +0,0 @@ -module TypeDeChampHelper - TOGGLES = { - TypeDeChamp.type_champs.fetch(:piece_justificative) => :champ_pj?, - TypeDeChamp.type_champs.fetch(:siret) => :champ_siret?, - TypeDeChamp.type_champs.fetch(:linked_drop_down_list) => :champ_linked_dropdown?, - TypeDeChamp.type_champs.fetch(:integer_number) => :champ_integer_number? - } - - def tdc_options - tdcs = TypeDeChamp.type_de_champs_list_fr - - tdcs.select! do |tdc| - toggle = TOGGLES[tdc.last] - toggle.blank? || Flipflop.send(toggle) - end - - tdcs - end -end diff --git a/app/services/types_de_champ_service.rb b/app/services/types_de_champ_service.rb index 7e7e8db4a..4555d5e9b 100644 --- a/app/services/types_de_champ_service.rb +++ b/app/services/types_de_champ_service.rb @@ -1,6 +1,24 @@ class TypesDeChampService include Rails.application.routes.url_helpers + TOGGLES = { + TypeDeChamp.type_champs.fetch(:piece_justificative) => :champ_pj?, + TypeDeChamp.type_champs.fetch(:siret) => :champ_siret?, + TypeDeChamp.type_champs.fetch(:linked_drop_down_list) => :champ_linked_dropdown?, + TypeDeChamp.type_champs.fetch(:integer_number) => :champ_integer_number? + } + + def options + types_de_champ = TypeDeChamp.type_de_champs_list_fr + + types_de_champ.select! do |tdc| + toggle = TOGGLES[tdc.last] + toggle.blank? || Flipflop.send(toggle) + end + + types_de_champ + end + def initialize(procedure, private_type_de_champ = false) @procedure = procedure @private_type_de_champ = private_type_de_champ diff --git a/spec/helpers/type_de_champ_helper_spec.rb b/spec/helpers/type_de_champ_helper_spec.rb deleted file mode 100644 index 81d295202..000000000 --- a/spec/helpers/type_de_champ_helper_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'rails_helper' - -RSpec.describe TypeDeChampHelper, type: :helper do - describe ".tdc_options" do - let(:pj_option) { ["Pièce justificative", TypeDeChamp.type_champs.fetch(:piece_justificative)] } - - subject { tdc_options } - - context "when the champ_pj is enabled" do - before do - Flipflop::FeatureSet.current.test!.switch!(:champ_pj, true) - end - - it { is_expected.to include(pj_option) } - end - - context "when the champ_pj is disabled" do - before do - Flipflop::FeatureSet.current.test!.switch!(:champ_pj, false) - end - - it { is_expected.not_to include(pj_option) } - end - end -end diff --git a/spec/services/types_de_champ_service_spec.rb b/spec/services/types_de_champ_service_spec.rb index 81fe0e611..6d8714352 100644 --- a/spec/services/types_de_champ_service_spec.rb +++ b/spec/services/types_de_champ_service_spec.rb @@ -101,4 +101,26 @@ describe TypesDeChampService do end end end + + describe ".options" do + let(:pj_option) { ["Pièce justificative", TypeDeChamp.type_champs.fetch(:piece_justificative)] } + + subject { service.options } + + context "when the champ_pj is enabled" do + before do + Flipflop::FeatureSet.current.test!.switch!(:champ_pj, true) + end + + it { is_expected.to include(pj_option) } + end + + context "when the champ_pj is disabled" do + before do + Flipflop::FeatureSet.current.test!.switch!(:champ_pj, false) + end + + it { is_expected.not_to include(pj_option) } + end + end end From a7de2e68ed9f66708b411ce2abb6478bb31b798d Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 6 Nov 2018 14:53:07 +0100 Subject: [PATCH 10/22] Refactor types_de_champ views to use service instead of facade --- .../admin/types_de_champ_controller.rb | 20 +++++++-------- .../types_de_champ_private_controller.rb | 25 +++++++++++-------- .../admin/types_de_champ/_fields.html.haml | 12 ++++----- .../admin/types_de_champ/_form.html.haml | 6 ++--- app/views/admin/types_de_champ/show.html.haml | 2 +- app/views/admin/types_de_champ/show.js.erb | 2 +- ...dmin_typesdechampcontroller_show.html.haml | 2 +- .../types_de_champ/show.html.haml_spec.rb | 4 +-- .../show.html.haml_spec.rb | 4 +-- 9 files changed, 40 insertions(+), 37 deletions(-) diff --git a/app/controllers/admin/types_de_champ_controller.rb b/app/controllers/admin/types_de_champ_controller.rb index b50d4c2c0..56b973638 100644 --- a/app/controllers/admin/types_de_champ_controller.rb +++ b/app/controllers/admin/types_de_champ_controller.rb @@ -5,30 +5,30 @@ class Admin::TypesDeChampController < AdminController def destroy @procedure.types_de_champ.destroy(params[:id]) - create_facade + setup_type_de_champ_service render 'show', format: :js rescue ActiveRecord::RecordNotFound render json: { message: 'Champ not found' }, status: 404 end def show - create_facade + setup_type_de_champ_service end def update - if @procedure.update(TypesDeChampService.create_update_procedure_params params) + setup_type_de_champ_service + if @procedure.update(@type_de_champ_service.create_update_procedure_params(params)) flash.now.notice = 'Modifications sauvegardées' else flash.now.alert = @procedure.errors.full_messages.join(', ') end - create_facade render 'show', format: :js end def move_up index = params[:index].to_i - 1 - if @procedure.switch_types_de_champ index - create_facade + if @procedure.switch_types_de_champ(index) + setup_type_de_champ_service render 'show', format: :js else render json: {}, status: 400 @@ -36,8 +36,8 @@ class Admin::TypesDeChampController < AdminController end def move_down - if @procedure.switch_types_de_champ params[:index].to_i - create_facade + if @procedure.switch_types_de_champ(params[:index].to_i) + setup_type_de_champ_service render 'show', format: :js else render json: {}, status: 400 @@ -46,7 +46,7 @@ class Admin::TypesDeChampController < AdminController private - def create_facade - @types_de_champ_facade = AdminTypesDeChampFacades.new false, @procedure + def setup_type_de_champ_service + @type_de_champ_service = TypesDeChampService.new(@procedure) end end diff --git a/app/controllers/admin/types_de_champ_private_controller.rb b/app/controllers/admin/types_de_champ_private_controller.rb index 5dfdc368b..246c8306a 100644 --- a/app/controllers/admin/types_de_champ_private_controller.rb +++ b/app/controllers/admin/types_de_champ_private_controller.rb @@ -5,28 +5,31 @@ class Admin::TypesDeChampPrivateController < AdminController def destroy @procedure.types_de_champ_private.destroy(params[:id]) - create_facade + setup_type_de_champ_service render 'admin/types_de_champ/show', format: :js rescue ActiveRecord::RecordNotFound render json: { message: 'Champ not found' }, status: 404 end def show - create_facade + setup_type_de_champ_service render 'admin/types_de_champ/show' end def update - @procedure.update(TypesDeChampService.create_update_procedure_params params, true) - create_facade - flash.now.notice = 'Modifications sauvegardées' + setup_type_de_champ_service + if @procedure.update(@type_de_champ_service.create_update_procedure_params(params)) + flash.now.notice = 'Modifications sauvegardées' + else + flash.now.alert = @procedure.errors.full_messages.join(', ') + end render 'admin/types_de_champ/show', format: :js end def move_up index = params[:index].to_i - 1 - if @procedure.switch_types_de_champ_private index - create_facade + if @procedure.switch_types_de_champ_private(index) + setup_type_de_champ_service render 'admin/types_de_champ/show', format: :js else render json: {}, status: 400 @@ -34,8 +37,8 @@ class Admin::TypesDeChampPrivateController < AdminController end def move_down - if @procedure.switch_types_de_champ_private params[:index].to_i - create_facade + if @procedure.switch_types_de_champ_private(params[:index].to_i) + setup_type_de_champ_service render 'admin/types_de_champ/show', format: :js else render json: {}, status: 400 @@ -44,7 +47,7 @@ class Admin::TypesDeChampPrivateController < AdminController private - def create_facade - @types_de_champ_facade = AdminTypesDeChampFacades.new true, @procedure + def setup_type_de_champ_service + @type_de_champ_service = TypesDeChampService.new(@procedure, true) end end diff --git a/app/views/admin/types_de_champ/_fields.html.haml b/app/views/admin/types_de_champ/_fields.html.haml index f282aaf48..9acfa02a2 100644 --- a/app/views/admin/types_de_champ/_fields.html.haml +++ b/app/views/admin/types_de_champ/_fields.html.haml @@ -1,4 +1,4 @@ -= f.fields_for @types_de_champ_facade.fields_for_var, types_de_champ, remote: true do |ff| += f.fields_for type_de_champ_service.fields_for_var, types_de_champ, remote: true do |ff| - type_champ = ff.object.object.type_champ .form-inline{ class: (type_champ == TypeDeChamp.type_champs.fetch(:header_section) ? 'header-section' : nil) } @@ -8,7 +8,7 @@ .form-group.type %h4 Type - = ff.select :type_champ, tdc_options, {}, { class: 'form-control type-champ' } + = ff.select :type_champ, type_de_champ_service.options, {}, { class: 'form-control type-champ' } .form-group.description %h4 Description @@ -65,8 +65,8 @@ - if ff.object.id.present? .form-group %br   - = ff.object.button_up(index: ff.index, url: @types_de_champ_facade.move_up_url(ff), private: @types_de_champ_facade.private) - = ff.object.button_down(index: ff.index, url: @types_de_champ_facade.move_down_url(ff), private: @types_de_champ_facade.private) + = ff.object.button_up(index: ff.index, url: type_de_champ_service.move_up_url(ff), private: type_de_champ_service.private?) + = ff.object.button_down(index: ff.index, url: type_de_champ_service.move_down_url(ff), private: type_de_champ_service.private?) .form-group %h4 position @@ -76,10 +76,10 @@ %br   - if ff.object.id.nil? = f.button 'Ajouter le champ', - id: @types_de_champ_facade.add_button_id, + id: type_de_champ_service.add_button_id, class: 'btn btn-success', data: { disable: true } - else - = link_to("", @types_de_champ_facade.delete_url(ff), method: :delete, remote: true, id: "delete_type_de_champ_#{ff.object.id}", class: %w(form-control btn btn-danger fa fa-trash-o) ) + = link_to("", type_de_champ_service.delete_url(ff), method: :delete, remote: true, id: "delete_type_de_champ_#{ff.object.id}", class: %w(form-control btn btn-danger fa fa-trash-o) ) %div{ style: 'background-color: rgb(204, 204, 204); height: 1px; margin: 30px auto;' } diff --git a/app/views/admin/types_de_champ/_form.html.haml b/app/views/admin/types_de_champ/_form.html.haml index 36c2b6c8d..e444e51de 100644 --- a/app/views/admin/types_de_champ/_form.html.haml +++ b/app/views/admin/types_de_champ/_form.html.haml @@ -1,5 +1,5 @@ -= form_for [:admin, @procedure], url: @types_de_champ_facade.url, remote: true do |f| - = render partial: 'admin/types_de_champ/fields', locals: { types_de_champ: @types_de_champ_facade.types_de_champ, f: f } += form_for [:admin, procedure], url: type_de_champ_service.url, remote: true do |f| + = render partial: 'admin/types_de_champ/fields', locals: { type_de_champ_service: type_de_champ_service, types_de_champ: type_de_champ_service.types_de_champ, f: f } = f.button 'Enregistrer', id: :save, @@ -8,4 +8,4 @@ %hr #new_type_de_champ - = render partial: 'admin/types_de_champ/fields', locals: { types_de_champ: @types_de_champ_facade.new_type_de_champ, f: f } + = render partial: 'admin/types_de_champ/fields', locals: { type_de_champ_service: type_de_champ_service, types_de_champ: type_de_champ_service.new_type_de_champ, f: f } diff --git a/app/views/admin/types_de_champ/show.html.haml b/app/views/admin/types_de_champ/show.html.haml index 6b3522fa1..de6465992 100644 --- a/app/views/admin/types_de_champ/show.html.haml +++ b/app/views/admin/types_de_champ/show.html.haml @@ -1,3 +1,3 @@ .row.white-back #liste-champ - = render partial: 'admin/types_de_champ/form' + = render partial: 'admin/types_de_champ/form', locals: { procedure: @procedure, type_de_champ_service: @type_de_champ_service } diff --git a/app/views/admin/types_de_champ/show.js.erb b/app/views/admin/types_de_champ/show.js.erb index 5c22f8080..3aae31ff3 100644 --- a/app/views/admin/types_de_champ/show.js.erb +++ b/app/views/admin/types_de_champ/show.js.erb @@ -1,2 +1,2 @@ <%= render_flash(timeout: 3000, sticky: true) %> -<%= render_to_element('#liste-champ', partial: 'admin/types_de_champ/form', locals: { procedure: @procedure, types_de_champ: @types_de_champ }) %> +<%= render_to_element('#liste-champ', partial: 'admin/types_de_champ/form', locals: { procedure: @procedure, type_de_champ_service: @type_de_champ_service }) %> diff --git a/app/views/layouts/left_panels/_left_panel_admin_typesdechampcontroller_show.html.haml b/app/views/layouts/left_panels/_left_panel_admin_typesdechampcontroller_show.html.haml index b1ee2bd6f..5be7cb742 100644 --- a/app/views/layouts/left_panels/_left_panel_admin_typesdechampcontroller_show.html.haml +++ b/app/views/layouts/left_panels/_left_panel_admin_typesdechampcontroller_show.html.haml @@ -1 +1 @@ -= render partial: 'layouts/left_panels/left_panel_admin_procedurescontroller_navbar', locals: { active: @types_de_champ_facade.active } += render partial: 'layouts/left_panels/left_panel_admin_procedurescontroller_navbar', locals: { active: @type_de_champ_service.active } diff --git a/spec/views/admin/types_de_champ/show.html.haml_spec.rb b/spec/views/admin/types_de_champ/show.html.haml_spec.rb index 32c6fb9c1..9cb1e32c9 100644 --- a/spec/views/admin/types_de_champ/show.html.haml_spec.rb +++ b/spec/views/admin/types_de_champ/show.html.haml_spec.rb @@ -14,7 +14,7 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do before do procedure.reload assign(:procedure, procedure) - assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(false, procedure)) + assign(:type_de_champ_service, TypesDeChampService.new(procedure)) render end it 'sorts by order place' do @@ -26,7 +26,7 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do subject do procedure.reload assign(:procedure, procedure) - assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(false, procedure)) + assign(:type_de_champ_service, TypesDeChampService.new(procedure)) render rendered end diff --git a/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb b/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb index 587ec1b80..074cd31b7 100644 --- a/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb +++ b/spec/views/admin/types_de_champ_private/show.html.haml_spec.rb @@ -14,7 +14,7 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do before do procedure.reload assign(:procedure, procedure) - assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(true, procedure)) + assign(:type_de_champ_service, TypesDeChampService.new(procedure, true)) render end it 'sorts by order place' do @@ -26,7 +26,7 @@ describe 'admin/types_de_champ/show.html.haml', type: :view do subject do procedure.reload assign(:procedure, procedure) - assign(:types_de_champ_facade, AdminTypesDeChampFacades.new(true, procedure)) + assign(:type_de_champ_service, TypesDeChampService.new(procedure, true)) render rendered end From 0488c451bae6aea0cb7bb2874aedcd6379196a40 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 6 Nov 2018 19:56:01 +0100 Subject: [PATCH 11/22] Mass-process dossiers for procedure 8670 --- ..._mass_process_procedure_8670_dossiers.rake | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 lib/tasks/deployment/20181106170434_mass_process_procedure_8670_dossiers.rake diff --git a/lib/tasks/deployment/20181106170434_mass_process_procedure_8670_dossiers.rake b/lib/tasks/deployment/20181106170434_mass_process_procedure_8670_dossiers.rake new file mode 100644 index 000000000..14eb5c7ba --- /dev/null +++ b/lib/tasks/deployment/20181106170434_mass_process_procedure_8670_dossiers.rake @@ -0,0 +1,128 @@ +require Rails.root.join("lib", "tasks", "task_helper") + +namespace :after_party do + desc 'Deployment task: approve / reject dossiers for procedure 8670' + task mass_process_procedure_8670_dossiers: :environment do + class MassProcessProcedure8670 + DOSSIER_IDS_TO_ACCEPT = [ + 194722, 172178, 170186, 177122, 171783, 173930, 176042, 183202, 192081, 170387, + 171136, 171765, 173743, 173784, 173802, 173904, 173915, 171744, 173945, 170839, + 173954, 173967, 173990, 174003, 172217, 170449, 176603, 175921, 172634, 179048, + 180970, 181508, 182035, 181526, 178543, 170822, 170782, 186579, 187928, 188183, + 188399, 176860, 170614, 194011, 194100, 196307, 200282, 171544, 201953, 176316, + 205882, 205907, 205962, 178940, 181650, 202114, 180333, 174687, 192439, 169826, + 170121, 169894, 170635, 170626, 171896, 171993, 171935, 172028, 172087, 172094, + 172138, 172206, 172456, 172468, 172533, 172627, 172758, 172834, 172845, 172879, + 172884, 173411, 173662, 172256, 173909, 191259, 197681, 200041, 177306, 202624, + 203230, 204556, 205785, 198252, 170227, 173513, 172296, 174292, 174483, 174492, + 175076, 176540, 177177, 177322, 183210, 183498, 184353, 195189, 195967, 186147, + 170799, 178152, 177440, 184132, 169967, 175335, 177364, 179365, 197527, 172820, + 187060, 200326, 169921, 183622, 174745, 175484, 174512, 180860, 189163, 170054, + 170106, 206667, 170263, 173759, 169879, 170632, 190310, 170325, 170336, 170650, + 171520, 171050, 170414, 173804, 173911, 173947, 178986, 172030, 177428, 182875, + 198458, 199080, 172489, 200406, 204297, 171184, 171265, 171338, 171347, 172620, + 173162, 171939, 171597, 173878, 173758, 175861, 175923, 176851, 176957, 172479, + 183279, 177429, 185382, 185586, 188898, 172840, 180340, 195351, 171135, 170583, + 171680, 174150, 175066, 177164, 172951, 170623, 172863, 178732, 178268, 179848, + 179896, 179923, 179283, 180083, 185764, 192455, 190329, 197121, 169897, 170005, + 170023, 170127, 170399, 170371, 170351, 170519, 170654, 170680, 170774, 170781, + 171892, 169828, 171989, 172070, 171952, 171923, 172184, 174859, 175560, 175865, + 172922, 171889, 173550, 181501, 179897, 185241, 190364, 193743, 178551, 199361, + 173739, 169885, 169893, 171777, 179338, 179818, 170339, 178090, 187012, 191063, + 179911, 195101, 177916, 170242, 173537, 173895, 173700, 174642, 174749, 174880, + 174818, 175011, 174863, 175422, 175644, 177797, 177829, 174276, 200208, 204312, + 204356, 179106, 177928, 180376, 181086, 180048, 192202, 194193, 204479, 204979, + 183388, 185549 + ] + + DOSSIER_IDS_TO_REJECT = [ + 172516, 177423, 177002, 179031, 176856, 179193, 179237, 179333, 179912, 179949, + 181001, 185704, 185710, 177001, 186898, 175420, 175412, 195668, 174463, 175347, + 174606, 176668, 176749, 177007, 177037, 174306, 177373, 174496, 174583, 205297, + 191646, 178553, 184288, 174296, 199563, 202567, 180596, 194441, 196523, 183504, + 190011, 184563, 175047, 177243, 174108, 174423, 170552, 171931, 170955, 170415, + 170652, 170145, 170044, 169841, 171280, 177569, 174711, 180357, 180554, 175594, + 181370, 180370, 180279, 182877, 188432, 183516, 191845, 184965, 198962, 199250, + 202324, 205887, 172006, 196073, 197861, 198389, 188855, 198639, 203881, 205520, + 205626, 206468, 196904, 206619, 206730, 175088, 191405, 173038, 195082, 185849, + 188454, 188501, 188713, 171057, 177541, 177882, 178185, 178951, 178962, 178997, + 179090, 179234, 173959, 177621, 174022, 181414, 181895, 183081, 175935, 175951, + 176156, 176200, 176506, 176567, 173898, 173906, 173905, 173932, 173810, 173949, + 173961, 174033, 172939, 174227, 172362, 173008, 174979, 173396, 173196, 172143, + 173790, 173745, 173779, 172151, 170332, 171424, 171434, 170459, 171635, 171689, + 170409, 171429, 171940, 170266, 172632, 172742, 170689, 206612, 169877, 170402, + 170563, 170605, 170658, 170653, 170699, 170511, 170835, 183559, 187911, 188163, + 188685, 188702, 170678, 183994, 173899, 194530, 194873, 194433, 173971, 174004, + 174239, 174430, 175849, 175850, 176265, 176630, 176789, 175946, 172407, 177398, + 170027, 170002, 170404, 173678, 170655, 170328, 170405, 170686, 171106, 171763, + 172317, 172763, 172880, 173250, 174938, 170714, 175798, 175899, 176015, 176041, + 176258, 176341, 176909, 176944, 174031, 180109, 170316, 174100, 174540, 175910, + 177872, 178117, 179092, 183923, 175005, 185795, 186580, 181383, 189186, 194998, + 177475, 174446, 180508, 181216, 181290, 181905, 191344, 187745, 192016, 193188, + 170201, 170288, 170568 + ] + + def run + rake_puts "Running deploy task 'mass_process_procedure_8670_dossiers'\n" + + reject_dossiers + accept_dossiers + + AfterParty::TaskRecord.create version: '20181106170434' + end + + def reject_dossiers + rake_puts "Rejecting dossiers\n" + + dossiers_for_traitement.where(id: DOSSIER_IDS_TO_REJECT).find_each do |dossier| + if skip_dossier?(dossier) + next + end + + dossier.update( + state: Dossier.states.fetch(:refuse), + motivation: "Malheureusement, votre dossier n'a pas été tiré au sort", + processed_at: Time.zone.now + ) + NotificationMailer.send_refused_notification(dossier).deliver_later + end + end + + def accept_dossiers + rake_puts "Accepting dossiers\n" + + dossiers_for_traitement.where(id: DOSSIER_IDS_TO_ACCEPT).find_each do |dossier| + if skip_dossier?(dossier) + next + end + + dossier.update( + state: Dossier.states.fetch(:accepte), + processed_at: Time.zone.now + ) + dossier.attestation = dossier.build_attestation + dossier.save + NotificationMailer.send_closed_notification(dossier).deliver_later + end + end + + def dossiers_for_traitement + Dossier.includes(:procedure, :user, :etablissement, :champs, :champs_private) + end + + def skip_dossier?(dossier) + if dossier.procedure_id != 8670 + rake_puts "Skipping dossier #{dossier.id} (wrong procedure)\n" + return true + end + if !dossier.en_instruction? + rake_puts "Skipping dossier #{dossier.id} (not en instruction)\n" + return true + end + return false + end + end + + MassProcessProcedure8670.new.run + end +end From 3187b5b05a2ad10b70d3817fe609d0e8673cf7d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chai=CC=88b=20Martinez?= Date: Fri, 2 Nov 2018 14:55:59 +0100 Subject: [PATCH 12/22] Add Matomo tracking code --- app/views/layouts/_matomo.html.haml | 15 +++++++++++++++ app/views/layouts/application.html.haml | 3 +++ app/views/layouts/new_application.html.haml | 4 ++++ 3 files changed, 22 insertions(+) create mode 100644 app/views/layouts/_matomo.html.haml diff --git a/app/views/layouts/_matomo.html.haml b/app/views/layouts/_matomo.html.haml new file mode 100644 index 000000000..686be9450 --- /dev/null +++ b/app/views/layouts/_matomo.html.haml @@ -0,0 +1,15 @@ +:javascript + var _paq = _paq || []; + /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ + _paq.push(["setCookieDomain", "*.www.demarches-simplifiees.fr"]); + _paq.push(["setDomains", ["*.www.demarches-simplifiees.fr"]]); + _paq.push(["setDoNotTrack", true]); + _paq.push(['trackPageView']); + _paq.push(['enableLinkTracking']); + (function() { + var u="//stats.data.gouv.fr/"; + _paq.push(['setTrackerUrl', u+'piwik.php']); + _paq.push(['setSiteId', '73']); + var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; + g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); + })(); diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 81397c33f..5b1b9cb21 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -16,10 +16,13 @@ = javascript_include_tag 'application', defer: true, 'data-turbolinks-track': 'reload' = csrf_meta_tags + = render partial: "layouts/matomo" + :javascript DATA = [{ sentry: #{raw(sentry_config)} }]; + %body{ class: browser.platform.ios? ? 'ios' : nil } = render partial: 'layouts/outdated_browser_banner' = render partial: 'layouts/pre_maintenance' diff --git a/app/views/layouts/new_application.html.haml b/app/views/layouts/new_application.html.haml index 833127d93..46cd62ac2 100644 --- a/app/views/layouts/new_application.html.haml +++ b/app/views/layouts/new_application.html.haml @@ -21,10 +21,14 @@ - if Rails.env.development? = stylesheet_link_tag :xray + - if !current_user + = render partial: "layouts/matomo" + :javascript DATA = [{ sentry: #{raw(sentry_config)} }]; + %body{ class: browser.platform.ios? ? 'ios' : nil } .page-wrapper = render partial: "layouts/outdated_browser_banner" From 8d02b4dbdf4a895d8ece26d13a09ef924aeb1c2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chai=CC=88b=20Martinez?= Date: Wed, 7 Nov 2018 16:54:18 +0100 Subject: [PATCH 13/22] Add Matomo Suivi page --- app/assets/stylesheets/new_design/suivi.scss | 27 ++++++++++++++++++++ app/controllers/root_controller.rb | 3 +++ app/views/root/_footer.html.haml | 2 ++ app/views/root/suivi.html.haml | 23 +++++++++++++++++ config/initializers/urls.rb | 1 + config/routes.rb | 1 + 6 files changed, 57 insertions(+) create mode 100644 app/assets/stylesheets/new_design/suivi.scss create mode 100644 app/views/root/suivi.html.haml diff --git a/app/assets/stylesheets/new_design/suivi.scss b/app/assets/stylesheets/new_design/suivi.scss new file mode 100644 index 000000000..af5008e41 --- /dev/null +++ b/app/assets/stylesheets/new_design/suivi.scss @@ -0,0 +1,27 @@ +$default-space: 15px; +$new-p-margin-bottom: 3 * $default-space; + +.suivi { + width: 1040px; + margin: 0 auto; + padding-top: $default-space * 2; + padding-bottom: $default-space * 2; + + ul { + list-style-type: disc; + margin-top: -($default-space * 2); + } + + iframe { + border: none; + width: 100%; + } + + .new-h2 { + text-align: left; + } +} + +.new-p { + margin-bottom: $new-p-margin-bottom; +} diff --git a/app/controllers/root_controller.rb b/app/controllers/root_controller.rb index f7e802545..d285f2104 100644 --- a/app/controllers/root_controller.rb +++ b/app/controllers/root_controller.rb @@ -55,4 +55,7 @@ class RootController < ApplicationController @dossier = Dossier.new(champs: all_champs) end + + def suivi + end end diff --git a/app/views/root/_footer.html.haml b/app/views/root/_footer.html.haml index 174db199b..aa831d74c 100644 --- a/app/views/root/_footer.html.haml +++ b/app/views/root/_footer.html.haml @@ -26,6 +26,8 @@ = link_to "CGU", CGU_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer" %li.footer-link = link_to "Mentions légales", MENTIONS_LEGALES_URL, :class => "footer-link", :target => "_blank", rel: "noopener noreferrer" + %li.footer-link + = link_to "Suivi d'audience et vie privée", suivi_path, :class => "footer-link" %li.footer-column %ul.footer-links diff --git a/app/views/root/suivi.html.haml b/app/views/root/suivi.html.haml new file mode 100644 index 000000000..758f9c124 --- /dev/null +++ b/app/views/root/suivi.html.haml @@ -0,0 +1,23 @@ +- content_for(:title, 'Suivi') + +.suivi + %h1.new-h1 Cookies déposés et configuration du suivi + + %p.new-p + Ce site dépose un petit fichier texte (un « cookie ») sur votre ordinateur lorsque vous le consultez. Cela nous permet de mesurer le nombre de visites et de comprendre quelles sont les pages les plus consultées. + + %iframe{ :src => MATOMO_IFRAME_URL } + + %h2.new-h2 Ce site n’affiche pas de bannière de consentement aux cookies, pourquoi ? + %p.new-p + C’est vrai, vous n’avez pas eu à cliquer sur un bloc qui recouvre la moitié de la page pour dire que vous êtes d’accord avec le dépôt de cookies. + %br + %br + Rien d'exceptionnel, pas de passe-droit. Nous respectons simplement la loi, qui dit que certains outils de suivi d’audience, correctement configurés pour respecter la vie privée, sont exemptés d’autorisation préalable. + %br + %br + Nous utilisons pour cela Matomo, un outil libre, paramétré pour être en conformité avec la recommandation « Cookies » de la CNIL. Cela signifie que votre adresse IP, par exemple, est anonymisée avant d’être enregistrée. Il est donc impossible d’associer vos visites sur ce site à votre personne. + + %h2.new-h2 Je contribue à enrichir vos données, puis-je y accéder ? + %p.new-p + Bien sûr ! Les statistiques d’usage sont en accès libre sur stats.data.gouv.fr. diff --git a/config/initializers/urls.rb b/config/initializers/urls.rb index 1ddfa748a..c0e6cc0f7 100644 --- a/config/initializers/urls.rb +++ b/config/initializers/urls.rb @@ -22,3 +22,4 @@ MENTIONS_LEGALES_URL = [CGU_URL, "4-mentions-legales"].join("#") API_DOC_URL = [DOC_URL, "pour-aller-plus-loin", "api"].join("/") WEBHOOK_DOC_URL = [DOC_URL, "pour-aller-plus-loin", "webhook"].join("/") FAQ_URL = "https://faq.demarches-simplifiees.fr" +MATOMO_IFRAME_URL = "https://stats.data.gouv.fr/index.php?module=CoreAdminHome&action=optOut&language=fr&&fontColor=333333&fontSize=16px&fontFamily=Muli" diff --git a/config/routes.rb b/config/routes.rb index bb0ebce98..20ca2bd6c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -128,6 +128,7 @@ Rails.application.routes.draw do end get "patron" => "root#patron" + get "suivi" => "root#suivi" get "contact", to: "support#index" post "contact", to: "support#create" From 80189def98424b75df1628fbe1058106fecd534f Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 1 Nov 2018 14:04:32 +0100 Subject: [PATCH 14/22] Remove n+1 calls from API queries --- app/controllers/api/v1/dossiers_controller.rb | 8 +++++--- .../api/v1/procedures_controller.rb | 2 +- app/models/dossier.rb | 20 +++++++++++++++++++ app/models/procedure.rb | 10 ++++++++++ .../api/v1/dossiers_controller_spec.rb | 4 ++-- 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v1/dossiers_controller.rb b/app/controllers/api/v1/dossiers_controller.rb index ef77d5d23..b522e3aca 100644 --- a/app/controllers/api/v1/dossiers_controller.rb +++ b/app/controllers/api/v1/dossiers_controller.rb @@ -4,7 +4,7 @@ class API::V1::DossiersController < APIController DEFAULT_PAGE_SIZE = 100 def index - dossiers = @procedure.dossiers.state_not_brouillon.page(params[:page]).per(per_page) + dossiers = @dossiers.page(params[:page]).per(per_page) render json: { dossiers: dossiers.map{ |dossier| DossiersSerializer.new(dossier) }, pagination: pagination(dossiers) }, status: 200 rescue ActiveRecord::RecordNotFound @@ -12,7 +12,7 @@ class API::V1::DossiersController < APIController end def show - dossier = @procedure.dossiers.find(params[:id]) + dossier = @dossiers.for_api.find(params[:id]) respond_to do |format| format.json { render json: { dossier: DossierSerializer.new(dossier).as_json }, status: 200 } @@ -36,12 +36,14 @@ class API::V1::DossiersController < APIController end def fetch_procedure_and_check_token - @procedure = Procedure.includes(:administrateur).find(params[:procedure_id]) + @procedure = Procedure.for_api.find(params[:procedure_id]) if !valid_token_for_administrateur?(@procedure.administrateur) render json: {}, status: :unauthorized end + @dossiers = @procedure.dossiers.state_not_brouillon + rescue ActiveRecord::RecordNotFound render json: {}, status: :not_found end diff --git a/app/controllers/api/v1/procedures_controller.rb b/app/controllers/api/v1/procedures_controller.rb index 8e2d8a1a5..dd929c7b7 100644 --- a/app/controllers/api/v1/procedures_controller.rb +++ b/app/controllers/api/v1/procedures_controller.rb @@ -8,7 +8,7 @@ class API::V1::ProceduresController < APIController private def fetch_procedure_and_check_token - @procedure = Procedure.includes(:administrateur).find(params[:id]) + @procedure = Procedure.for_api.find(params[:id]) if !valid_token_for_administrateur?(@procedure.administrateur) render json: {}, status: :unauthorized diff --git a/app/models/dossier.rb b/app/models/dossier.rb index fdcf4336c..3b31c6af0 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -59,6 +59,26 @@ class Dossier < ApplicationRecord scope :with_champs, -> { includes(champs: :type_de_champ) } scope :nearing_end_of_retention, -> (duration = '1 month') { joins(:procedure).where("en_instruction_at + (duree_conservation_dossiers_dans_ds * interval '1 month') - now() < interval ?", duration) } + scope :for_api, -> { + includes(commentaires: [], + champs: [ + :geo_areas, + :etablissement, + piece_justificative_file_attachment: :blob + ], + champs_private: [ + :geo_areas, + :etablissement, + piece_justificative_file_attachment: :blob + ], + pieces_justificatives: [], + quartier_prioritaires: [], + cadastres: [], + etablissement: [], + individual: [], + user: []) + } + accepts_nested_attributes_for :individual delegate :siret, :siren, to: :etablissement, allow_nil: true diff --git a/app/models/procedure.rb b/app/models/procedure.rb index ae429b517..c8dd7b625 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -47,6 +47,16 @@ class Procedure < ApplicationRecord scope :cloned_from_library, -> { where(cloned_from_library: true) } scope :avec_lien, -> { where.not(path: nil) } + scope :for_api, -> { + includes( + :administrateur, + :types_de_champ_private, + :types_de_champ, + :types_de_piece_justificative, + :module_api_carto + ) + } + validates :libelle, presence: true, allow_blank: false, allow_nil: false validates :description, presence: true, allow_blank: false, allow_nil: false validate :check_juridique diff --git a/spec/controllers/api/v1/dossiers_controller_spec.rb b/spec/controllers/api/v1/dossiers_controller_spec.rb index 47ced3e71..ba2018551 100644 --- a/spec/controllers/api/v1/dossiers_controller_spec.rb +++ b/spec/controllers/api/v1/dossiers_controller_spec.rb @@ -136,7 +136,7 @@ describe API::V1::DossiersController do context 'when dossier exists and belongs to procedure' do let(:procedure_id) { procedure.id } let(:date_creation) { Time.zone.local(2008, 9, 1, 10, 5, 0) } - let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, procedure: procedure, motivation: "Motivation") } } + let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, :en_construction, procedure: procedure, motivation: "Motivation") } } let(:dossier_id) { dossier.id } let(:body) { JSON.parse(retour.body, symbolize_names: true) } let(:field_list) { [:id, :created_at, :updated_at, :archived, :individual, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state, :simplified_state, :initiated_at, :processed_at, :received_at, :motivation, :email, :instructeurs] } @@ -147,7 +147,7 @@ describe API::V1::DossiersController do end it { expect(subject[:id]).to eq(dossier.id) } - it { expect(subject[:state]).to eq(dossier.state) } + it { expect(subject[:state]).to eq('initiated') } it { expect(subject[:created_at]).to eq('2008-09-01T08:05:00.000Z') } it { expect(subject[:updated_at]).to eq('2008-09-01T08:05:00.000Z') } it { expect(subject[:archived]).to eq(dossier.archived) } From 6706b9004f48b2cc27a5c2f08d564299d47173f2 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 8 Nov 2018 14:36:53 +0100 Subject: [PATCH 15/22] Fix includes on api queries --- app/models/champ.rb | 5 +++++ app/models/champs/carte_champ.rb | 2 -- app/models/champs/siret_champ.rb | 1 - 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/models/champ.rb b/app/models/champ.rb index 94123a53e..1f0741e3f 100644 --- a/app/models/champ.rb +++ b/app/models/champ.rb @@ -5,6 +5,11 @@ class Champ < ApplicationRecord has_one_attached :piece_justificative_file has_one :virus_scan + # We declare champ specific relationships (Champs::CarteChamp and Champs::SiretChamp) + # here because otherwise we can't easily use includes in our queries. + has_many :geo_areas, dependent: :destroy + belongs_to :etablissement, dependent: :destroy + delegate :libelle, :type_champ, :order_place, :mandatory?, :description, :drop_down_list, to: :type_de_champ scope :updated_since?, -> (date) { where('champs.updated_at > ?', date) } diff --git a/app/models/champs/carte_champ.rb b/app/models/champs/carte_champ.rb index 353e9ac20..26658adeb 100644 --- a/app/models/champs/carte_champ.rb +++ b/app/models/champs/carte_champ.rb @@ -1,6 +1,4 @@ class Champs::CarteChamp < Champ - has_many :geo_areas, foreign_key: :champ_id, dependent: :destroy - # We are not using scopes here as we want to access # the following collections on unsaved records. def cadastres diff --git a/app/models/champs/siret_champ.rb b/app/models/champs/siret_champ.rb index e33928e29..b36e3c1ba 100644 --- a/app/models/champs/siret_champ.rb +++ b/app/models/champs/siret_champ.rb @@ -37,7 +37,6 @@ class Champs::SiretChamp < Champ ] ] - belongs_to :etablissement, dependent: :destroy accepts_nested_attributes_for :etablissement, allow_destroy: true, update_only: true def search_terms From ebaecd1eddb9259cefde18d949ad41c5e0c37d7d Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 8 Nov 2018 14:37:16 +0100 Subject: [PATCH 16/22] Fix nutriscore rake task --- lib/tasks/2018_07_31_nutriscore.rake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/tasks/2018_07_31_nutriscore.rake b/lib/tasks/2018_07_31_nutriscore.rake index 76cb7dc47..0d3141fd0 100644 --- a/lib/tasks/2018_07_31_nutriscore.rake +++ b/lib/tasks/2018_07_31_nutriscore.rake @@ -67,6 +67,9 @@ namespace :'2018_07_31_nutriscore' do libelle: 'Numéro SIRET' ) ) do |d, target_tdc| + if d.etablissement.present? + d.etablissement.signature = d.etablissement.sign + end target_tdc.champ.create( value: d.etablissement&.siret, etablissement: d.etablissement, From 624b442cd70afcbc4352e35af5113c1bc681ca6a Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 6 Nov 2018 18:44:10 +0100 Subject: [PATCH 17/22] =?UTF-8?q?Remove=20=E2=80=9COutil=20de=20changement?= =?UTF-8?q?=20d'=C3=A9tat=20d'un=20dossier=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/change_dossier_state_controller.rb | 19 ------------------- .../change_dossier_state/change.html.haml | 16 ---------------- .../change_dossier_state/check.html.haml | 17 ----------------- .../change_dossier_state/index.html.haml | 7 ------- config/routes.rb | 4 ---- 5 files changed, 63 deletions(-) delete mode 100644 app/controllers/admin/change_dossier_state_controller.rb delete mode 100644 app/views/admin/change_dossier_state/change.html.haml delete mode 100644 app/views/admin/change_dossier_state/check.html.haml delete mode 100644 app/views/admin/change_dossier_state/index.html.haml diff --git a/app/controllers/admin/change_dossier_state_controller.rb b/app/controllers/admin/change_dossier_state_controller.rb deleted file mode 100644 index e4304bd9f..000000000 --- a/app/controllers/admin/change_dossier_state_controller.rb +++ /dev/null @@ -1,19 +0,0 @@ -class Admin::ChangeDossierStateController < AdminController - def index - @dossier = Dossier.new - end - - def change - @dossier = Dossier.find(params[:dossier][:id]) - @dossier.update state: params[:next_state] - end - - def check - @dossier = Dossier.find(params[:dossier][:id]) - - if @dossier.procedure.administrateur.email != current_administrateur.email - flash.alert = 'Dossier introuvable' - return redirect_to admin_change_dossier_state_path - end - end -end diff --git a/app/views/admin/change_dossier_state/change.html.haml b/app/views/admin/change_dossier_state/change.html.haml deleted file mode 100644 index 4249e6907..000000000 --- a/app/views/admin/change_dossier_state/change.html.haml +++ /dev/null @@ -1,16 +0,0 @@ -.center - %h2 Outil de changement d'état d'un dossier - - %h4.text-success - Changement effectué - - = form_for @dossier, url: 'change_dossier_state', action: :put do |f| - Dossier ID : - = @dossier.id - %br - État : - = @dossier.decorate.display_state - - %br - %br - = link_to 'Réaliser un autre dossier', 'change_dossier_state' diff --git a/app/views/admin/change_dossier_state/check.html.haml b/app/views/admin/change_dossier_state/check.html.haml deleted file mode 100644 index e92ed72d8..000000000 --- a/app/views/admin/change_dossier_state/check.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -.center - %h2 Outil de changement d'état d'un dossier - - = form_for @dossier, url: 'change_dossier_state', action: :put do |f| - Dossier ID : - = @dossier.id - = f.hidden_field :id - %br - État : - = @dossier.decorate.display_state - %br - État souhaité : - %select{ id: :next_state, name: :next_state } - - Dossier.states.each do |state| - %option{ value: state[0] } - = DossierDecorator.case_state_fr state[1] - = f.submit 'Valider' diff --git a/app/views/admin/change_dossier_state/index.html.haml b/app/views/admin/change_dossier_state/index.html.haml deleted file mode 100644 index 525023b5f..000000000 --- a/app/views/admin/change_dossier_state/index.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -.center - %h2 Outil de changement d'état d'un dossier - - = form_for @dossier, url: 'change_dossier_state', action: :post do |f| - Dossier ID - = f.text_field :id - = f.submit 'Vérifier état' diff --git a/config/routes.rb b/config/routes.rb index 20ca2bd6c..1c5f6ac70 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -173,10 +173,6 @@ Rails.application.routes.draw do get 'procedures/path_list' => 'procedures#path_list' get 'procedures/available' => 'procedures#check_availability' - get 'change_dossier_state' => 'change_dossier_state#index' - post 'change_dossier_state' => 'change_dossier_state#check' - patch 'change_dossier_state' => 'change_dossier_state#change' - resources :procedures do collection do get 'new_from_existing' => 'procedures#new_from_existing', as: :new_from_existing From f09a7a01c889b4395a17cc7f013e60a7fb885f7a Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 6 Nov 2018 18:44:32 +0100 Subject: [PATCH 18/22] Add dossier_display_state helper --- app/helpers/dossier_helper.rb | 5 +++ spec/helpers/dossier_helper_spec.rb | 70 +++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/app/helpers/dossier_helper.rb b/app/helpers/dossier_helper.rb index 06a7001c9..435cd6374 100644 --- a/app/helpers/dossier_helper.rb +++ b/app/helpers/dossier_helper.rb @@ -26,4 +26,9 @@ module DossierHelper def dossier_submission_is_closed?(dossier) dossier.brouillon? && dossier.procedure.archivee? end + + def dossier_display_state(dossier, lower: false) + state = I18n.t(dossier.state, scope: [:activerecord, :attributes, :dossier, :state]) + lower ? state.downcase : state + end end diff --git a/spec/helpers/dossier_helper_spec.rb b/spec/helpers/dossier_helper_spec.rb index f5683782c..c37bd7963 100644 --- a/spec/helpers/dossier_helper_spec.rb +++ b/spec/helpers/dossier_helper_spec.rb @@ -96,4 +96,74 @@ RSpec.describe DossierHelper, type: :helper do it_behaves_like "returns false" end end + + describe '.dossier_display_state' do + let(:dossier) { create(:dossier) } + + subject { dossier_display_state(dossier) } + + it 'brouillon is brouillon' do + dossier.brouillon! + expect(subject).to eq('Brouillon') + end + + it 'en_construction is En construction' do + dossier.en_construction! + expect(subject).to eq('En construction') + end + + it 'accepte is traité' do + dossier.accepte! + expect(subject).to eq('Accepté') + end + + it 'en_instruction is reçu' do + dossier.en_instruction! + expect(subject).to eq('En instruction') + end + + it 'sans_suite is traité' do + dossier.sans_suite! + expect(subject).to eq('Sans suite') + end + + it 'refuse is traité' do + dossier.refuse! + expect(subject).to eq('Refusé') + end + + context "lower: true" do + subject { dossier_display_state(dossier, lower: true) } + + it 'brouillon is brouillon' do + dossier.brouillon! + expect(subject).to eq('brouillon') + end + + it 'en_construction is En construction' do + dossier.en_construction! + expect(subject).to eq('en construction') + end + + it 'accepte is traité' do + dossier.accepte! + expect(subject).to eq('accepté') + end + + it 'en_instruction is reçu' do + dossier.en_instruction! + expect(subject).to eq('en instruction') + end + + it 'sans_suite is traité' do + dossier.sans_suite! + expect(subject).to eq('sans suite') + end + + it 'refuse is traité' do + dossier.refuse! + expect(subject).to eq('refusé') + end + end + end end From a524c72addef228839edfb818c791d1ca984b54b Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 6 Nov 2018 18:45:29 +0100 Subject: [PATCH 19/22] Use dossier_display_state helper --- app/serializers/dossier_serializer.rb | 4 +++- app/views/new_gestionnaire/dossiers/_header.html.haml | 2 +- app/views/new_gestionnaire/dossiers/_state_button.html.haml | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/serializers/dossier_serializer.rb b/app/serializers/dossier_serializer.rb index 0acd0ed29..a6d62e851 100644 --- a/app/serializers/dossier_serializer.rb +++ b/app/serializers/dossier_serializer.rb @@ -1,4 +1,6 @@ class DossierSerializer < ActiveModel::Serializer + include DossierHelper + attributes :id, :created_at, :updated_at, @@ -46,7 +48,7 @@ class DossierSerializer < ActiveModel::Serializer end def simplified_state - object.decorate.display_state + dossier_display_state(object) end def initiated_at diff --git a/app/views/new_gestionnaire/dossiers/_header.html.haml b/app/views/new_gestionnaire/dossiers/_header.html.haml index a624838f2..3928b531d 100644 --- a/app/views/new_gestionnaire/dossiers/_header.html.haml +++ b/app/views/new_gestionnaire/dossiers/_header.html.haml @@ -46,4 +46,4 @@ .print-header = dossier.procedure.libelle.truncate_words(10) > - = "Dossier nº #{dossier.id} (#{dossier.statut})" + = "Dossier nº #{dossier.id} (#{dossier_display_state(dossier, lower: true)})" diff --git a/app/views/new_gestionnaire/dossiers/_state_button.html.haml b/app/views/new_gestionnaire/dossiers/_state_button.html.haml index 48aaa5d8a..4063b6e56 100644 --- a/app/views/new_gestionnaire/dossiers/_state_button.html.haml +++ b/app/views/new_gestionnaire/dossiers/_state_button.html.haml @@ -1,7 +1,7 @@ - if dossier.en_construction? || dossier.en_instruction? %span.dropdown %button.button.primary.dropdown-button - = dossier.decorate.display_state + = dossier_display_state dossier .dropdown-content.fade-in-down %ul.dropdown-items - if dossier.en_construction? @@ -55,7 +55,7 @@ - if dossier.motivation.present? || dossier.attestation.present? %span.dropdown %button.button.dropdown-button{ class: button_or_label_class(dossier) } - = dossier.statut + = dossier_display_state(dossier, lower: true) .dropdown-content.fade-in-down.terminated - if dossier.motivation.present? %h4 Motivation @@ -67,4 +67,4 @@ = link_to "Voir l'attestation", attestation_gestionnaire_dossier_path(dossier.procedure, dossier), target: '_blank', class: 'button' - else %span.label{ class: button_or_label_class(dossier) } - = dossier.statut + = dossier_display_state(dossier, lower: true) From 0fe59a7c65191c925e7d3e60b1620db2786d1332 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Wed, 7 Nov 2018 14:46:22 +0100 Subject: [PATCH 20/22] Add dossier_legacy_state helper --- app/helpers/dossier_helper.rb | 17 +++++++++++++++ spec/helpers/dossier_helper_spec.rb | 34 +++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/app/helpers/dossier_helper.rb b/app/helpers/dossier_helper.rb index 435cd6374..53c759d5b 100644 --- a/app/helpers/dossier_helper.rb +++ b/app/helpers/dossier_helper.rb @@ -31,4 +31,21 @@ module DossierHelper state = I18n.t(dossier.state, scope: [:activerecord, :attributes, :dossier, :state]) lower ? state.downcase : state end + + def dossier_legacy_state(dossier) + case dossier.state + when Dossier.states.fetch(:en_construction) + 'initiated' + when Dossier.states.fetch(:en_instruction) + 'received' + when Dossier.states.fetch(:accepte) + 'closed' + when Dossier.states.fetch(:refuse) + 'refused' + when Dossier.states.fetch(:sans_suite) + 'without_continuation' + else + dossier.state + end + end end diff --git a/spec/helpers/dossier_helper_spec.rb b/spec/helpers/dossier_helper_spec.rb index c37bd7963..b165b3285 100644 --- a/spec/helpers/dossier_helper_spec.rb +++ b/spec/helpers/dossier_helper_spec.rb @@ -166,4 +166,38 @@ RSpec.describe DossierHelper, type: :helper do end end end + + describe '.dossier_legacy_state' do + subject { dossier_legacy_state(dossier) } + + context 'when the dossier is en instruction' do + let(:dossier) { create(:dossier) } + + it { is_expected.to eq('brouillon') } + end + + context 'when the dossier is en instruction' do + let(:dossier) { create(:dossier, :en_instruction) } + + it { is_expected.to eq('received') } + end + + context 'when the dossier is accepte' do + let(:dossier) { create(:dossier, state: Dossier.states.fetch(:accepte)) } + + it { is_expected.to eq('closed') } + end + + context 'when the dossier is refuse' do + let(:dossier) { create(:dossier, state: Dossier.states.fetch(:refuse)) } + + it { is_expected.to eq('refused') } + end + + context 'when the dossier is sans_suite' do + let(:dossier) { create(:dossier, state: Dossier.states.fetch(:sans_suite)) } + + it { is_expected.to eq('without_continuation') } + end + end end From eede94a59fa828bb76edc78999183513b3f8a19c Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 6 Nov 2018 18:46:17 +0100 Subject: [PATCH 21/22] Use dossier_legacy_state helper --- app/serializers/dossier_serializer.rb | 2 +- .../dossier_table_export_serializer.rb | 17 +++-------------- app/serializers/dossiers_serializer.rb | 4 +++- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/app/serializers/dossier_serializer.rb b/app/serializers/dossier_serializer.rb index a6d62e851..1e94ac318 100644 --- a/app/serializers/dossier_serializer.rb +++ b/app/serializers/dossier_serializer.rb @@ -44,7 +44,7 @@ class DossierSerializer < ActiveModel::Serializer end def state - object.old_state_value + dossier_legacy_state(object) end def simplified_state diff --git a/app/serializers/dossier_table_export_serializer.rb b/app/serializers/dossier_table_export_serializer.rb index 6622f3401..cdc125cca 100644 --- a/app/serializers/dossier_table_export_serializer.rb +++ b/app/serializers/dossier_table_export_serializer.rb @@ -1,4 +1,6 @@ class DossierTableExportSerializer < ActiveModel::Serializer + include DossierHelper + attributes :id, :created_at, :updated_at, @@ -22,20 +24,7 @@ class DossierTableExportSerializer < ActiveModel::Serializer end def state - case object.state - when Dossier.states.fetch(:en_construction) - 'initiated' - when Dossier.states.fetch(:en_instruction) - 'received' - when Dossier.states.fetch(:accepte) - 'closed' - when Dossier.states.fetch(:refuse) - 'refused' - when Dossier.states.fetch(:sans_suite) - 'without_continuation' - else - object.state - end + dossier_legacy_state(object) end def initiated_at diff --git a/app/serializers/dossiers_serializer.rb b/app/serializers/dossiers_serializer.rb index 6751e5c53..784236b96 100644 --- a/app/serializers/dossiers_serializer.rb +++ b/app/serializers/dossiers_serializer.rb @@ -1,4 +1,6 @@ class DossiersSerializer < ActiveModel::Serializer + include DossierHelper + attributes :id, :updated_at, :initiated_at, @@ -13,6 +15,6 @@ class DossiersSerializer < ActiveModel::Serializer end def state - object.old_state_value + dossier_legacy_state(object) end end From 33c6ddc452fa1318819385f45ac768fa41af03cc Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 6 Nov 2018 18:46:41 +0100 Subject: [PATCH 22/22] Remove dead code related to dossier state --- app/decorators/dossier_decorator.rb | 10 ------- app/models/dossier.rb | 27 ------------------ spec/decorators/dossier_decorator_spec.rb | 34 ----------------------- spec/models/dossier_spec.rb | 28 ------------------- 4 files changed, 99 deletions(-) diff --git a/app/decorators/dossier_decorator.rb b/app/decorators/dossier_decorator.rb index c4ce6b8e7..4f283e3c5 100644 --- a/app/decorators/dossier_decorator.rb +++ b/app/decorators/dossier_decorator.rb @@ -1,6 +1,4 @@ class DossierDecorator < Draper::Decorator - include Rails.application.routes.url_helpers - delegate :current_page, :limit_value, :total_pages delegate_all @@ -11,12 +9,4 @@ class DossierDecorator < Draper::Decorator def last_update updated_at.strftime('%d/%m/%Y %H:%M') end - - def display_state - DossierDecorator.case_state_fr state - end - - def self.case_state_fr(state = self.state) - h.t("activerecord.attributes.dossier.state.#{state}") - end end diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 3b31c6af0..69defd6aa 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -245,16 +245,6 @@ class Dossier < ApplicationRecord end end - def statut - if accepte? - 'accepté' - elsif sans_suite? - 'classé sans suite' - elsif refuse? - 'refusé' - end - end - def user_geometry if json_latlngs.present? UserGeometry.new(json_latlngs) @@ -308,23 +298,6 @@ class Dossier < ApplicationRecord DossierMailer.notify_deletion_to_user(deleted_dossier, user.email).deliver_later end - def old_state_value - case state - when Dossier.states.fetch(:en_construction) - 'initiated' - when Dossier.states.fetch(:en_instruction) - 'received' - when Dossier.states.fetch(:accepte) - 'closed' - when Dossier.states.fetch(:refuse) - 'refused' - when Dossier.states.fetch(:sans_suite) - 'without_continuation' - else - state - end - end - private def update_state_dates diff --git a/spec/decorators/dossier_decorator_spec.rb b/spec/decorators/dossier_decorator_spec.rb index 184d28407..3c8f4fe96 100644 --- a/spec/decorators/dossier_decorator_spec.rb +++ b/spec/decorators/dossier_decorator_spec.rb @@ -18,38 +18,4 @@ describe DossierDecorator do subject { super().last_update } it { is_expected.to eq('24/12/2015 14:10') } end - - describe 'state_fr' do - subject{ super().display_state } - - it 'brouillon is brouillon' do - dossier.brouillon! - expect(subject).to eq('Brouillon') - end - - it 'en_construction is En construction' do - dossier.en_construction! - expect(subject).to eq('En construction') - end - - it 'accepte is traité' do - dossier.accepte! - expect(subject).to eq('Accepté') - end - - it 'en_instruction is reçu' do - dossier.en_instruction! - expect(subject).to eq('En instruction') - end - - it 'sans_suite is traité' do - dossier.sans_suite! - expect(subject).to eq('Sans suite') - end - - it 'refuse is traité' do - dossier.refuse! - expect(subject).to eq('Refusé') - end - end end diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index 0b089438f..0562d528f 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -1000,32 +1000,4 @@ describe Dossier do it { expect(long_expired_dossier).to be_retention_expired } end end - - describe 'old_state_value' do - subject { dossier.old_state_value } - - context 'when the dossier is en instruction' do - let(:dossier) { create(:dossier, :en_instruction) } - - it { is_expected.to eq('received') } - end - - context 'when the dossier is accepte' do - let(:dossier) { create(:dossier, state: Dossier.states.fetch(:accepte)) } - - it { is_expected.to eq('closed') } - end - - context 'when the dossier is refuse' do - let(:dossier) { create(:dossier, state: Dossier.states.fetch(:refuse)) } - - it { is_expected.to eq('refused') } - end - - context 'when the dossier is sans_suite' do - let(:dossier) { create(:dossier, state: Dossier.states.fetch(:sans_suite)) } - - it { is_expected.to eq('without_continuation') } - end - end end