diff --git a/Gemfile b/Gemfile
index 81ac050d8..db2a7c5fd 100644
--- a/Gemfile
+++ b/Gemfile
@@ -29,6 +29,7 @@ gem 'flipper-active_record'
gem 'flipper-ui'
gem 'fog-openstack'
gem 'font-awesome-rails'
+gem 'geocoder'
gem 'gon'
gem 'graphiql-rails'
gem 'graphql'
@@ -49,6 +50,7 @@ gem 'openstack'
gem 'pg'
gem 'phonelib'
gem 'prawn' # PDF Generation
+gem 'prawn-svg'
gem 'prawn_rails'
gem 'premailer-rails'
gem 'puma' # Use Puma as the app server
@@ -64,7 +66,6 @@ gem 'rgeo-geojson'
gem 'sanitize-url'
gem 'sassc-rails' # Use SCSS for stylesheets
gem 'scenic'
-gem 'select2-rails'
gem 'sentry-raven'
gem 'skylight'
gem 'smart_listing'
diff --git a/Gemfile.lock b/Gemfile.lock
index 98b4576bf..c3d75309d 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -232,6 +232,7 @@ GEM
font-awesome-rails (4.7.0.4)
railties (>= 3.2, < 6.0)
formatador (0.2.5)
+ geocoder (1.6.0)
globalid (0.4.2)
activesupport (>= 4.2.0)
gon (6.2.1)
@@ -425,6 +426,9 @@ GEM
prawn (2.2.2)
pdf-core (~> 0.7.0)
ttfunk (~> 1.5)
+ 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)
@@ -592,8 +596,6 @@ GEM
scss_lint (0.57.1)
rake (>= 0.9, < 13)
sass (~> 3.5, >= 3.5.5)
- select2-rails (4.0.3)
- thor (~> 0.14)
selectize-rails (0.12.6)
selenium-webdriver (3.141.0)
childprocess (~> 0.5)
@@ -742,6 +744,7 @@ DEPENDENCIES
flipper-ui
fog-openstack
font-awesome-rails
+ geocoder
gon
graphiql-rails
graphql
@@ -770,6 +773,7 @@ DEPENDENCIES
pg
phonelib
prawn
+ prawn-svg
prawn_rails
premailer-rails
pry-byebug
@@ -793,7 +797,6 @@ DEPENDENCIES
sassc-rails
scenic
scss_lint
- select2-rails
sentry-raven
shoulda-matchers
simple_xlsx_reader
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index e9dd51d18..2f3b5b45e 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -29,7 +29,6 @@
// = require search
// = require site_banner
// = require switch_menu
-// = require autocomplete
// = require users
// = require attestation_template_edit
diff --git a/app/assets/stylesheets/autocomplete.scss b/app/assets/stylesheets/autocomplete.scss
deleted file mode 100644
index b46086c3f..000000000
--- a/app/assets/stylesheets/autocomplete.scss
+++ /dev/null
@@ -1,33 +0,0 @@
-.algolia-autocomplete {
- width: 100%;
-}
-
-.algolia-autocomplete .aa-input,
-.algolia-autocomplete .aa-hint {
- width: 100%;
-}
-
-.algolia-autocomplete .aa-hint {
- color: #999999;
-}
-
-.algolia-autocomplete .aa-dropdown-menu {
- width: 100%;
- background-color: #FFFFFF;
- border: 1px solid #999999;
- border-top: none;
-}
-
-.algolia-autocomplete .aa-dropdown-menu .aa-suggestion {
- cursor: pointer;
- padding: 5px 4px;
-}
-
-.algolia-autocomplete .aa-dropdown-menu .aa-suggestion.aa-cursor {
- background-color: #B2D7FF;
-}
-
-.algolia-autocomplete .aa-dropdown-menu .aa-suggestion em {
- font-weight: bold;
- font-style: normal;
-}
diff --git a/app/assets/stylesheets/new_design/forms.scss b/app/assets/stylesheets/new_design/forms.scss
index 07455dfff..62d37cb09 100644
--- a/app/assets/stylesheets/new_design/forms.scss
+++ b/app/assets/stylesheets/new_design/forms.scss
@@ -242,6 +242,16 @@
}
}
+ .select2-selection--single {
+ min-height: 62px;
+
+ // scss-lint:disable SelectorFormat
+ .select2-selection__arrow {
+ display: none;
+ }
+ // scss-lint:enable
+ }
+
// scss-lint:disable SelectorFormat
.select2-selection__rendered {
padding: $default-padding;
diff --git a/app/assets/stylesheets/new_design/map.scss b/app/assets/stylesheets/new_design/map.scss
index aa30790d2..588030137 100644
--- a/app/assets/stylesheets/new_design/map.scss
+++ b/app/assets/stylesheets/new_design/map.scss
@@ -63,6 +63,10 @@
width: 200px;
margin-right: 10px;
}
+
+ .select2-container {
+ margin-bottom: 0;
+ }
}
}
diff --git a/app/assets/stylesheets/new_design/new_application.scss b/app/assets/stylesheets/new_design/new_application.scss
index 2fffd36b7..af88e9f77 100644
--- a/app/assets/stylesheets/new_design/new_application.scss
+++ b/app/assets/stylesheets/new_design/new_application.scss
@@ -5,6 +5,5 @@
// = require ./fonts
// = require leaflet
// = require select2
-// = require autocomplete
// = require_tree .
// = stub ./print.scss
diff --git a/app/controllers/address_controller.rb b/app/controllers/address_controller.rb
deleted file mode 100644
index 6ae345d37..000000000
--- a/app/controllers/address_controller.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-class AddressController < ApplicationController
- def suggestions
- request = params[:request]
-
- json = ApiAdresse::AddressAdapter.new(request).get_suggestions.map do |value|
- { label: value }
- end.to_json
-
- render json: json
- end
-
- def geocode
- request = params[:request]
-
- point = ApiAdresse::PointAdapter.new(request).geocode
-
- if point.present?
- lon = point.x.to_s
- lat = point.y.to_s
- end
-
- render json: { lon: lon, lat: lat, zoom: '14', dossier_id: params[:dossier_id] }
- end
-end
diff --git a/app/controllers/api_geo_test_controller.rb b/app/controllers/api_geo_test_controller.rb
new file mode 100644
index 000000000..9328dc830
--- /dev/null
+++ b/app/controllers/api_geo_test_controller.rb
@@ -0,0 +1,13 @@
+class APIGeoTestController < ActionController::Base
+ def regions
+ render json: [{ nom: 'Martinique' }]
+ end
+
+ def departements
+ render json: [{ nom: 'Aisne', code: '02' }]
+ end
+
+ def communes
+ render json: [{ nom: 'Ambléon' }]
+ end
+end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index e5cba17b3..c192c0f75 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -117,6 +117,7 @@ class ApplicationController < ActionController::Base
def setup_javascript_settings
gon.autosave = Rails.application.config.ds_autosave
+ gon.autocomplete = Rails.application.secrets.autocomplete
end
def setup_tracking
diff --git a/app/controllers/instructeurs/dossiers_controller.rb b/app/controllers/instructeurs/dossiers_controller.rb
index 06c6e5ac4..a7a7d9c4c 100644
--- a/app/controllers/instructeurs/dossiers_controller.rb
+++ b/app/controllers/instructeurs/dossiers_controller.rb
@@ -27,6 +27,14 @@ module Instructeurs
def show
@demande_seen_at = current_instructeur.follows.find_by(dossier: dossier)&.demande_seen_at
+
+ respond_to do |format|
+ format.pdf do
+ @include_infos_administration = true
+ render(file: 'dossiers/show', formats: [:pdf])
+ end
+ format.all
+ end
end
def messagerie
diff --git a/app/controllers/manager/administrateurs_controller.rb b/app/controllers/manager/administrateurs_controller.rb
index f976f3cf6..10dec19d5 100644
--- a/app/controllers/manager/administrateurs_controller.rb
+++ b/app/controllers/manager/administrateurs_controller.rb
@@ -22,11 +22,7 @@ module Manager
def delete
administrateur = Administrateur.find(params[:id])
- if !administrateur.can_be_deleted?
- fail "Impossible de supprimer cet administrateur car il a des dossiers ou des procédures"
- end
- administrateur.dossiers.each(&:delete_and_keep_track)
- administrateur.destroy
+ administrateur.delete_and_transfer_services
logger.info("L'administrateur #{administrateur.id} est supprimé par #{current_administration.id}")
flash[:notice] = "L'administrateur #{administrateur.id} est supprimé"
diff --git a/app/controllers/manager/instructeurs_controller.rb b/app/controllers/manager/instructeurs_controller.rb
index 82b1e11eb..ed2107c45 100644
--- a/app/controllers/manager/instructeurs_controller.rb
+++ b/app/controllers/manager/instructeurs_controller.rb
@@ -6,5 +6,19 @@ module Manager
flash[:notice] = "Instructeur réinvité."
redirect_to manager_instructeur_path(instructeur)
end
+
+ def delete
+ instructeur = Instructeur.find(params[:id])
+
+ if !instructeur.can_be_deleted?
+ fail "Impossible de supprimer cet instructeur car il est administrateur ou il est le seul instructeur sur une démarche"
+ end
+ instructeur.destroy!
+
+ logger.info("L'instructeur #{instructeur.id} est supprimé par #{current_administration.id}")
+ flash[:notice] = "L'instructeur #{instructeur.id} est supprimé"
+
+ redirect_to manager_instructeurs_path
+ end
end
end
diff --git a/app/controllers/manager/users_controller.rb b/app/controllers/manager/users_controller.rb
index 9e1a9fc54..eb2c9e169 100644
--- a/app/controllers/manager/users_controller.rb
+++ b/app/controllers/manager/users_controller.rb
@@ -24,7 +24,7 @@ module Manager
def delete
user = User.find(params[:id])
if !user.can_be_deleted?
- fail "Impossible de supprimer cet utilisateur car il a des dossiers en instruction"
+ fail "Impossible de supprimer cet utilisateur. Il a des dossiers en instruction ou il est administrateur."
end
user.delete_and_keep_track_dossiers(current_administration)
diff --git a/app/controllers/new_administrateur/groupe_instructeurs_controller.rb b/app/controllers/new_administrateur/groupe_instructeurs_controller.rb
index fe1adc93a..cf024df3d 100644
--- a/app/controllers/new_administrateur/groupe_instructeurs_controller.rb
+++ b/app/controllers/new_administrateur/groupe_instructeurs_controller.rb
@@ -48,6 +48,33 @@ module NewAdministrateur
end
end
+ def destroy
+ if !groupe_instructeur.dossiers.empty?
+ flash[:alert] = "Impossible de supprimer un groupe avec des dossiers. Il faut le réaffecter avant"
+ elsif procedure.groupe_instructeurs.one?
+ flash[:alert] = "Suppression impossible : il doit y avoir au moins un groupe instructeur sur chaque procédure"
+ else
+ label = groupe_instructeur.label
+ groupe_instructeur.destroy!
+ flash[:notice] = "le groupe « #{label} » a été supprimé."
+ end
+ redirect_to procedure_groupe_instructeurs_path(procedure)
+ end
+
+ def reaffecter_dossiers
+ @procedure = procedure
+ @groupe_instructeur = groupe_instructeur
+ @groupes_instructeurs = paginated_groupe_instructeurs
+ .without_group(@groupe_instructeur)
+ end
+
+ def reaffecter
+ target_group = procedure.groupe_instructeurs.find(params[:target_group])
+ groupe_instructeur.dossiers.update_all(groupe_instructeur_id: target_group.id)
+ flash[:notice] = "Les dossiers du groupe « #{groupe_instructeur.label} » ont été réaffectés au groupe « #{target_group.label} »."
+ redirect_to procedure_groupe_instructeurs_path(procedure)
+ end
+
def add_instructeur
emails = params['emails'].presence || []
emails = emails.map(&:strip).map(&:downcase)
diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb
index df9204e89..f171e94fa 100644
--- a/app/controllers/users/dossiers_controller.rb
+++ b/app/controllers/users/dossiers_controller.rb
@@ -36,6 +36,13 @@ module Users
end
@dossier = dossier
+ respond_to do |format|
+ format.pdf do
+ @include_infos_administration = false
+ render(file: 'dossiers/show', formats: [:pdf])
+ end
+ format.all
+ end
end
def demande
diff --git a/app/graphql/schema.graphql b/app/graphql/schema.graphql
index 7f6364605..7d6ede50c 100644
--- a/app/graphql/schema.graphql
+++ b/app/graphql/schema.graphql
@@ -1012,6 +1012,11 @@ enum TypeDeChamp {
"""
civilite
+ """
+ Communes
+ """
+ communes
+
"""
Date
"""
diff --git a/app/javascript/new_design/select2.js b/app/javascript/new_design/select2.js
index a9fa8506c..8de34648d 100644
--- a/app/javascript/new_design/select2.js
+++ b/app/javascript/new_design/select2.js
@@ -1,46 +1,158 @@
import $ from 'jquery';
import 'select2';
-const optionTemplate = email =>
+const { api_geo_url, api_adresse_url } = gon.autocomplete || {};
+
+const language = {
+ errorLoading: function() {
+ return 'Les résultats ne peuvent pas être chargés.';
+ },
+ inputTooLong: function(args) {
+ var overChars = args.input.length - args.maximum;
+
+ return 'Supprimez ' + overChars + ' caractère' + (overChars > 1 ? 's' : '');
+ },
+ inputTooShort: function(args) {
+ var remainingChars = args.minimum - args.input.length;
+
+ return (
+ 'Saisissez au moins ' +
+ remainingChars +
+ ' caractère' +
+ (remainingChars > 1 ? 's' : '')
+ );
+ },
+ loadingMore: function() {
+ return 'Chargement de résultats supplémentaires…';
+ },
+ maximumSelected: function(args) {
+ return (
+ 'Vous pouvez seulement sélectionner ' +
+ args.maximum +
+ ' élément' +
+ (args.maximum > 1 ? 's' : '')
+ );
+ },
+ noResults: function() {
+ return 'Aucun résultat trouvé';
+ },
+ searching: function() {
+ return 'Recherche en cours…';
+ },
+ removeAllItems: function() {
+ return 'Supprimer tous les éléments';
+ }
+};
+
+const baseOptions = {
+ language,
+ width: '100%'
+};
+
+const baseAjaxOptions = {
+ delay: 250,
+ cache: true,
+ data({ term: nom }) {
+ return {
+ nom,
+ fields: 'nom,code'
+ };
+ },
+ processResults(data) {
+ return {
+ results: data.map(({ nom }) => ({ id: nom, text: nom }))
+ };
+ }
+};
+
+const regionsOptions = {
+ ...baseOptions,
+ minimumInputLength: 2,
+ ajax: { url: `${api_geo_url}/regions`, ...baseAjaxOptions }
+};
+
+const communesOptions = {
+ ...baseOptions,
+ minimumInputLength: 2,
+ ajax: { url: `${api_geo_url}/communes`, ...baseAjaxOptions }
+};
+
+const etranger99 = { id: '99 - Étranger', text: '99 - Étranger' };
+const departementsOptions = {
+ ...baseOptions,
+ minimumInputLength: 2,
+ ajax: {
+ ...baseAjaxOptions,
+ url: `${api_geo_url}/departements`,
+ processResults(data) {
+ return {
+ results: data
+ .map(({ nom, code }) => ({
+ id: `${code} - ${nom}`,
+ text: `${code} - ${nom}`
+ }))
+ .concat([etranger99])
+ };
+ }
+ }
+};
+
+const adresseOptions = {
+ ...baseOptions,
+ minimumInputLength: 2,
+ ajax: {
+ ...baseAjaxOptions,
+ url: `${api_adresse_url}/search`,
+ data({ term: q }) {
+ return {
+ q,
+ limit: 5
+ };
+ },
+ processResults(data) {
+ return {
+ results: data.features.map(({ properties: { label }, geometry }) => ({
+ id: label,
+ text: label,
+ geometry
+ }))
+ };
+ }
+ }
+};
+
+const templateOption = ({ text }) =>
$(
- '' +
- email.text +
- ''
+ `${text}`
);
addEventListener('ds:page:update', () => {
- $('select.select2').select2({
- language: 'fr',
- width: '100%'
- });
+ $('select.select2').select2(baseOptions);
+ $('select.select2.departements').select2(departementsOptions);
+ $('select.select2.regions').select2(regionsOptions);
+ $('select.select2.communes').select2(communesOptions);
+ $('select.select2.adresse').select2(adresseOptions);
$('.columns-form select.select2-limited').select2({
- language: 'fr',
+ width: '300px',
placeholder: 'Sélectionnez des colonnes',
- maximumSelectionLength: '5',
- width: '300px'
+ maximumSelectionLength: '5'
});
$('.recipients-form select.select2-limited').select2({
- language: 'fr',
+ language,
+ width: '300px',
placeholder: 'Sélectionnez des instructeurs',
- maximumSelectionLength: '30',
- width: '300px'
+ maximumSelectionLength: '30'
});
$('select.select2-limited.select-instructeurs').select2({
- language: 'fr',
+ language,
dropdownParent: $('.instructeur-wrapper'),
placeholder: 'Saisir l’adresse email de l’instructeur',
tags: true,
tokenSeparators: [',', ' '],
- templateResult: optionTemplate,
- templateSelection: function(email) {
- return $(
- '' +
- email.text +
- ''
- );
- }
+ templateResult: templateOption,
+ templateSelection: templateOption
});
});
diff --git a/app/javascript/packs/application-old.js b/app/javascript/packs/application-old.js
index 180698e4b..a10e991fb 100644
--- a/app/javascript/packs/application-old.js
+++ b/app/javascript/packs/application-old.js
@@ -8,7 +8,6 @@ import '../shared/page-update-event';
import '../shared/activestorage/ujs';
import '../shared/rails-ujs-fix';
import '../shared/safari-11-file-xhr-workaround';
-import '../shared/autocomplete';
import '../shared/remote-input';
import '../shared/franceconnect';
diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js
index 5a7e995cf..0e567c58b 100644
--- a/app/javascript/packs/application.js
+++ b/app/javascript/packs/application.js
@@ -13,7 +13,6 @@ import '../shared/activestorage/ujs';
import '../shared/activestorage/attachment-checker';
import '../shared/rails-ujs-fix';
import '../shared/safari-11-file-xhr-workaround';
-import '../shared/autocomplete';
import '../shared/remote-input';
import '../shared/franceconnect';
import '../shared/toggle-target';
diff --git a/app/javascript/shared/autocomplete.js b/app/javascript/shared/autocomplete.js
deleted file mode 100644
index e37dec4dc..000000000
--- a/app/javascript/shared/autocomplete.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import autocomplete from 'autocomplete.js';
-import { getJSON, fire } from '@utils';
-
-const sources = [
- {
- type: 'address',
- url: '/address/suggestions'
- }
-];
-
-const options = {
- autoselect: true,
- minLength: 1
-};
-
-function selector(type) {
- return `[data-autocomplete=${type}]`;
-}
-
-function source(url) {
- return {
- source(query, callback) {
- getJSON(url, { request: query }).then(callback);
- },
- templates: {
- suggestion({ label, mine }) {
- const mineClass = `path-mine-${mine ? 'true' : 'false'}`;
- const openTag = `
<%= link_to 'Réinviter', reinvite_manager_instructeur_path(instructeur), method: :post, class: 'button' %>
+
+ <%= button_to "Supprimer", delete_manager_instructeur_path(page.resource), method: :delete, disabled: !page.resource.can_be_deleted?, class: "button", data: { confirm: "Confirmez-vous la suppression de l'instructeur ?" }, title: page.resource.can_be_deleted? ? "Supprimer" : "Cet instructeur est administrateur ou a des démarches dont il est le seul instructeur et ne peut être supprimé" %>
+
diff --git a/app/views/manager/users/show.html.erb b/app/views/manager/users/show.html.erb
index ab51789a6..833e79723 100644
--- a/app/views/manager/users/show.html.erb
+++ b/app/views/manager/users/show.html.erb
@@ -25,7 +25,7 @@ as well as a link to its edit page.
- <%= button_to "supprimer", delete_manager_user_path(page.resource), method: :delete, disabled: !page.resource.can_be_deleted?, class: "button", data: { confirm: "Confirmez-vous la suppression de l'utilisateur ?" }, title: page.resource.can_be_deleted? ? "Supprimer" : "Cet utilisateur a des dossiers dont l'instruction a commencé et ne peut être supprimé" %>
+ <%= button_to "supprimer", delete_manager_user_path(page.resource), method: :delete, disabled: !page.resource.can_be_deleted?, class: "button", data: { confirm: "Confirmez-vous la suppression de l'utilisateur ?" }, title: page.resource.can_be_deleted? ? "Supprimer" : "Cet utilisateur ne peut être supprimé. Il a des dossiers dont l'instruction a commencé ou il est administrateur ou instructeur" %>
diff --git a/app/views/new_administrateur/groupe_instructeurs/index.html.haml b/app/views/new_administrateur/groupe_instructeurs/index.html.haml
index 28ce3b0c1..0e7923121 100644
--- a/app/views/new_administrateur/groupe_instructeurs/index.html.haml
+++ b/app/views/new_administrateur/groupe_instructeurs/index.html.haml
@@ -28,11 +28,21 @@
%table.table.mt-2
%thead
%tr
- %th{ colspan: 2 }= t(".existing_groupe", count: @groupes_instructeurs.count)
+ %th{ colspan: 2 }= t(".existing_groupe", count: @groupes_instructeurs.total_count)
%tbody
- @groupes_instructeurs.each do |group|
%tr
%td= group.label
%td.actions= link_to "voir", procedure_groupe_instructeur_path(@procedure, group)
-
+ - if @groupes_instructeurs.many?
+ - if group.dossiers.empty?
+ %td.actions
+ = link_to procedure_groupe_instructeur_path(@procedure, group), { method: :delete, class: 'button', data: { confirm: "Êtes-vous sûr de vouloir supprimer le groupe « #{group.label} » ?" }} do
+ %span.icon.delete
+ supprimer ce groupe
+ - else
+ %td.actions
+ = link_to reaffecter_dossiers_procedure_groupe_instructeur_path(@procedure, group), class: 'button', title:'Réaffecter les dossiers à un autre groupe afin de pouvoir le supprimer' do
+ %span.icon.follow
+ déplacer les dossiers
= paginate @groupes_instructeurs
diff --git a/app/views/new_administrateur/groupe_instructeurs/reaffecter_dossiers.html.haml b/app/views/new_administrateur/groupe_instructeurs/reaffecter_dossiers.html.haml
new file mode 100644
index 000000000..d62f1e7b3
--- /dev/null
+++ b/app/views/new_administrateur/groupe_instructeurs/reaffecter_dossiers.html.haml
@@ -0,0 +1,27 @@
+= render partial: 'new_administrateur/breadcrumbs',
+ locals: { steps: [link_to('Démarches', admin_procedures_path),
+ link_to(@procedure.libelle, admin_procedure_path(@procedure)),
+ link_to('Groupes d’instructeurs', procedure_groupe_instructeurs_path(@procedure)),
+ @groupe_instructeur.label] }
+
+.container.groupe-instructeur
+
+ .card
+ .card-title Réaffectation des dossiers du groupe « {@groupe_instructeur.label} »
+ %p
+ Le groupe « #{@groupe_instructeur.label} » contient des dossiers. Afin de procéder à sa suppression, vous devez réaffecter ses dossiers à un autre groupe instructeur.
+
+ %table.table.mt-2
+ %thead
+ %tr
+ %th{ colspan: 2 }= t(".existing_groupe", count: @groupes_instructeurs.total_count)
+ %tbody
+ - @groupes_instructeurs.each do |group|
+ %tr
+ %td= group.label
+ %td.actions= button_to 'Réaffecter les dossiers à ce groupe',
+ reaffecter_procedure_groupe_instructeur_path(:target_group => group),
+ { class: 'button',
+ data: { confirm: "Êtes-vous sûr de vouloir réaffecter les dossiers du groupe « #{@groupe_instructeur.label} » vers le groupe « #{group.label} » ?" } }
+
+ = paginate @groupes_instructeurs
diff --git a/app/views/shared/dossiers/editable_champs/_address.html.haml b/app/views/shared/dossiers/editable_champs/_address.html.haml
index b7ae4e032..95025fc33 100644
--- a/app/views/shared/dossiers/editable_champs/_address.html.haml
+++ b/app/views/shared/dossiers/editable_champs/_address.html.haml
@@ -1,4 +1,4 @@
-= form.text_field :value,
- data: { address: true, autocomplete: 'address' },
- placeholder: champ.libelle,
- required: champ.mandatory?
+= form.select :value, [champ.value].compact,
+ { include_blank: true },
+ required: champ.mandatory?,
+ class: 'select2 adresse'
diff --git a/app/views/shared/dossiers/editable_champs/_carte.html.haml b/app/views/shared/dossiers/editable_champs/_carte.html.haml
index e55bebec0..e15e1f6c6 100644
--- a/app/views/shared/dossiers/editable_champs/_carte.html.haml
+++ b/app/views/shared/dossiers/editable_champs/_carte.html.haml
@@ -1,6 +1,6 @@
.toolbar
%button.button.primary.new-area Ajouter une zone
- %input.address{ data: { address: true, autocomplete: 'address' }, placeholder: 'Saisissez une adresse ou positionner la carte' }
+ %select.select2.adresse{ data: { address: true }, placeholder: 'Saisissez une adresse ou positionner la carte' }
.carte.edit{ data: { geo: geo_data(champ) }, class: "carte-#{form.index}" }
diff --git a/app/views/shared/dossiers/editable_champs/_communes.html.haml b/app/views/shared/dossiers/editable_champs/_communes.html.haml
new file mode 100644
index 000000000..0087a725e
--- /dev/null
+++ b/app/views/shared/dossiers/editable_champs/_communes.html.haml
@@ -0,0 +1,4 @@
+= form.select :value, [champ.value].compact,
+ { include_blank: true },
+ required: champ.mandatory?,
+ class: 'select2 communes'
diff --git a/app/views/shared/dossiers/editable_champs/_departements.html.haml b/app/views/shared/dossiers/editable_champs/_departements.html.haml
index e3084d148..9d0171092 100644
--- a/app/views/shared/dossiers/editable_champs/_departements.html.haml
+++ b/app/views/shared/dossiers/editable_champs/_departements.html.haml
@@ -1,4 +1,4 @@
-= form.select :value,
- Champs::DepartementChamp.departements,
- include_blank: true,
- required: champ.mandatory?
+= form.select :value, [champ.value].compact,
+ { include_blank: true },
+ required: champ.mandatory?,
+ class: 'select2 departements'
diff --git a/app/views/shared/dossiers/editable_champs/_pays.html.haml b/app/views/shared/dossiers/editable_champs/_pays.html.haml
index 13062d8e5..0e686fee9 100644
--- a/app/views/shared/dossiers/editable_champs/_pays.html.haml
+++ b/app/views/shared/dossiers/editable_champs/_pays.html.haml
@@ -1,5 +1,5 @@
= form.select :value,
Champs::PaysChamp.pays,
- disabled: Champs::PaysChamp.disabled_options,
- include_blank: true,
- required: champ.mandatory?
+ { disabled: Champs::PaysChamp.disabled_options, include_blank: true },
+ required: champ.mandatory?,
+ class: 'select2 pays'
diff --git a/app/views/shared/dossiers/editable_champs/_regions.html.haml b/app/views/shared/dossiers/editable_champs/_regions.html.haml
index 8920cfc3c..4b16bea2d 100644
--- a/app/views/shared/dossiers/editable_champs/_regions.html.haml
+++ b/app/views/shared/dossiers/editable_champs/_regions.html.haml
@@ -1,4 +1,4 @@
-= form.select :value,
- Champs::RegionChamp.regions,
- include_blank: true,
- required: champ.mandatory?
+= form.select :value, [champ.value].compact,
+ { include_blank: true },
+ required: champ.mandatory?,
+ class: 'select2 regions'
diff --git a/app/views/users/dossiers/show/_header.html.haml b/app/views/users/dossiers/show/_header.html.haml
index 51d6a2797..e148b90d7 100644
--- a/app/views/users/dossiers/show/_header.html.haml
+++ b/app/views/users/dossiers/show/_header.html.haml
@@ -15,6 +15,12 @@
= render partial: 'invites/dropdown', locals: { dossier: dossier }
- if dossier.can_be_updated_by_user? && !current_page?(modifier_dossier_path(dossier))
= link_to "Modifier mon dossier", modifier_dossier_path(dossier), class: 'button accepted edit-form', 'title'=> "Vous pouvez modifier votre dossier tant qu'il n'est passé en instruction"
+ %span.dropdown.print-menu-opener
+ %button.button.dropdown-button.icon-only{ title: 'imprimer' }
+ %span.icon.printer
+ %ul.print-menu.dropdown-content
+ %li
+ = link_to "Tout le dossier", dossier_path(dossier, format: :pdf), target: "_blank", rel: "noopener", class: "menu-item menu-link"
%ul.tabs
= dynamic_tab_item('Résumé', dossier_path(dossier))
diff --git a/config/env.example b/config/env.example
index 5d9134cec..608fd59ff 100644
--- a/config/env.example
+++ b/config/env.example
@@ -105,3 +105,7 @@ LOGRAGE_ENABLED="disabled"
# Service externe d'horodatage des changements de statut des dossiers (effectué quotidiennement)
UNIVERSIGN_API_URL=""
UNIVERSIGN_USERPWD=""
+
+# API Geo / Adresse
+API_ADRESSE_URL="https://api-adresse.data.gouv.fr"
+API_GEO_URL="https://geo.api.gouv.fr"
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
index ee9bff7b4..1535e55ba 100644
--- a/config/initializers/assets.rb
+++ b/config/initializers/assets.rb
@@ -5,6 +5,7 @@ Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path
Rails.application.config.assets.paths << Rails.root.join('node_modules', 'trix', 'dist')
+Rails.application.config.assets.paths << Rails.root.join('node_modules', 'select2', 'dist', 'css')
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb
index 960c3cd3d..588cd5079 100644
--- a/config/initializers/content_security_policy.rb
+++ b/config/initializers/content_security_policy.rb
@@ -13,7 +13,7 @@ Rails.application.config.content_security_policy do |policy|
# c'est trop compliqué pour être rectifié immédiatement (et sans valeur ajoutée:
# c'est hardcodé dans les vues, donc pas injectable).
policy.style_src :self, "*.crisp.chat", "crisp.chat", :unsafe_inline
- policy.connect_src :self, "wss://*.crisp.chat", "*.crisp.chat", "*.demarches-simplifiees.fr", "in-automate.sendinblue.com", "app.franceconnect.gouv.fr", "sentry.io"
+ policy.connect_src :self, "wss://*.crisp.chat", "*.crisp.chat", "*.demarches-simplifiees.fr", "in-automate.sendinblue.com", "app.franceconnect.gouv.fr", "sentry.io", "geo.api.gouv.fr", "api-adresse.data.gouv.fr"
# 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"
diff --git a/config/initializers/geocoder.rb b/config/initializers/geocoder.rb
new file mode 100644
index 000000000..972505d47
--- /dev/null
+++ b/config/initializers/geocoder.rb
@@ -0,0 +1 @@
+Geocoder.configure(lookup: :ban_data_gouv_fr)
diff --git a/config/initializers/urls.rb b/config/initializers/urls.rb
index 53aca743e..00b747247 100644
--- a/config/initializers/urls.rb
+++ b/config/initializers/urls.rb
@@ -1,9 +1,6 @@
# API URLs
-API_ADRESSE_URL = ENV.fetch("API_ADRESSE_URL", "https://api-adresse.data.gouv.fr")
API_CARTO_URL = ENV.fetch("API_CARTO_URL", "https://sandbox.geo.api.gouv.fr/apicarto")
API_ENTREPRISE_URL = ENV.fetch("API_ENTREPRISE_URL", "https://entreprise.api.gouv.fr/v2")
-API_GEO_URL = ENV.fetch("API_GEO_URL", "https://geo.api.gouv.fr")
-API_GEO_SANDBOX_URL = ENV.fetch("API_GEO_SANDBOX_URL", "https://sandbox.geo.api.gouv.fr")
HELPSCOUT_API_URL = ENV.fetch("HELPSCOUT_API_URL", "https://api.helpscout.net/v2")
PIPEDRIVE_API_URL = ENV.fetch("PIPEDRIVE_API_URL", "https://api.pipedrive.com/v1")
SENDINBLUE_API_URL = ENV.fetch("SENDINBLUE_API_URL", "https://in-automate.sendinblue.com/api/v2")
diff --git a/config/locales/models/type_de_champ/fr.yml b/config/locales/models/type_de_champ/fr.yml
index cf97e106f..9d8b878d3 100644
--- a/config/locales/models/type_de_champ/fr.yml
+++ b/config/locales/models/type_de_champ/fr.yml
@@ -24,6 +24,7 @@ fr:
pays: 'Pays'
regions: 'Régions'
departements: 'Départements'
+ communes: 'Communes'
engagement: 'Engagement'
header_section: 'Titre de section'
explication: 'Explication'
diff --git a/config/locales/views/new_administrateur/groupe_instructeurs/fr.yml b/config/locales/views/new_administrateur/groupe_instructeurs/fr.yml
index 4e0ace44d..12f1f652a 100644
--- a/config/locales/views/new_administrateur/groupe_instructeurs/fr.yml
+++ b/config/locales/views/new_administrateur/groupe_instructeurs/fr.yml
@@ -16,3 +16,7 @@ fr:
assignment:
one: "L’instructeur %{value} a été affecté au groupe « %{groupe} »."
other: "Les instructeurs %{value} ont été affectés au groupe « %{groupe} »."
+ reaffecter_dossiers:
+ existing_groupe:
+ one: "%{count} groupe existe"
+ other: "%{count} groupes existent"
diff --git a/config/routes.rb b/config/routes.rb
index ce14ec9ee..e69a44a60 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -32,6 +32,7 @@ Rails.application.routes.draw do
resources :instructeurs, only: [:index, :show] do
post 'reinvite', on: :member
+ delete 'delete', on: :member
end
resources :dossiers, only: [:show]
@@ -209,13 +210,6 @@ Rails.application.routes.draw do
resources :instructeurs, only: [:index, :create, :destroy]
end
- #
- # Addresses
- #
-
- get 'address/suggestions' => 'address#suggestions'
- get 'address/geocode' => 'address#geocode'
-
resources :invites, only: [:show] do
collection do
post 'dossier/:dossier_id', to: 'invites#create', as: :dossier
@@ -363,10 +357,12 @@ Rails.application.routes.draw do
get 'annotations'
end
- resources :groupe_instructeurs, only: [:index, :show, :create, :update] do
+ resources :groupe_instructeurs, only: [:index, :show, :create, :update, :destroy] do
member do
post 'add_instructeur'
delete 'remove_instructeur'
+ get 'reaffecter_dossiers'
+ post 'reaffecter'
end
collection do
@@ -394,6 +390,14 @@ Rails.application.routes.draw do
end
end
+ if Rails.env.test?
+ scope 'test/api_geo' do
+ get 'regions' => 'api_geo_test#regions'
+ get 'communes' => 'api_geo_test#communes'
+ get 'departements' => 'api_geo_test#departements'
+ end
+ end
+
#
# Legacy routes
#
diff --git a/config/secrets.yml b/config/secrets.yml
index 6b0afe9dc..3d7ffa9af 100644
--- a/config/secrets.yml
+++ b/config/secrets.yml
@@ -68,6 +68,9 @@ defaults: &defaults
client_key: <%= ENV['CRISP_CLIENT_KEY'] %>
universign:
userpwd: <%= ENV['UNIVERSIGN_USERPWD'] %>
+ autocomplete:
+ api_geo_url: <%= ENV['API_GEO_URL'] %>
+ api_adresse_url: <%= ENV['API_ADRESSE_URL'] %>
@@ -98,6 +101,8 @@ test:
logout_endpoint: https://bidon.com/endpoint
universign:
userpwd: 'fake:fake'
+ autocomplete:
+ api_geo_url: /test/api_geo
# Do not keep production secrets in the repository,
# instead read values from the environment.
diff --git a/package.json b/package.json
index 8ccc7fce8..94fe7a75b 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,6 @@
"@rails/webpacker": "4.0.7",
"@sentry/browser": "^5.7.1",
"@turf/area": "^6.0.1",
- "autocomplete.js": "^0.37.0",
"babel-plugin-macros": "^2.6.1",
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
"chartkick": "^3.1.3",
diff --git a/spec/controllers/address_controller_spec.rb b/spec/controllers/address_controller_spec.rb
deleted file mode 100644
index 99a2e3218..000000000
--- a/spec/controllers/address_controller_spec.rb
+++ /dev/null
@@ -1,46 +0,0 @@
-require 'spec_helper'
-
-describe AddressController, type: :controller do
- describe '#GET suggestions' do
- subject { get :suggestions, params: { request: request } }
-
- before do
- subject
- end
-
- context 'when request return result', vcr: { cassette_name: 'api_adresse_search_paris_2' } do
- let (:request) { 'Paris' }
-
- it { expect(response.status).to eq 200 }
- it { expect(response.body).to eq '[{"label":"Paris"},{"label":"Paris 63120 Courpière"},{"label":"PARIS (Vaillac) 46240 Cœur de Causse"},{"label":"Paris 40500 Saint-Sever"},{"label":"Paris Buton 37140 Bourgueil"}]' }
- end
-
- context 'when request return nothing', vcr: { cassette_name: 'api_adresse_search_nothing_2' } do
- let (:request) { 'je recherche pas grand chose' }
-
- it { expect(response.status).to eq 200 }
- it { expect(response.body).to eq "[]" }
- end
- end
-
- describe '#GET geocode' do
- let(:dossier_id) { "1" }
- subject { get :geocode, params: { request: request, dossier_id: dossier_id } }
-
- before do
- subject
- end
-
- context 'when request return result', vcr: { cassette_name: 'api_adresse_search_paris' } do
- let(:request) { 'Paris' }
-
- it { expect(response.body).to eq ({ lon: '2.3469', lat: '48.8589', zoom: '14', dossier_id: dossier_id }).to_json }
- end
-
- context 'when request return nothing', vcr: { cassette_name: 'api_adresse_search_nothing' } do
- let(:request) { 'je recherche pas grand chose' }
-
- it { expect(response.body).to eq ({ lon: nil, lat: nil, zoom: '14', dossier_id: dossier_id }).to_json }
- end
- end
-end
diff --git a/spec/controllers/instructeurs/dossiers_controller_spec.rb b/spec/controllers/instructeurs/dossiers_controller_spec.rb
index 264d68ae3..f080ab548 100644
--- a/spec/controllers/instructeurs/dossiers_controller_spec.rb
+++ b/spec/controllers/instructeurs/dossiers_controller_spec.rb
@@ -473,6 +473,34 @@ describe Instructeurs::DossiersController, type: :controller do
end
end
+ describe "#show" do
+ context "when the dossier is exported as PDF" do
+ let(:instructeur) { create(:instructeur) }
+ let(:dossier) {
+ create(:dossier,
+ :accepte,
+ :with_all_champs,
+ :with_all_annotations,
+ :with_motivation,
+ :with_commentaires, procedure: procedure)
+}
+ let!(:avis) { create(:avis, dossier: dossier, instructeur: instructeur) }
+ subject do
+ get :show, params: {
+ procedure_id: procedure.id,
+ dossier_id: dossier.id,
+ format: :pdf
+ }
+ end
+
+ before do
+ subject
+ end
+ it { expect(assigns(:include_infos_administration)).to eq(true) }
+ it { expect(response).to render_template 'dossiers/show' }
+ end
+ end
+
describe "#update_annotations" do
let(:champ_multiple_drop_down_list) do
create(:type_de_champ_multiple_drop_down_list, :private, libelle: 'libelle').champ.create
diff --git a/spec/controllers/manager/instructeurs_controller_spec.rb b/spec/controllers/manager/instructeurs_controller_spec.rb
new file mode 100644
index 000000000..3a0164d4b
--- /dev/null
+++ b/spec/controllers/manager/instructeurs_controller_spec.rb
@@ -0,0 +1,17 @@
+describe Manager::InstructeursController, type: :controller do
+ let(:administration) { create(:administration) }
+
+ describe '#delete' do
+ let!(:instructeur) { create(:instructeur) }
+
+ before { sign_in administration }
+
+ subject { delete :delete, params: { id: instructeur.id } }
+
+ it 'deletes the instructeur' do
+ subject
+
+ expect(Instructeur.find_by(id: instructeur.id)).to be_nil
+ end
+ end
+end
diff --git a/spec/controllers/new_administrateur/groupe_instructeurs_controller_spec.rb b/spec/controllers/new_administrateur/groupe_instructeurs_controller_spec.rb
index e312b7c84..93d02b5fe 100644
--- a/spec/controllers/new_administrateur/groupe_instructeurs_controller_spec.rb
+++ b/spec/controllers/new_administrateur/groupe_instructeurs_controller_spec.rb
@@ -59,6 +59,106 @@ describe NewAdministrateur::GroupeInstructeursController, type: :controller do
end
end
+ describe '#destroy' do
+ def delete_group(group)
+ delete :destroy,
+ params: {
+ procedure_id: procedure.id,
+ id: group.id
+ }
+ end
+
+ context 'with only one group' do
+ before { delete_group gi_1_1 }
+
+ it { expect(flash.alert).to be_present }
+ it { expect(response).to redirect_to(procedure_groupe_instructeurs_path(procedure)) }
+ it { expect(procedure.groupe_instructeurs.count).to eq(1) }
+ end
+
+ context 'with many groups' do
+ let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') }
+
+ context 'of a group that can be deleted' do
+ before { delete_group gi_1_2 }
+ it { expect(flash.notice).to be_present }
+ it { expect(procedure.groupe_instructeurs.count).to eq(1) }
+ it { expect(response).to redirect_to(procedure_groupe_instructeurs_path(procedure)) }
+ end
+
+ context 'of a group with dossiers, that cannot be deleted' do
+ let!(:dossier12) { create(:dossier, procedure: procedure, state: Dossier.states.fetch(:en_construction), groupe_instructeur: gi_1_2) }
+ before { delete_group gi_1_2 }
+
+ it { expect(flash.alert).to be_present }
+ it { expect(procedure.groupe_instructeurs.count).to eq(2) }
+ it { expect(response).to redirect_to(procedure_groupe_instructeurs_path(procedure)) }
+ end
+ end
+ end
+
+ describe '#reaffecter_dossiers' do
+ let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') }
+ let!(:gi_1_3) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 3') }
+
+ before do
+ get :reaffecter_dossiers,
+ params: {
+ procedure_id: procedure.id,
+ id: gi_1_2.id
+ }
+ end
+ def reaffecter_url(group)
+ reaffecter_procedure_groupe_instructeur_path(:id => gi_1_2,
+ :target_group => group)
+ end
+
+ it { expect(response).to have_http_status(:ok) }
+ it { expect(response.body).to include(reaffecter_url(procedure.defaut_groupe_instructeur)) }
+ it { expect(response.body).not_to include(reaffecter_url(gi_1_2)) }
+ it { expect(response.body).to include(reaffecter_url(gi_1_3)) }
+ end
+
+ describe '#reaffecter' do
+ let!(:gi_1_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') }
+ let!(:dossier12) { create(:dossier, procedure: procedure, state: Dossier.states.fetch(:en_construction), groupe_instructeur: gi_1_1) }
+
+ describe 'when the new group is a group of the procedure' do
+ before do
+ post :reaffecter,
+ params: {
+ procedure_id: procedure.id,
+ id: gi_1_1.id,
+ target_group: gi_1_2.id
+ }
+ dossier12.reload
+ end
+
+ it { expect(response).to redirect_to(procedure_groupe_instructeurs_path(procedure)) }
+ it { expect(gi_1_1.dossiers.count).to be(0) }
+ it { expect(gi_1_2.dossiers.count).to be(1) }
+ it { expect(gi_1_2.dossiers.last.id).to be(dossier12.id) }
+ it { expect(dossier12.groupe_instructeur.id).to be(gi_1_2.id) }
+ end
+
+ describe 'when the target group is not a possible group' do
+ subject {
+ post :reaffecter,
+ params:
+ {
+ procedure_id: procedure.id,
+ id: gi_1_1.id,
+ target_group: gi_2_2.id
+ }
+ }
+ before do
+ dossier12.reload
+ end
+
+ it { expect { subject }.to raise_error(ActiveRecord::RecordNotFound) }
+ end
+ end
+
describe '#update' do
let(:new_name) { 'nouveau nom du groupe' }
diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb
index f9fd181b5..3671ae490 100644
--- a/spec/controllers/users/dossiers_controller_spec.rb
+++ b/spec/controllers/users/dossiers_controller_spec.rb
@@ -731,17 +731,37 @@ describe Users::DossiersController, type: :controller do
sign_in(user)
end
- subject! { get(:show, params: { id: dossier.id }) }
+ context 'with default output' do
+ subject! { get(:show, params: { id: dossier.id }) }
- context 'when the dossier is a brouillon' do
- let(:dossier) { create(:dossier, user: user) }
- it { is_expected.to redirect_to(brouillon_dossier_path(dossier)) }
+ context 'when the dossier is a brouillon' do
+ let(:dossier) { create(:dossier, user: user) }
+ it { is_expected.to redirect_to(brouillon_dossier_path(dossier)) }
+ end
+
+ context 'when the dossier has been submitted' do
+ let(:dossier) { create(:dossier, :en_construction, user: user) }
+ it { expect(assigns(:dossier)).to eq(dossier) }
+ it { is_expected.to render_template(:show) }
+ end
end
- context 'when the dossier has been submitted' do
- let(:dossier) { create(:dossier, :en_construction, user: user) }
- it { expect(assigns(:dossier)).to eq(dossier) }
- it { is_expected.to render_template(:show) }
+ context "with PDF output" do
+ let(:procedure) { create(:procedure) }
+ let(:dossier) {
+ create(:dossier,
+ :accepte,
+ :with_all_champs,
+ :with_motivation,
+ :with_commentaires,
+ procedure: procedure,
+ user: user)
+}
+
+ subject! { get(:show, params: { id: dossier.id, format: :pdf }) }
+
+ it { expect(assigns(:include_infos_administration)).to eq(false) }
+ it { expect(response).to render_template 'dossiers/show' }
end
end
diff --git a/spec/factories/champ.rb b/spec/factories/champ.rb
index b9913a536..4b10f249f 100644
--- a/spec/factories/champ.rb
+++ b/spec/factories/champ.rb
@@ -124,6 +124,11 @@ FactoryBot.define do
value { '971 - Guadeloupe' }
end
+ factory :champ_communes, class: 'Champs::CommuneChamp' do
+ type_de_champ { create(:type_de_champ_communes) }
+ value { 'Paris' }
+ end
+
factory :champ_engagement, class: 'Champs::EngagementChamp' do
type_de_champ { create(:type_de_champ_engagement) }
value { 'true' }
diff --git a/spec/factories/type_de_champ.rb b/spec/factories/type_de_champ.rb
index 2bc898b09..597d84c9e 100644
--- a/spec/factories/type_de_champ.rb
+++ b/spec/factories/type_de_champ.rb
@@ -71,6 +71,9 @@ FactoryBot.define do
factory :type_de_champ_departements do
type_champ { TypeDeChamp.type_champs.fetch(:departements) }
end
+ factory :type_de_champ_communes do
+ type_champ { TypeDeChamp.type_champs.fetch(:communes) }
+ end
factory :type_de_champ_engagement do
type_champ { TypeDeChamp.type_champs.fetch(:engagement) }
end
diff --git a/spec/features/users/brouillon_spec.rb b/spec/features/users/brouillon_spec.rb
index 90bea2630..f74f6c4f4 100644
--- a/spec/features/users/brouillon_spec.rb
+++ b/spec/features/users/brouillon_spec.rb
@@ -10,10 +10,7 @@ feature 'The user' do
# TODO: check
# the order
# there are no extraneous input
- scenario 'fill a dossier', js: true do
- allow(Champs::RegionChamp).to receive(:regions).and_return(['region1', 'region2']).at_least(:once)
- allow(Champs::DepartementChamp).to receive(:departements).and_return(['dep1', 'dep2']).at_least(:once)
-
+ scenario 'fill a dossier', js: true, vcr: { cassette_name: 'api_geo_departements_regions_et_communes' } do
log_in(user, procedure)
fill_individual
@@ -33,8 +30,16 @@ feature 'The user' do
select('val1', from: form_id_for('multiple_drop_down_list'))
select('val3', from: form_id_for('multiple_drop_down_list'))
select('AUSTRALIE', from: 'pays')
- select('region2', from: 'regions')
- select('dep2', from: 'departements')
+
+ select_champ_geo('regions', 'Ma', 'Martinique')
+ select('Martinique', from: 'regions')
+
+ select_champ_geo('departements', 'Ai', '02 - Aisne')
+ select('02 - Aisne', from: 'departements')
+
+ select_champ_geo('communes', 'Am', 'Ambléon')
+ select('Ambléon', from: 'communes')
+
check('engagement')
fill_in('dossier_link', with: '123')
find('.editable-champ-piece_justificative input[type=file]').attach_file(Rails.root + 'spec/fixtures/files/file.pdf')
@@ -57,8 +62,9 @@ feature 'The user' do
expect(champ_value_for('simple_drop_down_list')).to eq('val2')
expect(JSON.parse(champ_value_for('multiple_drop_down_list'))).to match(['val1', 'val3'])
expect(champ_value_for('pays')).to eq('AUSTRALIE')
- expect(champ_value_for('regions')).to eq('region2')
- expect(champ_value_for('departements')).to eq('dep2')
+ expect(champ_value_for('regions')).to eq('Martinique')
+ expect(champ_value_for('departements')).to eq('02 - Aisne')
+ expect(champ_value_for('communes')).to eq('Ambléon')
expect(champ_value_for('engagement')).to eq('on')
expect(champ_value_for('dossier_link')).to eq('123')
expect(champ_value_for('piece_justificative')).to be_nil # antivirus hasn't approved the file yet
@@ -78,8 +84,9 @@ feature 'The user' do
expect(page).to have_selected_value('simple_drop_down_list', selected: 'val2')
expect(page).to have_selected_value('multiple_drop_down_list', selected: ['val1', 'val3'])
expect(page).to have_selected_value('pays', selected: 'AUSTRALIE')
- expect(page).to have_selected_value('regions', selected: 'region2')
- expect(page).to have_selected_value('departement', selected: 'dep2')
+ expect(page).to have_selected_value('regions', selected: 'Martinique')
+ expect(page).to have_selected_value('departements', selected: '02 - Aisne')
+ expect(page).to have_selected_value('communes', selected: 'Ambléon')
expect(page).to have_checked_field('engagement')
expect(page).to have_field('dossier_link', with: '123')
expect(page).to have_text('file.pdf')
@@ -270,4 +277,12 @@ feature 'The user' do
expect(page).to have_selected_value("#{field}_4i", selected: date.strftime('%H'))
expect(page).to have_selected_value("#{field}_5i", selected: date.strftime('%M'))
end
+
+ def select_champ_geo(champ, fill_with, value)
+ find(".editable-champ-#{champ} .select2-container").click
+ id = find('.select2-container--open [role=listbox]')[:id]
+ find("[aria-controls=#{id}]").fill_in with: fill_with
+ expect(page).to have_content(value)
+ find('li', text: value).click
+ end
end
diff --git a/spec/features/users/dossier_creation_spec.rb b/spec/features/users/dossier_creation_spec.rb
index f6dc8de5b..662d02918 100644
--- a/spec/features/users/dossier_creation_spec.rb
+++ b/spec/features/users/dossier_creation_spec.rb
@@ -77,7 +77,7 @@ feature 'Creating a new dossier:' do
.to_return(status: 404, body: '')
end
- scenario 'the user can enter the SIRET of its etablissement and create a new draft', vcr: { cassette_name: 'api_adresse_search_paris_3' } do
+ scenario 'the user can enter the SIRET of its etablissement and create a new draft' do
visit commencer_path(path: procedure.path)
click_on 'Commencer la démarche'
diff --git a/spec/fixtures/cassettes/api_adresse_octo.yml b/spec/fixtures/cassettes/api_adresse_octo.yml
deleted file mode 100644
index 28ed2accb..000000000
--- a/spec/fixtures/cassettes/api_adresse_octo.yml
+++ /dev/null
@@ -1,47 +0,0 @@
----
-http_interactions:
-- request:
- method: get
- uri: https://api-adresse.data.gouv.fr/search?limit=1&q=50%20av%20des%20champs%20elysees
- body:
- encoding: US-ASCII
- string: ''
- headers:
- Accept:
- - "*/*"
- Accept-Encoding:
- - gzip, deflate
- User-Agent:
- - rest-client/2.0.0 (darwin15.6.0 x86_64) ruby/2.3.1p112
- response:
- status:
- code: 200
- message: OK
- headers:
- Server:
- - nginx/1.11.3
- Date:
- - Fri, 16 Dec 2016 16:22:23 GMT
- Content-Type:
- - application/json; charset=utf-8
- Content-Length:
- - '628'
- Connection:
- - keep-alive
- Access-Control-Allow-Origin:
- - "*"
- Access-Control-Allow-Headers:
- - X-Requested-With
- body:
- encoding: UTF-8
- string: '{"limit": 1, "attribution": "BAN", "version": "draft", "licence": "ODbL
- 1.0", "query": "50 av des champs elysees", "type": "FeatureCollection", "features":
- [{"geometry": {"type": "Point", "coordinates": [2.306888, 48.870374]}, "properties":
- {"citycode": "75108", "postcode": "75008", "name": "50 Avenue des Champs \u00c9lys\u00e9es",
- "id": "ADRNIVX_0000000270748251", "type": "housenumber", "context": "75, \u00cele-de-France",
- "score": 0.7561038961038961, "label": "50 Avenue des Champs \u00c9lys\u00e9es
- 75008 Paris", "city": "Paris", "housenumber": "50", "street": "Avenue des
- Champs \u00c9lys\u00e9es"}, "type": "Feature"}]}'
- http_version:
- recorded_at: Fri, 16 Dec 2016 16:22:23 GMT
-recorded_with: VCR 3.0.3
diff --git a/spec/fixtures/cassettes/api_adresse_search_nothing.yml b/spec/fixtures/cassettes/api_adresse_search_nothing.yml
deleted file mode 100644
index d951adbfc..000000000
--- a/spec/fixtures/cassettes/api_adresse_search_nothing.yml
+++ /dev/null
@@ -1,42 +0,0 @@
----
-http_interactions:
-- request:
- method: get
- uri: https://api-adresse.data.gouv.fr/search?limit=1&q=je%20recherche%20pas%20grand%20chose
- body:
- encoding: US-ASCII
- string: ''
- headers:
- Accept:
- - "*/*"
- Accept-Encoding:
- - gzip, deflate
- User-Agent:
- - rest-client/2.0.0 (darwin15.6.0 x86_64) ruby/2.3.1p112
- response:
- status:
- code: 200
- message: OK
- headers:
- Server:
- - nginx/1.11.3
- Date:
- - Fri, 16 Dec 2016 14:17:40 GMT
- Content-Type:
- - application/json; charset=utf-8
- Content-Length:
- - '163'
- Connection:
- - keep-alive
- Access-Control-Allow-Origin:
- - "*"
- Access-Control-Allow-Headers:
- - X-Requested-With
- body:
- encoding: UTF-8
- string: '{"limit": 1, "attribution": "BAN", "version": "draft", "licence": "ODbL
- 1.0", "query": "je recherche pas grand chose", "type": "FeatureCollection",
- "features": []}'
- http_version:
- recorded_at: Fri, 16 Dec 2016 14:17:40 GMT
-recorded_with: VCR 3.0.3
diff --git a/spec/fixtures/cassettes/api_adresse_search_nothing_2.yml b/spec/fixtures/cassettes/api_adresse_search_nothing_2.yml
deleted file mode 100644
index cbb4a0f66..000000000
--- a/spec/fixtures/cassettes/api_adresse_search_nothing_2.yml
+++ /dev/null
@@ -1,42 +0,0 @@
----
-http_interactions:
-- request:
- method: get
- uri: https://api-adresse.data.gouv.fr/search?limit=5&q=je%20recherche%20pas%20grand%20chose
- body:
- encoding: US-ASCII
- string: ''
- headers:
- Accept:
- - "*/*"
- Accept-Encoding:
- - gzip, deflate
- User-Agent:
- - rest-client/2.0.0 (darwin15.6.0 x86_64) ruby/2.3.1p112
- response:
- status:
- code: 200
- message: OK
- headers:
- Server:
- - nginx/1.11.3
- Date:
- - Fri, 16 Dec 2016 16:45:53 GMT
- Content-Type:
- - application/json; charset=utf-8
- Content-Length:
- - '163'
- Connection:
- - keep-alive
- Access-Control-Allow-Origin:
- - "*"
- Access-Control-Allow-Headers:
- - X-Requested-With
- body:
- encoding: UTF-8
- string: '{"limit": 5, "attribution": "BAN", "version": "draft", "licence": "ODbL
- 1.0", "query": "je recherche pas grand chose", "type": "FeatureCollection",
- "features": []}'
- http_version:
- recorded_at: Fri, 16 Dec 2016 16:45:53 GMT
-recorded_with: VCR 3.0.3
diff --git a/spec/fixtures/cassettes/api_adresse_search_paris.yml b/spec/fixtures/cassettes/api_adresse_search_paris.yml
deleted file mode 100644
index ced667e17..000000000
--- a/spec/fixtures/cassettes/api_adresse_search_paris.yml
+++ /dev/null
@@ -1,45 +0,0 @@
----
-http_interactions:
-- request:
- method: get
- uri: https://api-adresse.data.gouv.fr/search?limit=1&q=Paris
- body:
- encoding: US-ASCII
- string: ''
- headers:
- Accept:
- - "*/*"
- Accept-Encoding:
- - gzip, deflate
- User-Agent:
- - rest-client/2.0.0 (darwin15.6.0 x86_64) ruby/2.3.1p112
- response:
- status:
- code: 200
- message: OK
- headers:
- Server:
- - nginx/1.11.3
- Date:
- - Fri, 16 Dec 2016 14:16:43 GMT
- Content-Type:
- - application/json; charset=utf-8
- Content-Length:
- - '457'
- Connection:
- - keep-alive
- Access-Control-Allow-Origin:
- - "*"
- Access-Control-Allow-Headers:
- - X-Requested-With
- body:
- encoding: UTF-8
- string: '{"limit": 1, "attribution": "BAN", "version": "draft", "licence": "ODbL
- 1.0", "query": "Paris", "type": "FeatureCollection", "features": [{"geometry":
- {"type": "Point", "coordinates": [2.3469, 48.8589]}, "properties": {"adm_weight":
- "6", "citycode": "75056", "name": "Paris", "city": "Paris", "postcode": "75000",
- "context": "75, \u00cele-de-France", "score": 1.0, "label": "Paris", "id":
- "75056", "type": "city", "population": "2244"}, "type": "Feature"}]}'
- http_version:
- recorded_at: Fri, 16 Dec 2016 14:16:43 GMT
-recorded_with: VCR 3.0.3
diff --git a/spec/fixtures/cassettes/api_adresse_search_paris_2.yml b/spec/fixtures/cassettes/api_adresse_search_paris_2.yml
deleted file mode 100644
index 5faf1cd88..000000000
--- a/spec/fixtures/cassettes/api_adresse_search_paris_2.yml
+++ /dev/null
@@ -1,63 +0,0 @@
----
-http_interactions:
-- request:
- method: get
- uri: https://api-adresse.data.gouv.fr/search?limit=5&q=Paris
- body:
- encoding: US-ASCII
- string: ''
- headers:
- Accept:
- - "*/*"
- Accept-Encoding:
- - gzip, deflate
- User-Agent:
- - rest-client/2.0.0 (darwin15.6.0 x86_64) ruby/2.3.1p112
- response:
- status:
- code: 200
- message: OK
- headers:
- Server:
- - nginx/1.11.3
- Date:
- - Fri, 16 Dec 2016 16:43:34 GMT
- Content-Type:
- - application/json; charset=utf-8
- Content-Length:
- - '1887'
- Connection:
- - keep-alive
- Access-Control-Allow-Origin:
- - "*"
- Access-Control-Allow-Headers:
- - X-Requested-With
- body:
- encoding: UTF-8
- string: '{"limit": 5, "attribution": "BAN", "version": "draft", "licence": "ODbL
- 1.0", "query": "Paris", "type": "FeatureCollection", "features": [{"geometry":
- {"type": "Point", "coordinates": [2.3469, 48.8589]}, "properties": {"adm_weight":
- "6", "citycode": "75056", "name": "Paris", "city": "Paris", "postcode": "75000",
- "context": "75, \u00cele-de-France", "score": 1.0, "label": "Paris", "id":
- "75056", "type": "city", "population": "2244"}, "type": "Feature"}, {"geometry":
- {"type": "Point", "coordinates": [3.564293, 45.766413]}, "properties": {"citycode":
- "63125", "postcode": "63120", "name": "Paris", "city": "Courpi\u00e8re", "context":
- "63, Puy-de-D\u00f4me, Auvergne", "score": 0.8255363636363636, "label": "Paris
- 63120 Courpi\u00e8re", "id": "63125_B221_03549b", "type": "locality"}, "type":
- "Feature"}, {"geometry": {"type": "Point", "coordinates": [1.550208, 44.673592]},
- "properties": {"citycode": "46138", "postcode": "46240", "name": "PARIS (Vaillac)",
- "city": "C\u0153ur de Causse", "context": "46, Lot, Midi-Pyr\u00e9n\u00e9es",
- "score": 0.824090909090909, "label": "PARIS (Vaillac) 46240 C\u0153ur de Causse",
- "id": "46138_XXXX_6ee4ec", "type": "street"}, "type": "Feature"}, {"geometry":
- {"type": "Point", "coordinates": [-0.526884, 43.762253]}, "properties": {"citycode":
- "40282", "postcode": "40500", "name": "Paris", "city": "Saint-Sever", "context":
- "40, Landes, Aquitaine", "score": 0.8236181818181818, "label": "Paris 40500
- Saint-Sever", "id": "40282_B237_2364e3", "type": "locality"}, "type": "Feature"},
- {"geometry": {"type": "Point", "coordinates": [0.157613, 47.336685]}, "properties":
- {"citycode": "37031", "postcode": "37140", "name": "Paris Buton", "city":
- "Bourgueil", "context": "37, Indre-et-Loire, Centre Val-de-Loire", "score":
- 0.8235454545454545, "label": "Paris Buton 37140 Bourgueil", "id": "37031_X027_0a5e7a",
- "type": "locality"}, "type": "Feature"}]}'
- http_version:
- recorded_at: Fri, 16 Dec 2016 16:43:34 GMT
-recorded_with: VCR 3.0.3
diff --git a/spec/fixtures/cassettes/api_adresse_search_paris_3.yml b/spec/fixtures/cassettes/api_adresse_search_paris_3.yml
deleted file mode 100644
index 22eca3306..000000000
--- a/spec/fixtures/cassettes/api_adresse_search_paris_3.yml
+++ /dev/null
@@ -1,93 +0,0 @@
----
-http_interactions:
-- request:
- method: get
- uri: https://api-adresse.data.gouv.fr/search?limit=1&q=50%20AV%20DES%20CHAMPS%20ELYSEES%20complement_adresse%2075008%20PARIS%208
- body:
- encoding: US-ASCII
- string: ''
- headers:
- Accept:
- - "*/*"
- Accept-Encoding:
- - gzip, deflate
- User-Agent:
- - rest-client/2.0.0 (darwin15.6.0 x86_64) ruby/2.3.1p112
- response:
- status:
- code: 200
- message: OK
- headers:
- Server:
- - nginx/1.11.3
- Date:
- - Tue, 03 Jan 2017 13:00:54 GMT
- Content-Type:
- - application/json; charset=utf-8
- Content-Length:
- - '660'
- Connection:
- - keep-alive
- Access-Control-Allow-Origin:
- - "*"
- Access-Control-Allow-Headers:
- - X-Requested-With
- body:
- encoding: UTF-8
- string: '{"limit": 1, "attribution": "BAN", "version": "draft", "licence": "ODbL
- 1.0", "query": "50 AV DES CHAMPS ELYSEES complement_adresse 75008 PARIS 8",
- "type": "FeatureCollection", "features": [{"geometry": {"type": "Point", "coordinates":
- [2.306888, 48.870374]}, "properties": {"citycode": "75108", "postcode": "75008",
- "name": "50 Avenue des Champs \u00c9lys\u00e9es", "id": "ADRNIVX_0000000270748251",
- "type": "housenumber", "context": "75, \u00cele-de-France", "score": 0.596517719568567,
- "label": "50 Avenue des Champs \u00c9lys\u00e9es 75008 Paris", "city": "Paris",
- "housenumber": "50", "street": "Avenue des Champs \u00c9lys\u00e9es"}, "type":
- "Feature"}]}'
- http_version:
- recorded_at: Tue, 03 Jan 2017 13:00:54 GMT
-- request:
- method: get
- uri: http://api-adresse.data.gouv.fr/search?limit=1&q=50%20AV%20DES%20CHAMPS%20ELYSEES%20complement_adresse%2075008%20PARIS%208
- body:
- encoding: US-ASCII
- string: ''
- headers:
- Accept:
- - "*/*"
- Accept-Encoding:
- - gzip, deflate
- User-Agent:
- - rest-client/2.0.0 (darwin15.6.0 x86_64) ruby/2.3.1p112
- response:
- status:
- code: 200
- message: OK
- headers:
- Server:
- - nginx/1.11.3
- Date:
- - Tue, 03 Jan 2017 13:00:55 GMT
- Content-Type:
- - application/json; charset=utf-8
- Content-Length:
- - '660'
- Connection:
- - keep-alive
- Access-Control-Allow-Origin:
- - "*"
- Access-Control-Allow-Headers:
- - X-Requested-With
- body:
- encoding: UTF-8
- string: '{"limit": 1, "attribution": "BAN", "version": "draft", "licence": "ODbL
- 1.0", "query": "50 AV DES CHAMPS ELYSEES complement_adresse 75008 PARIS 8",
- "type": "FeatureCollection", "features": [{"geometry": {"type": "Point", "coordinates":
- [2.306888, 48.870374]}, "properties": {"citycode": "75108", "postcode": "75008",
- "name": "50 Avenue des Champs \u00c9lys\u00e9es", "id": "ADRNIVX_0000000270748251",
- "type": "housenumber", "context": "75, \u00cele-de-France", "score": 0.596517719568567,
- "label": "50 Avenue des Champs \u00c9lys\u00e9es 75008 Paris", "city": "Paris",
- "housenumber": "50", "street": "Avenue des Champs \u00c9lys\u00e9es"}, "type":
- "Feature"}]}'
- http_version:
- recorded_at: Tue, 03 Jan 2017 13:00:55 GMT
-recorded_with: VCR 3.0.3
diff --git a/spec/fixtures/cassettes/api_geo_departements.yml b/spec/fixtures/cassettes/api_geo_departements.yml
deleted file mode 100644
index 9a7dcd8b3..000000000
--- a/spec/fixtures/cassettes/api_geo_departements.yml
+++ /dev/null
@@ -1,51 +0,0 @@
----
-http_interactions:
-- request:
- method: get
- uri: https://geo.api.gouv.fr/departements?fields=nom
- body:
- encoding: US-ASCII
- string: ''
- headers:
- User-Agent:
- - demarches-simplifiees.fr
- Accept:
- - application/json
- Accept-Encoding:
- - gzip, deflate
- Expect:
- - ''
- response:
- status:
- code: 200
- message: OK
- headers:
- Server:
- - nginx/1.10.3 (Ubuntu)
- Date:
- - Tue, 23 Oct 2018 13:11:36 GMT
- Content-Type:
- - application/json; charset=utf-8
- Transfer-Encoding:
- - chunked
- Connection:
- - keep-alive
- Vary:
- - Accept-Encoding
- X-Powered-By:
- - Express
- Access-Control-Allow-Origin:
- - "*"
- Etag:
- - W/"cc1-jlb3C7xpXUEaq56Wojrp9rAkoH8"
- Strict-Transport-Security:
- - max-age=15552000
- Content-Encoding:
- - gzip
- body:
- encoding: ASCII-8BIT
- string: !binary |-
- W3sibm9tIjoiQWluIiwiY29kZSI6IjAxIn0seyJub20iOiJBaXNuZSIsImNvZGUiOiIwMiJ9LHsibm9tIjoiQWxsaWVyIiwiY29kZSI6IjAzIn0seyJub20iOiJBbHBlcy1kZS1IYXV0ZS1Qcm92ZW5jZSIsImNvZGUiOiIwNCJ9LHsibm9tIjoiSGF1dGVzLUFscGVzIiwiY29kZSI6IjA1In0seyJub20iOiJBbHBlcy1NYXJpdGltZXMiLCJjb2RlIjoiMDYifSx7Im5vbSI6IkFyZMOoY2hlIiwiY29kZSI6IjA3In0seyJub20iOiJBcmRlbm5lcyIsImNvZGUiOiIwOCJ9LHsibm9tIjoiQXJpw6hnZSIsImNvZGUiOiIwOSJ9LHsibm9tIjoiQXViZSIsImNvZGUiOiIxMCJ9LHsibm9tIjoiQXVkZSIsImNvZGUiOiIxMSJ9LHsibm9tIjoiQXZleXJvbiIsImNvZGUiOiIxMiJ9LHsibm9tIjoiQm91Y2hlcy1kdS1SaMO0bmUiLCJjb2RlIjoiMTMifSx7Im5vbSI6IkNhbHZhZG9zIiwiY29kZSI6IjE0In0seyJub20iOiJDYW50YWwiLCJjb2RlIjoiMTUifSx7Im5vbSI6IkNoYXJlbnRlIiwiY29kZSI6IjE2In0seyJub20iOiJDaGFyZW50ZS1NYXJpdGltZSIsImNvZGUiOiIxNyJ9LHsibm9tIjoiQ2hlciIsImNvZGUiOiIxOCJ9LHsibm9tIjoiQ29ycsOoemUiLCJjb2RlIjoiMTkifSx7Im5vbSI6IkPDtHRlLWQnT3IiLCJjb2RlIjoiMjEifSx7Im5vbSI6IkPDtHRlcy1kJ0FybW9yIiwiY29kZSI6IjIyIn0seyJub20iOiJDcmV1c2UiLCJjb2RlIjoiMjMifSx7Im5vbSI6IkRvcmRvZ25lIiwiY29kZSI6IjI0In0seyJub20iOiJEb3VicyIsImNvZGUiOiIyNSJ9LHsibm9tIjoiRHLDtG1lIiwiY29kZSI6IjI2In0seyJub20iOiJFdXJlIiwiY29kZSI6IjI3In0seyJub20iOiJFdXJlLWV0LUxvaXIiLCJjb2RlIjoiMjgifSx7Im5vbSI6IkZpbmlzdMOocmUiLCJjb2RlIjoiMjkifSx7Im5vbSI6IkNvcnNlLWR1LVN1ZCIsImNvZGUiOiIyQSJ9LHsibm9tIjoiSGF1dGUtQ29yc2UiLCJjb2RlIjoiMkIifSx7Im5vbSI6IkdhcmQiLCJjb2RlIjoiMzAifSx7Im5vbSI6IkhhdXRlLUdhcm9ubmUiLCJjb2RlIjoiMzEifSx7Im5vbSI6IkdlcnMiLCJjb2RlIjoiMzIifSx7Im5vbSI6Ikdpcm9uZGUiLCJjb2RlIjoiMzMifSx7Im5vbSI6IkjDqXJhdWx0IiwiY29kZSI6IjM0In0seyJub20iOiJJbGxlLWV0LVZpbGFpbmUiLCJjb2RlIjoiMzUifSx7Im5vbSI6IkluZHJlIiwiY29kZSI6IjM2In0seyJub20iOiJJbmRyZS1ldC1Mb2lyZSIsImNvZGUiOiIzNyJ9LHsibm9tIjoiSXPDqHJlIiwiY29kZSI6IjM4In0seyJub20iOiJKdXJhIiwiY29kZSI6IjM5In0seyJub20iOiJMYW5kZXMiLCJjb2RlIjoiNDAifSx7Im5vbSI6IkxvaXItZXQtQ2hlciIsImNvZGUiOiI0MSJ9LHsibm9tIjoiTG9pcmUiLCJjb2RlIjoiNDIifSx7Im5vbSI6IkhhdXRlLUxvaXJlIiwiY29kZSI6IjQzIn0seyJub20iOiJMb2lyZS1BdGxhbnRpcXVlIiwiY29kZSI6IjQ0In0seyJub20iOiJMb2lyZXQiLCJjb2RlIjoiNDUifSx7Im5vbSI6IkxvdCIsImNvZGUiOiI0NiJ9LHsibm9tIjoiTG90LWV0LUdhcm9ubmUiLCJjb2RlIjoiNDcifSx7Im5vbSI6IkxvesOocmUiLCJjb2RlIjoiNDgifSx7Im5vbSI6Ik1haW5lLWV0LUxvaXJlIiwiY29kZSI6IjQ5In0seyJub20iOiJNYW5jaGUiLCJjb2RlIjoiNTAifSx7Im5vbSI6Ik1hcm5lIiwiY29kZSI6IjUxIn0seyJub20iOiJIYXV0ZS1NYXJuZSIsImNvZGUiOiI1MiJ9LHsibm9tIjoiTWF5ZW5uZSIsImNvZGUiOiI1MyJ9LHsibm9tIjoiTWV1cnRoZS1ldC1Nb3NlbGxlIiwiY29kZSI6IjU0In0seyJub20iOiJNZXVzZSIsImNvZGUiOiI1NSJ9LHsibm9tIjoiTW9yYmloYW4iLCJjb2RlIjoiNTYifSx7Im5vbSI6Ik1vc2VsbGUiLCJjb2RlIjoiNTcifSx7Im5vbSI6Ik5pw6h2cmUiLCJjb2RlIjoiNTgifSx7Im5vbSI6Ik5vcmQiLCJjb2RlIjoiNTkifSx7Im5vbSI6Ik9pc2UiLCJjb2RlIjoiNjAifSx7Im5vbSI6Ik9ybmUiLCJjb2RlIjoiNjEifSx7Im5vbSI6IlBhcy1kZS1DYWxhaXMiLCJjb2RlIjoiNjIifSx7Im5vbSI6IlB1eS1kZS1Ew7RtZSIsImNvZGUiOiI2MyJ9LHsibm9tIjoiUHlyw6luw6llcy1BdGxhbnRpcXVlcyIsImNvZGUiOiI2NCJ9LHsibm9tIjoiSGF1dGVzLVB5csOpbsOpZXMiLCJjb2RlIjoiNjUifSx7Im5vbSI6IlB5csOpbsOpZXMtT3JpZW50YWxlcyIsImNvZGUiOiI2NiJ9LHsibm9tIjoiQmFzLVJoaW4iLCJjb2RlIjoiNjcifSx7Im5vbSI6IkhhdXQtUmhpbiIsImNvZGUiOiI2OCJ9LHsibm9tIjoiUmjDtG5lIiwiY29kZSI6IjY5In0seyJub20iOiJIYXV0ZS1TYcO0bmUiLCJjb2RlIjoiNzAifSx7Im5vbSI6IlNhw7RuZS1ldC1Mb2lyZSIsImNvZGUiOiI3MSJ9LHsibm9tIjoiU2FydGhlIiwiY29kZSI6IjcyIn0seyJub20iOiJTYXZvaWUiLCJjb2RlIjoiNzMifSx7Im5vbSI6IkhhdXRlLVNhdm9pZSIsImNvZGUiOiI3NCJ9LHsibm9tIjoiUGFyaXMiLCJjb2RlIjoiNzUifSx7Im5vbSI6IlNlaW5lLU1hcml0aW1lIiwiY29kZSI6Ijc2In0seyJub20iOiJTZWluZS1ldC1NYXJuZSIsImNvZGUiOiI3NyJ9LHsibm9tIjoiWXZlbGluZXMiLCJjb2RlIjoiNzgifSx7Im5vbSI6IkRldXgtU8OodnJlcyIsImNvZGUiOiI3OSJ9LHsibm9tIjoiU29tbWUiLCJjb2RlIjoiODAifSx7Im5vbSI6IlRhcm4iLCJjb2RlIjoiODEifSx7Im5vbSI6IlRhcm4tZXQtR2Fyb25uZSIsImNvZGUiOiI4MiJ9LHsibm9tIjoiVmFyIiwiY29kZSI6IjgzIn0seyJub20iOiJWYXVjbHVzZSIsImNvZGUiOiI4NCJ9LHsibm9tIjoiVmVuZMOpZSIsImNvZGUiOiI4NSJ9LHsibm9tIjoiVmllbm5lIiwiY29kZSI6Ijg2In0seyJub20iOiJIYXV0ZS1WaWVubmUiLCJjb2RlIjoiODcifSx7Im5vbSI6IlZvc2dlcyIsImNvZGUiOiI4OCJ9LHsibm9tIjoiWW9ubmUiLCJjb2RlIjoiODkifSx7Im5vbSI6IlRlcnJpdG9pcmUgZGUgQmVsZm9ydCIsImNvZGUiOiI5MCJ9LHsibm9tIjoiRXNzb25uZSIsImNvZGUiOiI5MSJ9LHsibm9tIjoiSGF1dHMtZGUtU2VpbmUiLCJjb2RlIjoiOTIifSx7Im5vbSI6IlNlaW5lLVNhaW50LURlbmlzIiwiY29kZSI6IjkzIn0seyJub20iOiJWYWwtZGUtTWFybmUiLCJjb2RlIjoiOTQifSx7Im5vbSI6IlZhbC1kJ09pc2UiLCJjb2RlIjoiOTUifSx7Im5vbSI6Ikd1YWRlbG91cGUiLCJjb2RlIjoiOTcxIn0seyJub20iOiJNYXJ0aW5pcXVlIiwiY29kZSI6Ijk3MiJ9LHsibm9tIjoiR3V5YW5lIiwiY29kZSI6Ijk3MyJ9LHsibm9tIjoiTGEgUsOpdW5pb24iLCJjb2RlIjoiOTc0In0seyJub20iOiJNYXlvdHRlIiwiY29kZSI6Ijk3NiJ9XQ==
- http_version:
- recorded_at: Tue, 23 Oct 2018 13:11:36 GMT
-recorded_with: VCR 4.0.0
diff --git a/spec/fixtures/cassettes/api_geo_regions.yml b/spec/fixtures/cassettes/api_geo_regions.yml
deleted file mode 100644
index 0d1c6a182..000000000
--- a/spec/fixtures/cassettes/api_geo_regions.yml
+++ /dev/null
@@ -1,51 +0,0 @@
----
-http_interactions:
-- request:
- method: get
- uri: https://geo.api.gouv.fr/regions?fields=nom
- body:
- encoding: US-ASCII
- string: ''
- headers:
- User-Agent:
- - demarches-simplifiees.fr
- Accept:
- - application/json
- Accept-Encoding:
- - gzip, deflate
- Expect:
- - ''
- response:
- status:
- code: 200
- message: OK
- headers:
- Server:
- - nginx/1.10.3 (Ubuntu)
- Date:
- - Tue, 23 Oct 2018 13:11:36 GMT
- Content-Type:
- - application/json; charset=utf-8
- Transfer-Encoding:
- - chunked
- Connection:
- - keep-alive
- Vary:
- - Accept-Encoding
- X-Powered-By:
- - Express
- Access-Control-Allow-Origin:
- - "*"
- Etag:
- - W/"28d-5OgIzgwL+0K2UaO0foKduqMMBrA"
- Strict-Transport-Security:
- - max-age=15552000
- Content-Encoding:
- - gzip
- body:
- encoding: ASCII-8BIT
- string: !binary |-
- W3sibm9tIjoiR3VhZGVsb3VwZSIsImNvZGUiOiIwMSJ9LHsibm9tIjoiTWFydGluaXF1ZSIsImNvZGUiOiIwMiJ9LHsibm9tIjoiR3V5YW5lIiwiY29kZSI6IjAzIn0seyJub20iOiJMYSBSw6l1bmlvbiIsImNvZGUiOiIwNCJ9LHsibm9tIjoiTWF5b3R0ZSIsImNvZGUiOiIwNiJ9LHsibm9tIjoiw45sZS1kZS1GcmFuY2UiLCJjb2RlIjoiMTEifSx7Im5vbSI6IkNlbnRyZS1WYWwgZGUgTG9pcmUiLCJjb2RlIjoiMjQifSx7Im5vbSI6IkJvdXJnb2duZS1GcmFuY2hlLUNvbXTDqSIsImNvZGUiOiIyNyJ9LHsibm9tIjoiTm9ybWFuZGllIiwiY29kZSI6IjI4In0seyJub20iOiJIYXV0cy1kZS1GcmFuY2UiLCJjb2RlIjoiMzIifSx7Im5vbSI6IkdyYW5kIEVzdCIsImNvZGUiOiI0NCJ9LHsibm9tIjoiUGF5cyBkZSBsYSBMb2lyZSIsImNvZGUiOiI1MiJ9LHsibm9tIjoiQnJldGFnbmUiLCJjb2RlIjoiNTMifSx7Im5vbSI6Ik5vdXZlbGxlLUFxdWl0YWluZSIsImNvZGUiOiI3NSJ9LHsibm9tIjoiT2NjaXRhbmllIiwiY29kZSI6Ijc2In0seyJub20iOiJBdXZlcmduZS1SaMO0bmUtQWxwZXMiLCJjb2RlIjoiODQifSx7Im5vbSI6IlByb3ZlbmNlLUFscGVzLUPDtHRlIGQnQXp1ciIsImNvZGUiOiI5MyJ9LHsibm9tIjoiQ29yc2UiLCJjb2RlIjoiOTQifV0=
- http_version:
- recorded_at: Tue, 23 Oct 2018 13:11:36 GMT
-recorded_with: VCR 4.0.0
diff --git a/spec/fixtures/cassettes/api_geo_search_rpg.yml b/spec/fixtures/cassettes/api_geo_search_rpg.yml
deleted file mode 100644
index 97b72996a..000000000
--- a/spec/fixtures/cassettes/api_geo_search_rpg.yml
+++ /dev/null
@@ -1,51 +0,0 @@
----
-http_interactions:
-- request:
- method: post
- uri: https://sandbox.geo.api.gouv.fr/rpg/parcelles/search
- body:
- encoding: UTF-8
- string: '{"polygonIntersects":{"type":"Polygon","coordinates":[[[2.3945903778076176,46.53312237252731],[2.394933700561524,46.532590956418076],[2.3948478698730473,46.53170525134736],[2.393732070922852,46.530760483351195],[2.3909854888916016,46.5309376286023],[2.391414642333985,46.531232869403546],[2.3913288116455083,46.53253190986272],[2.39278793334961,46.53329951007484],[2.3945903778076176,46.53312237252731]]]}}'
- headers:
- User-Agent:
- - demarches-simplifiees.fr
- Accept:
- - application/json
- Accept-Encoding:
- - gzip, deflate
- Content-Type:
- - application/json
- Expect:
- - ''
- response:
- status:
- code: 200
- message: OK
- headers:
- Server:
- - nginx/1.10.3 (Ubuntu)
- Date:
- - Tue, 23 Oct 2018 14:47:12 GMT
- Content-Type:
- - application/json; charset=utf-8
- Transfer-Encoding:
- - chunked
- Connection:
- - keep-alive
- Vary:
- - Accept-Encoding
- X-Powered-By:
- - Express
- Access-Control-Allow-Origin:
- - "*"
- Etag:
- - W/"fb0-ripeBc2xednIfUlCdOtrk6Vbny4"
- Content-Encoding:
- - gzip
- body:
- encoding: ASCII-8BIT
- string: !binary |-
- eyJ0eXBlIjoiRmVhdHVyZUNvbGxlY3Rpb24iLCJmZWF0dXJlcyI6W3sidHlwZSI6IkZlYXR1cmUiLCJwcm9wZXJ0aWVzIjp7ImlkIjoiODA2MzQzNSIsInN1cmZhY2UiOjExLjgsImJpbyI6ZmFsc2UsImNvZGVDdWx0dXJlIjoiUFBIIiwiY3VsdHVyZSI6IlByYWlyaWUgcGVybWFuZW50ZSAtIGhlcmJlIChyZXNzb3VyY2VzIGZvdXJyYWfDqHJlcyBsaWduZXVzZXMgYWJzZW50ZXMgb3UgcGV1IHByw6lzZW50ZXMpIn0sImdlb21ldHJ5Ijp7InR5cGUiOiJQb2x5Z29uIiwiY29vcmRpbmF0ZXMiOltbWzIuMzk2Mzg4ODA5NzM4NDQ3LDQ2LjUzMjYyMDU0MzY5NzY5Nl0sWzIuMzk2ODU4MDg0NjQyNDgsNDYuNTMyMzE0MDQ0MzY4NTVdLFsyLjM5NzM4MzQ3MzYzNjMzNSw0Ni41MzE5NjEwMjE0MDQ5NDZdLFsyLjM5NzI1NjI1NTk4MjkxNCw0Ni41MzEzODkxMTc2MTI0OV0sWzIuMzk2ODg4NzQ5MDkxNTM4LDQ2LjUzMTE0NDQ1MjU5MzczNl0sWzIuMzk2MzM3NzA4MjcwMjU1LDQ2LjUzMDQzNjIzMDY5MDg0XSxbMi4zOTYzNDMzNzM4MTI2NjQsNDYuNTMwMTQxNDkxMjY3NDFdLFsyLjM5Njk5MDY1OTkxMTQyMyw0Ni41Mjk1ODE4NTQzNTkxM10sWzIuMzk0OTYxNTY4NjUwODI4LDQ2LjUyODI3ODQwMDkxMzE5NF0sWzIuMzk0NDM4MzY3MjUwMTgsNDYuNTI3NTc1MzE3NjY1OF0sWzIuMzkzMzM3MDUwMTU1MTg1LDQ2LjUyODA0MzU4MTM3OTg1XSxbMi4zOTMwNjgxOTg0MTQxNjQsNDYuNTI4MTgyOTQ0MTk3MDhdLFsyLjM5MjY4NTYyOTQzOTc2NCw0Ni41MjgzOTM3ODU1NjM3NF0sWzIuMzkyNTE1MDIzNDM3MzQxLDQ2LjUyODQ5NzQwNjU3MzNdLFsyLjM5MjQzNzUzMTU2MDc3OSw0Ni41Mjg2MDQ1NDc0NDgwN10sWzIuMzkyNDMyNDg3OTE3MTM1LDQ2LjUyODcxNTIzMzY5NzQ1XSxbMi4zOTI2MTMxOTU1MjgyMDgsNDYuNTI5MTMxMTM5NzEzODldLFsyLjM5Mzc1MTEzODE0NTU5OCw0Ni41MzA3NjM3NzY2OTQyNl0sWzIuMzk0MTA5MDExMjkyNjc0LDQ2LjUzMTQ2Mzk5ODkxMjk3XSxbMi4zOTQyNTAzODg3Njc4MzIsNDYuNTMxNjQ0MjU5MTk2MTVdLFsyLjM5NDg0MDExMjU5NTQ4Nyw0Ni41MzIxMDc4ODcyNzY0NzRdLFsyLjM5NjA2OTc0MzI0MzkyLDQ2LjUzMzA1NzQyMDg2MTA4XSxbMi4zOTYzNjI2NTU4MjAxNTUsNDYuNTMyNzQ3MTQyNTA4ODc1XSxbMi4zOTYzODg4MDk3Mzg0NDcsNDYuNTMyNjIwNTQzNjk3Njk2XV1dfX0seyJ0eXBlIjoiRmVhdHVyZSIsInByb3BlcnRpZXMiOnsiaWQiOiI4MDYzNDM5Iiwic3VyZmFjZSI6NTkuMTgsImJpbyI6ZmFsc2UsImNvZGVDdWx0dXJlIjoiUFBIIiwiY3VsdHVyZSI6IlByYWlyaWUgcGVybWFuZW50ZSAtIGhlcmJlIChyZXNzb3VyY2VzIGZvdXJyYWfDqHJlcyBsaWduZXVzZXMgYWJzZW50ZXMgb3UgcGV1IHByw6lzZW50ZXMpIn0sImdlb21ldHJ5Ijp7InR5cGUiOiJQb2x5Z29uIiwiY29vcmRpbmF0ZXMiOltbWzIuMzg5NDk0MDQzODI1MDI3LDQ2LjUyOTI0Nzc5NzQ3NTUwNl0sWzIuMzkwNzkyNTgzNjgyNzc4LDQ2LjUzMDYzMzg1NjIyMjAyNV0sWzIuMzkwNzQ0ODA3MzE0MzUzLDQ2LjUzMDY1NzY1MjUxNDc2XSxbMi4zODk5OTM4MTM3OTE0MjEsNDYuNTMxMDMxNzA0MDU4MjM2XSxbMi4zODg4ODc5NTc3OTMwNzMsNDYuNTI5OTU3MDE5NzA3MTI2XSxbMi4zODg3OTIxMjIwNTIxNzIsNDYuNTI5ODQ0MTM0MjM4NzZdLFsyLjM4ODc0NDIzNjc1OTU3MSw0Ni41Mjk3OTc4MjgyNjE5Nl0sWzIuMzg4MzIyMTM2MjgzMDYsNDYuNTMwMzQ0MzAyMDA4Ml0sWzIuMzg4MDc2NjM2MjY5MTczLDQ2LjUzMDc5Njk4NzQxNTY0XSxbMi4zODc3MzIwNjY0NDgxNjgsNDYuNTMyMjgwNzE2NDkyMzY2XSxbMi4zODcxMTU4ODI1MjM0OTIsNDYuNTMzMjY4NTU1OTE5NTA2XSxbMi4zODY5NjA1NDI4Njc3NTIsNDYuNTM0MTAzNDM3OTc1Mjc2XSxbMi4zODY2OTc1MTgyMzA5Nyw0Ni41MzYwOTEzMDc2NzQxNTVdLFsyLjM4NzIzODY4NDQ2NDE0Miw0Ni41MzYwNjEyNzIzMzg2NV0sWzIuMzg4MDkxNjcwNDM0ODA0LDQ2LjUzNjE0OTUxNzk2NzQ5NV0sWzIuMzg4NzcyOTExNTQzMDA5LDQ2LjUzNjMzNjc5MjE5ODY2XSxbMi4zODg5MzYwNjQ2MjQxNDQsNDYuNTM2NTQ4MDMxNjc4NzM0XSxbMi4zODg4ODQ1OTQ4MjIyMDMsNDYuNTM2ODMwMTA4NDkxNDRdLFsyLjM4ODQ2MTQwMDc2ODM5OCw0Ni41MzY5NzM5OTM5MzM4OF0sWzIuMzg3NDY5OTA3NzI4MzM3LDQ2LjUzNzM4NjY3MTIxNTA2XSxbMi4zODkzNDI2MzkxMjc2NjIsNDYuNTM3MDE1NzkwNzYyMzA0XSxbMi4zOTAzNDc4MDIyNzQyOTcsNDYuNTM2OTg2NTM2NjQ4MzM1XSxbMi4zOTEzODQ1ODYwNDM3NTYsNDYuNTM3MTY5NDkzNzYxMjldLFsyLjM5MjMxMjQxNzE4NTc2Miw0Ni41MzczNjg5NTM3ODk0MjVdLFsyLjM5MzYxOTE5MTc2NDg4MSw0Ni41Mzc0NTYyMTczOTA4OV0sWzIuMzk0MTQ2OTY0Mzk3NTY0LDQ2LjUzNzQ5NTIyOTk4NjgxXSxbMi4zOTUyMzQyMDk1NDAxMjQsNDYuNTM3NTY5NTYxMzk3Nzk1XSxbMi4zOTYyNzM1Mjc3ODcxOTQsNDYuNTM3NjMzMzgyMjQ3OTJdLFsyLjM5NzI0NjE3Njk4Mjc3LDQ2LjUzNzYxNTAxNjc0OTU4NF0sWzIuMzk4MDYzNTQ2OTc2NDEsNDYuNTM3NTM5NjA5ODg3OTZdLFsyLjQwMDMzNDg1MDcyNjM3Miw0Ni41MzczMTIyMzU4MzAyM10sWzIuNDAwNTQ1ODg2NjQ0OTQ5LDQ2LjUzNzI4OTI4Mjg2NjM5XSxbMi40MDExNTY4MjQwMzU5OCw0Ni41MzYzOTQ0NTk0MjMzOF0sWzIuNDAyNjI5Mzg5NTE5MTY2LDQ2LjUzNjI4ODQ0NTUwNTAxXSxbMi40MDQyOTc1OTkwNjgzMTYsNDYuNTM2MTUxNDM3NzA2MjRdLFsyLjQwNDI5NjYyODUxNzg1OCw0Ni41MzUzNzc4NTQzMjQ2XSxbMi40MDAzMjE2MDkwMzM3MjcsNDYuNTM2MTMxMDQ2OTE2Nl0sWzIuMzk5ODU5OTA4NzQ0Njc1LDQ2LjUzNjA4Mzg5MDg2NjQ4Nl0sWzIuMzk5NjU4OTc5NzIxNzU3LDQ2LjUzNTg5MjY4MTgyMDExXSxbMi40MDAyMTIwNzg5NDE1MzUsNDYuNTM1NTQ4OTA0MTU1NTNdLFsyLjM5OTAzMzAyNzMwNzc1Nyw0Ni41MzQwOTc3MDAxNjE3OF0sWzIuMzk2MzY1MzcyOTQ0MzQ5LDQ2LjUzMjc2Njg3ODk2MDI1XSxbMi4zOTYwNjkwMDE3NTk5MjUsNDYuNTMzMDgyNDEzMTIxMjg1XSxbMi4zOTU5MjU2NDI3OTYwMjYsNDYuNTMzMTMyNzU3MTQ3N10sWzIuMzk0MDcwMjI5MTg5MzYxLDQ2LjUzMTYxNTQ3MzQzMzE0XSxbMi4zOTM2OTAxODM3OTk0Myw0Ni41MzA4Njc0NDE5NDE3NDRdLFsyLjM5MzY4MTAwNTA5MzM1MSw0Ni41MzA4NTQ0MTc1MDQxOV0sWzIuMzkxNTMyMTkyOTYxNTYsNDYuNTMxMzQ5NTg3MDg0NjhdLFsyLjM4OTUzNDIxMDI1NTE2Niw0Ni41MjkyMzUzMjQxNTUyMl0sWzIuMzg5NDk0MDQzODI1MDI3LDQ2LjUyOTI0Nzc5NzQ3NTUwNl1dXX19LHsidHlwZSI6IkZlYXR1cmUiLCJwcm9wZXJ0aWVzIjp7ImlkIjoiODA2MzQ0MyIsInN1cmZhY2UiOjQuMjQsImJpbyI6ZmFsc2UsImNvZGVDdWx0dXJlIjoiUFBIIiwiY3VsdHVyZSI6IlByYWlyaWUgcGVybWFuZW50ZSAtIGhlcmJlIChyZXNzb3VyY2VzIGZvdXJyYWfDqHJlcyBsaWduZXVzZXMgYWJzZW50ZXMgb3UgcGV1IHByw6lzZW50ZXMpIn0sImdlb21ldHJ5Ijp7InR5cGUiOiJQb2x5Z29uIiwiY29vcmRpbmF0ZXMiOltbWzIuMzg5NTM0MjEwMjU1MTY2LDQ2LjUyOTIzNTMyNDE1NTIyXSxbMi4zOTE1MzIxOTI5NjE1Niw0Ni41MzEzNDk1ODcwODQ2OF0sWzIuMzkzNjgxMDA1MDkzMzUxLDQ2LjUzMDg1NDQxNzUwNDE5XSxbMi4zOTM2NzAwMDI0ODQyOSw0Ni41MzA4Mzg4MDM1NDg4M10sWzIuMzkyOTg5NTY3MDI4NjE0LDQ2LjUyOTg3MzIzMTQ2MTU5XSxbMi4zOTI0OTMxMDcyODQ3MjYsNDYuNTI5MTAxMzQ3NTE3OTVdLFsyLjM5MjMyMTkzMjkyOTI2NCw0Ni41Mjg2NzA0NDIzNTI4XSxbMi4zOTE0ODkyMDkyNzIyMzUsNDYuNTI4NzcwODEzMTQ0NzhdLFsyLjM5MDkxNTA4ODU5MTExLDQ2LjUyODg1Njc2OTY4NDM5XSxbMi4zOTA0NjUxMzI5MzMxODQsNDYuNTI4OTQ2MjM5NDQ1NzZdLFsyLjM4OTUzNDIxMDI1NTE2Niw0Ni41MjkyMzUzMjQxNTUyMl1dXX19XX0=
- http_version:
- recorded_at: Tue, 23 Oct 2018 14:47:12 GMT
-recorded_with: VCR 4.0.0
diff --git a/spec/lib/api_adresse/address_adapter_spec.rb b/spec/lib/api_adresse/address_adapter_spec.rb
deleted file mode 100644
index 31a1d7bc3..000000000
--- a/spec/lib/api_adresse/address_adapter_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-require 'spec_helper'
-
-describe ApiAdresse::AddressAdapter do
- describe '#get_suggestions' do
- let(:request) { 'Paris' }
- let(:response) { File.open('spec/fixtures/files/api_adresse/search_results.json') }
- let(:status) { 200 }
-
- subject { described_class.new(request).get_suggestions }
-
- before do
- stub_request(:get, "https://api-adresse.data.gouv.fr/search?&q=#{request}&limit=5")
- .to_return(status: status, body: response, headers: {})
- end
-
- context 'when address return a list of address' do
- it { expect(subject.size).to eq 5 }
- it { is_expected.to be_an_instance_of Array }
- end
-
- context 'when address return an empty list' do
- let(:response) { File.open('spec/fixtures/files/api_adresse/search_no_results.json') }
-
- it { expect(subject.size).to eq 0 }
- it { is_expected.to be_an_instance_of Array }
- end
-
- context 'when BAN is unavailable' do
- let(:status) { 503 }
- let(:response) { '' }
-
- it { expect(subject.size).to eq 0 }
- it { is_expected.to be_an_instance_of Array }
- end
-
- context 'when request is empty' do
- let(:response) { 'Missing query' }
- let(:request) { '' }
-
- it { expect(subject.size).to eq 0 }
- it { is_expected.to be_an_instance_of Array }
- end
- end
-end
diff --git a/spec/lib/api_adresse/point_adapter_spec.rb b/spec/lib/api_adresse/point_adapter_spec.rb
deleted file mode 100644
index 9f21c8dd5..000000000
--- a/spec/lib/api_adresse/point_adapter_spec.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-require 'spec_helper'
-
-describe ApiAdresse::PointAdapter do
- let(:address) { '50 av des champs elysees' }
-
- describe '.geocode', vcr: { cassette_name: 'api_adresse_octo' } do
- it 'return a point' do
- expect(described_class.new(address).geocode.class).to eq(RGeo::Cartesian::PointImpl)
- end
-
- context 'when RestClient::Exception' do
- before do
- allow(ApiAdresse::API).to receive(:call).and_raise(RestClient::Exception)
- end
-
- it 'return nil' do
- expect(described_class.new(address).geocode).to be_nil
- end
- end
-
- context 'when JSON::ParserError' do
- before do
- allow(JSON).to receive(:parse).and_raise(JSON::ParserError)
- end
-
- it 'return nil' do
- expect(described_class.new(address).geocode).to be_nil
- end
- end
- end
-end
diff --git a/spec/lib/api_geo/api_spec.rb b/spec/lib/api_geo/api_spec.rb
deleted file mode 100644
index 6a046f119..000000000
--- a/spec/lib/api_geo/api_spec.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-require 'spec_helper'
-
-describe ApiGeo::API do
- describe '.regions', vcr: { cassette_name: 'api_geo_regions' } do
- subject { described_class.regions }
-
- it { expect(subject.size).to eq 18 }
- end
-
- describe '.departements', vcr: { cassette_name: 'api_geo_departements' } do
- subject { described_class.departements }
-
- it { expect(subject.size).to eq 101 }
- end
-
- describe '.pays' do
- subject { described_class.pays }
- let(:pays) {
- JSON.parse(File.open('app/lib/api_geo/pays.json').read, symbolize_names: true)
- }
-
- it { is_expected.to eq pays }
- end
-
- describe '.search_rpg', vcr: { cassette_name: 'api_geo_search_rpg' } do
- let(:coordinates) do
- [
- [
- 2.3945903778076176,
- 46.53312237252731
- ],
- [
- 2.394933700561524,
- 46.532590956418076
- ],
- [
- 2.3948478698730473,
- 46.53170525134736
- ],
- [
- 2.393732070922852,
- 46.530760483351195
- ],
- [
- 2.3909854888916016,
- 46.5309376286023
- ],
- [
- 2.391414642333985,
- 46.531232869403546
- ],
- [
- 2.3913288116455083,
- 46.53253190986272
- ],
- [
- 2.39278793334961,
- 46.53329951007484
- ],
- [
- 2.3945903778076176,
- 46.53312237252731
- ]
- ]
- end
-
- let(:geo_json) {
- GeojsonService.to_json_polygon_for_rpg(coordinates)
- }
-
- subject { described_class.search_rpg(geo_json) }
-
- it { expect(subject[:features].size).to eq 3 }
- end
-end
diff --git a/spec/lib/api_geo/rpg_adapter_spec.rb b/spec/lib/api_geo/rpg_adapter_spec.rb
deleted file mode 100644
index 5c277a15a..000000000
--- a/spec/lib/api_geo/rpg_adapter_spec.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-require 'spec_helper'
-
-describe ApiGeo::RPGAdapter do
- subject { described_class.new(coordinates).results }
-
- let(:coordinates) do
- [
- [
- 2.3945903778076176,
- 46.53312237252731
- ],
- [
- 2.394933700561524,
- 46.532590956418076
- ],
- [
- 2.3948478698730473,
- 46.53170525134736
- ],
- [
- 2.393732070922852,
- 46.530760483351195
- ],
- [
- 2.3909854888916016,
- 46.5309376286023
- ],
- [
- 2.391414642333985,
- 46.531232869403546
- ],
- [
- 2.3913288116455083,
- 46.53253190986272
- ],
- [
- 2.39278793334961,
- 46.53329951007484
- ],
- [
- 2.3945903778076176,
- 46.53312237252731
- ]
- ]
- end
-
- context 'coordinates are filled', vcr: { cassette_name: 'api_geo_search_rpg' } do
- describe 'Attribut filter' do
- it { expect(subject.size).to eq(3) }
- it do
- expect(subject.first.keys).to eq([
- :culture,
- :code_culture,
- :surface,
- :bio,
- :geometry,
- :geo_reference_id
- ])
- end
- end
- end
-end
diff --git a/spec/models/administrateur_spec.rb b/spec/models/administrateur_spec.rb
index 9f0c30923..3e6864466 100644
--- a/spec/models/administrateur_spec.rb
+++ b/spec/models/administrateur_spec.rb
@@ -46,6 +46,21 @@ describe Administrateur, type: :model do
end
end
+ describe '#delete_and_transfer_services' do
+ let!(:administrateur) { create(:administrateur) }
+ let!(:autre_administrateur) { create(:administrateur) }
+ let!(:procedure) { create(:procedure, :with_service, administrateurs: [administrateur, autre_administrateur]) }
+ let(:service) { procedure.service }
+
+ it "delete and transfer services to other admin" do
+ service.update(administrateur: administrateur)
+ administrateur.delete_and_transfer_services
+
+ expect(Administrateur.find_by(id: administrateur.id)).to be_nil
+ expect(service.reload.administrateur).to eq(autre_administrateur)
+ end
+ end
+
# describe '#password_complexity' do
# let(:email) { 'mail@beta.gouv.fr' }
# let(:passwords) { ['pass', '12pass23', 'démarches ', 'démarches-simple', 'démarches-simplifiées-pwd'] }
diff --git a/spec/models/champ_shared_example.rb b/spec/models/champ_shared_example.rb
index 31ae546fa..d00af9504 100644
--- a/spec/models/champ_shared_example.rb
+++ b/spec/models/champ_shared_example.rb
@@ -32,12 +32,6 @@ shared_examples 'champ_spec' do
end
end
- describe '.departement', vcr: { cassette_name: 'api_geo_departements' } do
- subject { Champs::DepartementChamp.departements }
-
- it { expect(subject).to include '99 - Étranger' }
- end
-
context "when type_champ=date" do
let(:type_de_champ) { create(:type_de_champ_date) }
let(:champ) { type_de_champ.champ.create }
diff --git a/spec/models/dossier_spec.rb b/spec/models/dossier_spec.rb
index 5167b274e..d1ae1d8ca 100644
--- a/spec/models/dossier_spec.rb
+++ b/spec/models/dossier_spec.rb
@@ -1084,4 +1084,39 @@ describe Dossier do
expect { expired_brouillon.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
end
+
+ describe '#geo_position' do
+ let(:lat) { "46.538192" }
+ let(:lon) { "2.428462" }
+ let(:zoom) { "13" }
+
+ let(:etablissement_geo_adresse_lat) { "40.7143528" }
+ let(:etablissement_geo_adresse_lon) { "-74.0059731" }
+
+ let(:result) { { lat: lat, lon: lon, zoom: zoom } }
+ let(:dossier) { create(:dossier) }
+
+ it 'should geolocate' do
+ expect(dossier.geo_position).to eq(result)
+ end
+
+ context 'with etablissement' do
+ before do
+ Geocoder::Lookup::Test.add_stub(
+ dossier.etablissement.geo_adresse, [
+ {
+ 'coordinates' => [etablissement_geo_adresse_lat.to_f, etablissement_geo_adresse_lon.to_f]
+ }
+ ]
+ )
+ end
+
+ let(:dossier) { create(:dossier, :with_entreprise) }
+ let(:result) { { lat: etablissement_geo_adresse_lat, lon: etablissement_geo_adresse_lon, zoom: zoom } }
+
+ it 'should geolocate' do
+ expect(dossier.geo_position).to eq(result)
+ end
+ end
+ end
end
diff --git a/spec/models/instructeur_spec.rb b/spec/models/instructeur_spec.rb
index 37917bf18..78737bf89 100644
--- a/spec/models/instructeur_spec.rb
+++ b/spec/models/instructeur_spec.rb
@@ -424,9 +424,40 @@ describe Instructeur, type: :model do
it { expect(instructeur_a.procedures.all.to_ary).to eq([procedure_a]) }
end
+ describe "#can_be_deleted?" do
+ subject { instructeur.can_be_deleted? }
+
+ context 'when the instructeur is an administrateur' do
+ let!(:administrateur) { create(:administrateur) }
+ let(:instructeur) { administrateur.instructeur }
+
+ it { is_expected.to be false }
+ end
+
+ context "when the instructeur's procedures have other instructeurs" do
+ let(:instructeur_not_admin) { create(:instructeur) }
+ let(:autre_instructeur) { create(:instructeur) }
+
+ it "can be deleted" do
+ assign(procedure, instructeur_assigne: instructeur_not_admin)
+ assign(procedure, instructeur_assigne: autre_instructeur)
+ expect(autre_instructeur.can_be_deleted?).to be_truthy
+ end
+ end
+
+ context "when the instructeur's procedures is the only one" do
+ let(:instructeur_not_admin) { create :instructeur }
+ let(:autre_procedure) { create :procedure }
+ it "can be deleted" do
+ assign(autre_procedure, instructeur_assigne: instructeur_not_admin)
+ expect(instructeur_not_admin.can_be_deleted?).to be_falsy
+ end
+ end
+ end
+
private
- def assign(procedure_to_assign)
- create :assign_to, instructeur: instructeur, procedure: procedure_to_assign, groupe_instructeur: procedure_to_assign.defaut_groupe_instructeur
+ def assign(procedure_to_assign, instructeur_assigne: instructeur)
+ create :assign_to, instructeur: instructeur_assigne, procedure: procedure_to_assign, groupe_instructeur: procedure_to_assign.defaut_groupe_instructeur
end
end
diff --git a/spec/models/procedure_overview_spec.rb b/spec/models/procedure_overview_spec.rb
index 06f0b291d..62f571e67 100644
--- a/spec/models/procedure_overview_spec.rb
+++ b/spec/models/procedure_overview_spec.rb
@@ -8,7 +8,7 @@ describe ProcedureOverview, type: :model do
before { Timecop.freeze(friday) }
after { Timecop.return }
- let(:procedure_overview) { ProcedureOverview.new(procedure, monday) }
+ let(:procedure_overview) { ProcedureOverview.new(procedure, monday, [procedure.defaut_groupe_instructeur]) }
describe 'dossiers_en_instruction_count' do
let!(:en_instruction_dossier) do
@@ -56,6 +56,27 @@ describe ProcedureOverview, type: :model do
it { expect(procedure_overview.created_dossiers_count).to eq(1) }
end
+ describe 'with a procedure routee' do
+ let!(:gi_2) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 2') }
+ let!(:gi_3) { procedure.groupe_instructeurs.create(label: 'groupe instructeur 3') }
+
+ def create_dossier_in_group(g)
+ create(:dossier, procedure: procedure, created_at: monday, state: Dossier.states.fetch(:en_instruction), groupe_instructeur: g)
+ end
+
+ let!(:created_dossier_during_the_week_on_group_2) { create_dossier_in_group(gi_2) }
+ let!(:created_dossier_during_the_week_on_group_3_a) { create_dossier_in_group(gi_3) }
+ let!(:created_dossier_during_the_week_on_group_3_b) { create_dossier_in_group(gi_3) }
+
+ let(:procedure_overview_gi_2) { ProcedureOverview.new(procedure, monday, [gi_2]) }
+ let(:procedure_overview_gi_3) { ProcedureOverview.new(procedure, monday, [gi_3]) }
+ let(:procedure_overview_default) { ProcedureOverview.new(procedure, monday, [procedure.defaut_groupe_instructeur]) }
+
+ it { expect(procedure_overview_gi_2.created_dossiers_count).to eq(1) }
+ it { expect(procedure_overview_gi_3.created_dossiers_count).to eq(2) }
+ it { expect(procedure_overview_default.created_dossiers_count).to eq(0) }
+ end
+
describe 'had_some_activities?' do
subject { procedure_overview.had_some_activities? }
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index b127d35c6..19b317f40 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -224,6 +224,24 @@ describe User, type: :model do
context 'when the user has no dossier in instruction' do
it { is_expected.to be true }
end
+
+ context 'when the user is an administrateur' do
+ it 'cannot be deleted' do
+ administrateur = create(:administrateur)
+ user = administrateur.user
+
+ expect(user.can_be_deleted?).to be_falsy
+ end
+ end
+
+ context 'when the user is an instructeur' do
+ it 'cannot be deleted' do
+ instructeur = create(:instructeur)
+ user = instructeur.user
+
+ expect(user.can_be_deleted?).to be_falsy
+ end
+ end
end
describe '#delete_and_keep_track_dossiers' do
@@ -241,12 +259,29 @@ describe User, type: :model do
let!(:dossier_en_construction) { create(:dossier, :en_construction, user: user) }
let!(:dossier_brouillon) { create(:dossier, user: user) }
- it "keep track of dossiers and delete user" do
- user.delete_and_keep_track_dossiers(administration)
+ context 'without a hidden dossier' do
+ it "keep track of dossiers and delete user" do
+ user.delete_and_keep_track_dossiers(administration)
- expect(DeletedDossier.find_by(dossier_id: dossier_en_construction)).to be_present
- expect(DeletedDossier.find_by(dossier_id: dossier_brouillon)).to be_present
- expect(User.find_by(id: user.id)).to be_nil
+ expect(DeletedDossier.find_by(dossier_id: dossier_en_construction)).to be_present
+ expect(DeletedDossier.find_by(dossier_id: dossier_brouillon)).to be_present
+ expect(User.find_by(id: user.id)).to be_nil
+ end
+ end
+
+ context 'with a hidden dossier' do
+ let!(:dossier_cache) do
+ create(:dossier, :en_construction, user: user)
+ end
+
+ it "keep track of dossiers and delete user" do
+ dossier_cache.delete_and_keep_track(administration)
+ user.delete_and_keep_track_dossiers(administration)
+
+ expect(DeletedDossier.find_by(dossier_id: dossier_en_construction)).to be_present
+ expect(DeletedDossier.find_by(dossier_id: dossier_brouillon)).to be_present
+ expect(User.find_by(id: user.id)).to be_nil
+ end
end
end
end
diff --git a/spec/services/procedure_export_service_spec.rb b/spec/services/procedure_export_service_spec.rb
index 8be461c80..eb58aed07 100644
--- a/spec/services/procedure_export_service_spec.rb
+++ b/spec/services/procedure_export_service_spec.rb
@@ -69,6 +69,7 @@ describe ProcedureExportService do
"pays",
"regions",
"departements",
+ "communes",
"engagement",
"dossier_link",
"piece_justificative",
@@ -142,6 +143,7 @@ describe ProcedureExportService do
"pays",
"regions",
"departements",
+ "communes",
"engagement",
"dossier_link",
"piece_justificative",
@@ -220,6 +222,7 @@ describe ProcedureExportService do
"pays",
"regions",
"departements",
+ "communes",
"engagement",
"dossier_link",
"piece_justificative",
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 538b95806..f5e6de454 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -152,6 +152,8 @@ RSpec.configure do |config|
ActionMailer::Base.deliveries.clear
ActiveStorage::Current.host = 'http://test.host'
+
+ Geocoder.configure(lookup: :test)
}
RSpec::Matchers.define :have_same_attributes_as do |expected, options|
diff --git a/yarn.lock b/yarn.lock
index ff57a5c76..8a6b6baaa 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1521,13 +1521,6 @@ atob@^2.1.1:
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
-autocomplete.js@^0.37.0:
- version "0.37.0"
- resolved "https://registry.yarnpkg.com/autocomplete.js/-/autocomplete.js-0.37.0.tgz#bcfbfd7bcabe90e90fad4c2b1aaa931379a10c38"
- integrity sha512-MxYfNb89sl7IRhNdEJv6z8dSfA7lVeU7Dk6m/+/ih0/tPLsbxIM7uPVsnWEUh4j7dFqJktlM7hCeU7jmx6VC8A==
- dependencies:
- immediate "^3.2.3"
-
autoprefixer@^9.4.9:
version "9.5.1"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.5.1.tgz#243b1267b67e7e947f28919d786b50d3bb0fb357"
@@ -4362,11 +4355,6 @@ ignore@^4.0.6:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
-immediate@^3.2.3:
- version "3.2.3"
- resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.2.3.tgz#d140fa8f614659bd6541233097ddaac25cdd991c"
- integrity sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=
-
import-cwd@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"