Commit b8ade54001d3480693016e52353b96a1bc79f9a2
1 parent
c0cb6076
Exists in
master
and in
22 other branches
Procedure after last admin leaves organization
* if he is also last member, the next user to join organization will become admin * if has other members, admin must choose some user to become admin * Generalized enterprise add_member interface. * Using json to manage action after join/leave/add/remove community/friend through ajax. * Person.members_of now returns unique profiles (ActionItem1400)
Showing
30 changed files
with
491 additions
and
134 deletions
Show diff stats
app/controllers/my_profile/profile_members_controller.rb
| ... | ... | @@ -15,26 +15,29 @@ class ProfileMembersController < MyProfileController |
| 15 | 15 | rescue ActiveRecord::RecordNotFound |
| 16 | 16 | @person = nil |
| 17 | 17 | end |
| 18 | - if @person && @person.define_roles(@roles, profile) | |
| 19 | - session[:notice] = _('Roles successfuly updated') | |
| 18 | + if !params[:confirmation] && @person && @person.is_last_admin_leaving?(profile, @roles) | |
| 19 | + redirect_to :action => :last_admin, :roles => params[:roles], :person => @person | |
| 20 | 20 | else |
| 21 | - session[:notice] = _('Couldn\'t change the roles') | |
| 21 | + if @person && @person.define_roles(@roles, profile) | |
| 22 | + session[:notice] = _('Roles successfuly updated') | |
| 23 | + else | |
| 24 | + session[:notice] = _('Couldn\'t change the roles') | |
| 25 | + end | |
| 26 | + if params[:confirmation] | |
| 27 | + redirect_to profile.url | |
| 28 | + else | |
| 29 | + redirect_to :action => :index | |
| 30 | + end | |
| 22 | 31 | end |
| 23 | - redirect_to :action => :index | |
| 24 | 32 | end |
| 25 | 33 | |
| 26 | - def change_role | |
| 27 | - @roles = Profile::Roles.organization_member_roles(environment.id) | |
| 28 | - begin | |
| 29 | - @member = profile.members.find(params[:id]) | |
| 30 | - rescue ActiveRecord::RecordNotFound | |
| 31 | - @member = nil | |
| 32 | - end | |
| 33 | - if @member | |
| 34 | - @associations = @member.find_roles(@profile) | |
| 35 | - else | |
| 36 | - redirect_to :action => :index | |
| 37 | - end | |
| 34 | + def last_admin | |
| 35 | + @person = params[:person] | |
| 36 | + @roles = params[:roles] || [] | |
| 37 | + @members = profile.members.select {|member| !profile.admins.include?(member)} | |
| 38 | + @title = _('Current admins') | |
| 39 | + @collection = :profile_admins | |
| 40 | + @remove_action = {:action => 'remove_admin'} | |
| 38 | 41 | end |
| 39 | 42 | |
| 40 | 43 | def add_role |
| ... | ... | @@ -59,14 +62,28 @@ class ProfileMembersController < MyProfileController |
| 59 | 62 | render :layout => false |
| 60 | 63 | end |
| 61 | 64 | |
| 65 | + def change_role | |
| 66 | + @roles = Profile::Roles.organization_member_roles(environment.id) | |
| 67 | + begin | |
| 68 | + @member = profile.members.find(params[:id]) | |
| 69 | + rescue ActiveRecord::RecordNotFound | |
| 70 | + @member = nil | |
| 71 | + end | |
| 72 | + if @member | |
| 73 | + @associations = @member.find_roles(@profile) | |
| 74 | + else | |
| 75 | + redirect_to :action => :index | |
| 76 | + end | |
| 77 | + end | |
| 78 | + | |
| 62 | 79 | def unassociate |
| 63 | 80 | member = Person.find(params[:id]) |
| 64 | 81 | associations = member.find_roles(profile) |
| 65 | 82 | RoleAssignment.transaction do |
| 66 | 83 | if associations.map(&:destroy) |
| 67 | - session[:notice] = 'Member succefully unassociated' | |
| 84 | + session[:notice] = _('Member succesfully unassociated') | |
| 68 | 85 | else |
| 69 | - session[:notice] = 'Failed to unassociate member' | |
| 86 | + session[:notice] = _('Failed to unassociate member') | |
| 70 | 87 | end |
| 71 | 88 | end |
| 72 | 89 | render :layout => false |
| ... | ... | @@ -83,11 +100,39 @@ class ProfileMembersController < MyProfileController |
| 83 | 100 | render :layout => false |
| 84 | 101 | end |
| 85 | 102 | |
| 103 | + def add_admin | |
| 104 | + @title = _('Current admins') | |
| 105 | + @collection = :profile_admins | |
| 106 | + | |
| 107 | + if profile.community? | |
| 108 | + member = profile.members.find_by_identifier(params[:id]) | |
| 109 | + profile.add_admin(member) | |
| 110 | + end | |
| 111 | + render :layout => false | |
| 112 | + end | |
| 113 | + | |
| 114 | + def remove_admin | |
| 115 | + @title = _('Current admins') | |
| 116 | + @collection = :profile_admins | |
| 117 | + | |
| 118 | + if profile.community? | |
| 119 | + member = profile.members.find_by_identifier(params[:id]) | |
| 120 | + profile.remove_admin(member) | |
| 121 | + end | |
| 122 | + render :layout => false | |
| 123 | + end | |
| 124 | + | |
| 86 | 125 | def find_users |
| 87 | 126 | if !params[:query] || params[:query].length <= 2 |
| 88 | 127 | @users_found = [] |
| 89 | - else | |
| 90 | - @users_found = Person.find_by_contents(params[:query] + '*') | |
| 128 | + elsif params[:scope] == 'all_users' | |
| 129 | + @users_found = Person.find_by_contents(params[:query] + '*').select {|user| !profile.members.include?(user)} | |
| 130 | + @button_alt = _('Add member') | |
| 131 | + @add_action = {:action => 'add_member'} | |
| 132 | + elsif params[:scope] == 'new_admins' | |
| 133 | + @users_found = Person.find_by_contents(params[:query] + '*').select {|user| profile.members.include?(user) && !profile.admins.include?(user)} | |
| 134 | + @button_alt = _('Add member') | |
| 135 | + @add_action = {:action => 'add_admin'} | |
| 91 | 136 | end |
| 92 | 137 | render :layout => false |
| 93 | 138 | end | ... | ... |
app/controllers/public/profile_controller.rb
| ... | ... | @@ -82,13 +82,13 @@ class ProfileController < PublicController |
| 82 | 82 | def join |
| 83 | 83 | if !user.memberships.include?(profile) |
| 84 | 84 | profile.add_member(user) |
| 85 | - if profile.closed? | |
| 86 | - render :text => _('%s administrator still needs to accept you as member.') % profile.name | |
| 85 | + if !profile.members.include?(user) | |
| 86 | + render :text => {:message => _('%s administrator still needs to accept you as member.') % profile.name}.to_json | |
| 87 | 87 | else |
| 88 | - render :text => _('You just became a member of %s.') % profile.name | |
| 88 | + render :text => {:message => _('You just became a member of %s.') % profile.name}.to_json | |
| 89 | 89 | end |
| 90 | 90 | else |
| 91 | - render :text => _('You are already a member of %s.') % profile.name | |
| 91 | + render :text => {:message => _('You are already a member of %s.') % profile.name}.to_json | |
| 92 | 92 | end |
| 93 | 93 | end |
| 94 | 94 | |
| ... | ... | @@ -110,11 +110,14 @@ class ProfileController < PublicController |
| 110 | 110 | end |
| 111 | 111 | |
| 112 | 112 | def leave |
| 113 | - if user.memberships.include?(profile) | |
| 114 | - profile.remove_member(current_user.person) | |
| 115 | - render :text => _('You just left %s.') % profile.name | |
| 113 | + if current_person.memberships.include?(profile) | |
| 114 | + if current_person.is_last_admin?(profile) | |
| 115 | + render :text => {:redirect_to => url_for({:controller => 'profile_members', :action => 'last_admin', :person => current_person.id})}.to_json | |
| 116 | + else | |
| 117 | + render :text => current_person.leave(profile, params[:reload]) | |
| 118 | + end | |
| 116 | 119 | else |
| 117 | - render :text => _('You are already a member of %s.') % profile.name | |
| 120 | + render :text => {:message => _('You are not a member of %s.') % profile.name}.to_json | |
| 118 | 121 | end |
| 119 | 122 | end |
| 120 | 123 | ... | ... |
app/models/environment_mailing.rb
| 1 | 1 | class EnvironmentMailing < Mailing |
| 2 | 2 | |
| 3 | 3 | def recipients(offset=0, limit=100) |
| 4 | - source.people.all(:order => :id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :order => :id, :conditions => { "m.person_id" => nil }) | |
| 4 | + source.people.all(:order => :id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :conditions => { "m.person_id" => nil }) | |
| 5 | 5 | end |
| 6 | 6 | |
| 7 | 7 | def each_recipient | ... | ... |
app/models/organization_mailing.rb
| ... | ... | @@ -5,7 +5,7 @@ class OrganizationMailing < Mailing |
| 5 | 5 | end |
| 6 | 6 | |
| 7 | 7 | def recipients(offset=0, limit=100) |
| 8 | - source.members.all(:order => :id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :order => :id, :conditions => { "m.person_id" => nil }) | |
| 8 | + source.members.all(:order => self.id, :offset => offset, :limit => limit, :joins => "LEFT OUTER JOIN mailing_sents m ON (m.mailing_id = #{id} AND m.person_id = profiles.id)", :conditions => { "m.person_id" => nil }) | |
| 9 | 9 | end |
| 10 | 10 | |
| 11 | 11 | def each_recipient | ... | ... |
app/models/person.rb
| ... | ... | @@ -4,7 +4,7 @@ class Person < Profile |
| 4 | 4 | acts_as_trackable :after_add => Proc.new {|p,t| notify_activity(t)} |
| 5 | 5 | acts_as_accessor |
| 6 | 6 | |
| 7 | - named_scope :members_of, lambda { |resource| { :select => 'DISTINCT profiles.*', :joins => :role_assignments, :conditions => ['role_assignments.resource_type = ? AND role_assignments.resource_id = ?', resource.class.base_class.name, resource.id ] } } | |
| 7 | + named_scope :members_of, lambda { |resource| { :select => 'DISTINCT profiles.*', :include => :role_assignments, :group => 'profiles.id', :conditions => ['role_assignments.resource_type = ? AND role_assignments.resource_id = ?', resource.class.base_class.name, resource.id ] } } | |
| 8 | 8 | |
| 9 | 9 | def memberships |
| 10 | 10 | Profile.memberships_of(self) |
| ... | ... | @@ -363,10 +363,26 @@ class Person < Profile |
| 363 | 363 | generate_url(:profile => identifier, :controller => 'profile', :action => 'index', :anchor => 'profile-wall') |
| 364 | 364 | end |
| 365 | 365 | |
| 366 | + def is_last_admin?(organization) | |
| 367 | + organization.admins == [self] | |
| 368 | + end | |
| 369 | + | |
| 370 | + def is_last_admin_leaving?(organization, roles) | |
| 371 | + is_last_admin?(organization) && roles.select {|role| role.key == "profile_admin"}.blank? | |
| 372 | + end | |
| 373 | + | |
| 374 | + def leave(profile, reload = false) | |
| 375 | + leave_hash = {:message => _('You just left %s.') % profile.name} | |
| 376 | + if reload | |
| 377 | + leave_hash.merge!({:reload => true}) | |
| 378 | + end | |
| 379 | + profile.remove_member(self) | |
| 380 | + leave_hash.to_json | |
| 381 | + end | |
| 382 | + | |
| 366 | 383 | protected |
| 367 | 384 | |
| 368 | 385 | def followed_by?(profile) |
| 369 | 386 | self == profile || self.is_a_friend?(profile) |
| 370 | 387 | end |
| 371 | - | |
| 372 | 388 | end | ... | ... |
app/models/profile.rb
| ... | ... | @@ -424,8 +424,8 @@ class Profile < ActiveRecord::Base |
| 424 | 424 | { :profile => identifier, :controller => 'profile_editor', :action => 'index' } |
| 425 | 425 | end |
| 426 | 426 | |
| 427 | - def leave_url | |
| 428 | - { :profile => identifier, :controller => 'profile', :action => 'leave' } | |
| 427 | + def leave_url(reload = false) | |
| 428 | + { :profile => identifier, :controller => 'profile', :action => 'leave', :reload => reload } | |
| 429 | 429 | end |
| 430 | 430 | |
| 431 | 431 | def join_url |
| ... | ... | @@ -563,13 +563,16 @@ private :generate_url, :url_options |
| 563 | 563 | # Adds a person as member of this Profile. |
| 564 | 564 | def add_member(person) |
| 565 | 565 | if self.has_members? |
| 566 | - if self.closed? | |
| 566 | + if self.closed? && members.count > 0 | |
| 567 | 567 | AddMember.create!(:person => person, :organization => self) unless self.already_request_membership?(person) |
| 568 | 568 | else |
| 569 | + if members.count == 0 | |
| 570 | + self.affiliate(person, Profile::Roles.admin(environment.id)) | |
| 571 | + end | |
| 569 | 572 | self.affiliate(person, Profile::Roles.member(environment.id)) |
| 570 | 573 | end |
| 571 | 574 | else |
| 572 | - raise _("%s can't has members") % self.class.name | |
| 575 | + raise _("%s can't have members") % self.class.name | |
| 573 | 576 | end |
| 574 | 577 | end |
| 575 | 578 | |
| ... | ... | @@ -582,6 +585,10 @@ private :generate_url, :url_options |
| 582 | 585 | self.affiliate(person, Profile::Roles.admin(environment.id)) |
| 583 | 586 | end |
| 584 | 587 | |
| 588 | + def remove_admin(person) | |
| 589 | + self.disaffiliate(person, Profile::Roles.admin(environment.id)) | |
| 590 | + end | |
| 591 | + | |
| 585 | 592 | def add_moderator(person) |
| 586 | 593 | if self.has_members? |
| 587 | 594 | self.affiliate(person, Profile::Roles.moderator(environment.id)) | ... | ... |
app/views/memberships/index.rhtml
| ... | ... | @@ -23,7 +23,7 @@ |
| 23 | 23 | <%= _('Created at: %s') % show_date(membership.created_at) unless membership.enterprise? %> <br/> |
| 24 | 24 | <% button_bar do %> |
| 25 | 25 | <%= button 'menu-ctrl-panel', _('Control panel of this group'), membership.admin_url %> |
| 26 | - <%= lightbox_button 'menu-logout', _('Leave'), membership.leave_url %> | |
| 26 | + <%= button 'menu-logout', _('Leave'), membership.leave_url(true), :class => 'leave-community' %> | |
| 27 | 27 | <% if (membership.community? && user.has_permission?(:destroy_profile, membership)) %> |
| 28 | 28 | <%= button 'delete', _('Remove'), { :controller => 'profile_editor', :action => 'destroy_profile', :profile => membership.identifier } %> |
| 29 | 29 | <% end %> | ... | ... |
| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | +<h2><%= _('Add admins to %s') % profile.name %></h2> | |
| 2 | + | |
| 3 | +<% form_remote_tag :url => {:action => 'find_users', :profile => profile.identifier, :scope => 'new_admins'}, :update => 'users-list', :loading => '$("users-list").addClassName("loading")', :complete => '$("users-list").removeClassName("loading")' do %> | |
| 4 | + <%= text_field_tag('query', '', :autocomplete => 'off') %> | |
| 5 | + <%= submit_tag(_('Search')) %> | |
| 6 | +<% end %> | |
| 7 | + | |
| 8 | +<%= observe_field('query', :url => {:action => 'find_users', :profile => profile.identifier, :scope => 'new_admins'}, :update => 'users-list', :frequency => 1, :with => 'query', :condition => '$("query").value.length > 2', :loading => '$("users-list").addClassName("loading")', :complete => '$("users-list").removeClassName("loading")') %> | |
| 9 | +<%= observe_field('query', :frequency => 1, :condition => '$("query").value.length <= 2', :function => '$("users-list").update($("empty-query").innerHTML)') %> | |
| 10 | + | |
| 11 | +<div id="users-list"> | |
| 12 | + <%= render :partial => 'find_users' %> | |
| 13 | +</div> | |
| 14 | + | |
| 15 | +<div id='empty-query' style='display: none'> | |
| 16 | + <%= render :partial => 'find_users' %> | |
| 17 | +</div> | |
| 18 | + | |
| 19 | +<div id="members-list" class="add-members"> | |
| 20 | + <%= render :partial => 'members_list' %> | |
| 21 | +</div> | |
| 22 | +<%= drop_receiving_element('members-list', | |
| 23 | + :url => {:action => 'add_admin', :profile => profile.identifier, :leaving_admin => @person}, | |
| 24 | + :before => '$("tr-" + element.id).hide()', | |
| 25 | + :loading => '$("members-list").addClassName("loading")', | |
| 26 | + :update => 'members-list', | |
| 27 | + :success => '$("tr-" + element.id).hide(); $(element.id).show();', | |
| 28 | + :complete => '$("members-list").removeClassName("loading")') %> | |
| 29 | + | |
| 30 | +<br style="clear:both" /> | ... | ... |
app/views/profile_members/_members_list.rhtml
| 1 | -<h3><%= _('Current Members') %></h3> | |
| 1 | +<% collection = @collection == :profile_admins ? profile.admins : profile.members %> | |
| 2 | +<% title = @title ? @title : "Current members" %> | |
| 3 | +<% remove_action = @remove_action ? @remove_action : {:action => 'unassociate'} %> | |
| 4 | + | |
| 5 | +<h3><%= _(title) %></h3> | |
| 2 | 6 | |
| 3 | 7 | <table> |
| 4 | 8 | <tr> |
| 5 | 9 | <th><%= _('Member') %></th> |
| 6 | 10 | <th><%= _('Actions') %></th> |
| 7 | 11 | </tr> |
| 8 | - <% profile.members.each do |m| %> | |
| 12 | + <% collection.each do |m| %> | |
| 9 | 13 | <tr> |
| 10 | 14 | <td><%= link_to_profile m.short_name, m.identifier, :title => m.name %> </td> |
| 11 | 15 | <td> |
| ... | ... | @@ -16,8 +20,7 @@ |
| 16 | 20 | :loading => '$("members-list").addClassName("loading")', |
| 17 | 21 | :success => "$('tr-#{m.identifier}').show()", |
| 18 | 22 | :complete => '$("members-list").removeClassName("loading")', |
| 19 | - :confirm => _('Are you sure that you want to remove this member?'), | |
| 20 | - :url => {:action => 'unassociate', :id => m}) if m != user %> | |
| 23 | + :url => { :id => m }.merge(remove_action)) if m != user %> | |
| 21 | 24 | </div> |
| 22 | 25 | </td> |
| 23 | 26 | </tr> | ... | ... |
app/views/profile_members/add_members.rhtml
| 1 | 1 | <h2><%= _('Add members to %s') % profile.name %></h2> |
| 2 | 2 | |
| 3 | -<% form_remote_tag :url => {:action => 'find_users', :profile => profile.identifier}, :update => 'users-list', :loading => '$("users-list").addClassName("loading")', :complete => '$("users-list").removeClassName("loading")' do %> | |
| 3 | +<% form_remote_tag :url => {:action => 'find_users', :profile => profile.identifier, :scope => 'all_users'}, :update => 'users-list', :loading => '$("users-list").addClassName("loading")', :complete => '$("users-list").removeClassName("loading")' do %> | |
| 4 | 4 | <%= text_field_tag('query', '', :autocomplete => 'off') %> |
| 5 | 5 | <%= submit_tag(_('Search')) %> |
| 6 | 6 | <% end %> |
| 7 | 7 | |
| 8 | -<%= observe_field('query', :url => {:action => 'find_users', :profile => profile.identifier}, :update => 'users-list', :frequency => 1, :with => 'query', :condition => '$("query").value.length > 2', :loading => '$("users-list").addClassName("loading")', :complete => '$("users-list").removeClassName("loading")') %> | |
| 8 | +<%= observe_field('query', :url => {:action => 'find_users', :profile => profile.identifier, :scope => 'all_users'}, :update => 'users-list', :frequency => 1, :with => 'query', :condition => '$("query").value.length > 2', :loading => '$("users-list").addClassName("loading")', :complete => '$("users-list").removeClassName("loading")') %> | |
| 9 | 9 | <%= observe_field('query', :frequency => 1, :condition => '$("query").value.length <= 2', :function => '$("users-list").update($("empty-query").innerHTML)') %> |
| 10 | 10 | |
| 11 | 11 | <div id="users-list"> | ... | ... |
app/views/profile_members/find_users.rhtml
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | <table> |
| 3 | 3 | <tr><th><%= _('Name') %></th><th></th></tr> |
| 4 | 4 | <% @users_found.each do |user| %> |
| 5 | - <tr id="tr-<%= user.identifier %>"<%= profile.members.include?(user) ? 'style="display:none"' : '' %>> | |
| 5 | + <tr id="tr-<%= user.identifier %>"> | |
| 6 | 6 | <td> |
| 7 | 7 | <div id="<%= user.identifier %>" class="draggable-user"> |
| 8 | 8 | <%= image_tag('/images/grip-clue.png') %> |
| ... | ... | @@ -14,10 +14,10 @@ |
| 14 | 14 | <%= draggable_element(user.identifier, :revert => true) %> |
| 15 | 15 | </td> |
| 16 | 16 | <td> |
| 17 | - <%= button_to_remote_without_text(:add, _('Add member'), | |
| 17 | + <%= button_to_remote_without_text(:add, @button_alt, | |
| 18 | 18 | { :loading => '$("members-list").addClassName("loading")', |
| 19 | 19 | :update => 'members-list', |
| 20 | - :url => {:action => 'add_member', :profile => profile.identifier, :id => user.id}, | |
| 20 | + :url => {:id => user.id, :profile => profile.identifier}.merge(@add_action), | |
| 21 | 21 | :success => "$('tr-#{user.identifier}').hide()", |
| 22 | 22 | :complete => '$("members-list").removeClassName("loading")'}) %> |
| 23 | 23 | ... | ... |
| ... | ... | @@ -0,0 +1,27 @@ |
| 1 | +<h1><%= _('Last administrator leaving %s') % profile.name %></h1> | |
| 2 | + | |
| 3 | +<% if profile.members.count > 1 %> | |
| 4 | + <div id='last-admin-message'> | |
| 5 | + <%= _('Since you are the last administrator, you must choose at least one member to administer this community.') % profile.name %> | |
| 6 | + </div> | |
| 7 | + | |
| 8 | + <%= render :partial => 'add_admins' %> | |
| 9 | + | |
| 10 | + <% form_tag :action => 'update_roles', :roles => @roles, :person => @person, :confirmation => profile.admins.count > 1 do %> | |
| 11 | + <% button_bar do %> | |
| 12 | + <%= submit_button(:save, _("Leave administration and save"), :cancel => {:action => 'index'}) %> | |
| 13 | + <% end %> | |
| 14 | + <% end %> | |
| 15 | + | |
| 16 | +<% else %> | |
| 17 | + | |
| 18 | + <div id='last-admin-message'> | |
| 19 | + <%= _('Since you are the last administrator and there is no other member in this community, the next member to join this community will assume the administrator role.') % profile.name %> | |
| 20 | + </div> | |
| 21 | + | |
| 22 | + <% form_tag :action => 'update_roles', :roles => @roles, :person => @person, :confirmation => true do %> | |
| 23 | + <% button_bar do %> | |
| 24 | + <%= submit_button(:ok, _("Ok, I want to leave"), :cancel => {:action => 'index'}) %> | |
| 25 | + <% end %> | |
| 26 | + <% end %> | |
| 27 | +<% end %> | ... | ... |
features/delete_profile.feature
| ... | ... | @@ -7,6 +7,11 @@ Feature: delete profile |
| 7 | 7 | Given the following users |
| 8 | 8 | | login | name | |
| 9 | 9 | | joaosilva | Joao Silva | |
| 10 | + | mariasilva | Maria Silva | | |
| 11 | + And the following community | |
| 12 | + | identifier | name | | |
| 13 | + | sample-community | Sample Community | | |
| 14 | + And "Maria Silva" is a member of "Sample Community" | |
| 10 | 15 | |
| 11 | 16 | Scenario: deleting profile |
| 12 | 17 | Given I am logged in as "joaosilva" |
| ... | ... | @@ -20,10 +25,7 @@ Feature: delete profile |
| 20 | 25 | Then I should see "There is no such page" |
| 21 | 26 | |
| 22 | 27 | Scenario: deleting other profile |
| 23 | - Given the following users | |
| 24 | - | login | name | | |
| 25 | - | mariasilva | Maria Silva | | |
| 26 | - And I am logged in as "mariasilva" | |
| 28 | + Given I am logged in as "mariasilva" | |
| 27 | 29 | And I go to /myprofile/joaosilva/profile_editor/destroy_profile |
| 28 | 30 | Then I should see "Access denied" |
| 29 | 31 | |
| ... | ... | @@ -37,20 +39,14 @@ Feature: delete profile |
| 37 | 39 | Then I should be on Joao Silva's profile |
| 38 | 40 | |
| 39 | 41 | 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" | |
| 42 | + Given "Joao Silva" is admin of "Sample Community" | |
| 44 | 43 | And I am logged in as "joaosilva" |
| 45 | 44 | And I am on Sample Community's control panel |
| 46 | 45 | When I follow "Community Info and settings" |
| 47 | 46 | Then I should see "Delete profile" |
| 48 | 47 | |
| 49 | 48 | 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" | |
| 49 | + Given "Joao Silva" is admin of "Sample Community" | |
| 54 | 50 | And I am logged in as "joaosilva" |
| 55 | 51 | And I am on Sample Community's control panel |
| 56 | 52 | And I follow "Community Info and settings" |
| ... | ... | @@ -62,10 +58,7 @@ Feature: delete profile |
| 62 | 58 | Then I should see "There is no such page" |
| 63 | 59 | |
| 64 | 60 | 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" | |
| 61 | + Given "Joao Silva" is a member of "Sample Community" | |
| 69 | 62 | And I am logged in as "joaosilva" |
| 70 | 63 | And I go to /myprofile/sample-community/profile_editor/destroy_profile |
| 71 | 64 | Then I should see "Access denied" |
| ... | ... | @@ -96,19 +89,17 @@ Feature: delete profile |
| 96 | 89 | Then I should see "There is no such page" |
| 97 | 90 | |
| 98 | 91 | Scenario: enterprise regular member tries to delete the enterprise |
| 99 | - Given the following community | |
| 92 | + Given the following enterprise | |
| 100 | 93 | | identifier | name | |
| 101 | 94 | | sample-enterprise | Sample Enterprise | |
| 95 | + And "Maria Silva" is a member of "Sample Enterprise" | |
| 102 | 96 | And "Joao Silva" is a member of "Sample Enterprise" |
| 103 | 97 | And I am logged in as "joaosilva" |
| 104 | 98 | And I go to /myprofile/sample-enterprise/profile_editor/destroy_profile |
| 105 | 99 | Then I should see "Access denied" |
| 106 | 100 | |
| 107 | 101 | 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" | |
| 102 | + Given "Joao Silva" is a member of "Sample Community" | |
| 112 | 103 | And I am logged in as "joaosilva" |
| 113 | 104 | And I am on Sample Community's control panel |
| 114 | 105 | When I follow "Community Info and settings" | ... | ... |
| ... | ... | @@ -0,0 +1,38 @@ |
| 1 | +Feature: remove administrator role | |
| 2 | + As an organization administrator | |
| 3 | + I want to remove my administrator role | |
| 4 | + In order to stop administrating the organization | |
| 5 | + | |
| 6 | + Background: | |
| 7 | + Given the following users | |
| 8 | + | login | name | | |
| 9 | + | joaosilva | Joao Silva | | |
| 10 | + | mariasouza | Maria Souza | | |
| 11 | + And the following community | |
| 12 | + | name | identifier | | |
| 13 | + | Nice people | nice-people | | |
| 14 | + And "Joao Silva" is admin of "Nice people" | |
| 15 | + And I am logged in as "joaosilva" | |
| 16 | + | |
| 17 | + Scenario: the last administrator and member removes his administrator role and the next member to join becomes the new administrator | |
| 18 | + Given I am on Nice people's members management | |
| 19 | + And I follow "Edit" | |
| 20 | + And I uncheck "Profile Administrator" | |
| 21 | + When I press "Save changes" | |
| 22 | + Then I should see "Since you are the last administrator and there is no other member in this community" | |
| 23 | + And I press "Ok, I want to leave" | |
| 24 | + And I am logged in as "mariasouza" | |
| 25 | + When I go to Nice people's join page | |
| 26 | + Then "Maria Souza" should be admin of "Nice people" | |
| 27 | + | |
| 28 | + Scenario: the last administrator and member removes his administrator role and the next member to join becomes the new administrator even if the organization is closed. | |
| 29 | + Given the community "Nice people" is closed | |
| 30 | + And I am on Nice people's members management | |
| 31 | + And I follow "Edit" | |
| 32 | + And I uncheck "Profile Administrator" | |
| 33 | + When I press "Save changes" | |
| 34 | + Then I should see "Since you are the last administrator and there is no other member in this community" | |
| 35 | + And I press "Ok, I want to leave" | |
| 36 | + And I am logged in as "mariasouza" | |
| 37 | + When I go to Nice people's join page | |
| 38 | + Then "Maria Souza" should be admin of "Nice people" | ... | ... |
features/register_enterprise.feature
| ... | ... | @@ -93,7 +93,7 @@ Feature: register enterprise |
| 93 | 93 | Then I should see "Enterprise registration completed" |
| 94 | 94 | And I am logged in as admin |
| 95 | 95 | And I go to the Control panel |
| 96 | - When I follow "Tasks" | |
| 96 | + When I follow "Tasks" within ".control-panel" | |
| 97 | 97 | Then I should see "Joao Silva wants to create enterprise My Enterprise." |
| 98 | 98 | And the first mail is to admin_user@example.com |
| 99 | 99 | And I choose "Accept" |
| ... | ... | @@ -120,7 +120,7 @@ Feature: register enterprise |
| 120 | 120 | Then I should see "Enterprise registration completed" |
| 121 | 121 | And I am logged in as admin |
| 122 | 122 | And I go to the Control panel |
| 123 | - When I follow "Tasks" | |
| 123 | + When I follow "Tasks" within ".control-panel" | |
| 124 | 124 | Then I should see "Joao Silva wants to create enterprise My Enterprise." |
| 125 | 125 | And the first mail is to admin_user@example.com |
| 126 | 126 | And I choose "Reject" | ... | ... |
features/step_definitions/noosfero_steps.rb
| ... | ... | @@ -16,13 +16,13 @@ Given /^"(.+)" is (online|offline|busy) in chat$/ do |user, status| |
| 16 | 16 | User.find_by_login(user).update_attributes(:chat_status => status, :chat_status_at => DateTime.now) |
| 17 | 17 | end |
| 18 | 18 | |
| 19 | -Given /^the following (community|communities|enterprises?)$/ do |kind,table| | |
| 19 | +Given /^the following (community|communities|enterprises?|organizations?)$/ do |kind,table| | |
| 20 | 20 | klass = kind.singularize.camelize.constantize |
| 21 | 21 | table.hashes.each do |row| |
| 22 | 22 | owner = row.delete("owner") |
| 23 | - community = klass.create!(row) | |
| 23 | + organization = klass.create!(row) | |
| 24 | 24 | if owner |
| 25 | - community.add_admin(Profile[owner]) | |
| 25 | + organization.add_admin(Profile[owner]) | |
| 26 | 26 | end |
| 27 | 27 | end |
| 28 | 28 | end |
| ... | ... | @@ -210,6 +210,12 @@ Given /^"(.+)" is admin of "(.+)"$/ do |person, organization| |
| 210 | 210 | org.add_admin(user) |
| 211 | 211 | end |
| 212 | 212 | |
| 213 | +Then /^"(.+)" should be admin of "(.+)"$/ do |person, organization| | |
| 214 | + org = Organization.find_by_name(organization) | |
| 215 | + user = Person.find_by_name(person) | |
| 216 | + org.admins.should include(user) | |
| 217 | +end | |
| 218 | + | |
| 213 | 219 | Given /^"([^\"]*)" has no articles$/ do |profile| |
| 214 | 220 | (Profile[profile] || Profile.find_by_name(profile)).articles.delete_all |
| 215 | 221 | end |
| ... | ... | @@ -317,3 +323,9 @@ Given /^the following comments?$/ do |table| |
| 317 | 323 | comment.save! |
| 318 | 324 | end |
| 319 | 325 | end |
| 326 | + | |
| 327 | +Given /^the community "(.+)" is closed$/ do |community| | |
| 328 | + community = Community.find_by_name(community) | |
| 329 | + community.closed = true | |
| 330 | + community.save | |
| 331 | +end | ... | ... |
features/support/paths.rb
| ... | ... | @@ -36,6 +36,12 @@ module NavigationHelpers |
| 36 | 36 | when /^the profile$/ |
| 37 | 37 | '/profile/%s' % User.find_by_id(session[:user]).login |
| 38 | 38 | |
| 39 | + when /^(.*)'s join page/ | |
| 40 | + '/profile/%s/join' % Profile.find_by_name($1).identifier | |
| 41 | + | |
| 42 | + when /^(.*)'s leave page/ | |
| 43 | + '/profile/%s/leave' % Profile.find_by_name($1).identifier | |
| 44 | + | |
| 39 | 45 | when /^login page$/ |
| 40 | 46 | '/account/login' |
| 41 | 47 | ... | ... |
public/javascripts/add-and-join.js
| ... | ... | @@ -23,8 +23,8 @@ jQuery(function($) { |
| 23 | 23 | }); |
| 24 | 24 | clicked.css("cursor",""); |
| 25 | 25 | $(".small-loading").remove(); |
| 26 | - display_notice(data); | |
| 27 | - }); | |
| 26 | + display_notice(data.message); | |
| 27 | + }, "json"); | |
| 28 | 28 | return false; |
| 29 | 29 | }) |
| 30 | 30 | |
| ... | ... | @@ -33,15 +33,24 @@ jQuery(function($) { |
| 33 | 33 | url = clicked.attr("href"); |
| 34 | 34 | loading_for_button(this); |
| 35 | 35 | $.post(url, function(data){ |
| 36 | - clicked.fadeOut(function(){ | |
| 37 | - clicked.css("display","none"); | |
| 38 | - clicked.parent().parent().find(".join-community").fadeIn(); | |
| 39 | - clicked.parent().parent().find(".join-community").css("display", ""); | |
| 40 | - }); | |
| 41 | - clicked.css("cursor",""); | |
| 42 | - $(".small-loading").remove(); | |
| 43 | - display_notice(data); | |
| 44 | - }); | |
| 36 | + if(data.redirect_to){ | |
| 37 | + document.location.href = data.redirect_to; | |
| 38 | + } | |
| 39 | + else if(data.reload){ | |
| 40 | + document.location.reload(true); | |
| 41 | + } | |
| 42 | + else{ | |
| 43 | + clicked.fadeOut(function(){ | |
| 44 | + clicked.css("display","none"); | |
| 45 | + clicked.parent().parent().find(".join-community").fadeIn(); | |
| 46 | + clicked.parent().parent().find(".join-community").css("display", ""); | |
| 47 | + }); | |
| 48 | + clicked.css("cursor",""); | |
| 49 | + $(".small-loading").remove(); | |
| 50 | + | |
| 51 | + display_notice(data.message); | |
| 52 | + } | |
| 53 | + }, "json"); | |
| 45 | 54 | return false; |
| 46 | 55 | }) |
| 47 | 56 | ... | ... |
public/stylesheets/application.css
| ... | ... | @@ -1566,7 +1566,7 @@ a.comment-picture { |
| 1566 | 1566 | a.button, a.button:visited, |
| 1567 | 1567 | body.noosfero a.button, body.noosfero a.button:visited, |
| 1568 | 1568 | input.button { |
| 1569 | - margin: 0px 2px; | |
| 1569 | + margin: 0px 2px 0px 0px; | |
| 1570 | 1570 | background-repeat: no-repeat; |
| 1571 | 1571 | background-position: 50% 50%; |
| 1572 | 1572 | padding: 3px 0px 3px 20px; |
| ... | ... | @@ -4094,6 +4094,15 @@ h1#agenda-title { |
| 4094 | 4094 | width: 100%; |
| 4095 | 4095 | } |
| 4096 | 4096 | |
| 4097 | +#last-admin-message { | |
| 4098 | + background-color: #CCC; | |
| 4099 | + color: #000; | |
| 4100 | + font-size: 14px; | |
| 4101 | + padding: 20px 15px; | |
| 4102 | + -moz-border-radius:10px; | |
| 4103 | + -webkit-border-radius:10px; | |
| 4104 | +} | |
| 4105 | + | |
| 4097 | 4106 | /* ==> public/stylesheets/controller_search.css <== */ |
| 4098 | 4107 | /* @import url(pagination.css); ALREADY INCLUDED ABOVE */ |
| 4099 | 4108 | ... | ... |
test/functional/content_viewer_controller_test.rb
| ... | ... | @@ -308,14 +308,16 @@ class ContentViewerControllerTest < Test::Unit::TestCase |
| 308 | 308 | end |
| 309 | 309 | |
| 310 | 310 | should 'not show private content to members' do |
| 311 | - community = Community.create!(:name => 'testcomm') | |
| 312 | - Folder.create!(:name => 'test', :profile => community, :published => false) | |
| 313 | - community.add_member(profile) | |
| 311 | + community = fast_create(Community) | |
| 312 | + admin = fast_create(Person) | |
| 313 | + community.add_member(admin) | |
| 314 | 314 | |
| 315 | + folder = fast_create(Folder, :profile_id => community.id, :published => false) | |
| 316 | + community.add_member(profile) | |
| 315 | 317 | login_as(profile.identifier) |
| 316 | 318 | |
| 317 | 319 | @request.stubs(:ssl?).returns(true) |
| 318 | - get :view_page, :profile => community.identifier, :page => [ 'test' ] | |
| 320 | + get :view_page, :profile => community.identifier, :page => [ folder.path ] | |
| 319 | 321 | |
| 320 | 322 | assert_template 'access_denied.rhtml' |
| 321 | 323 | end | ... | ... |
test/functional/memberships_controller_test.rb
| ... | ... | @@ -95,11 +95,11 @@ class MembershipsControllerTest < Test::Unit::TestCase |
| 95 | 95 | assert_no_tag :tag => 'li', :content => /Description:/ |
| 96 | 96 | end |
| 97 | 97 | |
| 98 | - should 'show link to leave from community' do | |
| 98 | + should 'show link to leave from community with reload' do | |
| 99 | 99 | community = Community.create!(:name => 'my test community', :description => 'description test') |
| 100 | 100 | community.add_member(profile) |
| 101 | 101 | get :index, :profile => profile.identifier |
| 102 | - assert_tag :tag => 'a', :attributes => { :href => "/profile/#{community.identifier}/leave" }, :content => 'Leave' | |
| 102 | + assert_tag :tag => 'a', :attributes => { :href => "/profile/#{community.identifier}/leave?reload=true" }, :content => 'Leave' | |
| 103 | 103 | end |
| 104 | 104 | |
| 105 | 105 | should 'current user is added as admin after create new community' do |
| ... | ... | @@ -127,7 +127,9 @@ class MembershipsControllerTest < Test::Unit::TestCase |
| 127 | 127 | end |
| 128 | 128 | |
| 129 | 129 | should 'not display destroy link to normal members' do |
| 130 | - community = Community.create!(:name => 'A community to destroy') | |
| 130 | + community = fast_create(Community) | |
| 131 | + admin = fast_create(Person) | |
| 132 | + community.add_member(admin) | |
| 131 | 133 | |
| 132 | 134 | person = Person['testuser'] |
| 133 | 135 | community.add_member(person) | ... | ... |
test/functional/profile_controller_test.rb
| ... | ... | @@ -383,14 +383,28 @@ class ProfileControllerTest < Test::Unit::TestCase |
| 383 | 383 | assert profile.memberships.include?(community), 'profile should be actually added to the community' |
| 384 | 384 | end |
| 385 | 385 | |
| 386 | - should 'create task when join to closed organization' do | |
| 387 | - community = Community.create!(:name => 'my test community', :closed => true) | |
| 388 | - login_as @profile.identifier | |
| 386 | + should 'create task when join to closed organization with members' do | |
| 387 | + community = fast_create(Community) | |
| 388 | + community.update_attribute(:closed, true) | |
| 389 | + admin = fast_create(Person) | |
| 390 | + community.add_member(admin) | |
| 391 | + | |
| 392 | + login_as profile.identifier | |
| 389 | 393 | assert_difference AddMember, :count do |
| 390 | 394 | post :join, :profile => community.identifier |
| 391 | 395 | end |
| 392 | 396 | end |
| 393 | 397 | |
| 398 | + should 'not create task when join to closed and empty organization' do | |
| 399 | + community = fast_create(Community) | |
| 400 | + community.update_attribute(:closed, true) | |
| 401 | + | |
| 402 | + login_as profile.identifier | |
| 403 | + assert_no_difference AddMember, :count do | |
| 404 | + post :join, :profile => community.identifier | |
| 405 | + end | |
| 406 | + end | |
| 407 | + | |
| 394 | 408 | should 'require login to join community' do |
| 395 | 409 | community = Community.create!(:name => 'my test community', :closed => true) |
| 396 | 410 | get :join, :profile => community.identifier |
| ... | ... | @@ -399,7 +413,10 @@ class ProfileControllerTest < Test::Unit::TestCase |
| 399 | 413 | end |
| 400 | 414 | |
| 401 | 415 | should 'actually leave profile' do |
| 402 | - community = Community.create!(:name => 'my test community') | |
| 416 | + community = fast_create(Community) | |
| 417 | + admin = fast_create(Person) | |
| 418 | + community.add_member(admin) | |
| 419 | + | |
| 403 | 420 | community.add_member(profile) |
| 404 | 421 | assert_includes profile.memberships, community |
| 405 | 422 | |
| ... | ... | @@ -417,6 +434,21 @@ class ProfileControllerTest < Test::Unit::TestCase |
| 417 | 434 | assert_redirected_to :controller => 'account', :action => 'login' |
| 418 | 435 | end |
| 419 | 436 | |
| 437 | + should 'not leave if is last admin' do | |
| 438 | + community = fast_create(Community) | |
| 439 | + | |
| 440 | + community.add_admin(profile) | |
| 441 | + assert_includes profile.memberships, community | |
| 442 | + | |
| 443 | + login_as(profile.identifier) | |
| 444 | + post :leave, :profile => community.identifier | |
| 445 | + | |
| 446 | + profile.reload | |
| 447 | + assert_response :success | |
| 448 | + assert_match(/last_admin/, @response.body) | |
| 449 | + assert_includes profile.memberships, community | |
| 450 | + end | |
| 451 | + | |
| 420 | 452 | should 'store location before login when request join via get not logged' do |
| 421 | 453 | community = Community.create!(:name => 'my test community') |
| 422 | 454 | ... | ... |
test/functional/profile_members_controller_test.rb
| ... | ... | @@ -236,22 +236,42 @@ class ProfileMembersControllerTest < Test::Unit::TestCase |
| 236 | 236 | should 'find users' do |
| 237 | 237 | ent = fast_create(Enterprise, :name => 'Test Ent', :identifier => 'test_ent') |
| 238 | 238 | user = create_user_full('test_user').person |
| 239 | - u = create_user_with_permission('ent_user', 'manage_memberships', ent) | |
| 239 | + person = create_user_with_permission('ent_user', 'manage_memberships', ent) | |
| 240 | 240 | login_as :ent_user |
| 241 | 241 | |
| 242 | - get :find_users, :profile => ent.identifier, :query => 'test*' | |
| 242 | + get :find_users, :profile => ent.identifier, :query => 'test*', :scope => 'all_users' | |
| 243 | 243 | |
| 244 | 244 | assert_includes assigns(:users_found), user |
| 245 | 245 | end |
| 246 | 246 | |
| 247 | - should 'not appear add button for member in add members page' do | |
| 247 | + should 'not display members when finding users in all_users scope' do | |
| 248 | 248 | ent = fast_create(Enterprise, :name => 'Test Ent', :identifier => 'test_ent') |
| 249 | - p = create_user_with_permission('test_user', 'manage_memberships', ent) | |
| 250 | - login_as :test_user | |
| 249 | + user = create_user_full('test_user').person | |
| 250 | + | |
| 251 | + person = create_user_with_permission('ent_user', 'manage_memberships', ent) | |
| 252 | + login_as :ent_user | |
| 253 | + | |
| 254 | + get :find_users, :profile => ent.identifier, :query => '*user', :scope => 'all_users' | |
| 255 | + | |
| 256 | + assert_tag :tag => 'a', :content => /#{user.name}/ | |
| 257 | + assert_no_tag :tag => 'a', :content => /#{person.name}/ | |
| 258 | + end | |
| 251 | 259 | |
| 252 | - get :find_users, :profile => ent.identifier, :query => 'test*' | |
| 260 | + should 'not display admins when finding users in new_admins scope' do | |
| 261 | + ent = fast_create(Enterprise, :name => 'Test Ent', :identifier => 'test_ent') | |
| 262 | + | |
| 263 | + person = create_user('admin_user').person | |
| 264 | + ent.add_admin(person) | |
| 265 | + | |
| 266 | + user = create_user_full('test_user').person | |
| 267 | + ent.add_member(user).finish | |
| 253 | 268 | |
| 254 | - assert_tag :tag => 'tr', :attributes => {:id => 'tr-test_user', :style => 'display:none'} | |
| 269 | + login_as :admin_user | |
| 270 | + | |
| 271 | + get :find_users, :profile => ent.identifier, :query => '*user', :scope => 'new_admins' | |
| 272 | + | |
| 273 | + assert_tag :tag => 'a', :content => /#{user.name}/ | |
| 274 | + assert_no_tag :tag => 'a', :content => /#{person.name}/ | |
| 255 | 275 | end |
| 256 | 276 | |
| 257 | 277 | should 'return users with <query> as a prefix' do |
| ... | ... | @@ -259,10 +279,10 @@ class ProfileMembersControllerTest < Test::Unit::TestCase |
| 259 | 279 | daniela = create_user_full('daniela').person |
| 260 | 280 | |
| 261 | 281 | ent = fast_create(Enterprise, :name => 'Test Ent', :identifier => 'test_ent') |
| 262 | - p = create_user_with_permission('test_user', 'manage_memberships', ent) | |
| 282 | + person = create_user_with_permission('test_user', 'manage_memberships', ent) | |
| 263 | 283 | login_as :test_user |
| 264 | 284 | |
| 265 | - get :find_users, :profile => ent.identifier, :query => 'daniel' | |
| 285 | + get :find_users, :profile => ent.identifier, :query => 'daniel', :scope => 'all_users' | |
| 266 | 286 | |
| 267 | 287 | assert_includes assigns(:users_found), daniel |
| 268 | 288 | assert_includes assigns(:users_found), daniela |
| ... | ... | @@ -307,4 +327,32 @@ class ProfileMembersControllerTest < Test::Unit::TestCase |
| 307 | 327 | assert_equal Profile['profile_admin_user'], assigns(:mailing).person |
| 308 | 328 | end |
| 309 | 329 | |
| 330 | + should 'set a community member as admin' do | |
| 331 | + community = fast_create(Community) | |
| 332 | + admin = create_user_with_permission('admin_user', 'manage_memberships', community) | |
| 333 | + member = create_user('test_member').person | |
| 334 | + community.add_member(member) | |
| 335 | + | |
| 336 | + assert_not_includes community.admins, member | |
| 337 | + | |
| 338 | + login_as :admin_user | |
| 339 | + get :add_admin, :profile => community.identifier, :id => member.identifier | |
| 340 | + | |
| 341 | + assert_includes community.admins, member | |
| 342 | + end | |
| 343 | + | |
| 344 | + should 'remove a community admin' do | |
| 345 | + community = fast_create(Community) | |
| 346 | + admin = create_user_with_permission('admin_user', 'manage_memberships', community) | |
| 347 | + member = create_user('test_member').person | |
| 348 | + community.add_admin(member) | |
| 349 | + | |
| 350 | + assert_includes community.admins, member | |
| 351 | + | |
| 352 | + login_as :admin_user | |
| 353 | + get :remove_admin, :profile => community.identifier, :id => member.identifier | |
| 354 | + | |
| 355 | + assert_not_includes community.admins, member | |
| 356 | + end | |
| 357 | + | |
| 310 | 358 | end | ... | ... |
test/unit/application_helper_test.rb
| ... | ... | @@ -96,11 +96,20 @@ class ApplicationHelperTest < Test::Unit::TestCase |
| 96 | 96 | assert_equal 'black', role_color('none', Environment.default.id) |
| 97 | 97 | end |
| 98 | 98 | |
| 99 | - should 'rolename for' do | |
| 99 | + should 'rolename for first organization member' do | |
| 100 | 100 | person = create_user('usertest').person |
| 101 | 101 | community = fast_create(Community, :name => 'new community', :identifier => 'new-community', :environment_id => Environment.default.id) |
| 102 | 102 | community.add_member(person) |
| 103 | - assert_equal 'Profile Member', rolename_for(person, community) | |
| 103 | + assert_equal 'Profile Administrator', rolename_for(person, community) | |
| 104 | + end | |
| 105 | + | |
| 106 | + should 'rolename for a member' do | |
| 107 | + member1 = create_user('usertest1').person | |
| 108 | + member2 = create_user('usertest2').person | |
| 109 | + community = fast_create(Community, :name => 'new community', :identifier => 'new-community', :environment_id => Environment.default.id) | |
| 110 | + community.add_member(member1) | |
| 111 | + community.add_member(member2) | |
| 112 | + assert_equal 'Profile Member', rolename_for(member2, community) | |
| 104 | 113 | end |
| 105 | 114 | |
| 106 | 115 | should 'get theme from environment by default' do | ... | ... |
test/unit/community_test.rb
| ... | ... | @@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../test_helper' |
| 3 | 3 | class CommunityTest < Test::Unit::TestCase |
| 4 | 4 | |
| 5 | 5 | def setup |
| 6 | - @person = create_user('testuser').person | |
| 6 | + @person = fast_create(Person) | |
| 7 | 7 | end |
| 8 | 8 | |
| 9 | 9 | attr_reader :person |
| ... | ... | @@ -183,10 +183,33 @@ class CommunityTest < Test::Unit::TestCase |
| 183 | 183 | end |
| 184 | 184 | end |
| 185 | 185 | |
| 186 | + should 'set as member without task if organization is closed and has no members' do | |
| 187 | + community = fast_create(Community) | |
| 188 | + community.closed = true | |
| 189 | + community.save | |
| 190 | + | |
| 191 | + assert_no_difference AddMember, :count do | |
| 192 | + community.add_member(person) | |
| 193 | + end | |
| 194 | + assert person.is_member_of?(community) | |
| 195 | + end | |
| 196 | + | |
| 197 | + should 'set as member without task if organization is not closed and has no members' do | |
| 198 | + community = fast_create(Community) | |
| 199 | + | |
| 200 | + assert_no_difference AddMember, :count do | |
| 201 | + community.add_member(person) | |
| 202 | + end | |
| 203 | + assert person.is_member_of?(community) | |
| 204 | + end | |
| 205 | + | |
| 186 | 206 | should 'not create new request membership if it already exists' do |
| 187 | 207 | community = fast_create(Community) |
| 188 | 208 | community.closed = true |
| 189 | 209 | community.save |
| 210 | + | |
| 211 | + community.add_member(fast_create(Person)) | |
| 212 | + | |
| 190 | 213 | assert_difference AddMember, :count do |
| 191 | 214 | community.add_member(person) |
| 192 | 215 | end | ... | ... |
test/unit/enterprise_test.rb
| ... | ... | @@ -102,14 +102,24 @@ class EnterpriseTest < Test::Unit::TestCase |
| 102 | 102 | assert_not_includes result, ent2 |
| 103 | 103 | end |
| 104 | 104 | |
| 105 | + should 'allow to add new members if has no members' do | |
| 106 | + enterprise = fast_create(Enterprise) | |
| 107 | + | |
| 108 | + person = fast_create(Person) | |
| 109 | + enterprise.add_member(person) | |
| 110 | + | |
| 111 | + assert person.is_member_of?(enterprise) | |
| 112 | + end | |
| 113 | + | |
| 105 | 114 | should 'not allow to add new members' do |
| 106 | - o = fast_create(Enterprise, :name => 'my test profile', :identifier => 'mytestprofile') | |
| 107 | - p = create_user('mytestuser').person | |
| 115 | + enterprise = fast_create(Enterprise) | |
| 116 | + member = fast_create(Person) | |
| 117 | + enterprise.add_member(member) | |
| 108 | 118 | |
| 109 | - o.add_member(p) | |
| 110 | - o.reload | |
| 119 | + person = fast_create(Person) | |
| 120 | + enterprise.add_member(person) | |
| 111 | 121 | |
| 112 | - assert_not_includes o.members, p | |
| 122 | + assert_equal false, person.is_member_of?(enterprise) | |
| 113 | 123 | end |
| 114 | 124 | |
| 115 | 125 | should 'allow to remove members' do | ... | ... |
test/unit/person_test.rb
| ... | ... | @@ -394,12 +394,16 @@ class PersonTest < Test::Unit::TestCase |
| 394 | 394 | end |
| 395 | 395 | |
| 396 | 396 | should 'not allow simple member to view group pending tasks' do |
| 397 | - c = fast_create(Community) | |
| 398 | - c.tasks << Task.new | |
| 399 | - p = create_user('user_without_tasks').person | |
| 400 | - c.add_member(p) | |
| 397 | + community = fast_create(Community) | |
| 398 | + member = fast_create(Person) | |
| 399 | + community.add_member(member) | |
| 400 | + | |
| 401 | + community.tasks << Task.new | |
| 401 | 402 | |
| 402 | - assert_not_includes Person.with_pending_tasks, p | |
| 403 | + person = fast_create(Person) | |
| 404 | + community.add_member(person) | |
| 405 | + | |
| 406 | + assert_not_includes Person.with_pending_tasks, person | |
| 403 | 407 | end |
| 404 | 408 | |
| 405 | 409 | should 'person has organization pending tasks' do |
| ... | ... | @@ -1116,4 +1120,29 @@ class PersonTest < Test::Unit::TestCase |
| 1116 | 1120 | assert person.receives_scrap_notification? |
| 1117 | 1121 | end |
| 1118 | 1122 | |
| 1123 | + should 'check if person is the only admin' do | |
| 1124 | + person = fast_create(Person) | |
| 1125 | + organization = fast_create(Organization) | |
| 1126 | + organization.add_admin(person) | |
| 1127 | + | |
| 1128 | + assert person.is_last_admin?(organization) | |
| 1129 | + end | |
| 1130 | + | |
| 1131 | + should 'check if person is the last admin leaving the community' do | |
| 1132 | + person = fast_create(Person) | |
| 1133 | + organization = fast_create(Organization) | |
| 1134 | + organization.add_admin(person) | |
| 1135 | + | |
| 1136 | + assert person.is_last_admin_leaving?(organization, []) | |
| 1137 | + assert !person.is_last_admin_leaving?(organization, [Role.find_by_key('profile_admin')]) | |
| 1138 | + end | |
| 1139 | + | |
| 1140 | + should 'return unique members of a community' do | |
| 1141 | + person = fast_create(Person) | |
| 1142 | + community = fast_create(Community) | |
| 1143 | + community.add_member(person) | |
| 1144 | + | |
| 1145 | + assert_equal [person], Person.members_of(community) | |
| 1146 | + assert_equal 1, Person.members_of(community).count | |
| 1147 | + end | |
| 1119 | 1148 | end | ... | ... |
test/unit/profile_test.rb
| ... | ... | @@ -1406,7 +1406,12 @@ class ProfileTest < Test::Unit::TestCase |
| 1406 | 1406 | |
| 1407 | 1407 | should 'provide URL to leave' do |
| 1408 | 1408 | profile = build(Profile, :identifier => 'testprofile') |
| 1409 | - assert_equal({ :profile => 'testprofile', :controller => 'profile', :action => 'leave'}, profile.leave_url) | |
| 1409 | + assert_equal({ :profile => 'testprofile', :controller => 'profile', :action => 'leave', :reload => false}, profile.leave_url) | |
| 1410 | + end | |
| 1411 | + | |
| 1412 | + should 'provide URL to leave with reload' do | |
| 1413 | + profile = build(Profile, :identifier => 'testprofile') | |
| 1414 | + assert_equal({ :profile => 'testprofile', :controller => 'profile', :action => 'leave', :reload => true}, profile.leave_url(true)) | |
| 1410 | 1415 | end |
| 1411 | 1416 | |
| 1412 | 1417 | should 'provide URL to join' do |
| ... | ... | @@ -1743,26 +1748,25 @@ class ProfileTest < Test::Unit::TestCase |
| 1743 | 1748 | end |
| 1744 | 1749 | |
| 1745 | 1750 | should "return one member on label if the profile has one member" do |
| 1746 | - p = fast_create(Person) | |
| 1747 | - c = fast_create(Community) | |
| 1748 | - c.add_member(p) | |
| 1749 | - assert_equal 1, c.members.count | |
| 1750 | - assert_equal "one member", c.more_popular_label | |
| 1751 | + person = fast_create(Person) | |
| 1752 | + community = fast_create(Community) | |
| 1753 | + community.add_member(person) | |
| 1754 | + | |
| 1755 | + assert_equal "one member", community.more_popular_label | |
| 1751 | 1756 | end |
| 1752 | 1757 | |
| 1753 | 1758 | should "return the number of members on label if the profile has more than one member" do |
| 1754 | - p1 = fast_create(Person) | |
| 1755 | - p2 = fast_create(Person) | |
| 1756 | - c = fast_create(Community) | |
| 1757 | - c.add_member(p1) | |
| 1758 | - c.add_member(p2) | |
| 1759 | - assert_equal 2, c.members.count | |
| 1760 | - assert_equal "2 members", c.more_popular_label | |
| 1759 | + person1 = fast_create(Person) | |
| 1760 | + person2 = fast_create(Person) | |
| 1761 | + community = fast_create(Community) | |
| 1761 | 1762 | |
| 1762 | - p3 = fast_create(Person) | |
| 1763 | - c.add_member(p3) | |
| 1764 | - assert_equal 3, c.members.count | |
| 1765 | - assert_equal "3 members", c.more_popular_label | |
| 1763 | + community.add_member(person1) | |
| 1764 | + community.add_member(person2) | |
| 1765 | + assert_equal "2 members", community.more_popular_label | |
| 1766 | + | |
| 1767 | + person3 = fast_create(Person) | |
| 1768 | + community.add_member(person3) | |
| 1769 | + assert_equal "3 members", community.more_popular_label | |
| 1766 | 1770 | end |
| 1767 | 1771 | |
| 1768 | 1772 | should 'provide list of galleries' do | ... | ... |