Commit ca285e1e979f3d756eee29a315ddfb6ef36bcb30

Authored by Daniela Feitosa
Committed by Antonio Terceiro
1 parent f9cb2dd4

fetching emails for invitation done in background

* Added message if user wants to fetch from hotmail
  * Added <url> to message if user removed it
  * Refactored invite_controller
  * Added ContactList
  * Added get_email_contacts_job
  * Added invitation_job

    (ActionItem1640)
app/controllers/public/invite_controller.rb
... ... @@ -2,42 +2,57 @@ class InviteController &lt; PublicController
2 2  
3 3 needs_profile
4 4 before_filter :login_required
5   - before_filter :check_permissions_to_invite, :only => 'friends'
  5 + before_filter :check_permissions_to_invite
6 6  
7   - def friends
8   - step = params[:step]
  7 + def select_address_book
  8 + @import_from = params[:import_from] || "manual"
9 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] = _('&lt;url&gt; is needed in invitation mail.')
23   - elsif !contacts_to_invite.empty?
24   - Delayed::Job.enqueue InvitationJob.new(user.id, contacts_to_invite, params[:mail_template], profile.id)
25   - session[:notice] = _('Your invitations are being sent.')
26   - if profile.person?
27   - redirect_to :controller => 'friends'
28   - else
29   - redirect_to :controller => 'profile_members'
30   - end
  10 + contact_list = ContactList.create
  11 + Delayed::Job.enqueue GetEmailContactsJob.new(@import_from, params[:login], params[:password], contact_list.id) if @import_from != 'manual'
  12 + redirect_to :action => 'select_friends', :contact_list => contact_list.id, :import_from => @import_from
  13 + end
  14 + end
  15 +
  16 + def select_friends
  17 + @contact_list = ContactList.find(params[:contact_list])
  18 + @mail_template = params[:mail_template] || environment.invitation_mail_template(profile)
  19 + @import_from = params[:import_from] || "manual"
  20 + if request.post?
  21 + manual_import_addresses = params[:manual_import_addresses]
  22 + webmail_import_addresses = params[:webmail_import_addresses]
  23 + contacts_to_invite = Invitation.join_contacts(manual_import_addresses, webmail_import_addresses)
  24 + if !contacts_to_invite.empty?
  25 + Delayed::Job.enqueue InvitationJob.new(current_user.person.id, contacts_to_invite, params[:mail_template], profile.id, @contact_list.id)
  26 + session[:notice] = _('Your invitations are being sent.')
  27 + if profile.person?
  28 + redirect_to :controller => 'profile', :action => 'friends'
31 29 else
32   - flash.now[:notice] = _('Please enter a valid email address.')
  30 + redirect_to :controller => 'profile', :action => 'members'
33 31 end
34   - @contacts = params[:webmail_friends] ? params[:webmail_friends].map {|e| YAML.load(e)} : []
35   - @manual_import_addresses = manual_import_addresses || ""
36   - @webmail_import_addresses = webmail_import_addresses || []
  32 + return
  33 + else
  34 + session[:notice] = _('Please enter a valid email address.')
37 35 end
  36 + @manual_import_addresses = manual_import_addresses || ""
  37 + @webmail_import_addresses = webmail_import_addresses || []
38 38 end
39   - @import_from = params[:import_from] || "manual"
40   - @mail_template = params[:mail_template] || environment.invitation_mail_template(profile)
  39 + end
  40 +
  41 + def invitation_data
  42 + contact_list = ContactList.find(params[:contact_list])
  43 + render :text => contact_list.data.to_json, :layout => false, :content_type => "application/javascript"
  44 + end
  45 +
  46 + def add_contact_list
  47 + contact_list = ContactList.find(params[:contact_list])
  48 + contacts = contact_list.list
  49 + render :partial => 'invite/contact_list', :locals => {:contacts => contacts}
  50 + end
  51 +
  52 + def cancel_fetching_emails
  53 + contact_list = ContactList.find(params[:contact_list])
  54 + contact_list.destroy
  55 + redirect_to :action => 'select_address_book'
41 56 end
42 57  
43 58 protected
... ...
app/models/contact_list.rb 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +class ContactList < ActiveRecord::Base
  2 +
  3 + serialize :list, Array
  4 +
  5 + def list
  6 + self[:list] || []
  7 + end
  8 +
  9 + def data
  10 + if self.fetched
  11 + { "fetched" => true, "contact_list" => self.id, "error" => self.error_fetching }
  12 + else
  13 + {}
  14 + end
  15 + end
  16 +
  17 + def register_auth_error
  18 + msg = _('There was an error while authenticating. Did you enter correct login and password?')
  19 + self.update_attributes(:fetched => true, :error_fetching => msg)
  20 + end
  21 +
  22 + def register_error
  23 + msg = _('There was an error while looking for your contact list. Please, try again')
  24 + self.update_attributes(:fetched => true, :error_fetching => msg)
  25 + end
  26 +
  27 +end
... ...
app/models/invitation.rb
... ... @@ -11,7 +11,6 @@ class Invitation &lt; Task
11 11 validates_format_of :friend_email, :with => Noosfero::Constants::EMAIL_FORMAT, :if => Proc.new{|invite| invite.target_id.blank?}
12 12  
13 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 14  
16 15 alias :person :requestor
17 16 alias :person= :requestor=
... ... @@ -19,6 +18,12 @@ class Invitation &lt; Task
19 18 alias :friend :target
20 19 alias :friend= :target=
21 20  
  21 + before_create do |task|
  22 + if task.message && !task.message.match(/<url>/)
  23 + task.message += task.message_to_accept_invitation
  24 + end
  25 + end
  26 +
