fix(carte): gracefully ignore invalid year and kind params
Empêche d'envoyer une date invalide à PG et polluer les logs.
This commit is contained in:
parent
40e952e8d2
commit
3d52601155
5 changed files with 31 additions and 29 deletions
|
@ -1,6 +1,13 @@
|
||||||
class CarteController < ApplicationController
|
class CarteController < ApplicationController
|
||||||
def show
|
def show
|
||||||
@map_filter = MapFilter.new(params)
|
@map_filter = MapFilter.new(params.fetch(:map_filter, {}).permit(:kind, :year))
|
||||||
|
@map_filter.validate
|
||||||
|
|
||||||
|
# Reset to default params in case of invalid params injection
|
||||||
|
@map_filter.kind = MapFilter.new.kind if @map_filter.errors.key?(:kind)
|
||||||
|
@map_filter.year = MapFilter.new.year if @map_filter.errors.key?(:year)
|
||||||
|
@map_filter.errors.clear
|
||||||
|
|
||||||
@map_filter.stats = stats
|
@map_filter.stats = stats
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,21 @@
|
||||||
class MapFilter
|
class MapFilter
|
||||||
# https://api.rubyonrails.org/v7.1.1/classes/ActiveModel/Errors.html
|
include ActiveModel::Model
|
||||||
|
include ActiveModel::Attributes
|
||||||
include ActiveModel::Conversion
|
|
||||||
extend ActiveModel::Translation
|
|
||||||
extend ActiveModel::Naming
|
|
||||||
|
|
||||||
LEGEND = {
|
LEGEND = {
|
||||||
nb_demarches: { 'nothing': -1, 'small': 20, 'medium': 50, 'large': 100, 'xlarge': 500 },
|
"nb_demarches" => { 'nothing': -1, 'small': 20, 'medium': 50, 'large': 100, 'xlarge': 500 },
|
||||||
nb_dossiers: { 'nothing': -1, 'small': 500, 'medium': 2000, 'large': 10000, 'xlarge': 50000 }
|
"nb_dossiers" => { 'nothing': -1, 'small': 500, 'medium': 2000, 'large': 10000, 'xlarge': 50000 }
|
||||||
}
|
}.freeze
|
||||||
|
|
||||||
|
YEARS_INTERVAL = 2018..Date.current.year
|
||||||
|
|
||||||
attr_accessor :stats
|
attr_accessor :stats
|
||||||
attr_reader :errors
|
|
||||||
|
|
||||||
def initialize(params)
|
attribute :year, :integer
|
||||||
@params = params[:map_filter]&.permit(:kind, :year) || {}
|
validates :year, numericality: { only_integer: true, greater_than_or_equal_to: YEARS_INTERVAL.begin, less_than_or_equal_to: YEARS_INTERVAL.end }
|
||||||
@errors = ActiveModel::Errors.new(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
def persisted?
|
attribute :kind, default: "nb_demarches"
|
||||||
false
|
validates :kind, inclusion: { in: LEGEND.keys }
|
||||||
end
|
|
||||||
|
|
||||||
def kind
|
|
||||||
@params[:kind]&.to_sym || :nb_demarches
|
|
||||||
end
|
|
||||||
|
|
||||||
def year
|
|
||||||
@params[:year].presence
|
|
||||||
end
|
|
||||||
|
|
||||||
def kind_buttons
|
def kind_buttons
|
||||||
LEGEND.keys.map do
|
LEGEND.keys.map do
|
||||||
|
@ -41,7 +28,7 @@ class MapFilter
|
||||||
end
|
end
|
||||||
|
|
||||||
def css_class_for_departement(departement)
|
def css_class_for_departement(departement)
|
||||||
if kind == :nb_demarches
|
if kind == "nb_demarches"
|
||||||
kind_legend_keys.reverse.find do
|
kind_legend_keys.reverse.find do
|
||||||
nb_demarches_for_departement(departement) > LEGEND[kind][_1]
|
nb_demarches_for_departement(departement) > LEGEND[kind][_1]
|
||||||
end
|
end
|
||||||
|
|
|
@ -249,7 +249,7 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
<div class="fr-select-group">
|
<div class="fr-select-group">
|
||||||
<%= map_form.label :year, class: 'fr-label' %>
|
<%= map_form.label :year, class: 'fr-label' %>
|
||||||
<%= map_form.select(:year, (2018..Date.current.year).to_a.reverse, { include_blank: t(:from_beginning, scope: 'activemodel.attributes.map_filter') }, { class: "fr-select" }) %>
|
<%= map_form.select(:year, MapFilter::YEARS_INTERVAL.to_a.reverse, { include_blank: t(:from_beginning, scope: 'activemodel.attributes.map_filter') }, { class: "fr-select" }) %>
|
||||||
</div>
|
</div>
|
||||||
<%= map_form.submit(name: nil, class: 'hidden', data: { autosubmit_target: 'submitter' } ) %>
|
<%= map_form.submit(name: nil, class: 'hidden', data: { autosubmit_target: 'submitter' } ) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -18,5 +18,13 @@ describe CarteController do
|
||||||
get :show, params: { map_filter: { year: 2020 } }
|
get :show, params: { map_filter: { year: 2020 } }
|
||||||
expect(subject.stats['75']).to eq({ nb_demarches: 1, nb_dossiers: 20 })
|
expect(subject.stats['75']).to eq({ nb_demarches: 1, nb_dossiers: 20 })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'gracefully ignore invalid params' do
|
||||||
|
get :show, params: { map_filter: { year: "not!" } }
|
||||||
|
expect(subject.stats['75']).to eq({ nb_demarches: 2, nb_dossiers: 50 })
|
||||||
|
|
||||||
|
get :show, params: { map_filter: { kind: "nimp" } }
|
||||||
|
expect(subject.stats['75']).to eq({ nb_demarches: 2, nb_dossiers: 50 })
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ describe MapFilter do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'css_class_for_departement' do
|
describe 'css_class_for_departement' do
|
||||||
let(:params) { { kind: :nb_demarches } }
|
let(:params) { { kind: "nb_demarches" } }
|
||||||
context 'for nb_demarches' do
|
context 'for nb_demarches' do
|
||||||
it 'return class css' do
|
it 'return class css' do
|
||||||
expect(map_filter.css_class_for_departement('63')).to eq :medium
|
expect(map_filter.css_class_for_departement('63')).to eq :medium
|
||||||
|
@ -14,7 +14,7 @@ describe MapFilter do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'fr nb_dossiers' do
|
context 'fr nb_dossiers' do
|
||||||
let(:params) { { kind: :nb_dossiers } }
|
let(:params) { { kind: "nb_dossiers" } }
|
||||||
it 'return class css' do
|
it 'return class css' do
|
||||||
expect(map_filter.css_class_for_departement('63')).to eq :medium
|
expect(map_filter.css_class_for_departement('63')).to eq :medium
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue