Commit b4c6fe75d04829c418398e305d62c8b1d87c93ed
Committed by
Antonio Terceiro
1 parent
cfccb6db
Exists in
master
and in
22 other branches
Invite friends to join community
- invite friends refactored (ActionItem1275)
Showing
28 changed files
with
753 additions
and
350 deletions
Show diff stats
app/controllers/my_profile/friends_controller.rb
1 | -require "contacts" | ||
2 | - | ||
3 | class FriendsController < MyProfileController | 1 | class FriendsController < MyProfileController |
4 | 2 | ||
5 | protect 'manage_friends', :profile | 3 | protect 'manage_friends', :profile |
@@ -30,83 +28,6 @@ class FriendsController < MyProfileController | @@ -30,83 +28,6 @@ class FriendsController < MyProfileController | ||
30 | end | 28 | end |
31 | end | 29 | end |
32 | 30 | ||
33 | - def invite | ||
34 | - @wizard = params[:wizard].blank? ? false : params[:wizard] | ||
35 | - @step = 3 | ||
36 | - if request.post? && params[:import] | ||
37 | - begin | ||
38 | - case params[:import_from] | ||
39 | - when "gmail" | ||
40 | - @friends = Contacts::Gmail.new(params[:login], params[:password]).contacts | ||
41 | - when "yahoo" | ||
42 | - @friends = Contacts::Yahoo.new(params[:login], params[:password]).contacts | ||
43 | - when "hotmail" | ||
44 | - @friends = Contacts::Hotmail.new(params[:login], params[:password]).contacts | ||
45 | - else | ||
46 | - @friends = [] | ||
47 | - end | ||
48 | - @friends.map! {|friend| friend + ["#{friend[0]} <#{friend[1]}>"]} | ||
49 | - rescue | ||
50 | - @login = params[:login] | ||
51 | - flash.now[:notice] = __('There was an error while looking for your contact list. Did you enter correct login and password?') | ||
52 | - end | ||
53 | - | ||
54 | - elsif request.post? && params[:confirmation] | ||
55 | - friends_to_invite = [] | ||
56 | - friends_to_invite += (params[:manual_import_addresses].is_a?(Array) ? params[:manual_import_addresses] : params[:manual_import_addresses].split("\r\n")) if params[:manual_import_addresses] | ||
57 | - friends_to_invite += (params[:webmail_import_addresses].is_a?(Array) ? params[:webmail_import_addresses] : params[:webmail_import_addresses].split("\r\n")) if params[:webmail_import_addresses] | ||
58 | - | ||
59 | - if !params[:message].match(/<url>/) | ||
60 | - flash.now[:notice] = __('<url> is needed in invitation message.') | ||
61 | - elsif !friends_to_invite.empty? | ||
62 | - friends_to_invite.each do |friend_to_invite| | ||
63 | - next if friend_to_invite == __("Firstname Lastname <friend@email.com>") | ||
64 | - | ||
65 | - friend_to_invite.strip! | ||
66 | - if match = friend_to_invite.match(/(.*)<(.*)>/) and match[2].match(Noosfero::Constants::EMAIL_FORMAT) | ||
67 | - friend_name = match[1].strip | ||
68 | - friend_email = match[2] | ||
69 | - elsif match = friend_to_invite.strip.match(Noosfero::Constants::EMAIL_FORMAT) | ||
70 | - friend_name = "" | ||
71 | - friend_email = match[0] | ||
72 | - else | ||
73 | - next | ||
74 | - end | ||
75 | - | ||
76 | - friend = User.find_by_email(friend_email) | ||
77 | - if friend.nil? | ||
78 | - InviteFriend.create(:person => profile, :friend_name => friend_name, :friend_email => friend_email, :message => params[:message]) | ||
79 | - elsif !friend.person.is_a_friend?(profile) | ||
80 | - InviteFriend.create(:person => profile, :friend => friend.person) | ||
81 | - end | ||
82 | - end | ||
83 | - | ||
84 | - flash[:notice] = __('Your invitations have been sent.') | ||
85 | - if @wizard | ||
86 | - redirect_to :action => 'invite', :wizard => true | ||
87 | - return | ||
88 | - else | ||
89 | - redirect_to :action => 'index' | ||
90 | - end | ||
91 | - else | ||
92 | - flash.now[:notice] = __('Please enter a valid email address.') | ||
93 | - end | ||
94 | - | ||
95 | - @friends = params[:webmail_friends] ? params[:webmail_friends].map {|e| YAML.load(e)} : [] | ||
96 | - @manual_import_addresses = params[:manual_import_addresses] || "" | ||
97 | - @webmail_import_addresses = params[:webmail_import_addresses] || [] | ||
98 | - end | ||
99 | - | ||
100 | - @import_from = params[:import_from] || "manual" | ||
101 | - @message = params[:message] || environment.message_for_friend_invitation | ||
102 | - if @wizard | ||
103 | - if !params[:import] | ||
104 | - @friends = [] | ||
105 | - end | ||
106 | - render :layout => 'wizard' | ||
107 | - end | ||
108 | - end | ||
109 | - | ||
110 | protected | 31 | protected |
111 | 32 | ||
112 | class << self | 33 | class << self |
@@ -117,4 +38,5 @@ class FriendsController < MyProfileController | @@ -117,4 +38,5 @@ class FriendsController < MyProfileController | ||
117 | def per_page | 38 | def per_page |
118 | self.class.per_page | 39 | self.class.per_page |
119 | end | 40 | end |
41 | + | ||
120 | end | 42 | end |
@@ -0,0 +1,50 @@ | @@ -0,0 +1,50 @@ | ||
1 | +class InviteController < PublicController | ||
2 | + | ||
3 | + needs_profile | ||
4 | + before_filter :login_required | ||
5 | + before_filter :check_permissions_to_invite, :only => 'friends' | ||
6 | + | ||
7 | + def friends | ||
8 | + step = params[:step] | ||
9 | + if request.post? | ||
10 | + if step == '1' | ||
11 | + begin | ||
12 | + @contacts = Invitation.get_contacts(params[:import_from], params[:login], params[:password]) | ||
13 | + rescue | ||
14 | + @login = params[:login] | ||
15 | + flash.now[:notice] = _('There was an error while looking for your contact list. Did you enter correct login and password?') | ||
16 | + end | ||
17 | + elsif step == '2' | ||
18 | + manual_import_addresses = params[:manual_import_addresses] | ||
19 | + webmail_import_addresses = params[:webmail_import_addresses] | ||
20 | + contacts_to_invite = Invitation.join_contacts(manual_import_addresses, webmail_import_addresses) | ||
21 | + if !params[:mail_template].match(/<url>/) | ||
22 | + flash.now[:notice] = _('<url> is needed in invitation mail.') | ||
23 | + elsif !contacts_to_invite.empty? | ||
24 | + Invitation.invite(current_user.person, contacts_to_invite, params[:mail_template], profile) | ||
25 | + flash[:notice] = _('Your invitations have been sent.') | ||
26 | + redirect_back_or_default :controller => 'profile' | ||
27 | + else | ||
28 | + flash.now[:notice] = _('Please enter a valid email address.') | ||
29 | + end | ||
30 | + @contacts = params[:webmail_friends] ? params[:webmail_friends].map {|e| YAML.load(e)} : [] | ||
31 | + @manual_import_addresses = manual_import_addresses || "" | ||
32 | + @webmail_import_addresses = webmail_import_addresses || [] | ||
33 | + end | ||
34 | + else | ||
35 | + store_location(request.referer) | ||
36 | + end | ||
37 | + @import_from = params[:import_from] || "manual" | ||
38 | + @mail_template = params[:mail_template] || environment.invitation_mail_template(profile) | ||
39 | + end | ||
40 | + | ||
41 | + protected | ||
42 | + | ||
43 | + def check_permissions_to_invite | ||
44 | + if profile.person? and !current_user.person.has_permission?(:manage_friends, profile) or | ||
45 | + profile.community? and !current_user.person.has_permission?(:invite_members, profile) | ||
46 | + render_access_denied | ||
47 | + end | ||
48 | + end | ||
49 | + | ||
50 | +end |
app/models/environment.rb
@@ -385,21 +385,30 @@ class Environment < ActiveRecord::Base | @@ -385,21 +385,30 @@ class Environment < ActiveRecord::Base | ||
385 | signup_fields | 385 | signup_fields |
386 | end | 386 | end |
387 | 387 | ||
388 | - # Default message send to friend when user use invite a friend feature | 388 | + def invitation_mail_template(profile) |
389 | + if profile.person? | ||
390 | + message_for_friend_invitation | ||
391 | + else | ||
392 | + message_for_member_invitation | ||
393 | + end | ||
394 | + end | ||
395 | + | ||
389 | def message_for_friend_invitation | 396 | def message_for_friend_invitation |
390 | - self.settings['message_for_friend_invitation'] || [ | ||
391 | - _('Hello <friend>,'), | ||
392 | - _('<user> is inviting you to participate on %{environment}.') % { :environment => self.name }, | ||
393 | - _('To accept the invitation, please follow this link:') + "\n" + '<url>', | ||
394 | - "--\n#{self.name}", | ||
395 | - '' | ||
396 | - ].join("\n\n") | 397 | + self.settings['message_for_friend_invitation'] || InviteFriend.mail_template |
397 | end | 398 | end |
398 | 399 | ||
399 | def message_for_friend_invitation=(value) | 400 | def message_for_friend_invitation=(value) |
400 | self.settings['message_for_friend_invitation'] = value | 401 | self.settings['message_for_friend_invitation'] = value |
401 | end | 402 | end |
402 | 403 | ||
404 | + def message_for_member_invitation | ||
405 | + self.settings['message_for_member_invitation'] || InviteMember.mail_template | ||
406 | + end | ||
407 | + | ||
408 | + def message_for_member_invitation=(value) | ||
409 | + self.settings['message_for_member_invitation'] = value | ||
410 | + end | ||
411 | + | ||
403 | def custom_enterprise_fields | 412 | def custom_enterprise_fields |
404 | self.settings[:custom_enterprise_fields].nil? ? {} : self.settings[:custom_enterprise_fields] | 413 | self.settings[:custom_enterprise_fields].nil? ? {} : self.settings[:custom_enterprise_fields] |
405 | end | 414 | end |
@@ -0,0 +1,113 @@ | @@ -0,0 +1,113 @@ | ||
1 | +class Invitation < Task | ||
2 | + | ||
3 | + acts_as_having_settings :field => :data | ||
4 | + settings_items :message, :friend_name, :friend_email | ||
5 | + | ||
6 | + validates_presence_of :requestor_id | ||
7 | + | ||
8 | + validates_presence_of :target_id, :if => Proc.new{|invite| invite.friend_email.blank?} | ||
9 | + | ||
10 | + validates_presence_of :friend_email, :if => Proc.new{|invite| invite.target_id.blank?} | ||
11 | + validates_format_of :friend_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => Proc.new{|invite| invite.target_id.blank?} | ||
12 | + | ||
13 | + validates_presence_of :message, :if => Proc.new{|invite| invite.target_id.blank?} | ||
14 | + validates_format_of :message, :with => /<url>/, :if => Proc.new{|invite| invite.target_id.blank?} | ||
15 | + | ||
16 | + alias :person :requestor | ||
17 | + alias :person= :requestor= | ||
18 | + | ||
19 | + alias :friend :target | ||
20 | + alias :friend= :target= | ||
21 | + | ||
22 | + after_create do |task| | ||
23 | + TaskMailer.deliver_invitation_notification(task) unless task.friend | ||
24 | + end | ||
25 | + | ||
26 | + def validate | ||
27 | + super | ||
28 | + email = friend ? friend.user.email : friend_email | ||
29 | + if person && email && person.user.email == email | ||
30 | + self.errors.add_to_base(_("You can't invite youself")) | ||
31 | + end | ||
32 | + end | ||
33 | + | ||
34 | + # Returns <tt>false</tt>. Adding friends by itself does not trigger e-mail | ||
35 | + # sending. | ||
36 | + def sends_email? | ||
37 | + false | ||
38 | + end | ||
39 | + | ||
40 | + def self.invite(person, contacts_to_invite, message, profile) | ||
41 | + contacts_to_invite.each do |contact_to_invite| | ||
42 | + next if contact_to_invite == _("Firstname Lastname <friend@email.com>") | ||
43 | + | ||
44 | + contact_to_invite.strip! | ||
45 | + if match = contact_to_invite.match(/(.*)<(.*)>/) and match[2].match(Noosfero::Constants::EMAIL_FORMAT) | ||
46 | + friend_name = match[1].strip | ||
47 | + friend_email = match[2] | ||
48 | + elsif match = contact_to_invite.strip.match(Noosfero::Constants::EMAIL_FORMAT) | ||
49 | + friend_name = "" | ||
50 | + friend_email = match[0] | ||
51 | + else | ||
52 | + next | ||
53 | + end | ||
54 | + | ||
55 | + user = User.find_by_email(friend_email) | ||
56 | + | ||
57 | + task_args = if user.nil? | ||
58 | + {:person => person, :friend_name => friend_name, :friend_email => friend_email, :message => message} | ||
59 | + elsif !user.person.is_a_friend?(person) | ||
60 | + {:person => person, :target => user.person} | ||
61 | + end | ||
62 | + | ||
63 | + if profile.person? | ||
64 | + InviteFriend.create(task_args) | ||
65 | + elsif profile.community? | ||
66 | + InviteMember.create(task_args.merge(:community_id => profile.id)) | ||
67 | + else | ||
68 | + raise NotImplementedError, 'Don\'t know how to invite people to a %s' % profile.class.to_s | ||
69 | + end | ||
70 | + end | ||
71 | + end | ||
72 | + | ||
73 | + def self.get_contacts(source, login, password) | ||
74 | + contacts = [] | ||
75 | + case source | ||
76 | + when "gmail" | ||
77 | + contacts = Contacts::Gmail.new(login, password).contacts | ||
78 | + when "yahoo" | ||
79 | + contacts = Contacts::Yahoo.new(login, password).contacts | ||
80 | + when "hotmail" | ||
81 | + contacts = Contacts::Hotmail.new(login, password).contacts | ||
82 | + when "manual" | ||
83 | + #do nothing | ||
84 | + else | ||
85 | + raise NotImplementedError, 'Unknown source to get contacts' | ||
86 | + end | ||
87 | + contacts.map { |contact| contact + ["#{contact[0]} <#{contact[1]}>"] } | ||
88 | + end | ||
89 | + | ||
90 | + def self.join_contacts(manual_import_addresses, webmail_import_addresses) | ||
91 | + contacts = [] | ||
92 | + if manual_import_addresses | ||
93 | + contacts += manual_import_addresses.is_a?(Array) ? manual_import_addresses : manual_import_addresses.split | ||
94 | + end | ||
95 | + if webmail_import_addresses | ||
96 | + contacts += webmail_import_addresses.is_a?(Array) ? webmail_import_addresses : webmail_import_addresses.split | ||
97 | + end | ||
98 | + contacts | ||
99 | + end | ||
100 | + | ||
101 | + def expanded_message | ||
102 | + msg = message | ||
103 | + msg = msg.gsub /<user>/, person.name | ||
104 | + msg = msg.gsub /<friend>/, friend_name.blank? ? friend_email : friend_name | ||
105 | + msg = msg.gsub /<environment>/, person.environment.name | ||
106 | + msg | ||
107 | + end | ||
108 | + | ||
109 | + def mail_template | ||
110 | + raise 'You should implement mail_template in a subclass' | ||
111 | + end | ||
112 | + | ||
113 | +end |
app/models/invite_friend.rb
1 | -class InviteFriend < Task | 1 | +class InviteFriend < Invitation |
2 | 2 | ||
3 | - acts_as_having_settings :group_for_person, :group_for_friend, :message, :friend_name, :friend_email, :field => :data | ||
4 | - | ||
5 | - validates_presence_of :requestor_id | ||
6 | - | ||
7 | - validates_presence_of :target_id, :if => Proc.new{|invite| invite.friend_email.blank? } | ||
8 | - | ||
9 | - validates_presence_of :friend_email, :if => Proc.new{|invite| invite.target_id.blank? } | ||
10 | - validates_format_of :friend_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => Proc.new{|invite| invite.target_id.blank? } | ||
11 | - | ||
12 | - validates_presence_of :message, :if => Proc.new{|invite| invite.target_id.blank? } | ||
13 | - validates_format_of :message, :with => /<url>/, :if => Proc.new{|invite| invite.target_id.blank? } | ||
14 | - | ||
15 | - alias :person :requestor | ||
16 | - alias :person= :requestor= | ||
17 | - | ||
18 | - alias :friend :target | ||
19 | - alias :friend= :target= | ||
20 | - | ||
21 | - after_create do |task| | ||
22 | - TaskMailer.deliver_invitation_notification(task) unless task.friend | ||
23 | - end | ||
24 | - | ||
25 | - def validate | ||
26 | - super | ||
27 | - friendemail = friend ? friend.user.email : friend_email | ||
28 | - if person && friendemail && person.user.email == friendemail | ||
29 | - self.errors.add_to_base(_("You can't invite youself")) | ||
30 | - end | ||
31 | - end | 3 | + settings_items :group_for_person, :group_for_friend |
32 | 4 | ||
33 | def perform | 5 | def perform |
34 | - requestor.add_friend(target, group_for_person) | ||
35 | - target.add_friend(requestor, group_for_friend) | ||
36 | - end | ||
37 | - | ||
38 | - # Returns <tt>false</tt>. Adding friends by itself does not trigger e-mail | ||
39 | - # sending. | ||
40 | - def sends_email? | ||
41 | - false | 6 | + person.add_friend(friend, group_for_person) |
7 | + friend.add_friend(person, group_for_friend) | ||
42 | end | 8 | end |
43 | 9 | ||
44 | def description | 10 | def description |
45 | - _('%s wants to be your friend.') % [requestor.name] | 11 | + _('%s wants to be your friend.') % [person.name] |
46 | end | 12 | end |
47 | 13 | ||
48 | def permission | 14 | def permission |
49 | :manage_friends | 15 | :manage_friends |
50 | end | 16 | end |
17 | + | ||
18 | + # Default message send to friend when user use invite a friend feature | ||
19 | + def self.mail_template | ||
20 | + [ _('Hello <friend>,'), | ||
21 | + _('<user> is inviting you to participate on <environment>.'), | ||
22 | + _('To accept the invitation, please follow this link:'), | ||
23 | + '<url>', | ||
24 | + "--\n<environment>", | ||
25 | + ].join("\n\n") | ||
26 | + end | ||
27 | + | ||
51 | end | 28 | end |
@@ -0,0 +1,36 @@ | @@ -0,0 +1,36 @@ | ||
1 | +class InviteMember < Invitation | ||
2 | + | ||
3 | + settings_items :community_id, :type => :integer | ||
4 | + validates_presence_of :community_id | ||
5 | + | ||
6 | + def community | ||
7 | + Community.find(community_id) | ||
8 | + end | ||
9 | + | ||
10 | + def community=(newcommunity) | ||
11 | + community_id = newcommunity.id | ||
12 | + end | ||
13 | + | ||
14 | + def perform | ||
15 | + community.add_member(friend) | ||
16 | + end | ||
17 | + | ||
18 | + def description | ||
19 | + _('%s invites you to join the community %s.') % [person.name, community.name] | ||
20 | + end | ||
21 | + | ||
22 | + def expanded_message | ||
23 | + super.gsub /<community>/, community.name | ||
24 | + end | ||
25 | + | ||
26 | + # Default message send to friend when user use invite a friend feature | ||
27 | + def self.mail_template | ||
28 | + [ _('Hello <friend>,'), | ||
29 | + _('<user> is inviting you to participate of <community> on <environment>.'), | ||
30 | + _('To accept the invitation, please follow this link:'), | ||
31 | + '<url>', | ||
32 | + "--\n<environment>", | ||
33 | + ].join("\n\n") | ||
34 | + end | ||
35 | + | ||
36 | +end |
app/models/profile.rb
@@ -43,6 +43,7 @@ class Profile < ActiveRecord::Base | @@ -43,6 +43,7 @@ class Profile < ActiveRecord::Base | ||
43 | 'edit_appearance' => N_('Edit appearance'), | 43 | 'edit_appearance' => N_('Edit appearance'), |
44 | 'view_private_content' => N_('View private content'), | 44 | 'view_private_content' => N_('View private content'), |
45 | 'publish_content' => N_('Publish content'), | 45 | 'publish_content' => N_('Publish content'), |
46 | + 'invite_members' => N_('Invite members'), | ||
46 | } | 47 | } |
47 | 48 | ||
48 | acts_as_accessible | 49 | acts_as_accessible |
app/models/task_mailer.rb
@@ -27,10 +27,8 @@ class TaskMailer < ActionMailer::Base | @@ -27,10 +27,8 @@ class TaskMailer < ActionMailer::Base | ||
27 | end | 27 | end |
28 | 28 | ||
29 | def invitation_notification(task) | 29 | def invitation_notification(task) |
30 | - msg = task.message | ||
31 | - msg = msg.gsub(/<user>/, task.requestor.name) | ||
32 | - msg = msg.gsub(/<friend>/, task.friend_name.blank? ? task.friend_email : task.friend_name) | ||
33 | - msg = msg.gsub(/<url>/, generate_environment_url(task, :controller => 'account', :action => 'signup', :invitation_code => task.code)) | 30 | + msg = task.expanded_message |
31 | + msg = msg.gsub /<url>/, generate_environment_url(task, :controller => 'account', :action => 'signup', :invitation_code => task.code) | ||
34 | 32 | ||
35 | recipients task.friend_email | 33 | recipients task.friend_email |
36 | 34 |
app/views/friends/index.rhtml
@@ -14,7 +14,7 @@ | @@ -14,7 +14,7 @@ | ||
14 | <% button_bar do %> | 14 | <% button_bar do %> |
15 | <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> | 15 | <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> |
16 | <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %> | 16 | <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %> |
17 | - <%= button(:search, _('Invite people from my e-mail contacts'), :action => 'invite') %> | 17 | + <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'friends') %> |
18 | <% end %> | 18 | <% end %> |
19 | <% end %> | 19 | <% end %> |
20 | 20 | ||
@@ -45,7 +45,7 @@ | @@ -45,7 +45,7 @@ | ||
45 | <% button_bar do %> | 45 | <% button_bar do %> |
46 | <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> | 46 | <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %> |
47 | <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %> | 47 | <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %> |
48 | - <%= button(:search, _('Invite people from my e-mail contacts'), :action => 'invite') %> | 48 | + <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'friends') %> |
49 | <% end %> | 49 | <% end %> |
50 | <% end %> | 50 | <% end %> |
51 | 51 |
app/views/friends/invite.rhtml
@@ -1,107 +0,0 @@ | @@ -1,107 +0,0 @@ | ||
1 | -<% if @wizard %> | ||
2 | - <%= render :partial => 'account/wizard_steps'%> | ||
3 | -<% end %> | ||
4 | - | ||
5 | -<h1><%= __('Invite your friends') %></h1> | ||
6 | - | ||
7 | -<% unless @friends %> | ||
8 | - | ||
9 | - <% if !@wizard %> | ||
10 | - <h2><%= __('Step 1 of 1: Select address book') %></h2> | ||
11 | - <% end %> | ||
12 | - | ||
13 | - <% form_tag do %> | ||
14 | - <%= hidden_field_tag(:import, 1) %> | ||
15 | - | ||
16 | - <%= hidden_field_tag(:wizard, @wizard) %> | ||
17 | - | ||
18 | - <%= [ | ||
19 | - radio_button_tag(:import_from, "manual", @import_from == "manual", :onclick => 'hide_invite_friend_login_password()') + content_tag('label', __('Manually (empty field)'), :for => "import_from_manual"), | ||
20 | - radio_button_tag(:import_from, "gmail", @import_from == "gmail", :onclick => 'show_invite_friend_login_password()') + content_tag('label', 'Gmail', :for => 'import_from_gmail'), | ||
21 | - radio_button_tag(:import_from, "yahoo", @import_from == "yahoo", :onclick => 'show_invite_friend_login_password()') + content_tag('label', 'Yahoo', :for => "import_from_yahoo"), | ||
22 | - radio_button_tag(:import_from, "hotmail", @import_from == "hotmail", :onclick => 'show_invite_friend_login_password()') + content_tag('label', 'Hotmail', :for => "import_from_hotmail") | ||
23 | - ].join("\n<br/>\n") %> | ||
24 | - | ||
25 | - <script type="text/javascript"> | ||
26 | - function hide_invite_friend_login_password() { | ||
27 | - $('invite-friends-login-password').hide(); | ||
28 | - } | ||
29 | - function show_invite_friend_login_password() { | ||
30 | - $('invite-friends-login-password').show(); | ||
31 | - $('login').focus(); | ||
32 | - } | ||
33 | - </script> | ||
34 | - <div id='invite-friends-login-password' <%= "style='display: none;'" if (@import_from == 'manual') %>> | ||
35 | - <%= labelled_form_field(__("Username") + ":", text_field_tag(:login, @login)) %> | ||
36 | - <%= labelled_form_field(__("Password") + ":", password_field_tag(:password)) %> | ||
37 | - </div> | ||
38 | - | ||
39 | - <% button_bar do %> | ||
40 | - <%= submit_button(:forward, __("Next")) %> | ||
41 | - <% end %> | ||
42 | - <p><%= __("We won't store your password or contact anyone without your permission.")%></p> | ||
43 | - | ||
44 | - <% end %> | ||
45 | - | ||
46 | -<% else %> | ||
47 | - | ||
48 | - <% if !@wizard %> | ||
49 | - <h2><%= __('Step 2 of 2: Selecting Friends') %></h2> | ||
50 | - <% end %> | ||
51 | - <p> | ||
52 | - <%= __('Indicate which friends you want to invite.') %> | ||
53 | - </p> | ||
54 | - | ||
55 | - <% if @wizard && @import_from == 'manual' %> | ||
56 | - <div> | ||
57 | - <%= __('Import now your contacts from %s, %s or %s') % [link_to_import('GMail', :import_from => 'gmail'), link_to_import('Yahoo', :import_from => 'yahoo'), link_to_import('Hotmail', :import_from => 'hotmail')] %> | ||
58 | - </div> | ||
59 | - <div> | ||
60 | - <%= _('or') %> | ||
61 | - </div> | ||
62 | - <% end %> | ||
63 | - | ||
64 | - <% form_tag do %> | ||
65 | - <%= hidden_field_tag(:confirmation, 1) %> | ||
66 | - <%= hidden_field_tag(:import_from, @import_from) %> | ||
67 | - <%= hidden_field_tag(:wizard, @wizard) %> | ||
68 | - | ||
69 | - <div> | ||
70 | - <%= __('Enter one e-mail address per line:') %> | ||
71 | - <%= text_area_tag(:manual_import_addresses, (@manual_import_addresses || ''), :cols => 72, :rows => 5) %> | ||
72 | - </div> | ||
73 | - <% if @import_from != 'manual' %> | ||
74 | - <div> | ||
75 | - <%= link_to_function __('Check all'), "$$('input.friend_to_invite').each(function(checkbox) { checkbox.checked = true; });" %> | ||
76 | - <%= link_to_function __('Uncheck all'), "$$('input.friend_to_invite').each(function(checkbox) { checkbox.checked = false; });" %> | ||
77 | - <% friend_pos = 0 %> | ||
78 | - <div id='friends-list'> | ||
79 | - <% @friends.each do |friend| %> | ||
80 | - <% friend_pos += 1 %> | ||
81 | - <p> | ||
82 | - <%= hidden_field_tag("webmail_friends[]", friend.to_yaml) %> | ||
83 | - <%= check_box_tag("webmail_import_addresses[]", friend[2], (!@webmail_import_addresses || @webmail_import_addresses.include?(friend[2])), :id => "friends_to_invite_#{friend_pos}", :class => "friend_to_invite" ) %><label for="<%= "friends_to_invite_#{friend_pos}" %>"><%= "#{friend[0]} (#{friend[1]})" %></label> | ||
84 | - </p> | ||
85 | - <% end %> | ||
86 | - </div> | ||
87 | - </div> | ||
88 | - <% end -%> | ||
89 | - | ||
90 | - <br/> | ||
91 | - | ||
92 | - <%= link_to_function(_('Personalize invitation message'), nil) do |page| | ||
93 | - page['invitation-message'].show | ||
94 | - end %> | ||
95 | - | ||
96 | - <div id='invitation-message' style='display:none'> | ||
97 | - <%= h __("Now enter an invitation message. You must keep the <url> code in your invitation message. When your friends receive the invitation e-mail, <url> will be replaced by a link that they need to click to activate their account. <user> and <friend> codes will be replaced by your name and friend name, but they are optional.") %> | ||
98 | - <%= labelled_form_field(__('Invitation message:'), text_area_tag(:message, @message, :cols => 72, :rows => 8)) %> | ||
99 | - </div> | ||
100 | - | ||
101 | - <% button_bar do %> | ||
102 | - <%= submit_button(:ok, __("Invite my friends!")) %> | ||
103 | - <% end %> | ||
104 | - <% end %> | ||
105 | - | ||
106 | -<% end %> | ||
107 | - |
@@ -0,0 +1,93 @@ | @@ -0,0 +1,93 @@ | ||
1 | +<% if profile.person? %> | ||
2 | + <h1><%= _('Invite your friends') %></h1> | ||
3 | +<% else %> | ||
4 | + <h1><%= _('Invite your friends to join %s') % profile.name %></h1> | ||
5 | +<% end %> | ||
6 | + | ||
7 | +<% unless @contacts %> | ||
8 | + | ||
9 | + <h2><%= _('Step 1 of 2: Select address book') %></h2> | ||
10 | + | ||
11 | + <% form_tag do %> | ||
12 | + <%= hidden_field_tag(:step, 1) %> | ||
13 | + | ||
14 | + <%= [ | ||
15 | + radio_button_tag(:import_from, "manual", @import_from == "manual", :onclick => 'hide_invite_friend_login_password()') + content_tag('label', _('Manually (empty field)'), :for => "import_from_manual"), | ||
16 | + radio_button_tag(:import_from, "gmail", @import_from == "gmail", :onclick => 'show_invite_friend_login_password()') + content_tag('label', 'Gmail', :for => 'import_from_gmail'), | ||
17 | + radio_button_tag(:import_from, "yahoo", @import_from == "yahoo", :onclick => 'show_invite_friend_login_password()') + content_tag('label', 'Yahoo', :for => "import_from_yahoo"), | ||
18 | + radio_button_tag(:import_from, "hotmail", @import_from == "hotmail", :onclick => 'show_invite_friend_login_password()') + content_tag('label', 'Hotmail', :for => "import_from_hotmail") | ||
19 | + ].join("\n<br/>\n") %> | ||
20 | + | ||
21 | + <script type="text/javascript"> | ||
22 | + function hide_invite_friend_login_password() { | ||
23 | + $('invite-friends-login-password').hide(); | ||
24 | + } | ||
25 | + function show_invite_friend_login_password() { | ||
26 | + $('invite-friends-login-password').show(); | ||
27 | + $('login').focus(); | ||
28 | + } | ||
29 | + </script> | ||
30 | + <div id='invite-friends-login-password' <%= "style='display: none;'" if (@import_from == 'manual') %>> | ||
31 | + <%= labelled_form_field(_("Username") + ":", text_field_tag(:login, @login)) %> | ||
32 | + <%= labelled_form_field(_("Password") + ":", password_field_tag(:password)) %> | ||
33 | + </div> | ||
34 | + | ||
35 | + <% button_bar do %> | ||
36 | + <%= submit_button(:forward, _("Next")) %> | ||
37 | + <% end %> | ||
38 | + <p><%= _("We won't store your password or contact anyone without your permission.") %></p> | ||
39 | + <% end %> | ||
40 | + | ||
41 | +<% else %> | ||
42 | + | ||
43 | + <h2><%= _('Step 2 of 2: Selecting Friends') %></h2> | ||
44 | + <p> | ||
45 | + <%= _('Indicate which friends you want to invite.') %> | ||
46 | + </p> | ||
47 | + | ||
48 | + <% form_tag do %> | ||
49 | + <%= hidden_field_tag(:step, 2) %> | ||
50 | + <%= hidden_field_tag(:import_from, @import_from) %> | ||
51 | + | ||
52 | + <div> | ||
53 | + <%= labelled_form_field(_('Enter one e-mail address per line:'), text_area_tag(:manual_import_addresses, (@manual_import_addresses || ''), :cols => 72, :rows => 5)) %> | ||
54 | + </div> | ||
55 | + <% if @import_from != 'manual' %> | ||
56 | + <div> | ||
57 | + <%= link_to_function _('Check all'), "$$('input.contact_to_invite').each(function(checkbox) { checkbox.checked = true; });" %> | ||
58 | + <%= link_to_function _('Uncheck all'), "$$('input.contact_to_invite').each(function(checkbox) { checkbox.checked = false; });" %> | ||
59 | + <% friend_pos = 0 %> | ||
60 | + <div id='contacts-list'> | ||
61 | + <% @contacts.each do |contact| %> | ||
62 | + <% friend_pos += 1 %> | ||
63 | + <p> | ||
64 | + <%= hidden_field_tag("webmail_friends[]", contact.to_yaml) %> | ||
65 | + <%= check_box_tag("webmail_import_addresses[]", contact[2], | ||
66 | + (!@webmail_import_addresses || @webmail_import_addresses.include?(contact[2])), | ||
67 | + :id => "contacts_to_invite_#{friend_pos}", | ||
68 | + :class => "contact_to_invite" ) | ||
69 | + %> | ||
70 | + <label for="<%= "contacts_to_invite_#{friend_pos}" %>"><%= "#{contact[0]} (#{contact[1]})" %></label> | ||
71 | + </p> | ||
72 | + <% end %> | ||
73 | + </div> | ||
74 | + </div> | ||
75 | + <% end -%> | ||
76 | + | ||
77 | + <br/> | ||
78 | + | ||
79 | + <%= link_to_function(_('Personalize invitation mail'), nil) do |page| | ||
80 | + page['invitation-mail_template'].show | ||
81 | + end %> | ||
82 | + | ||
83 | + <div id='invitation-mail_template' style='display:none'> | ||
84 | + <%= h _("Now enter an invitation message. You must keep the <url> code in your invitation mail_template. When your friends receive the invitation e-mail, <url> will be replaced by a link that they need to click to activate their account. <user> and <friend> codes will be replaced by your name and friend name, but they are optional.") %> | ||
85 | + <%= labelled_form_field(_('Invitation mail_template:'), text_area_tag(:mail_template, @mail_template, :cols => 72, :rows => 8)) %> | ||
86 | + </div> | ||
87 | + | ||
88 | + <% button_bar do %> | ||
89 | + <%= submit_button(:ok, _("Invite my friends!")) %> | ||
90 | + <% end %> | ||
91 | + <% end %> | ||
92 | + | ||
93 | +<% end %> |
app/views/profile/friends.rhtml
@@ -16,11 +16,11 @@ | @@ -16,11 +16,11 @@ | ||
16 | <% end %> | 16 | <% end %> |
17 | 17 | ||
18 | <% button_bar do %> | 18 | <% button_bar do %> |
19 | + <%= button :back, _('Go back'), { :controller => 'profile' }, :help => _('Back to the page where you come from.') %> | ||
19 | <% if user == profile %> | 20 | <% if user == profile %> |
20 | <%= button :edit, _('Manage my friends'), :controller => 'friends', :action => 'index', :profile => profile.identifier %> | 21 | <%= button :edit, _('Manage my friends'), :controller => 'friends', :action => 'index', :profile => profile.identifier %> |
22 | + <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'friends') %> | ||
21 | <% end %> | 23 | <% end %> |
22 | - <%= button :back, _('Go back'), { :controller => 'profile' }, | ||
23 | - :help => _('Back to the page where you come from.') %> | ||
24 | <% end %> | 24 | <% end %> |
25 | 25 | ||
26 | </div><!-- fim class="common-profile-list-block" --> | 26 | </div><!-- fim class="common-profile-list-block" --> |
app/views/profile/members.rhtml
@@ -10,9 +10,10 @@ | @@ -10,9 +10,10 @@ | ||
10 | </ul> | 10 | </ul> |
11 | 11 | ||
12 | <% button_bar do %> | 12 | <% button_bar do %> |
13 | - <%= button :back, _('Go back'), { :controller => 'profile' }, | ||
14 | - :help => _('Back to the page where you come from.') %> | 13 | + <%= button :back, _('Go back'), { :controller => 'profile' }, :help => _('Back to the page where you come from.') %> |
14 | + <% if profile.community? and user and user.has_permission?(:invite_members, profile) %> | ||
15 | + <%= button :search, _('Invite your friends to join %s') % profile.name, :controller => 'invite', :action => 'friends' %> | ||
16 | + <% end %> | ||
15 | <% end %> | 17 | <% end %> |
16 | 18 | ||
17 | </div><!-- fim class="common-profile-list-block" --> | 19 | </div><!-- fim class="common-profile-list-block" --> |
18 | - |
app/views/profile_members/index.rhtml
@@ -5,4 +5,7 @@ | @@ -5,4 +5,7 @@ | ||
5 | <% button_bar do %> | 5 | <% button_bar do %> |
6 | <%= button :back, _('Back'), :controller => 'profile_editor' %> | 6 | <%= button :back, _('Back'), :controller => 'profile_editor' %> |
7 | <%= button :add, _('Add members'), :action => 'add_members' if profile.enterprise? %> | 7 | <%= button :add, _('Add members'), :action => 'add_members' if profile.enterprise? %> |
8 | + <% if profile.community? and user.has_permission?(:invite_members, profile) %> | ||
9 | + <%= button :search, _('Invite your friends to join %s') % profile.name, :controller => 'invite', :action => 'friends' %> | ||
10 | + <% end %> | ||
8 | <% end %> | 11 | <% end %> |
config/routes.rb
@@ -58,13 +58,16 @@ ActionController::Routing::Routes.draw do |map| | @@ -58,13 +58,16 @@ ActionController::Routing::Routes.draw do |map| | ||
58 | map.events 'profile/:profile/events/:year/:month', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :profile => /#{Noosfero.identifier_format}/ | 58 | map.events 'profile/:profile/events/:year/:month', :controller => 'events', :action => 'events', :year => /\d*/, :month => /\d*/, :profile => /#{Noosfero.identifier_format}/ |
59 | map.events 'profile/:profile/events', :controller => 'events', :action => 'events', :profile => /#{Noosfero.identifier_format}/ | 59 | map.events 'profile/:profile/events', :controller => 'events', :action => 'events', :profile => /#{Noosfero.identifier_format}/ |
60 | 60 | ||
61 | - # public profile information | ||
62 | - map.profile 'profile/:profile/:action/:id', :controller => 'profile', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format}/ | ||
63 | - | ||
64 | # catalog | 61 | # catalog |
65 | map.catalog 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format}/ | 62 | map.catalog 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format}/ |
66 | map.product 'catalog/:profile/:id', :controller => 'catalog', :action => 'show', :profile => /#{Noosfero.identifier_format}/ | 63 | map.product 'catalog/:profile/:id', :controller => 'catalog', :action => 'show', :profile => /#{Noosfero.identifier_format}/ |
67 | 64 | ||
65 | + # invite | ||
66 | + map.invite 'profile/:profile/invite/:action', :controller => 'invite', :profile => /#{Noosfero.identifier_format}/ | ||
67 | + | ||
68 | + # public profile information | ||
69 | + map.profile 'profile/:profile/:action/:id', :controller => 'profile', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format}/ | ||
70 | + | ||
68 | # contact | 71 | # contact |
69 | map.contact 'contact/:profile/:action/:id', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format}/ | 72 | map.contact 'contact/:profile/:action/:id', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format}/ |
70 | 73 |
db/migrate/082_add_invite_members_permission_to_admins.rb
0 → 100644
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +class AddInviteMembersPermissionToAdmins < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + Environment.all.each{ |env| | ||
4 | + admin = Profile::Roles.admin(env.id) | ||
5 | + admin.permissions += ['invite_members'] | ||
6 | + admin.save! | ||
7 | + } | ||
8 | + end | ||
9 | + | ||
10 | + def self.down | ||
11 | + Environment.all.each{ |env| | ||
12 | + admin = Profile::Roles.admin(env.id) | ||
13 | + admin.permissions -= ['invite_members'] | ||
14 | + admin.save! | ||
15 | + } | ||
16 | + end | ||
17 | +end |
db/schema.rb
@@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
9 | # | 9 | # |
10 | # It's strongly recommended to check this file into your version control system. | 10 | # It's strongly recommended to check this file into your version control system. |
11 | 11 | ||
12 | -ActiveRecord::Schema.define(:version => 81) do | 12 | +ActiveRecord::Schema.define(:version => 82) do |
13 | 13 | ||
14 | create_table "article_versions", :force => true do |t| | 14 | create_table "article_versions", :force => true do |t| |
15 | t.integer "article_id" | 15 | t.integer "article_id" |
@@ -0,0 +1,85 @@ | @@ -0,0 +1,85 @@ | ||
1 | +Feature: invitation | ||
2 | + As a noosfero visitor | ||
3 | + I want to invite my friends to Noosfero | ||
4 | + | ||
5 | + Background: | ||
6 | + Given the following users | ||
7 | + | login | | ||
8 | + | josesilva | | ||
9 | + | josesantos | | ||
10 | + And the following communities | ||
11 | + | owner | identifier | name | | ||
12 | + | josesilva | 26-bsslines | 26 Bsslines | | ||
13 | + And the following enterprises | ||
14 | + | owner | identifier | name | | ||
15 | + | josesilva | beatles-for-sale | Beatles For Sale | | ||
16 | + And I am logged in as "josesilva" | ||
17 | + | ||
18 | + Scenario: see link to invite friends | ||
19 | + When I am on /profile/josesilva/friends | ||
20 | + Then I should see "Invite people from my e-mail contacts" link | ||
21 | + | ||
22 | + Scenario: see link to invite friends in myprofile | ||
23 | + When I am on /myprofile/josesilva/friends | ||
24 | + Then I should see "Invite people from my e-mail contacts" link | ||
25 | + | ||
26 | + Scenario: go to invitation screen when follow link to invite friends | ||
27 | + Given I am on /myprofile/josesilva/friends | ||
28 | + When I follow "Invite people from my e-mail contacts" | ||
29 | + Then I am on /profile/josesilva/invite/friends | ||
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 | + # why not work? | ||
36 | + Scenario: back to manage friends after invite friends | ||
37 | + Given I am on /myprofile/josesilva/friends | ||
38 | + And I follow "Invite people from my e-mail contacts" | ||
39 | + And I press "Next" | ||
40 | + And I fill in "manual_import_addresses" with "misfits@devil.doll" | ||
41 | + And I fill in "mail_template" with "Follow this link <url>" | ||
42 | + When I press "Invite my friends!" | ||
43 | + Then I should be on /myprofile/josesilva/friends | ||
44 | + | ||
45 | + Scenario: see link to invite members to community | ||
46 | + When I am on /profile/26-bsslines/members | ||
47 | + Then I should see "Invite your friends to join 26 Bsslines" link | ||
48 | + | ||
49 | + Scenario: not see link to invite members to community if has no rights | ||
50 | + Given I am not logged in | ||
51 | + And I am logged in as "josesantos" | ||
52 | + When I am on /profile/26-bsslines/members | ||
53 | + Then I should not see "Invite your friends to join 26 Bsslines" link | ||
54 | + | ||
55 | + Scenario: go to invitation screen when follow link to invite members | ||
56 | + Given I am on /profile/26-bsslines/members | ||
57 | + When I follow "Invite your friends to join 26 Bsslines" | ||
58 | + Then I am on /profile/26-bsslines/invite/friends | ||
59 | + | ||
60 | + Scenario: see title when invite members | ||
61 | + When I am on /profile/26-bsslines/invite/friends | ||
62 | + Then I should see "Invite your friends to join 26 Bsslines" | ||
63 | + | ||
64 | + Scenario: not see link to invite members to enterprise | ||
65 | + When I am on /profile/beatles-for-sale/members | ||
66 | + Then I should not see "Invite your friends to join Beatles For Sale" link | ||
67 | + | ||
68 | + Scenario: deny access if user has no right to invite members | ||
69 | + Given I am not logged in | ||
70 | + And I am logged in as "josesantos" | ||
71 | + When I am on /profile/26-bsslines/invite/friends | ||
72 | + Then I should see "Access denied" | ||
73 | + | ||
74 | + Scenario: not see link to invite members to enterprise in manage members | ||
75 | + Given I am on /myprofile/beatles-for-sale/profile_members | ||
76 | + Then I should not see "Invite your friends to join Beatles For Sale" link | ||
77 | + | ||
78 | + Scenario: back to manage members after invite friends | ||
79 | + Given I am on /myprofile/26-bsslines/profile_members | ||
80 | + And I follow "Invite your friends to join 26 Bsslines" | ||
81 | + And I press "Next" | ||
82 | + And I fill in "manual_import_addresses" with "misfits@devil.doll" | ||
83 | + And I fill in "mail_template" with "Follow this link <url>" | ||
84 | + When I press "Invite my friends!" | ||
85 | + Then I should be on /myprofile/26-bsslines/profile_members |
public/stylesheets/controller_friends.css
@@ -12,13 +12,6 @@ | @@ -12,13 +12,6 @@ | ||
12 | padding-top: 20px; | 12 | padding-top: 20px; |
13 | } | 13 | } |
14 | 14 | ||
15 | -#friends-list { | ||
16 | - overflow: auto; | ||
17 | - height: 300px; | ||
18 | - border: 1px solid #999; | ||
19 | - margin: 5px 0px; | ||
20 | -} | ||
21 | - | ||
22 | #pagination-friends .pagination span { | 15 | #pagination-friends .pagination span { |
23 | display: inline; | 16 | display: inline; |
24 | } | 17 | } |
test/fixtures/roles.yml
@@ -40,6 +40,8 @@ profile_admin: | @@ -40,6 +40,8 @@ profile_admin: | ||
40 | name: 'Profile Administrator' | 40 | name: 'Profile Administrator' |
41 | system: true | 41 | system: true |
42 | permissions: | 42 | permissions: |
43 | + - invite_members | ||
44 | + - manage_memberships | ||
43 | - edit_profile_design | 45 | - edit_profile_design |
44 | - edit_profile | 46 | - edit_profile |
45 | - moderate_comments | 47 | - moderate_comments |
test/functional/friends_controller_test.rb
@@ -75,93 +75,4 @@ class FriendsControllerTest < Test::Unit::TestCase | @@ -75,93 +75,4 @@ class FriendsControllerTest < Test::Unit::TestCase | ||
75 | assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/assets/people' } | 75 | assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/assets/people' } |
76 | end | 76 | end |
77 | 77 | ||
78 | - should 'display invitation page' do | ||
79 | - get :invite | ||
80 | - assert_response :success | ||
81 | - assert_template 'invite' | ||
82 | - end | ||
83 | - | ||
84 | - should 'actualy invite manually added addresses with name and e-mail' do | ||
85 | - assert_difference InviteFriend, :count, 1 do | ||
86 | - post :invite, :manual_import_addresses => "Test Name <test@test.com>", :import_from => "manual", :message => "click: <url>", :confirmation => 1 | ||
87 | - assert_redirected_to :action => 'index' | ||
88 | - end | ||
89 | - end | ||
90 | - | ||
91 | - should 'actualy invite manually added addresses with name and e-mail on wizard' do | ||
92 | - assert_difference InviteFriend, :count, 1 do | ||
93 | - post :invite, :manual_import_addresses => "Test Name <test@test.com>", :import_from => "manual", :message => "click: <url>", :confirmation => 1, :wizard => true | ||
94 | - assert_redirected_to :action => 'invite', :wizard => true | ||
95 | - end | ||
96 | - end | ||
97 | - | ||
98 | - should 'actually invite manually added address with only e-mail' do | ||
99 | - assert_difference InviteFriend, :count, 1 do | ||
100 | - post :invite, :manual_import_addresses => "test@test.com", :import_from => "manual", :message => "click: <url>", :confirmation => 1 | ||
101 | - assert_redirected_to :action => 'index' | ||
102 | - end | ||
103 | - end | ||
104 | - | ||
105 | - should 'actually invite manually added address with only e-mail on wizard' do | ||
106 | - assert_difference InviteFriend, :count, 1 do | ||
107 | - post :invite, :manual_import_addresses => "test@test.com", :import_from => "manual", :message => "click: <url>", :confirmation => 1, :wizard => true | ||
108 | - assert_redirected_to :action => 'invite', :wizard => true | ||
109 | - end | ||
110 | - end | ||
111 | - | ||
112 | - should 'actually invite manually added addresses with e-mail and other format' do | ||
113 | - assert_difference InviteFriend, :count, 1 do | ||
114 | - post :invite, :manual_import_addresses => "test@test.cz.com", :import_from => "manual", :message => "click: <url>", :confirmation => 1 | ||
115 | - assert_redirected_to :action => 'index' | ||
116 | - end | ||
117 | - end | ||
118 | - | ||
119 | - should 'actually invite manually added addresses with e-mail and other format on wizard' do | ||
120 | - assert_difference InviteFriend, :count, 1 do | ||
121 | - post :invite, :manual_import_addresses => "test@test.cz.com", :import_from => "manual", :message => "click: <url>", :confirmation => 1, :wizard => true | ||
122 | - assert_redirected_to :action => 'invite', :wizard => true | ||
123 | - end | ||
124 | - end | ||
125 | - | ||
126 | - should 'actually invite manually added address with friend object' do | ||
127 | - assert_difference InviteFriend, :count, 1 do | ||
128 | - post :invite, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :message => "click: <url>", :confirmation => 1 | ||
129 | - assert_redirected_to :action => 'index' | ||
130 | - end | ||
131 | - end | ||
132 | - | ||
133 | - should 'actually invite manually added address with friend object on wizard' do | ||
134 | - assert_difference InviteFriend, :count, 1 do | ||
135 | - post :invite, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :message => "click: <url>", :confirmation => 1, :wizard => true | ||
136 | - assert_redirected_to :action => 'invite', :wizard => true | ||
137 | - end | ||
138 | - end | ||
139 | - | ||
140 | - should 'actually invite more than one manually added addres' do | ||
141 | - assert_difference InviteFriend, :count, 2 do | ||
142 | - post :invite, :manual_import_addresses => "Some Friend <somefriend@email.com>\r\notherperson@bleble.net\r\n", :import_from => "manual", :message => "click: <url>", :confirmation => 1 | ||
143 | - assert_redirected_to :action => 'index' | ||
144 | - end | ||
145 | - end | ||
146 | - | ||
147 | - should 'actually invite more than one manually added addres on wizard' do | ||
148 | - assert_difference InviteFriend, :count, 2 do | ||
149 | - post :invite, :manual_import_addresses => "Some Friend <somefriend@email.com>\r\notherperson@bleble.net\r\n", :import_from => "manual", :message => "click: <url>", :confirmation => 1, :wizard => true | ||
150 | - assert_redirected_to :action => 'invite', :wizard => true | ||
151 | - end | ||
152 | - end | ||
153 | - | ||
154 | - should 'not invite yourself' do | ||
155 | - assert_no_difference InviteFriend, :count do | ||
156 | - post :invite, :manual_import_addresses => "#{profile.name} <#{profile.user.email}>", :import_from => "manual", :message => "click: <url>", :confirmation => 1, :wizard => true | ||
157 | - end | ||
158 | - end | ||
159 | - | ||
160 | - should 'not create InviteFriend if is a friend' do | ||
161 | - friend = create_user('testfriend', :email => 'friend@noosfero.org') | ||
162 | - friend.person.add_friend(profile) | ||
163 | - assert_no_difference InviteFriend, :count do | ||
164 | - post :invite, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :message => "click: <url>", :confirmation => 1, :wizard => true | ||
165 | - end | ||
166 | - end | ||
167 | end | 78 | end |
@@ -0,0 +1,86 @@ | @@ -0,0 +1,86 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class InviteControllerTest < ActionController::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + @profile = create_user('testuser').person | ||
7 | + @friend = create_user('thefriend').person | ||
8 | + @community = fast_create(Community) | ||
9 | + login_as ('testuser') | ||
10 | + end | ||
11 | + attr_accessor :profile, :friend, :community | ||
12 | + | ||
13 | + should 'actually invite manually added address with friend object' do | ||
14 | + assert_difference InviteFriend, :count, 1 do | ||
15 | + post :friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :step => 2 | ||
16 | + assert_redirected_to :controller => 'profile' | ||
17 | + end | ||
18 | + end | ||
19 | + | ||
20 | + should 'actually invite manually added address with only e-mail' do | ||
21 | + assert_difference InviteFriend, :count, 1 do | ||
22 | + post :friends, :profile => profile.identifier, :manual_import_addresses => "test@test.com", :import_from => "manual", :mail_template => "click: <url>", :step => 2 | ||
23 | + end | ||
24 | + end | ||
25 | + | ||
26 | + should 'actually invite manually added addresses with e-mail and other format' do | ||
27 | + assert_difference InviteFriend, :count, 1 do | ||
28 | + post :friends, :profile => profile.identifier, :manual_import_addresses => "test@test.cz.com", :import_from => "manual", :mail_template => "click: <url>", :step => 2 | ||
29 | + end | ||
30 | + end | ||
31 | + | ||
32 | + should 'actually invite more than one manually added address' do | ||
33 | + assert_difference InviteFriend, :count, 2 do | ||
34 | + post :friends, :profile => profile.identifier, :manual_import_addresses => "Some Friend <somefriend@email.com>\r\notherperson@bleble.net\r\n", :import_from => "manual", :mail_template => "click: <url>", :step => 2 | ||
35 | + end | ||
36 | + end | ||
37 | + | ||
38 | + should 'actualy invite manually added addresses with name and e-mail' do | ||
39 | + assert_difference InviteFriend, :count, 1 do | ||
40 | + post :friends, :profile => profile.identifier, :manual_import_addresses => "Test Name <test@test.com>", :import_from => "manual", :mail_template => "click: <url>", :step => 2 | ||
41 | + end | ||
42 | + end | ||
43 | + | ||
44 | + should 'not invite yourself' do | ||
45 | + assert_no_difference InviteFriend, :count do | ||
46 | + post :friends, :profile => profile.identifier, :manual_import_addresses => "#{profile.name} <#{profile.user.email}>", :import_from => "manual", :mail_template => "click: <url>", :step => 2 | ||
47 | + end | ||
48 | + end | ||
49 | + | ||
50 | + should 'not invite if already a friend' do | ||
51 | + friend = create_user('testfriend', :email => 'friend@noosfero.org') | ||
52 | + friend.person.add_friend(profile) | ||
53 | + assert_no_difference InviteFriend, :count do | ||
54 | + post :friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :step => 2 | ||
55 | + end | ||
56 | + end | ||
57 | + | ||
58 | + should 'display invitation page' do | ||
59 | + get :friends, :profile => profile.identifier | ||
60 | + assert_response :success | ||
61 | + assert_tag :tag => 'h1', :content => 'Invite your friends' | ||
62 | + end | ||
63 | + | ||
64 | + should 'get mail template to invite members' do | ||
65 | + community.add_admin(profile) | ||
66 | + get :friends, :profile => community.identifier | ||
67 | + assert_equal InviteMember.mail_template, assigns(:mail_template) | ||
68 | + end | ||
69 | + | ||
70 | + should 'get mail template to invite friends' do | ||
71 | + community.add_admin(profile) | ||
72 | + get :friends, :profile => profile.identifier | ||
73 | + assert_equal InviteFriend.mail_template, assigns(:mail_template) | ||
74 | + end | ||
75 | + | ||
76 | + should 'deny if user has no rights to invite members' do | ||
77 | + get :friends, :profile => community.identifier | ||
78 | + assert_response 403 # forbidden | ||
79 | + end | ||
80 | + | ||
81 | + should 'deny access when trying to invite friends to another user' do | ||
82 | + get :friends, :profile => friend.identifier | ||
83 | + assert_response 403 # forbidden | ||
84 | + end | ||
85 | + | ||
86 | +end |
test/unit/environment_test.rb
@@ -587,19 +587,32 @@ class EnvironmentTest < Test::Unit::TestCase | @@ -587,19 +587,32 @@ class EnvironmentTest < Test::Unit::TestCase | ||
587 | assert_equal ['birth_date'], env.required_person_fields | 587 | assert_equal ['birth_date'], env.required_person_fields |
588 | end | 588 | end |
589 | 589 | ||
590 | - should 'provide a default invitation message' do | ||
591 | - env = Environment.new | 590 | + should 'provide a default invitation message for friend' do |
591 | + env = Environment.default | ||
592 | message = [ | 592 | message = [ |
593 | 'Hello <friend>,', | 593 | 'Hello <friend>,', |
594 | - "<user> is inviting you to participate on #{env.name}.", | ||
595 | - 'To accept the invitation, please follow this link:' + "\n" + '<url>', | ||
596 | - "--\n#{env.name}", | ||
597 | - '' | 594 | + "<user> is inviting you to participate on <environment>.", |
595 | + 'To accept the invitation, please follow this link:', | ||
596 | + '<url>', | ||
597 | + "--\n<environment>", | ||
598 | ].join("\n\n") | 598 | ].join("\n\n") |
599 | 599 | ||
600 | assert_equal message, env.message_for_friend_invitation | 600 | assert_equal message, env.message_for_friend_invitation |
601 | end | 601 | end |
602 | 602 | ||
603 | + should 'provide a default invitation message for member' do | ||
604 | + env = Environment.default | ||
605 | + message = [ | ||
606 | + 'Hello <friend>,', | ||
607 | + "<user> is inviting you to participate of <community> on <environment>.", | ||
608 | + 'To accept the invitation, please follow this link:', | ||
609 | + '<url>', | ||
610 | + "--\n<environment>", | ||
611 | + ].join("\n\n") | ||
612 | + | ||
613 | + assert_equal message, env.message_for_member_invitation | ||
614 | + end | ||
615 | + | ||
603 | should 'set custom_enterprises_fields' do | 616 | should 'set custom_enterprises_fields' do |
604 | env = Environment.new | 617 | env = Environment.new |
605 | env.custom_enterprise_fields = {'contact_person' => {'required' => 'true', 'active' => 'true'},'contact_email'=> {'required' => 'true', 'active' => 'true'}} | 618 | env.custom_enterprise_fields = {'contact_person' => {'required' => 'true', 'active' => 'true'},'contact_email'=> {'required' => 'true', 'active' => 'true'}} |
@@ -841,4 +854,18 @@ class EnvironmentTest < Test::Unit::TestCase | @@ -841,4 +854,18 @@ class EnvironmentTest < Test::Unit::TestCase | ||
841 | assert_equal [], Environment.new.local_docs | 854 | assert_equal [], Environment.new.local_docs |
842 | end | 855 | end |
843 | 856 | ||
857 | + should 'provide right invitation mail template for friends' do | ||
858 | + env = Environment.default | ||
859 | + person = Person.new | ||
860 | + | ||
861 | + assert_equal env.message_for_friend_invitation, env.invitation_mail_template(person) | ||
862 | + end | ||
863 | + | ||
864 | + should 'provide right invitation mail template for members' do | ||
865 | + env = Environment.default | ||
866 | + community = Community.new | ||
867 | + | ||
868 | + assert_equal env.message_for_member_invitation, env.invitation_mail_template(community) | ||
869 | + end | ||
870 | + | ||
844 | end | 871 | end |
@@ -0,0 +1,62 @@ | @@ -0,0 +1,62 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class InvitationTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + should 'expand message' do | ||
6 | + invitation = Invitation.new( | ||
7 | + :person => Person.new(:name => 'Sadam', :environment => Environment.new(:name => 'AnarquiaOi')), | ||
8 | + :friend_name => 'Fernandinho', | ||
9 | + :message => 'Hi <friend>, <user> is inviting you to <environment>!' | ||
10 | + ) | ||
11 | + assert_equal 'Hi Fernandinho, Sadam is inviting you to AnarquiaOi!', invitation.expanded_message | ||
12 | + end | ||
13 | + | ||
14 | + should 'require subclasses implement mail_template method' do | ||
15 | + assert_raise RuntimeError do | ||
16 | + Invitation.new.mail_template | ||
17 | + end | ||
18 | + end | ||
19 | + | ||
20 | + should 'join string contacts with array contacts' do | ||
21 | + string_contacts = "sadam@garotos\nfernandinho@garotos\roi@garotos" | ||
22 | + array_contacts = ['casiotone@gengivas.negras'] | ||
23 | + | ||
24 | + assert_equal ['sadam@garotos', 'fernandinho@garotos', 'oi@garotos', 'casiotone@gengivas.negras'], | ||
25 | + Invitation.join_contacts(string_contacts, array_contacts) | ||
26 | + end | ||
27 | + | ||
28 | + should 'raises when try get contacts from unknown source' do | ||
29 | + assert_raise NotImplementedError do | ||
30 | + Invitation.get_contacts('ze', 'ze12', 'bli-mail') | ||
31 | + end | ||
32 | + end | ||
33 | + | ||
34 | + should 'not know how to invite members to non-community' do | ||
35 | + person = fast_create(Person) | ||
36 | + enterprise = fast_create(Enterprise) | ||
37 | + | ||
38 | + assert_raise NotImplementedError do | ||
39 | + Invitation.invite(person, ['sadam@garotos.podres'], 'hello friend', enterprise) | ||
40 | + end | ||
41 | + end | ||
42 | + | ||
43 | + should 'create right task when invite friends' do | ||
44 | + person = fast_create(Person) | ||
45 | + person.user = User.new(:email => 'current_user@email.invalid') | ||
46 | + | ||
47 | + assert_difference InviteFriend, :count do | ||
48 | + Invitation.invite(person, ['sadam@garotos.podres'], 'hello friend <url>', person) | ||
49 | + end | ||
50 | + end | ||
51 | + | ||
52 | + should 'create right task when invite members to community' do | ||
53 | + person = fast_create(Person) | ||
54 | + person.user = User.new(:email => 'current_user@email.invalid') | ||
55 | + community = fast_create(Community) | ||
56 | + | ||
57 | + assert_difference InviteMember, :count do | ||
58 | + Invitation.invite(person, ['sadam@garotos.podres'], 'hello friend <url>', community) | ||
59 | + end | ||
60 | + end | ||
61 | + | ||
62 | +end |
@@ -0,0 +1,112 @@ | @@ -0,0 +1,112 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class InviteMemberTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + should 'be a task' do | ||
6 | + ok { InviteMember.new.kind_of?(Task) } | ||
7 | + end | ||
8 | + | ||
9 | + should 'actually add as member when confirmed' do | ||
10 | + person = fast_create(Person) | ||
11 | + friend = fast_create(Person) | ||
12 | + friend.stubs(:user).returns(User.new(:email => 'garotos@podres.punk.oi')) | ||
13 | + person.stubs(:user).returns(User.new(:email => 'suburbio-operario@podres.podres')) | ||
14 | + community = fast_create(Community) | ||
15 | + | ||
16 | + assert_equal [], community.members | ||
17 | + | ||
18 | + task = InviteMember.create!(:person => person, :friend => friend, :community_id => community.id) | ||
19 | + task.finish | ||
20 | + community.reload | ||
21 | + | ||
22 | + ok('friend is member of community') { community.members.include?(friend) } | ||
23 | + end | ||
24 | + | ||
25 | + should 'require community (person inviting other to be a member)' do | ||
26 | + task = InviteMember.new | ||
27 | + task.valid? | ||
28 | + | ||
29 | + ok('community is required') { task.errors.invalid?(:community_id) } | ||
30 | + end | ||
31 | + | ||
32 | + should 'require friend email if no target given (person being invited)' do | ||
33 | + task = InviteMember.new | ||
34 | + task.valid? | ||
35 | + | ||
36 | + ok('friend_email is required') { task.errors.invalid?(:friend_email) } | ||
37 | + end | ||
38 | + | ||
39 | + should 'dont require friend email if target given (person being invited)' do | ||
40 | + task = InviteMember.new(:target => create_user('testuser2').person) | ||
41 | + task.valid? | ||
42 | + | ||
43 | + ok('friend_email isnt required') { !task.errors.invalid?(:friend_email) } | ||
44 | + end | ||
45 | + | ||
46 | + should 'require target (person being invited) if no friend email given' do | ||
47 | + task = InviteMember.new | ||
48 | + task.valid? | ||
49 | + | ||
50 | + ok('target is required') { task.errors.invalid?(:target_id) } | ||
51 | + end | ||
52 | + | ||
53 | + should 'dont require target (person being invited) if friend email given' do | ||
54 | + task = InviteMember.new(:friend_email => "test@test.com") | ||
55 | + task.valid? | ||
56 | + | ||
57 | + ok('target isn required') { !task.errors.invalid?(:target_id) } | ||
58 | + end | ||
59 | + | ||
60 | + should 'not send e-mails to requestor' do | ||
61 | + p1 = create_user('testuser1').person | ||
62 | + p2 = create_user('testuser2').person | ||
63 | + | ||
64 | + TaskMailer.expects(:deliver_task_finished).never | ||
65 | + TaskMailer.expects(:deliver_task_created).never | ||
66 | + | ||
67 | + task = InviteMember.create!(:person => p1, :friend => p2, :community_id => fast_create(Community).id) | ||
68 | + task.finish | ||
69 | + end | ||
70 | + | ||
71 | + should 'send e-mails to friend if friend_email given' do | ||
72 | + p1 = create_user('testuser1').person | ||
73 | + | ||
74 | + TaskMailer.expects(:deliver_invitation_notification).once | ||
75 | + | ||
76 | + task = InviteMember.create!(:person => p1, :friend_email => 'test@test.com', :message => '<url>', :community_id => fast_create(Community).id) | ||
77 | + end | ||
78 | + | ||
79 | + should 'not send e-mails to friend if target given (person being invited)' do | ||
80 | + p1 = create_user('testuser1').person | ||
81 | + p2 = create_user('testuser2').person | ||
82 | + | ||
83 | + TaskMailer.expects(:deliver_invitation_notification).never | ||
84 | + | ||
85 | + task = InviteMember.create!(:person => p1, :friend => p2, :community_id => fast_create(Community).id) | ||
86 | + end | ||
87 | + | ||
88 | + should 'provide proper description' do | ||
89 | + p1 = create_user('testuser1').person | ||
90 | + p2 = create_user('testuser2').person | ||
91 | + | ||
92 | + TaskMailer.expects(:deliver_task_finished).never | ||
93 | + TaskMailer.expects(:deliver_task_created).never | ||
94 | + | ||
95 | + community = fast_create(Community) | ||
96 | + task = InviteMember.create!(:person => p1, :friend => p2, :community_id => community.id) | ||
97 | + | ||
98 | + assert_equal "#{p1.name} invites you to join the community #{community.name}.", task.description | ||
99 | + end | ||
100 | + | ||
101 | + should 'not invite yourself' do | ||
102 | + p = create_user('testuser1').person | ||
103 | + | ||
104 | + task1 = InviteMember.new(:person => p, :friend => p, :message => 'click here: <url>') | ||
105 | + assert !task1.save | ||
106 | + | ||
107 | + task2 = InviteMember.new(:person => p, :friend_name => 'Myself', :friend_email => p.user.email, :message => 'click here: <url>') | ||
108 | + assert !task2.save | ||
109 | + end | ||
110 | + | ||
111 | +end | ||
112 | + |
test/unit/task_mailer_test.rb
@@ -124,6 +124,7 @@ class TaskMailerTest < Test::Unit::TestCase | @@ -124,6 +124,7 @@ class TaskMailerTest < Test::Unit::TestCase | ||
124 | environment.expects(:name).returns('example').at_least_once | 124 | environment.expects(:name).returns('example').at_least_once |
125 | 125 | ||
126 | task.expects(:requestor).returns(requestor).at_least_once | 126 | task.expects(:requestor).returns(requestor).at_least_once |
127 | + task.expects(:person).returns(requestor).at_least_once | ||
127 | requestor.expects(:environment).returns(environment).at_least_once | 128 | requestor.expects(:environment).returns(environment).at_least_once |
128 | 129 | ||
129 | mail = TaskMailer.create_invitation_notification(task) | 130 | mail = TaskMailer.create_invitation_notification(task) |