22 27 after_create do |task|
23 28 TaskMailer.deliver_invitation_notification(task) unless task.friend
24 29 end
... ... @@ -72,21 +77,26 @@ class Invitation &lt; Task
72 77 end
73 78 end
74 79  
75   - def self.get_contacts(source, login, password)
76   - contacts = []
  80 + def self.get_contacts(source, login, password, contact_list_id)
  81 + contact_list = ContactList.find(contact_list_id)
77 82 case source
78 83 when "gmail"
79   - contacts = Contacts::Gmail.new(login, password).contacts
  84 + email_service = Contacts::Gmail.new(login, password)
80 85 when "yahoo"
81   - contacts = Contacts::Yahoo.new(login, password).contacts
  86 + email_service = Contacts::Yahoo.new(login, password)
82 87 when "hotmail"
83   - contacts = Contacts::Hotmail.new(login, password).contacts
  88 + email_service = Contacts::Hotmail.new(login, password)
84 89 when "manual"
85 90 #do nothing
86 91 else
87 92 raise NotImplementedError, 'Unknown source to get contacts'
88 93 end
89   - contacts.map { |contact| contact + ["#{contact[0]} <#{contact[1]}>"] }
  94 + if email_service
  95 + contact_list.list = email_service.contacts.map { |contact| contact + ["#{contact[0]} <#{contact[1]}>"] }
  96 + contact_list.fetched = true
  97 + contact_list.save
  98 + end
  99 + contact_list.list
90 100 end
91 101  
92 102 def self.join_contacts(manual_import_addresses, webmail_import_addresses)
... ... @@ -112,4 +122,7 @@ class Invitation &lt; Task
112 122 raise 'You should implement mail_template in a subclass'
113 123 end
114 124  
  125 + def message_to_accept_invitation
  126 + '<p>' + _('To accept invitation, please follow this link: <url>') + '</p>'
  127 + end
115 128 end
... ...
app/views/friends/index.rhtml
... ... @@ -14,7 +14,7 @@
14 14 <% button_bar do %>
15 15 <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
16 16 <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %>
17   - <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'friends') %>
  17 + <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'select_address_book') %>
18 18 <% end %>
19 19 <% end %>
20 20  
... ... @@ -40,11 +40,11 @@
40 40 <%= pagination_links @friends, :param_name => 'npage' %>
41 41 </div>
42 42  
43   -<% button_bar do %>
44   - <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
45   - <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %>
46   - <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'friends') %>
47   -<% end %>
  43 + <% button_bar do %>
  44 + <%= button(:back, _('Back to control panel'), :controller => 'profile_editor') %>
  45 + <%= button(:search, _('Find people'), :controller => 'search', :action => 'assets', :asset => 'people') %>
  46 + <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'select_address_book') %>
  47 + <% end %>
48 48 <% end %>
49 49  
50 50 </div><!-- end id="manage_friends" -->
... ...
app/views/invite/_contact_list.rhtml 0 → 100644
... ... @@ -0,0 +1,12 @@
  1 +<% friend_pos = 0 %>
  2 +<% contacts.each do |contact| %>
  3 + <% friend_pos += 1 %>
  4 + <p>
  5 + <%= check_box_tag("webmail_import_addresses[]", contact[2],
  6 + (!@webmail_import_addresses || @webmail_import_addresses.include?(contact[2])),
  7 + :id => "contacts_to_invite_#{friend_pos}",
  8 + :class => "contact_to_invite" )
  9 + %>
  10 + <label for="<%= "contacts_to_invite_#{friend_pos}" %>"><%= "#{contact[0]} (#{contact[1]})" %></label>
  11 + </p>
  12 +<% end %>
... ...
app/views/invite/_dialog_wait_loading.rhtml 0 → 100644
... ... @@ -0,0 +1,23 @@
  1 +<% javascript_tag do %>
  2 + jQuery(function($) {
  3 + $("#loading-dialog").dialog({
  4 + height: 160,
  5 + width: 450,
  6 + modal: true,
  7 + resizable: false,
  8 + title: "<%= ui_icon('ui-icon-info') + _('Please, wait...') %>",
  9 + open: check_contact_list('<%= contact_list.to_s %>'),
  10 + });
  11 + });
  12 +<% end %>
  13 +
  14 +
  15 +<div id="loading-dialog">
  16 + <p><%= _('Your e-mails contacts are being fetched') %></p>
  17 + <p><%= _('If it takes too long, you will be redirected to the previous page to try again. Be sure to fill in the fields with your correct login and password.') %>
  18 + <span class='loading-message'/>
  19 + <%= link_to(_('Verify contact list'), {:action => 'invitation_data', :contact_list => @contact_list}, :id => "verify-contact-list", :style => 'display:none') %>
  20 + <%= link_to(_('Add contact list'), {:action => 'add_contact_list', :contact_list => @contact_list}, :id => "add-contact-list", :style => 'display:none') %>
  21 + <%= link_to(_('Cancel fetching e-mails'), {:action => 'cancel_fetching_emails', :contact_list => @contact_list}, :id => "cancel-fetching-emails", :style => 'display:none') %>
  22 +</div>
  23 +
