Merge pull request #4906 from betagouv/dev

2020-03-18-01
This commit is contained in:
Keirua 2020-03-18 14:24:46 +01:00 committed by GitHub
commit 584d5f1812
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
65 changed files with 871 additions and 387 deletions

View file

@ -116,6 +116,9 @@ jobs:
eval $COMMAND
- store_test_results:
path: ~/test_results
- store_artifacts:
path: tmp/capybara
destination: screenshots
lint:
<<: *defaults
steps:

View file

@ -1,6 +1,9 @@
require:
- rubocop/rspec/focused
- ./lib/cops/unscoped.rb
inherit_gem:
rubocop-rails_config:
- config/rails.yml
AllCops:
Exclude:
@ -30,13 +33,13 @@ Gemspec/RequiredRubyVersion:
Layout/AccessModifierIndentation:
Enabled: true
Layout/AlignArray:
Layout/ArrayAlignment:
Enabled: true
Layout/AlignHash:
Layout/HashAlignment:
Enabled: false
Layout/AlignParameters:
Layout/ParameterAlignment:
Enabled: true
EnforcedStyle: with_fixed_indentation
@ -89,6 +92,7 @@ Layout/EmptyLineAfterGuardClause:
# FIXME: private should not be a column name on TypeDeChamp
Layout/EmptyLinesAroundAccessModifier:
Enabled: true
EnforcedStyle: around
Exclude:
- "spec/factories/type_de_champ.rb"
@ -141,22 +145,23 @@ Layout/FirstMethodParameterLineBreak:
Layout/FirstParameterIndentation:
Enabled: true
Layout/IndentArray:
Layout/FirstArrayElementIndentation:
Enabled: true
EnforcedStyle: consistent
Layout/IndentAssignment:
Layout/AssignmentIndentation:
Enabled: true
Layout/IndentHash:
Layout/FirstHashElementIndentation:
Enabled: true
EnforcedStyle: consistent
Layout/IndentHeredoc:
Layout/HeredocIndentation:
Enabled: true
Layout/IndentationConsistency:
Enabled: true
EnforcedStyle: normal
Layout/IndentationWidth:
Enabled: true
@ -275,7 +280,7 @@ Layout/SpaceInsideStringInterpolation:
Layout/Tab:
Enabled: true
Layout/TrailingBlankLines:
Layout/TrailingEmptyLines:
Enabled: true
Layout/TrailingWhitespace:
@ -314,7 +319,7 @@ Lint/DuplicateCaseCondition:
Lint/DuplicateMethods:
Enabled: true
Lint/DuplicatedKey:
Lint/DuplicateHashKey:
Enabled: true
Lint/EachWithObjectArgument:
@ -347,7 +352,7 @@ Lint/FloatOutOfRange:
Lint/FormatParameterMismatch:
Enabled: true
Lint/HandleExceptions:
Lint/SuppressedException:
Enabled: false
Lint/ImplicitStringConcatenation:
@ -374,7 +379,7 @@ Lint/Loop:
Lint/MissingCopEnableDirective:
Enabled: true
Lint/MultipleCompare:
Lint/MultipleComparison:
Enabled: true
Lint/NestedMethodDefinition:
@ -445,7 +450,7 @@ Lint/ShadowedException:
Lint/ShadowingOuterLocalVariable:
Enabled: false
Lint/StringConversionInInterpolation:
Lint/RedundantStringCoercion:
Enabled: true
Lint/Syntax:
@ -457,16 +462,16 @@ Lint/UnderscorePrefixedVariableName:
Lint/UnifiedInteger:
Enabled: true
Lint/UnneededCopDisableDirective:
Lint/RedundantCopDisableDirective:
Enabled: true
Lint/UnneededCopEnableDirective:
Lint/RedundantCopEnableDirective:
Enabled: true
Lint/UnneededRequireStatement:
Lint/RedundantRequireStatement:
Enabled: true
Lint/UnneededSplatExpansion:
Lint/RedundantSplatExpansion:
Enabled: false
Lint/UnreachableCode:
@ -519,7 +524,7 @@ Metrics/ClassLength:
Metrics/CyclomaticComplexity:
Enabled: false
Metrics/LineLength:
Layout/LineLength:
Enabled: false
Metrics/MethodLength:
@ -567,10 +572,10 @@ Naming/MethodName:
Naming/PredicateName:
Enabled: false
Naming/UncommunicativeBlockParamName:
Naming/BlockParameterName:
Enabled: true
Naming/UncommunicativeMethodParamName:
Naming/MethodParameterName:
Enabled: false
Naming/VariableName:
@ -593,6 +598,8 @@ Performance/CompareWithBlock:
Performance/Count:
Enabled: true
Exclude:
- "app/services/administrateur_usage_statistics_service.rb"
Performance/Detect:
Enabled: true
@ -609,9 +616,6 @@ Performance/FixedSize:
Performance/FlatMap:
Enabled: true
Performance/LstripRstrip:
Enabled: true
Performance/RangeInclude:
Enabled: true
@ -624,7 +628,7 @@ Performance/RedundantMatch:
Performance/RedundantMerge:
Enabled: true
Performance/RedundantSortBy:
Style/RedundantSortBy:
Enabled: true
Performance/RegexpMatch:
@ -633,7 +637,7 @@ Performance/RegexpMatch:
Performance/ReverseEach:
Enabled: true
Performance/Sample:
Style/Sample:
Enabled: true
Performance/Size:
@ -669,6 +673,12 @@ Rails/ApplicationJob:
Rails/ApplicationRecord:
Enabled: true
Rails/ApplicationController:
Enabled: false
Rails/RakeEnvironment:
Enabled: false
Rails/Blank:
Enabled: true
@ -707,7 +717,7 @@ Rails/Exit:
Enabled: true
Rails/FilePath:
Enabled: true
Enabled: false
Rails/FindBy:
Enabled: true
@ -754,6 +764,9 @@ Rails/Present:
Rails/ReadWriteAttribute:
Enabled: false
Rails/RedundantAllowNil:
Enabled: false
Rails/RedundantReceiverInWithOptions:
Enabled: true
@ -766,9 +779,6 @@ Rails/RequestReferer:
Rails/ReversibleMigration:
Enabled: false
Rails/SafeNavigation:
Enabled: true
Rails/SaveBang:
Enabled: false
@ -846,9 +856,6 @@ Style/BlockDelimiters:
Exclude:
- "spec/**/*"
Style/BracesAroundHashParameters:
Enabled: false
Style/CaseEquality:
Enabled: true
@ -955,9 +962,6 @@ Style/EvenOdd:
Style/ExpandPathArguments:
Enabled: true
Style/FlipFlop:
Enabled: true
Style/For:
Enabled: true
@ -965,7 +969,7 @@ Style/FormatString:
Enabled: true
Style/FormatStringToken:
Enabled: true
Enabled: false
EnforcedStyle: template
Style/FrozenStringLiteralComment:
@ -1267,13 +1271,13 @@ Style/TrivialAccessors:
Style/UnlessElse:
Enabled: true
Style/UnneededCapitalW:
Style/RedundantCapitalW:
Enabled: true
Style/UnneededInterpolation:
Style/RedundantInterpolation:
Enabled: true
Style/UnneededPercentQ:
Style/RedundantPercentQ:
Enabled: true
Style/VariableInterpolation:

13
Gemfile
View file

@ -9,7 +9,6 @@ gem 'activestorage-openstack'
gem 'administrate'
gem 'after_party'
gem 'anchored'
gem 'axlsx', '~> 3.0.0.pre' # https://github.com/randym/axlsx/issues/501#issuecomment-373640365
gem 'bcrypt'
gem 'bootstrap-sass', '>= 3.4.1'
gem 'bootstrap-wysihtml5-rails', '~> 0.3.3.8'
@ -29,8 +28,6 @@ gem 'dotenv-rails', require: 'dotenv/rails-now' # dotenv should always be loaded
gem 'flipper'
gem 'flipper-active_record'
gem 'flipper-ui'
gem 'fog-openstack'
gem 'font-awesome-rails'
gem 'geocoder'
gem 'gon'
gem 'graphiql-rails'
@ -48,12 +45,10 @@ gem 'mailjet'
gem 'omniauth-github'
gem 'omniauth-rails_csrf_protection', '~> 0.1'
gem 'openid_connect'
gem 'openstack'
gem 'pg'
gem 'phonelib'
gem 'prawn' # PDF Generation
gem 'prawn-rails' # PDF Generation
gem 'prawn-svg'
gem 'prawn_rails'
gem 'premailer-rails'
gem 'puma' # Use Puma as the app server
gem 'pundit'
@ -63,15 +58,14 @@ gem 'rails'
gem 'rails-i18n' # Locales par défaut
gem 'rake-progressbar', require: false
gem 'react-rails'
gem 'rest-client'
gem 'rgeo-geojson'
gem 'sanitize-url'
gem 'sassc-rails' # Use SCSS for stylesheets
gem 'scenic'
gem 'sentry-raven'
gem 'skylight'
gem 'smart_listing'
gem 'spreadsheet_architect'
gem 'sprockets', '< 4'
gem 'turbolinks' # Turbolinks makes following links in your web application faster
gem 'typhoeus'
gem 'warden'
@ -103,6 +97,7 @@ group :development do
gem 'haml-lint'
gem 'letter_opener_web'
gem 'rubocop', require: false
gem 'rubocop-rails_config'
gem 'rubocop-rspec-focused', require: false
gem 'scss_lint', require: false
gem 'web-console'
@ -114,7 +109,7 @@ group :development, :test do
gem 'graphql-schema_comparator'
gem 'mina', git: 'https://github.com/mina-deploy/mina.git', require: false # Deploy
gem 'pry-byebug'
gem 'rspec-rails'
gem 'rspec-rails', '~> 4.0.0.beta'
gem 'rspec_junit_formatter', require: false
gem 'ruby-debug-ide', require: false
gem 'simple_xlsx_reader'

