Specs pass again, invitations moved to Invitation model, refactor possibly complete
This commit is contained in:
parent
ae28a6f70c
commit
6dd58fe875
8 changed files with 239 additions and 163 deletions
|
|
@ -30,8 +30,8 @@ class InvitationsController < Devise::InvitationsController
|
|||
|
||||
def update
|
||||
begin
|
||||
user = User.find_by_invitation_token(params["user"]["invitation_token"])
|
||||
user.accept_invitation!(params["user"])
|
||||
user = User.find_by_invitation_token(params[:user][:invitation_token])
|
||||
user.accept_invitation!(params[:user])
|
||||
rescue MongoMapper::DocumentNotValid => e
|
||||
user = nil
|
||||
flash[:error] = e.message
|
||||
|
|
@ -47,7 +47,7 @@ class InvitationsController < Devise::InvitationsController
|
|||
protected
|
||||
|
||||
def check_token
|
||||
if User.find_by_invitation_token(params['invitation_token']).nil?
|
||||
if User.find_by_invitation_token(params[:invitation_token]).nil?
|
||||
flash[:error] = I18n.t 'invitations.check_token.not_found'
|
||||
redirect_to root_url
|
||||
end
|
||||
|
|
|
|||
|
|
@ -94,9 +94,4 @@ class UsersController < ApplicationController
|
|||
tar_path = PhotoMover::move_photos(current_user)
|
||||
send_data( File.open(tar_path).read, :filename => "#{current_user.id}.tar" )
|
||||
end
|
||||
|
||||
def invite
|
||||
User.invite!(:email => params[:email])
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,7 +8,54 @@ class Invitation
|
|||
belongs_to :from, :class => User
|
||||
belongs_to :to, :class => User
|
||||
belongs_to :into, :class => Aspect
|
||||
key :message, String
|
||||
|
||||
validates_presence_of :from, :to, :into
|
||||
|
||||
def self.invite(opts = {})
|
||||
existing_user = User.find_by_email(opts[:email])
|
||||
if existing_user
|
||||
if opts[:from].contact_for(opts[:from].person)
|
||||
raise "You are already friends with this person"
|
||||
elsif not existing_user.invited?
|
||||
opts[:from].send_friend_request_to(existing_user.person, opts[:into])
|
||||
return
|
||||
elsif Invitation.first(:from_id => opts[:from].id, :to_id => existing_user.id)
|
||||
raise "You already invited this person"
|
||||
end
|
||||
end
|
||||
|
||||
invited_user = create_invitee(:email => opts[:email])
|
||||
if invited_user.persisted?
|
||||
Invitation.create!(:from => opts[:from],
|
||||
:to => invited_user,
|
||||
:into => opts[:into],
|
||||
:message => opts[:message])
|
||||
|
||||
opts[:from].invites -= 1
|
||||
opts[:from].save!
|
||||
invited_user
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def self.create_invitee(opts = {})
|
||||
invitable = User.find_or_initialize_with_error_by(:email, opts[:email])
|
||||
|
||||
if invitable.new_record?
|
||||
invitable.errors.clear if invitable.email.try(:match, Devise.email_regexp)
|
||||
else
|
||||
invitable.errors.add(:email, :taken) unless invitable.invited?
|
||||
end
|
||||
|
||||
invitable.invite! if invitable.errors.empty?
|
||||
invitable
|
||||
end
|
||||
|
||||
def to_request!
|
||||
request = from.send_friend_request_to(to.person, into)
|
||||
destroy if request
|
||||
request
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,13 +22,10 @@ class User
|
|||
key :invites, Integer, :default => 5
|
||||
key :invitation_token, String
|
||||
key :invitation_sent_at, DateTime
|
||||
key :inviter_ids, Array, :typecast => 'ObjectId'
|
||||
key :pending_request_ids, Array, :typecast => 'ObjectId'
|
||||
key :visible_post_ids, Array, :typecast => 'ObjectId'
|
||||
key :visible_person_ids, Array, :typecast => 'ObjectId'
|
||||
|
||||
key :invite_messages, Hash
|
||||
|
||||
key :getting_started, Boolean, :default => true
|
||||
|
||||
key :language, String
|
||||
|
|
@ -47,7 +44,8 @@ class User
|
|||
|
||||
one :person, :class_name => 'Person', :foreign_key => :owner_id
|
||||
|
||||
many :inviters, :in => :inviter_ids, :class_name => 'User'
|
||||
many :invitations_from_me, :class => Invitation, :foreign_key => :from_id
|
||||
many :invitations_to_me, :class => Invitation, :foreign_key => :to_id
|
||||
many :friends, :class_name => 'Contact', :foreign_key => :user_id
|
||||
many :visible_people, :in => :visible_person_ids, :class_name => 'Person' # One of these needs to go
|
||||
many :pending_requests, :in => :pending_request_ids, :class_name => 'Request'
|
||||
|
|
@ -87,7 +85,7 @@ class User
|
|||
key :email, String
|
||||
|
||||
def method_missing(method, *args)
|
||||
self.person.send(method, *args)
|
||||
self.person.send(method, *args) if self.person
|
||||
end
|
||||
|
||||
######### Aspects ######################
|
||||
|
|
@ -322,7 +320,6 @@ class User
|
|||
###Invitations############
|
||||
def invite_user(opts = {})
|
||||
if self.invites > 0
|
||||
|
||||
aspect_id = opts.delete(:aspect_id)
|
||||
if aspect_id == nil
|
||||
raise "Must invite into aspect"
|
||||
|
|
@ -331,83 +328,29 @@ class User
|
|||
if !(aspect_object)
|
||||
raise "Must invite to your aspect"
|
||||
else
|
||||
u = User.find_by_email(opts[:email])
|
||||
if u.nil?
|
||||
elsif contact_for(u.person)
|
||||
raise "You are already friends with this person"
|
||||
elsif not u.invited?
|
||||
self.send_friend_request_to(u.person, aspect_object)
|
||||
return
|
||||
elsif u.invited? && u.inviters.include?(self)
|
||||
raise "You already invited this person"
|
||||
end
|
||||
Invitation.invite(:email => opts[:email],
|
||||
:from => self,
|
||||
:into => aspect_object,
|
||||
:message => opts[:invite_message])
|
||||
|
||||
end
|
||||
request = Request.instantiate(
|
||||
:to => "http://local_request.example.com",
|
||||
:from => self.person,
|
||||
:into => aspect_id
|
||||
)
|
||||
|
||||
invited_user = User.invite!(:email => opts[:email], :request => request, :inviter => self, :invite_message => opts[:invite_message])
|
||||
|
||||
self.invites = self.invites - 1
|
||||
self.pending_requests << request
|
||||
request.save
|
||||
self.save!
|
||||
invited_user
|
||||
else
|
||||
raise "You have no invites"
|
||||
end
|
||||
end
|
||||
|
||||
def self.invite!(attributes={})
|
||||
inviter = attributes.delete(:inviter)
|
||||
request = attributes.delete(:request)
|
||||
|
||||
invitable = find_or_initialize_with_error_by(:email, attributes.delete(:email))
|
||||
invitable.attributes = attributes
|
||||
if invitable.inviters.include?(inviter)
|
||||
raise "You already invited this person"
|
||||
else
|
||||
invitable.pending_requests << Request.create(
|
||||
:from => inviter.person)
|
||||
|
||||
invitable.inviters << inviter
|
||||
message = attributes.delete(:invite_message)
|
||||
if message
|
||||
invitable.invite_messages[inviter.id.to_s] = message
|
||||
end
|
||||
end
|
||||
|
||||
if invitable.new_record?
|
||||
invitable.errors.clear if invitable.email.try(:match, Devise.email_regexp)
|
||||
else
|
||||
invitable.errors.add(:email, :taken) unless invitable.invited?
|
||||
end
|
||||
|
||||
invitable.invite! if invitable.errors.empty?
|
||||
invitable
|
||||
end
|
||||
|
||||
def accept_invitation!(opts = {})
|
||||
if self.invited?
|
||||
|
||||
self.setup(opts)
|
||||
|
||||
self.invitation_token = nil
|
||||
self.password = opts[:password]
|
||||
self.password_confirmation = opts[:password_confirmation]
|
||||
|
||||
self.person.save!
|
||||
self.invitation_token = nil
|
||||
friend_inviters
|
||||
self.save!
|
||||
self
|
||||
end
|
||||
end
|
||||
invitations_to_me.each{|invitation| invitation.to_request!}
|
||||
|
||||
def friend_inviters
|
||||
inviters.each do |inviter|
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -45,14 +45,19 @@
|
|||
%header
|
||||
= image_tag '/images/diaspora_white.png'
|
||||
#container
|
||||
- @invs = @resource.invitations_to_me
|
||||
%p
|
||||
Hello #{@resource.email}!
|
||||
%p
|
||||
#{(@resource.inviters.count == 1)? ( @resource.inviters.first.real_name + " (#{@resource.inviters.first.diaspora_handle})" + " has") : (@resource.inviters.map{|inv| inv.real_name + " (#{inv.diaspora_handle})"}.join(",") + " have")} invited you to join Diaspora at #{root_url}, you can accept it through the link below.
|
||||
- @resource.inviters.each do |inv|
|
||||
- if @resource.invite_messages[inv.id.to_s]
|
||||
= "#{inv.real_name}:"
|
||||
= "\"#{@resource.invite_messages[inv.id.to_s]}\""
|
||||
- if @invs.count == 1
|
||||
= @invs.first.real_name + " (#{@invs.first.diaspora_handle})" + " has"
|
||||
- else
|
||||
= (@invs.map{|inv| inv.from.real_name + " (#{inv.from.diaspora_handle})"}.join(",") + " have")
|
||||
= "invited you to join Diaspora at #{root_url}, you can accept it through the link below."
|
||||
- @invs.each do |inv|
|
||||
- if inv.message
|
||||
= "#{inv.from.real_name}:"
|
||||
= "\"#{inv.message}\""
|
||||
%p
|
||||
%p= link_to 'Accept invitation', accept_invitation_url(@resource, :invitation_token => @resource.invitation_token), :class => "large_text"
|
||||
%p.small
|
||||
|
|
|
|||
|
|
@ -67,9 +67,12 @@ module Diaspora
|
|||
#pp friend_request.person
|
||||
activate_friend(friend_request.from, destination_aspect)
|
||||
Rails.logger.info("#{self.real_name}'s friend request has been accepted")
|
||||
|
||||
|
||||
friend_request.destroy
|
||||
|
||||
pending_requests.delete(original_request)
|
||||
original_request.destroy
|
||||
self.save
|
||||
Request.send_request_accepted(self, friend_request.from, destination_aspect)
|
||||
|
||||
#this is a new friend request
|
||||
|
|
|
|||
|
|
@ -6,8 +6,11 @@ require 'spec_helper'
|
|||
|
||||
describe Invitation do
|
||||
let(:user) {make_user}
|
||||
let(:aspect) {user.aspects.create(:name => "Invitees")}
|
||||
let!(:aspect) {user.aspects.create(:name => "Invitees")}
|
||||
let(:user2) {make_user}
|
||||
before do
|
||||
@email = 'maggie@example.com'
|
||||
end
|
||||
describe 'validations' do
|
||||
before do
|
||||
aspect
|
||||
|
|
@ -32,5 +35,113 @@ describe Invitation do
|
|||
@invitation.should_not be_valid
|
||||
end
|
||||
end
|
||||
|
||||
it 'has a message' do
|
||||
@invitation = Invitation.new(:from => user, :to => user2, :into => aspect)
|
||||
@invitation.message = "!"
|
||||
@invitation.message.should == "!"
|
||||
end
|
||||
|
||||
describe '.invite' do
|
||||
it 'creates an invitation' do
|
||||
lambda {
|
||||
Invitation.invite(:email => @email, :from => user, :into => aspect)
|
||||
}.should change(Invitation, :count).by(1)
|
||||
end
|
||||
it 'associates the invitation with the inviter' do
|
||||
lambda {
|
||||
Invitation.invite(:email => @email, :from => user, :into => aspect)
|
||||
}.should change{user.reload.invitations_from_me.count}.by(1)
|
||||
end
|
||||
it 'associates the invitation with the invitee' do
|
||||
new_user = Invitation.invite(:email => @email, :from => user, :into => aspect)
|
||||
new_user.invitations_to_me.count.should == 1
|
||||
end
|
||||
it 'creates a user' do
|
||||
lambda {
|
||||
Invitation.invite(:from => user, :email => @email, :into => aspect)
|
||||
}.should change(User, :count).by(1)
|
||||
end
|
||||
it 'returns the new user' do
|
||||
new_user = Invitation.invite(:from => user, :email => @email, :into => aspect)
|
||||
new_user.is_a?(User).should be_true
|
||||
new_user.email.should == @email
|
||||
end
|
||||
it 'adds the inviter to the invited_user' do
|
||||
new_user = Invitation.invite(:from => user, :email => @email, :into => aspect)
|
||||
new_user.invitations_to_me.first.from.should == user
|
||||
end
|
||||
|
||||
it 'adds an optional message' do
|
||||
message = "How've you been?"
|
||||
new_user = Invitation.invite(:from => user, :email => @email, :into => aspect, :message => message)
|
||||
new_user.invitations_to_me.first.message.should == message
|
||||
end
|
||||
|
||||
it 'sends a friend request to a user with that email into the aspect' do
|
||||
user2
|
||||
user.should_receive(:send_friend_request_to){ |a, b|
|
||||
a.should == user2.person
|
||||
b.should == aspect
|
||||
}
|
||||
Invitation.invite(:from => user, :email => user2.email, :into => aspect)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.create_invitee' do
|
||||
it 'creates a user' do
|
||||
lambda {
|
||||
Invitation.create_invitee(:email => @email)
|
||||
}.should change(User, :count).by(1)
|
||||
end
|
||||
it 'sends email to the invited user' do
|
||||
lambda {
|
||||
Invitation.create_invitee(:email => @email)
|
||||
}.should change{Devise.mailer.deliveries.size}.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_request!' do
|
||||
before do
|
||||
@new_user = Invitation.invite(:from => user, :email => @email, :into => aspect)
|
||||
acceptance_params = {:invitation_token => "abc",
|
||||
:username => "user",
|
||||
:password => "secret",
|
||||
:password_confirmation => "secret",
|
||||
:person => {:profile => {:first_name => "Bob",
|
||||
:last_name => "Smith"}}}
|
||||
@new_user.setup(acceptance_params)
|
||||
@new_user.person.save
|
||||
@new_user.save
|
||||
@invitation = @new_user.invitations_to_me.first
|
||||
end
|
||||
it 'destroys the invitation' do
|
||||
lambda {
|
||||
@invitation.to_request!
|
||||
}.should change(Invitation, :count).by(-1)
|
||||
end
|
||||
it 'creates a request, and sends it to the new user' do
|
||||
lambda {
|
||||
@invitation.to_request!
|
||||
}.should change(Request, :count).by(2)
|
||||
end
|
||||
describe 'return values' do
|
||||
before do
|
||||
@request = @invitation.to_request!
|
||||
end
|
||||
it 'returns the sent request' do
|
||||
@request.is_a?(Request).should be_true
|
||||
end
|
||||
it 'sets the receiving user' do
|
||||
@request.to.should == @new_user.person
|
||||
end
|
||||
it 'sets the sending user' do
|
||||
@request.from.should == user.person
|
||||
end
|
||||
it 'sets the aspect' do
|
||||
@request.into.should == aspect
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -9,58 +9,35 @@ describe User do
|
|||
let(:aspect) {inviter.aspects.create(:name => "awesome")}
|
||||
let(:another_user) {make_user}
|
||||
let(:wrong_aspect) {another_user.aspects.create(:name => "super")}
|
||||
let(:inviter_with_3_invites) {Factory.create :user, :invites => 3}
|
||||
let(:inviter_with_3_invites) { new_user = make_user; new_user.invites = 3; new_user.save; new_user;}
|
||||
let(:aspect2) {inviter_with_3_invites.aspects.create(:name => "Jersey Girls")}
|
||||
|
||||
context "creating invites" do
|
||||
it 'requires an apect' do
|
||||
proc{inviter.invite_user(:email => "maggie@example.com")}.should raise_error /Must invite into aspect/
|
||||
proc{
|
||||
inviter.invite_user(:email => "maggie@example.com")
|
||||
}.should raise_error /Must invite into aspect/
|
||||
end
|
||||
|
||||
it 'requires your aspect' do
|
||||
proc{inviter.invite_user(:email => "maggie@example.com", :aspect_id => wrong_aspect.id)}.should raise_error /Must invite to your aspect/
|
||||
proc{
|
||||
inviter.invite_user(:email => "maggie@example.com", :aspect_id => wrong_aspect.id)
|
||||
}.should raise_error /Must invite to your aspect/
|
||||
end
|
||||
|
||||
it 'creates a user' do
|
||||
inviter
|
||||
lambda {
|
||||
inviter.invite_user(:email => "joe@example.com", :aspect_id => aspect.id )
|
||||
}.should change(User, :count).by(1)
|
||||
it 'calls Invitation.invite' do
|
||||
Invitation.should_receive(:invite)
|
||||
inviter.invite_user(:email => @email, :aspect_id => aspect.id)
|
||||
end
|
||||
|
||||
it 'has an invitation' do
|
||||
inviter.invite_user(:email => "joe@example.com", :aspect_id => aspect.id).invitations_to_me.count.should == 1
|
||||
end
|
||||
|
||||
it 'creates it with an email' do
|
||||
inviter.invite_user(:email => "joe@example.com", :aspect_id => aspect.id).email.should == "joe@example.com"
|
||||
end
|
||||
|
||||
it 'sends email to the invited user' do
|
||||
::Devise.mailer.should_receive(:invitation).once
|
||||
inviter.invite_user(:email => "ian@example.com", :aspect_id => aspect.id)
|
||||
end
|
||||
|
||||
it 'adds the inviter to the invited_user' do
|
||||
invited_user = inviter.invite_user(:email => "marcy@example.com", :aspect_id => aspect.id)
|
||||
invited_user.reload
|
||||
invited_user.inviters.include?(inviter).should be_true
|
||||
end
|
||||
|
||||
it 'adds an optional message' do
|
||||
invited_user = inviter.invite_user(:email => "marcy@example.com", :invite_message => "How've you been?",:aspect_id => aspect.id)
|
||||
invited_user.reload
|
||||
invited_user.invite_messages[inviter.id.to_s].should == "How've you been?"
|
||||
end
|
||||
|
||||
|
||||
it 'adds a pending request to the invited user' do
|
||||
invited_user = inviter.invite_user(:email => "marcy@example.com", :aspect_id => aspect.id)
|
||||
invited_user.reload
|
||||
invited_user.pending_requests.find_by_callback_url(inviter.receive_url).should_not be_nil
|
||||
end
|
||||
|
||||
it 'adds a pending request to the inviter' do
|
||||
inviter.invite_user(:email => "marcy@example.com", :aspect_id => aspect.id)
|
||||
inviter.reload
|
||||
inviter.pending_requests.find_by_callback_url(inviter.receive_url).nil?.should == false
|
||||
end
|
||||
|
||||
it 'throws if you try to add someone you"re friends with' do
|
||||
friend_users(inviter, aspect, another_user, wrong_aspect)
|
||||
|
|
@ -68,13 +45,6 @@ describe User do
|
|||
proc{inviter.invite_user(:email => another_user.email, :aspect_id => aspect.id)}.should raise_error /already friends/
|
||||
end
|
||||
|
||||
it 'sends a friend request to a user with that email into the aspect' do
|
||||
inviter.should_receive(:send_friend_request_to){ |a, b|
|
||||
a.should == another_user.person
|
||||
b.should == aspect
|
||||
}
|
||||
inviter.invite_user(:email => another_user.email, :aspect_id => aspect.id)
|
||||
end
|
||||
end
|
||||
|
||||
context "limit on invites" do
|
||||
|
|
@ -93,53 +63,55 @@ describe User do
|
|||
end
|
||||
|
||||
|
||||
context "the acceptance of an invitation" do
|
||||
let!(:invited_user1) { create_user_with_invitation("abc", :email => "email@example.com", :inviter => inviter)}
|
||||
let!(:invited_user2) { inviter.invite_user(:email => "jane@example.com", :aspect_id => aspect.id) }
|
||||
|
||||
it "should create the person with the passed in params" do
|
||||
person_count = Person.count
|
||||
u = invited_user1.accept_invitation!(:invitation_token => "abc",
|
||||
describe "#accept_invitation!" do
|
||||
let(:invited_user) {@invited_user_pre.accept_invitation!(:invitation_token => "abc",
|
||||
:username => "user",
|
||||
:password => "secret",
|
||||
:password_confirmation => "secret",
|
||||
:person => {:profile => {:first_name => "Bob",
|
||||
:last_name => "Smith"}} )
|
||||
Person.count.should be person_count + 1
|
||||
u.person.profile.first_name.should == "Bob"
|
||||
:last_name => "Smith"}} )}
|
||||
|
||||
before do
|
||||
@invited_user_pre = Invitation.invite(:from => inviter, :email => 'invitee@example.org', :into => aspect).reload
|
||||
@person_count = Person.count
|
||||
end
|
||||
|
||||
it 'should auto accept the request for the sender into the right aspect' do
|
||||
u = invited_user2.accept_invitation!(:invitation_token => invited_user2.invitation_token,
|
||||
:username => "user",
|
||||
:password => "secret",
|
||||
:password_confirmation => "secret",
|
||||
:person => {:profile => {:first_name => "Bob",
|
||||
:last_name => "Smith"}} )
|
||||
context 'after invitation acceptance' do
|
||||
before do
|
||||
invited_user.reload
|
||||
end
|
||||
it 'destroys the invitations' do
|
||||
invited_user.invitations_to_me.count.should == 0
|
||||
end
|
||||
it "should create the person with the passed in params" do
|
||||
Person.count.should == @person_count + 1
|
||||
invited_user.person.profile.first_name.should == "Bob"
|
||||
end
|
||||
|
||||
u.pending_requests.count.should == 1
|
||||
it 'resolves incoming invitations into friend requests' do
|
||||
invited_user.reload.pending_requests.count.should == 1
|
||||
inviter.reload.pending_requests.count.should == 1
|
||||
end
|
||||
|
||||
received_request = u.pending_requests.first
|
||||
context 'after request acceptance' do
|
||||
before do
|
||||
invited_user.accept_and_respond(invited_user.pending_requests.first.id,
|
||||
invited_user.aspects.create(
|
||||
:name => 'first aspect!').id)
|
||||
invited_user.reload
|
||||
inviter.reload
|
||||
end
|
||||
it 'successfully makes invited_user friends with inviter' do
|
||||
invited_user.contact_for(inviter.person).should_not be_nil
|
||||
invited_user.pending_requests.count.should == 0
|
||||
end
|
||||
|
||||
aspect2 = u.aspects.create(:name => "dudes")
|
||||
|
||||
reversed_request = u.accept_friend_request(received_request.id, aspect2.id)
|
||||
u.reload
|
||||
|
||||
inviter.receive_salmon(u.salmon(reversed_request).xml_for(inviter.person))
|
||||
inviter.reload.contact_for(u.person).should_not be_nil
|
||||
it 'successfully makes inviter friends with invited_user' do
|
||||
inviter.contact_for(invited_user.person).should_not be_nil
|
||||
inviter.pending_requests.size.should == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create_user_with_invitation(invitation_token, attributes={})
|
||||
inviter = attributes.delete(:inviter)
|
||||
user = User.new({:password => nil, :password_confirmation => nil}.update(attributes))
|
||||
#user.skip_confirmation!
|
||||
user.email = attributes[:email]
|
||||
user.invitation_token = invitation_token
|
||||
user.invitation_sent_at = Time.now.utc
|
||||
user.inviters << inviter
|
||||
user.save(:validate => false)
|
||||
user
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue