Commit a2f9612de8f01df1ad464a93d212ef4043c4ed73

Authored by Daniela Feitosa
Committed by Antonio Terceiro
1 parent 90844dbf

Allowing users to delete profile

Users can delete own profiles
Organization admins can delete organizations
Environment admins also can remove others profiles

(ActionItem1716)
app/controllers/my_profile/memberships_controller.rb
... ... @@ -24,15 +24,4 @@ class MembershipsController < MyProfileController
24 24 render :layout => 'wizard'
25 25 end
26 26 end
27   -
28   - def destroy_community
29   - @community = Community.find(params[:id])
30   - if request.post?
31   - if @community.destroy
32   - session[:notice] = _('%s was removed.') % @community.short_name
33   - redirect_to :action => 'index'
34   - end
35   - end
36   - end
37   -
38 27 end
... ...
app/controllers/my_profile/profile_editor_controller.rb
1 1 class ProfileEditorController < MyProfileController
2 2  
3   - protect 'edit_profile', :profile
  3 + protect 'edit_profile', :profile, :except => [:destroy_profile]
  4 + protect 'destroy_profile', :profile, :only => [:destroy_profile]
4 5  
5 6 def index
6 7 @pending_tasks = profile.all_pending_tasks.select{|i| user.has_permission?(i.permission, profile)}
... ... @@ -72,4 +73,14 @@ class ProfileEditorController &lt; MyProfileController
72 73 end
73 74 end
74 75  
  76 + def destroy_profile
  77 + if request.post?
  78 + if @profile.destroy
  79 + session[:notice] = _('The profile was deleted.')
  80 + redirect_to :controller => 'home'
  81 + else
  82 + session[:notice] = _('Could not delete profile')
  83 + end
  84 + end
  85 + end
75 86 end
... ...
app/models/person.rb
... ... @@ -19,7 +19,7 @@ class Person &lt; Profile
19 19  
20 20 has_many :mailings
21 21  
22   - has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id
  22 + has_many :scraps_sent, :class_name => 'Scrap', :foreign_key => :sender_id, :dependent => :destroy
23 23  
24 24 named_scope :more_popular,
25 25 :select => "#{Profile.qualified_column_names}, count(friend_id) as total",
... ...
app/models/profile.rb
... ... @@ -91,7 +91,7 @@ class Profile &lt; ActiveRecord::Base
91 91  
92 92 has_many :action_tracker_notifications, :foreign_key => 'profile_id'
93 93 has_many :tracked_notifications, :through => :action_tracker_notifications, :source => :action_tracker, :order => 'updated_at DESC'
94   - has_many :scraps_received, :class_name => 'Scrap', :foreign_key => :receiver_id, :order => "updated_at DESC"
  94 + has_many :scraps_received, :class_name => 'Scrap', :foreign_key => :receiver_id, :order => "updated_at DESC", :dependent => :destroy
95 95  
96 96 # FIXME ugly workaround
97 97 def self.human_attribute_name(attrib)
... ...
app/views/memberships/destroy_community.rhtml
... ... @@ -1,9 +0,0 @@
1   -<h1><%= _('To remove %s') % @community.short_name %></h1>
2   -
3   -<p><strong><%= _('Are you sure you want to <u>remove</u> "%s"?') % content_tag( 'i', @community.name ) %></strong></p>
4   -
5   -<% form_tag do %>
6   - <%= hidden_field_tag(:confirmation, 1) %>
7   - <%= submit_button(:ok, _("Yes, I want to remove.") % @community.short_name) %>
8   - <%= button(:cancel, _("No, I don't want."), :action => 'index') %>
9   -<% end %>
app/views/memberships/index.rhtml
... ... @@ -25,7 +25,7 @@
25 25 <%= button 'menu-ctrl-panel', _('Control panel of this group'), membership.admin_url %>
26 26 <%= lightbox_button 'menu-logout', _('Leave'), membership.leave_url %>
27 27 <% if (membership.community? && user.has_permission?(:destroy_profile, membership)) %>
28   - <%= button 'delete', _('Remove'), { :action => 'destroy_community', :id => membership } %>
  28 + <%= button 'delete', _('Remove'), { :controller => 'profile_editor', :action => 'destroy_profile', :profile => membership.identifier } %>
29 29 <% end %>
30 30 <% end %>
31 31 </span>
... ...
app/views/profile_editor/destroy_profile.rhtml 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +<h1><%= _('Deleting profile %s') % profile.short_name(30) %></h1>
  2 +
  3 +<p><%= _('Are you sure you want to delete this profile?') %></p>
  4 +<p><%= _('You must be aware that all content of this profile (articles, events, files and pictures) will also be deleted.') %></p>
  5 +
  6 +<% button_bar do %>
  7 + <%= button(:remove, _('Yes, I am sure'), {:action => 'destroy_profile'}, :method => :post) %>
  8 + <%= button(:cancel, _('No, I gave up'), profile.url) %>
  9 +<% end %>
  10 +
... ...
app/views/profile_editor/edit.rhtml
... ... @@ -76,6 +76,10 @@
76 76  
77 77 <%= select_categories(:profile_data, _('Select the categories of your interest'), 2) %>
78 78  
  79 + <% if user && user.has_permission?('destroy_profile', profile) %>
  80 + <%= link_to _('Delete profile'), {:action => :destroy_profile}, :id => 'delete-profile-link' %>
  81 + <% end %>
  82 +
79 83 <% button_bar do %>
80 84 <%= submit_button('save', _('Save'), :cancel => {:action => 'index'}) %>
81 85 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
... ...
features/delete_profile.feature 0 → 100644
... ... @@ -0,0 +1,126 @@
  1 +Feature: delete profile
  2 + As a noosfero user
  3 + I want to delete my profile
  4 + In order to leave the network
  5 +
  6 + Background:
  7 + Given the following users
  8 + | login | name |
  9 + | joaosilva | Joao Silva |
  10 +
  11 + Scenario: deleting profile
  12 + Given I am logged in as "joaosilva"
  13 + And I am on Joao Silva's control panel
  14 + And I follow "Profile Info and settings"
  15 + And I follow "Delete profile"
  16 + Then I should see "Are you sure you want to delete this profile?"
  17 + When I follow "Yes, I am sure"
  18 + Then I should be on the homepage
  19 + When I go to /joaosilva
  20 + Then I should see "There is no such page"
  21 +
  22 + Scenario: deleting other profile
  23 + Given the following users
  24 + | login | name |
  25 + | mariasilva | Maria Silva |
  26 + And I am logged in as "mariasilva"
  27 + And I go to /myprofile/joaosilva/profile_editor/destroy_profile
  28 + Then I should see "Access denied"
  29 +
  30 + Scenario: giving up of deleting profile
  31 + Given I am logged in as "joaosilva"
  32 + And I am on Joao Silva's control panel
  33 + And I follow "Profile Info and settings"
  34 + And I follow "Delete profile"
  35 + Then I should see "Are you sure you want to delete this profile?"
  36 + When I follow "No, I gave up"
  37 + Then I should be on Joao Silva's homepage
  38 +
  39 + Scenario: community admin can see link to delete profile
  40 + Given the following community
  41 + | identifier | name |
  42 + | sample-community | Sample Community |
  43 + And "Joao Silva" is admin of "Sample Community"
  44 + And I am logged in as "joaosilva"
  45 + And I am on Sample Community's control panel
  46 + When I follow "Community Info and settings"
  47 + Then I should see "Delete profile"
  48 +
  49 + Scenario: community admin deletes the community
  50 + Given the following community
  51 + | identifier | name |
  52 + | sample-community | Sample Community |
  53 + And "Joao Silva" is admin of "Sample Community"
  54 + And I am logged in as "joaosilva"
  55 + And I am on Sample Community's control panel
  56 + And I follow "Community Info and settings"
  57 + And I follow "Delete profile"
  58 + Then I should see "Are you sure you want to delete this profile?"
  59 + When I follow "Yes, I am sure"
  60 + Then I should be on the homepage
  61 + When I go to /sample-community
  62 + Then I should see "There is no such page"
  63 +
  64 + Scenario: community regular member tries to delete the community
  65 + Given the following community
  66 + | identifier | name |
  67 + | sample-community | Sample Community |
  68 + And "Joao Silva" is a member of "Sample Community"
  69 + And I am logged in as "joaosilva"
  70 + And I go to /myprofile/sample-community/profile_editor/destroy_profile
  71 + Then I should see "Access denied"
  72 +
  73 + Scenario: enterprise admin can see link to delete enterprise
  74 + Given the following enterprise
  75 + | identifier | name |
  76 + | sample-enterprise | Sample Enterprise |
  77 + And "Joao Silva" is admin of "Sample Enterprise"
  78 + And I am logged in as "joaosilva"
  79 + And I am on Sample Enterprise's control panel
  80 + When I follow "Enterprise Info and settings"
  81 + Then I should see "Delete profile"
  82 +
  83 + Scenario: enterprise admin deletes the enterprise
  84 + Given the following enterprise
  85 + | identifier | name |
  86 + | sample-enterprise | Sample Enterprise |
  87 + And "Joao Silva" is admin of "Sample Enterprise"
  88 + And I am logged in as "joaosilva"
  89 + And I am on Sample Enterprise's control panel
  90 + When I follow "Enterprise Info and settings"
  91 + And I follow "Delete profile"
  92 + Then I should see "Are you sure you want to delete this profile?"
  93 + When I follow "Yes, I am sure"
  94 + Then I should be on the homepage
  95 + When I go to /sample-enterprise
  96 + Then I should see "There is no such page"
  97 +
  98 + Scenario: enterprise regular member tries to delete the enterprise
  99 + Given the following community
  100 + | identifier | name |
  101 + | sample-enterprise | Sample Enterprise |
  102 + And "Joao Silva" is a member of "Sample Enterprise"
  103 + And I am logged in as "joaosilva"
  104 + And I go to /myprofile/sample-enterprise/profile_editor/destroy_profile
  105 + Then I should see "Access denied"
  106 +
  107 + Scenario: community regular member cannot see link to delete profile
  108 + Given the following community
  109 + | identifier | name |
  110 + | sample-community | Sample Community |
  111 + And "Joao Silva" is a member of "Sample Community"
  112 + And I am logged in as "joaosilva"
  113 + And I am on Sample Community's control panel
  114 + When I follow "Community Info and settings"
  115 + Then I should not see "Delete profile"
  116 +
  117 + Scenario: environment admin deletes profile
  118 + Given I am logged in as admin
  119 + And I am on Joao Silva's control panel
  120 + And I follow "Profile Info and settings"
  121 + And I follow "Delete profile"
  122 + Then I should see "Are you sure you want to delete this profile?"
  123 + When I follow "Yes, I am sure"
  124 + Then I should be on the homepage
  125 + When I go to /joaosilva
  126 + Then I should see "There is no such page"
... ...
public/stylesheets/application.css
... ... @@ -3503,6 +3503,10 @@ h1#agenda-title {
3503 3503 -webkit-border-radius: 3px;
3504 3504 }
3505 3505  
  3506 +.controller-profile_editor #delete-profile-link {
  3507 + float: right;
  3508 +}
  3509 +
3506 3510 .controller-profile_editor a.control-panel-groups { background-image: url(../images/control-panel/system-users.png) }
3507 3511 .controller-profile_editor .msie6 a.control-panel-groups { background-image: url(../images/control-panel/system-users.gif) }
3508 3512  
... ...
test/fixtures/roles.yml
... ... @@ -86,3 +86,5 @@ environment_administrator:
86 86 - manage_environment_validators
87 87 - moderate_comments
88 88 - manage_environment_users
  89 + - edit_profile
  90 + - destroy_profile
... ...
test/functional/memberships_controller_test.rb
... ... @@ -122,15 +122,9 @@ class MembershipsControllerTest &lt; Test::Unit::TestCase
122 122 assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testuser/memberships/new_community" }
123 123 end
124 124  
125   - should 'render destroy_community template' do
126   - community = Community.create!(:name => 'A community to destroy')
127   - get :destroy_community, :profile => 'testuser', :id => community.id
128   - assert_template 'destroy_community'
129   - end
130   -
131 125 should 'display destroy link only to communities' do
132 126 community = Community.create!(:name => 'A community to destroy')
133   - enterprise = fast_create(Enterprise, :name => 'A enterprise test', :identifier => 'enterprise-test')
  127 + enterprise = fast_create(Enterprise, :name => 'A enterprise test')
134 128  
135 129 person = Person['testuser']
136 130 community.add_admin(person)
... ... @@ -138,19 +132,8 @@ class MembershipsControllerTest &lt; Test::Unit::TestCase
138 132  
139 133 get :index, :profile => 'testuser'
140 134  
141   - assert_tag :tag => 'a', :attributes => { :href => "/myprofile/testuser/memberships/destroy_community/#{community.id}" }
142   - assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/testuser/memberships/destroy_community/#{enterprise.id}" }
143   - end
144   -
145   - should 'be able to destroy communities' do
146   - community = Community.create!(:name => 'A community to destroy')
147   -
148   - person = Person['testuser']
149   - community.add_admin(person)
150   -
151   - assert_difference Community, :count, -1 do
152   - post :destroy_community, :profile => 'testuser', :id => community.id
153   - end
  135 + assert_tag :tag => 'a', :attributes => { :href => "/myprofile/#{community.identifier}/profile_editor/destroy_profile" }
  136 + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{enterprise.identifier}/profile_editor/destroy_profile" }
154 137 end
155 138  
156 139 should 'not display destroy link to normal members' do
... ... @@ -163,7 +146,7 @@ class MembershipsControllerTest &lt; Test::Unit::TestCase
163 146 get :index, :profile => 'testuser'
164 147  
165 148 assert_template 'index'
166   - assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/testuser/memberships/destroy_community/#{community.id}" }
  149 + assert_no_tag :tag => 'a', :attributes => { :href => "/myprofile/#{community.identifier}/profile_editor/destroy_profile" }
167 150 end
168 151  
169 152 should 'use the current environment for the template of user' do
... ...
test/functional/profile_controller_test.rb
... ... @@ -647,6 +647,23 @@ class ProfileControllerTest &lt; Test::Unit::TestCase
647 647 assert_equal "You can't leave an empty message.", assigns(:message)
648 648 end
649 649  
  650 + should "display a scrap sent" do
  651 + another_person = fast_create(Person)
  652 + Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => profile, :content => 'A scrap'))
  653 + login_as(profile.identifier)
  654 + get :index, :profile => profile.identifier
  655 + assert_tag :tag => 'p', :content => 'A scrap'
  656 + end
  657 +
  658 + should "not display a scrap sent by a removed user" do
  659 + another_person = fast_create(Person)
  660 + Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => profile, :content => 'A scrap'))
  661 + login_as(profile.identifier)
  662 + another_person.destroy
  663 + get :index, :profile => profile.identifier
  664 + assert_no_tag :tag => 'p', :content => 'A scrap'
  665 + end
  666 +
650 667 should 'see all activities of the current profile' do
651 668 p1= Person.first
652 669 p2= fast_create(Person)
... ...
test/functional/profile_editor_controller_test.rb
... ... @@ -798,4 +798,64 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase
798 798 }
799 799 end
800 800  
  801 + should 'render destroy_profile template' do
  802 + community = fast_create(Community)
  803 + get :destroy_profile, :profile => community.identifier
  804 + assert_template 'destroy_profile'
  805 + end
  806 +
  807 + should 'be able to destroy a person' do
  808 + person = fast_create(Person)
  809 +
  810 + assert_difference Person, :count, -1 do
  811 + post :destroy_profile, :profile => person.identifier
  812 + end
  813 + end
  814 +
  815 + should 'be able to destroy communities' do
  816 + community = fast_create(Community)
  817 +
  818 + person = fast_create(Person)
  819 + community.add_admin(person)
  820 +
  821 + assert_difference Community, :count, -1 do
  822 + post :destroy_profile, :profile => community.identifier
  823 + end
  824 + end
  825 +
  826 + should 'not be able to destroy communities if is a regular member' do
  827 + community = fast_create(Community)
  828 +
  829 + person = fast_create(Person)
  830 + community.add_admin(person)
  831 +
  832 + login_as(person.identifier)
  833 + assert_difference Community, :count, 0 do
  834 + post :destroy_profile, :profile => community.identifier
  835 + end
  836 + end
  837 +
  838 + should 'be able to destroy enterprise' do
  839 + enterprise = fast_create(Enterprise)
  840 +
  841 + person = fast_create(Person)
  842 + enterprise.add_admin(person)
  843 +
  844 + assert_difference Enterprise, :count, -1 do
  845 + post :destroy_profile, :profile => enterprise.identifier
  846 + end
  847 + end
  848 +
  849 + should 'not be able to destroy enterprise if is a regular member' do
  850 + enterprise = fast_create(Enterprise)
  851 +
  852 + person = fast_create(Person)
  853 + enterprise.add_admin(person)
  854 +
  855 + login_as(person.identifier)
  856 + assert_difference Enterprise, :count, 0 do
  857 + post :destroy_profile, :profile => enterprise.identifier
  858 + end
  859 + end
  860 +
801 861 end
... ...
test/unit/person_test.rb
... ... @@ -786,6 +786,14 @@ class PersonTest &lt; Test::Unit::TestCase
786 786 assert_equal s2, person.scraps(s2.id.to_s)
787 787 end
788 788  
  789 + should "destroy scrap if sender was removed" do
  790 + person = fast_create(Person)
  791 + scrap = fast_create(Scrap, :sender_id => person.id)
  792 + assert_not_nil Scrap.find_by_id(scrap.id)
  793 + person.destroy
  794 + assert_nil Scrap.find_by_id(scrap.id)
  795 + end
  796 +
789 797 should "the tracked action be notified to person friends and herself" do
790 798 p1 = Person.first
791 799 p2 = fast_create(Person)
... ...
test/unit/profile_test.rb
... ... @@ -1805,6 +1805,15 @@ class ProfileTest &lt; Test::Unit::TestCase
1805 1805 assert_nil profile.profile_custom_icon
1806 1806 end
1807 1807  
  1808 + should "destroy scrap if receiver was removed" do
  1809 + person = fast_create(Person)
  1810 + scrap = fast_create(Scrap, :receiver_id => person.id)
  1811 + assert_not_nil Scrap.find_by_id(scrap.id)
  1812 + person.destroy
  1813 + assert_nil Scrap.find_by_id(scrap.id)
  1814 + end
  1815 +
  1816 +
1808 1817 private
1809 1818  
1810 1819 def assert_invalid_identifier(id)
... ...