View file

@ -78,16 +78,16 @@ GEM
tzinfo (~> 1.1)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
administrate (0.11.0)
actionpack (>= 4.2, < 6.0)
actionview (>= 4.2, < 6.0)
activerecord (>= 4.2, < 6.0)
administrate (0.12.0)
actionpack (>= 4.2)
actionview (>= 4.2)
activerecord (>= 4.2)
autoprefixer-rails (>= 6.0)
datetime_picker_rails (~> 0.0.7)
jquery-rails (>= 4.0)
kaminari (>= 1.0)
momentjs-rails (~> 2.8)
sass-rails (~> 5.0)
sassc-rails (~> 2.1)
selectize-rails (~> 0.6)
aes_key_wrap (1.0.1)
after_party (1.10.0)
@ -95,16 +95,11 @@ GEM
arel (9.0.0)
ast (2.4.0)
attr_required (1.0.1)
autoprefixer-rails (9.4.4)
autoprefixer-rails (9.7.4)
execjs
axlsx (3.0.0.pre)
htmlentities (~> 4.3, >= 4.3.4)
mimemagic (~> 0.3)
nokogiri (~> 1.8, >= 1.8.2)
rubyzip (~> 1.2, >= 1.2.1)
axlsx_styler (0.2.0)
axlsx_styler (1.0.0)
activesupport (>= 3.1)
axlsx (>= 2.0, < 4)
caxlsx (>= 2.0.2)
babel-source (5.8.35)
babel-transpiler (0.7.0)
babel-source (>= 4.0, < 6)
@ -118,7 +113,7 @@ GEM
bootstrap-wysihtml5-rails (0.3.3.8)
railties (>= 3.0)
brakeman (4.3.1)
browser (2.5.3)
browser (4.0.0)
builder (3.2.4)
byebug (10.0.2)
capybara (3.29.0)
@ -140,6 +135,11 @@ GEM
selenium-webdriver
case_transform (0.2)
activesupport
caxlsx (3.0.1)
htmlentities (~> 4.3, >= 4.3.4)
mimemagic (~> 0.3)
nokogiri (~> 1.10, >= 1.10.4)
rubyzip (>= 1.3.0, < 3)
chartkick (3.3.1)
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
@ -158,21 +158,21 @@ GEM
crack (0.4.3)
safe_yaml (~> 1.0.0)
crass (1.0.6)
css_parser (1.6.0)
css_parser (1.7.1)
addressable
curb (0.9.10)
daemons (1.3.1)
database_cleaner (1.7.0)
datetime_picker_rails (0.0.7)
momentjs-rails (>= 2.8.1)
deep_cloneable (2.3.2)
activerecord (>= 3.1.0, < 6)
deep_cloneable (3.0.0)
activerecord (>= 3.1.0, < 7)
delayed_cron_job (0.7.2)
delayed_job (>= 4.1)
delayed_job (4.1.5)
activesupport (>= 3.0, < 5.3)
delayed_job_active_record (4.1.3)
activerecord (>= 3.0, < 5.3)
delayed_job (4.1.8)
activesupport (>= 3.0, < 6.1)
delayed_job_active_record (4.1.4)
activerecord (>= 3.0, < 6.1)
delayed_job (>= 3.0, < 5)
delayed_job_web (1.4.3)
activerecord (> 3.0.0)
@ -193,10 +193,11 @@ GEM
activerecord (>= 4.2, < 7)
domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.5.0)
dotenv-rails (2.5.0)
dotenv (= 2.5.0)
railties (>= 3.2, < 6.0)
dotenv (2.7.5)
dotenv-rails (2.7.5)
dotenv (= 2.7.5)
railties (>= 3.2, < 6.1)
dry-inflector (0.2.0)
em-websocket (0.5.1)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
@ -233,8 +234,6 @@ GEM
fog-core (~> 2.1)
fog-json (>= 1.0)
ipaddress (>= 0.8)
font-awesome-rails (4.7.0.4)
railties (>= 3.2, < 6.0)
formatador (0.2.5)
geocoder (1.6.0)
globalid (0.4.2)
@ -260,8 +259,8 @@ GEM
bundler (>= 1.14)
graphql (~> 1.10)
thor (>= 0.19, < 2.0)
groupdate (4.1.1)
activesupport (>= 4.2)
groupdate (5.0.0)
activesupport (>= 5)
guard (2.15.0)
formatador (>= 0.2.4)
listen (>= 2.7, < 4.0)
@ -281,21 +280,20 @@ GEM
guard (~> 2.1)
guard-compat (~> 1.1)
rspec (>= 2.99.0, < 4.0)
haml (5.0.4)
haml (5.1.2)
temple (>= 0.8.0)
tilt
haml-lint (0.999.999)
haml_lint
haml-rails (1.0.0)
actionpack (>= 4.0.1)
activesupport (>= 4.0.1)
haml-rails (2.0.1)
actionpack (>= 5.1)
activesupport (>= 5.1)
haml (>= 4.0.6, < 6.0)
html2haml (>= 1.0.1)
railties (>= 4.0.1)
haml_lint (0.28.0)
haml (>= 4.0, < 5.1)
railties (>= 5.1)
haml_lint (0.35.0)
haml (>= 4.0, < 5.2)
rainbow
rake (>= 10, < 13)
rubocop (>= 0.50.0)
sysexits (~> 1.1)
hashdiff (0.3.8)
@ -313,12 +311,11 @@ GEM
i18n (1.8.2)
concurrent-ruby (~> 1.0)
ipaddress (0.8.3)
jaro_winkler (1.5.2)
jquery-rails (4.3.3)
jaro_winkler (1.5.4)
jquery-rails (4.3.5)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (2.2.0)
json-jwt (1.11.0)
activesupport (>= 4.2)
aes_key_wrap
@ -418,31 +415,31 @@ GEM
validate_email
validate_url
webfinger (>= 1.0.1)
openstack (3.3.21)
json
orm_adapter (0.5.0)
parallel (1.12.1)
parser (2.5.3.0)
parallel (1.19.1)
parser (2.7.0.4)
ast (~> 2.4.0)
pdf-core (0.7.0)
pg (1.1.3)
phonelib (0.6.39)
powerpack (0.1.2)
prawn (2.2.2)
pdf-core (~> 0.7.0)
ttfunk (~> 1.5)
prawn-rails (1.3.0)
prawn
prawn-table
rails (>= 3.1.0)
prawn-svg (0.29.1)
css_parser (~> 1.6)
prawn (>= 0.11.1, < 3)
prawn_rails (0.0.11)
prawn (>= 0.11.1)
railties (>= 3.0.0)
prawn-table (0.2.2)
prawn (>= 1.3.0, < 3.0.0)
premailer (1.11.1)
addressable
css_parser (>= 1.6.0)
htmlentities (>= 4.0.0)
premailer-rails (1.10.2)
actionmailer (>= 3, < 6)
premailer-rails (1.10.3)
actionmailer (>= 3)
premailer (~> 1.7, >= 1.7.9)
promise.rb (0.7.4)
pry (0.12.2)
@ -507,7 +504,7 @@ GEM
rake (12.3.3)
rake-progressbar (0.0.5)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
rb-inotify (0.10.1)
ffi (~> 1.0)
react-rails (2.4.7)
babel-transpiler (>= 0.7.0)
@ -525,12 +522,13 @@ GEM
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
rexml (3.2.4)
rgeo (2.0.0)
rgeo-geojson (2.1.1)
rgeo (>= 1.0.0)
rodf (1.0.0)
activesupport (>= 3.0)
rodf (1.1.1)
builder (>= 3.0)
dry-inflector (~> 0.1)
rubyzip (>= 1.0)
rouge (3.16.0)
rspec (3.9.0)
@ -545,47 +543,51 @@ GEM
rspec-mocks (3.9.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-rails (3.9.0)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-support (~> 3.9.0)
rspec-rails (4.0.0.beta4)
actionpack (>= 4.2)
activesupport (>= 4.2)
railties (>= 4.2)
rspec-core (~> 3.9)
rspec-expectations (~> 3.9)
rspec-mocks (~> 3.9)
rspec-support (~> 3.9)
rspec-support (3.9.2)
rspec_junit_formatter (0.4.1)
rspec-core (>= 2, < 4, != 2.12.0)
rubocop (0.62.0)
rubocop (0.80.1)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
parser (>= 2.5, != 2.5.1.1)
powerpack (~> 0.1)
parser (>= 2.7.0.1)
rainbow (>= 2.2.2, < 4.0)
rexml
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.4.0)
unicode-display_width (>= 1.4.0, < 1.7)
rubocop-performance (1.5.2)
rubocop (>= 0.71.0)
rubocop-rails (2.4.2)
rack (>= 1.1)
rubocop (>= 0.72.0)
rubocop-rails_config (0.10.0)
railties (>= 5.0)
rubocop (~> 0.80)
rubocop-performance (~> 1.3)
rubocop-rails (~> 2.0)
rubocop-rspec-focused (1.0.0)
rubocop (>= 0.51)
ruby-debug-ide (0.6.1)
rake (>= 0.8.1)
ruby-progressbar (1.10.0)
ruby-progressbar (1.10.1)
ruby_dep (1.5.0)
ruby_parser (3.12.0)
ruby_parser (3.14.2)
sexp_processor (~> 4.9)
rubyzip (1.3.0)
safe_yaml (1.0.4)
sanitize-url (0.1.4)
sass (3.7.3)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sass-rails (5.0.7)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
sassc (2.0.0)
ffi (~> 1.9.6)
rake
@ -595,9 +597,6 @@ GEM
sprockets (> 3.0)
sprockets-rails
tilt
scenic (1.4.1)
activerecord (>= 4.0.0)
railties (>= 4.0.0)
scss_lint (0.57.1)
rake (>= 0.9, < 13)
sass (~> 3.5, >= 3.5.5)
@ -607,7 +606,7 @@ GEM
rubyzip (~> 1.2, >= 1.2.2)
sentry-raven (2.7.4)
faraday (>= 0.7.6, < 1.0)
sexp_processor (4.11.0)
sexp_processor (4.14.1)
shellany (0.0.1)
shoulda-matchers (4.0.1)
activesupport (>= 4.2.0)
@ -628,9 +627,9 @@ GEM
jquery-rails
kaminari (>= 0.17)
rails (>= 3.2)
spreadsheet_architect (3.2.0)
axlsx (>= 2, < 4)
axlsx_styler (>= 0.1.7, < 2)
spreadsheet_architect (4.0.0)
axlsx_styler (>= 1.0.0, < 2)
caxlsx (>= 2.0.2, < 4)
rodf (>= 1.0.0, < 2)
spring (2.0.2)
activesupport (>= 4.2)
@ -648,10 +647,10 @@ GEM
attr_required (>= 0.0.5)
httpclient (>= 2.4)
sysexits (1.2.0)
temple (0.8.0)
temple (0.8.2)
thor (1.0.1)
thread_safe (0.3.6)
tilt (2.0.9)
tilt (2.0.10)
timecop (0.9.1)
ttfunk (1.5.1)
turbolinks (5.2.0)
@ -664,7 +663,7 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.7.5)
unicode-display_width (1.4.1)
unicode-display_width (1.6.1)
validate_email (0.1.6)
activemodel (>= 3.0)
mail (>= 2.2.5)
@ -721,7 +720,6 @@ DEPENDENCIES
administrate
after_party
anchored
axlsx (~> 3.0.0.pre)
bcrypt
bootstrap-sass (>= 3.4.1)
bootstrap-wysihtml5-rails (~> 0.3.3.8)
@ -749,8 +747,6 @@ DEPENDENCIES
flipper
flipper-active_record
flipper-ui
fog-openstack
font-awesome-rails
geocoder
gon
graphiql-rails
@ -776,12 +772,10 @@ DEPENDENCIES
omniauth-github
omniauth-rails_csrf_protection (~> 0.1)
openid_connect
openstack
pg
phonelib
prawn
prawn-rails
prawn-svg
prawn_rails
premailer-rails
pry-byebug
puma
@ -793,16 +787,15 @@ DEPENDENCIES
rails-i18n
rake-progressbar
react-rails
rest-client
rgeo-geojson
rspec-rails
rspec-rails (~> 4.0.0.beta)
rspec_junit_formatter
rubocop
rubocop-rails_config
rubocop-rspec-focused
ruby-debug-ide
sanitize-url
sassc-rails
scenic
scss_lint
sentry-raven
shoulda-matchers
@ -812,6 +805,7 @@ DEPENDENCIES
spreadsheet_architect
spring
spring-commands-rspec
sprockets (< 4)
timecop
turbolinks
typhoeus

View file

@ -34,7 +34,6 @@
// = require_self
// = require leaflet
// = require font-awesome
// = require franceconnect
// = require bootstrap-wysihtml5

View file

@ -198,7 +198,7 @@ class ApplicationController < ActionController::Base
# return at this location
# after the device is trusted
store_location_for(:user, request.fullpath)
store_location_for(:user, request.fullpath) if get_stored_location_for(:user).blank?
send_login_token_or_bufferize(current_instructeur)
redirect_to link_sent_path(email: current_instructeur.email)
@ -233,7 +233,7 @@ class ApplicationController < ActionController::Base
key: sentry[:client_key],
enabled: sentry[:enabled],
environment: sentry[:environment],
browser: { modern: browser.modern? },
browser: { modern: BrowserSupport.supported?(browser) },
user: sentry_user
}
end

View file

@ -62,7 +62,7 @@ class Champs::CarteController < ApplicationController
@champ.save
end
rescue RestClient::ResourceNotFound
rescue ApiCarto::API::ResourceNotFound
flash.alert = 'Les données cartographiques sont temporairement indisponibles. Réessayez dans un instant.'
response.status = 503
end

View file

@ -16,7 +16,7 @@ class Champs::SiretController < ApplicationController
begin
etablissement = find_etablissement_with_siret
rescue RestClient::RequestFailed
rescue ApiEntreprise::API::RequestFailed
return siret_error(:network_error)
end
if etablissement.blank?

View file

@ -58,7 +58,6 @@ class StatsController < ApplicationController
.includes(:procedure, :user)
.in_batches
.flat_map do |dossiers|
dossiers
.pluck(
"dossiers.id",

View file

@ -16,6 +16,20 @@ module Users
render 'commencer/show'
end
def dossier_vide_pdf
@procedure = retrieve_procedure
return procedure_not_found if @procedure.blank? || @procedure.brouillon?
generate_empty_pdf(@procedure)
end
def dossier_vide_pdf_test
@procedure = retrieve_procedure
return procedure_not_found if @procedure.blank? || @procedure.publiee?
generate_empty_pdf(@procedure)
end
def sign_in
@procedure = retrieve_procedure
return procedure_not_found if @procedure.blank?
@ -65,5 +79,11 @@ module Users
def store_user_location!(procedure)
store_location_for(:user, helpers.procedure_lien(procedure))
end
def generate_empty_pdf(procedure)
@dossier = procedure.new_dossier
s = render_to_string(file: 'dossiers/dossier_vide', formats: [:pdf])
send_data(s, :filename => "#{procedure.libelle}.pdf")
end
end
end

View file

@ -106,7 +106,7 @@ module Users
sanitized_siret = siret_model.siret
begin
etablissement_attributes = ApiEntrepriseService.get_etablissement_params_for_siret(sanitized_siret, @dossier.procedure.id)
rescue RestClient::RequestFailed
rescue ApiEntreprise::API::RequestFailed
return render_siret_error(t('errors.messages.siret_network_error'))
end
if etablissement_attributes.blank?

View file

@ -131,4 +131,12 @@ module ApplicationHelper
def has_dismissed_outdated_browser_banner?
cookies[:dismissed_outdated_browser_banner] == 'true'
end
def supported_browser?
BrowserSupport.supported?(browser)
end
def show_outdated_browser_banner?
!supported_browser? && !has_dismissed_outdated_browser_banner?
end
end

View file

@ -2,4 +2,8 @@ module FlipperHelper
def feature_enabled?(feature_name)
Flipper.enabled?(feature_name, current_user)
end
def feature_enabled_for?(feature_name, item)
Flipper.enabled?(feature_name, item)
end
end

View file

@ -1,4 +1,7 @@
class ApiCarto::API
class ResourceNotFound < StandardError
end
def self.search_qp(geojson)
url = [API_CARTO_URL, "quartiers-prioritaires", "search"].join("/")
call(url, geojson)
@ -19,7 +22,7 @@ class ApiCarto::API
else
message = response.code == 0 ? response.return_message : response.code.to_s
Rails.logger.error "[ApiCarto] Error on #{url}: #{message}"
raise RestClient::ResourceNotFound
raise ResourceNotFound
end
end
end

View file

@ -9,7 +9,7 @@ class ApiEntreprise::Adapter
def data_source
begin
@data_source ||= get_resource
rescue RestClient::ResourceNotFound
rescue ApiEntreprise::API::ResourceNotFound
@data_source = nil
end
end

View file

@ -6,6 +6,12 @@ class ApiEntreprise::API
TIMEOUT = 15
class ResourceNotFound < StandardError
end
class RequestFailed < StandardError
end
def self.entreprise(siren, procedure_id)
call(ENTREPRISE_RESOURCE_NAME, siren, procedure_id)
end
@ -35,9 +41,9 @@ class ApiEntreprise::API
if response.success?
JSON.parse(response.body, symbolize_names: true)
elsif response.code&.between?(401, 499)
raise RestClient::ResourceNotFound
raise ResourceNotFound
else
raise RestClient::RequestFailed
raise RequestFailed
end
end
@ -56,6 +62,7 @@ class ApiEntreprise::API
context: "demarches-simplifiees.fr",
recipient: siret_or_siren,
object: "procedure_id: #{procedure_id}",
non_diffusables: true,
token: token
}
end

View file

@ -24,7 +24,8 @@ class ApiEntreprise::EtablissementAdapter < ApiEntreprise::Adapter
:siret,
:siege_social,
:naf,
:libelle_naf
:libelle_naf,
:diffusable_commercialement
]
end

View file

@ -51,20 +51,29 @@ class Pipedrive::API
api_token: token
})
response = RestClient.get(url, params: params)
response = Typhoeus.get(url, params: params)
if response.success?
JSON.parse(response.body)['data']
end
end
def self.put(url, params)
url = "#{url}?api_token=#{token}"
RestClient.put(url, params.to_json, { content_type: :json })
Typhoeus.put(
url,
params: { api_token: token },
body: params.to_json,
headers: { 'content-type' => 'application/json' }
)
end
def self.post(url, params)
url = "#{url}?api_token=#{token}"
RestClient.post(url, params.to_json, { content_type: :json })
Typhoeus.post(
url,
params: { api_token: token },
body: params.to_json,
headers: { 'content-type' => 'application/json' }
)
end
def self.token

View file

@ -85,6 +85,11 @@ class Administrateur < ApplicationRecord
next_administrateur = procedure.administrateurs.where.not(id: self.id).first
procedure.service.update(administrateur: next_administrateur)
end
services.each do |service|
service.destroy unless service.procedures.any?
end
destroy
end
end

View file

@ -692,7 +692,6 @@ class Dossier < ApplicationRecord
.includes(:procedure, :user)
.group_by(&:user)
.each do |(user, dossiers)|
dossier_hashes = dossiers.map(&:hash_for_deletion_mail)
DossierMailer.notify_brouillon_deletion(user, dossier_hashes).deliver_later

View file

@ -148,11 +148,12 @@ class Instructeur < ApplicationRecord
def email_notification_data
groupe_instructeur_with_email_notifications
.reduce([]) do |acc, groupe|
procedure = groupe.procedure
h = {
nb_en_construction: groupe.dossiers.en_construction.count,
nb_en_instruction: groupe.dossiers.en_instruction.count,
nb_accepted: groupe.dossiers.accepte.where(processed_at: Time.zone.yesterday.beginning_of_day..Time.zone.yesterday.end_of_day).count,
nb_notification: notifications_for_procedure(procedure, :not_archived).count
}
@ -162,6 +163,14 @@ class Instructeur < ApplicationRecord
acc << h
end
[["en_instruction", h[:nb_en_instruction]], ["accepte", h[:nb_accepted]]].each do |state, count|
if procedure.declarative_with_state == state && count > 0
h[:procedure_id] = procedure.id
h[:procedure_libelle] = procedure.libelle
acc << h
end
end
acc
end
end

View file

@ -496,6 +496,10 @@ class Procedure < ApplicationRecord
dossiers.discard_all
end
def flipper_id
"Procedure;#{id}"
end
private
def move_type_de_champ_attributes(types_de_champ, type_de_champ, new_index)

View file

@ -4,7 +4,7 @@ class ApiEntrepriseService
# Returns nil if the SIRET is unknown; and nested params
# suitable for being saved into a Etablissement object otherwise.
#
# Raises a RestClient::RequestFailed exception on transcient errors
# Raises a ApiEntreprise::API::RequestFailed exception on transcient errors
# (timeout, 5XX HTTP error code, etc.)
def self.get_etablissement_params_for_siret(siret, procedure_id)
etablissement_params = ApiEntreprise::EtablissementAdapter.new(siret, procedure_id).to_params
@ -14,13 +14,13 @@ class ApiEntrepriseService
begin
association_params = ApiEntreprise::RNAAdapter.new(siret, procedure_id).to_params
etablissement_params.merge!(association_params)
rescue RestClient::RequestFailed
rescue ApiEntreprise::API::RequestFailed
end
begin
exercices_params = ApiEntreprise::ExercicesAdapter.new(siret, procedure_id).to_params
etablissement_params.merge!(exercices_params)
rescue RestClient::RequestFailed
rescue ApiEntreprise::API::RequestFailed
end
etablissement_params.merge(entreprise_params)

View file

@ -0,0 +1,13 @@
class BrowserSupport
def self.supported?(browser)
# See .browserslistrc
[
browser.chrome? && browser.version.to_i >= 50 && !browser.platform.ios?,
browser.edge? && browser.version.to_i >= 14 && !browser.compatibility_view?,
browser.firefox? && browser.version.to_i >= 50 && !browser.platform.ios?,
browser.opera? && browser.version.to_i >= 40,
browser.safari? && browser.version.to_i >= 8,
browser.platform.ios? && browser.platform.version.to_i >= 8
].any?
end
end

View file

@ -40,3 +40,15 @@
%h2.huge-title Vous avez déjà des dossiers pour cette démarche
= link_to 'Voir mes dossiers en cours', dossiers_path, class: ['button large expand primary']
= link_to 'Commencer un nouveau dossier', url_for_new_dossier(@procedure), class: ['button large expand']
- if feature_enabled_for?(:dossier_pdf_vide, @procedure)
- pdf_link = commencer_dossier_vide_path(path: @procedure.path)
- if @procedure.brouillon?
- pdf_link = commencer_dossier_vide_test_path(path: @procedure.path)
%hr
%p
Vous souhaitez effectuer une demande par papier ? Vous pouvez télécharger un dossier vide au format PDF,
et l'envoyer à ladministration concernée :
#{@procedure&.service&.nom} - #{@procedure&.service&.adresse}
%br
= link_to 'Télécharger un dossier vide au format PDF', pdf_link, class: ['button large expand']

View file

