Commit f24ef96b5e31111336817652222605c0b862debb
Committed by
Antonio Terceiro
1 parent
1f75d111
Exists in
master
and in
29 other branches
ActionItem910: Integration of feature "invite a friend"
Showing
16 changed files
with
454 additions
and
0 deletions
Show diff stats
app/controllers/my_profile/friends_controller.rb
1 | +require "contacts" | ||
2 | + | ||
1 | class FriendsController < MyProfileController | 3 | class FriendsController < MyProfileController |
2 | 4 | ||
3 | protect 'manage_friends', :profile | 5 | protect 'manage_friends', :profile |
@@ -26,4 +28,69 @@ class FriendsController < MyProfileController | @@ -26,4 +28,69 @@ class FriendsController < MyProfileController | ||
26 | end | 28 | end |
27 | end | 29 | end |
28 | 30 | ||
31 | + def invite | ||
32 | + | ||
33 | + if request.post? && params[:import] | ||
34 | + begin | ||
35 | + case params[:import_from] | ||
36 | + when "gmail" | ||
37 | + @friends = Contacts::Gmail.new(params[:login], params[:password]).contacts | ||
38 | + when "yahoo" | ||
39 | + @friends = Contacts::Yahoo.new(params[:login], params[:password]).contacts | ||
40 | + when "hotmail" | ||
41 | + @friends = Contacts::Hotmail.new(params[:login], params[:password]).contacts | ||
42 | + else | ||
43 | + @friends = [] | ||
44 | + end | ||
45 | + @friends.map! {|friend| friend + ["#{friend[0]} <#{friend[1]}>"]} | ||
46 | + rescue | ||
47 | + @login = params[:login] | ||
48 | + flash.now[:notice] = __('There was an error while looking for your contact list. Did you enter correct login and password?') | ||
49 | + end | ||
50 | + | ||
51 | + elsif request.post? && params[:confirmation] | ||
52 | + friends_to_invite = [] | ||
53 | + 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] | ||
54 | + 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] | ||
55 | + | ||
56 | + if !params[:message].match(/<url>/) | ||
57 | + flash.now[:notice] = __('<url> is needed in invitation message.') | ||
58 | + elsif !friends_to_invite.empty? | ||
59 | + friends_to_invite.each do |friend_to_invite| | ||
60 | + next if friend_to_invite == __("Firstname Lastname <friend@email.com>") | ||
61 | + | ||
62 | + friend_to_invite.strip! | ||
63 | + if match = friend_to_invite.match(/(.*)<(.*)>/) and match[2].match(Noosfero::Constants::EMAIL_FORMAT) | ||
64 | + friend_name = match[1].strip | ||
65 | + friend_email = match[2] | ||
66 | + elsif match = friend_to_invite.strip.match(Noosfero::Constants::EMAIL_FORMAT) | ||
67 | + friend_name = "" | ||
68 | + friend_email = match[0] | ||
69 | + else | ||
70 | + next | ||
71 | + end | ||
72 | + | ||
73 | + friend = User.find_by_email(friend_email) | ||
74 | + if !friend.nil? && friend.person.person? | ||
75 | + InviteFriend.create(:person => profile, :friend => friend.person) | ||
76 | + else | ||
77 | + InviteFriend.create(:person => profile, :friend_name => friend_name, :friend_email => friend_email, :message => params[:message]) | ||
78 | + end | ||
79 | + end | ||
80 | + | ||
81 | + flash[:notice] = __('Your invitations have been sent.') | ||
82 | + redirect_to :action => 'index' | ||
83 | + else | ||
84 | + flash.now[:notice] = __('Please enter a valid email address.') | ||
85 | + end | ||
86 | + | ||
87 | + @friends = params[:webmail_friends] ? params[:webmail_friends].map {|e| YAML.load(e)} : [] | ||
88 | + @manual_import_addresses = params[:manual_import_addresses] || "" | ||
89 | + @webmail_import_addresses = params[:webmail_import_addresses] || [] | ||
90 | + end | ||
91 | + | ||
92 | + @import_from = params[:import_from] || "manual" | ||
93 | + @message = params[:message] || environment.message_for_friend_invitation | ||
94 | + end | ||
95 | + | ||
29 | end | 96 | end |
app/controllers/public/account_controller.rb
@@ -42,6 +42,7 @@ class AccountController < ApplicationController | @@ -42,6 +42,7 @@ class AccountController < ApplicationController | ||
42 | 42 | ||
43 | # action to register an user to the application | 43 | # action to register an user to the application |
44 | def signup | 44 | def signup |
45 | + @invitation_code = params[:invitation_code] | ||
45 | begin | 46 | begin |
46 | @user = User.new(params[:user]) | 47 | @user = User.new(params[:user]) |
47 | @user.terms_of_use = environment.terms_of_use | 48 | @user.terms_of_use = environment.terms_of_use |
@@ -54,6 +55,11 @@ class AccountController < ApplicationController | @@ -54,6 +55,11 @@ class AccountController < ApplicationController | ||
54 | self.current_user = @user | 55 | self.current_user = @user |
55 | owner_role = Role.find_by_name('owner') | 56 | owner_role = Role.find_by_name('owner') |
56 | @user.person.affiliate(@user.person, [owner_role]) if owner_role | 57 | @user.person.affiliate(@user.person, [owner_role]) if owner_role |
58 | + invitation = Task.find_by_code(@invitation_code) | ||
59 | + if invitation | ||
60 | + invitation.update_attributes!({:friend => @user.person}) | ||
61 | + invitation.finish | ||
62 | + end | ||
57 | go_to_user_initial_page if redirect? | 63 | go_to_user_initial_page if redirect? |
58 | flash[:notice] = _("Thanks for signing up!") | 64 | flash[:notice] = _("Thanks for signing up!") |
59 | end | 65 | end |
app/models/environment.rb
@@ -280,6 +280,21 @@ class Environment < ActiveRecord::Base | @@ -280,6 +280,21 @@ class Environment < ActiveRecord::Base | ||
280 | signup_fields | 280 | signup_fields |
281 | end | 281 | end |
282 | 282 | ||
283 | + # Default message send to friend when user use invite a friend feature | ||
284 | + def message_for_friend_invitation | ||
285 | + self.settings['message_for_friend_invitation'] || [ | ||
286 | + _('Hello <friend>,'), | ||
287 | + _('<user> is inviting you to participate on %{environment}.') % { :environment => self.name }, | ||
288 | + _('To accept the invitation, please follow this link:') + "\n" + '<url>', | ||
289 | + "--\n#{self.name}", | ||
290 | + '' | ||
291 | + ].join("\n\n") | ||
292 | + end | ||
293 | + | ||
294 | + def message_for_friend_invitation=(value) | ||
295 | + self.settings['message_for_friend_invitation'] = value | ||
296 | + end | ||
297 | + | ||
283 | def custom_enterprise_fields | 298 | def custom_enterprise_fields |
284 | self.settings[:custom_enterprise_fields].nil? ? {} : self.settings[:custom_enterprise_fields] | 299 | self.settings[:custom_enterprise_fields].nil? ? {} : self.settings[:custom_enterprise_fields] |
285 | end | 300 | end |
@@ -0,0 +1,43 @@ | @@ -0,0 +1,43 @@ | ||
1 | +class InviteFriend < Task | ||
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 perform | ||
26 | + requestor.add_friend(target, group_for_person) | ||
27 | + target.add_friend(requestor, group_for_friend) | ||
28 | + end | ||
29 | + | ||
30 | + # Returns <tt>false</tt>. Adding friends by itself does not trigger e-mail | ||
31 | + # sending. | ||
32 | + def sends_email? | ||
33 | + false | ||
34 | + end | ||
35 | + | ||
36 | + def description | ||
37 | + _('%s wants to be your friend') % [requestor.name] | ||
38 | + end | ||
39 | + | ||
40 | + def permission | ||
41 | + :manage_friends | ||
42 | + end | ||
43 | +end |
app/models/task_mailer.rb
@@ -24,6 +24,19 @@ class TaskMailer < ActionMailer::Base | @@ -24,6 +24,19 @@ class TaskMailer < ActionMailer::Base | ||
24 | :tasks_url => url_for(task.target.url.merge(:controller => 'tasks', :action => 'index')) | 24 | :tasks_url => url_for(task.target.url.merge(:controller => 'tasks', :action => 'index')) |
25 | end | 25 | end |
26 | 26 | ||
27 | + def invitation_notification(task) | ||
28 | + msg = task.message | ||
29 | + msg = msg.gsub(/<user>/, task.requestor.name) | ||
30 | + msg = msg.gsub(/<friend>/, task.friend_name) | ||
31 | + msg = msg.gsub(/<url>/, url_for(:host => task.requestor.environment.default_hostname, :controller => 'account', :action => 'signup', :invitation_code => task.code)) | ||
32 | + | ||
33 | + recipients task.friend_email | ||
34 | + | ||
35 | + from self.class.generate_from(task) | ||
36 | + subject '[%s] %s' % [ task.requestor.environment.name, task.description ] | ||
37 | + body :message => msg | ||
38 | + end | ||
39 | + | ||
27 | protected | 40 | protected |
28 | 41 | ||
29 | def extract_message(message) | 42 | def extract_message(message) |
app/views/account/_signup_form.rhtml
@@ -14,6 +14,8 @@ in this environment.') % [environment.name, __('communities'), __('enterprises') | @@ -14,6 +14,8 @@ in this environment.') % [environment.name, __('communities'), __('enterprises') | ||
14 | :html => { :help=>_('Fill all this fields to join in this environment. <p/> If you forgot your password, do not create a new account, click on the "<b>I forgot my password!</b>" link. ;-)'), :id => 'profile-data' | 14 | :html => { :help=>_('Fill all this fields to join in this environment. <p/> If you forgot your password, do not create a new account, click on the "<b>I forgot my password!</b>" link. ;-)'), :id => 'profile-data' |
15 | } do |f| -%> | 15 | } do |f| -%> |
16 | 16 | ||
17 | +<%= hidden_field_tag :invitation_code, @invitation_code %> | ||
18 | + | ||
17 | <%= required_fields_message %> | 19 | <%= required_fields_message %> |
18 | 20 | ||
19 | <%= required f.text_field(:login, | 21 | <%= required f.text_field(:login, |
app/views/friends/index.rhtml
@@ -37,6 +37,7 @@ | @@ -37,6 +37,7 @@ | ||
37 | <% button_bar do %> | 37 | <% button_bar do %> |
38 | <%= button(:back, _('Go back'), :controller => 'profile_editor') %> | 38 | <%= button(:back, _('Go back'), :controller => 'profile_editor') %> |
39 | <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %> | 39 | <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %> |
40 | + <%= button(:search, _('Invite friends from my e-mail contacts'), :action => 'invite') %> | ||
40 | <% end %> | 41 | <% end %> |
41 | 42 | ||
42 | </div><!-- end id="manage_friends" --> | 43 | </div><!-- end id="manage_friends" --> |
@@ -0,0 +1,83 @@ | @@ -0,0 +1,83 @@ | ||
1 | +<h1><%= __('Invite your friends') %></h1> | ||
2 | + | ||
3 | + | ||
4 | +<% unless @friends %> | ||
5 | + | ||
6 | + <h2><%= __('Step 1 of 1: Accessing your contact list') %></h2> | ||
7 | + | ||
8 | + <p> | ||
9 | + <%= __('Choose your webmail provider and enter your login and password so we can fetch your contact list. If you only want to invite specific people by listing their e-mail addresses, select the "Enter e-mail addresses manually" option.') %> | ||
10 | + </p> | ||
11 | + | ||
12 | + <% form_tag do %> | ||
13 | + <%= hidden_field_tag(:import, 1) %> | ||
14 | + | ||
15 | + <%= labelled_form_field(_('Select your e-mail provider:'), [ | ||
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 | + radio_button_tag(:import_from, "manual", @import_from == "manual", :onclick => 'hide_invite_friend_login_password()') + content_tag('label', __('Enter e-mail addresses manually'), :for => "import_from_manual") | ||
20 | + ].join("\n<br/>\n")) %> | ||
21 | + | ||
22 | + <script type="text/javascript"> | ||
23 | + function hide_invite_friend_login_password() { | ||
24 | + $('invite-friends-login-password').hide(); | ||
25 | + } | ||
26 | + function show_invite_friend_login_password() { | ||
27 | + $('invite-friends-login-password').show(); | ||
28 | + $('login').focus(); | ||
29 | + } | ||
30 | + </script> | ||
31 | + <div id='invite-friends-login-password' <%= "style='display: none;'" if (@import_from == 'manual') %>> | ||
32 | + <%= labelled_form_field(__("Login:"), text_field_tag(:login, @login)) %> | ||
33 | + <%= labelled_form_field(__("Password:"), password_field_tag(:password)) %> | ||
34 | + </div> | ||
35 | + | ||
36 | + <% button_bar do %> | ||
37 | + <%= submit_button(:forward, __("Next")) %> | ||
38 | + <% end %> | ||
39 | + <p><%= __("We won't store your password or contact anyone without your permission.")%></p> | ||
40 | + | ||
41 | + <% end %> | ||
42 | + | ||
43 | +<% else %> | ||
44 | + | ||
45 | + <h2><%= __('Step 2 of 2: Selecting Friends') %></h2> | ||
46 | + <p> | ||
47 | + <%= __('Indicate which friends you want to invite.') %> | ||
48 | + </p> | ||
49 | + | ||
50 | + <% form_tag do %> | ||
51 | + <%= hidden_field_tag(:confirmation, 1) %> | ||
52 | + <%= hidden_field_tag(:import_from, @import_from) %> | ||
53 | + | ||
54 | + <div> | ||
55 | + <%= __("Enter one e-mail address per line, following the example below.")%> | ||
56 | + <%= labelled_form_field(__('E-mail addresses'), text_area_tag(:manual_import_addresses, (@manual_import_addresses || __("Firstname Lastname <friend@email.com>")), :cols => 72, :rows => 5)) %> | ||
57 | + </div> | ||
58 | + <% if @import_from != 'manual' %> | ||
59 | + <div> | ||
60 | + <%= link_to_function __('Check all'), "$$('input.friend_to_invite').each(function(checkbox) { checkbox.checked = true; });" %> | ||
61 | + <%= link_to_function __('Uncheck all'), "$$('input.friend_to_invite').each(function(checkbox) { checkbox.checked = false; });" %> | ||
62 | + <% friend_pos = 0 %> | ||
63 | + <% @friends.each do |friend| %> | ||
64 | + <% friend_pos += 1 %> | ||
65 | + <p> | ||
66 | + <%= hidden_field_tag("webmail_friends[]", friend.to_yaml) %> | ||
67 | + <%= 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> | ||
68 | + </p> | ||
69 | + <% end %> | ||
70 | + </div> | ||
71 | + <% end -%> | ||
72 | + | ||
73 | + <div> | ||
74 | + <%= 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.") %> | ||
75 | + <%= labelled_form_field(__('Invitation message'), text_area_tag(:message, @message, :cols => 72, :rows => 8)) %> | ||
76 | + </div> | ||
77 | + | ||
78 | + <% button_bar do %> | ||
79 | + <%= submit_button(:ok, __("Invite my friends!")) %> | ||
80 | + <% end %> | ||
81 | + <% end %> | ||
82 | + | ||
83 | +<% end %> |
app/views/profile/friends.rhtml
@@ -10,6 +10,9 @@ | @@ -10,6 +10,9 @@ | ||
10 | </ul> | 10 | </ul> |
11 | 11 | ||
12 | <% button_bar do %> | 12 | <% button_bar do %> |
13 | + <% if user == profile %> | ||
14 | + <%= button :edit, _('Manage my friends'), :controller => 'friends', :action => 'index', :profile => profile.identifier %> | ||
15 | + <% end %> | ||
13 | <%= button :back, _('Go back'), { :controller => 'profile' }, | 16 | <%= button :back, _('Go back'), { :controller => 'profile' }, |
14 | :help => _('Back to the page where you come from.') %> | 17 | :help => _('Back to the page where you come from.') %> |
15 | <% end %> | 18 | <% end %> |
doc/README_FOR_APP.en
@@ -20,6 +20,7 @@ You need to have a Subversion client (svn) installed, as well as: | @@ -20,6 +20,7 @@ You need to have a Subversion client (svn) installed, as well as: | ||
20 | * RedCloth: http://whytheluckystiff.net/ruby/redcloth/ | 20 | * RedCloth: http://whytheluckystiff.net/ruby/redcloth/ |
21 | * Ruby Locale: http://rubyforge.org/projects/locale/ | 21 | * Ruby Locale: http://rubyforge.org/projects/locale/ |
22 | * will_paginate: http://github.com/mislav/will_paginate/wikis | 22 | * will_paginate: http://github.com/mislav/will_paginate/wikis |
23 | +* contacts: http://github.com/cardmagic/contacts/tree/master | ||
23 | 24 | ||
24 | There are Debian packages available for all of them but ferret. Try: | 25 | There are Debian packages available for all of them but ferret. Try: |
25 | 26 |
test/functional/friends_controller_test.rb
@@ -73,4 +73,32 @@ class FriendsControllerTest < Test::Unit::TestCase | @@ -73,4 +73,32 @@ class FriendsControllerTest < Test::Unit::TestCase | ||
73 | get :index, :profile => 'testuser' | 73 | get :index, :profile => 'testuser' |
74 | assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/assets/people' } | 74 | assert_tag :tag => 'a', :content => 'Find people', :attributes => { :href => '/assets/people' } |
75 | end | 75 | end |
76 | + | ||
77 | + should 'display invitation page' do | ||
78 | + get :invite | ||
79 | + assert_response :success | ||
80 | + assert_template 'invite' | ||
81 | + end | ||
82 | + | ||
83 | + should 'actualy add invite' do | ||
84 | + assert_difference InviteFriend, :count, 1 do | ||
85 | + post :invite, :manual_import_addresses => "Test Name <test@test.com>", :import_from => "manual", :message => "click: <url>", :confirmation => 1 | ||
86 | + assert_redirected_to :action => 'index' | ||
87 | + end | ||
88 | + | ||
89 | + assert_difference InviteFriend, :count, 1 do | ||
90 | + post :invite, :manual_import_addresses => "test@test.com", :import_from => "manual", :message => "click: <url>", :confirmation => 1 | ||
91 | + assert_redirected_to :action => 'index' | ||
92 | + end | ||
93 | + | ||
94 | + assert_difference InviteFriend, :count, 1 do | ||
95 | + post :invite, :manual_import_addresses => "test@test.cz.com", :import_from => "manual", :message => "click: <url>", :confirmation => 1 | ||
96 | + assert_redirected_to :action => 'index' | ||
97 | + end | ||
98 | + | ||
99 | + assert_difference InviteFriend, :count, 1 do | ||
100 | + post :invite, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :message => "click: <url>", :confirmation => 1 | ||
101 | + assert_redirected_to :action => 'index' | ||
102 | + end | ||
103 | + end | ||
76 | end | 104 | end |
test/functional/profile_controller_test.rb
@@ -31,6 +31,18 @@ class ProfileControllerTest < Test::Unit::TestCase | @@ -31,6 +31,18 @@ class ProfileControllerTest < Test::Unit::TestCase | ||
31 | assert_kind_of Array, assigns(:friends) | 31 | assert_kind_of Array, assigns(:friends) |
32 | end | 32 | end |
33 | 33 | ||
34 | + should 'point to manage friends in user is seeing his own friends' do | ||
35 | + login_as('testuser') | ||
36 | + get :friends | ||
37 | + assert_tag :tag => 'a', :attributes => { :href => '/myprofile/testuser/friends' } | ||
38 | + end | ||
39 | + | ||
40 | + should 'not point to manage friends of other users' do | ||
41 | + login_as('ze') | ||
42 | + get :friends | ||
43 | + assert_no_tag :tag => 'a', :attributes => { :href => '/myprofile/testuser/friends' } | ||
44 | + end | ||
45 | + | ||
34 | should 'list communities' do | 46 | should 'list communities' do |
35 | get :communities | 47 | get :communities |
36 | 48 |
test/unit/environment_test.rb
@@ -584,6 +584,19 @@ class EnvironmentTest < Test::Unit::TestCase | @@ -584,6 +584,19 @@ class EnvironmentTest < Test::Unit::TestCase | ||
584 | assert_equal ['birth_date'], env.required_person_fields | 584 | assert_equal ['birth_date'], env.required_person_fields |
585 | end | 585 | end |
586 | 586 | ||
587 | + should 'provide a default invitation message' do | ||
588 | + env = Environment.create!(:name => 'test environment') | ||
589 | + message = [ | ||
590 | + 'Hello <friend>,', | ||
591 | + "<user> is inviting you to participate on #{env.name}.", | ||
592 | + 'To accept the invitation, please follow this link:' + "\n" + '<url>', | ||
593 | + "--\n#{env.name}", | ||
594 | + '' | ||
595 | + ].join("\n\n") | ||
596 | + | ||
597 | + assert_equal message, env.message_for_friend_invitation | ||
598 | + end | ||
599 | + | ||
587 | should 'set custom_enterprises_fields' do | 600 | should 'set custom_enterprises_fields' do |
588 | env = Environment.new | 601 | env = Environment.new |
589 | env.custom_enterprise_fields = {'contact_person' => {'required' => 'true', 'active' => 'true'},'contact_email'=> {'required' => 'true', 'active' => 'true'}} | 602 | env.custom_enterprise_fields = {'contact_person' => {'required' => 'true', 'active' => 'true'},'contact_email'=> {'required' => 'true', 'active' => 'true'}} |
@@ -0,0 +1,137 @@ | @@ -0,0 +1,137 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class InviteFriendTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + should 'be a task' do | ||
6 | + ok { InviteFriend.new.kind_of?(Task) } | ||
7 | + end | ||
8 | + | ||
9 | + should 'actually create friendships (two way) when confirmed' do | ||
10 | + p1 = create_user('testuser1').person | ||
11 | + p2 = create_user('testuser2').person | ||
12 | + | ||
13 | + task = InviteFriend.create!(:person => p1, :friend => p2) | ||
14 | + | ||
15 | + assert_difference Friendship, :count, 2 do | ||
16 | + task.finish | ||
17 | + end | ||
18 | + | ||
19 | + ok('p1 should have p2 as friend') { p1.friends.include?(p2) } | ||
20 | + ok('p2 should have p1 as friend') { p2.friends.include?(p1) } | ||
21 | + end | ||
22 | + | ||
23 | + should 'require requestor (person inviting other as friend)' do | ||
24 | + task = InviteFriend.new | ||
25 | + task.valid? | ||
26 | + | ||
27 | + ok('must not validate with empty requestor') { task.errors.invalid?(:requestor_id) } | ||
28 | + | ||
29 | + task.requestor = create_user('testuser2').person | ||
30 | + task.valid? | ||
31 | + ok('must validate when requestor is given') { !task.errors.invalid?(:requestor_id)} | ||
32 | + end | ||
33 | + | ||
34 | + should 'require friend email if no target given (person being invited)' do | ||
35 | + task = InviteFriend.new | ||
36 | + task.valid? | ||
37 | + | ||
38 | + ok('must not validate with empty target email') { task.errors.invalid?(:friend_email) } | ||
39 | + | ||
40 | + task.friend_email = 'test@test.com' | ||
41 | + task.valid? | ||
42 | + ok('must validate when target email is given') { !task.errors.invalid?(:friend_email)} | ||
43 | + end | ||
44 | + | ||
45 | + should 'dont require friend email if target given (person being invited)' do | ||
46 | + task = InviteFriend.new(:target => create_user('testuser2').person) | ||
47 | + task.valid? | ||
48 | + | ||
49 | + ok('must validate with empty target email') { !task.errors.invalid?(:friend_email) } | ||
50 | + end | ||
51 | + | ||
52 | + should 'require target (person being invited) if no friend email given' do | ||
53 | + task = InviteFriend.new | ||
54 | + task.valid? | ||
55 | + | ||
56 | + ok('must not validate with no target') { task.errors.invalid?(:target_id) } | ||
57 | + | ||
58 | + task.target = create_user('testuser2').person | ||
59 | + task.valid? | ||
60 | + ok('must validate when target is given') { !task.errors.invalid?(:target_id)} | ||
61 | + end | ||
62 | + | ||
63 | + should 'dont require target (person being invited) if friend email given' do | ||
64 | + task = InviteFriend.new(:friend_email => "test@test.com") | ||
65 | + task.valid? | ||
66 | + | ||
67 | + ok('must validate with no target') { !task.errors.invalid?(:target_id) } | ||
68 | + end | ||
69 | + | ||
70 | + should 'require message with <url> tag if no target given' do | ||
71 | + task = InviteFriend.new | ||
72 | + task.valid? | ||
73 | + | ||
74 | + ok('must not validate with no message') { task.errors.invalid?(:message) } | ||
75 | + | ||
76 | + task.message = 'a simple message' | ||
77 | + task.valid? | ||
78 | + ok('must not validate with no <url> tag in message') { task.errors.invalid?(:message) } | ||
79 | + | ||
80 | + task.message = 'a simple message with <url>' | ||
81 | + task.valid? | ||
82 | + ok('must validate when message is given with <url> tag') { !task.errors.invalid?(:message)} | ||
83 | + end | ||
84 | + | ||
85 | + should 'dont require message if target given (person being invited)' do | ||
86 | + task = InviteFriend.new(:target => create_user('testuser2').person) | ||
87 | + task.valid? | ||
88 | + | ||
89 | + ok('must validate with no target') { !task.errors.invalid?(:message) } | ||
90 | + end | ||
91 | + | ||
92 | + should 'not send e-mails to requestor' do | ||
93 | + p1 = create_user('testuser1').person | ||
94 | + p2 = create_user('testuser2').person | ||
95 | + | ||
96 | + TaskMailer.expects(:deliver_task_finished).never | ||
97 | + TaskMailer.expects(:deliver_task_created).never | ||
98 | + | ||
99 | + task = InviteFriend.create!(:person => p1, :friend => p2) | ||
100 | + task.finish | ||
101 | + end | ||
102 | + | ||
103 | + should 'send e-mails to friend if friend_email given' do | ||
104 | + p1 = create_user('testuser1').person | ||
105 | + | ||
106 | + TaskMailer.expects(:deliver_invitation_notification).once | ||
107 | + | ||
108 | + task = InviteFriend.create!(:person => p1, :friend_email => 'test@test.com', :message => '<url>') | ||
109 | + end | ||
110 | + | ||
111 | + should 'not send e-mails to friend if target given (person being invited)' do | ||
112 | + p1 = create_user('testuser1').person | ||
113 | + p2 = create_user('testuser2').person | ||
114 | + | ||
115 | + TaskMailer.expects(:deliver_invitation_notification).never | ||
116 | + | ||
117 | + task = InviteFriend.create!(:person => p1, :friend => p2) | ||
118 | + end | ||
119 | + | ||
120 | + should 'provide proper description' do | ||
121 | + p1 = create_user('testuser1').person | ||
122 | + p2 = create_user('testuser2').person | ||
123 | + | ||
124 | + TaskMailer.expects(:deliver_task_finished).never | ||
125 | + TaskMailer.expects(:deliver_task_created).never | ||
126 | + | ||
127 | + task = InviteFriend.create!(:person => p1, :friend => p2) | ||
128 | + | ||
129 | + assert_equal 'testuser1 wants to be your friend', task.description | ||
130 | + end | ||
131 | + | ||
132 | + should 'has permission to manage friends' do | ||
133 | + t = InviteFriend.new | ||
134 | + assert_equal :manage_friends, t.permission | ||
135 | + end | ||
136 | + | ||
137 | +end |
test/unit/task_mailer_test.rb
@@ -105,6 +105,35 @@ class TaskMailerTest < Test::Unit::TestCase | @@ -105,6 +105,35 @@ class TaskMailerTest < Test::Unit::TestCase | ||
105 | assert !ActionMailer::Base.deliveries.empty? | 105 | assert !ActionMailer::Base.deliveries.empty? |
106 | end | 106 | end |
107 | 107 | ||
108 | + should 'be able to send a "invitatiom notification" message' do | ||
109 | + | ||
110 | + task = InviteFriend.new | ||
111 | + task.expects(:description).returns('the task') | ||
112 | + task.expects(:code).returns('123456') | ||
113 | + | ||
114 | + task.expects(:message).returns('Hello <friend>, <user> invite you, please follow this link: <url>') | ||
115 | + task.expects(:friend_email).returns('friend@exemple.com') | ||
116 | + task.expects(:friend_name).returns('friend name') | ||
117 | + | ||
118 | + requestor = mock() | ||
119 | + requestor.expects(:name).returns('my name') | ||
120 | + | ||
121 | + environment = mock() | ||
122 | + environment.expects(:contact_email).returns('sender@example.com') | ||
123 | + environment.expects(:default_hostname).returns('example.com') | ||
124 | + environment.expects(:name).returns('example').at_least_once | ||
125 | + | ||
126 | + task.expects(:requestor).returns(requestor).at_least_once | ||
127 | + requestor.expects(:environment).returns(environment).at_least_once | ||
128 | + | ||
129 | + mail = TaskMailer.create_invitation_notification(task) | ||
130 | + | ||
131 | + assert_equal "Hello friend name, my name invite you, please follow this link: http://example.com/account/signup?invitation_code=123456", mail.body | ||
132 | + | ||
133 | + TaskMailer.deliver(mail) | ||
134 | + assert !ActionMailer::Base.deliveries.empty? | ||
135 | + end | ||
136 | + | ||
108 | should 'use environment name and contact email' do | 137 | should 'use environment name and contact email' do |
109 | task = mock | 138 | task = mock |
110 | requestor = mock | 139 | requestor = mock |