Commit ca285e1e979f3d756eee29a315ddfb6ef36bcb30
Committed by
Antonio Terceiro
1 parent
f9cb2dd4
Exists in
master
and in
22 other branches
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)
Showing
27 changed files
with
566 additions
and
223 deletions
Show diff stats
app/controllers/public/invite_controller.rb
| ... | ... | @@ -2,42 +2,57 @@ class InviteController < 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] = _('<url> 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 | ... | ... |
| ... | ... | @@ -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 < 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 < 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 < 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 < 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" --> | ... | ... |
| ... | ... | @@ -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 %> | ... | ... |
| ... | ... | @@ -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 %> |
| ... | ... | @@ -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 | + | ... | ... |
| ... | ... | @@ -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 %> | ... | ... |
| ... | ... | @@ -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 => 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 => 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 => 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 | ... | ... |
| ... | ... | @@ -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 < 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 < 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 < 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 < 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 < 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 < 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 < 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 < 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 | ... | ... |
| ... | ... | @@ -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 | ... | ... |
| ... | ... | @@ -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 < 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 < 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 < 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? | ... | ... |