... ...
app/views/invite/friends.rhtml
... ... @@ -1,93 +0,0 @@
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 text. 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 text:'), 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/invite/select_address_book.rhtml 0 → 100644
... ... @@ -0,0 +1,51 @@
  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 +<h2><%= _('Step 1 of 2: Select address book') %></h2>
  8 +
  9 +<% form_tag do %>
  10 +
  11 + <%= [
  12 + 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"),
  13 + radio_button_tag(:import_from, "gmail", @import_from == "gmail", :onclick => 'show_invite_friend_login_password(this.value)') + content_tag('label', 'Gmail', :for => 'import_from_gmail'),
  14 + radio_button_tag(:import_from, "yahoo", @import_from == "yahoo", :onclick => 'show_invite_friend_login_password(this.value)') + content_tag('label', 'Yahoo', :for => "import_from_yahoo"),
  15 + radio_button_tag(:import_from, "hotmail", @import_from == "hotmail", :onclick => 'show_invite_friend_login_password(this.value)') + content_tag('label', 'Hotmail', :for => "import_from_hotmail")
  16 + ].join("\n<br/>\n") %>
  17 +
  18 + <script type="text/javascript">
  19 + function hide_invite_friend_login_password() {
  20 + $('invite-friends-login-password').hide();
  21 + }
  22 + function show_invite_friend_login_password(option) {
  23 + if (option == 'hotmail') {
  24 + $('hotmail_username_tip').show();
  25 + } else {
  26 + $('hotmail_username_tip').hide();
  27 + }
  28 + $('invite-friends-login-password').show();
  29 + $('login').focus();
  30 + }
  31 + </script>
  32 + <div id='invite-friends-login-password' <%= "style='display: none;'" if (@import_from == 'manual') %>>
  33 + <div id='hotmail_username_tip'>
  34 + <%= ui_icon('ui-icon-alert') %>
  35 + <%= _('Please type your username in the format yourname@example.com') %>
  36 + </div>
  37 +
  38 + <%= labelled_form_field(_("Username") + ":", text_field_tag(:login, @login)) %>
  39 + <%= labelled_form_field(_("Password") + ":", password_field_tag(:password)) %>
  40 + </div>
  41 +
  42 + <% button_bar do %>
  43 + <%= submit_button(:forward, _("Next")) %>
  44 + <% end %>
  45 + <p><%= _("We won't store your password or contact anyone without your permission.") %></p>
  46 +<% end %>
  47 +
  48 +<div id="loadingScreen"></div>
  49 +
  50 +
  51 +
... ...
app/views/invite/select_friends.rhtml 0 → 100644
... ... @@ -0,0 +1,47 @@
  1 +<%= render :partial => 'invite/dialog_wait_loading', :locals => {:contact_list => @contact_list.id } if @import_from != 'manual' %>
  2 +
  3 +<% if profile.person? %>
  4 + <h1><%= _('Invite your friends') %></h1>
  5 +<% else %>
  6 + <h1><%= _('Invite your friends to join %s') % profile.name %></h1>
  7 +<% end %>
  8 +
  9 +
  10 +<h2><%= _('Step 2 of 2: Selecting Friends') %></h2>
  11 +
  12 +<%= button(:back, _('Back'), { :action => 'select_address_book' }, :id => 'invitation_back_button') %>
  13 +
  14 +<p>
  15 +<%= _('Indicate which friends you want to invite.') %>
  16 +</p>
  17 +
  18 +<% form_tag do %>
  19 + <%= hidden_field_tag(:import_from, @import_from) %>
  20 + <%= hidden_field_tag(:contact_list, @contact_list.id) %>
  21 +
  22 + <div>
  23 + <%= labelled_form_field(_('Enter one e-mail address per line:'), text_area_tag(:manual_import_addresses, (@manual_import_addresses || ''), :cols => 72, :rows => 5)) %>
  24 + </div>
  25 + <% if @import_from != 'manual' %>
  26 + <div>
  27 + <%= link_to_function _('Check all'), "$$('input.contact_to_invite').each(function(checkbox) { checkbox.checked = true; });" %>
  28 + <%= link_to_function _('Uncheck all'), "$$('input.contact_to_invite').each(function(checkbox) { checkbox.checked = false; });" %>
  29 + <div id='contacts-list'></div>
  30 + </div>
  31 + <% end -%>
  32 +
  33 + <br/>
  34 +
  35 + <%= link_to_function(_('Personalize invitation mail'), nil) do |page|
  36 + page['invitation-mail_template'].show
  37 + end %>
  38 +
  39 + <div id='invitation-mail_template' style='display:none'>
  40 + <%= h _("Now enter an invitation message. You must keep the <url> code in your invitation text. 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.") %>
  41 + <%= labelled_form_field(_('Invitation text:'), text_area_tag(:mail_template, @mail_template, :cols => 72, :rows => 8)) %>
  42 + </div>
  43 +
  44 + <% button_bar do %>
  45 + <%= submit_button(:ok, _("Invite my friends!")) %>
  46 + <% end %>
  47 +<% end %>
... ...
app/views/profile/friends.rhtml
... ... @@ -18,7 +18,7 @@
18 18 <%= button :back, _('Go back'), { :controller => 'profile' } %>
19 19 <% if user == profile %>
20 20 <%= button :edit, _('Manage my friends'), :controller => 'friends', :action => 'index', :profile => profile.identifier %>
21   - <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'friends') %>
  21 + <%= button(:search, _('Invite people from my e-mail contacts'), :controller => 'invite', :action => 'select_address_book') %>
22 22 <% end %>
23 23 <% end %>
24 24  
... ...
app/views/profile/members.rhtml
... ... @@ -17,7 +17,7 @@
17 17 <% button_bar do %>
18 18 <%= button :back, _('Go back'), { :controller => 'profile' } %>
19 19 <% if profile.community? and user and user.has_permission?(:invite_members, profile) %>
20   - <%= button :search, _('Invite your friends to join %s') % profile.name, :controller => 'invite', :action => 'friends' %>
  20 + <%= button :search, _('Invite your friends to join %s') % profile.name, :controller => 'invite', :action => 'selects_address_book' %>
21 21 <% end %>
22 22 <% end %>
23 23  
... ...
app/views/profile_members/index.rhtml
... ... @@ -6,6 +6,6 @@
6 6 <%= button :back, _('Back'), :controller => 'profile_editor' %>
7 7 <%= button :add, _('Add members'), :action => 'add_members' if profile.enterprise? %>
8 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' %>
  9 + <%= button :search, _('Invite your friends to join %s') % profile.name, :controller => 'invite', :action => 'select_address_book' %>
