Merge pull request #3634 from betagouv/dev

2019-03-18-01
This commit is contained in:
LeSim 2019-03-18 13:47:22 +01:00 committed by GitHub
commit 2908bd146f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 130 additions and 230 deletions

View file

@ -90,6 +90,7 @@ group :development do
gem 'rubocop', require: false gem 'rubocop', require: false
gem 'rubocop-rspec-focused', require: false gem 'rubocop-rspec-focused', require: false
gem 'scss_lint', require: false gem 'scss_lint', require: false
gem 'web-console'
gem 'xray-rails' gem 'xray-rails'
end end

View file

@ -101,6 +101,7 @@ GEM
axlsx (>= 2.0, < 4) axlsx (>= 2.0, < 4)
bcrypt (3.1.12) bcrypt (3.1.12)
bindata (2.4.4) bindata (2.4.4)
bindex (0.5.0)
bootstrap-sass (3.4.1) bootstrap-sass (3.4.1)
autoprefixer-rails (>= 5.2.1) autoprefixer-rails (>= 5.2.1)
sassc (>= 2.0.0) sassc (>= 2.0.0)
@ -620,6 +621,11 @@ GEM
vcr (4.0.0) vcr (4.0.0)
warden (1.2.8) warden (1.2.8)
rack (>= 2.0.6) rack (>= 2.0.6)
web-console (3.7.0)
actionview (>= 5.0)
activemodel (>= 5.0)
bindex (>= 0.4.0)
railties (>= 5.0)
webfinger (1.1.0) webfinger (1.1.0)
activesupport activesupport
httpclient (>= 2.4) httpclient (>= 2.4)
@ -734,6 +740,7 @@ DEPENDENCIES
typhoeus typhoeus
vcr vcr
warden warden
web-console
webmock webmock
webpacker (>= 4.0.x) webpacker (>= 4.0.x)
xray-rails xray-rails

View file

@ -3,7 +3,7 @@ $light-blue: #1C7EC9;
$lighter-blue: #C3D9FF; $lighter-blue: #C3D9FF;
$black: #333333; $black: #333333;
$white: #FFFFFF; $white: #FFFFFF;
$grey: #999999; $grey: #888888;
$light-grey: #F8F8F8; $light-grey: #F8F8F8;
$border-grey: #CCCCCC; $border-grey: #CCCCCC;
$dark-red: #A10005; $dark-red: #A10005;

View file

@ -7,9 +7,9 @@ class ApiEntreprise::EntrepriseAdapter < ApiEntreprise::Adapter
end end
def process_params def process_params
params = data_source[:entreprise].slice(*attr_to_fetch) params = data_source[:entreprise]&.slice(*attr_to_fetch)
if valid_params?(params) if params.present? && valid_params?(params)
params[:date_creation] = Time.zone.at(params[:date_creation]).to_datetime params[:date_creation] = Time.zone.at(params[:date_creation]).to_datetime
params.transform_keys { |k| :"entreprise_#{k}" } params.transform_keys { |k| :"entreprise_#{k}" }
else else

View file

@ -23,16 +23,6 @@
%h4 Où les usagers trouveront-ils le lien vers la démarche ? %h4 Où les usagers trouveront-ils le lien vers la démarche ?
= f.text_field :lien_site_web, class: 'form-control', placeholder: 'https://exemple.gouv.fr/ma_demarche' = f.text_field :lien_site_web, class: 'form-control', placeholder: 'https://exemple.gouv.fr/ma_demarche'
- if Flipflop.web_hook?
.form-group
%h4 Lien de rappel HTTP (webhook)
= f.text_field :web_hook_url, class: 'form-control', placeholder: 'https://callback.exemple.fr/'
%p.help-block
%i.fa.fa-info-circle
Vous pouvez définir un lien de rappel HTTP (aussi appelé webhook) pour notifier un service tiers du changement de l'état dun dossier de cette démarche sur demarches-simplifiees.fr.
= link_to("Consulter la documentation du webhook", WEBHOOK_DOC_URL, target: "_blank", rel: "noopener")
\.
.form-group .form-group
%h4 Cadre juridique * %h4 Cadre juridique *
%p Texte qui justifie le droit de collecter les données demandées dans votre démarche auprès des usagers, par exemple : %p Texte qui justifie le droit de collecter les données demandées dans votre démarche auprès des usagers, par exemple :
@ -131,9 +121,19 @@
.col-md-6 .col-md-6
%h4 Options avancées %h4 Options avancées
%label{ for: :auto_archive_on } Archivage automatique le - if Flipflop.web_hook?
= f.date_field :auto_archive_on, id: 'auto_archive_on', value: @procedure.auto_archive_on %label{ for: :web_hook_url } Lien de rappel HTTP (webhook)
(à 00h00) = f.text_field :web_hook_url, class: 'form-control', placeholder: 'https://callback.exemple.fr/'
%p.help-block %p.help-block
%i.fa.fa-info-circle %i.fa.fa-info-circle
L'archivage automatique de la démarche entrainera le passage en instruction de tous les dossiers en construction. Vous pouvez définir un lien de rappel HTTP (aussi appelé webhook) pour notifier un service tiers du changement de l'état dun dossier de cette démarche sur demarches-simplifiees.fr.
= link_to("Consulter la documentation du webhook", WEBHOOK_DOC_URL, target: "_blank", rel: "noopener")
\.
%label{ for: :auto_archive_on } Clôture automatique le
= f.date_field :auto_archive_on, id: 'auto_archive_on', value: @procedure.auto_archive_on
(à 00h01)
%p.help-block
%i.fa.fa-info-circle
La clôture automatique suspend la publication de la démarche et entraîne le passage de tous les dossiers "en construction"
(c'est à dire ceux qui ont été déposés), au statut "en instruction", ce qui ne permet plus aux usagers de les modifier.

View file

@ -70,7 +70,7 @@
= text_field_tag :address, nil, required: true = text_field_tag :address, nil, required: true
= label_tag :nb_of_procedures do = label_tag :nb_of_procedures do
Combien de démarches souhaitez-vous dématerialiser ? Combien de démarches souhaitez-vous dématérialiser ?
%span.mandatory * %span.mandatory *
= select_tag :nb_of_procedures, = select_tag :nb_of_procedures,
options_for_select(nb_of_procedures_options), options_for_select(nb_of_procedures_options),
@ -78,7 +78,7 @@
required: true required: true
= label_tag :deadline do = label_tag :deadline do
À quelle échance voudriez-vous dématerialiser ? À quelle échéance voudriez-vous dématérialiser ?
%span.mandatory * %span.mandatory *
= select_tag :deadline, = select_tag :deadline,
options_for_select(deadline_options), options_for_select(deadline_options),

View file

@ -5,7 +5,7 @@
%h1.new-h1 Accessibilité %h1.new-h1 Accessibilité
%p.new-p %p.new-p
Nous travaillons à améliorer le niveau d'accessibilité du site et sa conformité avec les normes en la matière. Une première version optimisée pour la partie « Usager » du site ainsi qu'une déclaration de conformité <a href="https://references.modernisation.gouv.fr/rgaa-accessibilite/" target="_blank" rel="noopener">RGAA</a> seront disponibles en août 2018. Nous travaillons continuellement à améliorer le niveau d'accessibilité du site et sa conformité avec les normes en la matière.
%h2.new-h2 Signaler un dysfonctionnement %h2.new-h2 Signaler un dysfonctionnement
%p.new-p %p.new-p

View file

@ -104,45 +104,6 @@
.clearfix .clearfix
- if administration_signed_in? - if administration_signed_in?
%h2.new-h2 Avis
.stat-cards
.stat-card.stat-card-half.pull-left
%span.stat-card-title Taux d'utilisation des avis
= line_chart @avis_usage, ytitle: 'dossiers avec avis / total dossiers', xtitle: 'semaines'
.stat-card.stat-card-half.pull-left
%span.stat-card-title Temps de réponse moyen par avis
= line_chart @avis_average_answer_time, ytitle: 'jours', xtitle: 'semaines'
.stat-card.stat-card-half.pull-left
%span.stat-card-title Pourcentage d'avis rempli
= line_chart @avis_answer_percentages, ytitle: 'avis avec réponse / total avis', xtitle: 'semaines'
.clearfix
%h2.new-h2 Encart motivation
.stat-cards
.stat-card.stat-card-half.pull-left
%span.stat-card-title Taux d'utilisation des motivations (par dossier)
= column_chart @motivation_usage_dossier, ytitle: 'dossiers avec motivation / total dossiers', xtitle: 'semaines'
.stat-card.stat-card-half.pull-left
%span.stat-card-title Taux d'utilisation des motivations (par démarche)
= column_chart @motivation_usage_procedure, ytitle: 'démarches avec motivation / total démarches', xtitle: 'semaines'
.clearfix
%h2.new-h2 Utilisation de la bibliothèque
.stat-cards
.stat-card.stat-card-half.pull-left
%span.stat-card-title Taux d'utilisation de la bibliothèque
= column_chart @cloned_from_library_procedures_ratio, ytitle: 'démarches clonées / total démarches', xtitle: 'semaines'
.clearfix
%h2.new-h2 Téléchargement %h2.new-h2 Téléchargement
= link_to "Télécharger les statistiques (CSV)", stats_download_path(format: :csv), class: 'button secondary' = link_to "Télécharger les statistiques (CSV)", stats_download_path(format: :csv), class: 'button secondary'

View file

@ -15,42 +15,43 @@ port ENV.fetch("PORT") { 3000 }
# #
environment ENV.fetch("RAILS_ENV") { "development" } environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the number of `workers` to boot in clustered mode. if ENV.fetch("RAILS_ENV") == "production"
# Workers are forked webserver processes. If using threads and workers together # Specifies the number of `workers` to boot in clustered mode.
# the concurrency of the application would be max `threads` * `workers`. # Workers are forked webserver processes. If using threads and workers together
# Workers do not work on JRuby or Windows (both of which do not support # the concurrency of the application would be max `threads` * `workers`.
# processes). # Workers do not work on JRuby or Windows (both of which do not support
# # processes).
# workers ENV.fetch("WEB_CONCURRENCY") { 2 } #
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
# Use the `preload_app!` method when specifying a `workers` number. # Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code # This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write # before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory. If you use this option # process behavior so workers use less memory. If you use this option
# you need to make sure to reconnect any threads in the `on_worker_boot` # you need to make sure to reconnect any threads in the `on_worker_boot`
# block. # block.
# #
# preload_app! preload_app!
# If you are preloading your application and using Active Record, it's # If you are preloading your application and using Active Record, it's
# recommended that you close any connections to the database before workers # recommended that you close any connections to the database before workers
# are forked to prevent connection leakage. # are forked to prevent connection leakage.
# #
# before_fork do before_fork do
# ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord) ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord)
# end end
# The code in the `on_worker_boot` will be called if you are using # The code in the `on_worker_boot` will be called if you are using
# clustered mode by specifying a number of `workers`. After each worker # clustered mode by specifying a number of `workers`. After each worker
# process is booted, this block will be run. If you are using the `preload_app!` # process is booted, this block will be run. If you are using the `preload_app!`
# option, you will want to use this block to reconnect to any threads # option, you will want to use this block to reconnect to any threads
# or connections that may have been created at application boot, as Ruby # or connections that may have been created at application boot, as Ruby
# cannot share connections between processes. # cannot share connections between processes.
# #
# on_worker_boot do on_worker_boot do
# ActiveRecord::Base.establish_connection if defined?(ActiveRecord) ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
# end end
# end
# Allow puma to be restarted by `rails restart` command. # Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart plugin :tmp_restart

View file

@ -262,94 +262,4 @@ describe StatsController, type: :controller do
it { expect(subject).to match([[3.weeks.ago.to_i, 0], [2.weeks.ago.to_i, 0], [1.week.ago.to_i, 33.33]]) } it { expect(subject).to match([[3.weeks.ago.to_i, 0], [2.weeks.ago.to_i, 0], [1.week.ago.to_i, 33.33]]) }
end end
describe "#avis_average_answer_time" do
before do
Timecop.freeze(Time.zone.local(2016, 10, 2))
# 1 week ago
create(:avis, answer: "voila ma réponse", created_at: 1.week.ago + 1.day, updated_at: 1.week.ago + 2.days) # 1 day
create(:avis, created_at: 1.week.ago + 2.days)
# 2 weeks ago
create(:avis, answer: "voila ma réponse", created_at: 2.weeks.ago + 1.day, updated_at: 2.weeks.ago + 2.days) # 1 day
create(:avis, answer: "voila ma réponse2", created_at: 2.weeks.ago + 3.days, updated_at: 1.week.ago + 6.days) # 10 days
create(:avis, answer: "voila ma réponse2", created_at: 2.weeks.ago + 2.days, updated_at: 1.week.ago + 6.days) # 11 days
create(:avis, created_at: 2.weeks.ago + 1.day, updated_at: 2.weeks.ago + 2.days)
# 3 weeks ago
create(:avis, answer: "voila ma réponse2", created_at: 3.weeks.ago + 1.day, updated_at: 3.weeks.ago + 2.days) # 1 day
create(:avis, answer: "voila ma réponse2", created_at: 3.weeks.ago + 1.day, updated_at: 1.week.ago + 5.days) # 18 day
end
after { Timecop.return }
subject { StatsController.new.send(:avis_average_answer_time) }
it { expect(subject.count).to eq(3) }
it { is_expected.to include [1.week.ago.to_i, 1.0] }
it { is_expected.to include [2.weeks.ago.to_i, 7.33] }
it { is_expected.to include [3.weeks.ago.to_i, 9.5] }
end
describe '#avis_answer_percentages' do
let!(:avis) { create(:avis, created_at: 2.days.ago) }
let!(:avis2) { create(:avis, answer: 'answer', created_at: 2.days.ago) }
let!(:avis3) { create(:avis, answer: 'answer', created_at: 2.days.ago) }
subject { StatsController.new.send(:avis_answer_percentages) }
before { Timecop.freeze(Time.zone.now) }
after { Timecop.return }
it { is_expected.to match [[3.weeks.ago.to_i, 0], [2.weeks.ago.to_i, 0], [1.week.ago.to_i, 66.67]] }
end
describe '#motivation_usage_dossier' do
let!(:dossier) { create(:dossier, processed_at: 1.week.ago, motivation: "Motivation") }
let!(:dossier2) { create(:dossier, processed_at: 1.week.ago) }
let!(:dossier3) { create(:dossier, processed_at: 1.week.ago) }
before { Timecop.freeze(Time.zone.now) }
after { Timecop.return }
subject { StatsController.new.send(:motivation_usage_dossier) }
it { expect(subject).to match([[I18n.l(3.weeks.ago.end_of_week, format: '%d/%m/%Y'), 0], [I18n.l(2.weeks.ago.end_of_week, format: '%d/%m/%Y'), 0], [I18n.l(1.week.ago.end_of_week, format: '%d/%m/%Y'), 33.33]]) }
end
describe '#motivation_usage_procedure' do
let!(:dossier) { create(:dossier, processed_at: 1.week.ago, motivation: "Motivation") }
let!(:dossier1) { create(:dossier, processed_at: 1.week.ago, motivation: "Motivation", procedure: dossier.procedure) }
let!(:dossier2) { create(:dossier, processed_at: 1.week.ago) }
let!(:dossier3) { create(:dossier, processed_at: 1.week.ago) }
before { Timecop.freeze(Time.zone.now) }
after { Timecop.return }
subject { StatsController.new.send(:motivation_usage_procedure) }
it { expect(subject).to match([[I18n.l(3.weeks.ago.end_of_week, format: '%d/%m/%Y'), 0], [I18n.l(2.weeks.ago.end_of_week, format: '%d/%m/%Y'), 0], [I18n.l(1.week.ago.end_of_week, format: '%d/%m/%Y'), 33.33]]) }
end
describe "#cloned_from_library_procedures_ratio" do
let!(:procedure1) { create(:procedure, created_at: 3.weeks.ago) }
let!(:procedure2) { create(:procedure, created_at: 2.weeks.ago) }
let!(:procedure3) { create(:procedure, created_at: 2.weeks.ago, cloned_from_library: true) }
before { Timecop.freeze(Time.zone.now) }
after { Timecop.return }
subject { StatsController.new.send(:cloned_from_library_procedures_ratio) }
let(:result) do
[
[I18n.l(3.weeks.ago.end_of_week, format: '%d/%m/%Y'), 0],
[I18n.l(2.weeks.ago.end_of_week, format: '%d/%m/%Y'), 50.0],
[I18n.l(1.week.ago.end_of_week, format: '%d/%m/%Y'), 0]
]
end
it { expect(subject).to match(result) }
end
end end

View file

@ -0,0 +1,6 @@
{
"errors": [
"Le siret ou siren indiqué n'existe pas, n'est pas connu ou ne comporte aucune information pour cet appel"
],
"gateway_error": true
}

View file

@ -8,9 +8,13 @@ describe ApiEntreprise::EntrepriseAdapter do
before do before do
stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=/) stub_request(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}?.*token=/)
.to_return(body: File.read('spec/fixtures/files/api_entreprise/entreprises.json', status: 200)) .to_return(body: body, status: status)
end end
context "when SIRET is OK" do
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises.json') }
let(:status) { 200 }
it '#to_params class est une Hash ?' do it '#to_params class est une Hash ?' do
expect(subject).to be_an_instance_of(Hash) expect(subject).to be_an_instance_of(Hash)
end end
@ -64,4 +68,14 @@ describe ApiEntreprise::EntrepriseAdapter do
expect(subject[:entreprise_prenom]).to eq('test_prenom') expect(subject[:entreprise_prenom]).to eq('test_prenom')
end end
end end
end
context "when SIRET is KO" do
let(:body) { File.read('spec/fixtures/files/api_entreprise/entreprises_not_found.json') }
let(:status) { 206 }
it '#to_params class est une Hash ?' do
expect(subject).to eq({})
end
end
end end