Merge branch 'invite_link'
This commit is contained in:
commit
4a564c0c0e
46 changed files with 688 additions and 794 deletions
1
Gemfile
1
Gemfile
|
|
@ -15,7 +15,6 @@ gem 'rack-cors', '~> 0.2.4', :require => 'rack/cors'
|
|||
# authentication
|
||||
|
||||
gem 'devise', '~> 1.3.1'
|
||||
gem 'devise_invitable', '0.5.0'
|
||||
gem 'jwt'
|
||||
gem 'oauth2-provider', '0.0.19'
|
||||
|
||||
|
|
|
|||
|
|
@ -138,9 +138,6 @@ GEM
|
|||
bcrypt-ruby (~> 2.1.2)
|
||||
orm_adapter (~> 0.0.3)
|
||||
warden (~> 1.0.3)
|
||||
devise_invitable (0.5.0)
|
||||
devise (~> 1.3.1)
|
||||
rails (>= 3.0.0, <= 3.2)
|
||||
diff-lcs (1.1.3)
|
||||
em-http-request (1.0.2)
|
||||
addressable (>= 2.2.3)
|
||||
|
|
@ -465,7 +462,6 @@ DEPENDENCIES
|
|||
cucumber-rails (= 1.2.1)
|
||||
database_cleaner (= 0.7.1)
|
||||
devise (~> 1.3.1)
|
||||
devise_invitable (= 0.5.0)
|
||||
diaspora-client!
|
||||
em-synchrony (= 1.0.0)
|
||||
factory_girl_rails
|
||||
|
|
|
|||
|
|
@ -11,16 +11,24 @@ class AdminsController < ApplicationController
|
|||
end
|
||||
|
||||
def admin_inviter
|
||||
user = User.find_by_email params[:idenitifer]
|
||||
inviter = InvitationCode.default_inviter_or(current_user)
|
||||
email = params[:identifier]
|
||||
user = User.find_by_email(email)
|
||||
|
||||
unless user
|
||||
Invitation.create(:service => 'email', :identifier => params[:identifier], :admin => true)
|
||||
flash[:notice] = "invitation sent to #{params[:identifier]}"
|
||||
EmailInviter.new(email, inviter).send!
|
||||
flash[:notice] = "invitation sent to #{email}"
|
||||
else
|
||||
flash[:notice]= "error sending invite to #{params[:identifier]}"
|
||||
flash[:notice]= "error sending invite to #{email}"
|
||||
end
|
||||
redirect_to user_search_path, :notice => flash[:notice]
|
||||
end
|
||||
|
||||
def add_invites
|
||||
InvitationCode.find_by_token(params[:invite_code_id]).add_invites!
|
||||
redirect_to user_search_path
|
||||
end
|
||||
|
||||
def weekly_user_stats
|
||||
@created_users = User.where("username IS NOT NULL")
|
||||
@created_users_by_week = Hash.new{ |h,k| h[k] = [] }
|
||||
|
|
|
|||
16
app/controllers/invitation_codes_controller.rb
Normal file
16
app/controllers/invitation_codes_controller.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
class InvitationCodesController < ApplicationController
|
||||
before_filter :ensure_valid_invite_code
|
||||
|
||||
rescue_from ActiveRecord::RecordNotFound do
|
||||
redirect_to root_url, :notice => "That invite code is no longer valid"
|
||||
end
|
||||
|
||||
def show
|
||||
sign_out(current_user) if user_signed_in?
|
||||
redirect_to new_user_registration_path(:invite => {:token => params[:id]})
|
||||
end
|
||||
|
||||
def ensure_valid_invite_code
|
||||
InvitationCode.find_by_token!(params[:id])
|
||||
end
|
||||
end
|
||||
|
|
@ -2,12 +2,12 @@
|
|||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
class InvitationsController < Devise::InvitationsController
|
||||
require Rails.root.join('lib', 'email_inviter')
|
||||
|
||||
before_filter :check_token, :only => [:edit, :email]
|
||||
before_filter :check_if_invites_open, :only =>[:create]
|
||||
class InvitationsController < ApplicationController
|
||||
|
||||
def new
|
||||
@invite_code = current_user.invitation_code
|
||||
@sent_invitations = current_user.invitations_from_me.includes(:recipient)
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
|
|
@ -16,65 +16,21 @@ class InvitationsController < Devise::InvitationsController
|
|||
end
|
||||
end
|
||||
|
||||
# this is for legacy invites. We try to look the person who sent them the
|
||||
# invite, and use their new invite code
|
||||
# owe will be removing this eventually
|
||||
# @depreciated
|
||||
def edit
|
||||
user = User.find_by_invitation_token(params[:invitation_token])
|
||||
invitation_code = user.ugly_accept_invitation_code
|
||||
redirect_to invite_code_path(invitation_code)
|
||||
end
|
||||
|
||||
|
||||
def create
|
||||
aspect_id = params[:user].delete(:aspects)
|
||||
message = params[:user].delete(:invite_messages)
|
||||
emails = params[:user][:email].to_s.gsub(/\s/, '').split(/, */)
|
||||
#NOTE should we try and find users by email here? probs
|
||||
aspect = current_user.aspects.find(aspect_id)
|
||||
|
||||
language = params[:user][:language]
|
||||
|
||||
invites = Invitation.batch_invite(emails, :message => message, :sender => current_user, :aspect => aspect, :service => 'email', :language => language)
|
||||
|
||||
flash[:notice] = extract_messages(invites)
|
||||
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
def update
|
||||
invitation_token = params[:user][:invitation_token]
|
||||
|
||||
if invitation_token.nil? || invitation_token.blank?
|
||||
redirect_to :back, :error => I18n.t('invitations.check_token.not_found')
|
||||
return
|
||||
end
|
||||
|
||||
user = User.find_by_invitation_token!(invitation_token)
|
||||
|
||||
user.accept_invitation!(params[:user])
|
||||
|
||||
if user.persisted? && user.person && user.person.persisted?
|
||||
user.seed_aspects
|
||||
flash[:notice] = I18n.t 'registrations.create.success'
|
||||
sign_in_and_redirect(:user, user)
|
||||
else
|
||||
user.errors.delete(:person)
|
||||
flash[:error] = user.errors.full_messages.join(", ")
|
||||
redirect_to accept_user_invitation_path(:invitation_token => params[:user][:invitation_token])
|
||||
end
|
||||
end
|
||||
|
||||
def resend
|
||||
invitation = current_user.invitations_from_me.where(:id => params[:id]).first
|
||||
if invitation
|
||||
Resque.enqueue(Jobs::ResendInvitation, invitation.id)
|
||||
flash[:notice] = I18n.t('invitations.create.sent') + invitation.recipient.email
|
||||
end
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
def email
|
||||
@invs = []
|
||||
@resource = User.find_by_invitation_token(params[:invitation_token])
|
||||
render 'devise/mailer/invitation_instructions', :layout => false
|
||||
end
|
||||
|
||||
protected
|
||||
def check_token
|
||||
if User.find_by_invitation_token(params[:invitation_token]).nil?
|
||||
render 'invitations/token_not_found'
|
||||
end
|
||||
inviter = EmailInviter.new(params[:email_inviter][:emails], current_user, params[:email_inviter])
|
||||
inviter.send!
|
||||
redirect_to :back, :notice => "Great! Invites were sent off to #{inviter.emails.join(', ')}"
|
||||
end
|
||||
|
||||
def check_if_invites_open
|
||||
|
|
@ -84,26 +40,4 @@ class InvitationsController < Devise::InvitationsController
|
|||
return
|
||||
end
|
||||
end
|
||||
|
||||
# @param invites [Array<Invitation>] Invitations to be sent.
|
||||
# @return [String] A full list of success and error messages.
|
||||
def extract_messages(invites)
|
||||
success_message = "Invites Successfully Sent to: "
|
||||
failure_message = "There was a problem with: "
|
||||
following_message = " already are on Diaspora, so you are now sharing with them."
|
||||
successes, failures = invites.partition{|x| x.persisted? }
|
||||
|
||||
followings, real_failures = failures.partition{|x| x.errors[:recipient].present? }
|
||||
|
||||
success_message += successes.map{|k| k.identifier }.to_sentence
|
||||
failure_message += real_failures.map{|k| k.identifier }.to_sentence
|
||||
following_message += followings.map{|k| k.identifier}.to_sentence
|
||||
|
||||
messages = []
|
||||
messages << success_message if successes.present?
|
||||
messages << failure_message if failures.present?
|
||||
messages << following_message if followings.present?
|
||||
|
||||
messages.join('\n')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -3,10 +3,12 @@
|
|||
# the COPYRIGHT file.
|
||||
|
||||
class RegistrationsController < Devise::RegistrationsController
|
||||
before_filter :check_registrations_open!
|
||||
before_filter :check_registrations_open_or_vaild_invite!, :check_valid_invite!
|
||||
|
||||
def create
|
||||
@user = User.build(params[:user])
|
||||
@user.process_invite_acceptence(invite) if invite.present?
|
||||
|
||||
if @user.save
|
||||
flash[:notice] = I18n.t 'registrations.create.success'
|
||||
@user.seed_aspects
|
||||
|
|
@ -14,7 +16,7 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
Rails.logger.info("event=registration status=successful user=#{@user.diaspora_handle}")
|
||||
else
|
||||
@user.errors.delete(:person)
|
||||
|
||||
|
||||
flash[:error] = @user.errors.full_messages.join(";")
|
||||
Rails.logger.info("event=registration status=failure errors='#{@user.errors.full_messages.join(', ')}'")
|
||||
render :new
|
||||
|
|
@ -26,10 +28,26 @@ class RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
|
||||
private
|
||||
def check_registrations_open!
|
||||
def check_valid_invite!
|
||||
return true unless AppConfig[:registrations_closed] #this sucks
|
||||
return true if invite && invite.can_be_used?
|
||||
flash[:error] = t('registrations.invalid_invite')
|
||||
redirect_to new_user_session_path
|
||||
end
|
||||
|
||||
def check_registrations_open_or_vaild_invite!
|
||||
return true if invite.present?
|
||||
if AppConfig[:registrations_closed]
|
||||
flash[:error] = t('registrations.closed')
|
||||
redirect_to new_user_session_path
|
||||
end
|
||||
end
|
||||
|
||||
def invite
|
||||
if params[:invite].present?
|
||||
@invite ||= InvitationCode.find_by_token(params[:invite][:token])
|
||||
end
|
||||
end
|
||||
|
||||
helper_method :invite
|
||||
end
|
||||
|
|
|
|||
|
|
@ -69,54 +69,4 @@ class ServicesController < ApplicationController
|
|||
@service = current_user.services.where(:type => "Services::#{params[:provider].titleize}").first
|
||||
@friends = @service ? @service.finder(:remote => params[:remote]).paginate( :page => params[:page], :per_page => 15) : []
|
||||
end
|
||||
|
||||
def inviter
|
||||
@uid = params[:uid]
|
||||
|
||||
if i_id = params[:invitation_id]
|
||||
invite = Invitation.find(i_id)
|
||||
invited_user = invite.recipient
|
||||
else
|
||||
invite = Invitation.create(:service => params[:provider], :identifier => @uid, :sender => current_user, :aspect => current_user.aspects.find(params[:aspect_id]))
|
||||
invited_user = invite.attach_recipient!
|
||||
end
|
||||
|
||||
#to make sure a friend you just invited from facebook shows up as invited
|
||||
service = current_user.services.where(:type => "Services::Facebook").first
|
||||
su = ServiceUser.where(:service_id => service.id, :uid => @uid).first
|
||||
su.attach_local_models
|
||||
su.save
|
||||
|
||||
respond_to do |format|
|
||||
format.html{ invite_redirect_url(invite, invited_user, su)}
|
||||
format.json{ render :json => invite_redirect_json(invite, invited_user, su) }
|
||||
end
|
||||
end
|
||||
|
||||
def facebook_message_url(user, facebook_uid)
|
||||
subject = t('services.inviter.join_me_on_diaspora')
|
||||
message = <<MSG
|
||||
#{t('services.inviter.click_link_to_accept_invitation')}:
|
||||
\n
|
||||
\n
|
||||
#{accept_invitation_url(user, :invitation_token => user.invitation_token)}
|
||||
MSG
|
||||
"https://www.facebook.com/messages/#{facebook_uid}?msg_prefill=#{message}"
|
||||
end
|
||||
|
||||
def invite_redirect_json(invite, user, service_user)
|
||||
if invite.email_like_identifer
|
||||
{:message => t("invitations.create.sent") + service_user.name }
|
||||
else
|
||||
{:url => facebook_message_url(user, service_user.uid)}
|
||||
end
|
||||
end
|
||||
|
||||
def invite_redirect_url(invite, user, service_user)
|
||||
if invite.email_like_identifer
|
||||
redirect_to(friend_finder_path(:provider => 'facebook'), :notice => "you re-invited #{service_user.name}")
|
||||
else
|
||||
redirect_to(facebook_message_url(user, service_user.uid))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
28
app/helpers/invitation_codes_helper.rb
Normal file
28
app/helpers/invitation_codes_helper.rb
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
module InvitationCodesHelper
|
||||
def invite_welcome_message
|
||||
if invite.present?
|
||||
content_tag(:div) do
|
||||
person_image_link(invite.user.person) +
|
||||
I18n.translate('invitation_codes.excited', :name => invite.user.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def invite_hidden_tag(invite)
|
||||
if invite.present?
|
||||
hidden_field_tag 'invite[token]', invite.token
|
||||
end
|
||||
end
|
||||
|
||||
def invite_link(invite_code)
|
||||
text_field_tag :invite_code, invite_code_url(@invite_code), :readonly => true
|
||||
end
|
||||
|
||||
def invited_by_message
|
||||
inviter = current_user.invited_by
|
||||
if inviter.present?
|
||||
contact = current_user.contact_for(inviter.person) || Contact.new
|
||||
render :partial => 'people/add_contact', :locals => {:inviter => inviter.person, :contact => contact}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -25,11 +25,10 @@ module NotifierHelper
|
|||
end
|
||||
|
||||
def invite_email_title
|
||||
names = @invites.collect{|x| x.sender.person.name}.uniq
|
||||
if @invites.empty? && names.empty?
|
||||
"Accept Your Diaspora* invite!"
|
||||
if @inviter.present?
|
||||
"#{@inviter.person.name} invited you to Diaspora*"
|
||||
else
|
||||
"#{names.to_sentence} invited you to Diaspora*"
|
||||
"Accept Your Diaspora* invite!"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,6 +33,21 @@ class Notifier < ActionMailer::Base
|
|||
mail(default_opts)
|
||||
end
|
||||
|
||||
def invite(email, message, inviter, invitation_code, locale)
|
||||
@inviter = inviter
|
||||
@message = message
|
||||
@locale = locale
|
||||
@invitation_code = invitation_code
|
||||
|
||||
mail_opts = {:to => email, :from => AppConfig[:smtp_sender_address],
|
||||
:subject => I18n.t('notifier.invited!'),
|
||||
:host => AppConfig[:pod_uri].host}
|
||||
|
||||
I18n.with_locale(locale) do
|
||||
mail(mail_opts)
|
||||
end
|
||||
end
|
||||
|
||||
def started_sharing(recipient_id, sender_id)
|
||||
send_notification(:started_sharing, recipient_id, sender_id)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@ class Invitation < ActiveRecord::Base
|
|||
validate :sender_owns_aspect?, :unless => :admin?
|
||||
validates_uniqueness_of :sender_id, :scope => [:identifier, :service], :unless => :admin?
|
||||
|
||||
after_create :queue_send! #TODO make this after_commit :queue_saved!, :on => :create
|
||||
|
||||
|
||||
# @note options hash is passed through to [Invitation.new]
|
||||
# @see [Invitation.new]
|
||||
|
|
@ -33,7 +31,7 @@ class Invitation < ActiveRecord::Base
|
|||
# @option opts [Aspect] :aspect
|
||||
# @option opts [String] :service
|
||||
# @return [Array<Invitation>] An array of [Invitation] models
|
||||
# the valid ones are saved, and the invalid ones are not.
|
||||
# the valid optsnes are saved, and the invalid ones are not.
|
||||
def self.batch_invite(emails, opts)
|
||||
|
||||
users_on_pod = User.where(:email => emails, :invitation_token => nil)
|
||||
|
|
@ -66,36 +64,16 @@ class Invitation < ActiveRecord::Base
|
|||
!email_like_identifer
|
||||
end
|
||||
|
||||
# Attach a recipient [User] to the [Invitation] unless
|
||||
# there is one already present.
|
||||
#
|
||||
# @return [User] The recipient.
|
||||
def attach_recipient!
|
||||
unless self.recipient.present?
|
||||
self.recipient = User.find_or_create_by_invitation(self)
|
||||
self.save
|
||||
end
|
||||
self.recipient
|
||||
end
|
||||
|
||||
# Find or create user, and send that resultant User an
|
||||
# invitation.
|
||||
#
|
||||
# @return [Invitation] self
|
||||
def send!
|
||||
self.attach_recipient!
|
||||
|
||||
# Sets an instance variable in User (set by devise invitable)
|
||||
# This determines whether an email should be sent to the recipient.
|
||||
recipient.skip_invitation = self.skip_email?
|
||||
|
||||
recipient.invite!
|
||||
|
||||
# Logging the invitation action
|
||||
log_hash = {:event => :invitation_sent, :to => self[:identifier], :service => self[:service]}
|
||||
log_hash.merge({:inviter => self.sender.diaspora_handle, :invitier_uid => self.sender.id, :inviter_created_at_unix => self.sender.created_at.to_i}) if self.sender
|
||||
Rails.logger.info(log_hash)
|
||||
|
||||
if email_like_identifer
|
||||
EmailInviter.new(self.identifier, sender).send!
|
||||
else
|
||||
puts "broken facebook invitation_token"
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
|
|
@ -135,19 +113,7 @@ class Invitation < ActiveRecord::Base
|
|||
when 'email'
|
||||
self.identifier
|
||||
when 'facebook'
|
||||
if username = ServiceUser.username_of_service_user_by_uid(self.identifier)
|
||||
unless username.include?('profile.php?')
|
||||
"#{username}@facebook.com"
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def queue_send!
|
||||
unless self.recipient.present?
|
||||
Resque.enqueue(Jobs::Mail::InviteUserByEmail, self.id)
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
41
app/models/invitation_code.rb
Normal file
41
app/models/invitation_code.rb
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
class InvitationCode < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
|
||||
validates_presence_of :user
|
||||
|
||||
before_create :generate_token, :set_default_invite_count
|
||||
|
||||
def to_param
|
||||
token
|
||||
end
|
||||
|
||||
def can_be_used?
|
||||
self.count > 0
|
||||
end
|
||||
|
||||
def add_invites!
|
||||
self.update_attributes(:count => self.count+100)
|
||||
end
|
||||
|
||||
def use!
|
||||
self.update_attributes(:count => self.count-1)
|
||||
end
|
||||
|
||||
def generate_token
|
||||
begin
|
||||
self.token = ActiveSupport::SecureRandom.hex(6)
|
||||
end while InvitationCode.exists?(:token => self[:token])
|
||||
end
|
||||
|
||||
def self.default_inviter_or(user)
|
||||
if AppConfig[:admin_account].present?
|
||||
inviter = User.find_by_username(AppConfig[:admin_account])
|
||||
end
|
||||
inviter ||= user
|
||||
inviter
|
||||
end
|
||||
|
||||
def set_default_invite_count
|
||||
self.count = AppConfig[:invite_count] || 25
|
||||
end
|
||||
end
|
||||
|
|
@ -8,12 +8,11 @@ require 'rest-client'
|
|||
|
||||
class User < ActiveRecord::Base
|
||||
include Encryptor::Private
|
||||
|
||||
include Connecting
|
||||
include Querying
|
||||
include SocialActions
|
||||
|
||||
devise :invitable, :database_authenticatable, :registerable,
|
||||
devise :database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :trackable, :validatable,
|
||||
:timeoutable, :token_authenticatable, :lockable,
|
||||
:lock_strategy => :none, :unlock_strategy => :none
|
||||
|
|
@ -40,7 +39,10 @@ class User < ActiveRecord::Base
|
|||
has_many :invitations_from_me, :class_name => 'Invitation', :foreign_key => :sender_id
|
||||
has_many :invitations_to_me, :class_name => 'Invitation', :foreign_key => :recipient_id
|
||||
has_many :aspects, :order => 'order_id ASC'
|
||||
|
||||
belongs_to :auto_follow_back_aspect, :class_name => 'Aspect'
|
||||
belongs_to :invited_by, :class_name => 'User'
|
||||
|
||||
has_many :aspect_memberships, :through => :aspects
|
||||
|
||||
has_many :contacts
|
||||
|
|
@ -64,7 +66,6 @@ class User < ActiveRecord::Base
|
|||
before_save :guard_unconfirmed_email,
|
||||
:save_person!
|
||||
|
||||
before_create :infer_email_from_invitation_provider
|
||||
|
||||
attr_accessible :getting_started,
|
||||
:password,
|
||||
|
|
@ -106,32 +107,23 @@ class User < ActiveRecord::Base
|
|||
ConversationVisibility.sum(:unread, :conditions => "person_id = #{self.person.id}")
|
||||
end
|
||||
|
||||
# @return [User]
|
||||
def self.find_by_invitation(invitation)
|
||||
service = invitation.service
|
||||
identifier = invitation.identifier
|
||||
|
||||
if service == 'email'
|
||||
existing_user = User.where(:email => identifier).first
|
||||
else
|
||||
existing_user = User.joins(:services).where(:services => {:type => "Services::#{service.titleize}", :uid => identifier}).first
|
||||
#@deprecated
|
||||
def ugly_accept_invitation_code
|
||||
begin
|
||||
self.invitations_to_me.first.sender.invitation_code
|
||||
rescue Exception => e
|
||||
nil
|
||||
end
|
||||
|
||||
if existing_user.nil?
|
||||
i = Invitation.where(:service => service, :identifier => identifier).first
|
||||
existing_user = i.recipient if i
|
||||
end
|
||||
|
||||
existing_user
|
||||
end
|
||||
|
||||
# @return [User]
|
||||
def self.find_or_create_by_invitation(invitation)
|
||||
if existing_user = self.find_by_invitation(invitation)
|
||||
existing_user
|
||||
else
|
||||
self.create_from_invitation!(invitation)
|
||||
end
|
||||
def process_invite_acceptence(invite)
|
||||
self.invited_by = invite.user
|
||||
invite.use!
|
||||
end
|
||||
|
||||
|
||||
def invitation_code
|
||||
InvitationCode.find_or_create_by_user_id(self.id)
|
||||
end
|
||||
|
||||
def hidden_shareables
|
||||
|
|
@ -389,39 +381,6 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
# This method is called when an invited user accepts his invitation
|
||||
#
|
||||
# @param [Hash] opts the options to accept the invitation with
|
||||
# @option opts [String] :username The username the invited user wants.
|
||||
# @option opts [String] :password
|
||||
# @option opts [String] :password_confirmation
|
||||
def accept_invitation!(opts = {})
|
||||
log_hash = {:event => :invitation_accepted, :username => opts[:username], :uid => self.id}
|
||||
log_hash[:inviter] = invitations_to_me.first.sender.diaspora_handle if invitations_to_me.first && invitations_to_me.first.sender
|
||||
|
||||
if self.invited?
|
||||
self.setup(opts)
|
||||
self.invitation_token = nil
|
||||
self.password = opts[:password]
|
||||
self.password_confirmation = opts[:password_confirmation]
|
||||
|
||||
self.save
|
||||
return unless self.errors.empty?
|
||||
|
||||
# moved old Invitation#share_with! logic into here,
|
||||
# but i don't think we want to destroy the invitation
|
||||
# anymore. we may want to just call self.share_with
|
||||
invitations_to_me.each do |invitation|
|
||||
if !invitation.admin? && invitation.sender.share_with(self.person, invitation.aspect)
|
||||
invitation.destroy
|
||||
end
|
||||
end
|
||||
|
||||
log_hash[:status] = "success"
|
||||
Rails.logger.info(log_hash)
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
###Helpers############
|
||||
def self.build(opts = {})
|
||||
|
|
@ -511,14 +470,6 @@ class User < ActiveRecord::Base
|
|||
self.person
|
||||
end
|
||||
|
||||
# Set the User's email to the one they've been invited at, if the user
|
||||
# is being created via an invitation.
|
||||
#
|
||||
# @return [User]
|
||||
def infer_email_from_invitation_provider
|
||||
self.email = self.invitation_identifier if self.invitation_service == 'email'
|
||||
self
|
||||
end
|
||||
|
||||
def no_person_with_same_username
|
||||
diaspora_id = "#{self.username}#{User.diaspora_id_host}"
|
||||
|
|
|
|||
|
|
@ -1,65 +1,47 @@
|
|||
|
||||
.span-24
|
||||
= render :partial => 'admins/admin_bar.haml'
|
||||
%br
|
||||
%br
|
||||
.span-24.prepend-4
|
||||
|
||||
%h3
|
||||
= form_tag 'admin_inviter', :method => :get do
|
||||
email to invite:
|
||||
= text_field_tag 'identifier'
|
||||
= submit_tag 'invite'
|
||||
%h3
|
||||
you currently have
|
||||
= current_user.invitation_code.count
|
||||
invites left
|
||||
= link_to "add_invites", add_invites_path(current_user.invitation_code)
|
||||
|
||||
= form_tag 'admin_inviter', :method => :get do
|
||||
email to invite:
|
||||
= text_field_tag 'identifier'
|
||||
= submit_tag 'invite'
|
||||
|
||||
|
||||
|
||||
%h3
|
||||
user search
|
||||
= form_tag 'user_search', :method => :get do
|
||||
username:
|
||||
= text_field_tag 'user[username]', params[:user][:username]
|
||||
%h3
|
||||
user search
|
||||
= form_tag 'user_search', :method => :get do
|
||||
username:
|
||||
= text_field_tag 'user[username]', params[:user][:username]
|
||||
|
||||
email:
|
||||
= text_field_tag 'user[email]', params[:user][:email]
|
||||
email:
|
||||
= text_field_tag 'user[email]', params[:user][:email]
|
||||
|
||||
invitation identifier:
|
||||
= text_field_tag 'user[invitation_identifier]', params[:user][:invitation_identifier]
|
||||
|
||||
invitation token:
|
||||
= text_field_tag 'user[invitation_token]', params[:user][:invitation_token]
|
||||
= submit_tag 'go'
|
||||
= submit_tag 'go'
|
||||
|
||||
|
||||
= "#{@users.count} users found"
|
||||
%br
|
||||
%br
|
||||
= for user in @users
|
||||
= user.inspect
|
||||
= "#{@users.count} users found"
|
||||
%br
|
||||
- if user.person
|
||||
= user.person.inspect
|
||||
%br
|
||||
- @users.each do |user|
|
||||
= user.inspect
|
||||
%br
|
||||
- if user.person.profile
|
||||
= user.person.profile.inspect
|
||||
- if user.person
|
||||
= user.person.inspect
|
||||
%br
|
||||
- if user.person.profile
|
||||
= user.person.profile.inspect
|
||||
%br
|
||||
= "invite token: #{invite_code_url(user.invited_by.invite_code)}" if user.invited_by.present?
|
||||
= link_to "add_invites", add_invites_path(user.invitation_code)
|
||||
%br
|
||||
= "invite token: #{accept_invitation_url(user, :invitation_token => user.invitation_token)}" if user.invitation_token
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
= javascript_include_tag 'apiconsole'
|
||||
#query
|
||||
%h3 api console
|
||||
= text_field_tag :api
|
||||
= submit_tag 'ping this api', :id => 'api_submit'
|
||||
|
||||
response:
|
||||
%br
|
||||
%br
|
||||
#resp
|
||||
|
||||
|
||||
%br
|
||||
post to Diaspora v1
|
||||
|
||||
|
||||
|
||||
%br
|
||||
%br
|
||||
|
|
@ -8,34 +8,35 @@
|
|||
.description
|
||||
= t('.if_they_accept_info')
|
||||
%br
|
||||
.span-7.append-1
|
||||
.span-7.append-1.last
|
||||
#email_invitation
|
||||
= form_for User.new, :url => invitation_path(User) do |invite|
|
||||
= form_tag new_user_invitation_path do
|
||||
%h4
|
||||
= t('email')
|
||||
= invite.text_field :email, :title => t('.comma_seperated_plz'), :placeholder => 'foo@bar.com, max@foo.com...'
|
||||
%br
|
||||
|
||||
%h4
|
||||
= t('.aspect')
|
||||
= invite.select(:aspects, options_from_collection_for_select(all_aspects, 'id', 'name'))
|
||||
|
||||
= text_field_tag 'email_inviter[emails]' ,nil, :title => t('.comma_seperated_plz'), :placeholder => 'foo@bar.com, max@foo.com...'
|
||||
%br
|
||||
%br
|
||||
|
||||
%h4
|
||||
= t('.language')
|
||||
= invite.select(:language, available_language_options, :selected => current_user.language)
|
||||
= select_tag('email_inviter[locale]', options_from_collection_for_select(available_language_options, "second", "first", :selected => current_user.language))
|
||||
|
||||
%br
|
||||
%br
|
||||
|
||||
%h4
|
||||
= t('.personal_message')
|
||||
= invite.text_area :invite_messages, :rows => 3, :value => t('.check_out_diaspora')
|
||||
= text_area_tag 'email_inviter[message]',nil, :rows => 3, :value => t('.check_out_diaspora')
|
||||
|
||||
%p
|
||||
= invite.submit t('.send_an_invitation')
|
||||
= submit_tag t('.send_an_invitation')
|
||||
|
||||
.clearfix
|
||||
.span-7.prepend-3.last
|
||||
|
||||
or paste them this link!
|
||||
= invite_link(@invite_code)
|
||||
= "#{@invite_code.count} invites left on this code"
|
||||
|
||||
%br
|
||||
%br
|
||||
|
|
|
|||
140
app/views/notifier/invite.html.erb
Normal file
140
app/views/notifier/invite.html.erb
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
<%- self.extend NotifierHelper -%>
|
||||
<head>
|
||||
<title><%=invite_email_title %></title>
|
||||
</head>
|
||||
<p style="background-color: rgb(255, 255, 255); text-align: center; font-size: 11px;"><%= t('devise.mailer.invitation_instructions.displaying_correctly', :link => link_to(t('devise.mailer.invitation_instructions.view_in'), invite_email_url(:invitation_code => @invitation_code), :style => "color: #3F8FBA; text-decoration: none;")).html_safe %> </p>
|
||||
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td style="padding: 30px 15px 0pt; background-color: rgb(221, 221, 221);">
|
||||
<table style="font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; font-size: 16px; color: rgb(51, 51, 51);" align="center" border="0" cellpadding="0" cellspacing="0" width="600">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="background-color: rgb(0, 0, 0);">
|
||||
<a style="display: block;" href="<%= invite_code_url(@invitation_code) %>" target="_blank">
|
||||
<img alt="Diaspora" src="http://dl.dropbox.com/u/15865/diaspora%20logo.png" style="border: 0pt none ; display: block;" height="134" width="600">
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
<td style="padding: 10px 0pt 0px 20px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-size: 44px; font-weight: bold; color: rgb(0, 0, 0);">
|
||||
<%= t('devise.mailer.invitation_instructions.finally') %><br>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr><td style="padding: 0px 20px 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" width="600" height='389'>
|
||||
<a href="<%= invite_code_url(@invitation_code)%>" target="_blank"><img src="http://dl.dropbox.com/u/15865/diaspora_shots.jpg" style="border: 0pt none ; display: block;" width="560">
|
||||
</a></td></tr>
|
||||
|
||||
|
||||
<tr><td style="padding: 0pt 30px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; line-height: 20px;">
|
||||
<%= t('devise.mailer.invitation_instructions.arrived', :strong_diaspora => content_tag(:strong, "DIASPORA*")).html_safe %>
|
||||
<br>
|
||||
<br>
|
||||
<%= link_to(t('devise.mailer.invitation_instructions.sign_up_now').html_safe, invite_code_url(@invitation_code), :style => "color: #3F8FBA; text-decoration: underline; font-weight: bold; font-size: 20px;", :target => "_blank").html_safe %>
|
||||
</td></tr>
|
||||
|
||||
|
||||
<% if @inviter.present? %>
|
||||
<%= @inviter.inspect %>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
||||
<tr><td style="padding: 20px 20px 0px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-size: 44px; font-weight: bold; color: rgb(0, 0, 0);">
|
||||
1. <%= t('devise.mailer.invitation_instructions.get_connected') %></td></tr>
|
||||
<tr><td>
|
||||
<table style="padding: 0pt 20px; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 16px; color: rgb(51, 51, 51); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" align="center" border="0" cellpadding="0" cellspacing="0" width="600">
|
||||
<tbody><tr>
|
||||
<td width="200">
|
||||
<a href="<%=invite_code_url(@invitation_code) %>" target="_blank"><img style="border: 0pt none ; padding: 0pt 10px 0px 5px; display: block;" src="https://joindiaspora.s3.amazonaws.com/uploads/images/scaled_full_c7506ec0b3ae6694c64d.gif" height="156" width="200"></a>
|
||||
</td>
|
||||
<td style="line-height: 20px; width: 360px;">
|
||||
<%= t('devise.mailer.invitation_instructions.get_connected_paragraph', :strong_diaspora => content_tag(:strong, "DIASPORA*")).html_safe %>
|
||||
<br>
|
||||
<!-- <a style="color: #3F8FBA; text-decoration: underline; font-weight: bold; font-size: 20px;" href="https://joindiaspora.com/channels" target="_blank">Tune in to your favorite Channels</a>-->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</td></tr>
|
||||
|
||||
<tr><td style="padding: 20px 20px 0px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-size: 44px; font-weight: bold; color: rgb(0, 0, 0);">
|
||||
2. <%= t('devise.mailer.invitation_instructions.be_yourself') %></td></tr>
|
||||
<tr><td>
|
||||
<table style="padding: 0pt 20px; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 16px; color: rgb(51, 51, 51); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" align="center" border="0" cellpadding="0" cellspacing="0" width="600">
|
||||
<tbody><tr>
|
||||
<td style="line-height: 20px; width: 360px;">
|
||||
|
||||
<%= t('devise.mailer.invitation_instructions.be_yourself_paragraph', :strong_diaspora => content_tag(:strong, "DIASPORA*")).html_safe %>
|
||||
|
||||
<br>
|
||||
<!-- <a style="color: #3F8FBA; text-decoration: underline; font-weight: bold; font-size: 20px;" href="#" target="_blank">Watch all the bumpers</a>-->
|
||||
</td>
|
||||
|
||||
<td width="200">
|
||||
<a href="<%= invite_code_url(@invitation_code)%>" target="_blank"><img style="border: 0pt none ; padding: 0pt 5px 0px 10px; display: block;" src="http://dl.dropbox.com/u/15865/apolonisaphrodisia.png" height="150" width="170"></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</td></tr>
|
||||
|
||||
|
||||
<tr><td style="padding: 20px 20px 0px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-size: 44px; font-weight: bold; color: rgb(0, 0, 0);">
|
||||
3. <%= t('devise.mailer.invitation_instructions.have_fun') %></td></tr>
|
||||
<tr><td>
|
||||
<table style="padding: 0pt 20px; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 16px; color: rgb(51, 51, 51); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" align="center" border="0" cellpadding="0" cellspacing="0" width="600">
|
||||
<tbody><tr>
|
||||
<td width="200">
|
||||
<a href="<%= invite_code_url(@invitation_code)%>" target="_blank"><img style="border: 0pt none ; padding: 0pt 5px; display: block;" src="http://joindiaspora.com/images/cubbies_screenshot2.png" height="151" width="200"></a>
|
||||
</td>
|
||||
<td style="line-height: 20px; width: 360px;">
|
||||
|
||||
<%= t('devise.mailer.invitation_instructions.have_fun_paragraph', :strong_diaspora => content_tag(:strong, "DIASPORA*"), :link => link_to(t('devise.mailer.invitation_instructions.cubbies'), "https://cubbi.es", :style => "color: #3F8FBA; text-decoration: underline; font-weight: bold; font-size: 20px;", :target => "_blank")).html_safe %>
|
||||
<!-- <a style="color: #3F8FBA; text-decoration: underline; font-weight: bold; font-size: 20px;" href="#" target="_blank">Watch all the bumpers</a>-->
|
||||
</td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</td></tr>
|
||||
|
||||
<tr><td>
|
||||
<table style="padding: 0pt 20px; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 16px; color: rgb(51, 51, 51); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" align="center" border="0" cellpadding="0" cellspacing="0" width="600">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="padding: 40px 20px 20px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
|
||||
<%= link_to(t('devise.mailer.invitation_instructions.sign_up_now').html_safe, invite_code_url(@invitation_code), :style => "color: #3F8FBA; text-decoration: underline; font-weight: bold; font-size: 20px;", :target => "_blank").html_safe %>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td></tr>
|
||||
|
||||
<tr><td>
|
||||
<table style="padding: 0pt 20px; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 16px; color: rgb(51, 51, 51); -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;" align="center" border="0" cellpadding="0" cellspacing="0" width="600">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="padding: 20px 20px 0px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
|
||||
<%= t('devise.mailer.invitation_instructions.made_by_people', :strong_diaspora => content_tag(:strong, "DIASPORA*"), :jointeam => link_to(t('devise.mailer.invitation_instructions.join_team'), "https://github.com/diaspora/diaspora/wiki/Become-a-Contributor", :style =>"color: #3F8FBA; text-decoration: underline; font-weight: bold; font-size: 18px;", :target => "_blank"), :helpfund => link_to(t('devise.mailer.invitation_instructions.help_fund'), "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QG4L6VYD8YGPU", :style =>"color: #3F8FBA; text-decoration: underline; font-weight: bold; font-size: 18px;", :target => "_blank")).html_safe %>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td></tr>
|
||||
|
||||
<tr><td style="padding: 35px 20px 20px; background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
|
||||
<%= t('devise.mailer.invitation_instructions.love') %><br>
|
||||
<%= t('devise.mailer.invitation_instructions.team_diaspora') %><br>
|
||||
</td></tr>
|
||||
<tr><td style="padding: 35px 40px; font-size: 11px; color: rgb(102, 102, 102); line-height: 16px;">
|
||||
<% if AppConfig[:pod_uri].host.match(/joindiaspora.com/) %>
|
||||
<%= t('devise.mailer.invitation_instructions.unsubscribe', :link => link_to(t('devise.mailer.invitation_instructions.here'), "http://joindiaspora.us1.list-manage.com/unsubscribe?u=d759919b94f9cdcf39d204f3f&id=7b5ceb2f8b", :style => "color: #3F8FBA; text-decoration: none;")).html_safe %>
|
||||
<% end %>
|
||||
<%= t('devise.mailer.invitation_instructions.email_us', :email => link_to(t('devise.mailer.invitation_instructions.email_address'), "mailto:questions@joindiaspora.com", :style => "color: #3F8FBA; text-decoration: none;")).html_safe %>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
12
app/views/notifier/invite.text.erb
Normal file
12
app/views/notifier/invite.text.erb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
Hello!
|
||||
|
||||
You have been invited to join Diaspora*!
|
||||
|
||||
Click this link to get started
|
||||
|
||||
<%= invite_code_url(@invitation_code)%>
|
||||
|
||||
|
||||
Love,
|
||||
|
||||
The Diaspora* email robot!
|
||||
5
app/views/people/_add_contact.html.haml
Normal file
5
app/views/people/_add_contact.html.haml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.alert-message.block-message.success
|
||||
you were invited by
|
||||
= person_image_link inviter
|
||||
= person_link inviter
|
||||
= aspect_membership_dropdown(contact, inviter, false)
|
||||
|
|
@ -11,16 +11,19 @@
|
|||
= t('welcome')
|
||||
%h3.accept_invitation_text
|
||||
= t('.sign_up_message')
|
||||
|
||||
- flash.each do |name, msg|
|
||||
%p{:class => "login_#{name}"}= msg
|
||||
|
||||
= image_tag 'diaspora_collage.png', :style => "margin-left:-50px;"
|
||||
|
||||
.span-10
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
%br
|
||||
|
||||
= invite_welcome_message
|
||||
|
||||
= form_for(resource, :as => resource_name, :html => {:class => 'new_user_form'}, :url => registration_path(resource_name), :validate => true) do |f|
|
||||
%fieldset
|
||||
.clearfix
|
||||
|
|
@ -42,6 +45,10 @@
|
|||
= t('password_confirmation')
|
||||
= f.password_field :password_confirmation, :title => t('registrations.new.enter_password_again')
|
||||
|
||||
.clearfix
|
||||
|
||||
= invite_hidden_tag(invite)
|
||||
|
||||
.submit_field
|
||||
= f.submit t('registrations.new.create_my_account'), :class => 'in_aspects'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
.stream_element{:id => friend.id}
|
||||
.float-right
|
||||
|
||||
- if friend.already_invited?
|
||||
= link_to t('.resend'), service_inviter_path(:uid => friend.uid, :provider => 'facebook', :invitation_id => friend.invitation_id), :class => 'button resend'
|
||||
- elsif friend.on_diaspora?
|
||||
- if friend.on_diaspora?
|
||||
= aspect_membership_dropdown(contact_proxy(friend), friend.person, 'left')
|
||||
- else
|
||||
= render 'shared/aspect_dropdown', :selected_aspects => contact_proxy(friend).aspects, :person => friend.person, :hang => 'left', :dropdown_class => 'inviter', :service_uid => friend.uid
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
%p.center
|
||||
= t(".community_welcome")
|
||||
|
||||
= invited_by_message
|
||||
|
||||
.clearfix
|
||||
%br
|
||||
%br
|
||||
|
|
|
|||
|
|
@ -49,6 +49,12 @@ defaults: &defaults
|
|||
# Set this to true if you want users to invite as many people as they want
|
||||
open_invitations: true
|
||||
|
||||
#the 'admin' account for your pod... ie for jd.com, this is diasporahq
|
||||
admin_account: ''
|
||||
|
||||
#the default amount of invitiations for an invite link
|
||||
invite_count: 25
|
||||
|
||||
# Set this to true if you don't want your users to follow the diasporahq@joindiaspora.com
|
||||
# account on account creation. The diasporahq account helps users start with some
|
||||
# activity in their stream and get news about Diaspora, but if you don't want your server
|
||||
|
|
|
|||
|
|
@ -319,6 +319,8 @@ en:
|
|||
simplicity_explanation: "Diaspora makes sharing clean and easy – and this goes for privacy too. Inherently private, Diaspora doesn’t make you wade through pages of settings and options just to keep your profile secure."
|
||||
learn_about_host: "Learn about how to host your own Diaspora server."
|
||||
|
||||
invitation_codes:
|
||||
excited: "%{name} is excited to see you here."
|
||||
invitations:
|
||||
create:
|
||||
sent: "Invitations have been sent to: "
|
||||
|
|
@ -332,6 +334,7 @@ en:
|
|||
invite_someone_to_join: "Invite someone to join Diaspora!"
|
||||
if_they_accept_info: "if they accept, they will be added to the aspect you invited them."
|
||||
comma_seperated_plz: "You can enter multiple email addresses separated by commas."
|
||||
check_out_diaspora: "Hey! You should check out Diaspora*"
|
||||
to: "To"
|
||||
personal_message: "Personal message"
|
||||
send_an_invitation: "Send an invitation"
|
||||
|
|
@ -679,6 +682,7 @@ en:
|
|||
update: "Update"
|
||||
cancel_my_account: "Cancel my account"
|
||||
closed: "Signups are closed on this Diaspora pod."
|
||||
invalid_invite: "The invite link you provided is no longer valid!"
|
||||
|
||||
requests:
|
||||
manage_aspect_contacts:
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@
|
|||
# the COPYRIGHT file.
|
||||
|
||||
Diaspora::Application.routes.draw do
|
||||
|
||||
# Posting and Reading
|
||||
|
||||
resources :reshares
|
||||
|
||||
resources :status_messages, :only => [:new, :create]
|
||||
|
|
@ -33,6 +31,7 @@ Diaspora::Application.routes.draw do
|
|||
get "liked" => "streams#liked", :as => "liked_stream"
|
||||
get "commented" => "streams#commented", :as => "commented_stream"
|
||||
get "aspects" => "streams#aspects", :as => "aspects_stream"
|
||||
|
||||
|
||||
resources :aspects do
|
||||
put :toggle_contact_visibility
|
||||
|
|
@ -97,11 +96,13 @@ Diaspora::Application.routes.draw do
|
|||
|
||||
devise_for :users, :controllers => {:registrations => "registrations",
|
||||
:password => "devise/passwords",
|
||||
:sessions => "sessions",
|
||||
:invitations => "invitations"} do
|
||||
get 'invitations/resend/:id' => 'invitations#resend', :as => 'invitation_resend'
|
||||
get 'invitations/email' => 'invitations#email', :as => 'invite_email'
|
||||
end
|
||||
:sessions => "sessions"}
|
||||
|
||||
#legacy routes to support old invite routes
|
||||
get 'users/invitations/accept' => 'invitations#edit'
|
||||
get 'users/invitations/email' => 'invitations#email', :as => 'invite_email'
|
||||
get 'users/invitations' => 'invitations#new', :as => 'new_user_invitation'
|
||||
post 'users/invitations' => 'invitations#create', :as => 'new_user_invitation'
|
||||
|
||||
get 'login' => redirect('/users/sign_in')
|
||||
|
||||
|
|
@ -111,6 +112,7 @@ Diaspora::Application.routes.draw do
|
|||
get :weekly_user_stats
|
||||
get :correlations
|
||||
get :stats, :as => 'pod_stats'
|
||||
get "add_invites/:invite_code_id" => 'admins#add_invites', :as => 'add_invites'
|
||||
end
|
||||
|
||||
resource :profile, :only => [:edit, :update]
|
||||
|
|
@ -122,7 +124,7 @@ Diaspora::Application.routes.draw do
|
|||
resources :share_visibilities, :only => [:update]
|
||||
resources :blocks, :only => [:create, :destroy]
|
||||
|
||||
get 'community_spotlight' => "contacts#spotlight", :as => 'community_spotlight'
|
||||
get 'i/:id' => 'invitation_codes#show', :as => 'invite_code'
|
||||
|
||||
get 'people/refresh_search' => "people#refresh_search"
|
||||
resources :people, :except => [:edit, :update] do
|
||||
|
|
@ -189,7 +191,7 @@ Diaspora::Application.routes.draw do
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
get 'community_spotlight' => "contacts#spotlight", :as => 'community_spotlight'
|
||||
# Mobile site
|
||||
|
||||
get 'mobile/toggle', :to => 'home#toggle_mobile', :as => 'toggle_mobile'
|
||||
|
|
|
|||
|
|
@ -166,7 +166,6 @@ class CreateImportTables < ActiveRecord::Migration
|
|||
t.string :language
|
||||
t.string :email
|
||||
t.database_authenticatable
|
||||
t.invitable
|
||||
t.recoverable
|
||||
t.rememberable
|
||||
t.trackable
|
||||
|
|
|
|||
15
db/migrate/20111211213438_create_invitation_codes.rb
Normal file
15
db/migrate/20111211213438_create_invitation_codes.rb
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
class CreateInvitationCodes < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :invitation_codes do |t|
|
||||
t.string :token
|
||||
t.integer :user_id
|
||||
t.integer :count
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :invitation_codes
|
||||
end
|
||||
end
|
||||
|
|
@ -109,6 +109,14 @@ ActiveRecord::Schema.define(:version => 20120301143226) do
|
|||
|
||||
add_index "conversations", ["author_id"], :name => "conversations_author_id_fk"
|
||||
|
||||
create_table "invitation_codes", :force => true do |t|
|
||||
t.string "token"
|
||||
t.integer "user_id"
|
||||
t.integer "count"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
create_table "invitations", :force => true do |t|
|
||||
t.text "message"
|
||||
t.integer "sender_id"
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Feature: invitation acceptance
|
|||
Then I should be on the stream page
|
||||
|
||||
Scenario: accept invitation from user
|
||||
Given I have been invited by a user
|
||||
Given I have been invited by bob
|
||||
And I am on my acceptance form page
|
||||
And I fill in the following:
|
||||
| user_username | ohai |
|
||||
|
|
@ -35,11 +35,15 @@ Feature: invitation acceptance
|
|||
And I preemptively confirm the alert
|
||||
And I follow "awesome_button"
|
||||
Then I should be on the stream page
|
||||
And I log out
|
||||
And I sign in as "bob@bob.bob"
|
||||
And I follow "By email"
|
||||
Then I should see one less invite
|
||||
|
||||
Scenario: sends an invitation
|
||||
Given a user with email "bob@bob.bob"
|
||||
When I sign in as "bob@bob.bob"
|
||||
And I follow "By email"
|
||||
And I fill in "user_email" with "alex@example.com"
|
||||
And I fill in "email_inviter_emails" with "alex@example.com"
|
||||
And I press "Send an invitation"
|
||||
Then I should have 1 Devise email delivery
|
||||
|
|
|
|||
10
features/invitations.feature
Normal file
10
features/invitations.feature
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
@javascript
|
||||
Feature: Invitations
|
||||
|
||||
Scenario: Accepting an invitation
|
||||
When I visit alice's invitation code url
|
||||
Then I should see the "alice is excited" message
|
||||
When I fill in the new user form
|
||||
And I press "Create my account!"
|
||||
Then I should see the "welcome to diaspora" message
|
||||
And I should be able to friend Alice
|
||||
|
|
@ -11,6 +11,7 @@ Then /^I should see the "(.*)" message$/ do |message|
|
|||
I18n.translate('profiles.edit.you_are_nsfw')
|
||||
else
|
||||
raise "muriel, you don't have that message key, add one here"
|
||||
end
|
||||
end
|
||||
|
||||
page.should have_content(text)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,15 +26,21 @@ Given /^a nsfw user with email "([^\"]*)"$/ do |email|
|
|||
end
|
||||
|
||||
Given /^I have been invited by an admin$/ do
|
||||
i = Invitation.create!(:admin => true, :service => 'email', :identifier => "new_invitee@example.com")
|
||||
@me = i.attach_recipient!
|
||||
admin = Factory(:user)
|
||||
admin.invitation_code
|
||||
i = EmailInviter.new("new_invitee@example.com", admin)
|
||||
i.send!
|
||||
end
|
||||
|
||||
Given /^I have been invited by a user$/ do
|
||||
@inviter = Factory(:user)
|
||||
aspect = @inviter.aspects.create(:name => "Rocket Scientists")
|
||||
i = Invitation.create!(:aspect => aspect, :sender => @inviter, :service => 'email', :identifier => "new_invitee@example.com", :message =>"Hey, tell me about your rockets!")
|
||||
@me = i.attach_recipient!
|
||||
Given /^I have been invited by bob$/ do
|
||||
@inviter = Factory(:user, :email => 'bob@bob.bob')
|
||||
@inviter_invite_count = @inviter.invitation_code.count
|
||||
i = EmailInviter.new("new_invitee@example.com", @inviter)
|
||||
i.send!
|
||||
end
|
||||
|
||||
When /^I should see one less invite$/ do
|
||||
step "I should see \"#{@inviter_invite_count -1} invites left\""
|
||||
end
|
||||
|
||||
When /^I click on my name$/ do
|
||||
|
|
@ -167,3 +173,22 @@ When /^I view "([^\"]*)"'s first post$/ do |email|
|
|||
post = user.posts.first
|
||||
visit post_path(post)
|
||||
end
|
||||
|
||||
Given /^I visit alice's invitation code url$/ do
|
||||
@alice ||= Factory(:user, :username => 'alice', :getting_started => false)
|
||||
invite_code = InvitationCode.find_or_create_by_user_id(@alice.id)
|
||||
visit invite_code_path(invite_code)
|
||||
end
|
||||
|
||||
When /^I fill in the new user form$/ do
|
||||
step 'I fill in "user_username" with "ohai"'
|
||||
step 'I fill in "user_email" with "ohai@example.com"'
|
||||
step 'I fill in "user_password" with "secret"'
|
||||
step 'I fill in "user_password_confirmation" with "secret"'
|
||||
end
|
||||
|
||||
And /^I should be able to friend Alice$/ do
|
||||
alice = User.find_by_username 'alice'
|
||||
step 'I should see "Add contact"'
|
||||
step "I should see \"#{alice.name}\""
|
||||
end
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ module NavigationHelpers
|
|||
when /^my profile page$/
|
||||
person_path(@me.person)
|
||||
when /^my acceptance form page$/
|
||||
accept_user_invitation_path(:invitation_token => @me.invitation_token)
|
||||
invite_code_path(InvitationCode.first)
|
||||
when /^the requestors profile$/
|
||||
person_path(Request.where(:recipient_id => @me.person.id).first.sender)
|
||||
when /^"([^\"]*)"'s page$/
|
||||
|
|
|
|||
30
lib/email_inviter.rb
Normal file
30
lib/email_inviter.rb
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
class EmailInviter
|
||||
attr_accessor :emails, :message, :inviter, :locale
|
||||
|
||||
def initialize(emails, inviter, options={})
|
||||
self.message = options[:message]
|
||||
self.locale = options.fetch(:locale, 'en')
|
||||
self.inviter = inviter
|
||||
self.emails = emails
|
||||
end
|
||||
|
||||
def emails=(list)
|
||||
emails = list.split(%r{[,\s]+})
|
||||
emails.reject!{|x| x == inviter.email } unless inviter.nil?
|
||||
@emails = emails
|
||||
end
|
||||
|
||||
def invitation_code
|
||||
@invitation_code ||= inviter.invitation_code
|
||||
end
|
||||
|
||||
def send!
|
||||
self.emails.each{ |email| mail(email)}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def mail(email)
|
||||
Notifier.invite(email, message, inviter, invitation_code, locale).deliver!
|
||||
end
|
||||
end
|
||||
|
|
@ -26,10 +26,15 @@ module RakeHelpers
|
|||
possible_invite = Invitation.find_by_identifier(backer_email)
|
||||
possible_user ||= possible_invite.recipient if possible_invite.present?
|
||||
|
||||
admin_account = User.find_by_username(AppConfig[:admin_account])
|
||||
raise "no admin_account in application.yml" unless admin_account.present?
|
||||
admin_account.invitation_code.count += num_to_process
|
||||
admin_account.invitation_code.save
|
||||
|
||||
unless possible_user
|
||||
puts "#{n}: sending email to: #{backer_name} #{backer_email}" unless Rails.env == 'test'
|
||||
unless test
|
||||
i = Invitation.new(:service => 'email', :identifier => backer_email, :admin => true)
|
||||
i = EmailInviter.new(backer_email)
|
||||
i.send!
|
||||
end
|
||||
else
|
||||
|
|
|
|||
|
|
@ -73,11 +73,6 @@ describe AdminsController do
|
|||
AppConfig[:admins] = [@user.username]
|
||||
end
|
||||
|
||||
it 'succeeds' do
|
||||
get :admin_inviter, :identifier => 'bob@moms.com'
|
||||
response.should be_redirect
|
||||
end
|
||||
|
||||
it 'does not die if you do it twice' do
|
||||
get :admin_inviter, :identifier => 'bob@moms.com'
|
||||
get :admin_inviter, :identifier => 'bob@moms.com'
|
||||
|
|
@ -85,7 +80,7 @@ describe AdminsController do
|
|||
end
|
||||
|
||||
it 'invites a new user' do
|
||||
Invitation.should_receive(:create)
|
||||
EmailInviter.should_receive(:new).and_return(stub.as_null_object)
|
||||
get :admin_inviter, :identifier => 'bob@moms.com'
|
||||
response.should redirect_to user_search_path
|
||||
flash.notice.should include("invitation sent")
|
||||
|
|
|
|||
|
|
@ -5,16 +5,11 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe InvitationsController do
|
||||
include Devise::TestHelpers
|
||||
|
||||
before do
|
||||
AppConfig[:open_invitations] = true
|
||||
@user = alice
|
||||
@aspect = @user.aspects.first
|
||||
@invite = {:invite_message=>"test", :aspects=> @aspect.id.to_s, :email=>"abc@example.com"}
|
||||
|
||||
request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
Webfinger.stub_chain(:new, :fetch).and_return(Factory(:person))
|
||||
@invite = {'email_inviter' => {'message' => "test", 'emails' => "abc@example.com"}}
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
|
|
@ -24,120 +19,26 @@ describe InvitationsController do
|
|||
request.env["HTTP_REFERER"]= 'http://test.host/cats/foo'
|
||||
end
|
||||
|
||||
it 'saves an invitation' do
|
||||
expect {
|
||||
post :create, :user => @invite
|
||||
}.should change(Invitation, :count).by(1)
|
||||
it 'creates an EmailInviter' do
|
||||
inviter = stub(:emails => ['mbs@gmail.com'], :send! => true)
|
||||
EmailInviter.should_receive(:new).with(@invite['email_inviter']['emails'], @user, @invite['email_inviter']).
|
||||
and_return(inviter)
|
||||
post :create, @invite
|
||||
end
|
||||
|
||||
it 'handles a comma-separated list of emails' do
|
||||
expect{
|
||||
post :create, :user => @invite.merge(
|
||||
:email => "foofoofoofoo@example.com, mbs@gmail.com")
|
||||
}.should change(Invitation, :count).by(2)
|
||||
end
|
||||
|
||||
it 'handles a comma-separated list of emails with whitespace' do
|
||||
expect {
|
||||
post :create, :user => @invite.merge(
|
||||
:email => "foofoofoofoo@example.com , mbs@gmail.com")
|
||||
}.should change(Invitation, :count).by(2)
|
||||
end
|
||||
|
||||
it "allows invitations without if invitations are open" do
|
||||
it "redirects if invitations are closed" do
|
||||
open_bit = AppConfig[:open_invitations]
|
||||
AppConfig[:open_invitations] = true
|
||||
AppConfig[:open_invitations] = false
|
||||
|
||||
expect{
|
||||
post :create, :user => @invite
|
||||
}.to change(Invitation, :count).by(1)
|
||||
post :create, @invite
|
||||
response.should be_redirect
|
||||
AppConfig[:open_invitations] = open_bit
|
||||
end
|
||||
|
||||
it 'returns to the previous page on success' do
|
||||
post :create, :user => @invite
|
||||
post :create, @invite
|
||||
response.should redirect_to("http://test.host/cats/foo")
|
||||
end
|
||||
|
||||
it 'strips out your own email' do
|
||||
lambda {
|
||||
post :create, :user => @invite.merge(:email => @user.email)
|
||||
}.should_not change(Invitation, :count)
|
||||
|
||||
expect{
|
||||
post :create, :user => @invite.merge(:email => "hello@example.org, #{@user.email}")
|
||||
}.should change(Invitation, :count).by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#email" do
|
||||
before do
|
||||
invites = Invitation.batch_invite(["foo@example.com"], :message => "hi", :sender => @user, :aspect => @user.aspects.first, :service => 'email', :language => "en-US")
|
||||
invites.first.send!
|
||||
@invited_user = User.find_by_email("foo@example.com")
|
||||
end
|
||||
|
||||
it "succeeds" do
|
||||
get :email, :invitation_token => @invited_user.invitation_token
|
||||
response.should be_success
|
||||
end
|
||||
|
||||
it "shows an error if there's no such invitation token" do
|
||||
get :email, :invitation_token => "12345"
|
||||
response.should render_template(:token_not_found)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
before do
|
||||
invite = Factory(:invitation, :sender => @user, :service => 'email', :identifier => "a@a.com")
|
||||
@invited_user = invite.attach_recipient!
|
||||
|
||||
@accept_params = {:user=>
|
||||
{:password_confirmation =>"password",
|
||||
:email => "a@a.com",
|
||||
:username=>"josh",
|
||||
:password=>"password",
|
||||
:invitation_token => @invited_user.invitation_token}}
|
||||
|
||||
end
|
||||
|
||||
context 'success' do
|
||||
let(:invited) {User.find_by_username(@accept_params[:user][:username])}
|
||||
|
||||
it 'creates a user' do
|
||||
put :update, @accept_params
|
||||
invited.should_not be_nil
|
||||
end
|
||||
|
||||
it 'seeds the aspects' do
|
||||
put :update, @accept_params
|
||||
invited.aspects.count.should == 4
|
||||
end
|
||||
|
||||
it 'adds a contact' do
|
||||
lambda {
|
||||
put :update, @accept_params
|
||||
}.should change(@user.contacts, :count).by(1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'failure' do
|
||||
before do
|
||||
@fail_params = @accept_params
|
||||
@fail_params[:user][:username] = @user.username
|
||||
end
|
||||
|
||||
it 'stays on the invitation accept form' do
|
||||
put :update, @fail_params
|
||||
response.location.include?(accept_user_invitation_path).should be_true
|
||||
end
|
||||
|
||||
it 'keeps the invitation token' do
|
||||
put :update, @fail_params
|
||||
response.location.include?("invitation_token=#{@invited_user.invitation_token}").should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#new' do
|
||||
|
|
@ -146,43 +47,4 @@ describe InvitationsController do
|
|||
get :new
|
||||
end
|
||||
end
|
||||
|
||||
describe '#resend' do
|
||||
before do
|
||||
sign_in :user, @user
|
||||
@controller.stub!(:current_user).and_return(@user)
|
||||
request.env["HTTP_REFERER"]= 'http://test.host/cats/foo'
|
||||
|
||||
invite = Factory(:invitation, :sender => @user, :service => 'email', :identifier => "a@a.com")
|
||||
@invited_user = invite.attach_recipient!
|
||||
end
|
||||
|
||||
it 'calls resend invitation if one exists' do
|
||||
@user.reload.invitations_from_me.count.should == 1
|
||||
invitation = @user.invitations_from_me.first
|
||||
Resque.should_receive(:enqueue)
|
||||
put :resend, :id => invitation.id
|
||||
end
|
||||
|
||||
it 'does not send an invitation for a different user' do
|
||||
invitation2 = Factory(:invitation, :sender => bob, :service => 'email', :identifier => "a@a.com")
|
||||
|
||||
Resque.should_not_receive(:enqueue)
|
||||
put :resend, :id => invitation2.id
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe '#extract_messages' do
|
||||
before do
|
||||
sign_in alice
|
||||
end
|
||||
it 'displays a message that tells the user how many invites were sent, and which REJECTED' do
|
||||
post :create, :user => @invite.merge(
|
||||
:email => "mbs@gmail.com, foo@bar.com, foo.com, lala@foo, cool@bar.com")
|
||||
flash[:notice].should_not be_blank
|
||||
flash[:notice].should =~ /foo\.com/
|
||||
flash[:notice].should =~ /lala@foo/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -39,10 +39,25 @@ describe RegistrationsController do
|
|||
flash[:error].should == I18n.t('registrations.closed')
|
||||
response.should redirect_to new_user_session_path
|
||||
end
|
||||
|
||||
it 'does not redirect if there is a valid invite token' do
|
||||
i = InvitationCode.create(:user => bob)
|
||||
get :new, :invite => {:token => i.token}
|
||||
response.should_not be_redirect
|
||||
end
|
||||
|
||||
it 'does redirect if there is an invalid invite token' do
|
||||
get :new, :invite => {:token => 'fssdfsd'}
|
||||
response.should be_redirect
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
context "with valid parameters" do
|
||||
before do
|
||||
AppConfig[:registrations_closed] = false
|
||||
end
|
||||
|
||||
before do
|
||||
user = Factory.build(:user)
|
||||
User.stub!(:build).and_return(user)
|
||||
|
|
|
|||
|
|
@ -143,51 +143,4 @@ describe ServicesController do
|
|||
Nokogiri(response.body).css('.translation_missing').should be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe '#inviter' do
|
||||
before do
|
||||
@uid = "abc"
|
||||
fb = Factory(:service, :type => "Services::Facebook", :user => @user)
|
||||
fb = Services::Facebook.find(fb.id)
|
||||
@su = Factory(:service_user, :service => fb, :uid => @uid)
|
||||
@invite_params = {:provider => 'facebook', :uid => @uid, :aspect_id => @user.aspects.first.id}
|
||||
end
|
||||
|
||||
it 'redirects to a prefilled facebook message url' do
|
||||
put :inviter, @invite_params
|
||||
response.location.should match(/https:\/\/www\.facebook\.com\/messages\/.*?msg_prefill=.*/)
|
||||
end
|
||||
|
||||
it 'creates an invitation' do
|
||||
lambda {
|
||||
put :inviter, @invite_params
|
||||
}.should change(Invitation, :count).by(1)
|
||||
end
|
||||
|
||||
it 'sets the invitation_id on the service_user' do
|
||||
post :inviter, @invite_params
|
||||
@su.reload.invitation.should_not be_nil
|
||||
end
|
||||
|
||||
it 'does not create a duplicate invitation' do
|
||||
invited_user = Factory.build(:user, :username =>nil)
|
||||
invited_user.save(:validate => false)
|
||||
inv = Invitation.create!(:sender => @user, :recipient => invited_user, :aspect => @user.aspects.first, :identifier => eve.email)
|
||||
@invite_params[:invitation_id] = inv.id
|
||||
|
||||
lambda {
|
||||
put :inviter, @invite_params
|
||||
}.should_not change(Invitation, :count)
|
||||
end
|
||||
|
||||
it 'disregards the amount of invites if open_invitations are enabled' do
|
||||
open_bit = AppConfig[:open_invitations]
|
||||
AppConfig[:open_invitations] = true
|
||||
|
||||
lambda {
|
||||
put :inviter, @invite_params
|
||||
}.should change(Invitation, :count).by(1)
|
||||
AppConfig[:open_invitations] = open_bit
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -130,6 +130,12 @@ FactoryGirl.define do
|
|||
end
|
||||
end
|
||||
|
||||
factory :invitation_code do
|
||||
sequence(:token){|n| "sdfsdsf#{n}"}
|
||||
association :user
|
||||
count 0
|
||||
end
|
||||
|
||||
factory :service do |service|
|
||||
nickname "sirrobertking"
|
||||
type "Services::Twitter"
|
||||
|
|
@ -239,4 +245,4 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
factory(:status, :parent => :status_message)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
15
spec/helpers/invitation_codes_helper_spec.rb
Normal file
15
spec/helpers/invitation_codes_helper_spec.rb
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
require 'spec_helper'
|
||||
|
||||
# Specs in this file have access to a helper object that includes
|
||||
# the InvitationCodesHelper. For example:
|
||||
#
|
||||
# describe InvitationCodesHelper do
|
||||
# describe "string concat" do
|
||||
# it "concats two strings with spaces" do
|
||||
# helper.concat_strings("this","that").should == "this that"
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
describe InvitationCodesHelper do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
56
spec/lib/email_inviter_spec.rb
Normal file
56
spec/lib/email_inviter_spec.rb
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
require File.join(File.dirname(__FILE__), '..', '..', 'lib', 'email_inviter')
|
||||
|
||||
describe EmailInviter do
|
||||
before do
|
||||
@user = stub(:invitation_code => 'coolcodebro', :present? => true,
|
||||
:email => 'foo@bar.com')
|
||||
@emails = "mbs333@gmail.com, foo1@bar.com maxwell@dude.com"
|
||||
end
|
||||
|
||||
it 'has a list of emails' do
|
||||
inviter = EmailInviter.new(@emails, @user)
|
||||
inviter.emails.should_not be_empty
|
||||
end
|
||||
|
||||
it 'should parse three emails' do
|
||||
inviter = EmailInviter.new(@emails, @user)
|
||||
inviter.emails.count.should == 3
|
||||
end
|
||||
|
||||
it 'has an inviter' do
|
||||
inviter = EmailInviter.new(@emails, @user)
|
||||
inviter.inviter.should_not be_nil
|
||||
end
|
||||
|
||||
it 'can have a message' do
|
||||
message = "you guys suck hard"
|
||||
inviter = EmailInviter.new("emails", @user, :message => message)
|
||||
inviter.message.should == message
|
||||
end
|
||||
|
||||
describe '#emails' do
|
||||
it 'rejects the inviter email if present' do
|
||||
inviter = EmailInviter.new(@emails + " #{@user.email}", @user)
|
||||
inviter.emails.should_not include(@user.email)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'language' do
|
||||
it 'defaults to english' do
|
||||
inviter = EmailInviter.new(@emails, @user)
|
||||
inviter.locale.should == 'en'
|
||||
end
|
||||
|
||||
it 'listens to the langauge option' do
|
||||
inviter = EmailInviter.new(@emails, @user, :locale => 'es')
|
||||
inviter.locale.should == 'es'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#invitation_code' do
|
||||
it 'delegates to the user' do
|
||||
inviter = EmailInviter.new(@emails, @user)
|
||||
inviter.invitation_code.should == @user.invitation_code
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -12,20 +12,18 @@ describe RakeHelpers do
|
|||
describe '#process_emails' do
|
||||
before do
|
||||
Devise.mailer.deliveries = []
|
||||
end
|
||||
it 'should send emails to each backer' do
|
||||
expect{
|
||||
process_emails(@csv, 100, 1, false)
|
||||
}.to change(User, :count).by(3)
|
||||
@old_admin = AppConfig[:admin_account]
|
||||
AppConfig[:admin_account] = Factory(:user).username
|
||||
end
|
||||
|
||||
it 'should not send the email to the same email twice' do
|
||||
process_emails(@csv, 100, 1, false)
|
||||
after do
|
||||
AppConfig[:admin_account] = @old_admin
|
||||
end
|
||||
|
||||
Devise.mailer.deliveries.count.should == 3
|
||||
process_emails(@csv, 100, 1, false)
|
||||
it 'should send emails to each email' do
|
||||
|
||||
Devise.mailer.deliveries.count.should == 3
|
||||
EmailInviter.should_receive(:new).exactly(3).times.and_return(stub.as_null_object)
|
||||
process_emails(@csv, 100, 1, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
42
spec/models/invitation_code_spec.rb
Normal file
42
spec/models/invitation_code_spec.rb
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe InvitationCode do
|
||||
it 'has a valid factory' do
|
||||
Factory(:invitation_code).should be_valid
|
||||
end
|
||||
|
||||
it 'sets the count to a default value' do
|
||||
code = Factory(:invitation_code)
|
||||
code.count.should > 0
|
||||
end
|
||||
|
||||
describe '#use!' do
|
||||
it 'decrements the count of the code' do
|
||||
code = Factory(:invitation_code)
|
||||
|
||||
expect{
|
||||
code.use!
|
||||
}.to change(code, :count).by(-1)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.default_inviter_or' do
|
||||
before do
|
||||
@old_account = AppConfig[:admin_account]
|
||||
AppConfig[:admin_account] = 'bob'
|
||||
end
|
||||
|
||||
after do
|
||||
AppConfig[:admin_account] = @old_account
|
||||
end
|
||||
|
||||
it 'grabs the set admin account for the pod...' do
|
||||
InvitationCode.default_inviter_or(alice).username.should == 'bob'
|
||||
end
|
||||
|
||||
it '..or the given user' do
|
||||
AppConfig[:admin_account] = ''
|
||||
InvitationCode.default_inviter_or(alice).username.should == 'alice'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -48,44 +48,6 @@ describe Invitation do
|
|||
@invitation.message.should == "!"
|
||||
end
|
||||
|
||||
describe 'the invite process' do
|
||||
before do
|
||||
end
|
||||
|
||||
it 'works for a new user' do
|
||||
invite = Invitation.new(:sender => alice, :aspect => alice.aspects.first, :service => 'email', :identifier => 'foo@bar.com', :language => alice.language)
|
||||
lambda {
|
||||
invite.save
|
||||
invite.send!
|
||||
}.should change(User, :count).by(1)
|
||||
end
|
||||
|
||||
it 'works for a current user(with the right email)' do
|
||||
invite = Invitation.create(:sender => alice, :aspect => alice.aspects.first, :service => 'email', :identifier => bob.email, :language => alice.language)
|
||||
lambda {
|
||||
invite.send!
|
||||
}.should_not change(User, :count)
|
||||
end
|
||||
|
||||
it 'works for a current user(with the same fb id)' do
|
||||
bob.services << Factory.build(:service, :type => "Services::Facebook")
|
||||
invite = Invitation.create(:sender => alice, :aspect => alice.aspects.first, :service => 'facebook', :identifier => bob.services.first.uid)
|
||||
lambda {
|
||||
invite.send!
|
||||
}.should_not change(User, :count)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#convert_to_admin!' do
|
||||
it 'reset sender and aspect to nil, and sets admin flag to true' do
|
||||
invite = Factory(:invitation)
|
||||
invite.convert_to_admin!
|
||||
invite.reload
|
||||
invite.admin?.should be_true
|
||||
invite.sender_id.should be_nil
|
||||
invite.aspect_id.should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '.batch_invite' do
|
||||
before do
|
||||
|
|
@ -109,63 +71,4 @@ describe Invitation do
|
|||
|
||||
end
|
||||
end
|
||||
|
||||
describe 'send' do
|
||||
before do
|
||||
@invitation = Factory(:invitation, :sender => alice, :aspect => alice.aspects.first, :service => 'email', :identifier => 'a@a.com' , :language => alice.language)
|
||||
end
|
||||
|
||||
it 'sends an email' do
|
||||
lambda {
|
||||
@invitation.send!
|
||||
}.should change(Devise.mailer.deliveries, :count).by(1)
|
||||
end
|
||||
|
||||
it 'sends an email with from header' do
|
||||
@invitation.send!
|
||||
Devise.mailer.deliveries.first.from.should_not be_blank
|
||||
end
|
||||
|
||||
it 'sends an email with from header' do
|
||||
@invitation.send!
|
||||
Devise.mailer.deliveries.first.to.should == ["a@a.com"]
|
||||
end
|
||||
|
||||
context "re-send" do
|
||||
it 'sends another email' do
|
||||
lambda {
|
||||
@invitation.resend
|
||||
}.should change(Devise.mailer.deliveries, :count).by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#recipient_identifier' do
|
||||
it 'calls email if the invitation_service is email' do
|
||||
email = 'abc@abc.com'
|
||||
invitation = Factory(:invitation, :sender => alice, :service => 'email', :identifier => email, :aspect => alice.aspects.first, :language => alice.language)
|
||||
invitation.recipient_identifier.should == email
|
||||
end
|
||||
|
||||
context 'facebook' do
|
||||
before do
|
||||
@uid = '23526464'
|
||||
@service = "facebook"
|
||||
alice.services << Services::Facebook.new(:uid => "13234895")
|
||||
alice.reload.services(true).first.service_users.create(:uid => @uid, :photo_url => 'url', :name => "Remote User")
|
||||
end
|
||||
|
||||
it 'gets the name if the invitation_service is facebook' do
|
||||
invitation = Factory(:invitation, :sender => alice, :identifier => @uid, :service => @service, :aspect => alice.aspects.first)
|
||||
invitation.recipient_identifier.should == "Remote User"
|
||||
end
|
||||
|
||||
it 'does not error if the facebook user is not recorded' do
|
||||
invitation = Factory(:invitation, :sender => alice, :identifier => @uid, :service => @service, :aspect => alice.aspects.first)
|
||||
alice.services.first.service_users.delete_all
|
||||
invitation.recipient_identifier.should == "A Facebook user"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -33,28 +33,6 @@ describe User do
|
|||
alice.save
|
||||
end
|
||||
end
|
||||
|
||||
describe '#infer_email_from_invitation_provider' do
|
||||
it 'sets corresponding email if invitation_service is email' do
|
||||
addr = '12345@alice.com'
|
||||
alice.invitation_service = 'email'
|
||||
alice.invitation_identifier = addr
|
||||
|
||||
lambda {
|
||||
alice.infer_email_from_invitation_provider
|
||||
}.should change(alice, :email)
|
||||
end
|
||||
|
||||
it 'does not set an email if invitation_service is not email' do
|
||||
addr = '1233123'
|
||||
alice.invitation_service = 'facebook'
|
||||
alice.invitation_identifier = addr
|
||||
|
||||
lambda {
|
||||
alice.infer_email_from_invitation_provider
|
||||
}.should_not change(alice, :email)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'hidden_shareables' do
|
||||
|
|
@ -400,70 +378,13 @@ describe User do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.find_by_invitation' do
|
||||
let(:invited_user) {
|
||||
inv = Factory.build(:invitation, :recipient => @recipient, :service => @type, :identifier => @identifier)
|
||||
User.find_by_invitation(inv)
|
||||
}
|
||||
|
||||
context 'send a request to an existing' do
|
||||
before do
|
||||
@recipient = alice
|
||||
end
|
||||
|
||||
context 'active user' do
|
||||
it 'by service' do
|
||||
@type = 'facebook'
|
||||
@identifier = '123456'
|
||||
|
||||
@recipient.services << Services::Facebook.new(:uid => @identifier)
|
||||
@recipient.save
|
||||
|
||||
invited_user.should == @recipient
|
||||
end
|
||||
|
||||
it 'by email' do
|
||||
@type = 'email'
|
||||
@identifier = alice.email
|
||||
|
||||
invited_user.should == @recipient
|
||||
end
|
||||
end
|
||||
|
||||
context 'invited user' do
|
||||
it 'by service and identifier' do
|
||||
@identifier = alice.email
|
||||
@type = 'email'
|
||||
invited_user.should == alice
|
||||
end
|
||||
end
|
||||
|
||||
context 'not on server (not yet invited)' do
|
||||
it 'returns nil' do
|
||||
@recipient = nil
|
||||
@identifier = 'foo@bar.com'
|
||||
@type = 'email'
|
||||
invited_user.should be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.find_or_create_by_invitation'
|
||||
|
||||
describe '.create_from_invitation!' do
|
||||
before do
|
||||
@identifier = 'max@foobar.com'
|
||||
@inv = Factory.build(:invitation, :admin => true, :service => 'email', :identifier => @identifier)
|
||||
@user = User.create_from_invitation!(@inv)
|
||||
end
|
||||
|
||||
it 'creates a persisted user' do
|
||||
@user.should be_persisted
|
||||
end
|
||||
|
||||
it 'sets the email if the service is email' do
|
||||
@user.email.should == @inv.identifier
|
||||
describe '#process_invite_acceptence' do
|
||||
it 'sets the inviter on user' do
|
||||
inv = InvitationCode.create(:user => bob)
|
||||
user = Factory(:user)
|
||||
user.process_invite_acceptence(inv)
|
||||
user.invited_by_id.should == bob.id
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -842,54 +763,6 @@ describe User do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#accept_invitation!" do
|
||||
before do
|
||||
fantasy_resque do
|
||||
@invitation = Factory(:invitation, :sender => eve, :identifier => 'invitee@example.org', :aspect => eve.aspects.first)
|
||||
end
|
||||
|
||||
@invitation.reload
|
||||
@form_params = {
|
||||
:invitation_token => "abc",
|
||||
:email => "a@a.com",
|
||||
:username => "user",
|
||||
:password => "secret",
|
||||
:password_confirmation => "secret",
|
||||
:person => {
|
||||
:profile => {:first_name => "Bob", :last_name => "Smith"}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
context 'after invitation acceptance' do
|
||||
it 'destroys the invitations' do
|
||||
user = @invitation.recipient.accept_invitation!(@form_params)
|
||||
user.invitations_to_me.count.should == 0
|
||||
end
|
||||
|
||||
it "should create the person with the passed in params" do
|
||||
lambda {
|
||||
@invitation.recipient.accept_invitation!(@form_params)
|
||||
}.should change(Person, :count).by(1)
|
||||
end
|
||||
|
||||
it 'resolves incoming invitations into contact requests' do
|
||||
user = @invitation.recipient.accept_invitation!(@form_params)
|
||||
eve.contacts.where(:person_id => user.person.id).count.should == 1
|
||||
end
|
||||
end
|
||||
|
||||
context 'from an admin' do
|
||||
it 'should work' do
|
||||
i = nil
|
||||
fantasy_resque do
|
||||
i = Invitation.create!(:admin => true, :service => 'email', :identifier => "new_invitee@example.com")
|
||||
end
|
||||
i.reload
|
||||
i.recipient.accept_invitation!(@form_params)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#retract' do
|
||||
before do
|
||||
|
|
|
|||
Loading…
Reference in a new issue