diff --git a/.rubocop.yml b/.rubocop.yml index 8007fd868..354ef3d74 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -661,6 +661,9 @@ Rails/ApplicationRecord: Rails/Blank: Enabled: true +Rails/BulkChangeTable: + Enabled: false + Rails/CreateTableWithTimestamps: Enabled: false @@ -792,6 +795,9 @@ Security/Open: Security/YAMLLoad: Enabled: true +Style/AccessModifierDeclarations: + Enabled: false + Style/Alias: Enabled: false diff --git a/Gemfile.lock b/Gemfile.lock index e2eae1d09..7434d95f7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -88,7 +88,7 @@ GEM sass-rails (~> 5.0) selectize-rails (~> 0.6) aes_key_wrap (1.0.1) - apipie-rails (0.5.8) + apipie-rails (0.5.9) rails (>= 4.1) arel (9.0.0) ast (2.4.0) @@ -107,7 +107,7 @@ GEM sass (>= 3.3.4) bootstrap-wysihtml5-rails (0.3.3.8) railties (>= 3.0) - brakeman (4.3.0) + brakeman (4.3.1) browser (2.5.3) builder (3.2.3) byebug (10.0.2) @@ -133,7 +133,7 @@ GEM carrierwave-i18n (0.2.0) case_transform (0.2) activesupport - chartkick (2.3.4) + chartkick (2.3.5) childprocess (0.8.0) ffi (~> 1.0, >= 1.0.11) chunky_png (1.3.10) @@ -167,10 +167,11 @@ GEM delayed_job_active_record (4.1.3) activerecord (>= 3.0, < 5.3) delayed_job (>= 3.0, < 5) - delayed_job_web (1.4.2) + delayed_job_web (1.4.3) activerecord (> 3.0.0) delayed_job (> 2.0.3) - sinatra (>= 2.0.1) + rack-protection (>= 1.5.5) + sinatra (>= 1.4.4) devise (4.4.3) bcrypt (~> 3.0) orm_adapter (~> 0.1) @@ -183,9 +184,9 @@ GEM diff-lcs (1.3) domain_name (0.5.20170404) unf (>= 0.0.5, < 1.0.0) - dotenv (2.4.0) - dotenv-rails (2.4.0) - dotenv (= 2.4.0) + dotenv (2.5.0) + dotenv-rails (2.5.0) + dotenv (= 2.5.0) railties (>= 3.2, < 6.0) draper (3.0.1) actionpack (~> 5.0) @@ -201,9 +202,9 @@ GEM ethon (0.11.0) ffi (>= 1.3.0) eventmachine (1.2.7) - excon (0.60.0) + excon (0.62.0) execjs (2.7.0) - factory_bot (4.8.2) + factory_bot (4.10.0) activesupport (>= 3.0.0) faraday (0.12.2) multipart-post (>= 1.2, < 3) @@ -299,13 +300,13 @@ GEM fog-joyent (0.0.1) fog-core (~> 1.42) fog-json (>= 1.0) - fog-json (1.0.2) - fog-core (~> 1.0) + fog-json (1.2.0) + fog-core multi_json (~> 1.10) fog-local (0.4.0) fog-core (~> 1.27) - fog-openstack (0.1.24) - fog-core (~> 1.40) + fog-openstack (0.1.27) + fog-core (~> 1.45.0) fog-json (>= 1.0) ipaddress (>= 0.8) fog-ovirt (0.1.3) @@ -420,6 +421,7 @@ GEM concurrent-ruby (~> 1.0) inflecto (0.0.2) ipaddress (0.8.3) + jaro_winkler (1.5.1) jquery-rails (4.3.3) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) @@ -490,7 +492,7 @@ GEM nenv (0.3.0) netrc (0.11.0) nio4r (2.3.1) - nokogiri (1.8.2) + nokogiri (1.8.4) mini_portile2 (~> 2.3.0) notiffany (0.1.1) nenv (~> 0.1) @@ -521,15 +523,15 @@ GEM validate_email validate_url webfinger (>= 1.0.1) - openstack (3.3.18) + openstack (3.3.20) json orm_adapter (0.5.0) parallel (1.12.1) - parser (2.5.1.0) + parser (2.5.1.2) ast (~> 2.4.0) pdf-core (0.7.0) pg (1.0.0) - powerpack (0.1.1) + powerpack (0.1.2) prawn (2.2.2) pdf-core (~> 0.7.0) ttfunk (~> 1.5) @@ -561,7 +563,7 @@ GEM httpclient json-jwt (>= 1.9.0) rack - rack-protection (2.0.2) + rack-protection (2.0.3) rack rack-test (1.0.0) rack (>= 1.0, < 3) @@ -649,11 +651,12 @@ GEM rspec-mocks (~> 3.7.0) rspec-support (~> 3.7.0) rspec-support (3.7.1) - rspec_junit_formatter (0.3.0) + rspec_junit_formatter (0.4.1) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (0.56.0) + rubocop (0.58.1) + jaro_winkler (~> 1.5.1) parallel (~> 1.10) - parser (>= 2.5) + parser (>= 2.5, != 2.5.1.1) powerpack (~> 0.1) rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) @@ -690,23 +693,23 @@ GEM selenium-webdriver (3.8.0) childprocess (~> 0.5) rubyzip (~> 1.0) - sentry-raven (2.7.3) + sentry-raven (2.7.4) faraday (>= 0.7.6, < 1.0) sexp_processor (4.11.0) shellany (0.0.1) shoulda-matchers (3.1.2) activesupport (>= 4.0.0) - simple_form (4.0.0) - actionpack (> 4) - activemodel (> 4) - sinatra (2.0.2) + simple_form (4.0.1) + actionpack (>= 5.0) + activemodel (>= 5.0) + sinatra (2.0.3) mustermann (~> 1.0) rack (~> 2.0) - rack-protection (= 2.0.2) + rack-protection (= 2.0.3) tilt (~> 2.0) - skylight (2.0.1) - skylight-core (= 2.0.1) - skylight-core (2.0.1) + skylight (2.0.2) + skylight-core (= 2.0.2) + skylight-core (2.0.2) activesupport (>= 4.2.0) smart_listing (1.2.2) coffee-rails @@ -749,12 +752,12 @@ GEM ethon (>= 0.9.0) tzinfo (1.2.5) thread_safe (~> 0.1) - uglifier (4.1.10) + uglifier (4.1.15) execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext unf_ext (0.0.7.5) - unicode-display_width (1.3.2) + unicode-display_width (1.4.0) unicorn (5.4.0) kgio (~> 2.6) raindrops (~> 0.7) @@ -773,7 +776,7 @@ GEM webfinger (1.1.0) activesupport httpclient (>= 2.4) - webmock (3.4.1) + webmock (3.4.2) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff diff --git a/app/controllers/manager/users_controller.rb b/app/controllers/manager/users_controller.rb index 4cde73804..9e59c1500 100644 --- a/app/controllers/manager/users_controller.rb +++ b/app/controllers/manager/users_controller.rb @@ -1,4 +1,17 @@ module Manager class UsersController < Manager::ApplicationController + def resend_confirmation_instructions + user = User.find(params[:id]) + user.resend_confirmation_instructions + flash[:notice] = "Le message de confirmation de l’adresse email a été renvoyé." + redirect_to manager_user_path(user) + end + + def confirm + user = User.find(params[:id]) + user.confirm + flash[:notice] = "L’adresse email de l’utilisateur a été marquée comme confirmée." + redirect_to manager_user_path(user) + end end end diff --git a/app/controllers/new_gestionnaire/procedures_controller.rb b/app/controllers/new_gestionnaire/procedures_controller.rb index d9584e5e0..48d53cdb3 100644 --- a/app/controllers/new_gestionnaire/procedures_controller.rb +++ b/app/controllers/new_gestionnaire/procedures_controller.rb @@ -356,7 +356,7 @@ module NewGestionnaire def last_page? current_page == total_pages end -EVAL + EVAL end end end diff --git a/app/controllers/new_user/dossiers_controller.rb b/app/controllers/new_user/dossiers_controller.rb index 971c471dd..b94747c7e 100644 --- a/app/controllers/new_user/dossiers_controller.rb +++ b/app/controllers/new_user/dossiers_controller.rb @@ -1,8 +1,10 @@ module NewUser class DossiersController < UserController + include DossierHelper + helper_method :new_demarche_url - before_action :ensure_ownership!, except: [:index, :modifier, :update] + before_action :ensure_ownership!, except: [:index, :modifier, :update, :recherche] before_action :ensure_ownership_or_invitation!, only: [:modifier, :update] before_action :ensure_dossier_can_be_updated, only: [:update_identite, :update] before_action :forbid_invite_submission!, only: [:update] @@ -114,6 +116,18 @@ module NewUser end end + def recherche + @dossier_id = params[:dossier_id] + dossier = current_user.dossiers.find_by(id: @dossier_id) + + if dossier + redirect_to url_for_dossier(dossier) + else + flash.alert = "Vous n’avez pas de dossier avec le nº #{@dossier_id}." + redirect_to dossiers_path + end + end + def new_demarche_url "https://doc.demarches-simplifiees.fr/listes-des-demarches" end diff --git a/app/dashboards/user_dashboard.rb b/app/dashboards/user_dashboard.rb index 19fcb2e54..c61cc424b 100644 --- a/app/dashboards/user_dashboard.rb +++ b/app/dashboards/user_dashboard.rb @@ -10,6 +10,7 @@ class UserDashboard < Administrate::BaseDashboard ATTRIBUTE_TYPES = { id: Field::Number, email: Field::String, + confirmed?: Field::Boolean, created_at: Field::DateTime, updated_at: Field::DateTime, current_sign_in_at: Field::DateTime, @@ -32,6 +33,7 @@ class UserDashboard < Administrate::BaseDashboard :dossiers, :id, :email, + :confirmed?, :current_sign_in_at, :created_at, ].freeze diff --git a/app/mailers/new_attestation_mailer.rb b/app/mailers/new_attestation_mailer.rb index 70706316c..686fbb4af 100644 --- a/app/mailers/new_attestation_mailer.rb +++ b/app/mailers/new_attestation_mailer.rb @@ -21,7 +21,7 @@ class NewAttestationMailer < ApplicationMailer Suite à cette opération, l'attestation liée à votre dossier n'a pas été regénérée. Ce problème est désormais reglé, votre nouvelle attestation est disponible à l'adresse suivante : - #{dossier_attestation_url(dossier)} + #{attestation_dossier_url(dossier)} Cordialement, diff --git a/app/mailers/resend_attestation_mailer.rb b/app/mailers/resend_attestation_mailer.rb index f8a99855c..8be56fa00 100644 --- a/app/mailers/resend_attestation_mailer.rb +++ b/app/mailers/resend_attestation_mailer.rb @@ -17,7 +17,7 @@ class ResendAttestationMailer < ApplicationMailer L'attestation de votre dossier nº #{dossier.id} (procédure "#{dossier.procedure.libelle}") a été modifiée. Votre nouvelle attestation est disponible à l'adresse suivante : - #{dossier_attestation_url(dossier)} + #{attestation_dossier_url(dossier)} Cordialement, diff --git a/app/models/concerns/tags_substitution_concern.rb b/app/models/concerns/tags_substitution_concern.rb index d220f5f80..d40926856 100644 --- a/app/models/concerns/tags_substitution_concern.rb +++ b/app/models/concerns/tags_substitution_concern.rb @@ -53,7 +53,7 @@ module TagsSubstitutionConcern { libelle: 'lien attestation', description: '', - lambda: -> (d) { external_link(dossier_attestation_url(d)) }, + lambda: -> (d) { external_link(attestation_dossier_url(d)) }, available_for_states: ['accepte'] } ] diff --git a/app/views/dossiers/_attestation.html.haml b/app/views/dossiers/_attestation.html.haml index 2aba8551e..da124abc7 100644 --- a/app/views/dossiers/_attestation.html.haml +++ b/app/views/dossiers/_attestation.html.haml @@ -12,6 +12,6 @@ %p.title= dossier.attestation.title %p.delivery Délivrée le #{l(dossier.attestation.created_at, format: '%d %B %Y')} - if user_signed_in? && current_user == dossier.user - = link_to 'Télécharger', dossier_attestation_path(dossier), target: '_blank', class: 'btn btn-primary' + = link_to 'Télécharger', attestation_dossier_path(dossier), target: '_blank', class: 'btn btn-primary' - else = link_to 'Télécharger', attestation_gestionnaire_dossier_path(dossier.procedure, dossier), target: '_blank', class: 'btn btn-primary' diff --git a/app/views/layouts/_new_header.haml b/app/views/layouts/_new_header.haml index 25f715ee8..9a9af4624 100644 --- a/app/views/layouts/_new_header.haml +++ b/app/views/layouts/_new_header.haml @@ -47,6 +47,14 @@ %button{ title: "Rechercher" } = image_tag "icons/search-blue.svg" + - if nav_bar_profile == :user && user_signed_in? && current_user.dossiers.count > 2 + %li + .header-search + = form_tag recherche_dossiers_path, method: :post, class: "form" do + = text_field_tag :dossier_id, "", placeholder: "Numéro de dossier" + %button{ title: "Rechercher" } + = image_tag "icons/search-blue.svg" + - if gestionnaire_signed_in? || user_signed_in? %li .header-menu-opener diff --git a/app/views/manager/users/show.html.erb b/app/views/manager/users/show.html.erb new file mode 100644 index 000000000..c6a5f87be --- /dev/null +++ b/app/views/manager/users/show.html.erb @@ -0,0 +1,57 @@ +<%# +# Show + +This view is the template for the show page. +It renders the attributes of a resource, +as well as a link to its edit page. + +## Local variables: + +- `page`: + An instance of [Administrate::Page::Show][1]. + Contains methods for accessing the resource to be displayed on the page, + as well as helpers for describing how each attribute of the resource + should be displayed. + +[1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Show +%> + +<% content_for(:title) { t("administrate.actions.show_resource", name: page.page_title) } %> +<% user = page.resource %> + + + +
+
+ <% page.attributes.each do |attribute| %> +
+ <%= t( + "helpers.label.#{resource_name}.#{attribute.name}", + default: attribute.name.titleize, + ) %> +
+ +
<%= render_field attribute %>
+ <% end %> +
+
diff --git a/app/views/shared/dossiers/editable_champs/_siret.html.haml b/app/views/shared/dossiers/editable_champs/_siret.html.haml index e875564cf..b67817792 100644 --- a/app/views/shared/dossiers/editable_champs/_siret.html.haml +++ b/app/views/shared/dossiers/editable_champs/_siret.html.haml @@ -1,7 +1,7 @@ = form.text_field :value, placeholder: champ.libelle, class: 'small-margin', - data: { siret: champs_siret_path(format: :js, champ_id: champ) }, + data: { siret: champ.persisted? ? champs_siret_path(format: :js, champ_id: champ) : nil }, required: champ.mandatory? .spinner.right-spinner %div{ id: "etablissement-for-#{champ.id}" } diff --git a/config/routes.rb b/config/routes.rb index 9e0ca185a..663a9562f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -15,7 +15,11 @@ Rails.application.routes.draw do put 'enable_feature', on: :member end - resources :users, only: [:index, :show] + resources :users, only: [:index, :show] do + post 'resend_confirmation_instructions', on: :member + post 'confirm', on: :member + end + resources :gestionnaires, only: [:index, :show] do post 'reinvite', on: :member end @@ -241,12 +245,16 @@ Rails.application.routes.draw do get 'modifier' get 'merci' post 'ask_deletion' + get 'attestation' + end + + collection do + post 'recherche' + # FIXME: to remove when show is implemeted + # needed to fix refresh after dossier draft save + get ':id', to: redirect('/dossiers/%{id}/modifier') end - get 'attestation' end - # FIXME: to remove when show is implemeted - # needed to fix refresh after dossier draft save - get 'dossiers/:id', to: redirect('/dossiers/%{id}/modifier') end scope module: 'new_gestionnaire', as: 'gestionnaire' do diff --git a/spec/controllers/new_user/dossiers_controller_spec.rb b/spec/controllers/new_user/dossiers_controller_spec.rb index 17802c563..22c7ff106 100644 --- a/spec/controllers/new_user/dossiers_controller_spec.rb +++ b/spec/controllers/new_user/dossiers_controller_spec.rb @@ -111,7 +111,7 @@ describe NewUser::DossiersController, type: :controller do controller.head :ok end - get :attestation, params: { dossier_id: dossier.id } + get :attestation, params: { id: dossier.id } expect(response).to have_http_status(:success) end end diff --git a/spec/features/users/list_dossiers_spec.rb b/spec/features/users/list_dossiers_spec.rb index 8341291df..95e140763 100644 --- a/spec/features/users/list_dossiers_spec.rb +++ b/spec/features/users/list_dossiers_spec.rb @@ -65,4 +65,41 @@ describe 'user access to the list of his dossier' do expect(page).to have_content(CONTACT_EMAIL) end end + + describe "recherche" do + context "when the dossier does not exist" do + before do + page.find_by_id('dossier_id').set(10000000) + click_button("Rechercher") + end + + it "shows an error message on the dossiers page" do + expect(current_path).to eq(dossiers_path) + expect(page).to have_content("Vous n’avez pas de dossier avec le nº 10000000.") + end + end + + context "when the dossier does not belong to the user" do + before do + page.find_by_id('dossier_id').set(dossier2.id) + click_button("Rechercher") + end + + it "shows an error message on the dossiers page" do + expect(current_path).to eq(dossiers_path) + expect(page).to have_content("Vous n’avez pas de dossier avec le nº #{dossier2.id}.") + end + end + + context "when the dossier belongs to the user" do + before do + page.find_by_id('dossier_id').set(dossier1.id) + click_button("Rechercher") + end + + it "redirects to the dossier page" do + expect(current_path).to eq(users_dossier_recapitulatif_path(dossier1)) + end + end + end end