diff --git a/app/controllers/my_profile/maps_controller.rb b/app/controllers/my_profile/maps_controller.rb
new file mode 100644
index 0000000..dec4ec3
--- /dev/null
+++ b/app/controllers/my_profile/maps_controller.rb
@@ -0,0 +1,21 @@
+class MapsController < MyProfileController
+
+ protect 'edit_profile', :profile
+
+ def edit_location
+ @profile_data = profile
+ if request.post?
+ begin
+ Profile.transaction do
+ if profile.update_attributes!(params[:profile_data])
+ flash[:notice] = _('Address was updated successfully!')
+ redirect_to :action => 'edit_location'
+ end
+ end
+ rescue
+ flash[:error] = _('Address could not be saved.')
+ end
+ end
+ end
+
+end
diff --git a/app/controllers/my_profile/profile_design_controller.rb b/app/controllers/my_profile/profile_design_controller.rb
index 46c24fa..7e0c348 100644
--- a/app/controllers/my_profile/profile_design_controller.rb
+++ b/app/controllers/my_profile/profile_design_controller.rb
@@ -5,7 +5,7 @@ class ProfileDesignController < BoxOrganizerController
protect 'edit_profile_design', :profile
def available_blocks
- blocks = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock ]
+ blocks = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock, LocationBlock ]
# blocks exclusive for organizations
if profile.has_members?
@@ -22,7 +22,6 @@ class ProfileDesignController < BoxOrganizerController
# blocks exclusive for enterprises
if profile.enterprise?
- blocks << LocalizationBlock
blocks << DisabledEnterpriseMessageBlock
end
diff --git a/app/models/community.rb b/app/models/community.rb
index cf46a00..d56ffad 100644
--- a/app/models/community.rb
+++ b/app/models/community.rb
@@ -4,6 +4,7 @@ class Community < Organization
settings_items :description
settings_items :language
+ settings_items :zip_code, :city, :state, :country
xss_terminate :only => [ :name, :address, :contact_phone, :description ]
@@ -23,6 +24,10 @@ class Community < Organization
end
FIELDS = %w[
+ city
+ state
+ country
+ zip_code
description
language
]
diff --git a/app/models/environment.rb b/app/models/environment.rb
index d109ef9..aa63db0 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -275,6 +275,16 @@ class Environment < ActiveRecord::Base
self.settings['message_for_disabled_enterprise'] = value
end
+ # the environment's default location
+ def location
+ self.settings['location']
+ end
+
+ # sets the environment's location.
+ def location=(value)
+ self.settings['location'] = value
+ end
+
# returns the approval method used for this environment. Possible values are:
#
# Defaults to :admim.
diff --git a/app/models/localization_block.rb b/app/models/localization_block.rb
deleted file mode 100644
index 588686e..0000000
--- a/app/models/localization_block.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-class LocalizationBlock < Block
-
- def self.description
- _('Localization map block')
- end
-
- def help
- _('Shows where the profile is on the material world.')
- end
-
- def content
- profile = self.owner
- title = self.title
- lambda do
- profile.lat ?
- block_title(title) +
- content_tag('div',
- '
',
- :class => 'the-localization-map' ) :
- content_tag('i', _('This profile has no geographical position registered.'))
- end
- end
-
-end
diff --git a/app/models/location_block.rb b/app/models/location_block.rb
new file mode 100644
index 0000000..7d38c93
--- /dev/null
+++ b/app/models/location_block.rb
@@ -0,0 +1,30 @@
+class LocationBlock < Block
+
+ settings_items :zoom, :type => :integer , :default => 4
+ settings_items :map_type, :type => :string , :default => 'roadmap'
+
+ def self.description
+ _('Location map block')
+ end
+
+ def help
+ _('Shows where the profile is on the material world.')
+ end
+
+ def content
+ profile = self.owner
+ title = self.title
+ if profile.lat
+ block_title(title) +
+ content_tag('div',
+ '
',
+ :class => 'the-localization-map' )
+ else
+ content_tag('i', _('This profile has no geographical position registered.'))
+ end
+ end
+
+end
diff --git a/app/models/profile.rb b/app/models/profile.rb
index b8dcdb1..e9498d2 100644
--- a/app/models/profile.rb
+++ b/app/models/profile.rb
@@ -151,12 +151,23 @@ class Profile < ActiveRecord::Base
belongs_to :region
- def location
+ def location(separator = ' - ')
myregion = self.region
if myregion
- myregion.hierarchy.reverse.first(2).map(&:name).join(' - ')
+ myregion.hierarchy.reverse.first(2).map(&:name).join(separator)
else
- [ :city, :state, :country_name ].map {|item| self.respond_to?(item) ? self.send(item) : nil }.compact.join(' - ')
+ %w[address city state country_name zip_code ].map {|item| (self.respond_to?(item) && !self.send(item).blank?) ? self.send(item) : nil }.compact.join(separator)
+ end
+ end
+
+ def geolocation
+ unless location.blank?
+ location
+ else
+ if environment.location.blank?
+ environment.location = "BRA"
+ end
+ environment.location
end
end
diff --git a/app/views/box_organizer/_location_block.rhtml b/app/views/box_organizer/_location_block.rhtml
new file mode 100644
index 0000000..6f6e405
--- /dev/null
+++ b/app/views/box_organizer/_location_block.rhtml
@@ -0,0 +1,10 @@
+
+ <%= labelled_form_field _('Zoom Level:'), select(:block, :zoom, [[_('World'), 0],
+ 1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18,
+ [_('Street'), 19]]) %>
+ <%= labelled_form_field _('Map Type:'), select(:block, :map_type, [[_('Road Map') , 'roadmap' ],
+ [_('Mobile') , 'mobile' ],
+ [_('Satellite'), 'satellite'],
+ [_('Terrain') , 'terrain' ],
+ [_('Hybrid') , 'hybrid' ]]) %>
+
diff --git a/app/views/maps/_google_map.rhtml b/app/views/maps/_google_map.rhtml
new file mode 100644
index 0000000..4cba405
--- /dev/null
+++ b/app/views/maps/_google_map.rhtml
@@ -0,0 +1,136 @@
+<%= content_tag('script', '', :src => GoogleMaps.api_url, :type => 'text/javascript') %>
+
+
diff --git a/app/views/maps/edit_location.rhtml b/app/views/maps/edit_location.rhtml
new file mode 100644
index 0000000..13ca1a9
--- /dev/null
+++ b/app/views/maps/edit_location.rhtml
@@ -0,0 +1,35 @@
+<%= _('Location') %>
+
+<% form_for :profile_data, :url => {:action => 'edit_location'} do |f| %>
+
+
+ <%= optional_field(profile, 'country', select_country(_('Country'), 'profile_data', 'country', {:class => 'type-select'})) %>
+ <%= optional_field(profile, 'state', labelled_form_field(_('State'), f.text_field(:state))) %>
+ <%= optional_field(profile, 'city', labelled_form_field(_('City'), f.text_field(:city))) %>
+ <%= optional_field(profile, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code))) %>
+ <%= optional_field(profile, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address))) %>
+ <% button_bar do %>
+ <%= button_to_function :search, _('Locate in the map'), "getAddress(null, getAddressData())", :title => _("Locate the address informed above in the map below (note that you'll probably need to adjust the marker to get a precise position)") %>
+ <%= submit_button 'save', _('Save') %>
+ <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
+ <% end %>
+
+
+
+
+
+ <%= f.hidden_field(:lat) %>
+ <%= f.hidden_field(:lng) %>
+
+
+
+ <% button_bar do %>
+ <%= submit_button 'save', _('Save') %>
+ <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
+ <% end %>
+
+<% end %>
+
+<%= render :partial => 'google_map'%>
diff --git a/app/views/profile_editor/index.rhtml b/app/views/profile_editor/index.rhtml
index 25717a8..054ff25 100644
--- a/app/views/profile_editor/index.rhtml
+++ b/app/views/profile_editor/index.rhtml
@@ -14,6 +14,8 @@
<%= control_panel_button(__('Community Info and settings'), 'edit-profile-group', :controller => 'profile_editor', :action => 'edit') if profile.community? %>
<%= control_panel_button(__('Enterprise Info and settings'), 'edit-profile-enterprise', :controller => 'profile_editor', :action => 'edit') if profile.enterprise? %>
+ <%= control_panel_button(_('Location'), 'edit-location', :controller => 'maps', :action => 'edit_location') %>
+
<%= control_panel_button(_('Mail settings'), 'mail', :controller => 'mailconf') if profile.person? && MailConf.enabled? %>
<%= control_panel_button(_('Tasks'), 'todo', :controller => 'tasks', :action => 'index') %>
diff --git a/db/migrate/077_rename_location_block.rb b/db/migrate/077_rename_location_block.rb
new file mode 100644
index 0000000..4b7e948
--- /dev/null
+++ b/db/migrate/077_rename_location_block.rb
@@ -0,0 +1,9 @@
+class RenameLocationBlock < ActiveRecord::Migration
+ def self.up
+ execute "update blocks set type='LocationBlock' where type='LocalizationBlock'"
+ end
+
+ def self.down
+ execute "update blocks set type='LocalizationBlock' where type='LocationBlock'"
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index cf1f56c..2f6a5d6 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 76) do
+ActiveRecord::Schema.define(:version => 77) do
create_table "article_versions", :force => true do |t|
t.integer "article_id"
@@ -88,8 +88,8 @@ ActiveRecord::Schema.define(:version => 76) do
t.boolean "virtual", :default => false
end
- add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id"
add_index "articles_categories", ["category_id"], :name => "index_articles_categories_on_category_id"
+ add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id"
create_table "blocks", :force => true do |t|
t.string "title"
@@ -103,10 +103,10 @@ ActiveRecord::Schema.define(:version => 76) do
t.datetime "fetched_at"
end
- add_index "blocks", ["box_id"], :name => "index_blocks_on_box_id"
- add_index "blocks", ["enabled"], :name => "index_blocks_on_enabled"
- add_index "blocks", ["fetched_at"], :name => "index_blocks_on_fetched_at"
add_index "blocks", ["type"], :name => "index_blocks_on_type"
+ add_index "blocks", ["fetched_at"], :name => "index_blocks_on_fetched_at"
+ add_index "blocks", ["enabled"], :name => "index_blocks_on_enabled"
+ add_index "blocks", ["box_id"], :name => "index_blocks_on_box_id"
create_table "boxes", :force => true do |t|
t.string "owner_type"
@@ -136,8 +136,8 @@ ActiveRecord::Schema.define(:version => 76) do
t.boolean "virtual", :default => false
end
- add_index "categories_profiles", ["category_id"], :name => "index_categories_profiles_on_category_id"
add_index "categories_profiles", ["profile_id"], :name => "index_categories_profiles_on_profile_id"
+ add_index "categories_profiles", ["category_id"], :name => "index_categories_profiles_on_category_id"
create_table "comments", :force => true do |t|
t.string "title"
@@ -189,8 +189,8 @@ ActiveRecord::Schema.define(:version => 76) do
t.integer "update_errors", :default => 0
end
- add_index "external_feeds", ["enabled"], :name => "index_external_feeds_on_enabled"
add_index "external_feeds", ["fetched_at"], :name => "index_external_feeds_on_fetched_at"
+ add_index "external_feeds", ["enabled"], :name => "index_external_feeds_on_enabled"
create_table "favorite_enteprises_people", :id => false, :force => true do |t|
t.integer "person_id"
@@ -224,8 +224,8 @@ ActiveRecord::Schema.define(:version => 76) do
t.datetime "updated_at"
end
- add_index "product_categorizations", ["category_id"], :name => "index_product_categorizations_on_category_id"
add_index "product_categorizations", ["product_id"], :name => "index_product_categorizations_on_product_id"
+ add_index "product_categorizations", ["category_id"], :name => "index_product_categorizations_on_category_id"
create_table "products", :force => true do |t|
t.integer "enterprise_id"
@@ -305,8 +305,8 @@ ActiveRecord::Schema.define(:version => 76) do
t.datetime "created_at"
end
- add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
add_index "taggings", ["taggable_id", "taggable_type"], :name => "index_taggings_on_taggable_id_and_taggable_type"
+ add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
create_table "tags", :force => true do |t|
t.string "name"
diff --git a/features/location.feature b/features/location.feature
new file mode 100644
index 0000000..d69c113
--- /dev/null
+++ b/features/location.feature
@@ -0,0 +1,57 @@
+Feature: Location
+ As a user
+ I want to edit my address and location
+ So that others can find me in the map
+
+ Background:
+ And the following users
+ | login |
+ | zezinho |
+ And I am logged in as "zezinho"
+
+ Scenario: editing my address
+ Given the following Person fields are enabled
+ | address |
+ | country |
+ | state |
+ | city |
+ | zip_code |
+ And I follow "Control panel"
+ And I follow "Location"
+ When I fill in "Address" with "Rua Marechal Floriano, 28"
+ And I select "Brazil" from "Country"
+ And I fill in "State" with "Bahia"
+ And I fill in "City" with "Salvador"
+ And I fill in "ZIP Code" with "40110010"
+ And I press "Save"
+ Then "zezinho" should have the following data
+ | address | country | state | city | zip_code |
+ | Rua Marechal Floriano, 28 | BR | Bahia | Salvador | 40110010 |
+
+ Scenario Outline: editing address of collectives
+ Given the following fields are enabled
+ | address |
+ | country |
+ | state |
+ | city |
+ | zip_code |
+ Given the following
+ | identifier | name | owner |
+ | colivre | Colivre | zezinho |
+ And I am on Colivre's control panel
+ And I follow "Location"
+ And I select "Brazil" from "Country"
+ And I fill in the following:
+ | Address | Rua Marechal Floriano, 28 |
+ | State | Bahia |
+ | City | Salvador |
+ | ZIP Code | 40110010 |
+ When I press "Save"
+ Then "colivre" should have the following data
+ | address | country | state | city | zip_code |
+ | Rua Marechal Floriano, 28 | BR | Bahia | Salvador | 40110010 |
+ Examples:
+ | class | plural |
+ | Community | communities |
+ | Enterprise | enterprises |
+
diff --git a/features/step_definitions/custom_webrat_steps.rb b/features/step_definitions/custom_webrat_steps.rb
index f88f67a..97ed810 100644
--- a/features/step_definitions/custom_webrat_steps.rb
+++ b/features/step_definitions/custom_webrat_steps.rb
@@ -6,3 +6,7 @@ When /^I should not see "([^\"]+)" link$/ do |link|
response.should_not have_selector("a", :content => link)
end
+When /^I wait (\d+) seconds$/ do |seconds|
+ sleep seconds.to_i
+end
+
diff --git a/features/step_definitions/noosfero_steps.rb b/features/step_definitions/noosfero_steps.rb
index d4e3a27..f7d4f3b 100644
--- a/features/step_definitions/noosfero_steps.rb
+++ b/features/step_definitions/noosfero_steps.rb
@@ -7,15 +7,14 @@ Given /^the following users$/ do |table|
end
end
-Given /^the following communities$/ do |table|
- table.hashes.each do |item|
- Community.create!(item)
- end
-end
-
-Given /^the following enterprises$/ do |table|
- table.hashes.each do |item|
- Enterprise.create!(item)
+Given /^the following (communities|enterprises)$/ do |kind,table|
+ klass = kind.singularize.camelize.constantize
+ table.hashes.each do |row|
+ owner = row.delete("owner")
+ community = klass.create!(row)
+ if owner
+ community.add_admin(Profile[owner])
+ end
end
end
@@ -111,3 +110,24 @@ end
Given /^"([^\"]*)" has no articles$/ do |profile|
(Profile[profile] || Profile.find_by_name(profile)).articles.delete_all
end
+
+Given /^the following (\w+) fields are enabled$/ do |klass, table|
+ env = Environment.default
+ fields = table.raw.inject({}) do |hash, line|
+ hash[line.first] = { "active" => 'true' }
+ hash
+ end
+
+ env.send("custom_#{klass.downcase}_fields=", fields)
+ env.save!
+ if fields.keys != env.send("active_#{klass.downcase}_fields")
+ raise "Not all fields enabled! Requested: %s; Enabled: %s" % [fields.keys.inspect, env.send("active_#{klass.downcase}_fields").inspect]
+ end
+end
+
+Then /^"([^\"]*)" should have the following data$/ do |id, table|
+ profile = Profile.find_by_identifier(id)
+ expected = table.hashes.first
+ data = expected.keys.inject({}) { |hash, key| hash[key] = profile.send(key).to_s; hash }
+ data.should == expected
+end
diff --git a/public/stylesheets/blocks/localization-block.css b/public/stylesheets/blocks/localization-block.css
deleted file mode 100644
index dc34ec7..0000000
--- a/public/stylesheets/blocks/localization-block.css
+++ /dev/null
@@ -1,13 +0,0 @@
-.localization-block {
- text-align: center;
-}
-
-.the-localization-map {
- margin: auto;
- width: 211px;
- max-width: 205px;
- padding: 3px;
- background: #FFF;
- border: 1px solid #888;
-}
-
diff --git a/public/stylesheets/blocks/location-block.css b/public/stylesheets/blocks/location-block.css
new file mode 100644
index 0000000..129a9b2
--- /dev/null
+++ b/public/stylesheets/blocks/location-block.css
@@ -0,0 +1,13 @@
+.location-block {
+ text-align: center;
+}
+
+.the-localization-map {
+ overflow: hidden;
+ margin: auto;
+ max-width: 205px;
+ padding: 3px;
+ background: #FFF;
+ border: 1px solid #888;
+}
+
diff --git a/public/stylesheets/common.css b/public/stylesheets/common.css
index ec97a3f..bf3cfdd 100644
--- a/public/stylesheets/common.css
+++ b/public/stylesheets/common.css
@@ -604,3 +604,10 @@ code input {
cursor: progress;
background: transparent url(../images/loading.gif) no-repeat scroll center 50px;
}
+
+/**** Location Map ****/
+#location-map {
+ width: 100%;
+ height: 320px;
+}
+
diff --git a/public/stylesheets/controller_profile_editor.css b/public/stylesheets/controller_profile_editor.css
index 87f95f4..406f808 100644
--- a/public/stylesheets/controller_profile_editor.css
+++ b/public/stylesheets/controller_profile_editor.css
@@ -88,3 +88,5 @@ a.control-panel-validation {background-image: url(../images/control-panel/applic
a.control-panel-mail {background-image: url(../images/control-panel/email.png)}
.msie6 a.control-panel-mail {background-image: url(../images/control-panel/email.gif)}
+a.control-panel-edit-location {background-image: url(../images/control-panel/set-geolocation.png)}
+.msie6 a.control-panel-edit-location {background-image: url(../images/control-panel/set-geolocation.gif)}
diff --git a/test/functional/maps_controller_test.rb b/test/functional/maps_controller_test.rb
new file mode 100644
index 0000000..f1963a9
--- /dev/null
+++ b/test/functional/maps_controller_test.rb
@@ -0,0 +1,43 @@
+require File.dirname(__FILE__) + '/../test_helper'
+require 'maps_controller'
+
+# Re-raise errors caught by the controller.
+class MapsController; def rescue_action(e) raise e end; end
+
+class MapsControllerTest < Test::Unit::TestCase
+
+ def setup
+ @controller = MapsController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @profile = create_user('test_profile').person
+ login_as(@profile.identifier)
+ end
+
+ attr_reader :profile
+
+ should 'save profile address' do
+ post :edit_location, :profile => profile.identifier, :profile_data => { 'address' => 'new address' }
+ assert_equal 'new address', Profile['test_profile'].address
+ end
+
+ should 'back when update address fail' do
+ Profile.any_instance.stubs(:update_attributes!).returns(false)
+ post :edit_location, :profile => profile.identifier, :profile_data => { 'address' => 'new address' }
+ assert_nil profile.address
+ assert_template 'edit_location'
+ end
+
+ should 'show page to edit location' do
+ get :edit_location, :profile => profile.identifier
+ assert_response :success
+ assert_template 'edit_location'
+ end
+
+ should 'dispĺay form for address with profile address' do
+ get :edit_location, :profile => profile.identifier
+ assert_tag :tag => 'input', :attributes => { :name => 'location' }
+ end
+
+end
diff --git a/test/unit/profile_test.rb b/test/unit/profile_test.rb
index bf99987..41c0621 100644
--- a/test/unit/profile_test.rb
+++ b/test/unit/profile_test.rb
@@ -698,15 +698,60 @@ class ProfileTest < Test::Unit::TestCase
assert_equal 'Salvador - Bahia', p.location
end
- should 'use city/state/country fields for location when no region object is set' do
+ should 'use city/state/country/address/zip_code fields for location when no region object is set' do
p = Profile.new
p.expects(:region).returns(nil)
- p.expects(:city).returns("Salvador")
- p.expects(:state).returns("Bahia")
- p.expects(:country_name).returns("Brasil")
- assert_equal 'Salvador - Bahia - Brasil', p.location
+ p.expects(:address).returns("Rua A").at_least_once
+ p.expects(:city).returns("Salvador").at_least_once
+ p.expects(:state).returns("Bahia").at_least_once
+ p.expects(:country_name).returns("Brasil").at_least_once
+ p.expects(:zip_code).returns("40000000").at_least_once
+ assert_equal 'Rua A - Salvador - Bahia - Brasil - 40000000', p.location
end
+ should 'choose separator for location' do
+ p = Profile.new
+ p.expects(:region).returns(nil)
+ p.expects(:address).returns("Rua A").at_least_once
+ p.expects(:city).returns("Salvador").at_least_once
+ p.expects(:state).returns("Bahia").at_least_once
+ p.expects(:country_name).returns("Brasil").at_least_once
+ p.expects(:zip_code).returns("40000000").at_least_once
+ assert_equal 'Rua A, Salvador, Bahia, Brasil, 40000000', p.location(', ')
+ end
+
+ should 'not display separator on location if city/state/country/address/zip_code is blank' do
+ p = Profile.new
+ p.expects(:region).returns(nil)
+ p.expects(:address).returns("Rua A").at_least_once
+ p.expects(:city).returns("Salvador").at_least_once
+ p.expects(:state).returns("").at_least_once
+ p.expects(:country_name).returns("Brasil").at_least_once
+ p.expects(:zip_code).returns("40000000").at_least_once
+ assert_equal 'Rua A - Salvador - Brasil - 40000000', p.location
+ end
+
+ should 'use location on geolocation if not blank' do
+ p = Profile.new
+ p.expects(:region).returns(nil).at_least_once
+ p.expects(:address).returns("Rua A").at_least_once
+ p.expects(:city).returns("Salvador").at_least_once
+ p.expects(:state).returns("").at_least_once
+ p.expects(:country_name).returns("Brasil").at_least_once
+ p.expects(:zip_code).returns("40000000").at_least_once
+ assert_equal 'Rua A - Salvador - Brasil - 40000000', p.geolocation
+ end
+
+ should 'use default location on geolocation if not blank' do
+ p = Profile.new
+ p.expects(:region).returns(nil)
+ e = Environment.default
+ p.expects(:environment).returns(e)
+ e.expects(:location).returns('Brasil')
+ assert_equal 'Brasil', p.geolocation
+ end
+
+
should 'lookup country name' do
p = Profile.new
# two sample countries; trust the rest works
--
libgit2 0.21.2