10 10 <% end %>
11 11 <% end %>
... ...
config/initializers/delayed_job_config.rb 0 → 100644
... ... @@ -0,0 +1,2 @@
  1 +Delayed::Worker.max_attempts = 2
  2 +Delayed::Worker.max_run_time = 10.minutes
... ...
db/migrate/20100823190348_create_contact_lists.rb 0 → 100644
... ... @@ -0,0 +1,14 @@
  1 +class CreateContactLists < ActiveRecord::Migration
  2 + def self.up
  3 + create_table :contact_lists do |t|
  4 + t.text :list
  5 + t.string :error_fetching
  6 + t.boolean :fetched, :default => false
  7 + t.timestamps
  8 + end
  9 + end
  10 +
  11 + def self.down
  12 + drop_table :contact_lists
  13 + end
  14 +end
... ...
db/schema.rb
... ... @@ -9,7 +9,7 @@
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11  
12   -ActiveRecord::Schema.define(:version => 20100822034415) do
  12 +ActiveRecord::Schema.define(:version => 20100823190348) do
13 13  
14 14 create_table "article_versions", :force => true do |t|
15 15 t.integer "article_id"
... ... @@ -145,9 +145,9 @@ ActiveRecord::Schema.define(:version =&gt; 20100822034415) do
145 145 t.string "name", :null => false
146 146 t.string "description"
147 147 t.string "link"
  148 + t.integer "environment_id"
148 149 t.datetime "created_at"
149 150 t.datetime "updated_at"
150   - t.integer "environment_id"
151 151 end
152 152  
153 153 create_table "comments", :force => true do |t|
... ... @@ -160,6 +160,14 @@ ActiveRecord::Schema.define(:version =&gt; 20100822034415) do
160 160 t.datetime "created_at"
161 161 end
162 162  
  163 + create_table "contact_lists", :force => true do |t|
  164 + t.text "list"
  165 + t.string "error_fetching"
  166 + t.boolean "fetched", :default => false
  167 + t.datetime "created_at"
  168 + t.datetime "updated_at"
  169 + end
  170 +
163 171 create_table "delayed_jobs", :force => true do |t|
164 172 t.integer "priority", :default => 0
165 173 t.integer "attempts", :default => 0
... ... @@ -351,9 +359,9 @@ ActiveRecord::Schema.define(:version =&gt; 20100822034415) do
351 359  
352 360 create_table "roles", :force => true do |t|
353 361 t.string "name"
  362 + t.text "permissions"
354 363 t.string "key"
355 364 t.boolean "system", :default => false
356   - t.text "permissions"
357 365 t.integer "environment_id"
358 366 end
359 367  
... ...
features/invitation.feature
... ... @@ -32,15 +32,14 @@ Feature: invitation
32 32 When I am on /profile/josesilva/invite/friends
33 33 Then I should see "Invite your friends"
34 34  
35   - # why not work?
36   - Scenario: back to manage friends after invite friends
  35 + Scenario: back to friends after invite friends
37 36 Given I am on /myprofile/josesilva/friends
38 37 And I follow "Invite people from my e-mail contacts"
39 38 And I press "Next"
40 39 And I fill in "manual_import_addresses" with "misfits@devil.doll"
41 40 And I fill in "mail_template" with "Follow this link <url>"
42 41 When I press "Invite my friends!"
43   - Then I should be on /myprofile/josesilva/friends
  42 + Then I should be on /profile/josesilva/friends
44 43  
45 44 Scenario: see link to invite members to community
46 45 When I am on /profile/26-bsslines/members
... ... @@ -75,14 +74,14 @@ Feature: invitation
75 74 Given I am on Beatles For Sale's members management
76 75 Then I should not see "Invite your friends to join Beatles For Sale" link
77 76  
78   - Scenario: back to manage members after invite friends
  77 + Scenario: back to members after invite friends to join a community
79 78 Given I am on 26 Bsslines's members management
80 79 And I follow "Invite your friends to join 26 Bsslines"
81 80 And I press "Next"
82 81 And I fill in "manual_import_addresses" with "misfits@devil.doll"
83 82 And I fill in "mail_template" with "Follow this link <url>"
84 83 When I press "Invite my friends!"
85   - Then I should be on /myprofile/26-bsslines/profile_members
  84 + Then I should be on /profile/26-bsslines/members
86 85  
87 86 Scenario: noosfero user receives a task when a user invites to join a community
88 87 Given I am on 26 Bsslines's members management
... ...
lib/get_email_contacts_job.rb 0 → 100644
... ... @@ -0,0 +1,11 @@
  1 +class GetEmailContactsJob < Struct.new(:import_from, :login, :password, :contact_list_id)
  2 + def perform
  3 + begin
  4 + Invitation.get_contacts(import_from, login, password, contact_list_id)
  5 + rescue Contacts::AuthenticationError => ex
  6 + ContactList.find(contact_list_id).register_auth_error
  7 + rescue Exception => ex
  8 + ContactList.find(contact_list_id).register_error
  9 + end
  10 + end
  11 +end
... ...
lib/invitation_job.rb
1   -class InvitationJob < Struct.new(:person_id, :contacts_to_invite, :message, :profile_id)
  1 +class InvitationJob < Struct.new(:person_id, :contacts_to_invite, :message, :profile_id, :contact_list_id)
2 2 def perform
3 3 begin
4   - person = Person.find(person_id)
5   - profile = Profile.find(profile_id)
6   - Invitation.invite(person, contacts_to_invite, message, profile)
  4 + person = Person.find(person_id)
  5 + profile = Profile.find(profile_id)
  6 + Invitation.invite(person, contacts_to_invite, message, profile)
  7 + ContactList.find(contact_list_id).destroy
