diff --git a/app/assets/javascripts/map.js.coffee b/app/assets/javascripts/map.js.coffee
index 3f28024a7..797232c4f 100644
--- a/app/assets/javascripts/map.js.coffee
+++ b/app/assets/javascripts/map.js.coffee
@@ -7,6 +7,10 @@ App.Map =
$.each maps, (index, map) ->
App.Map.initializeMap map
+ $('.js-toggle-map').on
+ click: ->
+ App.Map.toogleMap()
+
initializeMap: (element) ->
mapCenterLatitude = $(element).data('map-center-latitude')
@@ -76,3 +80,7 @@ App.Map =
$(removeMarkerSelector).on 'click', removeMarker
map.on 'zoomend', updateFormfields
map.on 'click', moveOrPlaceMarker
+
+ toogleMap: ->
+ $('.map').toggle()
+ $('.location-map-remove-marker-button').toggle()
\ No newline at end of file
diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb
index 5e7c1ddf0..f6125c214 100644
--- a/app/controllers/budgets/investments_controller.rb
+++ b/app/controllers/budgets/investments_controller.rb
@@ -104,7 +104,7 @@ module Budgets
def investment_params
params.require(:budget_investment)
.permit(:title, :description, :external_url, :heading_id, :tag_list,
- :organization_name, :location, :terms_of_service,
+ :organization_name, :location, :terms_of_service, :skip_map,
image_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
map_location_attributes: [:latitude, :longitude, :zoom])
diff --git a/app/controllers/proposals_controller.rb b/app/controllers/proposals_controller.rb
index 1f065db06..400887046 100644
--- a/app/controllers/proposals_controller.rb
+++ b/app/controllers/proposals_controller.rb
@@ -80,7 +80,7 @@ class ProposalsController < ApplicationController
def proposal_params
params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url,
- :responsible_name, :tag_list, :terms_of_service, :geozone_id,
+ :responsible_name, :tag_list, :terms_of_service, :geozone_id, :skip_map,
image_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy],
map_location_attributes: [:latitude, :longitude, :zoom])
diff --git a/app/models/concerns/mappable.rb b/app/models/concerns/mappable.rb
index c108bdca7..cd4a498f3 100644
--- a/app/models/concerns/mappable.rb
+++ b/app/models/concerns/mappable.rb
@@ -2,8 +2,29 @@ module Mappable
extend ActiveSupport::Concern
included do
+ attr_accessor :skip_map
+
has_one :map_location, dependent: :destroy
accepts_nested_attributes_for :map_location, allow_destroy: true
+
+ validate :map_must_be_valid, if: :feature_maps?
+
+ def map_must_be_valid
+ return true if skip_map?
+
+ unless map_location.try(:available?)
+ errors.add(:skip_map, I18n.t('activerecord.errors.models.map_location.attributes.map.invalid'))
+ end
+ end
+
+ def feature_maps?
+ Setting["feature.map"].present?
+ end
+
+ def skip_map?
+ skip_map == "1"
+ end
+
end
end
diff --git a/app/views/map_locations/_form_fields.html.erb b/app/views/map_locations/_form_fields.html.erb
index 39c87c7e4..41423b50d 100644
--- a/app/views/map_locations/_form_fields.html.erb
+++ b/app/views/map_locations/_form_fields.html.erb
@@ -16,4 +16,17 @@
<%= m_l_fields.hidden_field :zoom,
value: map_location.zoom,
id: map_location_input_id(parent_class, 'zoom') %>
+
+
+ <%= form.label :skip_map do %>
+ <%= form.check_box :skip_map,
+ title: t("proposals.form.map_skip_checkbox"),
+ label: false,
+ class: 'js-toggle-map' %>
+
+ <%= t("proposals.form.map_skip_checkbox") %>
+
+ <% end %>
+
<% end %>
+
diff --git a/config/locales/en/activerecord.yml b/config/locales/en/activerecord.yml
index f3952aaca..df5a59c90 100644
--- a/config/locales/en/activerecord.yml
+++ b/config/locales/en/activerecord.yml
@@ -250,6 +250,10 @@ en:
attachment:
min_image_width: "Image Width must be at least %{required_min_width}px"
min_image_height: "Image Height must be at least %{required_min_height}px"
+ map_location:
+ attributes:
+ map:
+ invalid: Map location can't be blank. Place a marker or select the checkbox if geolocalization is not needed
poll/voter:
attributes:
document_number:
diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml
index 5ca49fc6b..998af36ab 100644
--- a/config/locales/en/general.yml
+++ b/config/locales/en/general.yml
@@ -338,6 +338,7 @@ en:
map_location: "Map location"
map_location_instructions: "Navigate the map to the location and place the marker."
map_remove_marker: "Remove map marker"
+ map_skip_checkbox: "This proposal doesn't have a concrete location or I'm not aware of it."
index:
featured_proposals: Featured
filter_topic:
diff --git a/config/locales/es/activerecord.yml b/config/locales/es/activerecord.yml
index fe3ae694c..60492dc32 100644
--- a/config/locales/es/activerecord.yml
+++ b/config/locales/es/activerecord.yml
@@ -245,6 +245,10 @@ es:
attachment:
min_image_width: "La imagen debe tener al menos %{required_min_width}px de largo"
min_image_height: "La imagen debe tener al menos %{required_min_height}px de alto"
+ map_location:
+ attributes:
+ map:
+ invalid: El mapa no puede estar en blanco. Añade un punto al mapa o marca la casilla si no hace falta un mapa.
poll/voter:
attributes:
document_number:
diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml
index 5453b0555..4c4b6bac5 100644
--- a/config/locales/es/general.yml
+++ b/config/locales/es/general.yml
@@ -338,6 +338,7 @@ es:
map_location: "Ubicación en el mapa"
map_location_instructions: "Navega por el mapa hasta la ubicación y coloca el marcador."
map_remove_marker: "Eliminar el marcador"
+ map_skip_checkbox: "Esta propuesta no tiene una ubicación concreta o no la conozco."
index:
featured_proposals: Destacadas
filter_topic:
diff --git a/spec/factories.rb b/spec/factories.rb
index f7b68dd3c..8a32c4b9e 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -165,6 +165,7 @@ FactoryGirl.define do
video_url 'https://youtu.be/nhuNb0XtRhQ'
responsible_name 'John Snow'
terms_of_service '1'
+ skip_map '1'
association :author, factory: :user
trait :hidden do
@@ -279,6 +280,7 @@ FactoryGirl.define do
price 10
unfeasibility_explanation ''
external_url 'http://external_documention.org'
+ skip_map '1'
terms_of_service '1'
incompatible false
diff --git a/spec/models/proposal_spec.rb b/spec/models/proposal_spec.rb
index 6d35d54ff..6308b77be 100644
--- a/spec/models/proposal_spec.rb
+++ b/spec/models/proposal_spec.rb
@@ -7,6 +7,7 @@ describe Proposal do
describe "Concerns" do
it_behaves_like "has_public_author"
it_behaves_like "notifiable"
+ it_behaves_like "map validations"
end
it "should be valid" do
diff --git a/spec/shared/features/mappable.rb b/spec/shared/features/mappable.rb
index 65ece1f25..d3fa4fc70 100644
--- a/spec/shared/features/mappable.rb
+++ b/spec/shared/features/mappable.rb
@@ -56,6 +56,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
send("fill_in_#{mappable_factory_name}_form")
expect(page).to have_css ".map_location"
+ check "#{mappable_factory_name}_skip_map"
send("submit_#{mappable_factory_name}_form")
expect(page).not_to have_css(".map_location")
@@ -73,6 +74,41 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
expect(page).not_to have_css(".map_location")
end
+ scenario 'Errors on create' do
+ login_as user
+ visit send(mappable_new_path, arguments)
+
+ send("submit_#{mappable_factory_name}_form")
+
+ expect(page).to have_content "Map location can't be blank"
+ end
+
+ scenario 'Skip map', :js do
+ login_as user
+ visit send(mappable_new_path, arguments)
+
+ send("fill_in_#{mappable_factory_name}_form")
+ check "#{mappable_factory_name}_skip_map"
+ send("submit_#{mappable_factory_name}_form")
+
+ expect(page).to_not have_content "Map location can't be blank"
+ end
+
+ scenario 'Toggle map', :js do
+ login_as user
+ visit send(mappable_new_path, arguments)
+
+ check "#{mappable_factory_name}_skip_map"
+
+ expect(page).to_not have_css(".map")
+ expect(page).to_not have_content("Remove map marker")
+
+ uncheck "#{mappable_factory_name}_skip_map"
+
+ expect(page).to have_css(".map")
+ expect(page).to have_content("Remove map marker")
+ end
+
end
describe "At #{mappable_edit_path}" do
@@ -122,6 +158,7 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
visit send(mappable_edit_path, id: mappable.id)
click_link "Remove map marker"
+ check "#{mappable_factory_name}_skip_map"
click_on "Save changes"
expect(page).not_to have_css(".map_location")
@@ -138,6 +175,27 @@ shared_examples "mappable" do |mappable_factory_name, mappable_association_name,
expect(page).not_to have_css(".map_location")
end
+ scenario 'Errors on update', :js do
+ login_as mappable.author
+
+ visit send(mappable_edit_path, id: mappable.id)
+ click_link "Remove map marker"
+ click_on "Save changes"
+
+ expect(page).to have_content "Map location can't be blank"
+ end
+
+ scenario 'Skip map on update' do
+ login_as mappable.author
+
+ visit send(mappable_edit_path, id: mappable.id)
+ click_link "Remove map marker"
+ check "#{mappable_factory_name}_skip_map"
+ click_on "Save changes"
+
+ expect(page).to_not have_content "Map location can't be blank"
+ end
+
end
describe "At #{mappable_show_path}" do
@@ -189,9 +247,12 @@ def submit_proposal_form
check :proposal_terms_of_service
click_button 'Create proposal'
- click_link 'Not now, go to my proposal'
+ if page.has_content?('Not now, go to my proposal')
+ click_link 'Not now, go to my proposal'
+ end
end
+
def validate_latitude_longitude(mappable_factory_name)
expect(find("##{mappable_factory_name}_map_location_attributes_latitude", visible: false).value).to eq "51.48"
expect(find("##{mappable_factory_name}_map_location_attributes_longitude", visible: false).value).to eq "0.0"
diff --git a/spec/shared/models/map_validations.rb b/spec/shared/models/map_validations.rb
new file mode 100644
index 000000000..f9adb638f
--- /dev/null
+++ b/spec/shared/models/map_validations.rb
@@ -0,0 +1,53 @@
+shared_examples "map validations" do
+
+ let(:mappable) { build(model_name(described_class)) }
+
+ describe "map" do
+
+ before(:each) do
+ Setting["feature.map"] = true
+ end
+
+ after(:each) do
+ Setting["feature.map"] = nil
+ end
+
+ it "should be valid with a map location" do
+ mappable.map_location = build(:map_location)
+ mappable.skip_map = nil
+
+ expect(mappable).to be_valid
+ end
+
+ it "should be valid accepting that the mappable has no map" do
+ mappable.skip_map = "1"
+ mappable.map_location = nil
+
+ expect(mappable).to be_valid
+ end
+
+ it "should be valid when the feature map is deactivated" do
+ Setting["feature.map"] = nil
+
+ mappable.map_location = nil
+ mappable.skip_map = nil
+
+ expect(mappable).to be_valid
+ end
+
+ it "should not be valid without a map location" do
+ mappable.map_location = nil
+ mappable.skip_map = nil
+
+ expect(mappable).to_not be_valid
+ end
+
+ it "should not be valid without accepting that the mappable has no map" do
+ mappable.skip_map = nil
+
+ expect(mappable).to_not be_valid
+ end
+
+ end
+
+end
\ No newline at end of file