From dd80cc280a135e13a1a448f4628befc2a087415a Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 23 Oct 2018 10:55:59 +0200 Subject: [PATCH 01/14] [#2604] Extract method in ProceduresController --- app/controllers/new_gestionnaire/procedures_controller.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/controllers/new_gestionnaire/procedures_controller.rb b/app/controllers/new_gestionnaire/procedures_controller.rb index 5fe1f2425..71ba18093 100644 --- a/app/controllers/new_gestionnaire/procedures_controller.rb +++ b/app/controllers/new_gestionnaire/procedures_controller.rb @@ -208,7 +208,11 @@ module NewGestionnaire end def procedure_presentation - @procedure_presentation ||= current_gestionnaire.procedure_presentation_for_procedure_id(params[:procedure_id]) + @procedure_presentation ||= get_procedure_presentation + end + + def get_procedure_presentation + current_gestionnaire.procedure_presentation_for_procedure_id(params[:procedure_id]) end def displayed_fields_values From 86f01a91205eae7541c5ec949ca821f71d42f859 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 23 Oct 2018 11:03:43 +0200 Subject: [PATCH 02/14] [#2604] Factor AssignTo spec --- spec/models/assign_to_spec.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/spec/models/assign_to_spec.rb b/spec/models/assign_to_spec.rb index b0d62ded4..8cec3dfdd 100644 --- a/spec/models/assign_to_spec.rb +++ b/spec/models/assign_to_spec.rb @@ -1,17 +1,18 @@ describe AssignTo, type: :model do describe '#procedure_presentation_or_default' do - context "without a procedure_presentation" do - let!(:assign_to) { AssignTo.create } + let(:procedure) { create(:procedure) } + let(:assign_to) { AssignTo.create(procedure: procedure) } - it { expect(assign_to.procedure_presentation_or_default.persisted?).to be_falsey } + let(:procedure_presentation_or_default) { assign_to.procedure_presentation_or_default } + + context "without a procedure_presentation" do + it { expect(procedure_presentation_or_default.persisted?).to be_falsey } end context "with a procedure_presentation" do - let(:procedure) { create(:procedure) } - let!(:assign_to) { AssignTo.create(procedure: procedure) } let!(:procedure_presentation) { ProcedurePresentation.create(assign_to: assign_to) } - it { expect(assign_to.procedure_presentation_or_default).to eq(procedure_presentation) } + it { expect(procedure_presentation_or_default).to eq(procedure_presentation) } end end end From 91cfa69220de09d3132dded485e798c3ed3e20d5 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 23 Oct 2018 11:04:21 +0200 Subject: [PATCH 03/14] [#2604] Clean up AssignTo spec --- spec/models/assign_to_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/assign_to_spec.rb b/spec/models/assign_to_spec.rb index 8cec3dfdd..9b520c188 100644 --- a/spec/models/assign_to_spec.rb +++ b/spec/models/assign_to_spec.rb @@ -6,7 +6,7 @@ describe AssignTo, type: :model do let(:procedure_presentation_or_default) { assign_to.procedure_presentation_or_default } context "without a procedure_presentation" do - it { expect(procedure_presentation_or_default.persisted?).to be_falsey } + it { expect(procedure_presentation_or_default).not_to be_persisted } end context "with a procedure_presentation" do From eab8da43fcd638331f2b2347cae1390d6720ae55 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 23 Oct 2018 11:20:16 +0200 Subject: [PATCH 04/14] [#2604] Introduce explicit context in GestionnaireSpec --- spec/models/gestionnaire_spec.rb | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index b853c9e2c..6a2b1948e 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -198,10 +198,20 @@ describe Gestionnaire, type: :model do end describe "procedure_presentation_for_procedure_id" do - let!(:pp) { ProcedurePresentation.create(assign_to: procedure_assign) } + let(:procedure_presentation) { gestionnaire.procedure_presentation_for_procedure_id(procedure_id) } - it { expect(gestionnaire.procedure_presentation_for_procedure_id(procedure.id)).to eq(pp) } - it { expect(gestionnaire.procedure_presentation_for_procedure_id(procedure_2.id).persisted?).to be_falsey } + context 'with explicit presentation' do + let(:procedure_id) { procedure.id } + let!(:pp) { ProcedurePresentation.create(assign_to: procedure_assign) } + + it { expect(procedure_presentation).to eq(pp) } + end + + context 'with default presentation' do + let(:procedure_id) { procedure_2.id } + + it { expect(procedure_presentation.persisted?).to be_falsey } + end end describe '#notifications_for_dossier' do From 85f698bc712f94a47438cc64c5534b9ead4f1fe6 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 23 Oct 2018 11:21:32 +0200 Subject: [PATCH 05/14] [#2604] Clean up GestionnaireSpec --- spec/models/gestionnaire_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index 6a2b1948e..fc9ab72bc 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -210,7 +210,7 @@ describe Gestionnaire, type: :model do context 'with default presentation' do let(:procedure_id) { procedure_2.id } - it { expect(procedure_presentation.persisted?).to be_falsey } + it { expect(procedure_presentation).not_to be_persisted } end end From 84cac7a5c28534cac08189fd1dd784141b7b4863 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 23 Oct 2018 11:34:11 +0200 Subject: [PATCH 06/14] [#2604] Remove unneeded self in AssignTo --- app/models/assign_to.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/assign_to.rb b/app/models/assign_to.rb index e044014c7..af232d267 100644 --- a/app/models/assign_to.rb +++ b/app/models/assign_to.rb @@ -4,6 +4,6 @@ class AssignTo < ApplicationRecord has_one :procedure_presentation, dependent: :destroy def procedure_presentation_or_default - self.procedure_presentation || build_procedure_presentation + procedure_presentation || build_procedure_presentation end end From 7baa239095e1f79d72eb87c22e64a120b6477cb3 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 23 Oct 2018 11:39:54 +0200 Subject: [PATCH 07/14] [#2604] Introduce errors when retrieving ProcedurePresentation --- app/controllers/new_gestionnaire/procedures_controller.rb | 6 +++++- app/models/assign_to.rb | 4 ++-- app/models/gestionnaire.rb | 4 ++-- spec/models/assign_to_spec.rb | 8 ++++++-- spec/models/gestionnaire_spec.rb | 8 ++++++-- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/app/controllers/new_gestionnaire/procedures_controller.rb b/app/controllers/new_gestionnaire/procedures_controller.rb index 71ba18093..4c8ac5d56 100644 --- a/app/controllers/new_gestionnaire/procedures_controller.rb +++ b/app/controllers/new_gestionnaire/procedures_controller.rb @@ -212,7 +212,11 @@ module NewGestionnaire end def get_procedure_presentation - current_gestionnaire.procedure_presentation_for_procedure_id(params[:procedure_id]) + procedure_presentation, errors = current_gestionnaire.procedure_presentation_and_errors_for_procedure_id(params[:procedure_id]) + if errors.present? + flash[:alert] = "Votre affichage a dû être réinitialisé en raison du problème suivant : " + errors.full_messages.join(', ') + end + procedure_presentation end def displayed_fields_values diff --git a/app/models/assign_to.rb b/app/models/assign_to.rb index af232d267..1e21528b4 100644 --- a/app/models/assign_to.rb +++ b/app/models/assign_to.rb @@ -3,7 +3,7 @@ class AssignTo < ApplicationRecord belongs_to :gestionnaire has_one :procedure_presentation, dependent: :destroy - def procedure_presentation_or_default - procedure_presentation || build_procedure_presentation + def procedure_presentation_or_default_and_errors + [procedure_presentation || build_procedure_presentation, nil] end end diff --git a/app/models/gestionnaire.rb b/app/models/gestionnaire.rb index 675cafebb..ae9030646 100644 --- a/app/models/gestionnaire.rb +++ b/app/models/gestionnaire.rb @@ -81,8 +81,8 @@ class Gestionnaire < ApplicationRecord end end - def procedure_presentation_for_procedure_id(procedure_id) - assign_to.find_by(procedure_id: procedure_id).procedure_presentation_or_default + def procedure_presentation_and_errors_for_procedure_id(procedure_id) + assign_to.find_by(procedure_id: procedure_id).procedure_presentation_or_default_and_errors end def notifications_for_dossier(dossier) diff --git a/spec/models/assign_to_spec.rb b/spec/models/assign_to_spec.rb index 9b520c188..fbd3e59d0 100644 --- a/spec/models/assign_to_spec.rb +++ b/spec/models/assign_to_spec.rb @@ -1,18 +1,22 @@ describe AssignTo, type: :model do - describe '#procedure_presentation_or_default' do + describe '#procedure_presentation_or_default_and_errors' do let(:procedure) { create(:procedure) } let(:assign_to) { AssignTo.create(procedure: procedure) } - let(:procedure_presentation_or_default) { assign_to.procedure_presentation_or_default } + let(:procedure_presentation_and_errors) { assign_to.procedure_presentation_or_default_and_errors } + let(:procedure_presentation_or_default) { procedure_presentation_and_errors.first } + let(:errors) { procedure_presentation_and_errors.second } context "without a procedure_presentation" do it { expect(procedure_presentation_or_default).not_to be_persisted } + it { expect(errors).to be_nil } end context "with a procedure_presentation" do let!(:procedure_presentation) { ProcedurePresentation.create(assign_to: assign_to) } it { expect(procedure_presentation_or_default).to eq(procedure_presentation) } + it { expect(errors).to be_nil } end end end diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index fc9ab72bc..df119bc25 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -197,20 +197,24 @@ describe Gestionnaire, type: :model do end end - describe "procedure_presentation_for_procedure_id" do - let(:procedure_presentation) { gestionnaire.procedure_presentation_for_procedure_id(procedure_id) } + describe "procedure_presentation_and_errors_for_procedure_id" do + let(:procedure_presentation_and_errors) { gestionnaire.procedure_presentation_and_errors_for_procedure_id(procedure_id) } + let(:procedure_presentation) { procedure_presentation_and_errors.first } + let(:errors) { procedure_presentation_and_errors.second } context 'with explicit presentation' do let(:procedure_id) { procedure.id } let!(:pp) { ProcedurePresentation.create(assign_to: procedure_assign) } it { expect(procedure_presentation).to eq(pp) } + it { expect(errors).to be_nil } end context 'with default presentation' do let(:procedure_id) { procedure_2.id } it { expect(procedure_presentation).not_to be_persisted } + it { expect(errors).to be_nil } end end From 14fd60bee7bec4a89def311920b12ceec9aa74da Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 23 Oct 2018 11:48:25 +0200 Subject: [PATCH 08/14] [Fix #2604] Handle ProcedurePresentations that have gone invalid --- app/models/assign_to.rb | 17 ++++++++++++++++- spec/models/assign_to_spec.rb | 18 ++++++++++++++++++ spec/models/gestionnaire_spec.rb | 11 +++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/app/models/assign_to.rb b/app/models/assign_to.rb index 1e21528b4..b42601a33 100644 --- a/app/models/assign_to.rb +++ b/app/models/assign_to.rb @@ -4,6 +4,21 @@ class AssignTo < ApplicationRecord has_one :procedure_presentation, dependent: :destroy def procedure_presentation_or_default_and_errors - [procedure_presentation || build_procedure_presentation, nil] + errors = reset_procedure_presentation_if_invalid + [procedure_presentation || build_procedure_presentation, errors] + end + + private + + def reset_procedure_presentation_if_invalid + if procedure_presentation&.invalid? + # This is a last defense against invalid `ProcedurePresentation`s persistently + # hindering instructeurs. Whenever this gets triggered, it means that there is + # a bug somewhere else that we need to fix. + + errors = procedure_presentation.errors + self.procedure_presentation = nil + errors + end end end diff --git a/spec/models/assign_to_spec.rb b/spec/models/assign_to_spec.rb index fbd3e59d0..5e1f0e25f 100644 --- a/spec/models/assign_to_spec.rb +++ b/spec/models/assign_to_spec.rb @@ -9,6 +9,7 @@ describe AssignTo, type: :model do context "without a procedure_presentation" do it { expect(procedure_presentation_or_default).not_to be_persisted } + it { expect(procedure_presentation_or_default).to be_valid } it { expect(errors).to be_nil } end @@ -16,7 +17,24 @@ describe AssignTo, type: :model do let!(:procedure_presentation) { ProcedurePresentation.create(assign_to: assign_to) } it { expect(procedure_presentation_or_default).to eq(procedure_presentation) } + it { expect(procedure_presentation_or_default).to be_valid } it { expect(errors).to be_nil } end + + context "with an invalid procedure_presentation" do + let!(:procedure_presentation) do + pp = ProcedurePresentation.new(assign_to: assign_to, displayed_fields: [{ 'table' => 'invalid', 'column' => 'random' }]) + pp.save(validate: false) + pp + end + + it { expect(procedure_presentation_or_default).not_to be_persisted } + it { expect(procedure_presentation_or_default).to be_valid } + it { expect(errors).to be_present } + it do + procedure_presentation_or_default + expect(assign_to.procedure_presentation).not_to be(procedure_presentation) + end + end end end diff --git a/spec/models/gestionnaire_spec.rb b/spec/models/gestionnaire_spec.rb index df119bc25..277692099 100644 --- a/spec/models/gestionnaire_spec.rb +++ b/spec/models/gestionnaire_spec.rb @@ -210,6 +210,17 @@ describe Gestionnaire, type: :model do it { expect(errors).to be_nil } end + context 'with invalid presentation' do + let(:procedure_id) { procedure.id } + before do + pp = ProcedurePresentation.create(assign_to: procedure_assign, displayed_fields: [{ 'table' => 'invalid', 'column' => 'random' }]) + pp.save(:validate => false) + end + + it { expect(procedure_presentation).not_to be_persisted } + it { expect(errors).to be_present } + end + context 'with default presentation' do let(:procedure_id) { procedure_2.id } From 51954a6d85f48f1d6ac21163059d713828282473 Mon Sep 17 00:00:00 2001 From: Frederic Merizen Date: Tue, 23 Oct 2018 12:18:46 +0200 Subject: [PATCH 09/14] [#2604] Warn that we are destroying an invalid ProcedurePresentation --- app/models/assign_to.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/assign_to.rb b/app/models/assign_to.rb index b42601a33..1e5621fe3 100644 --- a/app/models/assign_to.rb +++ b/app/models/assign_to.rb @@ -17,6 +17,10 @@ class AssignTo < ApplicationRecord # a bug somewhere else that we need to fix. errors = procedure_presentation.errors + Raven.capture_message( + "Destroying invalid ProcedurePresentation", + extra: { procedure_presentation: procedure_presentation.as_json } + ) self.procedure_presentation = nil errors end From ed46e2c3be99be99b1046cdea7b1cb1763ddf430 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 23 Oct 2018 15:35:03 +0200 Subject: [PATCH 10/14] Use Typhoeus in ApiGeo adapter --- app/lib/api_geo/api.rb | 35 ++++++++++++---- app/models/champs/departement_champ.rb | 2 +- app/models/champs/pays_champ.rb | 2 +- app/models/champs/region_champ.rb | 2 +- config/initializers/typhoeus.rb | 1 + .../cassettes/api_geo_departements.yml | 41 +++++-------------- spec/fixtures/cassettes/api_geo_regions.yml | 28 +++++-------- spec/lib/api_geo/api_spec.rb | 9 ++-- 8 files changed, 60 insertions(+), 60 deletions(-) create mode 100644 config/initializers/typhoeus.rb diff --git a/app/lib/api_geo/api.rb b/app/lib/api_geo/api.rb index 5e86389a5..2e27d8b2e 100644 --- a/app/lib/api_geo/api.rb +++ b/app/lib/api_geo/api.rb @@ -1,23 +1,44 @@ class ApiGeo::API + TIMEOUT = 15 + def self.regions url = [API_GEO_URL, "regions"].join("/") - call(url) + call(url, { fields: :nom }) end def self.departements url = [API_GEO_URL, "departements"].join("/") - call(url) + call(url, { fields: :nom }) end def self.pays - File.open('app/lib/api_geo/pays.json').read + parse(File.open('app/lib/api_geo/pays.json').read) end private - def self.call(url) - RestClient.get(url, params: { fields: :nom }) - rescue RestClient::ServiceUnavailable - nil + def self.parse(body) + JSON.parse(body, symbolize_names: true) + end + + def self.call(url, body, method = :get) + response = Typhoeus::Request.new( + url, + method: method, + params: method == :get ? body : nil, + body: method == :post ? body : nil, + timeout: TIMEOUT, + accept_encoding: 'gzip', + headers: { + 'Accept' => 'application/json', + 'Accept-Encoding' => 'gzip, deflate' + }.merge(method == :post ? { 'Content-Type' => 'application/json' } : {}) + ).run + + if response.success? + parse(response.body) + else + nil + end end end diff --git a/app/models/champs/departement_champ.rb b/app/models/champs/departement_champ.rb index 8439a912d..f211b421c 100644 --- a/app/models/champs/departement_champ.rb +++ b/app/models/champs/departement_champ.rb @@ -1,5 +1,5 @@ class Champs::DepartementChamp < Champs::TextChamp def self.departements - JSON.parse(ApiGeo::API.departements).map { |liste| "#{liste['code']} - #{liste['nom']}" }.push('99 - Étranger') + ApiGeo::API.departements.map { |liste| "#{liste[:code]} - #{liste[:nom]}" }.push('99 - Étranger') end end diff --git a/app/models/champs/pays_champ.rb b/app/models/champs/pays_champ.rb index c8b1d68d8..d088d2880 100644 --- a/app/models/champs/pays_champ.rb +++ b/app/models/champs/pays_champ.rb @@ -1,5 +1,5 @@ class Champs::PaysChamp < Champs::TextChamp def self.pays - JSON.parse(ApiGeo::API.pays).pluck("nom") + ApiGeo::API.pays.pluck(:nom) end end diff --git a/app/models/champs/region_champ.rb b/app/models/champs/region_champ.rb index f8ac792ef..9ecba7173 100644 --- a/app/models/champs/region_champ.rb +++ b/app/models/champs/region_champ.rb @@ -1,5 +1,5 @@ class Champs::RegionChamp < Champs::TextChamp def self.regions - JSON.parse(ApiGeo::API.regions).sort_by { |e| e['nom'] }.pluck("nom") + ApiGeo::API.regions.sort_by { |e| e[:nom] }.pluck(:nom) end end diff --git a/config/initializers/typhoeus.rb b/config/initializers/typhoeus.rb new file mode 100644 index 000000000..790489eb5 --- /dev/null +++ b/config/initializers/typhoeus.rb @@ -0,0 +1 @@ +Typhoeus::Config.user_agent = "demarches-simplifiees.fr" diff --git a/spec/fixtures/cassettes/api_geo_departements.yml b/spec/fixtures/cassettes/api_geo_departements.yml index 5f827279d..9a7dcd8b3 100644 --- a/spec/fixtures/cassettes/api_geo_departements.yml +++ b/spec/fixtures/cassettes/api_geo_departements.yml @@ -7,21 +7,23 @@ http_interactions: encoding: US-ASCII string: '' headers: + User-Agent: + - demarches-simplifiees.fr Accept: - - "*/*" + - application/json Accept-Encoding: - gzip, deflate - User-Agent: - - rest-client/2.0.0 (darwin15.6.0 x86_64) ruby/2.3.1p112 + Expect: + - '' response: status: code: 200 message: OK headers: Server: - - nginx + - nginx/1.10.3 (Ubuntu) Date: - - Fri, 16 Dec 2016 09:25:41 GMT + - Tue, 23 Oct 2018 13:11:36 GMT Content-Type: - application/json; charset=utf-8 Transfer-Encoding: @@ -30,13 +32,12 @@ http_interactions: - keep-alive Vary: - Accept-Encoding - - Accept-Encoding X-Powered-By: - Express Access-Control-Allow-Origin: - "*" Etag: - - W/"cc1-lXUcIlpPmDfvrGONl0WWsQ" + - W/"cc1-jlb3C7xpXUEaq56Wojrp9rAkoH8" Strict-Transport-Security: - max-age=15552000 Content-Encoding: @@ -44,27 +45,7 @@ http_interactions: body: encoding: ASCII-8BIT string: !binary |- - H4sIAAAAAAAAA22Wy27bMBBFfyXwJpsKqF96dOfYrZsibow4MFAUXTARGxOQ - xZYSjbpF/yfZ5w/0YyVlpDq0sxTmajg8vJzh1z+9Um9773oTVfbe9O51Lt3H - 237v75suUpUSsQFjRaGkQXAYBH/IKspl9FHYWkZLo3eyvGeqEdStqIomhfsJ - CccnCRfCqFptA1VMlcmbx/sN10nCsCzL4O80CKvm8YE/Z4zaO4T6b4OQQ/ef - YD8guJN7o8G3T4YX2rpqHSgb3WyaZ7LuE+dUFDuRa8Dpk99UlLUoUAHJTTfC - yLJmgUT2Eo5e2CIN2U03POw+uU21Mc3jb65AcC5cSb/Flc275IPJsQGiVgjF - BRTT5tn5KD+/huMGBN0KHMnzidlqish7aqQNliDkmTa5fuAZDAh5pu0dDmBA - xjPTPG9ZOgm/t4YhQvWhSNbRlVYsmXA/qFJVdfMY5CDeuTDAOqQvD5fPCbRz - fQd2SG5zabCrIWnNlfuRzh4S18fmyQhb1MhLXJdF0W5trQqhgtUJ7rLMubEh - ubWxFzosnwQvqxDNkOw+WSNQHqldCbczbHxEbv44/MKh50fE5iWoaURuB+zH - CrJrY9GkLtzFVT8tE5FhKwPgEdFdaUYIzkV89SfnPiK4K/07JDciuYU/s1fY - j8hwIcqg147J0LUTnvqY8A6AjhVEuBB736m7wxsT30JaU2/a+ha6ks5pEBKg - E/K6j8lvoc2d2gi05jEhniYmvc9uUuxogDHpfXadBBWR2bViQTGJXQfAYgJb - inaYujEgFEwbE9nS7r1mFnaimNyWe9M8lc2Tn7X/vcd8rwzl7p9uRzE5Ium1 - UW7SiIIXKybUC7ePmw2fGzGpel8cx8n1eEbGJHsw1UqEYzQh4UPwFVsnhL0S - 3lzdbhNSXomdVgwGLbF97JxISHXpXjAgnpDkSvpLdzqHEyI8iLzzwwuWEOSX - nSxcLi5EjjNpf0Wr1sGUkOZKbznQUmK8dSt3eFKy86FXe09KiGuBaZeS4FrY - +yK4synprWWZO/ticfJbO/exZ6TkdrDHiYTU1rp6IJCUzL6EMzQlrFtp3LvU - N+uzXJ5dyOK7NmjOGeG9r6owU3bcGdur3h5zt88s8GDrk5Vr0XU0k+55AF0I - s/CpjoySBUCFk5yHTSkj07kVuSy0/cFiguvi0tfujRJMsSy4M3O7F8FmkmAW - irOb5smWiq/kLAnauNjrmi/YzF+Jb/8A5ygzwMEMAAA= + W3sibm9tIjoiQWluIiwiY29kZSI6IjAxIn0seyJub20iOiJBaXNuZSIsImNvZGUiOiIwMiJ9LHsibm9tIjoiQWxsaWVyIiwiY29kZSI6IjAzIn0seyJub20iOiJBbHBlcy1kZS1IYXV0ZS1Qcm92ZW5jZSIsImNvZGUiOiIwNCJ9LHsibm9tIjoiSGF1dGVzLUFscGVzIiwiY29kZSI6IjA1In0seyJub20iOiJBbHBlcy1NYXJpdGltZXMiLCJjb2RlIjoiMDYifSx7Im5vbSI6IkFyZMOoY2hlIiwiY29kZSI6IjA3In0seyJub20iOiJBcmRlbm5lcyIsImNvZGUiOiIwOCJ9LHsibm9tIjoiQXJpw6hnZSIsImNvZGUiOiIwOSJ9LHsibm9tIjoiQXViZSIsImNvZGUiOiIxMCJ9LHsibm9tIjoiQXVkZSIsImNvZGUiOiIxMSJ9LHsibm9tIjoiQXZleXJvbiIsImNvZGUiOiIxMiJ9LHsibm9tIjoiQm91Y2hlcy1kdS1SaMO0bmUiLCJjb2RlIjoiMTMifSx7Im5vbSI6IkNhbHZhZG9zIiwiY29kZSI6IjE0In0seyJub20iOiJDYW50YWwiLCJjb2RlIjoiMTUifSx7Im5vbSI6IkNoYXJlbnRlIiwiY29kZSI6IjE2In0seyJub20iOiJDaGFyZW50ZS1NYXJpdGltZSIsImNvZGUiOiIxNyJ9LHsibm9tIjoiQ2hlciIsImNvZGUiOiIxOCJ9LHsibm9tIjoiQ29ycsOoemUiLCJjb2RlIjoiMTkifSx7Im5vbSI6IkPDtHRlLWQnT3IiLCJjb2RlIjoiMjEifSx7Im5vbSI6IkPDtHRlcy1kJ0FybW9yIiwiY29kZSI6IjIyIn0seyJub20iOiJDcmV1c2UiLCJjb2RlIjoiMjMifSx7Im5vbSI6IkRvcmRvZ25lIiwiY29kZSI6IjI0In0seyJub20iOiJEb3VicyIsImNvZGUiOiIyNSJ9LHsibm9tIjoiRHLDtG1lIiwiY29kZSI6IjI2In0seyJub20iOiJFdXJlIiwiY29kZSI6IjI3In0seyJub20iOiJFdXJlLWV0LUxvaXIiLCJjb2RlIjoiMjgifSx7Im5vbSI6IkZpbmlzdMOocmUiLCJjb2RlIjoiMjkifSx7Im5vbSI6IkNvcnNlLWR1LVN1ZCIsImNvZGUiOiIyQSJ9LHsibm9tIjoiSGF1dGUtQ29yc2UiLCJjb2RlIjoiMkIifSx7Im5vbSI6IkdhcmQiLCJjb2RlIjoiMzAifSx7Im5vbSI6IkhhdXRlLUdhcm9ubmUiLCJjb2RlIjoiMzEifSx7Im5vbSI6IkdlcnMiLCJjb2RlIjoiMzIifSx7Im5vbSI6Ikdpcm9uZGUiLCJjb2RlIjoiMzMifSx7Im5vbSI6IkjDqXJhdWx0IiwiY29kZSI6IjM0In0seyJub20iOiJJbGxlLWV0LVZpbGFpbmUiLCJjb2RlIjoiMzUifSx7Im5vbSI6IkluZHJlIiwiY29kZSI6IjM2In0seyJub20iOiJJbmRyZS1ldC1Mb2lyZSIsImNvZGUiOiIzNyJ9LHsibm9tIjoiSXPDqHJlIiwiY29kZSI6IjM4In0seyJub20iOiJKdXJhIiwiY29kZSI6IjM5In0seyJub20iOiJMYW5kZXMiLCJjb2RlIjoiNDAifSx7Im5vbSI6IkxvaXItZXQtQ2hlciIsImNvZGUiOiI0MSJ9LHsibm9tIjoiTG9pcmUiLCJjb2RlIjoiNDIifSx7Im5vbSI6IkhhdXRlLUxvaXJlIiwiY29kZSI6IjQzIn0seyJub20iOiJMb2lyZS1BdGxhbnRpcXVlIiwiY29kZSI6IjQ0In0seyJub20iOiJMb2lyZXQiLCJjb2RlIjoiNDUifSx7Im5vbSI6IkxvdCIsImNvZGUiOiI0NiJ9LHsibm9tIjoiTG90LWV0LUdhcm9ubmUiLCJjb2RlIjoiNDcifSx7Im5vbSI6IkxvesOocmUiLCJjb2RlIjoiNDgifSx7Im5vbSI6Ik1haW5lLWV0LUxvaXJlIiwiY29kZSI6IjQ5In0seyJub20iOiJNYW5jaGUiLCJjb2RlIjoiNTAifSx7Im5vbSI6Ik1hcm5lIiwiY29kZSI6IjUxIn0seyJub20iOiJIYXV0ZS1NYXJuZSIsImNvZGUiOiI1MiJ9LHsibm9tIjoiTWF5ZW5uZSIsImNvZGUiOiI1MyJ9LHsibm9tIjoiTWV1cnRoZS1ldC1Nb3NlbGxlIiwiY29kZSI6IjU0In0seyJub20iOiJNZXVzZSIsImNvZGUiOiI1NSJ9LHsibm9tIjoiTW9yYmloYW4iLCJjb2RlIjoiNTYifSx7Im5vbSI6Ik1vc2VsbGUiLCJjb2RlIjoiNTcifSx7Im5vbSI6Ik5pw6h2cmUiLCJjb2RlIjoiNTgifSx7Im5vbSI6Ik5vcmQiLCJjb2RlIjoiNTkifSx7Im5vbSI6Ik9pc2UiLCJjb2RlIjoiNjAifSx7Im5vbSI6Ik9ybmUiLCJjb2RlIjoiNjEifSx7Im5vbSI6IlBhcy1kZS1DYWxhaXMiLCJjb2RlIjoiNjIifSx7Im5vbSI6IlB1eS1kZS1Ew7RtZSIsImNvZGUiOiI2MyJ9LHsibm9tIjoiUHlyw6luw6llcy1BdGxhbnRpcXVlcyIsImNvZGUiOiI2NCJ9LHsibm9tIjoiSGF1dGVzLVB5csOpbsOpZXMiLCJjb2RlIjoiNjUifSx7Im5vbSI6IlB5csOpbsOpZXMtT3JpZW50YWxlcyIsImNvZGUiOiI2NiJ9LHsibm9tIjoiQmFzLVJoaW4iLCJjb2RlIjoiNjcifSx7Im5vbSI6IkhhdXQtUmhpbiIsImNvZGUiOiI2OCJ9LHsibm9tIjoiUmjDtG5lIiwiY29kZSI6IjY5In0seyJub20iOiJIYXV0ZS1TYcO0bmUiLCJjb2RlIjoiNzAifSx7Im5vbSI6IlNhw7RuZS1ldC1Mb2lyZSIsImNvZGUiOiI3MSJ9LHsibm9tIjoiU2FydGhlIiwiY29kZSI6IjcyIn0seyJub20iOiJTYXZvaWUiLCJjb2RlIjoiNzMifSx7Im5vbSI6IkhhdXRlLVNhdm9pZSIsImNvZGUiOiI3NCJ9LHsibm9tIjoiUGFyaXMiLCJjb2RlIjoiNzUifSx7Im5vbSI6IlNlaW5lLU1hcml0aW1lIiwiY29kZSI6Ijc2In0seyJub20iOiJTZWluZS1ldC1NYXJuZSIsImNvZGUiOiI3NyJ9LHsibm9tIjoiWXZlbGluZXMiLCJjb2RlIjoiNzgifSx7Im5vbSI6IkRldXgtU8OodnJlcyIsImNvZGUiOiI3OSJ9LHsibm9tIjoiU29tbWUiLCJjb2RlIjoiODAifSx7Im5vbSI6IlRhcm4iLCJjb2RlIjoiODEifSx7Im5vbSI6IlRhcm4tZXQtR2Fyb25uZSIsImNvZGUiOiI4MiJ9LHsibm9tIjoiVmFyIiwiY29kZSI6IjgzIn0seyJub20iOiJWYXVjbHVzZSIsImNvZGUiOiI4NCJ9LHsibm9tIjoiVmVuZMOpZSIsImNvZGUiOiI4NSJ9LHsibm9tIjoiVmllbm5lIiwiY29kZSI6Ijg2In0seyJub20iOiJIYXV0ZS1WaWVubmUiLCJjb2RlIjoiODcifSx7Im5vbSI6IlZvc2dlcyIsImNvZGUiOiI4OCJ9LHsibm9tIjoiWW9ubmUiLCJjb2RlIjoiODkifSx7Im5vbSI6IlRlcnJpdG9pcmUgZGUgQmVsZm9ydCIsImNvZGUiOiI5MCJ9LHsibm9tIjoiRXNzb25uZSIsImNvZGUiOiI5MSJ9LHsibm9tIjoiSGF1dHMtZGUtU2VpbmUiLCJjb2RlIjoiOTIifSx7Im5vbSI6IlNlaW5lLVNhaW50LURlbmlzIiwiY29kZSI6IjkzIn0seyJub20iOiJWYWwtZGUtTWFybmUiLCJjb2RlIjoiOTQifSx7Im5vbSI6IlZhbC1kJ09pc2UiLCJjb2RlIjoiOTUifSx7Im5vbSI6Ikd1YWRlbG91cGUiLCJjb2RlIjoiOTcxIn0seyJub20iOiJNYXJ0aW5pcXVlIiwiY29kZSI6Ijk3MiJ9LHsibm9tIjoiR3V5YW5lIiwiY29kZSI6Ijk3MyJ9LHsibm9tIjoiTGEgUsOpdW5pb24iLCJjb2RlIjoiOTc0In0seyJub20iOiJNYXlvdHRlIiwiY29kZSI6Ijk3NiJ9XQ== http_version: - recorded_at: Fri, 16 Dec 2016 09:25:37 GMT -recorded_with: VCR 3.0.3 + 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 index 7519677b9..0d1c6a182 100644 --- a/spec/fixtures/cassettes/api_geo_regions.yml +++ b/spec/fixtures/cassettes/api_geo_regions.yml @@ -7,21 +7,23 @@ http_interactions: encoding: US-ASCII string: '' headers: + User-Agent: + - demarches-simplifiees.fr Accept: - - "*/*" + - application/json Accept-Encoding: - gzip, deflate - User-Agent: - - rest-client/2.0.0 (darwin15.6.0 x86_64) ruby/2.3.1p112 + Expect: + - '' response: status: code: 200 message: OK headers: Server: - - nginx + - nginx/1.10.3 (Ubuntu) Date: - - Fri, 16 Dec 2016 09:24:28 GMT + - Tue, 23 Oct 2018 13:11:36 GMT Content-Type: - application/json; charset=utf-8 Transfer-Encoding: @@ -30,13 +32,12 @@ http_interactions: - keep-alive Vary: - Accept-Encoding - - Accept-Encoding X-Powered-By: - Express Access-Control-Allow-Origin: - "*" Etag: - - W/"2dd-2SAFdhiM3SIQ2017gqYxbw" + - W/"28d-5OgIzgwL+0K2UaO0foKduqMMBrA" Strict-Transport-Security: - max-age=15552000 Content-Encoding: @@ -44,14 +45,7 @@ http_interactions: body: encoding: ASCII-8BIT string: !binary |- - H4sIAAAAAAAAA11Ry2rDMBD8FeNLLxE0rybpzTE0F6eYHHopPSyWSASyNllJ - Abf0F/ofvucP/GO1aIvXPQm0M7MzO68fqcU6fUx3AaQyGM4qnaQVStX/3U/T - z8kfYA/ktdWXwAEzBtiFBiwfztmwgOTQtcFqtEx/MdJv0HvOf2DT7ssoIZV4 - IrAVA025xVxZT0q8gEmkSgrUxJAzvmyLgY54tL+CJyVyrH3XDt5mK7b9GakG - KzWXW4/nUpTgosMcDGgnSl0BjRhzfqzMOKh68AnqM0QfGUll+7dAItD8jgtu - vITGxXAG/udbcvktKR9lhzxL3kZ2CdrHLaLQNQanrShRewzREPVXVG5grpaj - Hu0xKImVOPQ8p41BK/ZaalE21LW2a0dUXmEWropi1MOpu8XE5syx61FMwqvq - i/4Biby7eZXIu+w90GBswyPlSI7F3fRqb99L+pyA3QIAAA== + W3sibm9tIjoiR3VhZGVsb3VwZSIsImNvZGUiOiIwMSJ9LHsibm9tIjoiTWFydGluaXF1ZSIsImNvZGUiOiIwMiJ9LHsibm9tIjoiR3V5YW5lIiwiY29kZSI6IjAzIn0seyJub20iOiJMYSBSw6l1bmlvbiIsImNvZGUiOiIwNCJ9LHsibm9tIjoiTWF5b3R0ZSIsImNvZGUiOiIwNiJ9LHsibm9tIjoiw45sZS1kZS1GcmFuY2UiLCJjb2RlIjoiMTEifSx7Im5vbSI6IkNlbnRyZS1WYWwgZGUgTG9pcmUiLCJjb2RlIjoiMjQifSx7Im5vbSI6IkJvdXJnb2duZS1GcmFuY2hlLUNvbXTDqSIsImNvZGUiOiIyNyJ9LHsibm9tIjoiTm9ybWFuZGllIiwiY29kZSI6IjI4In0seyJub20iOiJIYXV0cy1kZS1GcmFuY2UiLCJjb2RlIjoiMzIifSx7Im5vbSI6IkdyYW5kIEVzdCIsImNvZGUiOiI0NCJ9LHsibm9tIjoiUGF5cyBkZSBsYSBMb2lyZSIsImNvZGUiOiI1MiJ9LHsibm9tIjoiQnJldGFnbmUiLCJjb2RlIjoiNTMifSx7Im5vbSI6Ik5vdXZlbGxlLUFxdWl0YWluZSIsImNvZGUiOiI3NSJ9LHsibm9tIjoiT2NjaXRhbmllIiwiY29kZSI6Ijc2In0seyJub20iOiJBdXZlcmduZS1SaMO0bmUtQWxwZXMiLCJjb2RlIjoiODQifSx7Im5vbSI6IlByb3ZlbmNlLUFscGVzLUPDtHRlIGQnQXp1ciIsImNvZGUiOiI5MyJ9LHsibm9tIjoiQ29yc2UiLCJjb2RlIjoiOTQifV0= http_version: - recorded_at: Fri, 16 Dec 2016 09:24:25 GMT -recorded_with: VCR 3.0.3 + recorded_at: Tue, 23 Oct 2018 13:11:36 GMT +recorded_with: VCR 4.0.0 diff --git a/spec/lib/api_geo/api_spec.rb b/spec/lib/api_geo/api_spec.rb index 6e1be6652..c0d6e7ccb 100644 --- a/spec/lib/api_geo/api_spec.rb +++ b/spec/lib/api_geo/api_spec.rb @@ -4,18 +4,21 @@ describe ApiGeo::API do describe '.regions', vcr: { cassette_name: 'api_geo_regions' } do subject { described_class.regions } - it { expect(subject.code).to eq 200 } + it { expect(subject.size).to eq 18 } end describe '.departements', vcr: { cassette_name: 'api_geo_departements' } do subject { described_class.departements } - it { expect(subject.code).to eq 200 } + 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 File.open('app/lib/api_geo/pays.json').read } + it { is_expected.to eq pays } end end From 7ffbe417f96fc210ee608fd78dde04aa068b922b Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 23 Oct 2018 15:37:13 +0200 Subject: [PATCH 11/14] Add ApiGeo RPG adapter --- app/lib/api_geo/api.rb | 5 +++++ app/lib/api_geo/rpg_adapter.rb | 24 ++++++++++++++++++++++++ app/services/geojson_service.rb | 11 +++++++++++ app/services/module_api_carto_service.rb | 8 ++++++++ config/initializers/urls.rb | 1 + 5 files changed, 49 insertions(+) create mode 100644 app/lib/api_geo/rpg_adapter.rb diff --git a/app/lib/api_geo/api.rb b/app/lib/api_geo/api.rb index 2e27d8b2e..9dbb9ccb6 100644 --- a/app/lib/api_geo/api.rb +++ b/app/lib/api_geo/api.rb @@ -15,6 +15,11 @@ class ApiGeo::API parse(File.open('app/lib/api_geo/pays.json').read) end + def self.search_rpg(geojson) + url = [API_GEO_SANDBOX_URL, "rpg", "parcelles", "search"].join("/") + call(url, geojson, :post) + end + private def self.parse(body) diff --git a/app/lib/api_geo/rpg_adapter.rb b/app/lib/api_geo/rpg_adapter.rb new file mode 100644 index 000000000..d63c18941 --- /dev/null +++ b/app/lib/api_geo/rpg_adapter.rb @@ -0,0 +1,24 @@ +class ApiGeo::RPGAdapter + def initialize(coordinates) + @coordinates = GeojsonService.to_json_polygon_for_rpg(coordinates) + end + + def data_source + @data_source ||= ApiGeo::API.search_rpg(@coordinates) + end + + def results + data_source[:features].map do |feature| + feature[:properties] + .stringify_keys + .transform_keys(&:underscore) + .symbolize_keys + .slice( + :culture, + :code_culture, + :surface, + :bio + ).merge({ geometry: feature[:geometry] }) + end + end +end diff --git a/app/services/geojson_service.rb b/app/services/geojson_service.rb index 7bcf59bdc..d7d3a3519 100644 --- a/app/services/geojson_service.rb +++ b/app/services/geojson_service.rb @@ -25,4 +25,15 @@ class GeojsonService polygon.to_json end + + def self.to_json_polygon_for_rpg(coordinates) + polygon = { + polygonIntersects: { + type: "Polygon", + coordinates: [coordinates] + } + } + + polygon.to_json + end end diff --git a/app/services/module_api_carto_service.rb b/app/services/module_api_carto_service.rb index 2505f60b3..b372e0870 100644 --- a/app/services/module_api_carto_service.rb +++ b/app/services/module_api_carto_service.rb @@ -38,4 +38,12 @@ class ModuleApiCartoService ).results end end + + def self.generate_rpg(coordinates) + coordinates.flat_map do |coordinate| + ApiGeo::RPGAdapter.new( + coordinate.map { |element| [element['lng'], element['lat']] } + ).results + end + end end diff --git a/config/initializers/urls.rb b/config/initializers/urls.rb index c1ca9b978..b8a298fe5 100644 --- a/config/initializers/urls.rb +++ b/config/initializers/urls.rb @@ -3,6 +3,7 @@ API_ADRESSE_URL = "https://api-adresse.data.gouv.fr" API_CARTO_URL = "https://apicarto.sgmap.fr" API_ENTREPRISE_URL = "https://entreprise.api.gouv.fr/v2" API_GEO_URL = "https://geo.api.gouv.fr" +API_GEO_SANDBOX_URL = "https://sandbox.geo.api.gouv.fr" HELPSCOUT_API_URL = "https://api.helpscout.net/v2" PIPEDRIVE_API_URL = "https://api.pipedrive.com/v1" From 5a8a4b393f51d5424bb6aa8136384a9675c032ef Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 23 Oct 2018 15:38:20 +0200 Subject: [PATCH 12/14] Add RPG carte source --- app/controllers/champs/carte_controller.rb | 8 ++++++++ app/helpers/champ_helper.rb | 3 ++- app/javascript/new_design/champs/carte.js | 2 ++ app/javascript/shared/carte.js | 17 +++++++++++++++++ app/models/champs/carte_champ.rb | 10 ++++++++++ app/models/geo_area.rb | 10 ++++++++-- app/models/type_de_champ.rb | 2 +- app/services/types_de_champ_service.rb | 1 + .../admin/types_de_champ/_fields.html.haml | 4 ++++ .../shared/champs/carte/_geo_areas.html.haml | 14 ++++++++++++++ config/locales/fr.yml | 3 +++ .../controllers/champs/carte_controller_spec.rb | 2 +- 12 files changed, 71 insertions(+), 5 deletions(-) diff --git a/app/controllers/champs/carte_controller.rb b/app/controllers/champs/carte_controller.rb index 4dc16440b..d3a7dbb38 100644 --- a/app/controllers/champs/carte_controller.rb +++ b/app/controllers/champs/carte_controller.rb @@ -46,6 +46,14 @@ class Champs::CarteController < ApplicationController qp end end + + if @champ.parcelles_agricoles? + parcelles_agricoles = ModuleApiCartoService.generate_rpg(geo_json) + geo_areas += parcelles_agricoles.map do |parcelle_agricole| + parcelle_agricole[:source] = GeoArea.sources.fetch(:parcelle_agricole) + parcelle_agricole + end + end end @champ.geo_areas = geo_areas.map do |geo_area| diff --git a/app/helpers/champ_helper.rb b/app/helpers/champ_helper.rb index 8f97ed229..ef8f6386f 100644 --- a/app/helpers/champ_helper.rb +++ b/app/helpers/champ_helper.rb @@ -10,7 +10,8 @@ module ChampHelper position: champ.position, selection: champ.value.present? ? JSON.parse(champ.value) : [], quartiersPrioritaires: champ.quartiers_prioritaires? ? champ.quartiers_prioritaires : [], - cadastres: champ.cadastres? ? champ.cadastres : [] + cadastres: champ.cadastres? ? champ.cadastres : [], + parcellesAgricoles: champ.parcelles_agricoles? ? champ.parcelles_agricoles : [] }.to_json) # rubocop:enable Rails/OutputSafety end diff --git a/app/javascript/new_design/champs/carte.js b/app/javascript/new_design/champs/carte.js index 97a46ae9c..1c2e8532e 100644 --- a/app/javascript/new_design/champs/carte.js +++ b/app/javascript/new_design/champs/carte.js @@ -6,6 +6,7 @@ import { geocodeAddress, drawCadastre, drawQuartiersPrioritaires, + drawParcellesAgricoles, drawUserSelection, addFreeDrawEvents } from '../../shared/carte'; @@ -30,6 +31,7 @@ function diplayMap(element, data, initial = false) { // draw external polygons drawCadastre(map, data, editable); drawQuartiersPrioritaires(map, data, editable); + drawParcellesAgricoles(map, data, editable); // draw user polygon if (initial) { diff --git a/app/javascript/shared/carte.js b/app/javascript/shared/carte.js index f56c859dc..5a86af744 100644 --- a/app/javascript/shared/carte.js +++ b/app/javascript/shared/carte.js @@ -57,6 +57,19 @@ export function drawQuartiersPrioritaires( ); } +export function drawParcellesAgricoles( + map, + { parcellesAgricoles }, + editable = false +) { + drawLayer( + map, + parcellesAgricoles, + editable ? RPG_POLYGON_STYLE : noEditStyle(RPG_POLYGON_STYLE), + 'parcellesAgricoles' + ); +} + export function drawUserSelection(map, { selection }, editable = false) { let hasSelection = selection && selection.length > 0; @@ -170,6 +183,10 @@ const QP_POLYGON_STYLE = Object.assign({}, POLYGON_STYLE, { fillColor: '#31708f' }); +const RPG_POLYGON_STYLE = Object.assign({}, POLYGON_STYLE, { + fillColor: '#31708f' +}); + delegate('click', '.carte.edit', event => { let element = event.target; let isPath = element.matches('.leaflet-container g path'); diff --git a/app/models/champs/carte_champ.rb b/app/models/champs/carte_champ.rb index 9a752722d..353e9ac20 100644 --- a/app/models/champs/carte_champ.rb +++ b/app/models/champs/carte_champ.rb @@ -15,6 +15,12 @@ class Champs::CarteChamp < Champ end end + def parcelles_agricoles + geo_areas.select do |area| + area.source == GeoArea.sources.fetch(:parcelle_agricole) + end + end + def cadastres? type_de_champ&.cadastres && type_de_champ.cadastres != '0' end @@ -23,6 +29,10 @@ class Champs::CarteChamp < Champ type_de_champ&.quartiers_prioritaires && type_de_champ.quartiers_prioritaires != '0' end + def parcelles_agricoles? + type_de_champ&.parcelles_agricoles && type_de_champ.parcelles_agricoles != '0' + end + def position if dossier.present? dossier.geo_position diff --git a/app/models/geo_area.rb b/app/models/geo_area.rb index 92de3100b..6d7613d4e 100644 --- a/app/models/geo_area.rb +++ b/app/models/geo_area.rb @@ -13,14 +13,20 @@ class GeoArea < ApplicationRecord :code_arr, :code, :nom, - :commune + :commune, + :culture, + :code_culture, + :surface, + :bio ] enum source: { quartier_prioritaire: 'quartier_prioritaire', - cadastre: 'cadastre' + cadastre: 'cadastre', + parcelle_agricole: 'parcelle_agricole' } scope :quartiers_prioritaires, -> { where(source: sources.fetch(:quartier_prioritaire)) } scope :cadastres, -> { where(source: sources.fetch(:cadastre)) } + scope :parcelles_agricoles, -> { where(source: sources.fetch(:parcelle_agricole)) } end diff --git a/app/models/type_de_champ.rb b/app/models/type_de_champ.rb index 59e154075..bab7c60d7 100644 --- a/app/models/type_de_champ.rb +++ b/app/models/type_de_champ.rb @@ -31,7 +31,7 @@ class TypeDeChamp < ApplicationRecord belongs_to :procedure - store :options, accessors: [:cadastres, :quartiers_prioritaires] + store :options, accessors: [:cadastres, :quartiers_prioritaires, :parcelles_agricoles] after_initialize :set_dynamic_type diff --git a/app/services/types_de_champ_service.rb b/app/services/types_de_champ_service.rb index 191d5e626..c30a8c08d 100644 --- a/app/services/types_de_champ_service.rb +++ b/app/services/types_de_champ_service.rb @@ -16,6 +16,7 @@ class TypesDeChampService :piece_justificative_template, :quartiers_prioritaires, :cadastres, + :parcelles_agricoles, drop_down_list_attributes: [:value, :id] ]) diff --git a/app/views/admin/types_de_champ/_fields.html.haml b/app/views/admin/types_de_champ/_fields.html.haml index 5a3d74ec7..f282aaf48 100644 --- a/app/views/admin/types_de_champ/_fields.html.haml +++ b/app/views/admin/types_de_champ/_fields.html.haml @@ -47,6 +47,10 @@ %label = ff.check_box :cadastres Cadastre + %br + %label + = ff.check_box :parcelles_agricoles + Parcelles Agricoles - hide_mandatory = (ff.object.object.private? || type_champ == TypeDeChamp.type_champs.fetch(:explication)) .form-group.mandatory{ style: hide_mandatory ? 'visibility: hidden;' : nil } diff --git a/app/views/shared/champs/carte/_geo_areas.html.haml b/app/views/shared/champs/carte/_geo_areas.html.haml index 863adc1d3..b2fabe249 100644 --- a/app/views/shared/champs/carte/_geo_areas.html.haml +++ b/app/views/shared/champs/carte/_geo_areas.html.haml @@ -25,3 +25,17 @@ %ul - champ.cadastres.each do |pc| %li Parcelle n° #{pc.numero} - Feuille #{pc.code_arr} #{pc.section} #{pc.feuille} + +- if champ.parcelles_agricoles? + .areas-title Parcelles agricoles (RPG) + .areas + - if error.present? + .error Merci de dessiner une surface plus petite afin de récupérer les parcelles agricoles. + - elsif champ.value.blank? + Aucune zone tracée + - elsif champ.parcelles_agricoles.blank? + = t('errors.messages.parcelles_agricoles_empty', count: champ.zones.size) + - else + %ul + - champ.parcelles_agricoles.each do |pa| + %li Culture : #{pa.culture} - Surface : #{pa.surface} ha diff --git a/config/locales/fr.yml b/config/locales/fr.yml index fbd48b6db..72651c3bd 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -183,6 +183,9 @@ fr: quartiers_prioritaires_empty: one: "Aucun quartier prioritaire sur la zone séléctionnée" other: "Aucun quartier prioritaire sur les zones séléctionnées" + parcelles_agricoles_empty: + one: "Aucune parcelle agricole sur la zone séléctionnée" + other: "Aucune parcelle agricole sur les zones séléctionnées" date: abbr_day_names: diff --git a/spec/controllers/champs/carte_controller_spec.rb b/spec/controllers/champs/carte_controller_spec.rb index fadf1fa1a..c4393bbcd 100644 --- a/spec/controllers/champs/carte_controller_spec.rb +++ b/spec/controllers/champs/carte_controller_spec.rb @@ -36,7 +36,7 @@ describe Champs::CarteController, type: :controller do context 'when coordinates are empty' do let(:selection) { [] } - it { expect(response.body).to include("DS.drawMapData(\".carte-1\", {\"position\":{\"lon\":\"2.428462\",\"lat\":\"46.538192\",\"zoom\":\"13\"},\"selection\":[],\"quartiersPrioritaires\":[],\"cadastres\":[]});") } + it { expect(response.body).to include("DS.drawMapData(\".carte-1\", {\"position\":{\"lon\":\"2.428462\",\"lat\":\"46.538192\",\"zoom\":\"13\"},\"selection\":[],\"quartiersPrioritaires\":[],\"cadastres\":[],\"parcellesAgricoles\":[]});") } end context 'when coordinates are informed' do From fd490efb5942f4bad921c51563db6be5d81b474e Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 23 Oct 2018 15:40:39 +0200 Subject: [PATCH 13/14] GeoArea on API expose fields per source type --- app/serializers/geo_area_serializer.rb | 46 +++++++++++++------ spec/factories/geo_area.rb | 6 +++ .../champs/carte_champ_serializer_spec.rb | 30 +++++++++--- 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/app/serializers/geo_area_serializer.rb b/app/serializers/geo_area_serializer.rb index 7d501ff4c..2b1f10766 100644 --- a/app/serializers/geo_area_serializer.rb +++ b/app/serializers/geo_area_serializer.rb @@ -1,16 +1,34 @@ class GeoAreaSerializer < ActiveModel::Serializer - attributes :geometry, - :source, - :surface_intersection, - :surface_parcelle, - :numero, - :feuille, - :section, - :code_dep, - :nom_com, - :code_com, - :code_arr, - :code, - :nom, - :commune + attributes :geometry, :source + + attribute :surface_intersection, if: :include_cadastre? + attribute :surface_parcelle, if: :include_cadastre? + attribute :numero, if: :include_cadastre? + attribute :feuille, if: :include_cadastre? + attribute :section, if: :include_cadastre? + attribute :code_dep, if: :include_cadastre? + attribute :nom_com, if: :include_cadastre? + attribute :code_com, if: :include_cadastre? + attribute :code_arr, if: :include_cadastre? + + attribute :code, if: :include_quartier_prioritaire? + attribute :nom, if: :include_quartier_prioritaire? + attribute :commune, if: :include_quartier_prioritaire? + + attribute :culture, if: :include_parcelle_agricole? + attribute :code_culture, if: :include_parcelle_agricole? + attribute :surface, if: :include_parcelle_agricole? + attribute :bio, if: :include_parcelle_agricole? + + def include_cadastre? + object.source == GeoArea.sources.fetch(:cadastre) + end + + def include_quartier_prioritaire? + object.source == GeoArea.sources.fetch(:quartier_prioritaire) + end + + def include_parcelle_agricole? + object.source == GeoArea.sources.fetch(:parcelle_agricole) + end end diff --git a/spec/factories/geo_area.rb b/spec/factories/geo_area.rb index 3050dc075..33b2decde 100644 --- a/spec/factories/geo_area.rb +++ b/spec/factories/geo_area.rb @@ -3,5 +3,11 @@ FactoryBot.define do source { GeoArea.sources.fetch(:cadastre) } numero { '42' } feuille { 'A11' } + + trait :quartier_prioritaire do + source { GeoArea.sources.fetch(:quartier_prioritaire) } + nom { 'XYZ' } + commune { 'Paris' } + end end end diff --git a/spec/serializers/champs/carte_champ_serializer_spec.rb b/spec/serializers/champs/carte_champ_serializer_spec.rb index 66419ac57..043fa3bc6 100644 --- a/spec/serializers/champs/carte_champ_serializer_spec.rb +++ b/spec/serializers/champs/carte_champ_serializer_spec.rb @@ -6,13 +6,29 @@ describe Champs::CarteChampSerializer do let(:geo_area) { create(:geo_area) } let(:champ) { create(:type_de_champ_carte).champ.create(geo_areas: [geo_area]) } - it { - expect(subject[:geo_areas].first).to include( - source: GeoArea.sources.fetch(:cadastre), - numero: '42', - feuille: 'A11' - ) - } + context 'and geo_area is cadastre' do + it { + expect(subject[:geo_areas].first).to include( + source: GeoArea.sources.fetch(:cadastre), + numero: '42', + feuille: 'A11' + ) + expect(subject[:geo_areas].first.key?(:nom)).to be_falsey + } + end + + context 'and geo_area is quartier_prioritaire' do + let(:geo_area) { create(:geo_area, :quartier_prioritaire) } + + it { + expect(subject[:geo_areas].first).to include( + source: GeoArea.sources.fetch(:quartier_prioritaire), + nom: 'XYZ', + commune: 'Paris' + ) + expect(subject[:geo_areas].first.key?(:numero)).to be_falsey + } + end end end end From 4abcffe2783dda57c3e89ef0ce05e05d1b901a69 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Tue, 23 Oct 2018 17:01:15 +0200 Subject: [PATCH 14/14] Test ApiGeo RPGAdapter --- .../fixtures/cassettes/api_geo_search_rpg.yml | 51 ++++++++++++++++ spec/lib/api_geo/api_spec.rb | 51 ++++++++++++++++ spec/lib/api_geo/rpg_adapter_spec.rb | 61 +++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 spec/fixtures/cassettes/api_geo_search_rpg.yml create mode 100644 spec/lib/api_geo/rpg_adapter_spec.rb diff --git a/spec/fixtures/cassettes/api_geo_search_rpg.yml b/spec/fixtures/cassettes/api_geo_search_rpg.yml new file mode 100644 index 000000000..97b72996a --- /dev/null +++ b/spec/fixtures/cassettes/api_geo_search_rpg.yml @@ -0,0 +1,51 @@ +--- +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_geo/api_spec.rb b/spec/lib/api_geo/api_spec.rb index c0d6e7ccb..6a046f119 100644 --- a/spec/lib/api_geo/api_spec.rb +++ b/spec/lib/api_geo/api_spec.rb @@ -21,4 +21,55 @@ describe ApiGeo::API do 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 new file mode 100644 index 000000000..83e5f9065 --- /dev/null +++ b/spec/lib/api_geo/rpg_adapter_spec.rb @@ -0,0 +1,61 @@ +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 + ]) + end + end + end +end