7 8 rescue ActiveRecord::NotFound => e
8   - # ...
  9 + #...
9 10 end
10 11 end
11 12 end
... ...
public/javascripts/application.js
... ... @@ -455,9 +455,46 @@ jQuery(function($) {
455 455 $('#user .not-logged-in, .login-block .not-logged-user').fadeIn();
456 456 }
457 457 if (data.notice) {
458   - var $noticeBox = $('<div id="notice"></div>').html(data.notice).appendTo('body').fadeTo('fast', 0.8);
459   - $noticeBox.click(function() { $(this).hide(); });
460   - setTimeout(function() { $noticeBox.fadeOut('fast'); }, 5000);
  458 + display_notice(data.notice);
461 459 }
462 460 });
463 461 });
  462 +
  463 +// controls the display of contact list
  464 +function check_contact_list(contact_list) {
  465 + jQuery(function($) {
  466 + var verify_url = $('#verify-contact-list').attr('href');
  467 + var add_contacts_url = $('#add-contact-list').attr('href');
  468 + var cancel_contacts_fetching_url = $('#cancel-fetching-emails').attr('href');
  469 + var interval = setInterval(function() {
  470 + $.getJSON(verify_url, function(data) {
  471 + if (data.fetched) {
  472 + clearInterval(interval);
  473 + if (data.error) {
  474 + $("#loading-dialog").dialog('close');
  475 + $.get(cancel_contacts_fetching_url);
  476 + redirect_to($('#invitation_back_button').attr('href'));
  477 + display_notice(data.error);
  478 + } else {
  479 + $.get(add_contacts_url, function(data){
  480 + $("#contacts-list").html(data);
  481 + });
  482 + };
  483 + $("#loading-dialog").dialog('close');
  484 + }
  485 + });
  486 + }, 5000);
  487 + setTimeout(function() {
  488 + clearInterval(interval);
  489 + $("#loading-dialog").dialog('close');
  490 + $.get(cancel_contacts_fetching_url);
  491 + redirect_to($('#invitation_back_button').attr('href'));
  492 + }, 600000);
  493 + });
  494 +}
  495 +
  496 +function display_notice(message) {
  497 + var $noticeBox = jQuery('<div id="notice"></div>').html(message).appendTo('body').fadeTo('fast', 0.8);
  498 + $noticeBox.click(function() { $(this).hide(); });
  499 + setTimeout(function() { $noticeBox.fadeOut('fast'); }, 5000);
  500 +}
... ...
public/stylesheets/application.css
... ... @@ -3189,6 +3189,26 @@ h1#agenda-title {
3189 3189 margin: 5px 0px;
3190 3190 }
3191 3191  
  3192 +#loading-dialog .loading-message {
  3193 + height: 32px;
  3194 + width: 32px;
  3195 + left: 209px;
  3196 + bottom: 5px;
  3197 + position: absolute;
  3198 + display: block;
  3199 + background: transparent url(/images/loading-dark.gif) center center no-repeat;
  3200 +}
  3201 +
  3202 +/* hide the close x on the loading screen */
  3203 +.controller-invite .ui-dialog-titlebar-close {
  3204 + display: none;
  3205 +}
  3206 +
  3207 +#hotmail_username_tip {
  3208 + color: red;
  3209 + margin-top: 10px;
  3210 +}
  3211 +
3192 3212 /* ==> public/stylesheets/controller_manage_products.css <== */
3193 3213  
3194 3214 #category_form {
... ...
script/delayed_job
... ... @@ -6,28 +6,9 @@
6 6 # The role of this script is to just start/stop the daemon, write a PID file,
7 7 # etc. The actual feed update logic is DelayedJob plugin.
8 8  
  9 +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))
9 10 require 'daemons'
  11 +require 'delayed/command'
10 12  
11   -NOOSFERO_ROOT = File.expand_path(File.dirname(__FILE__) + '/../')
12   -
13   -options = {
14   - :dir_mode => :normal,
15   - :dir => File.dirname(__FILE__) + '/../tmp/pids',
16   - :multiple => false,
17   - :backtrace => true,
18   - :monitor => true,
19   -}
20   -
21   -Daemons.run_proc('job_runner', options) do
22   - if ARGV.include?('--')
23   - ARGV.slice! 0..ARGV.index('--')
24   - else
25   - ARGV.clear
26   - end
27   -
28   - Dir.chdir NOOSFERO_ROOT
29   - RAILS_ENV = ARGV.first || ENV['RAILS_ENV'] || 'development'
30   - require NOOSFERO_ROOT + '/config/environment'
31   -
32   - Delayed::Worker.new.start
33   -end
  13 +ENV['RAILS_ENV'] ||= "production"
  14 +Delayed::Command.new(ARGV).daemonize
... ...
script/production
... ... @@ -20,14 +20,14 @@ do_start() {
20 20 clear_cache
21 21 ./script/ferret_server -e $RAILS_ENV start
22 22 ./script/feed-updater start
23   - ./script/delayed_job start
  23 +# ./script/delayed_job start -n 4
24 24 mongrel_rails cluster::start
25 25 }
26 26  
27 27 do_stop() {
28 28 mongrel_rails cluster::stop
29 29 ./script/delayed_job stop
30   - ./script/feed-updater stop
  30 +# ./script/feed-updater stop
31 31 ./script/ferret_server -e $RAILS_ENV stop
32 32 }
33 33  
... ...
test/functional/invite_controller_test.rb
... ... @@ -11,9 +11,10 @@ class InviteControllerTest &lt; ActionController::TestCase
11 11 attr_accessor :profile, :friend, :community
12 12  
13 13 should 'add manually invitation of an added address with friend object on a queue and process it later' do
  14 + contact_list = ContactList.create
14 15 assert_difference Delayed::Job, :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 => 'friends'
  16 + post :select_friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id
  17 + assert_redirected_to :controller => 'profile', :action => 'friends'
