Commit d2029dc663248b20682bb7bac311a8d705b3b28d
Exists in
staging
and in
42 other branches
Merge branch 'invitation' into stoa
Conflicts: db/schema.rb
Showing
21 changed files
with
242 additions
and
85 deletions
Show diff stats
app/controllers/public/invite_controller.rb
| @@ -11,7 +11,7 @@ class InviteController < PublicController | @@ -11,7 +11,7 @@ class InviteController < PublicController | ||
| 11 | labels = Profile::SEARCHABLE_FIELDS.except(:nickname).merge(User::SEARCHABLE_FIELDS).map { |name,info| info[:label].downcase } | 11 | labels = Profile::SEARCHABLE_FIELDS.except(:nickname).merge(User::SEARCHABLE_FIELDS).map { |name,info| info[:label].downcase } |
| 12 | last = labels.pop | 12 | last = labels.pop |
| 13 | label = labels.join(', ') | 13 | label = labels.join(', ') |
| 14 | - @search_friend_fields = "#{label} #{_('or')} #{last}" | 14 | + @search_fields = "#{label} #{_('or')} #{last}" |
| 15 | 15 | ||
| 16 | if request.post? | 16 | if request.post? |
| 17 | contact_list = ContactList.create | 17 | contact_list = ContactList.create |
| @@ -78,17 +78,17 @@ class InviteController < PublicController | @@ -78,17 +78,17 @@ class InviteController < PublicController | ||
| 78 | end | 78 | end |
| 79 | end | 79 | end |
| 80 | 80 | ||
| 81 | - def search_friend | ||
| 82 | - render :text => find_by_contents(:people, environment, environment.people.not_members_of(profile), params['q'], {:page => 1}, {:joins => :user})[:results].map {|person| {:id => person.id, :name => person.name} }.to_json | 81 | + def search |
| 82 | + scope = profile.invite_friends_only ? user.friends : environment.people | ||
| 83 | + scope = scope.not_members_of(profile) if profile.organization? | ||
| 84 | + scope = scope.not_friends_of(profile) if profile.person? | ||
| 85 | + results = find_by_contents(:people, environment, scope, params['q'], {:page => 1}, {:joins => :user})[:results] | ||
| 86 | + render :text => prepare_to_token_input(results).to_json | ||
| 83 | end | 87 | end |
| 84 | 88 | ||
| 85 | protected | 89 | protected |
| 86 | 90 | ||
| 87 | def check_permissions_to_invite | 91 | def check_permissions_to_invite |
| 88 | - if profile.person? and !user.has_permission?(:manage_friends, profile) or | ||
| 89 | - profile.community? and !user.has_permission?(:invite_members, profile) | ||
| 90 | - render_access_denied | ||
| 91 | - end | 92 | + render_access_denied if !profile.allow_invitation_from?(user) |
| 92 | end | 93 | end |
| 93 | - | ||
| 94 | end | 94 | end |
app/models/environment.rb
| @@ -86,7 +86,9 @@ class Environment < ActiveRecord::Base | @@ -86,7 +86,9 @@ class Environment < ActiveRecord::Base | ||
| 86 | end | 86 | end |
| 87 | 87 | ||
| 88 | def admins | 88 | def admins |
| 89 | - Person.members_of(self).all(:conditions => ['role_assignments.role_id = ?', Environment::Roles.admin(self).id]) | 89 | + admin_role = Environment::Roles.admin(self) |
| 90 | + return [] if admin_role.blank? | ||
| 91 | + Person.members_of(self).all(:conditions => ['role_assignments.role_id = ?', admin_role.id]) | ||
| 90 | end | 92 | end |
| 91 | 93 | ||
| 92 | # returns the available features for a Environment, in the form of a | 94 | # returns the available features for a Environment, in the form of a |
app/models/organization.rb
| @@ -177,4 +177,8 @@ class Organization < Profile | @@ -177,4 +177,8 @@ class Organization < Profile | ||
| 177 | self.visible = false | 177 | self.visible = false |
| 178 | save! | 178 | save! |
| 179 | end | 179 | end |
| 180 | + | ||
| 181 | + def allow_invitation_from?(person) | ||
| 182 | + (followed_by?(person) && self.allow_members_to_invite) || person.has_permission?('invite-members', self) | ||
| 183 | + end | ||
| 180 | end | 184 | end |
app/models/person.rb
| @@ -34,10 +34,22 @@ class Person < Profile | @@ -34,10 +34,22 @@ class Person < Profile | ||
| 34 | roles] } | 34 | roles] } |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | - def has_permission_with_plugins?(permission, profile) | ||
| 38 | - permissions = [has_permission_without_plugins?(permission, profile)] | 37 | + scope :not_friends_of, lambda { |resources| |
| 38 | + resources = Array(resources) | ||
| 39 | + { :select => 'DISTINCT profiles.*', :conditions => ['"profiles"."id" NOT IN (SELECT DISTINCT profiles.id FROM "profiles" INNER JOIN "friendships" ON "friendships"."person_id" = "profiles"."id" WHERE "friendships"."friend_id" IN (%s))' % resources.map(&:id)] } | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + def has_permission_with_admin?(permission, resource) | ||
| 43 | + return true if resource.blank? || resource.admins.include?(self) | ||
| 44 | + return true if resource.kind_of?(Profile) && resource.environment.admins.include?(self) | ||
| 45 | + has_permission_without_admin?(permission, resource) | ||
| 46 | + end | ||
| 47 | + alias_method_chain :has_permission?, :admin | ||
| 48 | + | ||
| 49 | + def has_permission_with_plugins?(permission, resource) | ||
| 50 | + permissions = [has_permission_without_plugins?(permission, resource)] | ||
| 39 | permissions += plugins.map do |plugin| | 51 | permissions += plugins.map do |plugin| |
| 40 | - plugin.has_permission?(self, permission, profile) | 52 | + plugin.has_permission?(self, permission, resource) |
| 41 | end | 53 | end |
| 42 | permissions.include?(true) | 54 | permissions.include?(true) |
| 43 | end | 55 | end |
| @@ -513,6 +525,10 @@ roles] } | @@ -513,6 +525,10 @@ roles] } | ||
| 513 | suggestion.disable if suggestion | 525 | suggestion.disable if suggestion |
| 514 | end | 526 | end |
| 515 | 527 | ||
| 528 | + def allow_invitation_from?(person) | ||
| 529 | + person.has_permission?(:manage_friends, self) | ||
| 530 | + end | ||
| 531 | + | ||
| 516 | protected | 532 | protected |
| 517 | 533 | ||
| 518 | def followed_by?(profile) | 534 | def followed_by?(profile) |
app/models/profile.rb
| @@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
| 3 | # which by default is the one returned by Environment:default. | 3 | # which by default is the one returned by Environment:default. |
| 4 | class Profile < ActiveRecord::Base | 4 | class Profile < ActiveRecord::Base |
| 5 | 5 | ||
| 6 | - attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, :redirection_after_login, :email_suggestions | 6 | + attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, :redirection_after_login, :email_suggestions, :allow_members_to_invite, :invite_friends_only |
| 7 | 7 | ||
| 8 | # use for internationalizable human type names in search facets | 8 | # use for internationalizable human type names in search facets |
| 9 | # reimplement on subclasses | 9 | # reimplement on subclasses |
| @@ -797,7 +797,10 @@ private :generate_url, :url_options | @@ -797,7 +797,10 @@ private :generate_url, :url_options | ||
| 797 | end | 797 | end |
| 798 | 798 | ||
| 799 | def admins | 799 | def admins |
| 800 | - self.members_by_role(Profile::Roles.admin(environment.id)) | 800 | + return [] if environment.blank? |
| 801 | + admin_role = Profile::Roles.admin(environment.id) | ||
| 802 | + return [] if admin_role.blank? | ||
| 803 | + self.members_by_role(admin_role) | ||
| 801 | end | 804 | end |
| 802 | 805 | ||
| 803 | def enable_contact? | 806 | def enable_contact? |
| @@ -1001,4 +1004,8 @@ private :generate_url, :url_options | @@ -1001,4 +1004,8 @@ private :generate_url, :url_options | ||
| 1001 | suggestion.disable if suggestion | 1004 | suggestion.disable if suggestion |
| 1002 | end | 1005 | end |
| 1003 | 1006 | ||
| 1007 | + def allow_invitation_from(person) | ||
| 1008 | + false | ||
| 1009 | + end | ||
| 1010 | + | ||
| 1004 | end | 1011 | end |
app/views/friends/index.html.erb
| @@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
| 16 | <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> | 16 | <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> |
| 17 | <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %> | 17 | <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %> |
| 18 | <% unless @plugins.dispatch(:remove_invite_friends_button).include?(true) %> | 18 | <% unless @plugins.dispatch(:remove_invite_friends_button).include?(true) %> |
| 19 | - <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'invite_friends') %> | 19 | + <%= button(:person, _('Invite people'), :controller => 'invite', :action => 'invite_friends') %> |
| 20 | <% end %> | 20 | <% end %> |
| 21 | <% end %> | 21 | <% end %> |
| 22 | 22 |
app/views/invite/invite_friends.html.erb
| 1 | <% if profile.person? %> | 1 | <% if profile.person? %> |
| 2 | - <h1><%= _('Invite your friends') %></h1> | 2 | + <h1><%= _('Ask for friendship') %></h1> |
| 3 | + <% description = _('You can search for user profiles and ask them to become your friends.') %> | ||
| 3 | <% else %> | 4 | <% else %> |
| 4 | - <h1><%= _('Invite your friends to join %s') % profile.name %></h1> | 5 | + <h1><%= _('Invite people to join') %></h1> |
| 6 | + <% description = _('You can search for user profiles and invite them to join this group.') %> | ||
| 5 | <% end %> | 7 | <% end %> |
| 6 | 8 | ||
| 7 | -<% if profile.community? %> | ||
| 8 | - <h2><%= _('Invite registered users') %></h2> | ||
| 9 | - <p><%= _('You can search for user profiles and invite them to join this community.') %></p> | 9 | +<h3> |
| 10 | + <%= _("Choose person by:") %> | ||
| 11 | +</h3> | ||
| 12 | + | ||
| 13 | +<p> | ||
| 14 | + <%= labelled_radio_button _("Name"), :invite_friend_by, 1, true, :id => "invite_friend_by_name", :class => "invite_friend_by" %> | ||
| 15 | + <%= labelled_radio_button _("Email"), :invite_friend_by, 2, false, :id => "invite_friend_by_email", :class => "invite_friend_by" %> | ||
| 16 | +</p> | ||
| 17 | + | ||
| 18 | +<div class='invite_by_name'> | ||
| 19 | + <p><%= description %></p> | ||
| 10 | <%= form_tag :action => 'invite_registered_friend' do %> | 20 | <%= form_tag :action => 'invite_registered_friend' do %> |
| 11 | - <% search_action = url_for(:action => 'search_friend') %> | ||
| 12 | - <%= token_input_field_tag(:q, 'search-friends', search_action, | ||
| 13 | - { :hint_text => _('Type in your friend\'s %{search_fields}') % {:search_fields => @search_friend_fields}, | ||
| 14 | - :focus => false }) %> | 21 | + <% search_action = url_for(:action => 'search') %> |
| 22 | + <%= token_input_field_tag( | ||
| 23 | + :q, 'search-people', search_action, | ||
| 24 | + { :hint_text => _('Type in the person\'s %{search_fields}') % {:search_fields => @search_fields}, | ||
| 25 | + :focus => false }) %> | ||
| 15 | 26 | ||
| 16 | <% button_bar do %> | 27 | <% button_bar do %> |
| 17 | <%= submit_button('save', _('Invite'))%> | 28 | <%= submit_button('save', _('Invite'))%> |
| 18 | <%= button('cancel', _('Cancel'), profile.url)%> | 29 | <%= button('cancel', _('Cancel'), profile.url)%> |
| 19 | <% end %> | 30 | <% end %> |
| 20 | <% end %> | 31 | <% end %> |
| 32 | +</div> | ||
| 21 | 33 | ||
| 22 | - <br /> | 34 | +<div class='invite_by_email' style="display: none;"> |
| 23 | <h2><%= _('Invite people from my e-mail contacts') %></h2> | 35 | <h2><%= _('Invite people from my e-mail contacts') %></h2> |
| 24 | <% header = 'h3' %> | 36 | <% header = 'h3' %> |
| 25 | 37 | ||
| 26 | -<% end %> | ||
| 27 | - | ||
| 28 | <%= render :partial => 'invite/select_address_book', :locals => {:header => header} %> | 38 | <%= render :partial => 'invite/select_address_book', :locals => {:header => header} %> |
| 39 | +</div> | ||
| 29 | 40 | ||
| 30 | <div id="loadingScreen"></div> | 41 | <div id="loadingScreen"></div> |
| 42 | +<%= javascript_include_tag 'invite' %> |
app/views/invite/select_friends.html.erb
| 1 | <%= render :partial => 'invite/dialog_wait_loading', :locals => {:contact_list => @contact_list.id } if @import_from != 'manual' %> | 1 | <%= render :partial => 'invite/dialog_wait_loading', :locals => {:contact_list => @contact_list.id } if @import_from != 'manual' %> |
| 2 | 2 | ||
| 3 | <% if profile.person? %> | 3 | <% if profile.person? %> |
| 4 | - <h1><%= _('Invite your friends') %></h1> | 4 | + <h1><%= _('Invite people') %></h1> |
| 5 | <% else %> | 5 | <% else %> |
| 6 | - <h1><%= _('Invite your friends to join %s') % profile.name %></h1> | 6 | + <h1><%= _('Invite people to join') %></h1> |
| 7 | <% end %> | 7 | <% end %> |
| 8 | 8 | ||
| 9 | 9 | ||
| 10 | -<h2><%= _('Step 2 of 2: Selecting Friends') %></h2> | 10 | +<h2><%= _('Step 2 of 2: Selecting People') %></h2> |
| 11 | 11 | ||
| 12 | <%= button(:back, _('Back'), { :action => 'invite_friends' }, :id => 'invitation_back_button') %> | 12 | <%= button(:back, _('Back'), { :action => 'invite_friends' }, :id => 'invitation_back_button') %> |
| 13 | 13 | ||
| 14 | <p> | 14 | <p> |
| 15 | -<%= _('Indicate which friends you want to invite.') %> | 15 | +<%= _('Indicate which people you want to invite.') %> |
| 16 | </p> | 16 | </p> |
| 17 | 17 | ||
| 18 | <%= form_tag do %> | 18 | <%= form_tag do %> |
| @@ -33,6 +33,6 @@ | @@ -33,6 +33,6 @@ | ||
| 33 | <%= render :partial => 'invite/personalize_invitation_mail', :locals => {:mail_template => @mail_template } %> | 33 | <%= render :partial => 'invite/personalize_invitation_mail', :locals => {:mail_template => @mail_template } %> |
| 34 | 34 | ||
| 35 | <% button_bar do %> | 35 | <% button_bar do %> |
| 36 | - <%= submit_button(:ok, _("Invite my friends!")) %> | 36 | + <%= submit_button(:ok, _("Invite!")) %> |
| 37 | <% end %> | 37 | <% end %> |
| 38 | <% end %> | 38 | <% end %> |
app/views/profile/friends.html.erb
| @@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
| 18 | <%= button :back, _('Go back'), { :controller => 'profile' } %> | 18 | <%= button :back, _('Go back'), { :controller => 'profile' } %> |
| 19 | <% if user == profile %> | 19 | <% if user == profile %> |
| 20 | <%= button :edit, _('Manage my friends'), :controller => 'friends', :action => 'index', :profile => profile.identifier %> | 20 | <%= button :edit, _('Manage my friends'), :controller => 'friends', :action => 'index', :profile => profile.identifier %> |
| 21 | - <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'invite_friends') %> | 21 | + <%= button(:person, _('Invite people'), :controller => 'invite', :action => 'invite_friends') %> |
| 22 | <% end %> | 22 | <% end %> |
| 23 | <% end %> | 23 | <% end %> |
| 24 | 24 |
app/views/profile/members.html.erb
| @@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
| 18 | <%= button :back, _('Go back'), { :controller => 'profile' } %> | 18 | <%= button :back, _('Go back'), { :controller => 'profile' } %> |
| 19 | <% if profile.community? and user %> | 19 | <% if profile.community? and user %> |
| 20 | <% if user.has_permission?(:invite_members, profile) %> | 20 | <% if user.has_permission?(:invite_members, profile) %> |
| 21 | - <%= button :search, _('Invite your friends to join %s') % profile.name, :controller => 'invite', :action => 'invite_friends' %> | 21 | + <%= button :person, _('Invite people to join'), :controller => 'invite', :action => 'invite_friends' %> |
| 22 | <% end %> | 22 | <% end %> |
| 23 | <% if user.has_permission?(:send_mail_to_members, profile) %> | 23 | <% if user.has_permission?(:send_mail_to_members, profile) %> |
| 24 | <%= button :send, _('Send e-mail to members'), :controller => 'profile', :action => 'send_mail' %> | 24 | <%= button :send, _('Send e-mail to members'), :controller => 'profile', :action => 'send_mail' %> |
app/views/profile_editor/_moderation.html.erb
| 1 | <h2><%= _('Moderation options') %></h2> | 1 | <h2><%= _('Moderation options') %></h2> |
| 2 | <% if profile.community? %> | 2 | <% if profile.community? %> |
| 3 | <div style='margin-bottom: 1em'> | 3 | <div style='margin-bottom: 1em'> |
| 4 | + <h4><%= _('Invitation moderation:')%></h4> | ||
| 5 | + </div> | ||
| 6 | + <div style='margin-bottom: 0.5em'> | ||
| 7 | + <%= check_box(:profile_data, :allow_members_to_invite, :style => 'float: left') %> | ||
| 8 | + <div style='margin-left: 30px'> | ||
| 9 | + <%= _('Allow all members to send invitation (Default: only administrator)') %> | ||
| 10 | + </div> | ||
| 11 | + <br> | ||
| 12 | + <div class = 'invite_friends_only' > | ||
| 13 | + <%= check_box(:profile_data, :invite_friends_only, :style => 'float: left') %> | ||
| 14 | + <div style='margin-left: 30px'> | ||
| 15 | + <%= _('Allow members to invite only friends (Default: all users)') %> | ||
| 16 | + </div> | ||
| 17 | + </div> | ||
| 18 | + </div> | ||
| 19 | + <br> | ||
| 20 | + | ||
| 21 | + <div style='margin-bottom: 1em'> | ||
| 4 | <%= _('New members must be approved:')%> | 22 | <%= _('New members must be approved:')%> |
| 5 | </div> | 23 | </div> |
| 6 | <div style='margin-bottom: 0.5em'> | 24 | <div style='margin-bottom: 0.5em'> |
| @@ -33,3 +51,5 @@ | @@ -33,3 +51,5 @@ | ||
| 33 | <%= _('<strong>After</strong> being published in this group (a moderator can always remove publicated articles later).') %> | 51 | <%= _('<strong>After</strong> being published in this group (a moderator can always remove publicated articles later).') %> |
| 34 | </div> | 52 | </div> |
| 35 | </div> | 53 | </div> |
| 54 | + | ||
| 55 | +<%= javascript_include_tag('invite') %> |
app/views/profile_members/_index_buttons.html.erb
| @@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
| 2 | <%= button :back, _('Back'), :controller => 'profile_editor' %> | 2 | <%= button :back, _('Back'), :controller => 'profile_editor' %> |
| 3 | <%= button :add, _('Add members'), :action => 'add_members' if profile.enterprise? %> | 3 | <%= button :add, _('Add members'), :action => 'add_members' if profile.enterprise? %> |
| 4 | <% if profile.community? and user.has_permission?(:invite_members, profile) %> | 4 | <% if profile.community? and user.has_permission?(:invite_members, profile) %> |
| 5 | - <%= button :search, _('Invite your friends to join %s') % profile.short_name, :controller => 'invite', :action => 'invite_friends' %> | 5 | + <%= button :person, _('Invite people to join'), :controller => 'invite', :action => 'invite_friends' %> |
| 6 | <% end %> | 6 | <% end %> |
| 7 | <% if profile.community? and user.has_permission?(:send_mail_to_members, profile) %> | 7 | <% if profile.community? and user.has_permission?(:send_mail_to_members, profile) %> |
| 8 | <%= button :send, _('Send e-mail to members'), :controller => 'profile', :action => 'send_mail' %> | 8 | <%= button :send, _('Send e-mail to members'), :controller => 'profile', :action => 'send_mail' %> |
db/migrate/20150121173654_add_invitation_moderation_to_profile.rb
0 → 100644
db/migrate/20150122164937_add_invite_friends_only_to_profile.rb
0 → 100644
db/schema.rb
| @@ -519,6 +519,8 @@ ActiveRecord::Schema.define(:version => 20150122165042) do | @@ -519,6 +519,8 @@ ActiveRecord::Schema.define(:version => 20150122165042) do | ||
| 519 | t.string "personal_website" | 519 | t.string "personal_website" |
| 520 | t.string "jabber_id" | 520 | t.string "jabber_id" |
| 521 | t.integer "welcome_page_id" | 521 | t.integer "welcome_page_id" |
| 522 | + t.boolean "allow_members_to_invite", :default => true | ||
| 523 | + t.boolean "invite_friends_only", :default => false | ||
| 522 | end | 524 | end |
| 523 | 525 | ||
| 524 | add_index "profiles", ["activities_count"], :name => "index_profiles_on_activities_count" | 526 | add_index "profiles", ["activities_count"], :name => "index_profiles_on_activities_count" |
features/invitation.feature
| @@ -17,53 +17,50 @@ Feature: invitation | @@ -17,53 +17,50 @@ Feature: invitation | ||
| 17 | 17 | ||
| 18 | Scenario: see link to invite friends | 18 | Scenario: see link to invite friends |
| 19 | When I am on /profile/josesilva/friends | 19 | When I am on /profile/josesilva/friends |
| 20 | - Then I should see "Invite people from my e-mail contacts" link | 20 | + Then I should see "Invite people" link |
| 21 | 21 | ||
| 22 | Scenario: see link to invite friends in myprofile | 22 | Scenario: see link to invite friends in myprofile |
| 23 | When I am on /myprofile/josesilva/friends | 23 | When I am on /myprofile/josesilva/friends |
| 24 | - Then I should see "Invite people from my e-mail contacts" link | 24 | + Then I should see "Invite people" link |
| 25 | 25 | ||
| 26 | Scenario: go to invitation screen when follow link to invite friends | 26 | Scenario: go to invitation screen when follow link to invite friends |
| 27 | Given I am on /myprofile/josesilva/friends | 27 | Given I am on /myprofile/josesilva/friends |
| 28 | - When I follow "Invite people from my e-mail contacts" | 28 | + When I follow "Invite people" |
| 29 | Then I am on /profile/josesilva/invite/friends | 29 | Then I am on /profile/josesilva/invite/friends |
| 30 | 30 | ||
| 31 | - Scenario: see title when invite friends | ||
| 32 | - When I am on /profile/josesilva/invite/friends | ||
| 33 | - Then I should see "Invite your friends" | ||
| 34 | - | ||
| 35 | @selenium | 31 | @selenium |
| 36 | Scenario: back to friends after invite friends | 32 | Scenario: back to friends after invite friends |
| 37 | Given I am on /myprofile/josesilva/friends | 33 | Given I am on /myprofile/josesilva/friends |
| 38 | - And I follow "Invite people from my e-mail contacts" | 34 | + And I follow "Invite people" |
| 35 | + And I choose "Email" | ||
| 39 | And I press "Next" | 36 | And I press "Next" |
| 40 | And I fill in "manual_import_addresses" with "misfits@devil.doll" | 37 | And I fill in "manual_import_addresses" with "misfits@devil.doll" |
| 41 | And I follow "Personalize invitation mail" | 38 | And I follow "Personalize invitation mail" |
| 42 | And I fill in "mail_template" with "Follow this link <url>" | 39 | And I fill in "mail_template" with "Follow this link <url>" |
| 43 | - When I press "Invite my friends!" | 40 | + When I press "Invite!" |
| 44 | Then I should be on /profile/josesilva/friends | 41 | Then I should be on /profile/josesilva/friends |
| 45 | 42 | ||
| 46 | Scenario: see link to invite members to community | 43 | Scenario: see link to invite members to community |
| 47 | When I am on /profile/26-bsslines/members | 44 | When I am on /profile/26-bsslines/members |
| 48 | - Then I should see "Invite your friends to join 26 Bsslines" link | 45 | + Then I should see "Invite people to join" link |
| 49 | 46 | ||
| 50 | Scenario: not see link to invite members to community if has no rights | 47 | Scenario: not see link to invite members to community if has no rights |
| 51 | Given I am logged in as "josesantos" | 48 | Given I am logged in as "josesantos" |
| 52 | When I am on /profile/26-bsslines/members | 49 | When I am on /profile/26-bsslines/members |
| 53 | - Then I should not see "Invite your friends to join 26 Bsslines" link | 50 | + Then I should not see "Invite people to join" link |
| 54 | 51 | ||
| 55 | Scenario: go to invitation screen when follow link to invite members | 52 | Scenario: go to invitation screen when follow link to invite members |
| 56 | Given I am on /profile/26-bsslines/members | 53 | Given I am on /profile/26-bsslines/members |
| 57 | - When I follow "Invite your friends to join 26 Bsslines" | 54 | + When I follow "Invite people to join" |
| 58 | Then I am on /profile/26-bsslines/invite/friends | 55 | Then I am on /profile/26-bsslines/invite/friends |
| 59 | 56 | ||
| 60 | Scenario: see title when invite members | 57 | Scenario: see title when invite members |
| 61 | When I am on /profile/26-bsslines/invite/friends | 58 | When I am on /profile/26-bsslines/invite/friends |
| 62 | - Then I should see "Invite your friends to join 26 Bsslines" | 59 | + Then I should see "Invite people to join" |
| 63 | 60 | ||
| 64 | Scenario: not see link to invite members to enterprise | 61 | Scenario: not see link to invite members to enterprise |
| 65 | When I am on /profile/beatles-for-sale/members | 62 | When I am on /profile/beatles-for-sale/members |
| 66 | - Then I should not see "Invite your friends to join Beatles For Sale" link | 63 | + Then I should not see "Invite people to join" link |
| 67 | 64 | ||
| 68 | Scenario: deny access if user has no right to invite members | 65 | Scenario: deny access if user has no right to invite members |
| 69 | Given I am logged in as "josesantos" | 66 | Given I am logged in as "josesantos" |
| @@ -72,28 +69,30 @@ Feature: invitation | @@ -72,28 +69,30 @@ Feature: invitation | ||
| 72 | 69 | ||
| 73 | Scenario: not see link to invite members to enterprise in manage members | 70 | Scenario: not see link to invite members to enterprise in manage members |
| 74 | Given I am on Beatles For Sale's members management | 71 | Given I am on Beatles For Sale's members management |
| 75 | - Then I should not see "Invite your friends to join Beatles For Sale" link | 72 | + Then I should not see "Invite people to join" link |
| 76 | 73 | ||
| 77 | @selenium | 74 | @selenium |
| 78 | Scenario: back to members after invite friends to join a community | 75 | Scenario: back to members after invite friends to join a community |
| 79 | Given I am on 26 Bsslines's members management | 76 | Given I am on 26 Bsslines's members management |
| 80 | - And I follow "Invite your friends to join 26 Bsslines" | 77 | + And I follow "Invite people" |
| 78 | + And I choose "Email" | ||
| 81 | And I press "Next" | 79 | And I press "Next" |
| 82 | And I fill in "manual_import_addresses" with "misfits@devil.doll" | 80 | And I fill in "manual_import_addresses" with "misfits@devil.doll" |
| 83 | And I follow "Personalize invitation mail" | 81 | And I follow "Personalize invitation mail" |
| 84 | And I fill in "mail_template" with "Follow this link <url>" | 82 | And I fill in "mail_template" with "Follow this link <url>" |
| 85 | - When I press "Invite my friends!" | 83 | + When I press "Invite!" |
| 86 | Then I should be on /profile/26-bsslines/members | 84 | Then I should be on /profile/26-bsslines/members |
| 87 | 85 | ||
| 88 | @selenium | 86 | @selenium |
| 89 | Scenario: noosfero user receives a task when a user invites to join a community | 87 | Scenario: noosfero user receives a task when a user invites to join a community |
| 90 | Given I am on 26 Bsslines's members management | 88 | Given I am on 26 Bsslines's members management |
| 91 | - And I follow "Invite your friends to join 26 Bsslines" | 89 | + And I follow "Invite people" |
| 90 | + And I choose "Email" | ||
| 92 | And I press "Next" | 91 | And I press "Next" |
| 93 | And I fill in "manual_import_addresses" with "santos@invalid.br" | 92 | And I fill in "manual_import_addresses" with "santos@invalid.br" |
| 94 | And I follow "Personalize invitation mail" | 93 | And I follow "Personalize invitation mail" |
| 95 | And I fill in "mail_template" with "Follow this link <url>" | 94 | And I fill in "mail_template" with "Follow this link <url>" |
| 96 | - And I press "Invite my friends!" | 95 | + And I press "Invite!" |
| 97 | Given there are no pending jobs | 96 | Given there are no pending jobs |
| 98 | When I am logged in as "josesantos" | 97 | When I am logged in as "josesantos" |
| 99 | And I go to josesantos's control panel | 98 | And I go to josesantos's control panel |
| @@ -133,12 +132,13 @@ Feature: invitation | @@ -133,12 +132,13 @@ Feature: invitation | ||
| 133 | Scenario: noosfero user receives a task when a user invites to be friend | 132 | Scenario: noosfero user receives a task when a user invites to be friend |
| 134 | Given I am on josesilva's control panel | 133 | Given I am on josesilva's control panel |
| 135 | And I follow "Manage friends" | 134 | And I follow "Manage friends" |
| 136 | - And I follow "Invite people from my e-mail contacts" | 135 | + And I follow "Invite people" |
| 136 | + And I choose "Email" | ||
| 137 | And I press "Next" | 137 | And I press "Next" |
| 138 | And I fill in "manual_import_addresses" with "santos@invalid.br" | 138 | And I fill in "manual_import_addresses" with "santos@invalid.br" |
| 139 | And I follow "Personalize invitation mail" | 139 | And I follow "Personalize invitation mail" |
| 140 | And I fill in "mail_template" with "Follow this link <url>" | 140 | And I fill in "mail_template" with "Follow this link <url>" |
| 141 | - And I press "Invite my friends!" | 141 | + And I press "Invite!" |
| 142 | Given there are no pending jobs | 142 | Given there are no pending jobs |
| 143 | When I am logged in as "josesantos" | 143 | When I am logged in as "josesantos" |
| 144 | And I go to josesantos's control panel | 144 | And I go to josesantos's control panel |
features/step_definitions/invitation_steps.rb
| 1 | Given /^I invite email "(.+)" to join community "(.+)"$/ do |email, community| | 1 | Given /^I invite email "(.+)" to join community "(.+)"$/ do |email, community| |
| 2 | identifier = Community.find_by_name(community).identifier | 2 | identifier = Community.find_by_name(community).identifier |
| 3 | visit("/myprofile/#{identifier}/profile_members") | 3 | visit("/myprofile/#{identifier}/profile_members") |
| 4 | - first(:link, "Invite your friends to join #{community}").click | 4 | + first(:link, "Invite people to join").click |
| 5 | + choose("Email") | ||
| 5 | click_button('Next') | 6 | click_button('Next') |
| 6 | fill_in('manual_import_addresses', :with => "#{email}") | 7 | fill_in('manual_import_addresses', :with => "#{email}") |
| 7 | click_link('Personalize invitation mail') | 8 | click_link('Personalize invitation mail') |
| 8 | fill_in('mail_template', :with => 'Follow this link <url>') | 9 | fill_in('mail_template', :with => 'Follow this link <url>') |
| 9 | - click_button("Invite my friends!") | 10 | + click_button("Invite!") |
| 10 | end | 11 | end |
| 11 | 12 | ||
| 12 | Given /^I invite email "(.+)" to be my friend$/ do |email| | 13 | Given /^I invite email "(.+)" to be my friend$/ do |email| |
| 13 | click_link('Manage friends') | 14 | click_link('Manage friends') |
| 14 | - click_link('Invite people from my e-mail contacts') | 15 | + click_link('Invite people') |
| 16 | + choose("Email") | ||
| 15 | click_button('Next') | 17 | click_button('Next') |
| 16 | fill_in('manual_import_addresses', :with => "#{email}") | 18 | fill_in('manual_import_addresses', :with => "#{email}") |
| 17 | click_link('Personalize invitation mail') | 19 | click_link('Personalize invitation mail') |
| 18 | fill_in('mail_template', :with => 'Follow this link <url>') | 20 | fill_in('mail_template', :with => 'Follow this link <url>') |
| 19 | - click_button("Invite my friends!") | 21 | + click_button("Invite!") |
| 20 | end | 22 | end |
| @@ -0,0 +1,52 @@ | @@ -0,0 +1,52 @@ | ||
| 1 | +(function($){ | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + function toggle_invitation_method() { | ||
| 5 | + if (+(this.value) === 1) { | ||
| 6 | + $('.invite_by_email').hide(); | ||
| 7 | + $('.invite_by_name').show(); | ||
| 8 | + } else { | ||
| 9 | + $('.invite_by_name').hide(); | ||
| 10 | + $('.invite_by_email').show(); | ||
| 11 | + } | ||
| 12 | + } | ||
| 13 | + | ||
| 14 | + function manage_members_moderation() { | ||
| 15 | + var checked = $('#profile_data_allow_members_to_invite').is(':checked'); | ||
| 16 | + | ||
| 17 | + if (checked) { | ||
| 18 | + $('.invite_friends_only').show(); | ||
| 19 | + } else { | ||
| 20 | + $('.invite_friends_only').hide(); | ||
| 21 | + } | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + function hide_invite_friend_login_password() { | ||
| 25 | + $('#invite-friends-login-password').hide(); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + function show_invite_friend_login_password() { | ||
| 29 | + if (this.value === 'hotmail') { | ||
| 30 | + $('#hotmail_username_tip').show(); | ||
| 31 | + } else { | ||
| 32 | + $('#hotmail_username_tip').hide(); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + $('#invite-friends-login-password').show(); | ||
| 36 | + $('#login').focus(); | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + $(document).ready(function() { | ||
| 40 | + $('.invite_by_email').hide(); | ||
| 41 | + manage_members_moderation(); | ||
| 42 | + | ||
| 43 | + // Event triggers | ||
| 44 | + $('.invite_friend_by').click(toggle_invitation_method); | ||
| 45 | + | ||
| 46 | + $("#import_from_manual").click(hide_invite_friend_login_password); | ||
| 47 | + | ||
| 48 | + $('.invite_by_this_email').click(show_invite_friend_login_password); | ||
| 49 | + | ||
| 50 | + $('#profile_data_allow_members_to_invite').click(manage_members_moderation); | ||
| 51 | + }); | ||
| 52 | +})(jQuery); |
test/functional/invite_controller_test.rb
| @@ -101,7 +101,6 @@ class InviteControllerTest < ActionController::TestCase | @@ -101,7 +101,6 @@ class InviteControllerTest < ActionController::TestCase | ||
| 101 | should 'display invitation page' do | 101 | should 'display invitation page' do |
| 102 | get :invite_friends, :profile => profile.identifier | 102 | get :invite_friends, :profile => profile.identifier |
| 103 | assert_response :success | 103 | assert_response :success |
| 104 | - assert_tag :tag => 'h1', :content => 'Invite your friends' | ||
| 105 | end | 104 | end |
| 106 | 105 | ||
| 107 | should 'get mail template to invite members' do | 106 | should 'get mail template to invite members' do |
| @@ -243,18 +242,18 @@ class InviteControllerTest < ActionController::TestCase | @@ -243,18 +242,18 @@ class InviteControllerTest < ActionController::TestCase | ||
| 243 | friend1.save | 242 | friend1.save |
| 244 | friend2.save | 243 | friend2.save |
| 245 | 244 | ||
| 246 | - get :search_friend, :profile => profile.identifier, :q => 'me@' | 245 | + get :search, :profile => profile.identifier, :q => 'me@' |
| 247 | 246 | ||
| 248 | assert_equal 'text/html', @response.content_type | 247 | assert_equal 'text/html', @response.content_type |
| 249 | assert_equal [{"id" => friend2.id, "name" => friend2.name}].to_json, @response.body | 248 | assert_equal [{"id" => friend2.id, "name" => friend2.name}].to_json, @response.body |
| 250 | 249 | ||
| 251 | - get :search_friend, :profile => profile.identifier, :q => 'cri' | 250 | + get :search, :profile => profile.identifier, :q => 'cri' |
| 252 | 251 | ||
| 253 | assert_equal [{"id" => friend1.id, "name" => friend1.name}].to_json, @response.body | 252 | assert_equal [{"id" => friend1.id, "name" => friend1.name}].to_json, @response.body |
| 254 | 253 | ||
| 255 | - get :search_friend, :profile => profile.identifier, :q => 'will' | 254 | + get :search, :profile => profile.identifier, :q => 'will' |
| 256 | 255 | ||
| 257 | - assert_equal [{"id" => friend1.id, "name" => friend1.name}, {"id" => friend2.id, "name" => friend2.name}].to_json, @response.body | 256 | + assert_equivalent [{"id" => friend1.id, "name" => friend1.name}, {"id" => friend2.id, "name" => friend2.name}], json_response |
| 258 | end | 257 | end |
| 259 | 258 | ||
| 260 | should 'not include members in search friends profiles' do | 259 | should 'not include members in search friends profiles' do |
| @@ -266,11 +265,25 @@ class InviteControllerTest < ActionController::TestCase | @@ -266,11 +265,25 @@ class InviteControllerTest < ActionController::TestCase | ||
| 266 | 265 | ||
| 267 | community.add_member(friend2) | 266 | community.add_member(friend2) |
| 268 | 267 | ||
| 269 | - get :search_friend, :profile => community.identifier, :q => 'will' | 268 | + get :search, :profile => community.identifier, :q => 'will' |
| 270 | 269 | ||
| 271 | assert_equivalent [{"name" => friend1.name, "id" => friend1.id}], json_response | 270 | assert_equivalent [{"name" => friend1.name, "id" => friend1.id}], json_response |
| 272 | end | 271 | end |
| 273 | 272 | ||
| 273 | + should 'not include friends in search for people to request friendship' do | ||
| 274 | + friend1 = create_user('willy').person | ||
| 275 | + friend2 = create_user('william').person | ||
| 276 | + | ||
| 277 | + profile.add_friend friend1 | ||
| 278 | + friend1.add_friend profile | ||
| 279 | + profile.add_friend friend2 | ||
| 280 | + friend2.add_friend profile | ||
| 281 | + | ||
| 282 | + get :search, :profile => profile.identifier, :q => 'will' | ||
| 283 | + | ||
| 284 | + assert_empty json_response | ||
| 285 | + end | ||
| 286 | + | ||
| 274 | should 'invite registered users through profile id' do | 287 | should 'invite registered users through profile id' do |
| 275 | friend1 = create_user('testuser1').person | 288 | friend1 = create_user('testuser1').person |
| 276 | friend2 = create_user('testuser2').person | 289 | friend2 = create_user('testuser2').person |
test/functional/search_controller_test.rb
| @@ -471,25 +471,6 @@ class SearchControllerTest < ActionController::TestCase | @@ -471,25 +471,6 @@ class SearchControllerTest < ActionController::TestCase | ||
| 471 | assert_tag :tag => 'script', :attributes => { :src => 'http://maps.google.com/maps/api/js?sensor=true'} | 471 | assert_tag :tag => 'script', :attributes => { :src => 'http://maps.google.com/maps/api/js?sensor=true'} |
| 472 | end | 472 | end |
| 473 | 473 | ||
| 474 | - should 'not add script tag for google maps if searching articles' do | ||
| 475 | - ent = create_profile_with_optional_category(Enterprise, 'teste') | ||
| 476 | - get 'articles', :query => 'article', :display => 'map' | ||
| 477 | - | ||
| 478 | - assert_no_tag :tag => 'script', :attributes => { :src => 'http://maps.google.com/maps/api/js?sensor=true'} | ||
| 479 | - end | ||
| 480 | - | ||
| 481 | - should 'not add script tag for google maps if searching people' do | ||
| 482 | - get 'people', :query => 'person', :display => 'map' | ||
| 483 | - | ||
| 484 | - assert_no_tag :tag => 'script', :attributes => { :src => 'http://maps.google.com/maps/api/js?sensor=true'} | ||
| 485 | - end | ||
| 486 | - | ||
| 487 | - should 'not add script tag for google maps if searching communities' do | ||
| 488 | - get 'communities', :query => 'community', :display => 'map' | ||
| 489 | - | ||
| 490 | - assert_no_tag :tag => 'script', :attributes => { :src => 'http://maps.google.com/maps/api/js?sensor=true'} | ||
| 491 | - end | ||
| 492 | - | ||
| 493 | should 'show events of specific day' do | 474 | should 'show events of specific day' do |
| 494 | person = create_user('anotheruser').person | 475 | person = create_user('anotheruser').person |
| 495 | event = create_event(person, :name => 'Joao Birthday', :start_date => Date.new(2009, 10, 28)) | 476 | event = create_event(person, :name => 'Joao Birthday', :start_date => Date.new(2009, 10, 28)) |
test/unit/person_test.rb
| @@ -1139,6 +1139,17 @@ class PersonTest < ActiveSupport::TestCase | @@ -1139,6 +1139,17 @@ class PersonTest < ActiveSupport::TestCase | ||
| 1139 | assert_equal (Person.all - Person.members_of(community)).sort, Person.not_members_of(community).sort | 1139 | assert_equal (Person.all - Person.members_of(community)).sort, Person.not_members_of(community).sort |
| 1140 | end | 1140 | end |
| 1141 | 1141 | ||
| 1142 | + should 'return unique non-friends of a person' do | ||
| 1143 | + friend = fast_create(Person) | ||
| 1144 | + not_friend = fast_create(Person) | ||
| 1145 | + person = fast_create(Person) | ||
| 1146 | + person.add_friend(friend) | ||
| 1147 | + friend.add_friend(person) | ||
| 1148 | + | ||
| 1149 | + assert_includes Person.not_friends_of(person), not_friend | ||
| 1150 | + assert_not_includes Person.not_friends_of(person), friend | ||
| 1151 | + end | ||
| 1152 | + | ||
| 1142 | should 'be able to pass array to members_of' do | 1153 | should 'be able to pass array to members_of' do |
| 1143 | person1 = fast_create(Person) | 1154 | person1 = fast_create(Person) |
| 1144 | community = fast_create(Community) | 1155 | community = fast_create(Community) |
| @@ -1263,6 +1274,23 @@ class PersonTest < ActiveSupport::TestCase | @@ -1263,6 +1274,23 @@ class PersonTest < ActiveSupport::TestCase | ||
| 1263 | assert_equivalent [person_scrap,person_activity], person.activities.map { |a| a.klass.constantize.find(a.id) } | 1274 | assert_equivalent [person_scrap,person_activity], person.activities.map { |a| a.klass.constantize.find(a.id) } |
| 1264 | end | 1275 | end |
| 1265 | 1276 | ||
| 1277 | + should 'grant every permission over profile for its admin' do | ||
| 1278 | + admin = create_user('some-user').person | ||
| 1279 | + profile = fast_create(Profile) | ||
| 1280 | + profile.add_admin(admin) | ||
| 1281 | + | ||
| 1282 | + assert admin.has_permission?('anything', profile), 'Admin does not have every permission!' | ||
| 1283 | + end | ||
| 1284 | + | ||
| 1285 | + should 'grant every permission over profile for environment admin' do | ||
| 1286 | + admin = create_user('some-user').person | ||
| 1287 | + profile = fast_create(Profile) | ||
| 1288 | + environment = profile.environment | ||
| 1289 | + environment.add_admin(admin) | ||
| 1290 | + | ||
| 1291 | + assert admin.has_permission?('anything', profile), 'Environment admin does not have every permission!' | ||
| 1292 | + end | ||
| 1293 | + | ||
| 1266 | should 'allow plugins to extend person\'s permission access' do | 1294 | should 'allow plugins to extend person\'s permission access' do |
| 1267 | person = create_user('some-user').person | 1295 | person = create_user('some-user').person |
| 1268 | class Plugin1 < Noosfero::Plugin | 1296 | class Plugin1 < Noosfero::Plugin |