@ -0,0 +1,196 @@
require 'prawn/measurement_extensions'
def render_in_2_columns(pdf, label, text)
pdf.text_box label, width: 200, height: 100, overflow: :expand, at: [0, pdf.cursor]
pdf.text_box ":", width: 10, height: 100, overflow: :expand, at: [100, pdf.cursor]
pdf.text_box text, width: 420, height: 100, overflow: :expand, at: [110, pdf.cursor]
pdf.text "\n"
end
def format_in_2_lines(pdf, label, nb_lines = 1)
add_single_line(pdf, label, 12, :bold)
height = 10 * (nb_lines+1)
pdf.bounding_box([0, pdf.cursor],:width => 460,:height => height) do
pdf.stroke_bounds
end
pdf.text "\n"
end
def format_in_2_columns(pdf, label)
pdf.text_box label, width: 200, height: 100, overflow: :expand, at: [0, pdf.cursor]
pdf.bounding_box([110, pdf.cursor+5],:width => 350,:height => 20) do
pdf.stroke_bounds
end
pdf.text "\n"
end
def format_with_checkbox(pdf, label, offset = 0)
pdf.font 'liberation serif', size: 12 do
pdf.stroke_rectangle [0 + offset, pdf.cursor], 10, 10
pdf.text_box label, at: [15 + offset, pdf.cursor]
end
pdf.text "\n"
end
def add_page_numbering(pdf)
# This method should be called at the end of the drawing since pages drawn after
# do not have page numbering
string = '<page> / <total>'
options = {
at: [0, -15],
align: :right
}
pdf.number_pages string, options
end
def add_procedure(pdf, dossier)
pdf.repeat(lambda {|page| page > 1 }) do
pdf.draw_text dossier.procedure.libelle, :at => pdf.bounds.top_left
end
end
def format_date(date)
I18n.l(date, format: :message_date_with_year)
end
def add_identite_individual(pdf, dossier)
format_in_2_columns(pdf, "Civilité")
format_in_2_columns(pdf, "Nom")
format_in_2_columns(pdf, "Prénom")
format_in_2_columns(pdf, "Date de naissance")
end
def add_identite_etablissement(pdf, libelle)
add_single_line(pdf, libelle, 12, :bold)
format_in_2_columns(pdf, "SIRET")
format_in_2_columns(pdf, "Dénomination")
format_in_2_columns(pdf, "Forme juridique")
end
def add_single_line(pdf, libelle, size, style)
pdf.font 'liberation serif', style: style, size: size do
pdf.text libelle
end
end
def add_title(pdf, title)
add_single_line(pdf, title, 24, :bold)
pdf.text "\n"
end
def add_libelle(pdf, champ)
add_single_line(pdf, champ.libelle, 12, :bold)
end
def add_explanation(pdf, explanation)
add_single_line(pdf, explanation, 9, :italic)
end
def render_single_champ(pdf, champ)
case champ.type
when 'Champs::RepetitionChamp'
raise 'There should not be a RepetitionChamp here !'
when 'Champs::PieceJustificativeChamp'
add_single_line(pdf, 'Pièce justificative à joindre', 12, :bold)
pdf.text champ.libelle
pdf.text champ.description
pdf.text "\n"
when 'Champs::YesNoChamp', 'Champs::CheckboxChamp'
add_libelle(pdf, champ)
add_explanation(pdf, 'Cochez la mention applicable')
format_with_checkbox(pdf, 'Oui')
format_with_checkbox(pdf, 'Non')
pdf.text "\n"
when 'Champs::CiviliteChamp'
add_libelle(pdf, champ)
format_with_checkbox(pdf, Individual::GENDER_FEMALE)
format_with_checkbox(pdf, Individual::GENDER_MALE)
pdf.text "\n"
when 'Champs::HeaderSectionChamp'
add_single_line(pdf, champ.libelle, 18, :bold)
pdf.text "\n"
when 'Champs::ExplicationChamp'
add_libelle(pdf, champ)
pdf.text champ.description
pdf.text "\n"
when 'Champs::AddressChamp', 'Champs::CarteChamp', 'Champs::TextareaChamp'
format_in_2_lines(pdf, champ.libelle, 3)
when 'Champs::DropDownListChamp'
add_libelle(pdf, champ)
add_explanation(pdf, 'Cochez la mention applicable, une seule valeur possible')
champ.drop_down_list.options.reject(&:blank?).each do |option|
format_with_checkbox(pdf, option)
end
pdf.text "\n"
when 'Champs::MultipleDropDownListChamp'
add_libelle(pdf, champ)
add_explanation(pdf, 'Cochez la mention applicable, plusieurs valeurs possibles')
champ.drop_down_list.options.reject(&:blank?).each do |option|
format_with_checkbox(pdf, option)
end
pdf.text "\n"
when 'Champs::LinkedDropDownListChamp'
add_libelle(pdf, champ)
champ.primary_options.reject(&:blank?).each do |o|
format_with_checkbox(pdf, o)
champ.secondary_options[o].reject(&:blank?).each do |secondary_option|
format_with_checkbox(pdf, secondary_option, 15)
end
end
pdf.text "\n"
when 'Champs::SiretChamp'
add_identite_etablissement(pdf, champ.libelle)
else
format_in_2_lines(pdf, champ.libelle)
end
end
def add_champs(pdf, champs)
champs.each do |champ|
if champ.type == 'Champs::RepetitionChamp'
add_libelle(pdf, champ)
(1..3).each do
champ.rows.each do |row|
row.each do |inner_champ|
render_single_champ(pdf, inner_champ)
end
end
end
else
render_single_champ(pdf, champ)
end
end
end
prawn_document(page_size: "A4") do |pdf|
pdf.font_families.update( 'liberation serif' => {
normal: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Regular.ttf' ),
bold: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Bold.ttf' ),
italic: Rails.root.join('lib/prawn/fonts/liberation_serif/LiberationSerif-Italic.ttf' ),
})
pdf.font 'liberation serif'
pdf.svg IO.read("app/assets/images/header/logo-ds-wide.svg"), width: 300, position: :center
pdf.move_down(40)
render_in_2_columns(pdf, 'Démarche', @dossier.procedure.libelle)
render_in_2_columns(pdf, 'Organisme', @dossier.procedure.organisation_name)
pdf.text "\n"
add_title(pdf, "Identité du demandeur")
format_in_2_columns(pdf, "Email")
if @dossier.procedure.for_individual?
add_identite_individual(pdf, @dossier)
else
render_identite_etablissement(pdf, @dossier.etablissement) if @dossier.etablissement.present?
end
pdf.text "\n"
add_title(pdf, 'Formulaire')
add_champs(pdf, @dossier.champs)
add_page_numbering(pdf)
add_procedure(pdf, @dossier)
end

View file

@ -16,5 +16,12 @@
- if datum[:nb_notification] > 0
%br
#{datum[:nb_notification]} #{'notification'.pluralize(datum[:nb_notification])}
- if datum[:nb_en_instruction] > 0
%br
#{datum[:nb_en_instruction]} #{'dossier'.pluralize(datum[:nb_en_instruction])}
- if datum[:nb_accepted] > 0
%br
#{datum[:nb_accepted]} #{'dossier'.pluralize(datum[:nb_accepted])}
= render partial: "layouts/mailers/signature"

View file

@ -1,5 +1,4 @@
-# See config/browser.rb
- if !browser.modern? && !has_dismissed_outdated_browser_banner?
- if show_outdated_browser_banner?
#outdated-browser-banner.site-banner
.container
.site-banner-icon ⚠️

View file

@ -121,4 +121,4 @@
Par défaut, un dossier déposé peut être complété ou corrigé par le demandeur jusqu'à sa mise en instruction.<br>
Dans une démarche déclarative, une fois déposé, un dossier ne peut plus être modifié.
Soit il passe immédiatement « en instruction » pour être traité soit il est immédiatement « accepté ».
= f.select :declarative_with_state, Procedure.declarative_attributes_for_select, { prompt: 'Non' }, class: 'form-control'
= f.select :declarative_with_state, Procedure.declarative_attributes_for_select, { include_blank: 'Non' }, class: 'form-control'

View file

@ -1,5 +1,9 @@
%table.table.vertical.dossier-champs
%tbody
- if etablissement.diffusable_commercialement == false && profile != 'instructeur'
%tr
%td= t('warning_for_private_info', etablissement: raison_sociale_or_name(etablissement), scope: 'views.shared.dossiers.identite_entreprise')
- else
%tr
%th.libelle Dénomination :
%td= raison_sociale_or_name(etablissement)

View file

@ -7,6 +7,11 @@
.container
%h1 Informations sur létablissement
- etablissement = @dossier.etablissement
- if etablissement.diffusable_commercialement == false
%p= t('warning_for_private_info', etablissement: raison_sociale_or_name(etablissement), scope: 'views.shared.dossiers.identite_entreprise')
- else
%p
Nous avons récupéré auprès de lINSEE et dInfogreffe les informations suivantes concernant votre établissement.
@ -14,7 +19,7 @@
Ces informations seront jointes à votre dossier.
.etablissement-infos.card.featured
- etablissement = @dossier.etablissement
%h2.card-title= raison_sociale_or_name(etablissement)
= render partial: 'users/dossiers/etablissement/infos_entreprise', locals: { etablissement: etablissement }

View file

@ -1,8 +0,0 @@
# See .browserslistrc
Browser.modern_rules.clear
Browser.modern_rules << -> b { b.chrome? && b.version.to_i >= 50 && !b.platform.ios? }
Browser.modern_rules << -> b { b.edge? && b.version.to_i >= 14 && !b.compatibility_view? }
Browser.modern_rules << -> b { b.firefox? && b.version.to_i >= 50 && !b.platform.ios? }
Browser.modern_rules << -> b { b.opera? && b.version.to_i >= 40 }
Browser.modern_rules << -> b { b.safari? && b.version.to_i >= 8 }
Browser.modern_rules << -> b { b.platform.ios? && b.platform.version.to_i >= 8 }

View file