17 18 end
18 19  
19 20 assert_difference InviteFriend, :count, 1 do
... ... @@ -22,9 +23,10 @@ class InviteControllerTest &lt; ActionController::TestCase
22 23 end
23 24  
24 25 should 'add manually invitation of an added address with only email on a queue and process it later' do
  26 + contact_list = ContactList.create
25 27 assert_difference Delayed::Job, :count, 1 do
26   - post :friends, :profile => profile.identifier, :manual_import_addresses => "test@test.com", :import_from => "manual", :mail_template => "click: <url>", :step => 2
27   - assert_redirected_to :controller => 'friends'
  28 + post :select_friends, :profile => profile.identifier, :manual_import_addresses => "test@test.com", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id
  29 + assert_redirected_to :controller => 'profile', :action => 'friends'
28 30 end
29 31  
30 32 assert_difference InviteFriend, :count, 1 do
... ... @@ -33,9 +35,10 @@ class InviteControllerTest &lt; ActionController::TestCase
33 35 end
34 36  
35 37 should 'add manually invitation of an added address with email and other format on a queue and process it later' do
  38 + contact_list = ContactList.create
36 39 assert_difference Delayed::Job, :count, 1 do
37   - post :friends, :profile => profile.identifier, :manual_import_addresses => "test@test.cz.com", :import_from => "manual", :mail_template => "click: <url>", :step => 2
38   - assert_redirected_to :controller => 'friends'
  40 + post :select_friends, :profile => profile.identifier, :manual_import_addresses => "test@test.cz.com", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id
  41 + assert_redirected_to :controller => 'profile', :action => 'friends'
39 42 end
40 43  
41 44 assert_difference InviteFriend, :count, 1 do
... ... @@ -44,9 +47,10 @@ class InviteControllerTest &lt; ActionController::TestCase
44 47 end
45 48  
46 49 should 'add manually invitation of more than one added address on a queue and process it later' do
  50 + contact_list = ContactList.create
47 51 assert_difference Delayed::Job, :count, 1 do
48   - 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
49   - assert_redirected_to :controller => 'friends'
  52 + post :select_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>", :contact_list => contact_list.id
  53 + assert_redirected_to :controller => 'profile', :action => 'friends'
50 54 end
51 55  
52 56 assert_difference InviteFriend, :count, 2 do
... ... @@ -55,9 +59,10 @@ class InviteControllerTest &lt; ActionController::TestCase
55 59 end
56 60  
57 61 should 'add manually invitation of an added address with name and e-mail on a queue and process it later' do
  62 + contact_list = ContactList.create
58 63 assert_difference Delayed::Job, :count, 1 do
59   - post :friends, :profile => profile.identifier, :manual_import_addresses => "Test Name <test@test.com>", :import_from => "manual", :mail_template => "click: <url>", :step => 2
60   - assert_redirected_to :controller => 'friends'
  64 + post :select_friends, :profile => profile.identifier, :manual_import_addresses => "Test Name <test@test.com>", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id
  65 + assert_redirected_to :controller => 'profile', :action => 'friends'
61 66 end
62 67  
63 68 assert_difference InviteFriend, :count, 1 do
... ... @@ -66,9 +71,10 @@ class InviteControllerTest &lt; ActionController::TestCase
66 71 end
67 72  
68 73 should 'add invitation of yourself on a queue and not process it later' do
  74 + contact_list = ContactList.create
69 75 assert_difference Delayed::Job, :count, 1 do
70   - post :friends, :profile => profile.identifier, :manual_import_addresses => "#{profile.name} <#{profile.user.email}>", :import_from => "manual", :mail_template => "click: <url>", :step => 2
71   - assert_redirected_to :controller => 'friends'
  76 + post :select_friends, :profile => profile.identifier, :manual_import_addresses => "#{profile.name} <#{profile.user.email}>", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id
  77 + assert_redirected_to :controller => 'profile', :action => 'friends'
72 78 end
73 79  
74 80 assert_no_difference InviteFriend, :count do
... ... @@ -80,9 +86,10 @@ class InviteControllerTest &lt; ActionController::TestCase
80 86 friend = create_user('testfriend', :email => 'friend@noosfero.org')
81 87 friend.person.add_friend(profile)
82 88  
  89 + contact_list = ContactList.create
83 90 assert_difference Delayed::Job, :count, 1 do
84   - post :friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :step => 2
85   - assert_redirected_to :controller => 'friends'
  91 + post :select_friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id
  92 + assert_redirected_to :controller => 'profile', :action => 'friends'
86 93 end
87 94  
88 95 assert_no_difference InviteFriend, :count do
... ... @@ -91,42 +98,131 @@ class InviteControllerTest &lt; ActionController::TestCase
91 98 end
92 99  
93 100 should 'display invitation page' do
94   - get :friends, :profile => profile.identifier
  101 + get :select_address_book, :profile => profile.identifier
95 102 assert_response :success
96 103 assert_tag :tag => 'h1', :content => 'Invite your friends'
97 104 end
98 105  
99 106 should 'get mail template to invite members' do
100 107 community.add_admin(profile)
101   - get :friends, :profile => community.identifier
  108 + contact_list = ContactList.create
  109 + get :select_friends, :profile => community.identifier, :contact_list => contact_list.id
102 110 assert_equal InviteMember.mail_template, assigns(:mail_template)
103 111 end
104 112  
105 113 should 'get mail template to invite friends' do
106 114 community.add_admin(profile)
107   - get :friends, :profile => profile.identifier
  115 + contact_list = ContactList.create
  116 + get :select_friends, :profile => profile.identifier, :contact_list => contact_list.id
