Commit d7ab4a9dfa8b388dbfba1004a6c69ff4f9690a02
Committed by
Antonio Terceiro
1 parent
88921ec9
Exists in
master
and in
28 other branches
Georeferencing
* The user can set his location in the map by dragging a marker or by setting his address in the form. * After setting his location, the map is added to the location block. * The user can configure the zoom level and the map type that will be shown in the location block. ActionItem1256
Showing
22 changed files
with
487 additions
and
65 deletions
Show diff stats
... | ... | @@ -0,0 +1,21 @@ |
1 | +class MapsController < MyProfileController | |
2 | + | |
3 | + protect 'edit_profile', :profile | |
4 | + | |
5 | + def edit_location | |
6 | + @profile_data = profile | |
7 | + if request.post? | |
8 | + begin | |
9 | + Profile.transaction do | |
10 | + if profile.update_attributes!(params[:profile_data]) | |
11 | + flash[:notice] = _('Address was updated successfully!') | |
12 | + redirect_to :action => 'edit_location' | |
13 | + end | |
14 | + end | |
15 | + rescue | |
16 | + flash[:error] = _('Address could not be saved.') | |
17 | + end | |
18 | + end | |
19 | + end | |
20 | + | |
21 | +end | ... | ... |
app/controllers/my_profile/profile_design_controller.rb
... | ... | @@ -5,7 +5,7 @@ class ProfileDesignController < BoxOrganizerController |
5 | 5 | protect 'edit_profile_design', :profile |
6 | 6 | |
7 | 7 | def available_blocks |
8 | - blocks = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock ] | |
8 | + blocks = [ ArticleBlock, TagsBlock, RecentDocumentsBlock, ProfileInfoBlock, LinkListBlock, MyNetworkBlock, FeedReaderBlock, ProfileImageBlock, LocationBlock ] | |
9 | 9 | |
10 | 10 | # blocks exclusive for organizations |
11 | 11 | if profile.has_members? |
... | ... | @@ -22,7 +22,6 @@ class ProfileDesignController < BoxOrganizerController |
22 | 22 | |
23 | 23 | # blocks exclusive for enterprises |
24 | 24 | if profile.enterprise? |
25 | - blocks << LocalizationBlock | |
26 | 25 | blocks << DisabledEnterpriseMessageBlock |
27 | 26 | end |
28 | 27 | ... | ... |
app/models/community.rb
... | ... | @@ -4,6 +4,7 @@ class Community < Organization |
4 | 4 | |
5 | 5 | settings_items :description |
6 | 6 | settings_items :language |
7 | + settings_items :zip_code, :city, :state, :country | |
7 | 8 | |
8 | 9 | xss_terminate :only => [ :name, :address, :contact_phone, :description ] |
9 | 10 | |
... | ... | @@ -23,6 +24,10 @@ class Community < Organization |
23 | 24 | end |
24 | 25 | |
25 | 26 | FIELDS = %w[ |
27 | + city | |
28 | + state | |
29 | + country | |
30 | + zip_code | |
26 | 31 | description |
27 | 32 | language |
28 | 33 | ] | ... | ... |
app/models/environment.rb
... | ... | @@ -275,6 +275,16 @@ class Environment < ActiveRecord::Base |
275 | 275 | self.settings['message_for_disabled_enterprise'] = value |
276 | 276 | end |
277 | 277 | |
278 | + # the environment's default location | |
279 | + def location | |
280 | + self.settings['location'] | |
281 | + end | |
282 | + | |
283 | + # sets the environment's location. | |
284 | + def location=(value) | |
285 | + self.settings['location'] = value | |
286 | + end | |
287 | + | |
278 | 288 | # returns the approval method used for this environment. Possible values are: |
279 | 289 | # |
280 | 290 | # Defaults to <tt>:admim</tt>. | ... | ... |
app/models/localization_block.rb
... | ... | @@ -1,24 +0,0 @@ |
1 | -class LocalizationBlock < Block | |
2 | - | |
3 | - def self.description | |
4 | - _('Localization map block') | |
5 | - end | |
6 | - | |
7 | - def help | |
8 | - _('Shows where the profile is on the material world.') | |
9 | - end | |
10 | - | |
11 | - def content | |
12 | - profile = self.owner | |
13 | - title = self.title | |
14 | - lambda do | |
15 | - profile.lat ? | |
16 | - block_title(title) + | |
17 | - content_tag('div', | |
18 | - '<img src="http://maps.google.com/staticmap?center='+profile.lat.to_s()+','+profile.lng.to_s()+'&zoom=8&size=205x250&maptype=roadmap&markers='+profile.lat.to_s()+','+profile.lng.to_s()+',green&key='+GoogleMaps::key+'&sensor=false"/>', | |
19 | - :class => 'the-localization-map' ) : | |
20 | - content_tag('i', _('This profile has no geographical position registered.')) | |
21 | - end | |
22 | - end | |
23 | - | |
24 | -end |
... | ... | @@ -0,0 +1,30 @@ |
1 | +class LocationBlock < Block | |
2 | + | |
3 | + settings_items :zoom, :type => :integer , :default => 4 | |
4 | + settings_items :map_type, :type => :string , :default => 'roadmap' | |
5 | + | |
6 | + def self.description | |
7 | + _('Location map block') | |
8 | + end | |
9 | + | |
10 | + def help | |
11 | + _('Shows where the profile is on the material world.') | |
12 | + end | |
13 | + | |
14 | + def content | |
15 | + profile = self.owner | |
16 | + title = self.title | |
17 | + if profile.lat | |
18 | + block_title(title) + | |
19 | + content_tag('div', | |
20 | + '<img src="http://maps.google.com/staticmap?center=' + profile.lat.to_s() + | |
21 | + ',' + profile.lng.to_s() + '&zoom=' + zoom.to_s() + | |
22 | + '&size=205x250&maptype=' + map_type + '&markers=' + profile.lat.to_s() + ',' + | |
23 | + profile.lng.to_s() + ',green&key=' + GoogleMaps::key + '&sensor=false"/>', | |
24 | + :class => 'the-localization-map' ) | |
25 | + else | |
26 | + content_tag('i', _('This profile has no geographical position registered.')) | |
27 | + end | |
28 | + end | |
29 | + | |
30 | +end | ... | ... |
app/models/profile.rb
... | ... | @@ -151,12 +151,23 @@ class Profile < ActiveRecord::Base |
151 | 151 | |
152 | 152 | belongs_to :region |
153 | 153 | |
154 | - def location | |
154 | + def location(separator = ' - ') | |
155 | 155 | myregion = self.region |
156 | 156 | if myregion |
157 | - myregion.hierarchy.reverse.first(2).map(&:name).join(' - ') | |
157 | + myregion.hierarchy.reverse.first(2).map(&:name).join(separator) | |
158 | 158 | else |
159 | - [ :city, :state, :country_name ].map {|item| self.respond_to?(item) ? self.send(item) : nil }.compact.join(' - ') | |
159 | + %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) | |
160 | + end | |
161 | + end | |
162 | + | |
163 | + def geolocation | |
164 | + unless location.blank? | |
165 | + location | |
166 | + else | |
167 | + if environment.location.blank? | |
168 | + environment.location = "BRA" | |
169 | + end | |
170 | + environment.location | |
160 | 171 | end |
161 | 172 | end |
162 | 173 | ... | ... |
... | ... | @@ -0,0 +1,10 @@ |
1 | +<div> | |
2 | + <%= labelled_form_field _('Zoom Level:'), select(:block, :zoom, [[_('World'), 0], | |
3 | + 1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18, | |
4 | + [_('Street'), 19]]) %> | |
5 | + <%= labelled_form_field _('Map Type:'), select(:block, :map_type, [[_('Road Map') , 'roadmap' ], | |
6 | + [_('Mobile') , 'mobile' ], | |
7 | + [_('Satellite'), 'satellite'], | |
8 | + [_('Terrain') , 'terrain' ], | |
9 | + [_('Hybrid') , 'hybrid' ]]) %> | |
10 | +</div> | ... | ... |
... | ... | @@ -0,0 +1,136 @@ |
1 | +<%= content_tag('script', '', :src => GoogleMaps.api_url, :type => 'text/javascript') %> | |
2 | + | |
3 | +<script type="text/javascript" > | |
4 | + var geocoder; | |
5 | + var map; | |
6 | + var marker; | |
7 | + var center; | |
8 | + var move = true; | |
9 | + var previousCenter; | |
10 | + | |
11 | + function getAddress(overlay, latlng) { | |
12 | + $('location-fields').addClassName("loading"); | |
13 | + if (latlng != null) { | |
14 | + geocoder.getLocations(latlng, showAddress); | |
15 | + } | |
16 | + } | |
17 | + | |
18 | + function getAddressData() { | |
19 | + var text = ''; | |
20 | + var fields = [ | |
21 | + 'profile_data_country', | |
22 | + 'profile_data_state', | |
23 | + 'profile_data_city', | |
24 | + 'profile_data_address', | |
25 | + 'profile_data_zip_code' | |
26 | + ]; | |
27 | + for (var i = 0; i < fields.length; i++) { | |
28 | + var field = fields[i]; | |
29 | + if ($(field)) { | |
30 | + text += $(field).value + " "; | |
31 | + } | |
32 | + } | |
33 | + return text; | |
34 | + } | |
35 | + | |
36 | + function showAddress(response) { | |
37 | + var message; | |
38 | + place = geoCodeAddress(response); | |
39 | + if ( place ) { | |
40 | + if ( move ) { | |
41 | + center = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]); | |
42 | + marker.setLatLng(center); | |
43 | + } else { | |
44 | + move = true; | |
45 | + } | |
46 | + message = showMessage(place); | |
47 | + updateFields(place); | |
48 | + } else { | |
49 | + message = showNotFoundMessage(); | |
50 | + } | |
51 | + map.addOverlay(marker); | |
52 | + map.setCenter(marker.getLatLng()); | |
53 | + marker.openInfoWindowHtml(message, {maxWidth:300}); | |
54 | + } | |
55 | + | |
56 | + function geoCodeAddress(response) { | |
57 | + if (!response || (response && response.Status.code != '200')) { | |
58 | + return false; | |
59 | + } else { | |
60 | + place = response.Placemark[0]; | |
61 | + return place; | |
62 | + } | |
63 | + } | |
64 | + | |
65 | + function showMessage(place) { | |
66 | + var message = '<b><%= _('Address:') %></b> ' + place.address + '<br>' + | |
67 | + '<b><%= _('Coordinates:') %></b> ' + place.Point.coordinates[0] + "," + place.Point.coordinates[1] + '<br>' + | |
68 | + '<b><%= _('Country code:') %></b> ' + place.AddressDetails.Country.CountryNameCode + '<br>'; | |
69 | + return message; | |
70 | + } | |
71 | + | |
72 | + function showNotFoundMessage() { | |
73 | + var message = '<%= _('Address not found') %>' + '<br>' + | |
74 | + '<b><%= _('Coordinates:') %></b> ' + marker.getLatLng().lng() + "," + marker.getLatLng().lat(); | |
75 | + return message; | |
76 | + } | |
77 | + | |
78 | + function updateFields(response) { | |
79 | + var position = marker.getLatLng(); | |
80 | + $('profile_data_lat').value = position.lat(); | |
81 | + $('profile_data_lng').value = position.lng(); | |
82 | + $('location-fields').removeClassName("loading"); | |
83 | + } | |
84 | + | |
85 | + function loadMap() { | |
86 | + if (GBrowserIsCompatible()) { | |
87 | + map = new GMap2(document.getElementById("location-map")); | |
88 | + geocoder = new GClientGeocoder(); | |
89 | + var lat = <%= profile.lat || 'false' %>; | |
90 | + var lng = <%= profile.lng || 'false' %>; | |
91 | + if ( lat && lng ) { | |
92 | + center = new GLatLng( lat, lng ); | |
93 | + continueLoadMap(); | |
94 | + } else { | |
95 | + geocoder.getLocations('<%= profile.geolocation %>', loadAddress); | |
96 | + } | |
97 | + } | |
98 | + } | |
99 | + | |
100 | + function loadAddress(response) { | |
101 | + place = geoCodeAddress(response); | |
102 | + if ( move ) { | |
103 | + center = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]); | |
104 | + } | |
105 | + continueLoadMap(); | |
106 | + } | |
107 | + | |
108 | + function continueLoadMap() { | |
109 | + marker = new GMarker(center, {draggable: true}); | |
110 | + map.setCenter(center, 4); | |
111 | + | |
112 | + map.addControl(new GLargeMapControl()); | |
113 | + map.addControl(new GScaleControl()); | |
114 | + map.addControl(new GMapTypeControl()); | |
115 | + | |
116 | + GEvent.addListener(marker, "dragstart", function() { | |
117 | + previousCenter = marker.getLatLng(); | |
118 | + map.closeInfoWindow(); | |
119 | + }); | |
120 | + | |
121 | + GEvent.addListener(marker, "dragend", function() { | |
122 | + move = false; | |
123 | + getAddress(overlay, marker.getLatLng()); | |
124 | + }); | |
125 | + | |
126 | + GEvent.addListener(marker, "click", function() { | |
127 | + move = false; | |
128 | + getAddress(overlay, marker.getLatLng()); | |
129 | + }); | |
130 | + | |
131 | + map.addOverlay(marker); | |
132 | + } | |
133 | + | |
134 | + window.onload = loadMap; | |
135 | + window.unload = GUnload(); | |
136 | +</script> | ... | ... |
... | ... | @@ -0,0 +1,35 @@ |
1 | +<h1><%= _('Location') %></h1> | |
2 | + | |
3 | +<% form_for :profile_data, :url => {:action => 'edit_location'} do |f| %> | |
4 | + | |
5 | + <div id='location-fields'> | |
6 | + <%= optional_field(profile, 'country', select_country(_('Country'), 'profile_data', 'country', {:class => 'type-select'})) %> | |
7 | + <%= optional_field(profile, 'state', labelled_form_field(_('State'), f.text_field(:state))) %> | |
8 | + <%= optional_field(profile, 'city', labelled_form_field(_('City'), f.text_field(:city))) %> | |
9 | + <%= optional_field(profile, 'zip_code', labelled_form_field(_('ZIP code'), text_field(:profile_data, :zip_code))) %> | |
10 | + <%= optional_field(profile, 'address', labelled_form_field(_('Address (street and number)'), text_field(:profile_data, :address))) %> | |
11 | + <% button_bar do %> | |
12 | + <%= 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)") %> | |
13 | + <%= submit_button 'save', _('Save') %> | |
14 | + <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> | |
15 | + <% end %> | |
16 | + </div> | |
17 | + | |
18 | + | |
19 | + <div style='overflow: hidden'> | |
20 | + <p><div id="location-map"></div></p> | |
21 | + </div> | |
22 | + | |
23 | + <%= f.hidden_field(:lat) %> | |
24 | + <%= f.hidden_field(:lng) %> | |
25 | + | |
26 | + | |
27 | + | |
28 | + <% button_bar do %> | |
29 | + <%= submit_button 'save', _('Save') %> | |
30 | + <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> | |
31 | + <% end %> | |
32 | + | |
33 | +<% end %> | |
34 | + | |
35 | +<%= render :partial => 'google_map'%> | ... | ... |
app/views/profile_editor/index.rhtml
... | ... | @@ -14,6 +14,8 @@ |
14 | 14 | <%= control_panel_button(__('Community Info and settings'), 'edit-profile-group', :controller => 'profile_editor', :action => 'edit') if profile.community? %> |
15 | 15 | <%= control_panel_button(__('Enterprise Info and settings'), 'edit-profile-enterprise', :controller => 'profile_editor', :action => 'edit') if profile.enterprise? %> |
16 | 16 | |
17 | + <%= control_panel_button(_('Location'), 'edit-location', :controller => 'maps', :action => 'edit_location') %> | |
18 | + | |
17 | 19 | <%= control_panel_button(_('Mail settings'), 'mail', :controller => 'mailconf') if profile.person? && MailConf.enabled? %> |
18 | 20 | |
19 | 21 | <%= control_panel_button(_('Tasks'), 'todo', :controller => 'tasks', :action => 'index') %> | ... | ... |
... | ... | @@ -0,0 +1,9 @@ |
1 | +class RenameLocationBlock < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + execute "update blocks set type='LocationBlock' where type='LocalizationBlock'" | |
4 | + end | |
5 | + | |
6 | + def self.down | |
7 | + execute "update blocks set type='LocalizationBlock' where type='LocationBlock'" | |
8 | + end | |
9 | +end | ... | ... |
db/schema.rb
... | ... | @@ -9,7 +9,7 @@ |
9 | 9 | # |
10 | 10 | # It's strongly recommended to check this file into your version control system. |
11 | 11 | |
12 | -ActiveRecord::Schema.define(:version => 76) do | |
12 | +ActiveRecord::Schema.define(:version => 77) do | |
13 | 13 | |
14 | 14 | create_table "article_versions", :force => true do |t| |
15 | 15 | t.integer "article_id" |
... | ... | @@ -88,8 +88,8 @@ ActiveRecord::Schema.define(:version => 76) do |
88 | 88 | t.boolean "virtual", :default => false |
89 | 89 | end |
90 | 90 | |
91 | - add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id" | |
92 | 91 | add_index "articles_categories", ["category_id"], :name => "index_articles_categories_on_category_id" |
92 | + add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id" | |
93 | 93 | |
94 | 94 | create_table "blocks", :force => true do |t| |
95 | 95 | t.string "title" |
... | ... | @@ -103,10 +103,10 @@ ActiveRecord::Schema.define(:version => 76) do |
103 | 103 | t.datetime "fetched_at" |
104 | 104 | end |
105 | 105 | |
106 | - add_index "blocks", ["box_id"], :name => "index_blocks_on_box_id" | |
107 | - add_index "blocks", ["enabled"], :name => "index_blocks_on_enabled" | |
108 | - add_index "blocks", ["fetched_at"], :name => "index_blocks_on_fetched_at" | |
109 | 106 | add_index "blocks", ["type"], :name => "index_blocks_on_type" |
107 | + add_index "blocks", ["fetched_at"], :name => "index_blocks_on_fetched_at" | |
108 | + add_index "blocks", ["enabled"], :name => "index_blocks_on_enabled" | |
109 | + add_index "blocks", ["box_id"], :name => "index_blocks_on_box_id" | |
110 | 110 | |
111 | 111 | create_table "boxes", :force => true do |t| |
112 | 112 | t.string "owner_type" |
... | ... | @@ -136,8 +136,8 @@ ActiveRecord::Schema.define(:version => 76) do |
136 | 136 | t.boolean "virtual", :default => false |
137 | 137 | end |
138 | 138 | |
139 | - add_index "categories_profiles", ["category_id"], :name => "index_categories_profiles_on_category_id" | |
140 | 139 | add_index "categories_profiles", ["profile_id"], :name => "index_categories_profiles_on_profile_id" |
140 | + add_index "categories_profiles", ["category_id"], :name => "index_categories_profiles_on_category_id" | |
141 | 141 | |
142 | 142 | create_table "comments", :force => true do |t| |
143 | 143 | t.string "title" |
... | ... | @@ -189,8 +189,8 @@ ActiveRecord::Schema.define(:version => 76) do |
189 | 189 | t.integer "update_errors", :default => 0 |
190 | 190 | end |
191 | 191 | |
192 | - add_index "external_feeds", ["enabled"], :name => "index_external_feeds_on_enabled" | |
193 | 192 | add_index "external_feeds", ["fetched_at"], :name => "index_external_feeds_on_fetched_at" |
193 | + add_index "external_feeds", ["enabled"], :name => "index_external_feeds_on_enabled" | |
194 | 194 | |
195 | 195 | create_table "favorite_enteprises_people", :id => false, :force => true do |t| |
196 | 196 | t.integer "person_id" |
... | ... | @@ -224,8 +224,8 @@ ActiveRecord::Schema.define(:version => 76) do |
224 | 224 | t.datetime "updated_at" |
225 | 225 | end |
226 | 226 | |
227 | - add_index "product_categorizations", ["category_id"], :name => "index_product_categorizations_on_category_id" | |
228 | 227 | add_index "product_categorizations", ["product_id"], :name => "index_product_categorizations_on_product_id" |
228 | + add_index "product_categorizations", ["category_id"], :name => "index_product_categorizations_on_category_id" | |
229 | 229 | |
230 | 230 | create_table "products", :force => true do |t| |
231 | 231 | t.integer "enterprise_id" |
... | ... | @@ -305,8 +305,8 @@ ActiveRecord::Schema.define(:version => 76) do |
305 | 305 | t.datetime "created_at" |
306 | 306 | end |
307 | 307 | |
308 | - add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" | |
309 | 308 | add_index "taggings", ["taggable_id", "taggable_type"], :name => "index_taggings_on_taggable_id_and_taggable_type" |
309 | + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" | |
310 | 310 | |
311 | 311 | create_table "tags", :force => true do |t| |
312 | 312 | t.string "name" | ... | ... |
... | ... | @@ -0,0 +1,57 @@ |
1 | +Feature: Location | |
2 | + As a user | |
3 | + I want to edit my address and location | |
4 | + So that others can find me in the map | |
5 | + | |
6 | + Background: | |
7 | + And the following users | |
8 | + | login | | |
9 | + | zezinho | | |
10 | + And I am logged in as "zezinho" | |
11 | + | |
12 | + Scenario: editing my address | |
13 | + Given the following Person fields are enabled | |
14 | + | address | | |
15 | + | country | | |
16 | + | state | | |
17 | + | city | | |
18 | + | zip_code | | |
19 | + And I follow "Control panel" | |
20 | + And I follow "Location" | |
21 | + When I fill in "Address" with "Rua Marechal Floriano, 28" | |
22 | + And I select "Brazil" from "Country" | |
23 | + And I fill in "State" with "Bahia" | |
24 | + And I fill in "City" with "Salvador" | |
25 | + And I fill in "ZIP Code" with "40110010" | |
26 | + And I press "Save" | |
27 | + Then "zezinho" should have the following data | |
28 | + | address | country | state | city | zip_code | | |
29 | + | Rua Marechal Floriano, 28 | BR | Bahia | Salvador | 40110010 | | |
30 | + | |
31 | + Scenario Outline: editing address of collectives | |
32 | + Given the following <class> fields are enabled | |
33 | + | address | | |
34 | + | country | | |
35 | + | state | | |
36 | + | city | | |
37 | + | zip_code | | |
38 | + Given the following <plural> | |
39 | + | identifier | name | owner | | |
40 | + | colivre | Colivre | zezinho | | |
41 | + And I am on Colivre's control panel | |
42 | + And I follow "Location" | |
43 | + And I select "Brazil" from "Country" | |
44 | + And I fill in the following: | |
45 | + | Address | Rua Marechal Floriano, 28 | | |
46 | + | State | Bahia | | |
47 | + | City | Salvador | | |
48 | + | ZIP Code | 40110010 | | |
49 | + When I press "Save" | |
50 | + Then "colivre" should have the following data | |
51 | + | address | country | state | city | zip_code | | |
52 | + | Rua Marechal Floriano, 28 | BR | Bahia | Salvador | 40110010 | | |
53 | + Examples: | |
54 | + | class | plural | | |
55 | + | Community | communities | | |
56 | + | Enterprise | enterprises | | |
57 | + | ... | ... |
features/step_definitions/custom_webrat_steps.rb
features/step_definitions/noosfero_steps.rb
... | ... | @@ -7,15 +7,14 @@ Given /^the following users$/ do |table| |
7 | 7 | end |
8 | 8 | end |
9 | 9 | |
10 | -Given /^the following communities$/ do |table| | |
11 | - table.hashes.each do |item| | |
12 | - Community.create!(item) | |
13 | - end | |
14 | -end | |
15 | - | |
16 | -Given /^the following enterprises$/ do |table| | |
17 | - table.hashes.each do |item| | |
18 | - Enterprise.create!(item) | |
10 | +Given /^the following (communities|enterprises)$/ do |kind,table| | |
11 | + klass = kind.singularize.camelize.constantize | |
12 | + table.hashes.each do |row| | |
13 | + owner = row.delete("owner") | |
14 | + community = klass.create!(row) | |
15 | + if owner | |
16 | + community.add_admin(Profile[owner]) | |
17 | + end | |
19 | 18 | end |
20 | 19 | end |
21 | 20 | |
... | ... | @@ -111,3 +110,24 @@ end |
111 | 110 | Given /^"([^\"]*)" has no articles$/ do |profile| |
112 | 111 | (Profile[profile] || Profile.find_by_name(profile)).articles.delete_all |
113 | 112 | end |
113 | + | |
114 | +Given /^the following (\w+) fields are enabled$/ do |klass, table| | |
115 | + env = Environment.default | |
116 | + fields = table.raw.inject({}) do |hash, line| | |
117 | + hash[line.first] = { "active" => 'true' } | |
118 | + hash | |
119 | + end | |
120 | + | |
121 | + env.send("custom_#{klass.downcase}_fields=", fields) | |
122 | + env.save! | |
123 | + if fields.keys != env.send("active_#{klass.downcase}_fields") | |
124 | + raise "Not all fields enabled! Requested: %s; Enabled: %s" % [fields.keys.inspect, env.send("active_#{klass.downcase}_fields").inspect] | |
125 | + end | |
126 | +end | |
127 | + | |
128 | +Then /^"([^\"]*)" should have the following data$/ do |id, table| | |
129 | + profile = Profile.find_by_identifier(id) | |
130 | + expected = table.hashes.first | |
131 | + data = expected.keys.inject({}) { |hash, key| hash[key] = profile.send(key).to_s; hash } | |
132 | + data.should == expected | |
133 | +end | ... | ... |
public/stylesheets/blocks/localization-block.css
public/stylesheets/common.css
public/stylesheets/controller_profile_editor.css
... | ... | @@ -88,3 +88,5 @@ a.control-panel-validation {background-image: url(../images/control-panel/applic |
88 | 88 | a.control-panel-mail {background-image: url(../images/control-panel/email.png)} |
89 | 89 | .msie6 a.control-panel-mail {background-image: url(../images/control-panel/email.gif)} |
90 | 90 | |
91 | +a.control-panel-edit-location {background-image: url(../images/control-panel/set-geolocation.png)} | |
92 | +.msie6 a.control-panel-edit-location {background-image: url(../images/control-panel/set-geolocation.gif)} | ... | ... |
... | ... | @@ -0,0 +1,43 @@ |
1 | +require File.dirname(__FILE__) + '/../test_helper' | |
2 | +require 'maps_controller' | |
3 | + | |
4 | +# Re-raise errors caught by the controller. | |
5 | +class MapsController; def rescue_action(e) raise e end; end | |
6 | + | |
7 | +class MapsControllerTest < Test::Unit::TestCase | |
8 | + | |
9 | + def setup | |
10 | + @controller = MapsController.new | |
11 | + @request = ActionController::TestRequest.new | |
12 | + @response = ActionController::TestResponse.new | |
13 | + | |
14 | + @profile = create_user('test_profile').person | |
15 | + login_as(@profile.identifier) | |
16 | + end | |
17 | + | |
18 | + attr_reader :profile | |
19 | + | |
20 | + should 'save profile address' do | |
21 | + post :edit_location, :profile => profile.identifier, :profile_data => { 'address' => 'new address' } | |
22 | + assert_equal 'new address', Profile['test_profile'].address | |
23 | + end | |
24 | + | |
25 | + should 'back when update address fail' do | |
26 | + Profile.any_instance.stubs(:update_attributes!).returns(false) | |
27 | + post :edit_location, :profile => profile.identifier, :profile_data => { 'address' => 'new address' } | |
28 | + assert_nil profile.address | |
29 | + assert_template 'edit_location' | |
30 | + end | |
31 | + | |
32 | + should 'show page to edit location' do | |
33 | + get :edit_location, :profile => profile.identifier | |
34 | + assert_response :success | |
35 | + assert_template 'edit_location' | |
36 | + end | |
37 | + | |
38 | + should 'dispĺay form for address with profile address' do | |
39 | + get :edit_location, :profile => profile.identifier | |
40 | + assert_tag :tag => 'input', :attributes => { :name => 'location' } | |
41 | + end | |
42 | + | |
43 | +end | ... | ... |
test/unit/profile_test.rb
... | ... | @@ -698,15 +698,60 @@ class ProfileTest < Test::Unit::TestCase |
698 | 698 | assert_equal 'Salvador - Bahia', p.location |
699 | 699 | end |
700 | 700 | |
701 | - should 'use city/state/country fields for location when no region object is set' do | |
701 | + should 'use city/state/country/address/zip_code fields for location when no region object is set' do | |
702 | 702 | p = Profile.new |
703 | 703 | p.expects(:region).returns(nil) |
704 | - p.expects(:city).returns("Salvador") | |
705 | - p.expects(:state).returns("Bahia") | |
706 | - p.expects(:country_name).returns("Brasil") | |
707 | - assert_equal 'Salvador - Bahia - Brasil', p.location | |
704 | + p.expects(:address).returns("Rua A").at_least_once | |
705 | + p.expects(:city).returns("Salvador").at_least_once | |
706 | + p.expects(:state).returns("Bahia").at_least_once | |
707 | + p.expects(:country_name).returns("Brasil").at_least_once | |
708 | + p.expects(:zip_code).returns("40000000").at_least_once | |
709 | + assert_equal 'Rua A - Salvador - Bahia - Brasil - 40000000', p.location | |
708 | 710 | end |
709 | 711 | |
712 | + should 'choose separator for location' do | |
713 | + p = Profile.new | |
714 | + p.expects(:region).returns(nil) | |
715 | + p.expects(:address).returns("Rua A").at_least_once | |
716 | + p.expects(:city).returns("Salvador").at_least_once | |
717 | + p.expects(:state).returns("Bahia").at_least_once | |
718 | + p.expects(:country_name).returns("Brasil").at_least_once | |
719 | + p.expects(:zip_code).returns("40000000").at_least_once | |
720 | + assert_equal 'Rua A, Salvador, Bahia, Brasil, 40000000', p.location(', ') | |
721 | + end | |
722 | + | |
723 | + should 'not display separator on location if city/state/country/address/zip_code is blank' do | |
724 | + p = Profile.new | |
725 | + p.expects(:region).returns(nil) | |
726 | + p.expects(:address).returns("Rua A").at_least_once | |
727 | + p.expects(:city).returns("Salvador").at_least_once | |
728 | + p.expects(:state).returns("").at_least_once | |
729 | + p.expects(:country_name).returns("Brasil").at_least_once | |
730 | + p.expects(:zip_code).returns("40000000").at_least_once | |
731 | + assert_equal 'Rua A - Salvador - Brasil - 40000000', p.location | |
732 | + end | |
733 | + | |
734 | + should 'use location on geolocation if not blank' do | |
735 | + p = Profile.new | |
736 | + p.expects(:region).returns(nil).at_least_once | |
737 | + p.expects(:address).returns("Rua A").at_least_once | |
738 | + p.expects(:city).returns("Salvador").at_least_once | |
739 | + p.expects(:state).returns("").at_least_once | |
740 | + p.expects(:country_name).returns("Brasil").at_least_once | |
741 | + p.expects(:zip_code).returns("40000000").at_least_once | |
742 | + assert_equal 'Rua A - Salvador - Brasil - 40000000', p.geolocation | |
743 | + end | |
744 | + | |
745 | + should 'use default location on geolocation if not blank' do | |
746 | + p = Profile.new | |
747 | + p.expects(:region).returns(nil) | |
748 | + e = Environment.default | |
749 | + p.expects(:environment).returns(e) | |
750 | + e.expects(:location).returns('Brasil') | |
751 | + assert_equal 'Brasil', p.geolocation | |
752 | + end | |
753 | + | |
754 | + | |
710 | 755 | should 'lookup country name' do |
711 | 756 | p = Profile.new |
712 | 757 | # two sample countries; trust the rest works | ... | ... |