diff --git a/Gemfile b/Gemfile index c065d7692..378447a6f 100644 --- a/Gemfile +++ b/Gemfile @@ -22,6 +22,7 @@ gem 'jbuilder', '~> 2.0' # bundle exec rake doc:rails generates the API under doc/api. gem 'sdoc', '~> 0.4.0', group: :doc + # Use ActiveModel has_secure_password # gem 'bcrypt', '~> 3.1.7' @@ -52,6 +53,8 @@ gem 'openid_connect' gem 'rest-client' +gem 'clamav-client', require: 'clamav/client' + gem 'carrierwave' gem 'pg' @@ -124,6 +127,7 @@ group :development, :test do gem 'parallel_tests' + gem 'brakeman', require: false # Deploy gem 'mina', git: 'https://github.com/mina-deploy/mina.git' end diff --git a/Gemfile.lock b/Gemfile.lock index 1776d6d98..f21a7f26f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -72,6 +72,17 @@ GEM sass (>= 3.2.19) bootstrap-wysihtml5-rails (0.3.3.8) railties (>= 3.0) + brakeman (3.1.1) + erubis (~> 2.6) + fastercsv (~> 1.5) + haml (>= 3.0, < 5.0) + highline (~> 1.6) + multi_json (~> 1.2) + ruby2ruby (>= 2.1.1, < 2.3.0) + ruby_parser (~> 3.7.0) + sass (~> 3.0) + slim (>= 1.3.6, < 4.0) + terminal-table (~> 1.4) builder (3.2.2) byebug (5.0.0) columnize (= 0.9.0) @@ -89,6 +100,7 @@ GEM chartkick (1.3.2) childprocess (0.5.5) ffi (~> 1.0, >= 1.0.11) + clamav-client (3.0.0) cliver (0.3.2) coderay (1.1.0) coffee-rails (4.1.0) @@ -132,6 +144,7 @@ GEM activesupport (>= 3.0.0) faraday (0.9.1) multipart-post (>= 1.2, < 3) + fastercsv (1.5.5) ffi (1.9.6) font-awesome-rails (4.4.0.0) railties (>= 3.2, < 5.0) @@ -165,6 +178,7 @@ GEM html2haml (>= 1.0.1) railties (>= 4.0.1) hashie (3.4.1) + highline (1.7.8) html2haml (2.0.0) erubis (~> 2.7.0) haml (~> 4.0.0) @@ -346,6 +360,9 @@ GEM rubocop (>= 0.20.1) rubocop-rspec (1.3.0) ruby-progressbar (1.7.5) + ruby2ruby (2.1.4) + ruby_parser (~> 3.1) + sexp_processor (~> 4.0) ruby_parser (3.7.0) sexp_processor (~> 4.1) rubyzip (1.1.7) @@ -377,6 +394,9 @@ GEM multi_json (~> 1.0) simplecov-html (~> 0.8.0) simplecov-html (0.8.0) + slim (3.0.6) + temple (~> 0.7.3) + tilt (>= 1.3.3, < 2.1) slop (3.6.0) smart_listing (1.1.2) coffee-rails @@ -399,8 +419,10 @@ GEM httpclient (>= 2.4) i18n json (>= 1.4.3) + temple (0.7.6) terminal-notifier (1.6.3) terminal-notifier-guard (1.6.4) + terminal-table (1.5.2) therubyracer (0.12.2) libv8 (~> 3.16.14.0) ref @@ -463,10 +485,12 @@ DEPENDENCIES bootstrap-datepicker-rails bootstrap-sass (~> 3.3.5) bootstrap-wysihtml5-rails (~> 0.3.3.8) + brakeman byebug capybara carrierwave chartkick + clamav-client coffee-rails (~> 4.1.0) css_splitter database_cleaner diff --git a/Rakefile b/Rakefile index 47d01467e..e9c354f09 100644 --- a/Rakefile +++ b/Rakefile @@ -13,8 +13,8 @@ task :deploy do end task :deploy_test do - domains = %w(test_sgmap) - branch = 'master' + domains = %w(192.168.0.116) + branch = 'clamav' domains.each do |domain| sh "mina deploy domain=#{domain} branch=#{branch}" end diff --git a/app/assets/stylesheets/recapiitulatif.scss b/app/assets/stylesheets/recapitulatif.scss similarity index 58% rename from app/assets/stylesheets/recapiitulatif.scss rename to app/assets/stylesheets/recapitulatif.scss index 617f5b9cb..39699dc8f 100644 --- a/app/assets/stylesheets/recapiitulatif.scss +++ b/app/assets/stylesheets/recapitulatif.scss @@ -6,4 +6,14 @@ padding-top:15px; margin-left:-10rem; margin-right:-10rem; +} + +#UploadPJmodal { + text-align: left; + + table { + width: 100% !important; + margin-left: 0 !important; + margin-bottom: 0; + } } \ No newline at end of file diff --git a/app/controllers/france_connect/particulier_controller.rb b/app/controllers/france_connect/particulier_controller.rb index 118dbde01..16e103693 100644 --- a/app/controllers/france_connect/particulier_controller.rb +++ b/app/controllers/france_connect/particulier_controller.rb @@ -11,7 +11,7 @@ class FranceConnect::ParticulierController < ApplicationController state: session[:state], nonce: session[:nonce] ) - redirect_to authorization_uri + redirect_to URI.parse(authorization_uri).to_s end def callback diff --git a/app/controllers/users/description_controller.rb b/app/controllers/users/description_controller.rb index 9c2ad7624..fb6ecb930 100644 --- a/app/controllers/users/description_controller.rb +++ b/app/controllers/users/description_controller.rb @@ -55,19 +55,9 @@ class Users::DescriptionController < UsersController end end - @dossier.types_de_piece_justificative.each do |type_de_pieces_justificatives| - unless params["piece_justificative_#{type_de_pieces_justificatives.id}"].nil? - - piece_justificative = PieceJustificative.new(content: params["piece_justificative_#{type_de_pieces_justificatives.id}"], - dossier: @dossier, - type_de_piece_justificative: type_de_pieces_justificatives, - user: current_user) - - unless piece_justificative.save - flash.now.alert = piece_justificative.errors.full_messages.join('
').html_safe - return render 'show' - end - end + unless (errors_upload = PiecesJustificativesService.upload!(@dossier, current_user, params)).empty? + flash.alert = errors_upload.html_safe + return render 'show' end if @dossier.draft? @@ -78,6 +68,23 @@ class Users::DescriptionController < UsersController redirect_to url_for(controller: :recapitulatif, action: :show, dossier_id: @dossier.id) end + def pieces_justificatives + invite = current_user.invite? params[:dossier_id] + + @dossier ||= Dossier.find(params[:dossier_id]) if invite + @dossier ||= current_user_dossier + + if !((errors_upload = PiecesJustificativesService.upload!(@dossier, current_user, params)).empty?) + flash.alert = errors_upload.html_safe + else + flash.notice = 'Nouveaux fichiers envoyés' + end + + return redirect_to users_dossiers_invite_path(id: current_user.invites.find_by_dossier_id(@dossier.id).id) if invite + + redirect_to users_dossier_recapitulatif_path + end + def self.route_authorization { states: [:draft, :initiated, :replied, :updated] diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 913f96758..6bb913e25 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -42,7 +42,7 @@ class Dossier < ActiveRecord::Base end def retrieve_all_piece_justificative_by_type(type) - pieces_justificatives.where(type_de_piece_justificative_id: type) + pieces_justificatives.where(type_de_piece_justificative_id: type).order(created_at: :DESC) end def build_default_champs diff --git a/app/models/user.rb b/app/models/user.rb index c1cc2f0ce..93237e89c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -29,4 +29,8 @@ class User < ActiveRecord::Base def loged_in_with_france_connect? !loged_in_with_france_connect.nil? end + + def invite? dossier_id + invites.pluck(:dossier_id).include?(dossier_id.to_i) + end end diff --git a/app/services/clamav_service.rb b/app/services/clamav_service.rb new file mode 100644 index 000000000..f34c32c76 --- /dev/null +++ b/app/services/clamav_service.rb @@ -0,0 +1,12 @@ +class ClamavService + def self.safe_file? path_file + + FileUtils.chmod 0666, path_file + + client = ClamAV::Client.new + response = client.execute(ClamAV::Commands::ScanCommand.new(path_file)) + + return false if response.first.class == ClamAV::VirusResponse + true + end +end \ No newline at end of file diff --git a/app/services/pieces_justificatives_service.rb b/app/services/pieces_justificatives_service.rb new file mode 100644 index 000000000..c19a7ddc8 --- /dev/null +++ b/app/services/pieces_justificatives_service.rb @@ -0,0 +1,24 @@ +class PiecesJustificativesService + def self.upload! dossier, user, params + errors = '' + + dossier.types_de_piece_justificative.each do |type_de_pieces_justificatives| + unless params["piece_justificative_#{type_de_pieces_justificatives.id}"].nil? + + if ClamavService.safe_file? params["piece_justificative_#{type_de_pieces_justificatives.id}"].path + piece_justificative = PieceJustificative.new(content: params["piece_justificative_#{type_de_pieces_justificatives.id}"], + dossier: dossier, + type_de_piece_justificative: type_de_pieces_justificatives, + user: user) + + unless piece_justificative.save + errors << piece_justificative.errors.messages[:content][0]+" (#{piece_justificative.libelle})"+"
" + end + else + errors << params["piece_justificative_#{type_de_pieces_justificatives.id}"].original_filename+": Virus détecté !!"+"
" + end + end + end + errors + end +end \ No newline at end of file diff --git a/app/views/admin/procedures/show.html.haml b/app/views/admin/procedures/show.html.haml index af3d83e5d..3dc75cd8a 100644 --- a/app/views/admin/procedures/show.html.haml +++ b/app/views/admin/procedures/show.html.haml @@ -54,7 +54,7 @@ %h4.text-info = @facade.procedure.libelle - = @facade.procedure.description.html_safe + = h @facade.procedure.description.html_safe .champs.col-md-4.col-lg-4 %h4.text-info Champs diff --git a/app/views/dossiers/_infos_dossier.html.haml b/app/views/dossiers/_infos_dossier.html.haml index bf1471b30..94b269a48 100644 --- a/app/views/dossiers/_infos_dossier.html.haml +++ b/app/views/dossiers/_infos_dossier.html.haml @@ -7,7 +7,7 @@ = @facade.dossier.procedure.libelle .description - = @facade.dossier.description.html_safe + = h @facade.dossier.description.html_safe - if @facade.dossier.mandataire_social && gestionnaire_signed_in? .mandataire_social.text-success.center @@ -46,13 +46,23 @@ %br .row{style: 'text-align:right'} - -if user_signed_in? && (current_user.email == @facade.dossier.user.email) - -if !@facade.dossier.validated? && !@facade.dossier.submitted? && !@facade.dossier.closed? - -if @facade.dossier.procedure.module_api_carto.use_api_carto - %a#maj_carte.btn.btn-primary{href: "/users/dossiers/#{@facade.dossier.id}/carte"} - = 'Editer ma carte' - %a#maj_infos.btn.btn-info{href: "/users/dossiers/#{@facade.dossier.id}/description"} - = 'Editer mon dossier' + -if !@facade.dossier.validated? && !@facade.dossier.submitted? && !@facade.dossier.closed? + - if user_signed_in? + - if @facade.procedure.cerfa_flag? || @facade.dossier.types_de_piece_justificative.size > 0 + %a.btn.btn-success{"data-target" => "#UploadPJmodal", + "data-toggle" => "modal", + :type => "button", + style: 'margin-bottom: 15px; margin-top: -30px'} + Modifier les documents + %br + = render partial: 'users/recapitulatif/modal_upload_pj' + + - if(current_user.email == @facade.dossier.user.email) + -if @facade.dossier.procedure.module_api_carto.use_api_carto + %a#maj_carte.btn.btn-primary{href: "/users/dossiers/#{@facade.dossier.id}/carte"} + = 'Modifier ma carte' + %a#maj_infos.btn.btn-info{href: "/users/dossiers/#{@facade.dossier.id}/description"} + = 'Modifier mon dossier' -if gestionnaire_signed_in? -if !@facade.dossier.validated? && !@facade.dossier.submitted? && !@facade.dossier.closed? diff --git a/app/views/dossiers/_pieces_justificatives.html.haml b/app/views/dossiers/_pieces_justificatives.html.haml index b280699a1..69a367896 100644 --- a/app/views/dossiers/_pieces_justificatives.html.haml +++ b/app/views/dossiers/_pieces_justificatives.html.haml @@ -7,18 +7,18 @@ ='Formulaire' %td.col-lg-6.col-md-6 - if @facade.dossier.cerfa_available? - - if user_signed_in? - = 'Pièce fournie' - - elsif gestionnaire_signed_in? - %a{ href: "#{@facade.dossier.cerfa.last.content_url}", target: '_blank' } Consulter - %span{style:'margin-left:12px'} - \- - %a.btn.glyphicon.glyphicon-time{style:'color: black; padding-top: 0', - "data-target" => "#PJmodal", - "data-toggle" => "modal", - :type => "button", - "data-modal_title" => 'formulaires', - "data-modal_index" => 'cerfa'} + -#- if user_signed_in? + -# = 'Pièce fournie' + -#- elsif gestionnaire_signed_in? + %a{ href: "#{@facade.dossier.cerfa.last.content_url}", target: '_blank' } Consulter + %span{style:'margin-left:12px'} + \- + %a.btn.glyphicon.glyphicon-time{style:'color: black; padding-top: 0', + "data-target" => "#PJmodal", + "data-toggle" => "modal", + :type => "button", + "data-modal_title" => 'formulaires', + "data-modal_index" => 'cerfa'} - else = 'Pièce non fournie' @@ -30,20 +30,20 @@ - if type_de_piece_justificative.api_entreprise %span.text-success Nous l'avons récupéré pour vous. - elsif !(@pj = @facade.dossier.retrieve_last_piece_justificative_by_type(type_de_piece_justificative.id)).nil? - - if user_signed_in? - = 'Pièce fournie' - - elsif gestionnaire_signed_in? - %a{ href: "#{@pj.content_url}", target: '_blank' } Consulter - %span{style:'margin-left:12px'} - \- - %a.btn.glyphicon.glyphicon-time{style:'color: black; padding-top: 0', - "data-target" => "#PJmodal", - "data-toggle" => "modal", - :type => "button", - "data-modal_title" => type_de_piece_justificative.libelle, - "data-modal_index" => "type_de_pj_#{type_de_piece_justificative.id}"} + -#- if user_signed_in? + -# = 'Pièce fournie' + -#- elsif gestionnaire_signed_in? + %a{ href: "#{@pj.content_url}", target: '_blank' } Consulter + %span{style:'margin-left:12px'} + \- + %a.btn.glyphicon.glyphicon-time{style:'color: black; padding-top: 0', + "data-target" => "#PJmodal", + "data-toggle" => "modal", + :type => "button", + "data-modal_title" => type_de_piece_justificative.libelle, + "data-modal_index" => "type_de_pj_#{type_de_piece_justificative.id}"} - else = 'Pièce non fournie' - - if gestionnaire_signed_in? - =render partial: '/dossiers/modal_historique' \ No newline at end of file + -#- if gestionnaire_signed_in? + =render partial: '/dossiers/modal_historique' \ No newline at end of file diff --git a/app/views/users/description/_pieces_justificatives.html.haml b/app/views/users/description/_pieces_justificatives.html.haml new file mode 100644 index 000000000..1aed8207a --- /dev/null +++ b/app/views/users/description/_pieces_justificatives.html.haml @@ -0,0 +1,65 @@ +%table{class:'table', style:'width:55%; margin-left:5%'} + - if @dossier.procedure.cerfa_flag + %tr + %th{class:'col-lg-6'} + ='Formulaire' + + %td{class:'col-lg-5'} + -if @dossier.cerfa_available? + %span.btn.btn-sm.btn-file.btn-success + Modifier + %input{type: 'file', name:'cerfa_pdf', id:'cerfa_pdf', accept: "application/pdf, + application/msword, + application/vnd.openxmlformats-officedocument.wordprocessingml.document, + application/vnd.ms-excel, + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, + application/vnd.ms-powerpoint, + application/vnd.openxmlformats-officedocument.presentationml.presentation, + application/vnd.oasis.opendocument.text, + application/vnd.oasis.opendocument.presentation, + application/vnd.oasis.opendocument.spreadsheet", :max_file_size => 3.megabytes } + -else + %input{type: 'file', name:'cerfa_pdf', id:'cerfa_pdf', accept: "application/pdf, + application/msword, + application/vnd.openxmlformats-officedocument.wordprocessingml.document, + application/vnd.ms-excel, + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, + application/vnd.ms-powerpoint, + application/vnd.openxmlformats-officedocument.presentationml.presentation, + application/vnd.oasis.opendocument.text, + application/vnd.oasis.opendocument.presentation, + application/vnd.oasis.opendocument.spreadsheet", :max_file_size => 3.megabytes } + + - @dossier.types_de_piece_justificative.each do |type_de_piece_justificative| + %tr + %th.col-lg-6 + = type_de_piece_justificative.libelle + %td.col-lg-5 + -if type_de_piece_justificative.api_entreprise + %span.text-success{ id: "piece_justificative_#{type_de_piece_justificative.id}" } Nous l'avons récupéré pour vous. + -else + -if @dossier.retrieve_last_piece_justificative_by_type(type_de_piece_justificative.id).nil? + = file_field_tag "piece_justificative_#{type_de_piece_justificative.id}", accept: " application/pdf, + application/msword, + application/vnd.openxmlformats-officedocument.wordprocessingml.document, + application/vnd.ms-excel, + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, + application/vnd.ms-powerpoint, + application/vnd.openxmlformats-officedocument.presentationml.presentation, + application/vnd.oasis.opendocument.text, + application/vnd.oasis.opendocument.presentation, + application/vnd.oasis.opendocument.spreadsheet", :max_file_size => 3.megabytes + -else + %span.btn.btn-sm.btn-file.btn-success + Modifier + = file_field_tag "piece_justificative_#{type_de_piece_justificative.id}", accept: " application/pdf, + application/msword, + application/vnd.openxmlformats-officedocument.wordprocessingml.document, + application/vnd.ms-excel, + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, + application/vnd.ms-powerpoint, + application/vnd.openxmlformats-officedocument.presentationml.presentation, + application/vnd.oasis.opendocument.text, + application/vnd.oasis.opendocument.presentation, + application/vnd.oasis.opendocument.spreadsheet", :max_file_size => 3.megabytes + diff --git a/app/views/users/description/show.html.haml b/app/views/users/description/show.html.haml index 87acd5758..a1d9b0300 100644 --- a/app/views/users/description/show.html.haml +++ b/app/views/users/description/show.html.haml @@ -62,70 +62,7 @@ %br //TODO a refactorer - %table{class:'table', style:'width:55%; margin-left:5%'} - - if @procedure.cerfa_flag - %tr - %th{class:'col-lg-6'} - ='Formulaire' - - %td{class:'col-lg-5'} - -if @dossier.cerfa_available? - %span.btn.btn-sm.btn-file.btn-success - Modifier - %input{type: 'file', name:'cerfa_pdf', id:'cerfa_pdf', accept: "application/pdf, - application/msword, - application/vnd.openxmlformats-officedocument.wordprocessingml.document, - application/vnd.ms-excel, - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, - application/vnd.ms-powerpoint, - application/vnd.openxmlformats-officedocument.presentationml.presentation, - application/vnd.oasis.opendocument.text, - application/vnd.oasis.opendocument.presentation, - application/vnd.oasis.opendocument.spreadsheet", :max_file_size => 3.megabytes } - -else - %input{type: 'file', name:'cerfa_pdf', id:'cerfa_pdf', accept: "application/pdf, - application/msword, - application/vnd.openxmlformats-officedocument.wordprocessingml.document, - application/vnd.ms-excel, - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, - application/vnd.ms-powerpoint, - application/vnd.openxmlformats-officedocument.presentationml.presentation, - application/vnd.oasis.opendocument.text, - application/vnd.oasis.opendocument.presentation, - application/vnd.oasis.opendocument.spreadsheet", :max_file_size => 3.megabytes } - - - @dossier.types_de_piece_justificative.each do |type_de_piece_justificative| - %tr - %th.col-lg-6 - = type_de_piece_justificative.libelle - %td.col-lg-5 - -if type_de_piece_justificative.api_entreprise - %span.text-success{ id: "piece_justificative_#{type_de_piece_justificative.id}" } Nous l'avons récupéré pour vous. - -else - -if @dossier.retrieve_last_piece_justificative_by_type(type_de_piece_justificative.id).nil? - = file_field_tag "piece_justificative_#{type_de_piece_justificative.id}", accept: " application/pdf, - application/msword, - application/vnd.openxmlformats-officedocument.wordprocessingml.document, - application/vnd.ms-excel, - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, - application/vnd.ms-powerpoint, - application/vnd.openxmlformats-officedocument.presentationml.presentation, - application/vnd.oasis.opendocument.text, - application/vnd.oasis.opendocument.presentation, - application/vnd.oasis.opendocument.spreadsheet", :max_file_size => 3.megabytes - -else - %span.btn.btn-sm.btn-file.btn-success - Modifier - = file_field_tag "piece_justificative_#{type_de_piece_justificative.id}", accept: " application/pdf, - application/msword, - application/vnd.openxmlformats-officedocument.wordprocessingml.document, - application/vnd.ms-excel, - application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, - application/vnd.ms-powerpoint, - application/vnd.openxmlformats-officedocument.presentationml.presentation, - application/vnd.oasis.opendocument.text, - application/vnd.oasis.opendocument.presentation, - application/vnd.oasis.opendocument.spreadsheet", :max_file_size => 3.megabytes + = render partial: 'pieces_justificatives' %div{style: 'text-align:right'} %h6 Tous les champs portant un * sont obligatoires. diff --git a/app/views/users/dossiers/new.html.haml b/app/views/users/dossiers/new.html.haml index d40fcabd4..2103965e1 100644 --- a/app/views/users/dossiers/new.html.haml +++ b/app/views/users/dossiers/new.html.haml @@ -14,7 +14,7 @@ %h2#titre_procedure.text-info = @dossier.procedure.libelle %p - = @dossier.procedure.description.html_safe + = h @dossier.procedure.description.html_safe %br = form_for @dossier, url: {controller: 'users/dossiers', action: :create}, method: :post do |f| diff --git a/app/views/users/recapitulatif/_modal_upload_pj.html.haml b/app/views/users/recapitulatif/_modal_upload_pj.html.haml new file mode 100644 index 000000000..0691c3f09 --- /dev/null +++ b/app/views/users/recapitulatif/_modal_upload_pj.html.haml @@ -0,0 +1,17 @@ +#UploadPJmodal.modal.fade{"aria-labelledby" => "myModalLabel", :role => "dialog", :tabindex => "-1"} + .modal-dialog{:role => "document"} + .modal-content + - @dossier = @facade.dossier + = form_tag(url_for({controller: '/users/description', action: :pieces_justificatives, dossier_id: @dossier.id}), class: 'form-inline', method: 'PATCH', multipart: true) do + + .modal-header + %button.close{"aria-label" => "Close", "data-dismiss" => "modal", :type => "button"} + %span{"aria-hidden" => "true"} × + %h4.modal-title + Modification des documents + + .modal-body + = render partial: 'users/description/pieces_justificatives' + + .modal-footer + = submit_tag 'Modification terminée', class: %w(btn btn btn-info), id: 'modification_terminee', data: { disable_with: 'Modification terminée', submit: true} diff --git a/app/views/users/recapitulatif/show.html.haml b/app/views/users/recapitulatif/show.html.haml index 70b1a9d78..ef03c1c61 100644 --- a/app/views/users/recapitulatif/show.html.haml +++ b/app/views/users/recapitulatif/show.html.haml @@ -36,5 +36,4 @@ %br = render partial: '/dossiers/infos_dossier' -%br = render partial: '/users/recapitulatif/commentaires_flux' \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 004c08e54..5da3ac7ac 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -53,9 +53,13 @@ Rails.application.routes.draw do get '/description' => 'description#show' get '/description/error' => 'description#error' post 'description' => 'description#create' + + patch 'pieces_justificatives' => 'description#pieces_justificatives' + get '/recapitulatif' => 'recapitulatif#show' post '/recapitulatif/initiate' => 'recapitulatif#initiate' post '/recapitulatif/submit' => 'recapitulatif#submit' + post '/commentaire' => 'commentaires#create' get '/carte/position' => 'carte#get_position' diff --git a/public/fonts/bootstrap/glyphicons-halflings-regular.svg b/public/fonts/bootstrap/glyphicons-halflings-regular.svg new file mode 100755 index 000000000..94fb5490a --- /dev/null +++ b/public/fonts/bootstrap/glyphicons-halflings-regular.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/fonts/bootstrap/glyphicons-halflings-regular.ttf b/public/fonts/bootstrap/glyphicons-halflings-regular.ttf new file mode 100755 index 000000000..1413fc609 Binary files /dev/null and b/public/fonts/bootstrap/glyphicons-halflings-regular.ttf differ diff --git a/public/fonts/bootstrap/glyphicons-halflings-regular.woff b/public/fonts/bootstrap/glyphicons-halflings-regular.woff new file mode 100755 index 000000000..9e612858f Binary files /dev/null and b/public/fonts/bootstrap/glyphicons-halflings-regular.woff differ diff --git a/spec/controllers/users/description_controller_spec.rb b/spec/controllers/users/description_controller_spec.rb index 88d6ffb13..6c9b50600 100644 --- a/spec/controllers/users/description_controller_spec.rb +++ b/spec/controllers/users/description_controller_spec.rb @@ -9,7 +9,17 @@ describe Users::DescriptionController, type: :controller do let(:dossier_id) { dossier.id } let(:bad_dossier_id) { Dossier.count + 10000 } + let(:name_piece_justificative) { 'dossierPDF.pdf' } + let(:name_piece_justificative_0) { 'piece_justificative_0.pdf' } + let(:name_piece_justificative_1) { 'piece_justificative_1.pdf' } + + let(:cerfa_pdf) { Rack::Test::UploadedFile.new("./spec/support/files/#{name_piece_justificative}", 'application/pdf') } + let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/#{name_piece_justificative_0}", 'application/pdf') } + let(:piece_justificative_1) { Rack::Test::UploadedFile.new("./spec/support/files/#{name_piece_justificative_1}", 'application/pdf') } + before do + allow(ClamavService).to receive(:safe_file?).and_return(true) + sign_in dossier.user end @@ -56,14 +66,6 @@ describe Users::DescriptionController, type: :controller do let(:nom_projet) { 'Projet de test' } let(:description) { 'Description de test Coucou, je suis un saut à la ligne Je suis un double saut la ligne.' } - let(:name_piece_justificative) { 'dossierPDF.pdf' } - let(:name_piece_justificative_0) { 'piece_justificative_0.pdf' } - let(:name_piece_justificative_1) { 'piece_justificative_1.pdf' } - - let(:cerfa_pdf) { Rack::Test::UploadedFile.new("./spec/support/files/#{name_piece_justificative}", 'application/pdf') } - let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/#{name_piece_justificative_0}", 'application/pdf') } - let(:piece_justificative_1) { Rack::Test::UploadedFile.new("./spec/support/files/#{name_piece_justificative_1}", 'application/pdf') } - context 'Tous les attributs sont bons' do # TODO separer en deux tests : check donnees et check redirect describe 'Premier enregistrement des données' do @@ -221,6 +223,20 @@ describe Users::DescriptionController, type: :controller do dossier.reload end + describe 'clamav anti-virus presence' do + it 'ClamavService safe_file? is call' do + expect(ClamavService).to receive(:safe_file?).twice + + post :create, {dossier_id: dossier_id, + nom_projet: nom_projet, + description: description, + 'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0, + 'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} + + + end + end + context 'for piece 0' do subject { dossier.retrieve_last_piece_justificative_by_type all_pj_type[0].to_s } it { expect(subject.content).not_to be_nil } @@ -233,4 +249,132 @@ describe Users::DescriptionController, type: :controller do end end end + + describe 'POST #pieces_justificatives' do + let(:all_pj_type) { dossier.procedure.type_de_piece_justificative_ids } + + subject { patch :pieces_justificatives, {dossier_id: dossier.id, + 'piece_justificative_'+all_pj_type[0].to_s => piece_justificative_0, + 'piece_justificative_'+all_pj_type[1].to_s => piece_justificative_1} } + + context 'when user is the owner' do + before do + sign_in user + end + + context 'when PJ have no documents' do + it { expect(dossier.pieces_justificatives.size).to eq 0 } + + context 'when upload two PJ' do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 2 } + it { expect(flash[:notice]).to be_present } + it { is_expected.to redirect_to users_dossier_recapitulatif_path } + end + end + + context 'when PJ have already a document' do + before do + create :piece_justificative, :rib, dossier: dossier, type_de_piece_justificative_id: all_pj_type[0] + create :piece_justificative, :contrat, dossier: dossier, type_de_piece_justificative_id: all_pj_type[1] + end + + it { expect(dossier.pieces_justificatives.size).to eq 2 } + + context 'when upload two PJ' do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 4 } + it { expect(flash[:notice]).to be_present } + it { is_expected.to redirect_to users_dossier_recapitulatif_path } + end + end + + context 'when one of PJs is not valid' do + let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/entreprise.json", 'application/json') } + + it { expect(dossier.pieces_justificatives.size).to eq 0 } + + context 'when upload two PJ' do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 1 } + it { expect(flash[:alert]).to be_present } + it { is_expected.to redirect_to users_dossier_recapitulatif_path } + end + end + end + + context 'when user is a guest' do + let(:guest) { create :user } + + before do + create :invite, dossier: dossier, email: guest.email, user: guest + + sign_in guest + end + + context 'when PJ have no documents' do + it { expect(dossier.pieces_justificatives.size).to eq 0 } + + context 'when upload two PJ' do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 2 } + it { expect(flash[:notice]).to be_present } + it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) } + end + end + + context 'when PJ have already a document' do + before do + create :piece_justificative, :rib, dossier: dossier, type_de_piece_justificative_id: all_pj_type[0] + create :piece_justificative, :contrat, dossier: dossier, type_de_piece_justificative_id: all_pj_type[1] + end + + it { expect(dossier.pieces_justificatives.size).to eq 2 } + + context 'when upload two PJ' do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 4 } + it { expect(flash[:notice]).to be_present } + it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) } + end + end + + context 'when one of PJs is not valid' do + let(:piece_justificative_0) { Rack::Test::UploadedFile.new("./spec/support/files/entreprise.json", 'application/json') } + + it { expect(dossier.pieces_justificatives.size).to eq 0 } + + context 'when upload two PJ' do + before do + subject + dossier.reload + end + + it { expect(dossier.pieces_justificatives.size).to eq 1 } + it { expect(flash[:alert]).to be_present } + it { is_expected.to redirect_to users_dossiers_invite_path(id: guest.invites.find_by_dossier_id(dossier.id).id) } + end + end + end + end end diff --git a/spec/features/description_page/upload_piece_justificative_spec.rb b/spec/features/description_page/upload_piece_justificative_spec.rb index 468fd4415..3ea348592 100644 --- a/spec/features/description_page/upload_piece_justificative_spec.rb +++ b/spec/features/description_page/upload_piece_justificative_spec.rb @@ -3,7 +3,10 @@ require 'spec_helper' feature 'user is on description page' do let!(:procedure) { create(:procedure, :with_two_type_de_piece_justificative, cerfa_flag: true) } let!(:dossier) { create(:dossier, :with_entreprise, procedure: procedure) } + before do + allow(ClamavService).to receive(:safe_file?).and_return(true) + visit users_dossier_description_path dossier within('#new_user') do @@ -13,6 +16,7 @@ feature 'user is on description page' do end end + it { expect(page).to have_css('#description_page') } context 'he fill description fields' do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index aeedb4f69..555fdfcb1 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -36,7 +36,7 @@ describe User, type: :model do expect(subject.siret).to eq(siret) end it 'does not create new user' do - expect{ subject }.not_to change(User, :count) + expect { subject }.not_to change(User, :count) end end context 'when user does not exist' do @@ -46,11 +46,30 @@ describe User, type: :model do expect(subject).to be_an_instance_of(User) end it 'creates new user' do - expect{ subject }.to change(User, :count).by(1) + expect { subject }.to change(User, :count).by(1) end it 'saves siret' do expect(subject.siret).to eq(siret) end end end + + describe '#invite?' do + let(:dossier) { create :dossier } + let(:user) { dossier.user } + + subject { user.invite? dossier.id } + + context 'when user is invite at the dossier' do + before do + create :invite, dossier_id: dossier.id, user: user + end + + it { is_expected.to be_truthy } + end + + context 'when user is not invite at the dossier' do + it { is_expected.to be_falsey } + end + end end diff --git a/spec/views/backoffice/dossiers/show.html.html_spec.rb b/spec/views/backoffice/dossiers/show.html.html_spec.rb index 9e54e4b74..194da7043 100644 --- a/spec/views/backoffice/dossiers/show.html.html_spec.rb +++ b/spec/views/backoffice/dossiers/show.html.html_spec.rb @@ -15,6 +15,12 @@ describe 'backoffice/dossiers/show.html.haml', type: :view do before do render end + + it 'button Modifier les document est present' do + expect(rendered).not_to have_content('Modifier les documents') + expect(rendered).not_to have_css('#UploadPJmodal') + end + it 'enterprise informations are present' do expect(rendered).to have_selector('#infos_entreprise') end diff --git a/spec/views/users/recapitulatif/show.html.haml_spec.rb b/spec/views/users/recapitulatif/show.html.haml_spec.rb index 6d38bd8a7..799e52f7e 100644 --- a/spec/views/users/recapitulatif/show.html.haml_spec.rb +++ b/spec/views/users/recapitulatif/show.html.haml_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe 'users/recapitulatif/show.html.haml', type: :view do - let(:dossier) { create(:dossier, :with_entreprise, state: state, procedure: create(:procedure, :with_api_carto)) } + let(:dossier) { create(:dossier, :with_entreprise, state: state, procedure: create(:procedure, :with_api_carto, :with_two_type_de_piece_justificative)) } let(:dossier_id) { dossier.id } let(:state) { 'draft' } @@ -60,6 +60,12 @@ describe 'users/recapitulatif/show.html.haml', type: :view do end it { expect(rendered).to have_content('Soumis') } + + it 'button Modifier les document est present' do + expect(rendered).to have_content('Modifier les documents') + expect(rendered).to have_css('#UploadPJmodal') + end + end context 'when dossier state is replied' do @@ -96,7 +102,11 @@ describe 'users/recapitulatif/show.html.haml', type: :view do it 'button Editer mon dossier n\'est plus present' do expect(rendered).not_to have_css('#maj_infos') - expect(rendered).not_to have_content('Editer mon dossier') + expect(rendered).not_to have_content('Modifier mon dossier') + end + + it 'button Modifier les document n\'est plus present' do + expect(rendered).not_to have_content('Modifier les documents') end end @@ -111,7 +121,7 @@ describe 'users/recapitulatif/show.html.haml', type: :view do it 'button Editer mon dossier n\'est plus present' do expect(rendered).not_to have_css('#maj_infos') - expect(rendered).not_to have_content('Editer mon dossier') + expect(rendered).not_to have_content('Modifier mon dossier') end end @@ -125,7 +135,7 @@ describe 'users/recapitulatif/show.html.haml', type: :view do it 'button Editer mon dossier n\'est plus present' do expect(rendered).not_to have_css('#maj_infos') - expect(rendered).not_to have_content('Editer mon dossier') + expect(rendered).not_to have_content('Modifier mon dossier') end end end