@ -1,9 +1,4 @@
Rails.application.config.content_security_policy do |policy|
if Rails.env.development?
# les CSP ne sont pas appliquées en dev: on notifie cependant une url quelconque de la violation
# pour détecter les erreurs lors de l'ajout d'une nouvelle brique externe durant le développement
policy.report_uri "http://#{ENV['APP_HOST']}/csp/"
end
# Whitelist image
policy.img_src :self, "*.openstreetmap.org", "static.demarches-simplifiees.fr", "*.cloud.ovh.net", "stats.data.gouv.fr", "*", :data
# Whitelist JS: nous, sendinblue et matomo
@ -17,4 +12,11 @@ Rails.application.config.content_security_policy do |policy|
# Pour tout le reste, par défaut on accepte uniquement ce qui vient de chez nous
# et dans la notification on inclue la source de l'erreur
policy.default_src :self, :data, :report_sample, "fonts.gstatic.com", "in-automate.sendinblue.com", "player.vimeo.com", "app.franceconnect.gouv.fr", "sentry.io", "static.demarches-simplifiees.fr", "*.crisp.chat", "crisp.chat", "*.crisp.help", "*.sibautomation.com", "sibautomation.com", "data"
if Rails.env.development?
# Les CSP ne sont pas appliquées en dev: on notifie cependant une url quelconque de la violation
# pour détecter les erreurs lors de l'ajout d'une nouvelle brique externe durant le développement
policy.report_uri "http://#{ENV['APP_HOST']}/csp/"
# En développement, quand bin/webpack-dev-server est utilisé, on autorise les requêtes faites par le live-reload
policy.connect_src(*policy.connect_src, "ws://localhost:3035", "localhost:3035")
end
end

View file

@ -1 +0,0 @@
OpenStack::VERSION = 2.0

View file

@ -0,0 +1,6 @@
fr:
views:
shared:
dossiers:
identite_entreprise:
warning_for_private_info: "L'établissement %{etablissement} a exercé son droit à la non publication des informations relatives à son identité. Les informations ne seront donc visibles que de la part des services instructeurs"

View file

@ -242,8 +242,10 @@ Rails.application.routes.draw do
scope module: 'users' do
namespace :commencer do
get '/test/:path/dossier_vide', action: 'dossier_vide_pdf_test', as: :dossier_vide_test
get '/test/:path', action: 'commencer_test', as: :test
get '/:path', action: 'commencer'
get '/:path/dossier_vide', action: 'dossier_vide_pdf', as: :dossier_vide
get '/:path/sign_in', action: 'sign_in', as: :sign_in
get '/:path/sign_up', action: 'sign_up', as: :sign_up
get '/:path/france_connect', action: 'france_connect', as: :france_connect

View file

@ -0,0 +1,5 @@
class AddDiffusableCommercialementToEtablissements < ActiveRecord::Migration[5.2]
def change
add_column :etablissements, :diffusable_commercialement, :boolean
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_02_27_100001) do
ActiveRecord::Schema.define(version: 2020_03_04_155418) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@ -304,6 +304,7 @@ ActiveRecord::Schema.define(version: 2020_02_27_100001) do
t.date "association_date_publication"
t.datetime "created_at"
t.datetime "updated_at"
t.boolean "diffusable_commercialement"
t.index ["dossier_id"], name: "index_etablissements_on_dossier_id"
end

View file

@ -16,4 +16,4 @@ user = User.create!(
confirmed_at: Time.zone.now
)
user.create_instructeur!
user.create_administrateur!(email: user.email)
user.create_administrateur!

View file

@ -1,18 +0,0 @@
namespace :after_party do
desc 'Deployment task: create_dummy_paths_for_archived_and_hidden_procedures'
task create_dummy_paths_for_archived_and_hidden_procedures: :environment do
rake_puts "Running deploy task 'create_dummy_paths_for_archived_procedures'"
Procedure.with_discarded.archivees.where(path: nil).each do |p|
p.update_column(:path, SecureRandom.uuid)
end
Procedure.hidden.where(path: nil).each do |p|
p.update_column(:path, SecureRandom.uuid)
end
# Update task as completed. If you remove the line below, the task will
# run with every deploy (or every time you call after_party:run).
AfterParty::TaskRecord.create version: '20190704133852'
end
end

View file

@ -1,28 +0,0 @@
namespace :after_party do
desc 'Deployment task: migrate_geo_area_data'
task migrate_geo_area_data: :environment do
rake_puts "Running deploy task 'migrate_geo_area_data'"
progress = ProgressReport.new(Champs::CarteChamp.count)
Champs::CarteChamp.includes(:geo_areas).find_each do |champ|
geo_area = champ.geo_areas.find(&:selection_utilisateur?)
geo_json = champ.geo_json_from_value
if geo_area.blank? && geo_json.present?
GeoArea.create(
champ: champ,
geometry: geo_json,
source: GeoArea.sources.fetch(:selection_utilisateur)
)
progress.inc
end
end
progress.finish
# Update task as completed. If you remove the line below, the task will
# run with every deploy (or every time you call after_party:run).
AfterParty::TaskRecord.create version: '20190731152733'
end
end

View file

@ -1,33 +0,0 @@
namespace :after_party do
desc 'Deployment task: migrate_flipflop_to_flipper'
task migrate_flipflop_to_flipper: :environment do
rake_puts "Running deploy task 'migrate_flipflop_to_flipper'"
Instructeur.includes(:user).find_each do |instructeur|
if instructeur.features['download_as_zip_enabled']
pp "enable :instructeur_download_as_zip for #{instructeur.user.email}"
Flipper.enable_actor(:instructeur_download_as_zip, instructeur.user)
end
if instructeur.features['bypass_email_login_token']
pp "enable :instructeur_bypass_email_login_token for #{instructeur.user.email}"
Flipper.enable_actor(:instructeur_bypass_email_login_token, instructeur.user)
end
end
Administrateur.includes(:user).find_each do |administrateur|
if administrateur.features['web_hook']
pp "enable :administrateur_web_hook for #{administrateur.user.email}"
Flipper.enable_actor(:administrateur_web_hook, administrateur.user)
end
if administrateur.features['champ_integer_number']
pp "enable :administrateur_champ_integer_number for #{administrateur.user.email}"
Flipper.enable_actor(:administrateur_champ_integer_number, administrateur.user)
end
end
# Update task as completed. If you remove the line below, the task will
# run with every deploy (or every time you call after_party:run).
AfterParty::TaskRecord.create version: '20190829065022'
end
end

View file

@ -1,16 +0,0 @@
namespace :after_party do
desc 'Deployment task: backfill_daily_email_notification_columns'
task backfill_daily_email_notification_columns: :environment do
puts "Running deploy task 'backfill_daily_email_notification_columns'"
AssignTo.find_each do |assign_to|
columns_to_update = {}
if assign_to.email_notifications_enabled != assign_to.daily_email_notifications_enabled
columns_to_update[:daily_email_notifications_enabled] = assign_to.email_notifications_enabled
end
assign_to.update_columns(columns_to_update) unless columns_to_update.empty?
end
# Update task as completed. If you remove the line below, the task will
# run with every deploy (or every time you call after_party:run).
AfterParty::TaskRecord.create version: '20200220142710'
end # task :backfill_daily_email_notification_columns
end # namespace :after_party

View file

@ -164,6 +164,7 @@ describe ApplicationController, type: :controller do
allow(@controller).to receive(:instructeur_signed_in?).and_return(instructeur_signed_in)
allow(@controller).to receive(:sensitive_path).and_return(sensitive_path)
allow(@controller).to receive(:send_login_token_or_bufferize)
allow(@controller).to receive(:get_stored_location_for).and_return(nil)
allow(@controller).to receive(:store_location_for)
allow(IPService).to receive(:ip_trusted?).and_return(ip_trusted)
end

View file

@ -75,7 +75,7 @@ describe Champs::CarteController, type: :controller do
allow_any_instance_of(ApiCarto::QuartiersPrioritairesAdapter)
.to receive(:results)
.and_raise(RestClient::ResourceNotFound)
.and_raise(ApiCarto::API::ResourceNotFound)
post :show, params: params, format: 'js'
end

View file

@ -59,7 +59,7 @@ describe Champs::SiretController, type: :controller do
let(:siret) { '82161143100015' }
before do
allow(controller).to receive(:find_etablissement_with_siret).and_raise(RestClient::RequestFailed)
allow(controller).to receive(:find_etablissement_with_siret).and_raise(ApiEntreprise::API::RequestFailed)
end
subject! { get :show, params: params, format: 'js' }

View file

@ -29,6 +29,10 @@ FactoryBot.define do
create(:exercice, etablissement: etablissement)
end
end
trait :non_diffusable do
diffusable_commercialement { false }
end
end
trait :is_association do