108 117 assert_equal InviteFriend.mail_template, assigns(:mail_template)
109 118 end
110 119  
111   - should 'deny if user has no rights to invite members' do
112   - get :friends, :profile => community.identifier
  120 + should 'deny select_address_book f user has no rights to invite members' do
  121 + get :select_address_book, :profile => community.identifier
113 122 assert_response 403 # forbidden
114 123 end
115 124  
116   - should 'deny access when trying to invite friends to another user' do
117   - get :friends, :profile => friend.identifier
  125 + should 'deny select_friends if user has no rights to invite members' do
  126 + get :select_friends, :profile => community.identifier
118 127 assert_response 403 # forbidden
119 128 end
120 129  
121   - should 'redirect to friends after invitation if profile is a person' do
122   - post :friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :step => 2
123   - assert_redirected_to :controller => 'friends'
  130 + should 'deny select_address_book access when trying to invite friends to another user' do
  131 + get :select_address_book, :profile => friend.identifier
  132 + assert_response 403 # forbidden
  133 + end
  134 +
  135 + should 'deny select_friends access when trying to invite friends to another user' do
  136 + get :select_address_book, :profile => friend.identifier
  137 + assert_response 403 # forbidden
  138 + end
  139 +
  140 + should 'redirect to profile after invitation if profile is a person' do
  141 + contact_list = ContactList.create
  142 + post :select_friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id
  143 + assert_redirected_to :controller => 'profile', :action => 'friends'
124 144 end
125 145  
126   - should 'redirect to friends after invitation if profile is not a person' do
  146 + should 'redirect to profile after invitation if profile is not a person' do
127 147 community.add_admin(profile)
128   - post :friends, :profile => community.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :step => 2
129   - assert_redirected_to :controller => 'profile_members'
  148 + contact_list = ContactList.create
  149 + post :select_friends, :profile => community.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id
  150 + assert_redirected_to :controller => 'profile', :action => 'members'
  151 + end
  152 +
  153 + should 'create a job to get emails after choose address book' do
  154 + community.add_admin(profile)
  155 + contact_list = ContactList.create
  156 + assert_difference Delayed::Job, :count, 1 do
  157 + post :select_address_book, :profile => community.identifier, :contact_list => contact_list.id, :import_from => 'gmail'
  158 + assert_redirected_to :action => 'select_friends'
  159 + end
  160 + end
  161 +
  162 + should 'destroy contact_list after invitation when import is manual' do
  163 + contact_list = ContactList.create
  164 + post :select_friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "manual", :mail_template => "click: <url>", :contact_list => contact_list.id
  165 +
  166 + assert ContactList.exists?(contact_list.id)
  167 + Delayed::Worker.new.work_off
  168 + assert !ContactList.exists?(contact_list.id)
  169 + end
  170 +
  171 + should 'destroy contact_list after invitation when import is not manual' do
  172 + contact_list = ContactList.create
  173 + post :select_friends, :profile => profile.identifier, :manual_import_addresses => "#{friend.name} <#{friend.email}>", :import_from => "not_manual", :mail_template => "click: <url>", :contact_list => contact_list.id
  174 +
  175 + assert ContactList.exists?(contact_list.id)
  176 + Delayed::Worker.new.work_off
  177 + assert !ContactList.exists?(contact_list.id)
  178 + end
  179 +
  180 + should 'return empty hash as invitation data if contact list was not fetched' do
  181 + contact_list = ContactList.create
  182 + get :invitation_data, :profile => profile.identifier, :contact_list => contact_list.id
  183 +
  184 + assert_equal 'application/javascript', @response.content_type
  185 + assert_equal '{}', @response.body
  186 + end
  187 +
  188 + should 'return hash as invitation data if contact list was fetched' do
  189 + contact_list = ContactList.create(:fetched => true)
  190 + get :invitation_data, :profile => profile.identifier, :contact_list => contact_list.id
  191 +
  192 + assert_equal 'application/javascript', @response.content_type
  193 + assert_equal "{\"fetched\": true, \"contact_list\": #{contact_list.id}, \"error\": null}", @response.body
  194 + end
  195 +
  196 + should 'render empty list of contacts' do
  197 + contact_list = ContactList.create(:fetched => true)
  198 + get :add_contact_list, :profile => profile.identifier, :contact_list => contact_list.id
  199 +
  200 + assert_response :success
  201 + assert_template '_contact_list'
  202 + assert_no_tag(:tag => 'input', :attributes => { :type => 'checkbox', :name => 'webmail_import_addresses[]'})
  203 + end
  204 +
  205 + should 'render list of contacts' do
  206 + contact_list = ContactList.create(:fetched => true, :list => ['email1@noosfero.org', 'email2@noosfero.org'])
  207 + get :add_contact_list, :profile => profile.identifier, :contact_list => contact_list.id
  208 +
  209 + assert_response :success
  210 + assert_template '_contact_list'
  211 +
  212 + i = 0
  213 + contact_list.list.each do |contact|
  214 + i += 1
  215 + assert_tag(:tag => 'input', :attributes => { :type => 'checkbox', :name => 'webmail_import_addresses[]', :id => "contacts_to_invite_#{i}", :value => contact[2]})
  216 + end
  217 + end
  218 +
  219 + should 'destroy contact_list when cancel_fetching_emails' do
  220 + contact_list = ContactList.create
  221 +
  222 + assert_difference ContactList, :count, -1 do
  223 + get :cancel_fetching_emails, :profile => profile.identifier, :contact_list => contact_list.id
  224 + end
  225 + assert_redirected_to :action => 'select_address_book'
