Commit 68934890fe022493063c10ab0b2cab46b6703b46
Committed by
Antonio Terceiro
1 parent
4a8583d3
Exists in
master
and in
29 other branches
ActionItem1126: organization can change address
Showing
12 changed files
with
130 additions
and
20 deletions
Show diff stats
app/controllers/my_profile/profile_editor_controller.rb
@@ -17,7 +17,7 @@ class ProfileEditorController < MyProfileController | @@ -17,7 +17,7 @@ class ProfileEditorController < MyProfileController | ||
17 | Profile.transaction do | 17 | Profile.transaction do |
18 | Image.transaction do | 18 | Image.transaction do |
19 | if profile.update_attributes!(params[:profile_data]) | 19 | if profile.update_attributes!(params[:profile_data]) |
20 | - redirect_to :action => 'index' | 20 | + redirect_to :action => 'index', :profile => profile.identifier |
21 | end | 21 | end |
22 | end | 22 | end |
23 | end | 23 | end |
app/models/environment.rb
@@ -127,6 +127,7 @@ class Environment < ActiveRecord::Base | @@ -127,6 +127,7 @@ class Environment < ActiveRecord::Base | ||
127 | 'display_header_footer_explanation' => N_("Display explanation about header and footer"), | 127 | 'display_header_footer_explanation' => N_("Display explanation about header and footer"), |
128 | 'articles_dont_accept_comments_by_default' => N_("Articles don't accept comments by default"), | 128 | 'articles_dont_accept_comments_by_default' => N_("Articles don't accept comments by default"), |
129 | 'organizations_are_moderated_by_default' => N_("Organizations have moderated publication by default"), | 129 | 'organizations_are_moderated_by_default' => N_("Organizations have moderated publication by default"), |
130 | + 'enable_organization_url_change' => N_("Enable organizations to change its address"), | ||
130 | } | 131 | } |
131 | end | 132 | end |
132 | 133 |
app/models/person.rb
@@ -12,6 +12,15 @@ class Person < Profile | @@ -12,6 +12,15 @@ class Person < Profile | ||
12 | Friendship.find(:all, :conditions => { :friend_id => person.id}).each { |friendship| friendship.destroy } | 12 | Friendship.find(:all, :conditions => { :friend_id => person.id}).each { |friendship| friendship.destroy } |
13 | end | 13 | end |
14 | 14 | ||
15 | + # Sets the identifier for this person. Raises an exception when called on a | ||
16 | + # existing person (since peoples' identifiers cannot be changed) | ||
17 | + def identifier=(value) | ||
18 | + unless self.new_record? | ||
19 | + raise ArgumentError.new(_('An existing person cannot be renamed.')) | ||
20 | + end | ||
21 | + self[:identifier] = value | ||
22 | + end | ||
23 | + | ||
15 | settings_items :last_lang, :type => :string | 24 | settings_items :last_lang, :type => :string |
16 | def last_lang | 25 | def last_lang |
17 | if self.data[:last_lang].nil? or self.data[:last_lang].empty? | 26 | if self.data[:last_lang].nil? or self.data[:last_lang].empty? |
app/models/profile.rb
@@ -194,15 +194,6 @@ class Profile < ActiveRecord::Base | @@ -194,15 +194,6 @@ class Profile < ActiveRecord::Base | ||
194 | end | 194 | end |
195 | @top_level_articles ||= Article.top_level_for(self) | 195 | @top_level_articles ||= Article.top_level_for(self) |
196 | end | 196 | end |
197 | - | ||
198 | - # Sets the identifier for this profile. Raises an exception when called on a | ||
199 | - # existing profile (since profiles cannot be renamed) | ||
200 | - def identifier=(value) | ||
201 | - unless self.new_record? | ||
202 | - raise ArgumentError.new(_('An existing profile cannot be renamed.')) | ||
203 | - end | ||
204 | - self[:identifier] = value | ||
205 | - end | ||
206 | 197 | ||
207 | def self.is_available?(identifier) | 198 | def self.is_available?(identifier) |
208 | !(identifier =~ IDENTIFIER_FORMAT).nil? && !RESERVED_IDENTIFIERS.include?(identifier) && Profile.find(:first, :conditions => ['environment_id = ? and identifier = ?', Environment.default.id, identifier]).nil? | 199 | !(identifier =~ IDENTIFIER_FORMAT).nil? && !RESERVED_IDENTIFIERS.include?(identifier) && Profile.find(:first, :conditions => ['environment_id = ? and identifier = ?', Environment.default.id, identifier]).nil? |
app/views/profile_editor/_organization.rhtml
@@ -2,14 +2,59 @@ | @@ -2,14 +2,59 @@ | ||
2 | 2 | ||
3 | <%= required_fields_message if @profile.required_fields.any? %> | 3 | <%= required_fields_message if @profile.required_fields.any? %> |
4 | 4 | ||
5 | +<% if @environment.enabled?('enable_organization_url_change') %> | ||
6 | + <script type="text/javascript"> | ||
7 | + function updateUrlField(name_field, id) { | ||
8 | + url_field = $(id); | ||
9 | + url_field.value = convToValidIdentifier(name_field.value, "-"); | ||
10 | + warn_value_change(url_field); | ||
11 | + } | ||
12 | + </script> | ||
13 | +<% end %> | ||
14 | + | ||
5 | <div class="formfieldline"> | 15 | <div class="formfieldline"> |
6 | <label class="formlabel" for="profile_data_nickname"><%= _('Display name') %></label> | 16 | <label class="formlabel" for="profile_data_nickname"><%= _('Display name') %></label> |
7 | <div class="formfield type-text"> | 17 | <div class="formfield type-text"> |
8 | - <%= text_field_tag 'profile_data[nickname]', @profile_data.nickname, :id => 'profile_data_nickname', :size => 30, :maxlength => 16 %> | 18 | + <%= text_field_tag 'profile_data[nickname]', @profile_data.nickname, :id => 'profile_data_nickname', :size => 30, :maxlength => 16, :onchange => (@environment.enabled?('enable_organization_url_change') ? "updateUrlField(this, 'profile_data_identifier')" : "") %> |
9 | <em><%= _('A short name by which the organization is know.')%></em> | 19 | <em><%= _('A short name by which the organization is know.')%></em> |
20 | + </div> | ||
10 | </div> | 21 | </div> |
11 | 22 | ||
12 | - </div> | 23 | +<% if @environment.enabled?('enable_organization_url_change') %> |
24 | + <script type="text/javascript"> | ||
25 | + function submit_button() { | ||
26 | + return $("profile_data_identifier").form.select("input.submit")[0]; | ||
27 | + } | ||
28 | + | ||
29 | + function warn_value_change(field) { | ||
30 | + new Effect.Highlight($("profile-identifier-formitem"), {duration:3}); | ||
31 | + $("identifier-change-confirmation").show(); | ||
32 | + submit_button().disable(); | ||
33 | + submit_button().addClassName("disabled"); | ||
34 | + } | ||
35 | + | ||
36 | + function hide_warning() { | ||
37 | + submit_button().enable(); | ||
38 | + submit_button().removeClassName("disabled"); | ||
39 | + $("identifier-change-confirmation").hide() | ||
40 | + } | ||
41 | + </script> | ||
42 | + | ||
43 | + <%= hidden_field_tag 'old_profile_identifier', @profile.identifier %> | ||
44 | + <div id="profile-identifier-formitem"> | ||
45 | + <%= labelled_form_field( _('Address'), | ||
46 | + '<code>' + url_for(profile.url).gsub(/#{profile.identifier}$/, '') + | ||
47 | + text_field(:profile_data, :identifier, :onchange => "warn_value_change(this)", :size => 15) + '</code>' + | ||
48 | + content_tag('div', '<strong>' + _('WARNING:') + '</strong> ' + _("the address was changed, this might break any external links to this profile and articles in this profile, you really want to change? ") + | ||
49 | + '<div>' + button_to_function(:ok, _("Yes"), 'hide_warning()') + ' ' + | ||
50 | + button_to_function(:cancel, _('No'), '$("profile_data_identifier").value = $("old_profile_identifier").value; hide_warning()') + '</div>', | ||
51 | + :id => 'identifier-change-confirmation' | ||
52 | + ) | ||
53 | + ) | ||
54 | + %> | ||
55 | + </div> | ||
56 | +<% end %> | ||
57 | + | ||
13 | <%= f.text_field(:acronym) %> | 58 | <%= f.text_field(:acronym) %> |
14 | <%= f.text_field(:foundation_year) %> | 59 | <%= f.text_field(:foundation_year) %> |
15 | <%= optional_field(@profile, 'contact_person', f.text_field(:contact_person)) %> | 60 | <%= optional_field(@profile, 'contact_person', f.text_field(:contact_person)) %> |
public/javascripts/application.js
@@ -29,6 +29,11 @@ function focus_first_field() { | @@ -29,6 +29,11 @@ function focus_first_field() { | ||
29 | 29 | ||
30 | /* * * Convert a string to a valid login name * * */ | 30 | /* * * Convert a string to a valid login name * * */ |
31 | function convToValidLogin( str ) { | 31 | function convToValidLogin( str ) { |
32 | + return convToValidIdentifier(str, '') | ||
33 | +} | ||
34 | + | ||
35 | +/* * * Convert a string to a valid login name * * */ | ||
36 | +function convToValidIdentifier( str, sep ) { | ||
32 | return str.toLowerCase() | 37 | return str.toLowerCase() |
33 | .replace( /@.*$/, "" ) | 38 | .replace( /@.*$/, "" ) |
34 | .replace( /á|à|ã|â/g, "a" ) | 39 | .replace( /á|à|ã|â/g, "a" ) |
@@ -38,7 +43,7 @@ function convToValidLogin( str ) { | @@ -38,7 +43,7 @@ function convToValidLogin( str ) { | ||
38 | .replace( /ú|ũ|ü/g, "u" ) | 43 | .replace( /ú|ũ|ü/g, "u" ) |
39 | .replace( /ñ/g, "n" ) | 44 | .replace( /ñ/g, "n" ) |
40 | .replace( /ç/g, "c" ) | 45 | .replace( /ç/g, "c" ) |
41 | - .replace( /[^-_a-z0-9]+/g, "" ) | 46 | + .replace( /[^-_a-z0-9]+/g, sep ) |
42 | } | 47 | } |
43 | 48 | ||
44 | document.observe("dom:loaded", function() { | 49 | document.observe("dom:loaded", function() { |
public/stylesheets/button.css
public/stylesheets/controller_profile_editor.css
@@ -31,6 +31,21 @@ | @@ -31,6 +31,21 @@ | ||
31 | -moz-border-radius: 3px; | 31 | -moz-border-radius: 3px; |
32 | } | 32 | } |
33 | 33 | ||
34 | +#identifier-change-confirmation { | ||
35 | + background-color: #EE4444; | ||
36 | + padding: 3px 20px 3px 20px; | ||
37 | + margin: 5px 30px 10px 30px; | ||
38 | +} | ||
39 | + | ||
40 | +#identifier-change-confirmation div { | ||
41 | + text-align: right; | ||
42 | + padding: 0px 10px 5px 0px; | ||
43 | +} | ||
44 | + | ||
45 | +code input { | ||
46 | + font-family: monospace; | ||
47 | +} | ||
48 | + | ||
34 | a.control-panel-groups { background-image: url(../images/control-panel/system-users.png) } | 49 | a.control-panel-groups { background-image: url(../images/control-panel/system-users.png) } |
35 | .msie6 a.control-panel-groups { background-image: url(../images/control-panel/system-users.gif) } | 50 | .msie6 a.control-panel-groups { background-image: url(../images/control-panel/system-users.gif) } |
36 | 51 | ||
@@ -87,3 +102,4 @@ a.control-panel-validation {background-image: url(../images/control-panel/applic | @@ -87,3 +102,4 @@ a.control-panel-validation {background-image: url(../images/control-panel/applic | ||
87 | 102 | ||
88 | a.control-panel-mail {background-image: url(../images/control-panel/email.png)} | 103 | a.control-panel-mail {background-image: url(../images/control-panel/email.png)} |
89 | .msie6 a.control-panel-mail {background-image: url(../images/control-panel/email.gif)} | 104 | .msie6 a.control-panel-mail {background-image: url(../images/control-panel/email.gif)} |
105 | + |
test/functional/profile_editor_controller_test.rb
@@ -724,5 +724,37 @@ class ProfileEditorControllerTest < Test::Unit::TestCase | @@ -724,5 +724,37 @@ class ProfileEditorControllerTest < Test::Unit::TestCase | ||
724 | assert_no_tag :tag => 'div', :attributes => { :id => 'activation_enterprise' }, :descendant => {:tag => 'form', :attributes => {:action => '/account/activation_question'}} | 724 | assert_no_tag :tag => 'div', :attributes => { :id => 'activation_enterprise' }, :descendant => {:tag => 'form', :attributes => {:action => '/account/activation_question'}} |
725 | end | 725 | end |
726 | 726 | ||
727 | + should 'have url field for identifier when environment allows' do | ||
728 | + c = Community.create!(:name => 'test community', :identifier => 'test_comm') | ||
729 | + env = c.environment | ||
730 | + env.enable('enable_organization_url_change') | ||
731 | + env.save! | ||
732 | + | ||
733 | + get :edit, :profile => c.identifier | ||
734 | + assert_tag :tag => 'div', | ||
735 | + :attributes => { :class => 'formfield type-text' }, | ||
736 | + :content => /https?:\/\/#{c.environment.default_hostname}\//, | ||
737 | + :descendant => {:tag => 'input', :attributes => {:id => 'profile_data_identifier'} } | ||
738 | + end | ||
739 | + | ||
740 | + should 'not have url field for identifier when environment not allows' do | ||
741 | + c = Community.create!(:name => 'test community', :identifier => 'test_comm') | ||
742 | + env = c.environment | ||
743 | + env.disable('enable_organization_url_change') | ||
744 | + env.save! | ||
745 | + | ||
746 | + get :edit, :profile => c.identifier | ||
747 | + assert_no_tag :tag => 'div', | ||
748 | + :attributes => { :class => 'formfield type-text' }, | ||
749 | + :content => /https?:\/\/#{c.environment.default_hostname}\//, | ||
750 | + :descendant => {:tag => 'input', :attributes => {:id => 'profile_data_identifier'} } | ||
751 | + end | ||
752 | + | ||
753 | + should 'redirect to new url when is changed' do | ||
754 | + c = Community.create!(:name => 'test community', :identifier => 'test_comm') | ||
755 | + post :edit, :profile => c.identifier, :profile_data => {:identifier => 'new_address'} | ||
756 | + assert_response :redirect | ||
757 | + assert_redirected_to :action => 'index', :profile => 'new_address' | ||
758 | + end | ||
727 | 759 | ||
728 | end | 760 | end |
test/unit/organization_test.rb
@@ -232,4 +232,11 @@ class OrganizationTest < Test::Unit::TestCase | @@ -232,4 +232,11 @@ class OrganizationTest < Test::Unit::TestCase | ||
232 | assert p.has_permission?(:moderate_comments, o) | 232 | assert p.has_permission?(:moderate_comments, o) |
233 | end | 233 | end |
234 | 234 | ||
235 | + should 'be able to change identifier' do | ||
236 | + o = Organization.create!(:name => 'Test Org', :identifier => 'test_org') | ||
237 | + assert_nothing_raised do | ||
238 | + o.identifier = 'test_org_new_url' | ||
239 | + end | ||
240 | + end | ||
241 | + | ||
235 | end | 242 | end |
test/unit/person_test.rb
@@ -574,4 +574,11 @@ class PersonTest < Test::Unit::TestCase | @@ -574,4 +574,11 @@ class PersonTest < Test::Unit::TestCase | ||
574 | end | 574 | end |
575 | end | 575 | end |
576 | 576 | ||
577 | + should 'not rename' do | ||
578 | + assert_valid p = create_user('test_user').person | ||
579 | + assert_raise ArgumentError do | ||
580 | + p.identifier = 'other_person_name' | ||
581 | + end | ||
582 | + end | ||
583 | + | ||
577 | end | 584 | end |
test/unit/profile_test.rb
@@ -72,13 +72,6 @@ class ProfileTest < Test::Unit::TestCase | @@ -72,13 +72,6 @@ class ProfileTest < Test::Unit::TestCase | ||
72 | assert_equal Environment.default, e | 72 | assert_equal Environment.default, e |
73 | end | 73 | end |
74 | 74 | ||
75 | - def test_cannot_rename | ||
76 | - assert_valid p = Profile.create(:name => 'new_profile', :identifier => 'new_profile') | ||
77 | - assert_raise ArgumentError do | ||
78 | - p.identifier = 'other_profile' | ||
79 | - end | ||
80 | - end | ||
81 | - | ||
82 | should 'provide access to home page' do | 75 | should 'provide access to home page' do |
83 | profile = Profile.create!(:identifier => 'newprofile', :name => 'New Profile') | 76 | profile = Profile.create!(:identifier => 'newprofile', :name => 'New Profile') |
84 | assert_kind_of Article, profile.home_page | 77 | assert_kind_of Article, profile.home_page |