View file

@ -14,7 +14,7 @@ FactoryBot.define do
path { SecureRandom.uuid }
transient do
administrateur {}
administrateur { }
instructeurs { [] }
end

View file

@ -110,4 +110,16 @@ feature 'Creating a new dossier:' do
end
end
end
context 'when the user is not signed in' do
let(:instructeur) { create(:instructeur) }
let(:procedure) { create(:procedure, :published) }
scenario 'the user is an instructeur with untrusted device' do
visit commencer_path(path: procedure.path)
click_on "Jai déjà un compte"
sign_in_with(instructeur.email, instructeur.user.password, true)
expect(page).to have_current_path(commencer_path(path: procedure.path))
end
end
end

View file

@ -26,7 +26,7 @@
"code": null,
"value": null
},
"diffusable_commercialement": null,
"diffusable_commercialement": true,
"adresse": {
"l1": "OCTO TECHNOLOGY",
"l2": null,

View file

@ -0,0 +1,49 @@
{
"etablissement": {
"siege_social": true,
"siret": "41816609600051",
"naf": "6202A",
"libelle_naf": "Conseil en systèmes et logiciels informatiques",
"date_mise_a_jour": 1449183600,
"tranche_effectif_salarie_etablissement": {
"de": 200,
"a": 249,
"code": "31",
"date_reference": "2014",
"intitule": "200 à 249 salariés"
},
"date_creation_etablissement": 1108594800,
"enseigne": null,
"region_implantation": {
"code": "11",
"value": "Île-de-France"
},
"commune_implantation": {
"code": "75108",
"value": "PARIS 8"
},
"pays_implantation": {
"code": null,
"value": null
},
"diffusable_commercialement": false,
"adresse": {
"l1": "OCTO TECHNOLOGY",
"l2": null,
"l3": null,
"l4": "50 AVENUE DES CHAMPS ELYSEES",
"l5": null,
"l6": "75008 PARIS",
"l7": "FRANCE",
"numero_voie": "50",
"type_voie": "AV",
"nom_voie": "DES CHAMPS ELYSEES",
"complement_adresse": "complement_adresse",
"code_postal": "75008",
"localite": "PARIS 8",
"code_insee_localite": "75108",
"cedex": null
}
},
"gateway_error": false
}

View file

@ -15,8 +15,8 @@ describe ApiCarto::API do
let(:status) { 404 }
let(:body) { '' }
it 'raises RestClient::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound)
it 'raises ApiCarto::API::ResourceNotFound' do
expect { subject }.to raise_error(ApiCarto::API::ResourceNotFound)
end
end
@ -25,8 +25,8 @@ describe ApiCarto::API do
let(:status) { 500 }
let(:body) { 'toto' }
it 'raises RestClient::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound)
it 'raises ApiCarto::API::ResourceNotFound' do
expect { subject }.to raise_error(ApiCarto::API::ResourceNotFound)
end
end
@ -63,8 +63,8 @@ describe ApiCarto::API do
let(:status) { 404 }
let(:body) { '' }
it 'raises RestClient::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound)
it 'raises ApiCarto::API::ResourceNotFound' do
expect { subject }.to raise_error(ApiCarto::API::ResourceNotFound)
end
end

View file

@ -60,6 +60,6 @@ describe ApiCarto::CadastreAdapter do
let(:status) { 404 }
let(:body) { '' }
it { expect { subject }.to raise_error(RestClient::ResourceNotFound) }
it { expect { subject }.to raise_error(ApiCarto::API::ResourceNotFound) }
end
end

View file

@ -33,6 +33,6 @@ describe ApiCarto::QuartiersPrioritairesAdapter do
let(:status) { 404 }
let(:body) { '' }
it { expect { subject }.to raise_error(RestClient::ResourceNotFound) }
it { expect { subject }.to raise_error(ApiCarto::API::ResourceNotFound) }
end
end

View file

@ -16,8 +16,8 @@ describe ApiEntreprise::API do
let(:status) { 502 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_unavailable.json') }
it 'raises RestClient::RequestFailed' do
expect { subject }.to raise_error(RestClient::RequestFailed)
it 'raises ApiEntreprise::API::RequestFailed' do
expect { subject }.to raise_error(ApiEntreprise::API::RequestFailed)
end
end
@ -26,8 +26,8 @@ describe ApiEntreprise::API do
let(:status) { 404 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_not_found.json') }
it 'raises RestClient::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound)
it 'raises ApiEntreprise::API::ResourceNotFound' do
expect { subject }.to raise_error(ApiEntreprise::API::ResourceNotFound)
end
end
@ -36,8 +36,8 @@ describe ApiEntreprise::API do
let(:status) { 403 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_private.json') }
it 'raises RestClient::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound)
it 'raises ApiEntreprise::API::ResourceNotFound' do
expect { subject }.to raise_error(ApiEntreprise::API::ResourceNotFound)
end
end
@ -55,7 +55,7 @@ describe ApiEntreprise::API do
describe '.etablissement' do
subject { described_class.etablissement(siret, procedure_id) }
before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/)
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*non_diffusables=true&.*token=/)
.to_return(status: status, body: body)
end
@ -64,8 +64,8 @@ describe ApiEntreprise::API do
let(:status) { 404 }
let(:body) { '' }
it 'raises RestClient::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound)
it 'raises ApiEntreprise::API::ResourceNotFound' do
expect { subject }.to raise_error(ApiEntreprise::API::ResourceNotFound)
end
end
@ -93,8 +93,8 @@ describe ApiEntreprise::API do
let(:status) { 404 }
let(:body) { '' }
it 'raises RestClient::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound)
it 'raises ApiEntreprise::API::ResourceNotFound' do
expect { subject }.to raise_error(ApiEntreprise::API::ResourceNotFound)
end
end
@ -105,7 +105,7 @@ describe ApiEntreprise::API do
let(:status) { 200 }
let(:body) { File.read('spec/fixtures/files/api_entreprise/exercices.json') }
it 'raises RestClient::Unauthorized' do
it 'success' do
expect(subject).to eq(JSON.parse(body, symbolize_names: true))
end
end
@ -124,8 +124,8 @@ describe ApiEntreprise::API do
let(:status) { 404 }
let(:body) { '' }
it 'raises RestClient::ResourceNotFound' do
expect { subject }.to raise_error(RestClient::ResourceNotFound)
it 'raises ApiEntreprise::API::ResourceNotFound' do
expect { subject }.to raise_error(ApiEntreprise::API::ResourceNotFound)
end
end

View file

@ -84,7 +84,7 @@ describe ApiEntreprise::EntrepriseAdapter do
let(:status) { 502 }
it 'raises an exception' do
expect { subject }.to raise_error(RestClient::RequestFailed)
expect { subject }.to raise_error(ApiEntreprise::API::RequestFailed)
end
end
end

View file

@ -3,7 +3,7 @@ require 'spec_helper'
describe ApiEntreprise::EtablissementAdapter do
let(:procedure_id) { 33 }
context 'SIRET valide' do
context 'SIRET valide avec infos diffusables' do
let(:siret) { '41816609600051' }
subject { described_class.new(siret, procedure_id).to_params }
@ -33,6 +33,10 @@ describe ApiEntreprise::EtablissementAdapter do
expect(subject[:libelle_naf]).to eq('Conseil en systèmes et logiciels informatiques')
end
it 'L\'entreprise contient bien un diffusable_commercialement qui vaut true' do
expect(subject[:diffusable_commercialement]).to eq(true)
end
context 'Concaténation lignes adresse' do
it 'L\'entreprise contient bien une adresse sur plusieurs lignes' do
expect(subject[:adresse]).to eq("OCTO TECHNOLOGY\r\n50 AVENUE DES CHAMPS ELYSEES\r\n75008 PARIS\r\nFRANCE")
@ -70,6 +74,20 @@ describe ApiEntreprise::EtablissementAdapter do
end
end
context 'SIRET valide avec infos non diffusables' do
let(:siret) { '41816609600051' }
subject { described_class.new(siret, procedure_id).to_params }
before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/etablissements\/#{siret}?.*token=/)
.to_return(body: File.read('spec/fixtures/files/api_entreprise/etablissements_private.json', status: 200))
end
it 'L\'entreprise contient bien un diffusable_commercialement qui vaut false' do
expect(subject[:diffusable_commercialement]).to eq(false)
end
end
context 'when siret is not found' do
let(:bad_siret) { 11_111_111_111_111 }
subject { described_class.new(bad_siret, 12).to_params }

View file

@ -59,6 +59,14 @@ describe Administrateur, type: :model do
expect(Administrateur.find_by(id: administrateur.id)).to be_nil
expect(service.reload.administrateur).to eq(autre_administrateur)
end
it "delete service if not associated to procedures" do
service_without_procedure = create(:service, administrateur: administrateur)
administrateur.delete_and_transfer_services
expect(Service.find_by(id: service_without_procedure.id)).to be_nil
expect(Administrateur.find_by(id: administrateur.id)).to be_nil
end
end
# describe '#password_complexity' do

View file

@ -401,6 +401,8 @@ describe Instructeur, type: :model do
expect(instructeur.email_notification_data).to eq([
{
nb_en_construction: 1,
nb_en_instruction: 0,
nb_accepted: 0,
nb_notification: 0,
procedure_id: procedure_to_assign.id,
procedure_libelle: procedure_to_assign.libelle
@ -420,6 +422,8 @@ describe Instructeur, type: :model do
expect(instructeur.email_notification_data).to eq([
{
nb_en_construction: 0,
nb_en_instruction: 0,
nb_accepted: 0,
nb_notification: 3,
procedure_id: procedure_to_assign.id,
procedure_libelle: procedure_to_assign.libelle
@ -428,6 +432,75 @@ describe Instructeur, type: :model do
end
end
context 'when a declarated dossier in instruction exists' do
let!(:dossier) { create(:dossier, procedure: procedure_to_assign, state: Dossier.states.fetch(:en_construction)) }
before do
procedure_to_assign.update(declarative_with_state: "en_instruction")
DeclarativeProceduresJob.new.perform
dossier.reload
end
it { expect(procedure_to_assign.declarative_with_state).to eq("en_instruction") }
it { expect(dossier.state).to eq("en_instruction") }
it do
expect(instructeur.email_notification_data).to eq([
{
nb_en_construction: 0,
nb_en_instruction: 1,
nb_accepted: 0,
nb_notification: 0,
procedure_id: procedure_to_assign.id,
procedure_libelle: procedure_to_assign.libelle
}
])
end
end
context 'when a declarated dossier in accepte processed at today exists' do
let!(:dossier) { create(:dossier, procedure: procedure_to_assign, state: Dossier.states.fetch(:en_construction)) }
before do
procedure_to_assign.update(declarative_with_state: "accepte")
DeclarativeProceduresJob.new.perform
dossier.reload
end
it { expect(procedure_to_assign.declarative_with_state).to eq("accepte") }
it { expect(dossier.state).to eq("accepte") }
it do
expect(instructeur.email_notification_data).to eq([])
end
end
context 'when a declarated dossier in accepte processed at yesterday exists' do
let!(:dossier) { create(:dossier, procedure: procedure_to_assign, state: Dossier.states.fetch(:en_construction)) }
before do
procedure_to_assign.update(declarative_with_state: "accepte")
DeclarativeProceduresJob.new.perform
dossier.update(processed_at: Time.zone.yesterday.beginning_of_day)
dossier.reload
end
it { expect(procedure_to_assign.declarative_with_state).to eq("accepte") }
it { expect(dossier.state).to eq("accepte") }
it do
expect(instructeur.email_notification_data).to eq([
{
nb_en_construction: 0,
nb_en_instruction: 0,
nb_accepted: 1,
nb_notification: 0,
procedure_id: procedure_to_assign.id,
procedure_libelle: procedure_to_assign.libelle
}
])
end
end
context 'otherwise' do
it { expect(instructeur.email_notification_data).to eq([]) }
end

View file

@ -66,8 +66,8 @@ describe ApiEntrepriseService do
let(:entreprises_status) { 400 }
let(:entreprises_body) { '' }
it 'should raise RestClient::RequestFailed' do
expect { result }.to raise_error(RestClient::RequestFailed)
it 'should raise ApiEntreprise::API::RequestFailed' do
expect { result }.to raise_error(ApiEntreprise::API::RequestFailed)
end
end
@ -75,8 +75,8 @@ describe ApiEntrepriseService do
let(:etablissements_status) { 400 }
let(:etablissements_body) { '' }
it 'should raise RestClient::RequestFailed' do
expect { result }.to raise_error(RestClient::RequestFailed)
it 'should raise ApiEntreprise::API::RequestFailed' do
expect { result }.to raise_error(ApiEntreprise::API::RequestFailed)
end
end

View file

@ -47,6 +47,49 @@ describe NotificationService do
end
end
context 'when a declarative dossier in instruction exists on this procedure' do
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
before do
procedure.update(declarative_with_state: "en_instruction")
DeclarativeProceduresJob.new.perform
dossier.reload
end
it do
subject
expect(InstructeurMailer).to have_received(:send_notifications)
end
end
context 'when a declarative dossier in accepte on yesterday exists on this procedure' do
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
before do
procedure.update(declarative_with_state: "accepte")
DeclarativeProceduresJob.new.perform
dossier.update(processed_at: Time.zone.yesterday.beginning_of_day)
dossier.reload
end
it do
subject
expect(InstructeurMailer).to have_received(:send_notifications)
end
end
context 'when a declarative dossier in accepte on today exists on this procedure' do
let!(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
before do
procedure.update(declarative_with_state: "accepte")
DeclarativeProceduresJob.new.perform
dossier.reload
end
it do
subject
expect(InstructeurMailer).not_to have_received(:send_notifications)
end
end
context 'when there is a notification on this procedure' do
before do
allow_any_instance_of(Instructeur).to receive(:notifications_for_procedure)

View file

@ -16,6 +16,8 @@ describe 'instructeur_mailer/send_notifications.html.haml', type: :view do
procedure_libelle: 'une superbe démarche',
procedure_id: 213,
nb_en_construction: 1,
nb_en_instruction: 0,
nb_accepted: 0,
nb_notification: 0
}
]
@ -27,6 +29,50 @@ describe 'instructeur_mailer/send_notifications.html.haml', type: :view do
it { expect(rendered).not_to have_text('notification') }
end
context 'when there is one declarated dossier in instruction' do
let(:data) do
[
{
procedure_libelle: 'une superbe démarche',
procedure_id: 213,
nb_en_construction: 0,
nb_en_instruction: 1,
nb_accepted: 0,
nb_notification: 0
}
]
end
it { expect(rendered).to have_link('une superbe démarche', href: procedure_url(213)) }
it { expect(rendered).to have_text('une superbe démarche') }
it { expect(rendered).to have_text('1 dossier') }
it { expect(rendered).not_to have_text('notification') }
it { expect(rendered).not_to have_text('construction') }
it { expect(rendered).not_to have_text('accepte') }
end
context 'when there is one declarated dossier in accepte' do
let(:data) do
[
{
procedure_libelle: 'une superbe démarche',
procedure_id: 213,
nb_en_construction: 0,
nb_en_instruction: 0,
nb_accepted: 1,
nb_notification: 0
}
]
end
it { expect(rendered).to have_link('une superbe démarche', href: procedure_url(213)) }
it { expect(rendered).to have_text('une superbe démarche') }
it { expect(rendered).to have_text('1 dossier') }
it { expect(rendered).not_to have_text('notification') }
it { expect(rendered).not_to have_text('construction') }
it { expect(rendered).not_to have_text('instruction') }
end
context 'when there is one notification' do
let(:data) do
[
@ -34,6 +80,8 @@ describe 'instructeur_mailer/send_notifications.html.haml', type: :view do
procedure_libelle: 'une superbe démarche',
procedure_id: 213,
nb_en_construction: 0,
nb_en_instruction: 0,
nb_accepted: 0,
nb_notification: 1
}
]

View file

@ -12,4 +12,13 @@ describe 'shared/dossiers/identite_entreprise.html.haml', type: :view do
end
end
end
context "for an entreprise with private infos" do
let(:etablissement) { create(:etablissement, :non_diffusable) }
it "displays only public infos" do
expect(rendered).to have_text(etablissement.entreprise_raison_sociale)
expect(rendered).not_to have_text(etablissement.entreprise.forme_juridique)
end
end
end

View file

@ -29,6 +29,14 @@ describe 'users/dossiers/etablissement.html.haml', type: :view do
end
end
context 'etablissement avec infos non diffusables' do
let(:etablissement) { create(:etablissement, :with_exercices, :non_diffusable) }
it "affiche uniquement le nom de l'établissement si infos non diffusables" do
expect(rendered).to have_text(etablissement.entreprise_raison_sociale)
expect(rendered).not_to have_text(etablissement.entreprise.forme_juridique)
end
end
it 'prépare le footer' do
expect(footer).to have_selector('footer')
end

View file

@ -1254,9 +1254,9 @@ acorn-walk@^6.1.1:
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
acorn@^6.0.7, acorn@^6.2.1:
version "6.4.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784"
integrity sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==
version "6.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474"
integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==
acorn@^7.1.0:
version "7.1.0"