130 226 end
131 227  
132 228 end
... ...
test/unit/contact_list_test.rb 0 → 100644
... ... @@ -0,0 +1,41 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class ContactListTest < ActiveSupport::TestCase
  4 +
  5 + should 'have list as an array' do
  6 + assert_equal [], ContactList.create.list
  7 + end
  8 +
  9 + should 'display list' do
  10 + contact_list = ContactList.create(:list => ['email1@noosfero.org', 'email2@noosfero.org'])
  11 +
  12 + assert_equal ['email1@noosfero.org', 'email2@noosfero.org'], contact_list.list
  13 + end
  14 +
  15 + should 'return empty hash if contact list was not fetched' do
  16 + contact_list = ContactList.create
  17 + assert_equal({}, contact_list.data)
  18 + end
  19 +
  20 + should 'return hash if contact list was fetched' do
  21 + contact_list = ContactList.create(:fetched => true)
  22 + assert_equal({"fetched" => true, "contact_list" => contact_list.id, "error" => contact_list.error_fetching}, contact_list.data)
  23 + end
  24 +
  25 + should 'update fetched and error_fetching when register auth error' do
  26 + contact_list = ContactList.create
  27 + assert_equal({}, contact_list.data)
  28 +
  29 + contact_list.register_error
  30 + assert_equal({"fetched" => true, "contact_list" => contact_list.id, "error" => 'There was an error while looking for your contact list. Please, try again'}, contact_list.data)
  31 + end
  32 +
  33 + should 'update fetched and error_fetching when register error' do
  34 + contact_list = ContactList.create
  35 + assert_equal({}, contact_list.data)
  36 +
  37 + contact_list.register_auth_error
  38 + assert_equal({"fetched" => true, "contact_list" => contact_list.id, "error" => 'There was an error while authenticating. Did you enter correct login and password?'}, contact_list.data)
  39 + end
  40 +
  41 +end
... ...
test/unit/get_email_contacts_job_test.rb 0 → 100644
... ... @@ -0,0 +1,27 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class GetEmailContactsJobTest < ActiveSupport::TestCase
  4 +
  5 + should 'register error' do
  6 + contact_list = ContactList.create
  7 + Invitation.expects(:get_contacts).with('from-email', 'mylogin', 'mypassword', contact_list.id).raises(Exception.new("crash"))
  8 +
  9 + job = GetEmailContactsJob.new('from-email', 'mylogin', 'mypassword', contact_list.id)
  10 + job.perform
  11 +
  12 + assert ContactList.find(contact_list).fetched
  13 + assert_equal 'There was an error while looking for your contact list. Please, try again', ContactList.find(contact_list).error_fetching
  14 + end
  15 +
  16 + should 'register auth error' do
  17 + contact_list = ContactList.create
  18 + Invitation.expects(:get_contacts).with('from-email', 'mylogin', 'wrongpassword', contact_list.id).raises(Contacts::AuthenticationError)
  19 +
  20 + job = GetEmailContactsJob.new('from-email', 'mylogin', 'wrongpassword', contact_list.id)
  21 + job.perform
  22 +
  23 + assert ContactList.find(contact_list).fetched
  24 + assert_equal 'There was an error while authenticating. Did you enter correct login and password?', ContactList.find(contact_list).error_fetching
  25 + end
  26 +
  27 +end
... ...
test/unit/invitation_test.rb
... ... @@ -26,8 +26,9 @@ class InvitationTest &lt; ActiveSupport::TestCase
26 26 end
27 27  
28 28 should 'raises when try get contacts from unknown source' do
  29 + contact_list = ContactList.create
29 30 assert_raise NotImplementedError do
30   - Invitation.get_contacts('ze', 'ze12', 'bli-mail')
  31 + Invitation.get_contacts('ze', 'ze12', 'bli-mail', contact_list.id)
31 32 end
32 33 end
33 34  
... ... @@ -71,4 +72,29 @@ class InvitationTest &lt; ActiveSupport::TestCase
71 72 end
72 73 end
73 74  
  75 + should 'add url on message if user removed it' do
  76 + person = create_user('testuser1').person
  77 + friend = create_user('testuser2').person
  78 + invitation = Invitation.create!(
  79 + :person => person,
  80 + :friend => friend,
  81 + :message => 'Hi <friend>, <user> is inviting you!'
  82 + )
  83 + assert_equal "Hi <friend>, <user> is inviting you!#{invitation.message_to_accept_invitation}", invitation.message
  84 + end
  85 +
  86 + should 'do nothing with message if user added url' do
  87 + person = create_user('testuser1').person
  88 + friend = create_user('testuser2').person
  89 + invitation = Invitation.create!(
  90 + :person => person,
  91 + :friend => friend,
  92 + :message => 'Hi <friend>, <user> is inviting you to be his friend on <url>!'
  93 + )
  94 + assert_equal "Hi <friend>, <user> is inviting you to be his friend on <url>!", invitation.message
  95 + end
  96 +
  97 + should 'have a message with url' do
  98 + assert_equal "<p>To accept invitation, please follow this link: <url></p>", Invitation.new.message_to_accept_invitation
  99 + end
74 100 end
... ...
test/unit/invite_friend_test.rb
... ... @@ -70,21 +70,6 @@ class InviteFriendTest &lt; ActiveSupport::TestCase
70 70 ok('must validate with no target') { !task.errors.invalid?(:target_id) }
71 71 end
72 72  
73   - should 'require message with <url> tag if no target given' do
74   - task = InviteFriend.new
75   - task.valid?
76   -
77   - ok('must not validate with no message') { task.errors.invalid?(:message) }
78   -
79   - task.message = 'a simple message'
80   - task.valid?
81   - ok('must not validate with no <url> tag in message') { task.errors.invalid?(:message) }
82   -
83   - task.message = 'a simple message with <url>'
84   - task.valid?
85   - ok('must validate when message is given with <url> tag') { !task.errors.invalid?(:message)}
86   - end
87   -
88 73 should 'dont require message if target given (person being invited)' do
89 74 task = InviteFriend.new(:target => create_user('testuser2').person)
90 75 task.valid?
... ...