From 833d7790c2d34fa50621bd4a9f6470a581a457f5 Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Fri, 13 May 2016 16:08:51 +0200 Subject: [PATCH 01/20] Add support for remote OVH cloud storage --- Gemfile | 3 + Gemfile.lock | 143 + app/models/cerfa.rb | 8 +- app/models/piece_justificative.rb | 10 +- app/uploaders/cerfa_uploader.rb | 72 +- .../{downloader.rb => local_downloader.rb} | 2 +- app/uploaders/piece_justificative_uploader.rb | 74 +- app/uploaders/procedure_logo_uploader.rb | 66 +- app/uploaders/remote_downloader.rb | 11 + .../_commentaires_flux.html.haml | 2 +- config/initializers/carrierwave.rb | 28 + config/initializers/features.rb | 26 + ...ginal_filename_to_pieces_justificatives.rb | 5 + ...2160658_add_original_filename_to_cerfas.rb | 5 + ...0824_add_content_secure_token_to_cerfas.rb | 5 + ...t_secure_token_to_pieces_justificatives.rb | 5 + ...425_add_logo_secure_token_to_procedures.rb | 5 + db/schema.rb | 7 +- lib/tasks/dev.rake | 27 + .../api/v1/dossiers_controller_spec.rb | 10 +- .../commentaires_controller_spec.rb | 2 +- .../users/commentaires_controller_spec.rb | 2 +- .../users/description_controller_spec.rb | 20 +- .../upload_piece_justificative_spec.rb | 4 +- .../drawing_a_zone_with_freedraw_spec.rb | 4 +- ...llers_api_v1_dossiers_controller_cerfa.yml | 7833 ++++ ...ossiers_controller_piece_justificative.yml | 7833 ++++ ...res_controller_doc_upload_with_comment.yml | 7833 ++++ ...ers_commentaires_controller_upload_doc.yml | 7833 ++++ ...s_description_controller_cerfa_is_sent.yml | 7833 ++++ ...description_controller_clamav_presence.yml | 31020 ++++++++++++++++ ...ption_controller_pieces_justificatives.yml | 15562 ++++++++ ...escription_controller_pj_already_exist.yml | 15562 ++++++++ ...controller_pj_already_exist_upload_2pj.yml | 31020 ++++++++++++++++ ...s_description_controller_sauvegarde_pj.yml | 15562 ++++++++ ...sers_description_controller_save_cerfa.yml | 15562 ++++++++ ...sers_description_controller_upload_2pj.yml | 31020 ++++++++++++++++ ..._upload_piece_justificative_adds_cerfa.yml | 7833 ++++ ...ce_justificative_adds_cerfa_and_submit.yml | 7833 ++++ ..._with_freedraw_when_draw_a_zone_on_map.yml | 143 + .../cassettes/model_piece_justificative.yml | 7833 ++++ .../fixtures/cassettes/models_cerfa_empty.yml | 7833 ++++ ...rieve_last_piece_justificative_by_type.yml | 7833 ++++ spec/fixtures/cassettes/ovh_storage_init.yml | 104 + .../cassettes/user_dossier_new_html.yml | 1344 + ..._users_recapitulatif_commentaires_flux.yml | 7833 ++++ spec/models/cerfa_spec.rb | 2 +- spec/models/dossier_spec.rb | 2 +- spec/models/piece_justificative_spec.rb | 2 +- spec/spec_helper.rb | 23 + spec/support/factory_girl.rb | 3 + .../users/dossiers/new_html.haml_spec.rb | 2 +- .../recapitulatif/_commentaires_flux_spec.rb | 2 +- 53 files changed, 243518 insertions(+), 126 deletions(-) rename app/uploaders/{downloader.rb => local_downloader.rb} (97%) create mode 100644 app/uploaders/remote_downloader.rb create mode 100644 config/initializers/carrierwave.rb create mode 100644 config/initializers/features.rb create mode 100644 db/migrate/20160512160602_add_original_filename_to_pieces_justificatives.rb create mode 100644 db/migrate/20160512160658_add_original_filename_to_cerfas.rb create mode 100644 db/migrate/20160512160824_add_content_secure_token_to_cerfas.rb create mode 100644 db/migrate/20160512160836_add_content_secure_token_to_pieces_justificatives.rb create mode 100644 db/migrate/20160513093425_add_logo_secure_token_to_procedures.rb create mode 100644 spec/fixtures/cassettes/controllers_api_v1_dossiers_controller_cerfa.yml create mode 100644 spec/fixtures/cassettes/controllers_api_v1_dossiers_controller_piece_justificative.yml create mode 100644 spec/fixtures/cassettes/controllers_backoffice_commentaires_controller_doc_upload_with_comment.yml create mode 100644 spec/fixtures/cassettes/controllers_sers_commentaires_controller_upload_doc.yml create mode 100644 spec/fixtures/cassettes/controllers_users_description_controller_cerfa_is_sent.yml create mode 100644 spec/fixtures/cassettes/controllers_users_description_controller_clamav_presence.yml create mode 100644 spec/fixtures/cassettes/controllers_users_description_controller_pieces_justificatives.yml create mode 100644 spec/fixtures/cassettes/controllers_users_description_controller_pj_already_exist.yml create mode 100644 spec/fixtures/cassettes/controllers_users_description_controller_pj_already_exist_upload_2pj.yml create mode 100644 spec/fixtures/cassettes/controllers_users_description_controller_sauvegarde_pj.yml create mode 100644 spec/fixtures/cassettes/controllers_users_description_controller_save_cerfa.yml create mode 100644 spec/fixtures/cassettes/controllers_users_description_controller_upload_2pj.yml create mode 100644 spec/fixtures/cassettes/description_page_upload_piece_justificative_adds_cerfa.yml create mode 100644 spec/fixtures/cassettes/description_page_upload_piece_justificative_adds_cerfa_and_submit.yml create mode 100644 spec/fixtures/cassettes/drawing_a_zone_with_freedraw_when_draw_a_zone_on_map.yml create mode 100644 spec/fixtures/cassettes/model_piece_justificative.yml create mode 100644 spec/fixtures/cassettes/models_cerfa_empty.yml create mode 100644 spec/fixtures/cassettes/models_dossier_retrieve_last_piece_justificative_by_type.yml create mode 100644 spec/fixtures/cassettes/ovh_storage_init.yml create mode 100644 spec/fixtures/cassettes/user_dossier_new_html.yml create mode 100644 spec/fixtures/cassettes/views_users_recapitulatif_commentaires_flux.yml create mode 100644 spec/support/factory_girl.rb diff --git a/Gemfile b/Gemfile index 378447a6f..5bd2a237d 100644 --- a/Gemfile +++ b/Gemfile @@ -56,6 +56,8 @@ gem 'rest-client' gem 'clamav-client', require: 'clamav/client' gem 'carrierwave' +gem 'fog' +gem 'fog-openstack' gem 'pg' @@ -99,6 +101,7 @@ group :test do gem 'guard' gem 'guard-rspec', require: false gem 'guard-livereload', '~> 2.4', require: false + gem 'vcr' end group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index f21a7f26f..21f55c50e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,6 +9,7 @@ GIT GEM remote: https://rubygems.org/ specs: + CFPropertyList (2.3.2) actionmailer (4.2.5.2) actionpack (= 4.2.5.2) actionview (= 4.2.5.2) @@ -139,6 +140,7 @@ GEM http_parser.rb (~> 0.6.0) erubis (2.7.0) eventmachine (1.0.8) + excon (0.49.0) execjs (2.5.2) factory_girl (4.5.0) activesupport (>= 3.0.0) @@ -146,6 +148,135 @@ GEM multipart-post (>= 1.2, < 3) fastercsv (1.5.5) ffi (1.9.6) + fission (0.5.0) + CFPropertyList (~> 2.2) + fog (1.38.0) + fog-aliyun (>= 0.1.0) + fog-atmos + fog-aws (>= 0.6.0) + fog-brightbox (~> 0.4) + fog-cloudatcost (~> 0.1.0) + fog-core (~> 1.32) + fog-dynect (~> 0.0.2) + fog-ecloud (~> 0.1) + fog-google (<= 0.1.0) + fog-json + fog-local + fog-openstack + fog-powerdns (>= 0.1.1) + fog-profitbricks + fog-rackspace + fog-radosgw (>= 0.0.2) + fog-riakcs + fog-sakuracloud (>= 0.0.4) + fog-serverlove + fog-softlayer + fog-storm_on_demand + fog-terremark + fog-vmfusion + fog-voxel + fog-vsphere (>= 0.4.0) + fog-xenserver + fog-xml (~> 0.1.1) + ipaddress (~> 0.5) + fog-aliyun (0.1.0) + fog-core (~> 1.27) + fog-json (~> 1.0) + ipaddress (~> 0.8) + xml-simple (~> 1.1) + fog-atmos (0.1.0) + fog-core + fog-xml + fog-aws (0.9.2) + fog-core (~> 1.27) + fog-json (~> 1.0) + fog-xml (~> 0.1) + ipaddress (~> 0.8) + fog-brightbox (0.10.1) + fog-core (~> 1.22) + fog-json + inflecto (~> 0.0.2) + fog-cloudatcost (0.1.2) + fog-core (~> 1.36) + fog-json (~> 1.0) + fog-xml (~> 0.1) + ipaddress (~> 0.8) + fog-core (1.38.0) + builder + excon (~> 0.49) + formatador (~> 0.2) + fog-dynect (0.0.3) + fog-core + fog-json + fog-xml + fog-ecloud (0.3.0) + fog-core + fog-xml + fog-google (0.1.0) + fog-core + fog-json + fog-xml + fog-json (1.0.2) + fog-core (~> 1.0) + multi_json (~> 1.10) + fog-local (0.3.0) + fog-core (~> 1.27) + fog-openstack (0.1.5) + fog-core (>= 1.38) + fog-json (>= 1.0) + fog-xml (>= 0.1) + ipaddress (>= 0.8) + fog-powerdns (0.1.1) + fog-core (~> 1.27) + fog-json (~> 1.0) + fog-xml (~> 0.1) + fog-profitbricks (0.0.5) + fog-core + fog-xml + nokogiri + fog-rackspace (0.1.1) + fog-core (>= 1.35) + fog-json (>= 1.0) + fog-xml (>= 0.1) + ipaddress (>= 0.8) + fog-radosgw (0.0.5) + fog-core (>= 1.21.0) + fog-json + fog-xml (>= 0.0.1) + fog-riakcs (0.1.0) + fog-core + fog-json + fog-xml + fog-sakuracloud (1.7.5) + fog-core + fog-json + fog-serverlove (0.1.2) + fog-core + fog-json + fog-softlayer (1.1.1) + fog-core + fog-json + fog-storm_on_demand (0.1.1) + fog-core + fog-json + fog-terremark (0.1.0) + fog-core + fog-xml + fog-vmfusion (0.1.0) + fission + fog-core + fog-voxel (0.1.0) + fog-core + fog-xml + fog-vsphere (0.6.4) + fog-core + rbvmomi (~> 1.8) + fog-xenserver (0.2.3) + fog-core + fog-xml + fog-xml (0.1.2) + fog-core + nokogiri (~> 1.5, >= 1.5.11) font-awesome-rails (4.4.0.0) railties (>= 3.2, < 5.0) formatador (0.2.5) @@ -189,6 +320,8 @@ GEM http_parser.rb (0.6.0) httpclient (2.6.0.1) i18n (0.7.0) + inflecto (0.0.2) + ipaddress (0.8.3) jbuilder (2.3.1) activesupport (>= 3.0.0, < 5) multi_json (~> 1.2) @@ -316,6 +449,10 @@ GEM rb-fsevent (0.9.6) rb-inotify (0.9.5) ffi (>= 0.5.0) + rbvmomi (1.8.2) + builder + nokogiri (>= 1.4.1) + trollop rdoc (4.2.0) json (~> 1.4) ref (2.0.0) @@ -430,6 +567,7 @@ GEM thread_safe (0.3.5) tilt (1.4.1) timecop (0.7.3) + trollop (2.1.2) turbolinks (2.5.3) coffee-rails tzinfo (1.2.2) @@ -451,6 +589,7 @@ GEM validate_url (1.0.2) activemodel (>= 3.0.0) addressable + vcr (3.0.1) warden (1.2.3) rack (>= 1.0) web-console (2.2.1) @@ -472,6 +611,7 @@ GEM will_paginate (3.0.7) will_paginate-bootstrap (1.0.1) will_paginate (>= 3.0.3) + xml-simple (1.1.5) xpath (2.0.0) nokogiri (~> 1.3) @@ -497,6 +637,8 @@ DEPENDENCIES devise draper factory_girl + fog + fog-openstack font-awesome-rails guard guard-livereload (~> 2.4) @@ -542,6 +684,7 @@ DEPENDENCIES turbolinks uglifier (>= 1.3.0) unicorn + vcr web-console (~> 2.0) webmock will_paginate-bootstrap diff --git a/app/models/cerfa.rb b/app/models/cerfa.rb index 7dc020acb..277496d42 100644 --- a/app/models/cerfa.rb +++ b/app/models/cerfa.rb @@ -10,8 +10,12 @@ class Cerfa < ActiveRecord::Base end def content_url - unless content.url.nil? - (Downloader.new content, 'CERFA').url + if Features.remote_storage and !content.url.nil? + (RemoteDownloader.new content.filename).url + else + unless content.url.nil? + (LocalDownloader.new content, 'CERFA').url + end end end end \ No newline at end of file diff --git a/app/models/piece_justificative.rb b/app/models/piece_justificative.rb index 3b29561ba..18763e234 100644 --- a/app/models/piece_justificative.rb +++ b/app/models/piece_justificative.rb @@ -18,9 +18,13 @@ class PieceJustificative < ActiveRecord::Base end def content_url - unless content.url.nil? - (Downloader.new content, - (type_de_piece_justificative.nil? ? content.file.original_filename : type_de_piece_justificative.libelle)).url + if Features.remote_storage and !content.url.nil? + (RemoteDownloader.new content.filename).url + else + unless content.url.nil? + (LocalDownloader.new content, + (type_de_piece_justificative.nil? ? content.original_filename : type_de_piece_justificative.libelle)).url + end end end diff --git a/app/uploaders/cerfa_uploader.rb b/app/uploaders/cerfa_uploader.rb index a0fe6b7d5..fe1b62342 100644 --- a/app/uploaders/cerfa_uploader.rb +++ b/app/uploaders/cerfa_uploader.rb @@ -1,40 +1,28 @@ # encoding: utf-8 class CerfaUploader < CarrierWave::Uploader::Base + before :cache, :save_original_filename - # Include RMagick or MiniMagick support: - # include CarrierWave::RMagick - # include CarrierWave::MiniMagick - - # Choose what kind of storage to use for this uploader: - storage :file - # storage :fog +# Choose what kind of storage to use for this uploader: + if Features.remote_storage + storage :fog + else + storage :file + end # Override the directory where uploaded files will be stored. # This is a sensible default for uploaders that are meant to be mounted: def store_dir - "../uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" + if Features.remote_storage + nil + else + "../uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" + end end - # Provide a default URL as a default if there hasn't been a file uploaded: - # def default_url - # # For Rails 3.1+ asset pipeline compatibility: - # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) - # - # "/images/fallback/" + [version_name, "default.png"].compact.join('_') - # end - - # Process files as they are uploaded: - # process :scale => [200, 300] - # - # def scale(width, height) - # # do something - # end - - # Create different versions of your uploaded files: - # version :thumb do - # process :resize_to_fit => [50, 50] - # end + def cache_dir + '/tmp/tps-cache' + end # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: @@ -42,10 +30,30 @@ class CerfaUploader < CarrierWave::Uploader::Base %w(pdf doc docx xls xlsx ppt pptx odt ods odp) end - # Override the filename of the uploaded files: - # Avoid using model.id or version_name here, see uploader/store.rb for details. - # def filename - # "something.jpg" if original_filename - # end + def filename + if original_filename || model.content_secure_token + if Features.remote_storage + @filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" + else original_filename + @filename = "#{model.class.to_s.underscore}.pdf" + end + else + @filename = nil + end + @filename + end + private + + def secure_token + model.content_secure_token ||= generate_secure_token + end + + def generate_secure_token + SecureRandom.uuid + end + + def save_original_filename(file) + model.original_filename ||= file.original_filename if file.respond_to?(:original_filename) + end end diff --git a/app/uploaders/downloader.rb b/app/uploaders/local_downloader.rb similarity index 97% rename from app/uploaders/downloader.rb rename to app/uploaders/local_downloader.rb index c6e5da35a..d83fab129 100644 --- a/app/uploaders/downloader.rb +++ b/app/uploaders/local_downloader.rb @@ -1,6 +1,6 @@ require 'securerandom' -class Downloader +class LocalDownloader BASE_PATH_DISK = File.join(Rails.root, "public/downloads/") def initialize(filename, filename_suffix = '') diff --git a/app/uploaders/piece_justificative_uploader.rb b/app/uploaders/piece_justificative_uploader.rb index 76a1269e4..2c754f01d 100644 --- a/app/uploaders/piece_justificative_uploader.rb +++ b/app/uploaders/piece_justificative_uploader.rb @@ -1,40 +1,28 @@ # encoding: utf-8 class PieceJustificativeUploader < CarrierWave::Uploader::Base - - # Include RMagick or MiniMagick support: - # include CarrierWave::RMagick - # include CarrierWave::MiniMagick + before :cache, :save_original_filename # Choose what kind of storage to use for this uploader: - storage :file - # storage :fog + if Features.remote_storage + storage :fog + else + storage :file + end # Override the directory where uploaded files will be stored. # This is a sensible default for uploaders that are meant to be mounted: def store_dir - "../uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" + if Features.remote_storage + nil + else + "../uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" + end end - # Provide a default URL as a default if there hasn't been a file uploaded: - # def default_url - # # For Rails 3.1+ asset pipeline compatibility: - # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) - # - # "/images/fallback/" + [version_name, "default.png"].compact.join('_') - # end - - # Process files as they are uploaded: - # process :scale => [200, 300] - # - # def scale(width, height) - # # do something - # end - - # Create different versions of your uploaded files: - # version :thumb do - # process :resize_to_fit => [50, 50] - # end + def cache_dir + '/tmp/tps-cache' + end # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: @@ -42,10 +30,34 @@ class PieceJustificativeUploader < CarrierWave::Uploader::Base %w(pdf doc docx xls xlsx ppt pptx odt ods odp) end - # Override the filename of the uploaded files: - # Avoid using model.id or version_name here, see uploader/store.rb for details. - # def filename - # "something.jpg" if original_filename - # end + def filename + if original_filename || model.content_secure_token + if Features.remote_storage + @filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" + else original_filename + @filename = "#{model.class.to_s.underscore}.pdf" + end + else + @filename = nil + end + @filename + end + def original_filename + model.original_filename + end + + private + + def secure_token + model.content_secure_token ||= generate_secure_token + end + + def generate_secure_token + SecureRandom.uuid + end + + def save_original_filename(file) + model.original_filename ||= file.original_filename if file.respond_to?(:original_filename) + end end diff --git a/app/uploaders/procedure_logo_uploader.rb b/app/uploaders/procedure_logo_uploader.rb index 70787d524..8c4585132 100644 --- a/app/uploaders/procedure_logo_uploader.rb +++ b/app/uploaders/procedure_logo_uploader.rb @@ -2,39 +2,26 @@ class ProcedureLogoUploader < CarrierWave::Uploader::Base - # Include RMagick or MiniMagick support: - # include CarrierWave::RMagick - # include CarrierWave::MiniMagick - # Choose what kind of storage to use for this uploader: - storage :file - # storage :fog + if Features.remote_storage + storage :fog + else + storage :file + end # Override the directory where uploaded files will be stored. # This is a sensible default for uploaders that are meant to be mounted: def store_dir - "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" + if Features.remote_storage + nil + else + "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" + end end - # Provide a default URL as a default if there hasn't been a file uploaded: - # def default_url - # # For Rails 3.1+ asset pipeline compatibility: - # # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_')) - # - # "/images/fallback/" + [version_name, "default.png"].compact.join('_') - # end - - # Process files as they are uploaded: - # process :scale => [200, 300] - # - # def scale(width, height) - # # do something - # end - - # Create different versions of your uploaded files: - # version :thumb do - # process :resize_to_fit => [50, 50] - # end + def cache_dir + '/tmp/tps-cache' + end # Add a white list of extensions which are allowed to be uploaded. # For images you might use something like this: @@ -42,10 +29,27 @@ class ProcedureLogoUploader < CarrierWave::Uploader::Base %w(jpg jpeg png) end - # Override the filename of the uploaded files: - # Avoid using model.id or version_name here, see uploader/store.rb for details. - # def filename - # "something.jpg" if original_filename - # end + def filename + if original_filename || model.logo_secure_token + if Features.remote_storage + @filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" + else original_filename + @filename = "#{model.class.to_s.underscore}.pdf" + end + else + @filename = nil + end + @filename + end + + private + + def secure_token + model.logo_secure_token ||= generate_secure_token + end + + def generate_secure_token + SecureRandom.uuid + end end diff --git a/app/uploaders/remote_downloader.rb b/app/uploaders/remote_downloader.rb new file mode 100644 index 000000000..987971f86 --- /dev/null +++ b/app/uploaders/remote_downloader.rb @@ -0,0 +1,11 @@ +class RemoteDownloader + DEST_URL = "https://storage.apientreprise.fr/" + CarrierWave::Uploader::Base.fog_directory + '/' + + def initialize(filename) + @filename = filename + end + + def url + @url ||= File.join(DEST_URL, @filename) + end +end diff --git a/app/views/users/recapitulatif/_commentaires_flux.html.haml b/app/views/users/recapitulatif/_commentaires_flux.html.haml index f666e066d..ef9404be1 100644 --- a/app/views/users/recapitulatif/_commentaires_flux.html.haml +++ b/app/views/users/recapitulatif/_commentaires_flux.html.haml @@ -16,7 +16,7 @@ \- %span#piece_justificative %b - = link_to com.piece_justificative.content.file.original_filename, com.piece_justificative.content_url, style:'color: green', target: '_blank' + = link_to com.piece_justificative.original_filename, com.piece_justificative.content_url, style:'color: green', target: '_blank' %br .description#body diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb new file mode 100644 index 000000000..51d0adefb --- /dev/null +++ b/config/initializers/carrierwave.rb @@ -0,0 +1,28 @@ +require_relative 'features' + +Fog.credentials_path = Rails.root.join('config/fog_credentials.yml') + +CarrierWave.configure do |config| + # These permissions will make dir and files available only to the user running + # the servers + config.permissions = 0600 + config.directory_permissions = 0700 + + if Features.remote_storage and not Rails.env.test? + config.fog_credentials = { provider: 'OpenStack' } + end + + # This avoids uploaded files from saving to public/ and so + # they will not be available for public (non-authenticated) downloading + config.root = Rails.root + + config.cache_dir = "#{Rails.root}/uploads" + + config.fog_public = true + + if Rails.env.production? + config.fog_directory = "tps" + else + config.fog_directory = "tps_dev" + end +end diff --git a/config/initializers/features.rb b/config/initializers/features.rb new file mode 100644 index 000000000..286132103 --- /dev/null +++ b/config/initializers/features.rb @@ -0,0 +1,26 @@ +require 'yaml' +# this class manage features +# Features must be added in file config/initializers/features.yml : +# feature_name: true +# other_feature: false +# +# this file is templated by ansible for staging and production so don't forget to add your features in +# ansible config +class Features + class << self + if File.exist?(File.dirname(__FILE__) + '/features.yml') + features_map = YAML.load_file(File.dirname(__FILE__) + '/features.yml') + if features_map + features_map.each do |feature, is_active| + define_method("#{feature}") do + is_active + end + end + end + + def method_missing(method, *args) + false + end + end + end +end diff --git a/db/migrate/20160512160602_add_original_filename_to_pieces_justificatives.rb b/db/migrate/20160512160602_add_original_filename_to_pieces_justificatives.rb new file mode 100644 index 000000000..49b136ba3 --- /dev/null +++ b/db/migrate/20160512160602_add_original_filename_to_pieces_justificatives.rb @@ -0,0 +1,5 @@ +class AddOriginalFilenameToPiecesJustificatives < ActiveRecord::Migration + def change + add_column :pieces_justificatives, :original_filename, :string + end +end diff --git a/db/migrate/20160512160658_add_original_filename_to_cerfas.rb b/db/migrate/20160512160658_add_original_filename_to_cerfas.rb new file mode 100644 index 000000000..e12e86f52 --- /dev/null +++ b/db/migrate/20160512160658_add_original_filename_to_cerfas.rb @@ -0,0 +1,5 @@ +class AddOriginalFilenameToCerfas < ActiveRecord::Migration + def change + add_column :cerfas, :original_filename, :string + end +end diff --git a/db/migrate/20160512160824_add_content_secure_token_to_cerfas.rb b/db/migrate/20160512160824_add_content_secure_token_to_cerfas.rb new file mode 100644 index 000000000..1453eded5 --- /dev/null +++ b/db/migrate/20160512160824_add_content_secure_token_to_cerfas.rb @@ -0,0 +1,5 @@ +class AddContentSecureTokenToCerfas < ActiveRecord::Migration + def change + add_column :cerfas, :content_secure_token, :string + end +end diff --git a/db/migrate/20160512160836_add_content_secure_token_to_pieces_justificatives.rb b/db/migrate/20160512160836_add_content_secure_token_to_pieces_justificatives.rb new file mode 100644 index 000000000..1b256c74b --- /dev/null +++ b/db/migrate/20160512160836_add_content_secure_token_to_pieces_justificatives.rb @@ -0,0 +1,5 @@ +class AddContentSecureTokenToPiecesJustificatives < ActiveRecord::Migration + def change + add_column :pieces_justificatives, :content_secure_token, :string + end +end diff --git a/db/migrate/20160513093425_add_logo_secure_token_to_procedures.rb b/db/migrate/20160513093425_add_logo_secure_token_to_procedures.rb new file mode 100644 index 000000000..359771b96 --- /dev/null +++ b/db/migrate/20160513093425_add_logo_secure_token_to_procedures.rb @@ -0,0 +1,5 @@ +class AddLogoSecureTokenToProcedures < ActiveRecord::Migration + def change + add_column :procedures, :logo_secure_token, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 0aaefd46e..d66cb0ebe 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160419142017) do +ActiveRecord::Schema.define(version: 20160513093425) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -72,6 +72,8 @@ ActiveRecord::Schema.define(version: 20160419142017) do t.integer "dossier_id" t.datetime "created_at" t.integer "user_id" + t.string "original_filename" + t.string "content_secure_token" end add_index "cerfas", ["dossier_id"], name: "index_cerfas_on_dossier_id", using: :btree @@ -203,6 +205,8 @@ ActiveRecord::Schema.define(version: 20160419142017) do t.integer "type_de_piece_justificative_id" t.datetime "created_at" t.integer "user_id" + t.string "original_filename" + t.string "content_secure_token" end add_index "pieces_justificatives", ["type_de_piece_justificative_id"], name: "index_pieces_justificatives_on_type_de_piece_justificative_id", using: :btree @@ -221,6 +225,7 @@ ActiveRecord::Schema.define(version: 20160419142017) do t.boolean "euro_flag", default: false t.string "logo" t.boolean "cerfa_flag", default: false + t.string "logo_secure_token" end create_table "quartier_prioritaires", force: :cascade do |t| diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake index 77bd09d6a..236d54d61 100644 --- a/lib/tasks/dev.rake +++ b/lib/tasks/dev.rake @@ -4,6 +4,8 @@ namespace :dev do puts 'start initialisation' Rake::Task['dev:generate_token_file'].invoke Rake::Task['dev:generate_franceconnect_file'].invoke + Rake::Task['dev:generate_ovh_storage_file'].invoke + Rake::Task['dev:generate_features_file'].invoke puts 'end initialisation' end @@ -35,4 +37,29 @@ EOF file.write(comment) file.close end + + task :generate_ovh_storage_file do + puts 'creating fog_credentials.yml file' + content = < Date: Tue, 17 May 2016 16:22:35 +0200 Subject: [PATCH 02/20] Add feature file --- config/initializers/features.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 config/initializers/features.yml diff --git a/config/initializers/features.yml b/config/initializers/features.yml new file mode 100644 index 000000000..efd3e5324 --- /dev/null +++ b/config/initializers/features.yml @@ -0,0 +1 @@ +remote_storage: false \ No newline at end of file From 143a683303bddf047dc1c899a5fa863e7dc645af Mon Sep 17 00:00:00 2001 From: Xavier J Date: Thu, 19 May 2016 10:57:18 +0200 Subject: [PATCH 03/20] Change management navbar procedure admin --- .../admin/pieces_justificatives/show.html.haml | 9 +-------- app/views/admin/procedures/_navbar.html.haml | 14 ++++++++++++++ app/views/admin/procedures/edit.html.haml | 9 +-------- app/views/admin/procedures/show.html.haml | 16 +--------------- app/views/admin/types_de_champ/show.html.haml | 9 +-------- .../administrateurs/_login_banner.html.haml | 2 +- config/initializers/features.yml | 2 +- .../admin/procedures/show.html.haml_spec.rb | 2 +- 8 files changed, 21 insertions(+), 42 deletions(-) create mode 100644 app/views/admin/procedures/_navbar.html.haml diff --git a/app/views/admin/pieces_justificatives/show.html.haml b/app/views/admin/pieces_justificatives/show.html.haml index 079c6289d..6fdc68a99 100644 --- a/app/views/admin/pieces_justificatives/show.html.haml +++ b/app/views/admin/pieces_justificatives/show.html.haml @@ -3,14 +3,7 @@ %br %ul.nav.nav-tabs - %li - = link_to('Informations', admin_procedure_path(@procedure)) - %li - = link_to('Description', edit_admin_procedure_path(@procedure)) - %li - = link_to('Champs', admin_procedure_types_de_champ_path(@procedure)) - %li.active - = link_to('Pièces justificatives', admin_procedure_pieces_justificatives_path(@procedure)) + = render partial: 'admin/procedures/navbar', locals: {active: 'Pieces'} #piece_justificative_form = render 'form' \ No newline at end of file diff --git a/app/views/admin/procedures/_navbar.html.haml b/app/views/admin/procedures/_navbar.html.haml new file mode 100644 index 000000000..24093f0a1 --- /dev/null +++ b/app/views/admin/procedures/_navbar.html.haml @@ -0,0 +1,14 @@ +%li{ class: ('active' if active == 'Informations') } + = link_to('Informations', admin_procedure_path(@procedure)) + +%li{ class: ('disabled' if @procedure.locked?) || ('active' if active == 'Description') } + = link_to_unless(@procedure.locked?, 'Description', edit_admin_procedure_path(@procedure)) do + = link_to('Description', '#') + +%li{ class: ('disabled' if @procedure.locked?) || ('active' if active == 'Champs') } + = link_to_unless(@procedure.locked?, 'Champs', admin_procedure_types_de_champ_path(@procedure)) do + = link_to('Champs', '#') + +%li{ class: ('disabled' if @procedure.locked?) || ('active' if active == 'Pieces') } + = link_to_unless(@procedure.locked?, 'Pièces justificatives', admin_procedure_pieces_justificatives_path(@procedure)) do + = link_to('Pièces justificatives', '#') \ No newline at end of file diff --git a/app/views/admin/procedures/edit.html.haml b/app/views/admin/procedures/edit.html.haml index 9d3dd28e7..cc799d336 100644 --- a/app/views/admin/procedures/edit.html.haml +++ b/app/views/admin/procedures/edit.html.haml @@ -3,14 +3,7 @@ %br %ul.nav.nav-tabs - %li - = link_to('Informations', admin_procedure_path(@procedure)) - %li.active - = link_to('Description', edit_admin_procedure_path(@procedure)) - %li - = link_to('Champs', admin_procedure_types_de_champ_path(@procedure)) - %li - = link_to('Pièces justificatives', admin_procedure_pieces_justificatives_path(@procedure)) + = render partial: 'navbar', locals: {active: 'Description'} #procedure_new.section.section-label = form_for @procedure, url: url_for({controller: 'admin/procedures', action: :update, id: @procedure.id}), multipart: true do |f| diff --git a/app/views/admin/procedures/show.html.haml b/app/views/admin/procedures/show.html.haml index 3dc75cd8a..efb1d9e10 100644 --- a/app/views/admin/procedures/show.html.haml +++ b/app/views/admin/procedures/show.html.haml @@ -4,21 +4,7 @@ %br %ul.nav.nav-tabs - %li.active - = link_to('Informations', admin_procedure_path(@facade.procedure)) - - %li{ class: ('disabled' if @facade.procedure.locked?) } - = link_to_unless(@facade.procedure.locked?, 'Description', edit_admin_procedure_path(@facade.procedure)) do - = link_to('Description', '#') - - %li{ class: ('disabled' if @facade.procedure.locked?) } - = link_to_unless(@facade.procedure.locked?, 'Champs', admin_procedure_types_de_champ_path(@facade.procedure)) do - = link_to('Champs', '#') - - %li{ class: ('disabled' if @facade.procedure.locked?) } - = link_to_unless(@facade.procedure.locked?, 'Pièces justificatives', admin_procedure_pieces_justificatives_path(@facade.procedure)) do - = link_to('Pièces justificatives', '#') - + = render partial: 'navbar', locals: {active: 'Informations'} %li{style:'float:right'} = form_tag admin_procedure_archive_path(procedure_id: @facade.procedure.id, archive: !@facade.procedure.archived?), method: :put do diff --git a/app/views/admin/types_de_champ/show.html.haml b/app/views/admin/types_de_champ/show.html.haml index afe5a07de..a89627788 100644 --- a/app/views/admin/types_de_champ/show.html.haml +++ b/app/views/admin/types_de_champ/show.html.haml @@ -3,14 +3,7 @@ %br %ul.nav.nav-tabs - %li - = link_to('Informations', admin_procedure_path(@procedure)) - %li - = link_to('Description', edit_admin_procedure_path(@procedure)) - %li.active - = link_to('Champs', admin_procedure_types_de_champ_path(@procedure)) - %li - = link_to('Pièces justificatives', admin_procedure_pieces_justificatives_path(@procedure)) + = render partial: 'admin/procedures/navbar', locals: {active: 'Champs'} #liste_champ = render partial: 'form' \ No newline at end of file diff --git a/app/views/administrateurs/_login_banner.html.haml b/app/views/administrateurs/_login_banner.html.haml index 6b38f4867..0d6c464da 100644 --- a/app/views/administrateurs/_login_banner.html.haml +++ b/app/views/administrateurs/_login_banner.html.haml @@ -13,7 +13,7 @@ %li = link_to(admin_gestionnaires_path) do %i.fa.fa-user -  Gestionnaires +  Accompagnateur %li.divider{ role: :separator} %li = link_to(admin_profile_path, id: :profile) do diff --git a/config/initializers/features.yml b/config/initializers/features.yml index efd3e5324..e91fb5346 100644 --- a/config/initializers/features.yml +++ b/config/initializers/features.yml @@ -1 +1 @@ -remote_storage: false \ No newline at end of file +remote_storage: false diff --git a/spec/views/admin/procedures/show.html.haml_spec.rb b/spec/views/admin/procedures/show.html.haml_spec.rb index c40f96b88..3f3474aa8 100644 --- a/spec/views/admin/procedures/show.html.haml_spec.rb +++ b/spec/views/admin/procedures/show.html.haml_spec.rb @@ -5,7 +5,7 @@ describe 'admin/procedures/show.html.haml', type: :view do before do assign(:facade, AdminProceduresShowFacades.new(procedure.decorate)) - + assign(:procedure, procedure) render end From fe4d9219979499352e9055f08adbaaa0dd1aac0c Mon Sep 17 00:00:00 2001 From: Xavier J Date: Fri, 20 May 2016 15:36:38 +0200 Subject: [PATCH 04/20] Add accompagnateur tab on all procedure navbar --- app/controllers/admin/accompagnateurs_controller.rb | 11 +++++++++++ app/views/admin/accompagnateurs/show.html.haml | 9 +++++++++ app/views/admin/procedures/_navbar.html.haml | 3 +++ config/routes.rb | 5 +++++ 4 files changed, 28 insertions(+) create mode 100644 app/controllers/admin/accompagnateurs_controller.rb create mode 100644 app/views/admin/accompagnateurs/show.html.haml diff --git a/app/controllers/admin/accompagnateurs_controller.rb b/app/controllers/admin/accompagnateurs_controller.rb new file mode 100644 index 000000000..4e226a840 --- /dev/null +++ b/app/controllers/admin/accompagnateurs_controller.rb @@ -0,0 +1,11 @@ +class Admin::AccompagnateursController < AdminController + before_action :retrieve_procedure + + def show + + end + + def update + + end +end \ No newline at end of file diff --git a/app/views/admin/accompagnateurs/show.html.haml b/app/views/admin/accompagnateurs/show.html.haml new file mode 100644 index 000000000..3077caeeb --- /dev/null +++ b/app/views/admin/accompagnateurs/show.html.haml @@ -0,0 +1,9 @@ +%h2.text-info + =@procedure.libelle +%br + +%ul.nav.nav-tabs + = render partial: 'admin/procedures/navbar', locals: {active: 'Accompagnateurs'} + +#accompagnateur_form + plop \ No newline at end of file diff --git a/app/views/admin/procedures/_navbar.html.haml b/app/views/admin/procedures/_navbar.html.haml index 24093f0a1..10bbe3d66 100644 --- a/app/views/admin/procedures/_navbar.html.haml +++ b/app/views/admin/procedures/_navbar.html.haml @@ -1,6 +1,9 @@ %li{ class: ('active' if active == 'Informations') } = link_to('Informations', admin_procedure_path(@procedure)) +%li{ class: ('active' if active == 'Accompagnateurs') } + = link_to('Accompagnateurs', admin_procedure_accompagnateurs_path(@procedure)) + %li{ class: ('disabled' if @procedure.locked?) || ('active' if active == 'Description') } = link_to_unless(@procedure.locked?, 'Description', edit_admin_procedure_path(@procedure)) do = link_to('Description', '#') diff --git a/config/routes.rb b/config/routes.rb index 5da3ac7ac..7c5a7fe5e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -80,6 +80,7 @@ Rails.application.routes.draw do get 'sign_in' => '/administrateurs/sessions#new' get 'procedures/archived' => 'procedures#archived' get 'profile' => 'profile#show', as: :profile + resources :procedures do resource :types_de_champ, only: [:show, :update] do post '/:index/move_up' => 'types_de_champ#move_up', as: :move_up @@ -88,10 +89,14 @@ Rails.application.routes.draw do put 'archive' => 'procedures#archive', as: :archive + resource :accompagnateurs, only: [:show, :update] + resources :types_de_champ, only: [:destroy] resource :pieces_justificatives, only: [:show, :update] resources :pieces_justificatives, only: :destroy end + + resources :gestionnaires, only: [:index, :create, :destroy] end From 1923f2aec1305562db8015d9420feb28163ddbe5 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Fri, 20 May 2016 15:39:17 +0200 Subject: [PATCH 05/20] =?UTF-8?q?Migrate=20Admin=20/=20Gestionnaire=20/=20?= =?UTF-8?q?Proc=C3=A9dure=20gestion=20in=20database?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/gestionnaires_controller.rb | 4 +-- app/models/administrateur.rb | 4 +-- app/models/assign_to.rb | 4 +++ app/models/gestionnaire.rb | 7 ++-- app/models/procedure.rb | 3 ++ config/initializers/inflections.rb | 1 + ...00904_admin_has_and_belong_gestionnaire.rb | 32 +++++++++++++++++ ...018_gestionnaire_is_assign_to_procedure.rb | 36 +++++++++++++++++++ db/schema.rb | 19 ++++++++-- .../admin/gestionnaires_controller_spec.rb | 10 ++++-- .../backoffice/dossiers_controller_spec.rb | 2 +- spec/factories/assign_to.rb | 4 +++ spec/features/backoffice/connection_spec.rb | 2 +- .../backoffice/navigate_to_dossier_spec.rb | 5 ++- spec/features/backoffice/onglets_link_spec.rb | 2 +- spec/features/backoffice/search_file_spec.rb | 6 ++-- spec/models/administrateur_spec.rb | 2 +- spec/models/dossier_spec.rb | 15 ++++++-- spec/models/gestionnaire_spec.rb | 16 +++++++-- .../gestionnaires/index.html.haml_spec.rb | 2 +- .../dossiers/index_html.haml_spec.rb | 6 +++- .../procedure_filter/index_html.haml_spec.rb | 6 +++- 22 files changed, 159 insertions(+), 29 deletions(-) create mode 100644 app/models/assign_to.rb create mode 100644 db/migrate/20160519100904_admin_has_and_belong_gestionnaire.rb create mode 100644 db/migrate/20160519101018_gestionnaire_is_assign_to_procedure.rb create mode 100644 spec/factories/assign_to.rb diff --git a/app/controllers/admin/gestionnaires_controller.rb b/app/controllers/admin/gestionnaires_controller.rb index 6d7f34cd5..bfef9991b 100644 --- a/app/controllers/admin/gestionnaires_controller.rb +++ b/app/controllers/admin/gestionnaires_controller.rb @@ -15,6 +15,8 @@ class Admin::GestionnairesController < AdminController @gestionnaire = Gestionnaire.create(create_gestionnaire_params) if @gestionnaire.errors.messages.empty? + @gestionnaire.administrateurs.push current_administrateur + flash.notice = 'Gestionnaire ajouté' GestionnaireMailer.new_gestionnaire(@gestionnaire.email, @gestionnaire.password).deliver_now! else @@ -33,8 +35,6 @@ class Admin::GestionnairesController < AdminController def create_gestionnaire_params params.require(:gestionnaire).permit(:email) - .merge(administrateur_id: current_administrateur.id) .merge(password: SecureRandom.hex(5)) end - end \ No newline at end of file diff --git a/app/models/administrateur.rb b/app/models/administrateur.rb index af04114c3..5cb4723bf 100644 --- a/app/models/administrateur.rb +++ b/app/models/administrateur.rb @@ -1,10 +1,8 @@ class Administrateur < ActiveRecord::Base - # Include default devise modules. Others available are: - # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable - has_many :gestionnaires + has_and_belongs_to_many :gestionnaires has_many :procedures before_save :ensure_api_token diff --git a/app/models/assign_to.rb b/app/models/assign_to.rb new file mode 100644 index 000000000..64e2f5e30 --- /dev/null +++ b/app/models/assign_to.rb @@ -0,0 +1,4 @@ +class AssignTo < ActiveRecord::Base + belongs_to :procedure + belongs_to :gestionnaire +end \ No newline at end of file diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb index 49e3249f6..94ee10e21 100644 --- a/app/models/gestionnaire.rb +++ b/app/models/gestionnaire.rb @@ -1,12 +1,11 @@ class Gestionnaire < ActiveRecord::Base - # Include default devise modules. Others available are: - # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable - belongs_to :administrateur + has_and_belongs_to_many :administrateurs - has_many :procedures, through: :administrateur + has_many :assign_to + has_many :procedures, through: :assign_to has_many :dossiers, through: :procedures def dossiers_filter diff --git a/app/models/procedure.rb b/app/models/procedure.rb index 1e6cac78f..8f3fa1eef 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -7,6 +7,9 @@ class Procedure < ActiveRecord::Base belongs_to :administrateur + has_many :assign_to + has_many :gestionnaires, through: :assign_to + delegate :use_api_carto, to: :module_api_carto accepts_nested_attributes_for :types_de_champ,:reject_if => proc { |attributes| attributes['libelle'].blank? }, :allow_destroy => true diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 08b296997..1e5e84144 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -13,6 +13,7 @@ ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.irregular 'piece_justificative', 'pieces_justificatives' inflect.irregular 'type_de_piece_justificative', 'types_de_piece_justificative' inflect.irregular 'type_de_champ', 'types_de_champ' + inflect.irregular 'assign_to', 'assign_tos' end # These inflection rules are supported but not enabled by default: diff --git a/db/migrate/20160519100904_admin_has_and_belong_gestionnaire.rb b/db/migrate/20160519100904_admin_has_and_belong_gestionnaire.rb new file mode 100644 index 000000000..9eb2bc05b --- /dev/null +++ b/db/migrate/20160519100904_admin_has_and_belong_gestionnaire.rb @@ -0,0 +1,32 @@ +class AdminHasAndBelongGestionnaire < ActiveRecord::Migration + class Gestionnaire < ActiveRecord::Base + end + + class AdministrateursGestionnaire < ActiveRecord::Base + end + + def up + create_table :administrateurs_gestionnaires, id: false do |t| + t.belongs_to :administrateur, index: true + t.belongs_to :gestionnaire, index: true + end + + Gestionnaire.all.each do |gestionnaire| + execute "insert into administrateurs_gestionnaires (gestionnaire_id, administrateur_id) values (#{gestionnaire.id}, #{gestionnaire.administrateur_id}) " + end + + remove_column :gestionnaires, :administrateur_id + end + + def down + add_column :gestionnaires, :administrateur_id, :integer + + AdministrateursGestionnaire.all.each do |ag| + gestionnaire = Gestionnaire.find(ag.gestionnaire_id) + gestionnaire.administrateur_id = ag.administrateur_id + gestionnaire.save + end + + drop_table :administrateurs_gestionnaires + end +end diff --git a/db/migrate/20160519101018_gestionnaire_is_assign_to_procedure.rb b/db/migrate/20160519101018_gestionnaire_is_assign_to_procedure.rb new file mode 100644 index 000000000..120245803 --- /dev/null +++ b/db/migrate/20160519101018_gestionnaire_is_assign_to_procedure.rb @@ -0,0 +1,36 @@ +class GestionnaireIsAssignToProcedure < ActiveRecord::Migration + class AssignTo < ActiveRecord::Base + belongs_to :gestionnaire + belongs_to :procedure + end + + class Gestionnaire < ActiveRecord::Base + has_and_belongs_to_many :administrateurs + has_many :procedures, through: :assign_to + end + + class Administrateur < ActiveRecord::Base + has_and_belongs_to_many :gestionnaires + has_many :procedures + end + + class Procedure < ActiveRecord::Base + belongs_to :administrateur + has_many :gestionnaires, through: :assign_to + end + + def change + create_table :assign_tos, id: false do |t| + t.belongs_to :gestionnaire, index: true + t.belongs_to :procedure, index: true + end + + Administrateur.all.each do |administrateur| + administrateur.gestionnaires.each do |gestionnaire| + administrateur.procedures.each do |procedure| + AssignTo.create gestionnaire: gestionnaire, procedure: procedure + end + end + end + end +end diff --git a/db/schema.rb b/db/schema.rb index d66cb0ebe..2bd180bb1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160513093425) do +ActiveRecord::Schema.define(version: 20160519101018) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -35,6 +35,14 @@ ActiveRecord::Schema.define(version: 20160513093425) do add_index "administrateurs", ["email"], name: "index_administrateurs_on_email", unique: true, using: :btree add_index "administrateurs", ["reset_password_token"], name: "index_administrateurs_on_reset_password_token", unique: true, using: :btree + create_table "administrateurs_gestionnaires", id: false, force: :cascade do |t| + t.integer "administrateur_id" + t.integer "gestionnaire_id" + end + + add_index "administrateurs_gestionnaires", ["administrateur_id"], name: "index_administrateurs_gestionnaires_on_administrateur_id", using: :btree + add_index "administrateurs_gestionnaires", ["gestionnaire_id"], name: "index_administrateurs_gestionnaires_on_gestionnaire_id", using: :btree + create_table "administrations", force: :cascade do |t| t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false @@ -53,6 +61,14 @@ ActiveRecord::Schema.define(version: 20160513093425) do add_index "administrations", ["email"], name: "index_administrations_on_email", unique: true, using: :btree add_index "administrations", ["reset_password_token"], name: "index_administrations_on_reset_password_token", unique: true, using: :btree + create_table "assign_tos", id: false, force: :cascade do |t| + t.integer "gestionnaire_id" + t.integer "procedure_id" + end + + add_index "assign_tos", ["gestionnaire_id"], name: "index_assign_tos_on_gestionnaire_id", using: :btree + add_index "assign_tos", ["procedure_id"], name: "index_assign_tos_on_procedure_id", using: :btree + create_table "cadastres", force: :cascade do |t| t.string "surface_intersection" t.float "surface_parcelle" @@ -176,7 +192,6 @@ ActiveRecord::Schema.define(version: 20160513093425) do t.inet "last_sign_in_ip" t.datetime "created_at" t.datetime "updated_at" - t.integer "administrateur_id" t.integer "procedure_filter", default: [], array: true end diff --git a/spec/controllers/admin/gestionnaires_controller_spec.rb b/spec/controllers/admin/gestionnaires_controller_spec.rb index cdca71359..b6ad3407b 100644 --- a/spec/controllers/admin/gestionnaires_controller_spec.rb +++ b/spec/controllers/admin/gestionnaires_controller_spec.rb @@ -19,13 +19,19 @@ describe Admin::GestionnairesController, type: :controller do before do subject end + + let(:gestionnaire) { Gestionnaire.last } + it { expect(response.status).to eq(302) } it { expect(response).to redirect_to admin_gestionnaires_path } describe 'Gestionnaire attributs in database' do - let(:gestionnaire) { Gestionnaire.last } it { expect(gestionnaire.email).to eq(email) } - it { expect(gestionnaire.administrateur_id).to eq(admin.id) } + end + + describe 'New gestionnaire is assign to the admin' do + it { expect(gestionnaire.administrateurs).to include admin } + it { expect(admin.gestionnaires).to include gestionnaire } end end diff --git a/spec/controllers/backoffice/dossiers_controller_spec.rb b/spec/controllers/backoffice/dossiers_controller_spec.rb index 102037905..895c0e4a5 100644 --- a/spec/controllers/backoffice/dossiers_controller_spec.rb +++ b/spec/controllers/backoffice/dossiers_controller_spec.rb @@ -6,7 +6,7 @@ describe Backoffice::DossiersController, type: :controller do let(:dossier_id) { dossier.id } let(:bad_dossier_id) { Dossier.count + 10 } - let(:gestionnaire) { create(:gestionnaire, administrateur: create(:administrateur)) } + let(:gestionnaire) { create(:gestionnaire, administrateurs: [create(:administrateur)]) } describe 'GET #show' do context 'gestionnaire is connected' do diff --git a/spec/factories/assign_to.rb b/spec/factories/assign_to.rb new file mode 100644 index 000000000..82976c8b9 --- /dev/null +++ b/spec/factories/assign_to.rb @@ -0,0 +1,4 @@ +FactoryGirl.define do + factory :assign_to do + end +end diff --git a/spec/features/backoffice/connection_spec.rb b/spec/features/backoffice/connection_spec.rb index 685d80075..20dab8f8b 100644 --- a/spec/features/backoffice/connection_spec.rb +++ b/spec/features/backoffice/connection_spec.rb @@ -21,7 +21,7 @@ feature 'when gestionnaire come to /backoffice and is not authenticated' do end context 'when user enter good credentials' do let(:administrateur) { create(:administrateur) } - let(:gestionnaire) { create(:gestionnaire, administrateur: administrateur) } + let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) } before do page.find_by_id(:gestionnaire_email).set gestionnaire.email diff --git a/spec/features/backoffice/navigate_to_dossier_spec.rb b/spec/features/backoffice/navigate_to_dossier_spec.rb index 9619ffe04..41d0944f6 100644 --- a/spec/features/backoffice/navigate_to_dossier_spec.rb +++ b/spec/features/backoffice/navigate_to_dossier_spec.rb @@ -2,13 +2,16 @@ require 'spec_helper' feature 'on backoffice page' do let(:administrateur) { create(:administrateur) } - let(:gestionnaire) { create(:gestionnaire, administrateur: administrateur) } + let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) } let(:procedure) { create(:procedure, administrateur: administrateur) } let!(:dossier) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') } + before do + create :assign_to, gestionnaire: gestionnaire, procedure: procedure visit backoffice_path end + context 'when gestionnaire is logged in' do before do page.find_by_id(:gestionnaire_email).set gestionnaire.email diff --git a/spec/features/backoffice/onglets_link_spec.rb b/spec/features/backoffice/onglets_link_spec.rb index fbbd057a0..6d8c5c7ce 100644 --- a/spec/features/backoffice/onglets_link_spec.rb +++ b/spec/features/backoffice/onglets_link_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature 'on click on tabs button' do let(:administrateur) { create(:administrateur) } - let(:gestionnaire) { create(:gestionnaire, administrateur: administrateur) } + let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) } before do login_as gestionnaire, scope: :gestionnaire diff --git a/spec/features/backoffice/search_file_spec.rb b/spec/features/backoffice/search_file_spec.rb index 5a18a6012..8d0bb38df 100644 --- a/spec/features/backoffice/search_file_spec.rb +++ b/spec/features/backoffice/search_file_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' feature 'search file on gestionnaire backoffice' do let(:administrateur) { create(:administrateur) } - let(:gestionnaire) { create(:gestionnaire, administrateur: administrateur) } + let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) } before do login_as gestionnaire, scope: :gestionnaire @@ -11,8 +11,11 @@ feature 'search file on gestionnaire backoffice' do context 'when gestionnaire is logged in' do context 'when he click on search button' do let(:terms) { '' } + let!(:procedure) { create(:procedure, administrateur: administrateur) } before do + create :assign_to, gestionnaire: gestionnaire, procedure: procedure + visit backoffice_dossiers_url page.find_by_id(:q).set terms page.find_by_id(:search_button).click @@ -36,7 +39,6 @@ feature 'search file on gestionnaire backoffice' do end context 'when terms input does return result' do - let!(:procedure) { create(:procedure, administrateur: administrateur) } let!(:dossier) { create(:dossier, :with_entreprise, procedure: procedure, state: 'initiated') } let!(:dossier_2) { create(:dossier, procedure: procedure, state: 'initiated', nom_projet: 'Projet de test') } diff --git a/spec/models/administrateur_spec.rb b/spec/models/administrateur_spec.rb index 7ee0f353b..d41a54b36 100644 --- a/spec/models/administrateur_spec.rb +++ b/spec/models/administrateur_spec.rb @@ -18,7 +18,7 @@ describe Administrateur, type: :model do end describe 'assocations' do - it { is_expected.to have_many(:gestionnaires) } + it { is_expected.to have_and_belong_to_many(:gestionnaires) } it { is_expected.to have_many(:procedures) } end diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index e6abe45be..8635f5054 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -387,10 +387,14 @@ describe Dossier do let(:admin) { create(:administrateur) } let(:admin_2) { create(:administrateur) } - let(:gestionnaire) { create(:gestionnaire, administrateur: admin) } + let(:gestionnaire) { create(:gestionnaire, administrateurs: [admin]) } let(:procedure_admin) { create(:procedure, administrateur: admin) } let(:procedure_admin_2) { create(:procedure, administrateur: admin_2) } + before do + create :assign_to, gestionnaire: gestionnaire, procedure: procedure_admin + end + let!(:dossier1) { create(:dossier, procedure: procedure_admin, state: 'draft') } let!(:dossier2) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #a_traiter let!(:dossier3) { create(:dossier, procedure: procedure_admin, state: 'initiated') } #a_traiter @@ -432,8 +436,13 @@ describe Dossier do let(:administrateur_1) { create(:administrateur) } let(:administrateur_2) { create(:administrateur) } - let(:gestionnaire_1) { create(:gestionnaire, administrateur: administrateur_1) } - let(:gestionnaire_2) { create(:gestionnaire, administrateur: administrateur_2) } + let(:gestionnaire_1) { create(:gestionnaire, administrateurs: [administrateur_1]) } + let(:gestionnaire_2) { create(:gestionnaire, administrateurs: [administrateur_2]) } + + before do + create :assign_to, gestionnaire: gestionnaire_1, procedure: procedure_1 + create :assign_to, gestionnaire: gestionnaire_2, procedure: procedure_2 + end let(:procedure_1) { create(:procedure, administrateur: administrateur_1) } let(:procedure_2) { create(:procedure, administrateur: administrateur_2) } diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index 8eaebf490..a7aea4737 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -17,7 +17,7 @@ describe Gestionnaire, type: :model do end describe 'association' do - it { is_expected.to belong_to(:administrateur) } + it { is_expected.to have_and_belong_to_many(:administrateurs) } it { is_expected.to have_many(:procedures) } it { is_expected.to have_many(:dossiers) } end @@ -26,10 +26,15 @@ describe Gestionnaire, type: :model do let(:admin) { create :administrateur } let(:procedure) { create :procedure, administrateur: admin } let(:procedure_2) { create :procedure, administrateur: admin } - let(:gestionnaire) { create :gestionnaire, procedure_filter: procedure_filter, administrateur: admin } + let(:gestionnaire) { create :gestionnaire, procedure_filter: procedure_filter, administrateurs: [admin] } let!(:dossier) { create :dossier, procedure: procedure } let(:procedure_filter) { [] } + before do + create :assign_to, gestionnaire: gestionnaire, procedure: procedure + create :assign_to, gestionnaire: gestionnaire, procedure: procedure_2 + end + subject { gestionnaire.dossiers_filter } context 'before filter' do @@ -47,7 +52,12 @@ describe Gestionnaire, type: :model do let(:admin) { create :administrateur } let!(:procedure) { create :procedure, administrateur: admin } let!(:procedure_2) { create :procedure, administrateur: admin } - let(:gestionnaire) { create :gestionnaire, procedure_filter: procedure_filter, administrateur: admin } + let(:gestionnaire) { create :gestionnaire, procedure_filter: procedure_filter, administrateurs: [admin] } + + before do + create :assign_to, gestionnaire: gestionnaire, procedure: procedure + create :assign_to, gestionnaire: gestionnaire, procedure: procedure_2 + end let(:procedure_filter) { [] } diff --git a/spec/views/admin/gestionnaires/index.html.haml_spec.rb b/spec/views/admin/gestionnaires/index.html.haml_spec.rb index d72ffc79d..083ac658b 100644 --- a/spec/views/admin/gestionnaires/index.html.haml_spec.rb +++ b/spec/views/admin/gestionnaires/index.html.haml_spec.rb @@ -21,7 +21,7 @@ describe 'admin/gestionnaires/index.html.haml', type: :view do context 'Ajout d\'un accompagnateur' do before do - create(:gestionnaire, administrateur: admin) + create(:gestionnaire, administrateurs: [admin]) admin.reload assign(:gestionnaires, (smart_listing_create :gestionnaires, admin.gestionnaires, diff --git a/spec/views/backoffice/dossiers/index_html.haml_spec.rb b/spec/views/backoffice/dossiers/index_html.haml_spec.rb index 3165a949a..5cc52453a 100644 --- a/spec/views/backoffice/dossiers/index_html.haml_spec.rb +++ b/spec/views/backoffice/dossiers/index_html.haml_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe 'backoffice/dossiers/index.html.haml', type: :view do let(:administrateur) { create(:administrateur) } - let(:gestionnaire) { create(:gestionnaire, administrateur: administrateur) } + let(:gestionnaire) { create(:gestionnaire, administrateurs: [administrateur]) } let!(:procedure) { create(:procedure, administrateur: administrateur) } @@ -10,6 +10,10 @@ describe 'backoffice/dossiers/index.html.haml', type: :view do let!(:decorate_dossier_replied) { create(:dossier, procedure: procedure, nom_projet: 'projet replied', state: 'replied').decorate } let!(:decorate_dossier_closed) { create(:dossier, procedure: procedure, nom_projet: 'projet closed', state: 'closed').decorate } + before do + create :assign_to, gestionnaire: gestionnaire, procedure: procedure + end + describe 'on tab a_traiter' do before do assign(:dossiers, (smart_listing_create :dossiers, diff --git a/spec/views/backoffice/procedure_filter/index_html.haml_spec.rb b/spec/views/backoffice/procedure_filter/index_html.haml_spec.rb index 271b6dc20..3f4a8b442 100644 --- a/spec/views/backoffice/procedure_filter/index_html.haml_spec.rb +++ b/spec/views/backoffice/procedure_filter/index_html.haml_spec.rb @@ -11,11 +11,15 @@ describe 'backoffice/procedure_filter/index.html.haml', type: :view do context 'when gestionnaire have already check procedure' do let(:gestionnaire) { create(:gestionnaire, - administrateur: administrateur, + administrateurs: [administrateur], procedure_filter: [administrateur.procedures.first.id, administrateur.procedures.last.id]) } before do + create :assign_to, gestionnaire: gestionnaire, procedure: administrateur.procedures.first + create :assign_to, gestionnaire: gestionnaire, procedure: administrateur.procedures.second + create :assign_to, gestionnaire: gestionnaire, procedure: administrateur.procedures.last + sign_in gestionnaire assign(:gestionnaire, gestionnaire) From 745eee126af5b4bf1a26b1d35ca0ddccabd840f0 Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Wed, 18 May 2016 11:43:32 +0200 Subject: [PATCH 06/20] Code review - Remote storage --- app/models/cerfa.rb | 8 ++++---- app/models/piece_justificative.rb | 8 ++++---- app/uploaders/cerfa_uploader.rb | 20 ++++++++----------- app/uploaders/piece_justificative_uploader.rb | 18 +++++++---------- app/uploaders/procedure_logo_uploader.rb | 14 +++++-------- spec/models/cerfa_spec.rb | 2 ++ spec/models/piece_justificative_spec.rb | 2 ++ spec/models/procedure_spec.rb | 1 + 8 files changed, 33 insertions(+), 40 deletions(-) diff --git a/app/models/cerfa.rb b/app/models/cerfa.rb index 277496d42..a106e6084 100644 --- a/app/models/cerfa.rb +++ b/app/models/cerfa.rb @@ -10,10 +10,10 @@ class Cerfa < ActiveRecord::Base end def content_url - if Features.remote_storage and !content.url.nil? - (RemoteDownloader.new content.filename).url - else - unless content.url.nil? + unless content.url.nil? + if Features.remote_storage + (RemoteDownloader.new content.filename).url + else (LocalDownloader.new content, 'CERFA').url end end diff --git a/app/models/piece_justificative.rb b/app/models/piece_justificative.rb index 18763e234..0ba0f6531 100644 --- a/app/models/piece_justificative.rb +++ b/app/models/piece_justificative.rb @@ -18,10 +18,10 @@ class PieceJustificative < ActiveRecord::Base end def content_url - if Features.remote_storage and !content.url.nil? - (RemoteDownloader.new content.filename).url - else - unless content.url.nil? + unless content.url.nil? + if Features.remote_storage + (RemoteDownloader.new content.filename).url + else (LocalDownloader.new content, (type_de_piece_justificative.nil? ? content.original_filename : type_de_piece_justificative.libelle)).url end diff --git a/app/uploaders/cerfa_uploader.rb b/app/uploaders/cerfa_uploader.rb index fe1b62342..8040d94ff 100644 --- a/app/uploaders/cerfa_uploader.rb +++ b/app/uploaders/cerfa_uploader.rb @@ -1,7 +1,7 @@ # encoding: utf-8 class CerfaUploader < CarrierWave::Uploader::Base - before :cache, :save_original_filename + before :cache, :set_original_filename # Choose what kind of storage to use for this uploader: if Features.remote_storage @@ -13,9 +13,7 @@ class CerfaUploader < CarrierWave::Uploader::Base # Override the directory where uploaded files will be stored. # This is a sensible default for uploaders that are meant to be mounted: def store_dir - if Features.remote_storage - nil - else + unless Features.remote_storage "../uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end end @@ -31,16 +29,14 @@ class CerfaUploader < CarrierWave::Uploader::Base end def filename - if original_filename || model.content_secure_token + if original_filename.present? || model.content_secure_token if Features.remote_storage - @filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" - else original_filename - @filename = "#{model.class.to_s.underscore}.pdf" + filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" + else + filename = "#{model.class.to_s.underscore}.pdf" end - else - @filename = nil end - @filename + filename end private @@ -53,7 +49,7 @@ class CerfaUploader < CarrierWave::Uploader::Base SecureRandom.uuid end - def save_original_filename(file) + def set_original_filename(file) model.original_filename ||= file.original_filename if file.respond_to?(:original_filename) end end diff --git a/app/uploaders/piece_justificative_uploader.rb b/app/uploaders/piece_justificative_uploader.rb index 2c754f01d..3fbc4b32f 100644 --- a/app/uploaders/piece_justificative_uploader.rb +++ b/app/uploaders/piece_justificative_uploader.rb @@ -1,7 +1,7 @@ # encoding: utf-8 class PieceJustificativeUploader < CarrierWave::Uploader::Base - before :cache, :save_original_filename + before :cache, :set_original_filename # Choose what kind of storage to use for this uploader: if Features.remote_storage @@ -13,9 +13,7 @@ class PieceJustificativeUploader < CarrierWave::Uploader::Base # Override the directory where uploaded files will be stored. # This is a sensible default for uploaders that are meant to be mounted: def store_dir - if Features.remote_storage - nil - else + unless Features.remote_storage "../uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end end @@ -31,16 +29,14 @@ class PieceJustificativeUploader < CarrierWave::Uploader::Base end def filename - if original_filename || model.content_secure_token + if original_filename.present? || model.content_secure_token if Features.remote_storage - @filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" + filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" else original_filename - @filename = "#{model.class.to_s.underscore}.pdf" + filename = "#{model.class.to_s.underscore}.pdf" end - else - @filename = nil end - @filename + filename end def original_filename @@ -57,7 +53,7 @@ class PieceJustificativeUploader < CarrierWave::Uploader::Base SecureRandom.uuid end - def save_original_filename(file) + def set_original_filename(file) model.original_filename ||= file.original_filename if file.respond_to?(:original_filename) end end diff --git a/app/uploaders/procedure_logo_uploader.rb b/app/uploaders/procedure_logo_uploader.rb index 8c4585132..6bd9b0690 100644 --- a/app/uploaders/procedure_logo_uploader.rb +++ b/app/uploaders/procedure_logo_uploader.rb @@ -12,9 +12,7 @@ class ProcedureLogoUploader < CarrierWave::Uploader::Base # Override the directory where uploaded files will be stored. # This is a sensible default for uploaders that are meant to be mounted: def store_dir - if Features.remote_storage - nil - else + unless Features.remote_storage "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end end @@ -30,16 +28,14 @@ class ProcedureLogoUploader < CarrierWave::Uploader::Base end def filename - if original_filename || model.logo_secure_token + if original_filename.present? || model.logo_secure_token if Features.remote_storage - @filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" + filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" else original_filename - @filename = "#{model.class.to_s.underscore}.pdf" + filename = "#{model.class.to_s.underscore}.pdf" end - else - @filename = nil end - @filename + filename end private diff --git a/spec/models/cerfa_spec.rb b/spec/models/cerfa_spec.rb index f2b00fddf..4ea8dd675 100644 --- a/spec/models/cerfa_spec.rb +++ b/spec/models/cerfa_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe Cerfa do describe 'database columns' do it { is_expected.to have_db_column(:content) } + it { is_expected.to have_db_column(:original_filename) } + it { is_expected.to have_db_column(:content_secure_token) } it { is_expected.to have_db_column(:created_at) } end diff --git a/spec/models/piece_justificative_spec.rb b/spec/models/piece_justificative_spec.rb index 3c66eaaaa..70abcb299 100644 --- a/spec/models/piece_justificative_spec.rb +++ b/spec/models/piece_justificative_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe PieceJustificative do describe 'database columns' do it { is_expected.to have_db_column(:content) } + it { is_expected.to have_db_column(:original_filename) } + it { is_expected.to have_db_column(:content_secure_token) } it { is_expected.to have_db_column(:created_at) } end diff --git a/spec/models/procedure_spec.rb b/spec/models/procedure_spec.rb index 066034086..6b6118104 100644 --- a/spec/models/procedure_spec.rb +++ b/spec/models/procedure_spec.rb @@ -17,6 +17,7 @@ describe Procedure do it { is_expected.to have_db_column(:test) } it { is_expected.to have_db_column(:euro_flag) } it { is_expected.to have_db_column(:logo) } + it { is_expected.to have_db_column(:logo_secure_token) } it { is_expected.to have_db_column(:cerfa_flag) } end From d6a3884c813ff89bc4a373c34dcef4cfde121e7b Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Fri, 20 May 2016 16:27:32 +0200 Subject: [PATCH 07/20] Make use of fog_credentials.test.yml for testing. --- config/initializers/carrierwave.rb | 6 +++++- lib/tasks/dev.rake | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb index 51d0adefb..00f363aa8 100644 --- a/config/initializers/carrierwave.rb +++ b/config/initializers/carrierwave.rb @@ -1,6 +1,10 @@ require_relative 'features' -Fog.credentials_path = Rails.root.join('config/fog_credentials.yml') +if Rails.env.test? + Fog.credentials_path = Rails.root.join('config/fog_credentials.test.yml') +else + Fog.credentials_path = Rails.root.join('config/fog_credentials.yml') +end CarrierWave.configure do |config| # These permissions will make dir and files available only to the user running diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake index 236d54d61..3373efb79 100644 --- a/lib/tasks/dev.rake +++ b/lib/tasks/dev.rake @@ -4,7 +4,7 @@ namespace :dev do puts 'start initialisation' Rake::Task['dev:generate_token_file'].invoke Rake::Task['dev:generate_franceconnect_file'].invoke - Rake::Task['dev:generate_ovh_storage_file'].invoke + Rake::Task['dev:generate_fog_credentials_file'].invoke Rake::Task['dev:generate_features_file'].invoke puts 'end initialisation' @@ -38,8 +38,8 @@ EOF file.close end - task :generate_ovh_storage_file do - puts 'creating fog_credentials.yml file' + task :generate_fog_credentials_file do + puts 'creating fog_credentials.test.yml file' content = < Date: Fri, 20 May 2016 16:34:38 +0200 Subject: [PATCH 08/20] Update gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9b7818561..dc45b1263 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,7 @@ config/initializers/token.rb doc/*.svg rubocop.html config/france_connect.yml +config/initializers/mailjet.rb +config/fog_credentials.yml uploads/* coverage/**/* From 9e3b1d73dedd5fa4e68d3773319c685f7b4d1649 Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Fri, 20 May 2016 16:54:32 +0200 Subject: [PATCH 09/20] Fix test according to remote_storage feature activation --- spec/controllers/users/description_controller_spec.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/spec/controllers/users/description_controller_spec.rb b/spec/controllers/users/description_controller_spec.rb index d0a7e1363..2e6c17e65 100644 --- a/spec/controllers/users/description_controller_spec.rb +++ b/spec/controllers/users/description_controller_spec.rb @@ -138,7 +138,11 @@ describe Users::DescriptionController, type: :controller, vcr: { cassette_name: subject { dossier.cerfa.first } it 'content' do - expect(subject['content']).to eq('cerfa-3dbb3535-5388-4a37-bc2d-778327b9f999.pdf') + if Features.remote_storage + expect(subject['content']).to eq('cerfa-3dbb3535-5388-4a37-bc2d-778327b9f999.pdf') + else + expect(subject['content']).to eq('cerfa.pdf') + end end it 'dossier_id' do From e2391d86355e4c43c8ccb5e02ffcef10f8d99411 Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Fri, 20 May 2016 18:24:05 +0200 Subject: [PATCH 10/20] Fix CSV output for addresses on several lines. --- app/serializers/etablissement_serializer.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/serializers/etablissement_serializer.rb b/app/serializers/etablissement_serializer.rb index 30a66065e..8df8b1603 100644 --- a/app/serializers/etablissement_serializer.rb +++ b/app/serializers/etablissement_serializer.rb @@ -11,4 +11,8 @@ class EtablissementSerializer < ActiveModel::Serializer :code_postal, :localite, :code_insee_localite + + def adresse + object.adresse.chomp.gsub("\r\n", ' ') + end end \ No newline at end of file From f95815d9521030bfccf9ce6f933b514b4592e342 Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Tue, 24 May 2016 12:51:53 +0200 Subject: [PATCH 11/20] Set original filename data for uploaded files. --- ...93540_set_original_filename_for_uploaders.rb | 17 +++++++++++++++++ db/schema.rb | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20160524093540_set_original_filename_for_uploaders.rb diff --git a/db/migrate/20160524093540_set_original_filename_for_uploaders.rb b/db/migrate/20160524093540_set_original_filename_for_uploaders.rb new file mode 100644 index 000000000..0b02b8c55 --- /dev/null +++ b/db/migrate/20160524093540_set_original_filename_for_uploaders.rb @@ -0,0 +1,17 @@ +class SetOriginalFilenameForUploaders < ActiveRecord::Migration + def change + PieceJustificative.find_each do |pj| + if pj.original_filename.nil? + pj.original_filename = pj.content_identifier + pj.save! + end + end + + Cerfa.find_each do |cerfa| + if cerfa.original_filename.nil? + cerfa.original_filename = cerfa.content_identifier + cerfa.save! + end + end + end +end diff --git a/db/schema.rb b/db/schema.rb index d66cb0ebe..5a6ce0baa 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160513093425) do +ActiveRecord::Schema.define(version: 20160524093540) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" From 9aca554eb240a1c592f2d9bfe535a154c1624979 Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Tue, 24 May 2016 14:25:40 +0200 Subject: [PATCH 12/20] Fix uploaded file permissions --- config/initializers/carrierwave.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb index 00f363aa8..35813733a 100644 --- a/config/initializers/carrierwave.rb +++ b/config/initializers/carrierwave.rb @@ -9,8 +9,8 @@ end CarrierWave.configure do |config| # These permissions will make dir and files available only to the user running # the servers - config.permissions = 0600 - config.directory_permissions = 0700 + config.permissions = 0664 + config.directory_permissions = 0775 if Features.remote_storage and not Rails.env.test? config.fog_credentials = { provider: 'OpenStack' } From d9b94568b216ab33bedafaf2134cef97771839c6 Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Tue, 24 May 2016 15:28:16 +0200 Subject: [PATCH 13/20] Handle siret with whitespaces --- app/models/siret.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/models/siret.rb b/app/models/siret.rb index de274b5a1..0bac4702b 100644 --- a/app/models/siret.rb +++ b/app/models/siret.rb @@ -1,7 +1,15 @@ class Siret include ActiveModel::Model + include ActiveModel::Validations::Callbacks + attr_accessor :siret validates_presence_of :siret validates :siret, siret_format: true + + before_validation :remove_whitespace + + def remove_whitespace + siret.delete!(' ') + end end From 63cf35a7483e53c50cc7b9542861b9fedf46244f Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Tue, 24 May 2016 15:43:05 +0200 Subject: [PATCH 14/20] Add tests for siret with whitespaces --- app/models/siret.rb | 2 +- .../controllers/users/dossiers_controller_spec.rb | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/models/siret.rb b/app/models/siret.rb index 0bac4702b..8196a223d 100644 --- a/app/models/siret.rb +++ b/app/models/siret.rb @@ -10,6 +10,6 @@ class Siret before_validation :remove_whitespace def remove_whitespace - siret.delete!(' ') + siret.delete!(' ') unless siret.nil? end end diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb index 35eb2d87f..7630eb94c 100644 --- a/spec/controllers/users/dossiers_controller_spec.rb +++ b/spec/controllers/users/dossiers_controller_spec.rb @@ -17,6 +17,7 @@ describe Users::DossiersController, type: :controller do let(:siren) { dossier.siren } let(:siret) { dossier.siret } + let(:siret_with_whitespaces) { '440 1176 2001 530' } let(:bad_siret) { 1 } describe 'GET #show' do @@ -103,12 +104,12 @@ describe Users::DossiersController, type: :controller do describe 'dossier attributs' do let(:user) { create(:user) } - context 'with valid siret ' do + shared_examples 'with valid siret' do before do sign_in user end - subject { post :create, dossier: {siret: siret, procedure_id: Procedure.last} } + subject { post :create, dossier: {siret: example_siret, procedure_id: Procedure.last} } it 'create a dossier' do expect { subject }.to change { Dossier.count }.by(1) @@ -215,6 +216,16 @@ describe Users::DossiersController, type: :controller do end end + describe "with siret without whitespaces" do + let(:example_siret) { siret } + it_should_behave_like "with valid siret" + end + + describe "with siret with whitespaces" do + let(:example_siret) { siret_with_whitespaces } + it_should_behave_like "with valid siret" + end + context 'with non existant siret' do before do sign_in create(:user) From f62c9ebec94ff8dfb57c145cadde59ee281e3dae Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Tue, 24 May 2016 15:58:21 +0200 Subject: [PATCH 15/20] Remove carriage returns in address in CSV format only --- app/models/dossier.rb | 2 +- app/serializers/etablissement_csv_serializer.rb | 5 +++++ app/serializers/etablissement_serializer.rb | 3 --- spec/models/dossier_spec.rb | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) create mode 100644 app/serializers/etablissement_csv_serializer.rb diff --git a/app/models/dossier.rb b/app/models/dossier.rb index 6bb913e25..900b71fcb 100644 --- a/app/models/dossier.rb +++ b/app/models/dossier.rb @@ -190,7 +190,7 @@ class Dossier < ActiveRecord::Base def as_csv(options={}) dossier_attr = DossierSerializer.new(self).attributes - etablissement_attr = EtablissementSerializer.new(self.etablissement).attributes.map {|k, v| ["etablissement.#{k}", v] }.to_h + etablissement_attr = EtablissementCsvSerializer.new(self.etablissement).attributes.map {|k, v| ["etablissement.#{k}", v] }.to_h entreprise_attr = EntrepriseSerializer.new(self.entreprise).attributes.map {|k, v| ["entreprise.#{k}", v] }.to_h dossier_attr.merge(etablissement_attr).merge(entreprise_attr) end diff --git a/app/serializers/etablissement_csv_serializer.rb b/app/serializers/etablissement_csv_serializer.rb new file mode 100644 index 000000000..ec33919bd --- /dev/null +++ b/app/serializers/etablissement_csv_serializer.rb @@ -0,0 +1,5 @@ +class EtablissementCsvSerializer < EtablissementSerializer + def adresse + object.adresse.chomp.gsub("\r\n", ' ').gsub("\r", '') + end +end \ No newline at end of file diff --git a/app/serializers/etablissement_serializer.rb b/app/serializers/etablissement_serializer.rb index 8df8b1603..b0bcd0c19 100644 --- a/app/serializers/etablissement_serializer.rb +++ b/app/serializers/etablissement_serializer.rb @@ -12,7 +12,4 @@ class EtablissementSerializer < ActiveModel::Serializer :localite, :code_insee_localite - def adresse - object.adresse.chomp.gsub("\r\n", ' ') - end end \ No newline at end of file diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb index e6abe45be..5c59b0a39 100644 --- a/spec/models/dossier_spec.rb +++ b/spec/models/dossier_spec.rb @@ -538,7 +538,7 @@ describe Dossier do it { expect(subject['etablissement.siege_social']).to be_truthy } it { expect(subject['etablissement.naf']).to eq('4950Z') } it { expect(subject['etablissement.libelle_naf']).to eq('Transports par conduites') } - it { expect(subject['etablissement.adresse']).to eq("GRTGAZ\r IMMEUBLE BORA\r 6 RUE RAOUL NORDLING\r 92270 BOIS COLOMBES\r") } + it { expect(subject['etablissement.adresse']).to eq("GRTGAZ IMMEUBLE BORA 6 RUE RAOUL NORDLING 92270 BOIS COLOMBES") } it { expect(subject['etablissement.numero_voie']).to eq('6') } it { expect(subject['etablissement.type_voie']).to eq('RUE') } it { expect(subject['etablissement.nom_voie']).to eq('RAOUL NORDLING') } From 1fcb33104dd51c8159770912493948aa436a7693 Mon Sep 17 00:00:00 2001 From: Xavier J Date: Tue, 24 May 2016 16:39:39 +0200 Subject: [PATCH 16/20] Administrateur can be assign accompagnateur on each of his procedure. --- app/assets/javascripts/application.js | 1 + .../admin/accompagnateurs_controller.rb | 19 +++ .../admin/gestionnaires_controller.rb | 48 ++++-- app/mailers/gestionnaire_mailer.rb | 12 +- app/services/accompagnateur_service.rb | 12 ++ .../accompagnateurs/_list_assign.html.haml | 20 +++ .../_list_not_assign.html.haml | 27 ++++ .../admin/accompagnateurs/show.html.haml | 12 +- app/views/admin/accompagnateurs/show.js.erb | 3 + .../new_assignement.text.erb | 11 ++ .../new_gestionnaire.text.erb | 4 +- config/routes.rb | 4 + ..._foreign_key_admnistrateur_gestionnaire.rb | 5 + db/schema.rb | 3 +- .../admin/accompagnateurs_controller_spec.rb | 30 ++++ .../admin/gestionnaires_controller_spec.rb | 144 ++++++++++++------ spec/services/accompagnateur_service_spec.rb | 32 ++++ .../accompagnateurs/show.html.haml_spec.rb | 60 ++++++++ .../gestionnaires/index.html.haml_spec.rb | 12 +- 19 files changed, 385 insertions(+), 74 deletions(-) create mode 100644 app/services/accompagnateur_service.rb create mode 100644 app/views/admin/accompagnateurs/_list_assign.html.haml create mode 100644 app/views/admin/accompagnateurs/_list_not_assign.html.haml create mode 100644 app/views/admin/accompagnateurs/show.js.erb create mode 100644 app/views/gestionnaire_mailer/new_assignement.text.erb create mode 100644 db/migrate/20160523163054_add_foreign_key_admnistrateur_gestionnaire.rb create mode 100644 spec/controllers/admin/accompagnateurs_controller_spec.rb create mode 100644 spec/services/accompagnateur_service_spec.rb create mode 100644 spec/views/admin/accompagnateurs/show.html.haml_spec.rb diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 007634297..5ec3d6999 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -31,6 +31,7 @@ //= require bootstrap-wysihtml5/locales/fr-FR + $(document).on('page:load', scroll_to); $(document).ready(scroll_to); diff --git a/app/controllers/admin/accompagnateurs_controller.rb b/app/controllers/admin/accompagnateurs_controller.rb index 4e226a840..584c80f68 100644 --- a/app/controllers/admin/accompagnateurs_controller.rb +++ b/app/controllers/admin/accompagnateurs_controller.rb @@ -1,11 +1,30 @@ class Admin::AccompagnateursController < AdminController + include SmartListing::Helper::ControllerExtensions + helper SmartListing::Helper + before_action :retrieve_procedure def show + assign_scope = @procedure.gestionnaires + @accompagnateurs_assign = smart_listing_create :accompagnateurs_assign, + assign_scope, + partial: "admin/accompagnateurs/list_assign", + array: true + + not_assign_scope = current_administrateur.gestionnaires.where.not(id: assign_scope.ids) + not_assign_scope = not_assign_scope.where("email LIKE '%#{params[:filter]}%'") if params[:filter] + + @accompagnateurs_not_assign = smart_listing_create :accompagnateurs_not_assign, + not_assign_scope, + partial: "admin/accompagnateurs/list_not_assign", + array: true end def update + AccompagnateurService.change_assignement! Gestionnaire.find(params[:accompagnateur_id]), Procedure.find(params[:procedure_id]), params[:to] + flash.notice = "Assignement effectué" + redirect_to admin_procedure_accompagnateurs_path, procedure_id: params[:procedure_id] end end \ No newline at end of file diff --git a/app/controllers/admin/gestionnaires_controller.rb b/app/controllers/admin/gestionnaires_controller.rb index bfef9991b..651d22f38 100644 --- a/app/controllers/admin/gestionnaires_controller.rb +++ b/app/controllers/admin/gestionnaires_controller.rb @@ -4,37 +4,59 @@ class Admin::GestionnairesController < AdminController def index @gestionnaires = smart_listing_create :gestionnaires, - current_administrateur.gestionnaires, - partial: "admin/gestionnaires/list", - array: true + current_administrateur.gestionnaires, + partial: "admin/gestionnaires/list", + array: true @gestionnaire ||= Gestionnaire.new end def create - @gestionnaire = Gestionnaire.create(create_gestionnaire_params) + @gestionnaire = Gestionnaire.find_by_email(params[:gestionnaire][:email]) - if @gestionnaire.errors.messages.empty? - @gestionnaire.administrateurs.push current_administrateur - - flash.notice = 'Gestionnaire ajouté' - GestionnaireMailer.new_gestionnaire(@gestionnaire.email, @gestionnaire.password).deliver_now! + if @gestionnaire.nil? + new_gestionnaire! else - flash.alert = @gestionnaire.errors.full_messages.join('
').html_safe + assign_gestionnaire! end redirect_to admin_gestionnaires_path end - def destroy - Gestionnaire.find(params[:id]).destroy + Gestionnaire.find(params[:id]).administrateurs.delete current_administrateur redirect_to admin_gestionnaires_path end def create_gestionnaire_params params.require(:gestionnaire).permit(:email) - .merge(password: SecureRandom.hex(5)) + .merge(password: SecureRandom.hex(5)) + .merge(administrateurs: [current_administrateur]) + end + + private + + def new_gestionnaire! + @gestionnaire = Gestionnaire.create(create_gestionnaire_params) + + if @gestionnaire.errors.messages.empty? + flash.notice = 'Accompagnateur ajouté' + GestionnaireMailer.new_gestionnaire(@gestionnaire.email, @gestionnaire.password).deliver_now! + GestionnaireMailer.new_assignement(@gestionnaire.email, current_administrateur.email).deliver_now! + else + flash.alert = @gestionnaire.errors.full_messages.join('
').html_safe + end + end + + def assign_gestionnaire! + if current_administrateur.gestionnaires.include? @gestionnaire + flash.alert = 'Accompagnateur déjà ajouté' + else + GestionnaireMailer.new_assignement(@gestionnaire.email, current_administrateur.email).deliver_now! + @gestionnaire.administrateurs.push current_administrateur + flash.notice = 'Accompagnateur ajouté' + #TODO Mailer no assign_to + end end end \ No newline at end of file diff --git a/app/mailers/gestionnaire_mailer.rb b/app/mailers/gestionnaire_mailer.rb index 86339a022..74765352b 100644 --- a/app/mailers/gestionnaire_mailer.rb +++ b/app/mailers/gestionnaire_mailer.rb @@ -4,15 +4,19 @@ class GestionnaireMailer < ApplicationMailer send_mail email, password, "Vous avez été nommé accompagnateur sur la plateforme TPS" end + def new_assignement email, email_admin + send_mail email, email_admin, "Vous avez été assigné à un nouvel administrateur sur la plateforme TPS" + end + private - def vars_mailer email, password - @password = password + def vars_mailer email, args + @args = args @email = email end - def send_mail email, password, subject - vars_mailer email, password + def send_mail email, args, subject + vars_mailer email, args mail(from: "tps@apientreprise.fr", to: email, subject: subject) diff --git a/app/services/accompagnateur_service.rb b/app/services/accompagnateur_service.rb new file mode 100644 index 000000000..119560418 --- /dev/null +++ b/app/services/accompagnateur_service.rb @@ -0,0 +1,12 @@ +class AccompagnateurService + ASSIGN = 'assign' + NOT_ASSIGN = 'not_assign' + + def self.change_assignement! accompagnateur, procedure, to + if to == ASSIGN + AssignTo.create(gestionnaire: accompagnateur, procedure: procedure) + elsif to == NOT_ASSIGN + AssignTo.delete_all(gestionnaire: accompagnateur, procedure: procedure) + end + end +end \ No newline at end of file diff --git a/app/views/admin/accompagnateurs/_list_assign.html.haml b/app/views/admin/accompagnateurs/_list_assign.html.haml new file mode 100644 index 000000000..e83b58d21 --- /dev/null +++ b/app/views/admin/accompagnateurs/_list_assign.html.haml @@ -0,0 +1,20 @@ +.row{style:'height: 34px'} + +- unless smart_listing.empty? + %table.table#liste_gestionnaire + %thead + %th Enlever + %th#email{style:'text-align: right'} Email + + - @accompagnateurs_assign.each do |accompagnateur| + %tr + %td.col-md-1.col-lg-1.center + %a.btn.btn-primary{href: "#{admin_procedure_accompagnateurs_path(procedure_id: @procedure.id, accompagnateur_id: accompagnateur.id, to: AccompagnateurService::NOT_ASSIGN)}", 'data-method' => 'put'} + .fa.fa-arrow-left + %td{style:'padding-top: 11px; font-size:15px; text-align:right'}= accompagnateur.email + + = smart_listing.paginate + = smart_listing.pagination_per_page_links +- else + %h4.center + Aucun d'affecté diff --git a/app/views/admin/accompagnateurs/_list_not_assign.html.haml b/app/views/admin/accompagnateurs/_list_not_assign.html.haml new file mode 100644 index 000000000..8d036f9ae --- /dev/null +++ b/app/views/admin/accompagnateurs/_list_not_assign.html.haml @@ -0,0 +1,27 @@ += smart_listing_controls_for(:accompagnateurs_not_assign, {class: "form-inline text-right"}) do + .form-group.filter.input-append + = text_field_tag :filter, '', class: "search form-control", + placeholder: "Recherche...", autocomplete: :off + %button.btn.btn-primary{type: :submit} + %span.glyphicon.glyphicon-search + +- unless smart_listing.empty? + + %table.table#liste_gestionnaire + %thead + %th#email Email + %th Ajouter + + - @accompagnateurs_not_assign.each do |accompagnateur| + %tr + %td.col-md-11.col-lg-11{style:'padding-top: 11px; font-size:15px'}= accompagnateur.email + %td.center + %a.btn.btn-success{href: "#{admin_procedure_accompagnateurs_path(procedure_id: @procedure.id, accompagnateur_id: accompagnateur.id, to: AccompagnateurService::ASSIGN)}", 'data-method' => 'put'} + .fa.fa-arrow-right + + + = smart_listing.paginate + = smart_listing.pagination_per_page_links +- else + %h4.center + Aucun de disponible diff --git a/app/views/admin/accompagnateurs/show.html.haml b/app/views/admin/accompagnateurs/show.html.haml index 3077caeeb..1c82ecc96 100644 --- a/app/views/admin/accompagnateurs/show.html.haml +++ b/app/views/admin/accompagnateurs/show.html.haml @@ -6,4 +6,14 @@ = render partial: 'admin/procedures/navbar', locals: {active: 'Accompagnateurs'} #accompagnateur_form - plop \ No newline at end of file + .row + .col-md-6.col-lg-6 + %h3.text-info Disponibles + = smart_listing_render :accompagnateurs_not_assign + + .col-md-6.col-lg-6 + %h3.text-success Affectés + + = smart_listing_render :accompagnateurs_assign + + diff --git a/app/views/admin/accompagnateurs/show.js.erb b/app/views/admin/accompagnateurs/show.js.erb new file mode 100644 index 000000000..197a811b4 --- /dev/null +++ b/app/views/admin/accompagnateurs/show.js.erb @@ -0,0 +1,3 @@ +<%= smart_listing_update :accompagnateurs_not_assign %> + +<%= smart_listing_update :accompagnateurs_assign %> diff --git a/app/views/gestionnaire_mailer/new_assignement.text.erb b/app/views/gestionnaire_mailer/new_assignement.text.erb new file mode 100644 index 000000000..b4bfa57e4 --- /dev/null +++ b/app/views/gestionnaire_mailer/new_assignement.text.erb @@ -0,0 +1,11 @@ +Bienvenue sur la plateforme TPS + +Vous venez d'être assigné à un administrateur sur la plateforme TPS. Voici quelques informations utiles : + + URL : https://tps.apientreprise.fr/gestionnaires/sign_in + Email administrateur : <%= @args %> + +Bonne journée, + +--- +L'équipe TPS - tps@apientreprise.fr \ No newline at end of file diff --git a/app/views/gestionnaire_mailer/new_gestionnaire.text.erb b/app/views/gestionnaire_mailer/new_gestionnaire.text.erb index 29ea6fd04..c68a7ae98 100644 --- a/app/views/gestionnaire_mailer/new_gestionnaire.text.erb +++ b/app/views/gestionnaire_mailer/new_gestionnaire.text.erb @@ -2,9 +2,9 @@ Bienvenue sur la plateforme TPS Vous venez d'être nommé accompagnateur sur la plateforme TPS. Pour mémoire, voici quelques informations utiles : - URL : https://tps.apientreprise.fr/gestionnaires/sign_in + URL : <%= new_gestionnaire_session_url %> Login : <%= @email %> - Mot de passe : <%= @password %> + Mot de passe : <%= @args %> Bonne journée, diff --git a/config/routes.rb b/config/routes.rb index 7c5a7fe5e..06c348e58 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -91,11 +91,15 @@ Rails.application.routes.draw do resource :accompagnateurs, only: [:show, :update] + resources :types_de_champ, only: [:destroy] resource :pieces_justificatives, only: [:show, :update] resources :pieces_justificatives, only: :destroy end + namespace :accompagnateurs do + get 'show' #delete after fixed tests admin/accompagnateurs/show_spec without this line + end resources :gestionnaires, only: [:index, :create, :destroy] end diff --git a/db/migrate/20160523163054_add_foreign_key_admnistrateur_gestionnaire.rb b/db/migrate/20160523163054_add_foreign_key_admnistrateur_gestionnaire.rb new file mode 100644 index 000000000..61bbb4424 --- /dev/null +++ b/db/migrate/20160523163054_add_foreign_key_admnistrateur_gestionnaire.rb @@ -0,0 +1,5 @@ +class AddForeignKeyAdmnistrateurGestionnaire < ActiveRecord::Migration + def change + add_index :administrateurs_gestionnaires, [:gestionnaire_id, :administrateur_id], unique: true, name: 'unique_couple_administrateur_gestionnaire' + end +end diff --git a/db/schema.rb b/db/schema.rb index 2bd180bb1..9081ec6b6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160519101018) do +ActiveRecord::Schema.define(version: 20160523163054) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -41,6 +41,7 @@ ActiveRecord::Schema.define(version: 20160519101018) do end add_index "administrateurs_gestionnaires", ["administrateur_id"], name: "index_administrateurs_gestionnaires_on_administrateur_id", using: :btree + add_index "administrateurs_gestionnaires", ["gestionnaire_id", "administrateur_id"], name: "unique_couple_administrateur_gestionnaire", unique: true, using: :btree add_index "administrateurs_gestionnaires", ["gestionnaire_id"], name: "index_administrateurs_gestionnaires_on_gestionnaire_id", using: :btree create_table "administrations", force: :cascade do |t| diff --git a/spec/controllers/admin/accompagnateurs_controller_spec.rb b/spec/controllers/admin/accompagnateurs_controller_spec.rb new file mode 100644 index 000000000..42889eb1f --- /dev/null +++ b/spec/controllers/admin/accompagnateurs_controller_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe Admin::AccompagnateursController, type: :controller do + let(:admin) { create(:administrateur) } + let(:procedure) { create :procedure, administrateur: admin } + let(:gestionnaire) { create :gestionnaire, administrateurs: [admin] } + + before do + sign_in admin + end + + describe 'GET #show' do + subject { get :show, procedure_id: procedure.id } + it { expect(subject.status).to eq(200) } + end + + describe 'PUT #update' do + subject { put :update, accompagnateur_id: gestionnaire.id ,procedure_id: procedure.id } + + it { expect(subject).to redirect_to admin_procedure_accompagnateurs_path(procedure_id: procedure.id) } + + context 'when assignement is valid' do + before do + subject + end + + it { expect(flash[:notice]).to be_present } + end + end +end \ No newline at end of file diff --git a/spec/controllers/admin/gestionnaires_controller_spec.rb b/spec/controllers/admin/gestionnaires_controller_spec.rb index b6ad3407b..6b414d5e9 100644 --- a/spec/controllers/admin/gestionnaires_controller_spec.rb +++ b/spec/controllers/admin/gestionnaires_controller_spec.rb @@ -1,19 +1,22 @@ require 'spec_helper' -describe Admin::GestionnairesController, type: :controller do +describe Admin::GestionnairesController, type: :controller do let(:admin) { create(:administrateur) } + let(:email_2) { 'plip@octo.com' } + let(:admin_2) { create :administrateur, email: email_2 } + before do sign_in admin end describe 'GET #index' do - subject { get :index } - it { expect(subject.status).to eq(200) } + subject { get :index } + it { expect(subject.status).to eq(200) } end describe 'POST #create' do - let(:email) { 'test@plop.com' } - subject { post :create, gestionnaire: { email: email } } + let(:email) { 'test@plop.com' } + subject { post :create, gestionnaire: {email: email} } context 'When email is valid' do before do @@ -39,77 +42,124 @@ describe Admin::GestionnairesController, type: :controller do before do subject end - let(:email) { 'piou' } - it { expect(response.status).to eq(302) } - it { expect{ response }.not_to change(Gestionnaire, :count) } - end - - context 'when email is empty' do - before do - subject - end - let(:email) { '' } - it { expect(response.status).to eq(302) } - it { expect{ response }.not_to change(Gestionnaire, :count) } - it 'Notification email is not send' do - expect(GestionnaireMailer).not_to receive(:new_gestionnaire) - expect(GestionnaireMailer).not_to receive(:deliver_now!) - end - end - - context ' when email already exists' do - let(:email) { 'test@plop.com' } - before do - subject - post :create, gestionnaire: { email: email } - end + let(:email) { 'piou' } it { expect(response.status).to eq(302) } - it { expect{ response }.not_to change(Gestionnaire, :count) } - end + it { expect { response }.not_to change(Gestionnaire, :count) } + it { expect(flash[:alert]).to be_present } - context 'Email notification' do - - it 'Notification email is sent when email is valid' do - expect(GestionnaireMailer).to receive(:new_gestionnaire).and_return(GestionnaireMailer) - expect(GestionnaireMailer).to receive(:deliver_now!) - subject - end - - context 'is not sent when email is not valid' do - let(:email) { 'testplop.com' } + describe 'Email Notification' do it { expect(GestionnaireMailer).not_to receive(:new_gestionnaire) expect(GestionnaireMailer).not_to receive(:deliver_now!) subject } end + end - it 'is not sent when email already exists' do + context 'when email is empty' do + before do subject + end + let(:email) { '' } + it { expect(response.status).to eq(302) } + it { expect { response }.not_to change(Gestionnaire, :count) } + + it 'Notification email is not send' do expect(GestionnaireMailer).not_to receive(:new_gestionnaire) expect(GestionnaireMailer).not_to receive(:deliver_now!) + end + end + + context 'when email is already assign at the admin' do + before do + create :gestionnaire, email: email, administrateurs: [admin] subject end + it { expect(response.status).to eq(302) } + it { expect { response }.not_to change(Gestionnaire, :count) } + it { expect(flash[:alert]).to be_present } + + describe 'Email notification' do + it 'is not sent when email already exists' do + expect(GestionnaireMailer).not_to receive(:new_gestionnaire) + expect(GestionnaireMailer).not_to receive(:deliver_now!) + + subject + end + end + end + + context 'when an other admin will add the same email' do + let(:gestionnaire) { Gestionnaire.find_by_email(email) } + + before do + create :gestionnaire, email: email, administrateurs: [admin] + + sign_out admin + sign_in admin_2 + + subject + end + + it { expect(response.status).to eq(302) } + it { expect { response }.not_to change(Gestionnaire, :count) } + it { expect(flash[:notice]).to be_present } + + it { expect(admin_2.gestionnaires).to include gestionnaire } + it { expect(gestionnaire.administrateurs.size).to eq 2 } + end + + context 'Email notification' do + it 'Notification email is sent when accompagnateur is create' do + expect(GestionnaireMailer).to receive(:new_gestionnaire).and_return(GestionnaireMailer) + expect(GestionnaireMailer).to receive(:deliver_now!) + subject + end + + it 'Notification email is sent when accompagnateur is assign' do + expect(GestionnaireMailer).to receive(:new_assignement).and_return(GestionnaireMailer) + expect(GestionnaireMailer).to receive(:deliver_now!) + subject + end + + context 'when accompagnateur is assign at a new admin' do + before do + create :gestionnaire, email: email, administrateurs: [admin] + + sign_out admin + sign_in admin_2 + end + + it { + expect(GestionnaireMailer).to receive(:new_assignement).and_return(GestionnaireMailer) + expect(GestionnaireMailer).to receive(:deliver_now!) + subject + } + end end end - describe 'DELETE #destroy' do let(:email) { 'test@plop.com' } - let!(:gestionnaire) { create :gestionnaire, email: email } + let!(:admin) { create :administrateur } + let!(:gestionnaire) { create :gestionnaire, email: email, administrateurs: [admin] } + subject { delete :destroy, id: gestionnaire.id } context "when gestionaire_id is valid" do before do subject + admin.reload + gestionnaire.reload end + it { expect(response.status).to eq(302) } it { expect(response).to redirect_to admin_gestionnaires_path } - it { expect{Gestionnaire.find(gestionnaire.id)}.to raise_error ActiveRecord::RecordNotFound} + it { expect(admin.gestionnaires).not_to include gestionnaire } + it { expect(gestionnaire.administrateurs).not_to include admin } end - it { expect{subject}.to change(Gestionnaire, :count).by(-1) } + it { expect { subject }.not_to change(Gestionnaire, :count) } end - end \ No newline at end of file diff --git a/spec/services/accompagnateur_service_spec.rb b/spec/services/accompagnateur_service_spec.rb new file mode 100644 index 000000000..1c0dcf9ab --- /dev/null +++ b/spec/services/accompagnateur_service_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe AccompagnateurService do + describe '#change_assignement!' do + + let(:procedure) { create :procedure } + let(:accompagnateur) { create :gestionnaire } + + subject { AccompagnateurService.change_assignement! accompagnateur, procedure, to } + + context 'when accompagnateur is not assign at the procedure' do + let(:to) { AccompagnateurService::ASSIGN } + + before do + subject + end + + it { expect(accompagnateur.procedures).to include procedure } + end + + context 'when accompagnateur is assign at the procedure' do + let(:to) { AccompagnateurService::NOT_ASSIGN } + + before do + create :assign_to, gestionnaire: accompagnateur, procedure: procedure + subject + end + + it { expect(accompagnateur.procedures).not_to include procedure } + end + end +end \ No newline at end of file diff --git a/spec/views/admin/accompagnateurs/show.html.haml_spec.rb b/spec/views/admin/accompagnateurs/show.html.haml_spec.rb new file mode 100644 index 000000000..bf5deb5a6 --- /dev/null +++ b/spec/views/admin/accompagnateurs/show.html.haml_spec.rb @@ -0,0 +1,60 @@ +require 'spec_helper' + +describe 'admin/accompagnateurs/show.html.haml', type: :view do + let(:admin) { create(:administrateur) } + let(:procedure) { create :procedure, administrateur: admin } + + let(:assign_gestionnaires) { procedure.gestionnaires } + let(:not_assign_gestionnaires) { admin.gestionnaires.where.not(id: assign_gestionnaires.ids) } + + before do + assign(:procedure, procedure) + + assign(:accompagnateurs_assign, (smart_listing_create :accompagnateurs_assign, + assign_gestionnaires, + partial: "admin/accompagnateurs/list_assign", + array: true)) + + assign(:accompagnateurs_not_assign, (smart_listing_create :accompagnateurs_not_assign, + not_assign_gestionnaires, + partial: "admin/accompagnateurs/list_not_assign", + array: true)) + end + + context 'when admin have none accompagnateur ' do + before do + render + end + + it { expect(rendered).to have_content('Aucun de disponible') } + + context 'when administrateur have none accompagnateur assign' do + it { expect(rendered).to have_content('Aucun d\'affecté') } + end + end + + context 'when administrateur have two accompagnateur' do + let!(:accompagnateur_1) { create :gestionnaire, email: 'plop@plop.com', administrateurs: [admin] } + let!(:accompagnateur_2) { create :gestionnaire, email: 'plip@plop.com', administrateurs: [admin] } + + before do + not_assign_gestionnaires.reload + assign_gestionnaires.reload + + assign(:accompagnateurs_assign, (smart_listing_create :accompagnateurs_assign, + assign_gestionnaires, + partial: "admin/accompagnateurs/list_assign", + array: true)) + + assign(:accompagnateurs_not_assign, (smart_listing_create :accompagnateurs_not_assign, + not_assign_gestionnaires, + partial: "admin/accompagnateurs/list_not_assign", + array: true)) + + render + end + + it { expect(rendered).to have_content(accompagnateur_1.email) } + it { expect(rendered).to have_content(accompagnateur_2.email) } + end +end \ No newline at end of file diff --git a/spec/views/admin/gestionnaires/index.html.haml_spec.rb b/spec/views/admin/gestionnaires/index.html.haml_spec.rb index 083ac658b..222b43b2c 100644 --- a/spec/views/admin/gestionnaires/index.html.haml_spec.rb +++ b/spec/views/admin/gestionnaires/index.html.haml_spec.rb @@ -6,9 +6,9 @@ describe 'admin/gestionnaires/index.html.haml', type: :view do before do assign(:gestionnaires, (smart_listing_create :gestionnaires, - admin.gestionnaires, - partial: "admin/gestionnaires/list", - array: true)) + admin.gestionnaires, + partial: "admin/gestionnaires/list", + array: true)) assign(:gestionnaire, Gestionnaire.new()) end @@ -24,9 +24,9 @@ describe 'admin/gestionnaires/index.html.haml', type: :view do create(:gestionnaire, administrateurs: [admin]) admin.reload assign(:gestionnaires, (smart_listing_create :gestionnaires, - admin.gestionnaires, - partial: "admin/gestionnaires/list", - array: true)) + admin.gestionnaires, + partial: "admin/gestionnaires/list", + array: true)) render end it { expect(rendered).to match(/plop\d+@plop.com/) } From ccf89700470a6345db9d8980485fd7ba3c3b4bcb Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Tue, 24 May 2016 17:24:47 +0200 Subject: [PATCH 17/20] Do not load fog configuration if feature is disabled --- spec/spec_helper.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index da8d5abc4..7411d7377 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -105,9 +105,11 @@ RSpec.configure do |config| config.before(:all) { Warden.test_mode! - VCR.use_cassette("ovh_storage_init") do - CarrierWave.configure do |config| - config.fog_credentials = { provider: 'OpenStack' } + if Features.remote_storage + VCR.use_cassette("ovh_storage_init") do + CarrierWave.configure do |config| + config.fog_credentials = { provider: 'OpenStack' } + end end end } From 2c7b65199eec3a331f72cb7e300928265e631c3d Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Tue, 24 May 2016 17:34:25 +0200 Subject: [PATCH 18/20] Fix logo filename --- app/uploaders/procedure_logo_uploader.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/uploaders/procedure_logo_uploader.rb b/app/uploaders/procedure_logo_uploader.rb index 6bd9b0690..4b52cb59b 100644 --- a/app/uploaders/procedure_logo_uploader.rb +++ b/app/uploaders/procedure_logo_uploader.rb @@ -30,9 +30,9 @@ class ProcedureLogoUploader < CarrierWave::Uploader::Base def filename if original_filename.present? || model.logo_secure_token if Features.remote_storage - filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" - else original_filename - filename = "#{model.class.to_s.underscore}.pdf" + filename = "#{model.class.to_s.underscore}-#{secure_token}.#{file.extension.downcase}" + else + filename = "logo.#{file.extension.downcase}" end end filename From a62076c34beff95a01816440a84d28bced64c8da Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Tue, 24 May 2016 17:34:52 +0200 Subject: [PATCH 19/20] Use original file extension for uploaded files --- app/uploaders/cerfa_uploader.rb | 4 ++-- app/uploaders/piece_justificative_uploader.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/uploaders/cerfa_uploader.rb b/app/uploaders/cerfa_uploader.rb index 8040d94ff..8b966aa4a 100644 --- a/app/uploaders/cerfa_uploader.rb +++ b/app/uploaders/cerfa_uploader.rb @@ -31,9 +31,9 @@ class CerfaUploader < CarrierWave::Uploader::Base def filename if original_filename.present? || model.content_secure_token if Features.remote_storage - filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" + filename = "#{model.class.to_s.underscore}-#{secure_token}.#{file.extension.downcase}" else - filename = "#{model.class.to_s.underscore}.pdf" + filename = "#{model.class.to_s.underscore}.#{file.extension.downcase}" end end filename diff --git a/app/uploaders/piece_justificative_uploader.rb b/app/uploaders/piece_justificative_uploader.rb index 3fbc4b32f..5337f87c3 100644 --- a/app/uploaders/piece_justificative_uploader.rb +++ b/app/uploaders/piece_justificative_uploader.rb @@ -31,9 +31,9 @@ class PieceJustificativeUploader < CarrierWave::Uploader::Base def filename if original_filename.present? || model.content_secure_token if Features.remote_storage - filename = "#{model.class.to_s.underscore}-#{secure_token}.pdf" + filename = "#{model.class.to_s.underscore}-#{secure_token}.#{file.extension.downcase}" else original_filename - filename = "#{model.class.to_s.underscore}.pdf" + filename = "#{model.class.to_s.underscore}.#{file.extension.downcase}" end end filename From 7fbee7a5b5b24d6fb028bc7b13818d380461d22e Mon Sep 17 00:00:00 2001 From: Guillaume Lazzara Date: Tue, 24 May 2016 18:35:25 +0200 Subject: [PATCH 20/20] Fix carrierwave root issues --- app/models/cerfa.rb | 2 +- app/models/piece_justificative.rb | 2 +- app/uploaders/cerfa_uploader.rb | 2 +- app/uploaders/piece_justificative_uploader.rb | 2 +- app/uploaders/procedure_logo_uploader.rb | 4 ++++ 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/models/cerfa.rb b/app/models/cerfa.rb index a106e6084..40fdd8cdf 100644 --- a/app/models/cerfa.rb +++ b/app/models/cerfa.rb @@ -14,7 +14,7 @@ class Cerfa < ActiveRecord::Base if Features.remote_storage (RemoteDownloader.new content.filename).url else - (LocalDownloader.new content, 'CERFA').url + (LocalDownloader.new content.path, 'CERFA').url end end end diff --git a/app/models/piece_justificative.rb b/app/models/piece_justificative.rb index 0ba0f6531..7bb2cdb34 100644 --- a/app/models/piece_justificative.rb +++ b/app/models/piece_justificative.rb @@ -22,7 +22,7 @@ class PieceJustificative < ActiveRecord::Base if Features.remote_storage (RemoteDownloader.new content.filename).url else - (LocalDownloader.new content, + (LocalDownloader.new content.path, (type_de_piece_justificative.nil? ? content.original_filename : type_de_piece_justificative.libelle)).url end end diff --git a/app/uploaders/cerfa_uploader.rb b/app/uploaders/cerfa_uploader.rb index 8b966aa4a..c69dcbac8 100644 --- a/app/uploaders/cerfa_uploader.rb +++ b/app/uploaders/cerfa_uploader.rb @@ -14,7 +14,7 @@ class CerfaUploader < CarrierWave::Uploader::Base # This is a sensible default for uploaders that are meant to be mounted: def store_dir unless Features.remote_storage - "../uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" + "./uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end end diff --git a/app/uploaders/piece_justificative_uploader.rb b/app/uploaders/piece_justificative_uploader.rb index 5337f87c3..ce446eb0a 100644 --- a/app/uploaders/piece_justificative_uploader.rb +++ b/app/uploaders/piece_justificative_uploader.rb @@ -14,7 +14,7 @@ class PieceJustificativeUploader < CarrierWave::Uploader::Base # This is a sensible default for uploaders that are meant to be mounted: def store_dir unless Features.remote_storage - "../uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" + "./uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end end diff --git a/app/uploaders/procedure_logo_uploader.rb b/app/uploaders/procedure_logo_uploader.rb index 4b52cb59b..1199b32fa 100644 --- a/app/uploaders/procedure_logo_uploader.rb +++ b/app/uploaders/procedure_logo_uploader.rb @@ -2,6 +2,10 @@ class ProcedureLogoUploader < CarrierWave::Uploader::Base + def root + File.join(Rails.root, "public") + end + # Choose what kind of storage to use for this uploader: if Features.remote_storage storage :fog