Merge branch 'master' into issue1586-aspectdropdown-when-posting
This commit is contained in:
commit
b1e95def4a
57 changed files with 840 additions and 774 deletions
4
Gemfile
4
Gemfile
|
|
@ -97,13 +97,13 @@ group :test, :development do
|
|||
gem 'linecache', '0.43', :platforms => :mri_18
|
||||
end
|
||||
gem 'launchy'
|
||||
gem 'jasmine', '1.0.2.1'
|
||||
gem 'jasmine', '1.1.0.rc3'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'factory_girl_rails'
|
||||
gem 'fixture_builder', '0.2.2'
|
||||
gem 'selenium-webdriver', '0.2.2'
|
||||
gem 'selenium-webdriver', '2.4'
|
||||
gem 'capybara', '~> 0.3.9'
|
||||
gem 'cucumber-rails', '0.3.2'
|
||||
gem 'rspec', '>= 2.0.0'
|
||||
|
|
|
|||
15
Gemfile.lock
15
Gemfile.lock
|
|
@ -143,7 +143,7 @@ GEM
|
|||
ohai (>= 0.5.7)
|
||||
rest-client (< 1.7.0, >= 1.0.4)
|
||||
uuidtools
|
||||
childprocess (0.2.0)
|
||||
childprocess (0.2.1)
|
||||
ffi (~> 1.0.6)
|
||||
closure-compiler (1.1.1)
|
||||
cloudfiles (1.4.10)
|
||||
|
|
@ -225,11 +225,12 @@ GEM
|
|||
jammit (0.5.4)
|
||||
closure-compiler (>= 0.1.0)
|
||||
yui-compressor (>= 0.9.1)
|
||||
jasmine (1.0.2.1)
|
||||
json_pure (>= 1.4.3)
|
||||
jasmine (1.1.0.rc3)
|
||||
jasmine-core (>= 1.1.0.rc2)
|
||||
rack (>= 1.1)
|
||||
rspec (>= 1.3.1)
|
||||
selenium-webdriver (>= 0.1.3)
|
||||
jasmine-core (1.1.0.rc3)
|
||||
json (1.4.6)
|
||||
json_pure (1.5.3)
|
||||
launchy (2.0.3)
|
||||
|
|
@ -399,8 +400,8 @@ GEM
|
|||
rubyntlm (0.1.1)
|
||||
rubyzip (0.9.4)
|
||||
sass (3.1.4)
|
||||
selenium-webdriver (0.2.2)
|
||||
childprocess (>= 0.1.9)
|
||||
selenium-webdriver (2.4.0)
|
||||
childprocess (>= 0.2.1)
|
||||
ffi (>= 1.0.7)
|
||||
json_pure
|
||||
rubyzip
|
||||
|
|
@ -484,7 +485,7 @@ DEPENDENCIES
|
|||
http_accept_language!
|
||||
i18n-inflector-rails (~> 1.0)
|
||||
jammit (= 0.5.4)
|
||||
jasmine (= 1.0.2.1)
|
||||
jasmine (= 1.1.0.rc3)
|
||||
json (= 1.4.6)
|
||||
jwt!
|
||||
launchy
|
||||
|
|
@ -511,7 +512,7 @@ DEPENDENCIES
|
|||
ruby-debug
|
||||
ruby-debug19
|
||||
sass (= 3.1.4)
|
||||
selenium-webdriver (= 0.2.2)
|
||||
selenium-webdriver (= 2.4)
|
||||
settingslogic (= 2.0.6)
|
||||
sod!
|
||||
sqlite3
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ class AdminsController < ApplicationController
|
|||
@users = params[:user].empty? ? [] : User.where(params[:user])
|
||||
end
|
||||
|
||||
def admin_inviter
|
||||
opts = {:service => 'email', :identifier => params[:identifier]}
|
||||
existing_user = Invitation.find_existing_user('email', params[:identifier])
|
||||
opts.merge!(:existing_user => existing_user) if existing_user
|
||||
Invitation.create_invitee(opts)
|
||||
flash[:notice] = "invitation sent to #{params[:identifier]}"
|
||||
def admin_inviter
|
||||
user = User.find_by_email params[:idenitifer]
|
||||
unless user
|
||||
Invitation.create(:service => 'email', :identifer => params[:identifier], :admin => true)
|
||||
flash[:notice] = "invitation sent to #{params[:identifier]}"
|
||||
end
|
||||
redirect_to user_search_path
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class CommentsController < ApplicationController
|
|||
def index
|
||||
@post = current_user.find_visible_post_by_id(params[:post_id])
|
||||
if @post
|
||||
@comments = @post.comments.includes(:author => :profile)
|
||||
@comments = @post.comments.includes(:author => :profile).order('created_at ASC')
|
||||
render :layout => false
|
||||
else
|
||||
raise ActiveRecord::RecordNotFound.new
|
||||
|
|
|
|||
|
|
@ -31,15 +31,17 @@ class ConversationsController < ApplicationController
|
|||
message_text = params[:conversation].delete(:text)
|
||||
params[:conversation][:messages_attributes] = [ {:author => current_user.person, :text => message_text }]
|
||||
|
||||
if @conversation = Conversation.create(params[:conversation])
|
||||
@conversation = Conversation.new(params[:conversation])
|
||||
if @conversation.save
|
||||
Postzord::Dispatch.new(current_user, @conversation).post
|
||||
|
||||
flash[:notice] = I18n.t('conversations.create.sent')
|
||||
if params[:profile]
|
||||
redirect_to person_path(params[:profile])
|
||||
else
|
||||
redirect_to conversations_path(:conversation_id => @conversation.id)
|
||||
end
|
||||
else
|
||||
flash[:error] = I18n.t('conversations.create.fail')
|
||||
end
|
||||
if params[:profile]
|
||||
redirect_to person_path(params[:profile])
|
||||
else
|
||||
redirect_to conversations_path(:conversation_id => @conversation.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
class InvitationsController < Devise::InvitationsController
|
||||
|
||||
before_filter :check_token, :only => [:edit]
|
||||
before_filter :check_if_invites_open, :only =>[:create]
|
||||
|
||||
def new
|
||||
@sent_invitations = current_user.invitations_from_me.includes(:recipient)
|
||||
|
|
@ -16,63 +17,36 @@ class InvitationsController < Devise::InvitationsController
|
|||
end
|
||||
|
||||
def create
|
||||
unless AppConfig[:open_invitations]
|
||||
flash[:error] = I18n.t 'invitations.create.no_more'
|
||||
redirect_to :back
|
||||
return
|
||||
end
|
||||
aspect = params[:user].delete(:aspects)
|
||||
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)
|
||||
|
||||
good_emails, bad_emails = emails.partition{|e| e.try(:match, Devise.email_regexp)}
|
||||
invites = Invitation.batch_invite(emails, :sender => current_user, :aspect => aspect, :service => 'email')
|
||||
|
||||
if good_emails.include?(current_user.email)
|
||||
if good_emails.length == 1
|
||||
flash[:error] = I18n.t 'invitations.create.own_address'
|
||||
redirect_to :back
|
||||
return
|
||||
else
|
||||
bad_emails.push(current_user.email)
|
||||
good_emails.delete(current_user.email)
|
||||
end
|
||||
end
|
||||
|
||||
good_emails.each{|e| Resque.enqueue(Job::Mail::InviteUserByEmail, current_user.id, e, aspect, message)}
|
||||
|
||||
if bad_emails.any?
|
||||
flash[:error] = I18n.t('invitations.create.sent') + good_emails.join(', ') + " "+ I18n.t('invitations.create.rejected') + bad_emails.join(', ')
|
||||
else
|
||||
flash[:notice] = I18n.t('invitations.create.sent') + good_emails.join(', ')
|
||||
end
|
||||
flash[:notice] = extract_messages(invites)
|
||||
|
||||
redirect_to :back
|
||||
end
|
||||
|
||||
def update
|
||||
begin
|
||||
invitation_token = params[:user][:invitation_token]
|
||||
|
||||
if invitation_token.nil? || invitation_token.blank?
|
||||
raise I18n.t('invitations.check_token.not_found')
|
||||
end
|
||||
user = User.find_by_invitation_token(params[:user][:invitation_token])
|
||||
|
||||
user = User.find_by_invitation_token!(invitation_token)
|
||||
|
||||
user.accept_invitation!(params[:user])
|
||||
user.seed_aspects
|
||||
rescue Exception => e #What exception is this trying to rescue? If it is ActiveRecord::NotFound, we should say so.
|
||||
raise e unless e.respond_to?(:record)
|
||||
user = nil
|
||||
record = e.record
|
||||
record.errors.delete(:person)
|
||||
|
||||
flash[:error] = record.errors.full_messages.join(", ")
|
||||
end
|
||||
|
||||
if user
|
||||
flash[:notice] = I18n.t 'registrations.create.success'
|
||||
sign_in_and_redirect(:user, 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
|
||||
redirect_to accept_user_invitation_path(
|
||||
:invitation_token => params[:user][:invitation_token])
|
||||
redirect_to accept_user_invitation_path(:invitation_token => params[:user][:invitation_token]), :error => user.errors.full_messages.join(", ")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -90,12 +64,37 @@ class InvitationsController < Devise::InvitationsController
|
|||
@resource = User.find_by_invitation_token(params[:invitation_token])
|
||||
render 'devise/mailer/invitation_instructions', :layout => false
|
||||
end
|
||||
protected
|
||||
|
||||
protected
|
||||
def check_token
|
||||
if User.find_by_invitation_token(params[:invitation_token]).nil?
|
||||
flash[:error] = I18n.t 'invitations.check_token.not_found'
|
||||
redirect_to root_url
|
||||
end
|
||||
end
|
||||
|
||||
def check_if_invites_open
|
||||
unless AppConfig[:open_invitations]
|
||||
flash[:error] = I18n.t 'invitations.create.no_more'
|
||||
redirect_to :back
|
||||
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: "
|
||||
successes, failures = invites.partition{|x| x.persisted? }
|
||||
|
||||
success_message += successes.map{|k| k.identifier }.join(', ')
|
||||
failure_message += failures.map{|k| k.identifier }.join(', ')
|
||||
|
||||
messages = []
|
||||
messages << success_message if successes.present?
|
||||
messages << failure_message if failures.present?
|
||||
|
||||
messages.join('\n')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,11 +19,10 @@ class MessagesController < ApplicationController
|
|||
if message.save
|
||||
Rails.logger.info("event=create type=comment user=#{current_user.diaspora_handle} status=success message=#{message.id} chars=#{params[:message][:text].length}")
|
||||
Postzord::Dispatch.new(current_user, message).post
|
||||
|
||||
redirect_to conversations_path(:conversation_id => cnv.id)
|
||||
else
|
||||
render :nothing => true, :status => 422
|
||||
flash[:error] = I18n.t('conversations.new_message.fail')
|
||||
end
|
||||
redirect_to conversations_path(:conversation_id => cnv.id)
|
||||
else
|
||||
render :nothing => true, :status => 422
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class NotificationsController < VannaController
|
|||
end
|
||||
notifications.each do |n|
|
||||
n[:actors] = n.actors
|
||||
n[:translation] = object_link(n, n.actors.map { |a| person_link(a) })
|
||||
n[:translation] = notification_message_for(n)
|
||||
n[:translation_key] = n.popup_translation_key
|
||||
n[:target] = n.translation_key == "notifications.mentioned" ? n.target.post : n.target
|
||||
end
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ class ServicesController < ApplicationController
|
|||
if i_id = params[:invitation_id]
|
||||
invited_user = Invitation.find(i_id).recipient
|
||||
else
|
||||
invited_user = current_user.invite_user(params[:aspect_id], params[:provider], @uid)
|
||||
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
|
||||
|
||||
@subject = t('services.inviter.join_me_on_diaspora')
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ module NotificationsHelper
|
|||
number_of_actors = actors.count
|
||||
sentence_translations = {:two_words_connector => " #{t('notifications.index.and')} ", :last_word_connector => ", #{t('notifications.index.and')} " }
|
||||
actor_links = actors.collect{ |person|
|
||||
person_link(person, :class => 'hovercardable', :what => 'thefuck' )
|
||||
person_link(person, :class => 'hovercardable')
|
||||
}
|
||||
|
||||
if number_of_actors < 4
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# Copyright (c) 2011, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
|
|
@ -8,121 +8,145 @@ class Invitation < ActiveRecord::Base
|
|||
belongs_to :recipient, :class_name => 'User'
|
||||
belongs_to :aspect
|
||||
|
||||
validates_presence_of :sender,
|
||||
:recipient,
|
||||
:aspect
|
||||
attr_accessible :sender, :recipient, :aspect, :service, :identifier, :admin
|
||||
|
||||
# @param opts [Hash] Takes :identifier, :service, :idenfitier, :from, :message
|
||||
# @return [User]
|
||||
def self.invite(opts={})
|
||||
opts[:identifier].downcase! if opts[:identifier]
|
||||
# return if the current user is trying to invite himself via email
|
||||
return false if opts[:identifier] == opts[:from].email
|
||||
before_validation :set_email_as_default_service
|
||||
|
||||
if existing_user = self.find_existing_user(opts[:service], opts[:identifier])
|
||||
# If the sender of the invitation is already connected to the person
|
||||
# he is inviting, raise an error.
|
||||
if opts[:from].contact_for(opts[:from].person)
|
||||
raise "You are already connceted to this person"
|
||||
validates_presence_of :identifier, :service
|
||||
validate :valid_identifier?
|
||||
validates_presence_of :sender, :aspect, :unless => :admin?
|
||||
validate :ensure_not_inviting_self, :on => :create, :unless => :admin?
|
||||
validate :sender_owns_aspect?, :unless => :admin?
|
||||
validates_uniqueness_of :sender_id, :scope => [:identifier, :service], :unless => :admin?
|
||||
|
||||
# Check whether or not the existing User has already been invited;
|
||||
# and if so, start sharing with the Person.
|
||||
elsif not existing_user.invited?
|
||||
opts[:from].share_with(existing_user.person, opts[:into])
|
||||
return
|
||||
after_create :queue_send! #TODO make this after_commit :queue_saved!, :on => :create
|
||||
|
||||
# If the sender has already invited the recipient, raise an error.
|
||||
elsif Invitation.where(:sender_id => opts[:from].id, :recipient_id => existing_user.id).first
|
||||
raise "You already invited this person"
|
||||
|
||||
# When everything checks out, we merge the existing user into the
|
||||
# options hash to pass on to self.create_invitee.
|
||||
else
|
||||
opts.merge(:existing_user => existing_user)
|
||||
end
|
||||
# @note options hash is passed through to [Invitation.new]
|
||||
# @see [Invitation.new]
|
||||
#
|
||||
# @param [Array<String>] emails
|
||||
# @option opts [User] :sender
|
||||
# @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.
|
||||
def self.batch_invite(emails, opts)
|
||||
|
||||
users_on_pod = User.where(:email => emails, :invitation_token => nil)
|
||||
|
||||
#share with anyone whose email you entered who is on the pod
|
||||
emails = emails - users_on_pod.map{|u| u.email}
|
||||
users_on_pod.each{|u| opts[:sender].share_with(u.person, opts[:aspect])}
|
||||
|
||||
emails.map! do |e|
|
||||
Invitation.create(opts.merge(:identifier => e))
|
||||
end
|
||||
|
||||
create_invitee(opts)
|
||||
emails
|
||||
end
|
||||
|
||||
# @param service [String] String representation of the service invitation provider (i.e. facebook, email)
|
||||
# @param identifier [String] String representation of the reciepients identity on the provider (i.e. 'bob.smith', bob@aol.com)
|
||||
# @return [User]
|
||||
def self.find_existing_user(service, identifier)
|
||||
unless existing_user = User.where(:invitation_service => service,
|
||||
:invitation_identifier => identifier).first
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
existing_user
|
||||
# Downcases the incoming service identifier and assigns it
|
||||
#
|
||||
# @param ident [String] Service identifier
|
||||
# @see super
|
||||
def identifier=(ident)
|
||||
ident.downcase! if ident
|
||||
super
|
||||
end
|
||||
|
||||
# @params opts [Hash] Takes :from, :existing_user, :service, :identifier, :message
|
||||
# @return [User]
|
||||
def self.create_invitee(opts={})
|
||||
invitee = opts[:existing_user]
|
||||
invitee ||= User.new(:invitation_service => opts[:service], :invitation_identifier => opts[:identifier])
|
||||
# Determine if we want to skip emailing the recipient.
|
||||
#
|
||||
# @return [Boolean]
|
||||
# @return [void]
|
||||
def skip_email?
|
||||
self.service != 'email'
|
||||
end
|
||||
|
||||
# (dan) I'm not sure why, but we need to call .valid? on our User.
|
||||
invitee.valid?
|
||||
|
||||
# Return a User immediately if an invalid email is passed in
|
||||
return invitee if opts[:service] == 'email' && !opts[:identifier].match(Devise.email_regexp)
|
||||
|
||||
if invitee.new_record?
|
||||
invitee.errors.clear
|
||||
invitee.serialized_private_key = User.generate_key if invitee.serialized_private_key.blank?
|
||||
invitee.send(:generate_invitation_token)
|
||||
elsif invitee.invitation_token.nil?
|
||||
return invitee
|
||||
# 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
|
||||
|
||||
# Logic if there is an explicit sender
|
||||
if opts[:from]
|
||||
invitee.save(:validate => false)
|
||||
Invitation.create!(:sender => opts[:from],
|
||||
:recipient => invitee,
|
||||
:aspect => opts[:into],
|
||||
:message => opts[:message])
|
||||
invitee.reload
|
||||
end
|
||||
invitee.skip_invitation = (opts[:service] != 'email')
|
||||
invitee.invite!
|
||||
# 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 => opts[:identifier], :service => opts[:service]}
|
||||
log_hash.merge({:inviter => opts[:from].diaspora_handle, :invitier_uid => opts[:from].id, :inviter_created_at_unix => opts[:from].created_at.to_i}) if opts[:from]
|
||||
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)
|
||||
|
||||
invitee
|
||||
self
|
||||
end
|
||||
|
||||
# @return [Invitation] self
|
||||
def resend
|
||||
recipient.invite!
|
||||
end
|
||||
|
||||
# @return Contact
|
||||
def share_with!
|
||||
if contact = sender.share_with(recipient.person, aspect)
|
||||
self.destroy
|
||||
end
|
||||
contact
|
||||
self.send!
|
||||
end
|
||||
|
||||
# @return [String]
|
||||
def recipient_identifier
|
||||
if recipient.invitation_service == 'email'
|
||||
recipient.invitation_identifier
|
||||
elsif recipient.invitation_service == 'facebook'
|
||||
if su = ServiceUser.where(:uid => recipient.invitation_identifier).first
|
||||
case self.service
|
||||
when 'email'
|
||||
self.identifier
|
||||
when'facebook'
|
||||
if su = ServiceUser.where(:uid => self.identifier).first
|
||||
su.name
|
||||
else
|
||||
I18n.t('invitations.a_facebook_user')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def queue_send!
|
||||
unless self.recipient.present?
|
||||
Resque.enqueue(Job::Mail::InviteUserByEmail, self.id)
|
||||
end
|
||||
end
|
||||
|
||||
# @note before_save
|
||||
def set_email_as_default_service
|
||||
self.service ||= 'email'
|
||||
end
|
||||
|
||||
# @note Validation
|
||||
def ensure_not_inviting_self
|
||||
if self.identifier == self.sender.email
|
||||
errors[:base] << 'You can not invite yourself.'
|
||||
end
|
||||
end
|
||||
|
||||
# @note Validation
|
||||
def sender_owns_aspect?
|
||||
if self.sender_id != self.aspect.user_id
|
||||
errors[:base] << 'You do not own that aspect.'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# @note Validation
|
||||
def valid_identifier?
|
||||
return false unless self.identifier
|
||||
if self.service == 'email'
|
||||
unless self.identifier.match(Devise.email_regexp)
|
||||
errors[:base] << 'invalid email'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ module Job
|
|||
end
|
||||
unless response.success?
|
||||
pod = Pod.find_or_create_by_url(response.effective_url)
|
||||
log_line = "event=http_multi_fail sender_id=#{user_id} recipient_id=#{person.id} url=#{response.effective_url} response_code='#{response.code}' xml='#{Base64.decode64(enc_object_xml)}'"
|
||||
log_line = "event=http_multi_fail sender_id=#{user_id} recipient_id=#{person.id} url=#{response.effective_url} response_code='#{response.code}'"
|
||||
Rails.logger.info(log_line)
|
||||
pod.pod_stats.create(:error_message => log_line, :person_id => person.id, :error_code => response.code.to_i)
|
||||
failed_request_people << person.id
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ module Job
|
|||
module Mail
|
||||
class InviteUserByEmail < Base
|
||||
@queue = :mail
|
||||
def self.perform(sender_id, email, aspect_id, invite_message)
|
||||
user = User.find(sender_id)
|
||||
user.invite_user(aspect_id, 'email', email, invite_message)
|
||||
def self.perform(invite_id)
|
||||
invite = Invitation.find(invite_id)
|
||||
invite.send!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,12 +14,23 @@ module Job
|
|||
socket_to_users(post, recipient_user_ids) if post.respond_to?(:socket_to_user)
|
||||
notify_mentioned_users(post)
|
||||
end
|
||||
|
||||
def self.create_visibilities(post, recipient_user_ids)
|
||||
contacts = Contact.where(:user_id => recipient_user_ids, :person_id => post.author_id)
|
||||
new_post_visibilities = contacts.map do |contact|
|
||||
PostVisibility.new(:contact_id => contact.id, :post_id => post.id)
|
||||
|
||||
if postgres?
|
||||
# Take the naive approach to inserting our new visibilities for now.
|
||||
contacts.each do |contact|
|
||||
PostVisibility.find_or_create_by_contact_id_and_post_id(contact.id, post.id)
|
||||
end
|
||||
else
|
||||
# Use a batch insert on mySQL.
|
||||
new_post_visibilities = contacts.map do |contact|
|
||||
PostVisibility.new(:contact_id => contact.id, :post_id => post.id)
|
||||
end
|
||||
PostVisibility.import(new_post_visibilities)
|
||||
end
|
||||
PostVisibility.import new_post_visibilities
|
||||
|
||||
end
|
||||
def self.socket_to_users(post, recipient_user_ids)
|
||||
recipient_user_ids.each do |id|
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module Job
|
|||
class ResendInvitation < Base
|
||||
@queue = :mail
|
||||
def self.perform(invitation_id)
|
||||
inv = Invitation.where(:id => invitation_id).first
|
||||
inv = Invitation.find(invitation_id)
|
||||
inv.resend
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ class Message < ActiveRecord::Base
|
|||
belongs_to :author, :class_name => 'Person'
|
||||
belongs_to :conversation, :touch => true
|
||||
|
||||
validates_presence_of :text
|
||||
|
||||
after_create do
|
||||
#sign comment as commenter
|
||||
self.author_signature = self.sign_with_key(self.author.owner.encryption_key) if self.author.owner
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ class Person < ActiveRecord::Base
|
|||
|
||||
has_one :profile, :dependent => :destroy
|
||||
delegate :last_name, :to => :profile
|
||||
accepts_nested_attributes_for :profile
|
||||
|
||||
before_validation :downcase_diaspora_handle
|
||||
def downcase_diaspora_handle
|
||||
|
|
@ -51,7 +52,21 @@ class Person < ActiveRecord::Base
|
|||
AppConfig[:featured_users].present? ? Person.where(:diaspora_handle => AppConfig[:featured_users]) : []
|
||||
end
|
||||
|
||||
|
||||
# Set a default of an empty profile when a new Person record is instantiated.
|
||||
# Passing :profile => nil to Person.new will instantiate a person with no profile.
|
||||
# Calling Person.new with a block:
|
||||
# Person.new do |p|
|
||||
# p.profile = nil
|
||||
# end
|
||||
# will not work! The nil profile will be overriden with an empty one.
|
||||
def initialize(params={})
|
||||
profile_set = params.has_key?(:profile) || params.has_key?("profile")
|
||||
params[:profile_attributes] = params.delete(:profile) if params.has_key?(:profile) && params[:profile].is_a?(Hash)
|
||||
super
|
||||
self.profile ||= Profile.new unless profile_set
|
||||
end
|
||||
|
||||
|
||||
def self.find_from_id_or_username(params)
|
||||
p = if params[:id].present?
|
||||
Person.where(:id => params[:id]).first
|
||||
|
|
@ -67,18 +82,12 @@ class Person < ActiveRecord::Base
|
|||
|
||||
def self.search_query_string(query)
|
||||
query = query.downcase
|
||||
like_operator = postgres? ? "ILIKE" : "LIKE"
|
||||
|
||||
if postgres?
|
||||
where_clause = <<-SQL
|
||||
profiles.full_name ILIKE ? OR
|
||||
profiles.diaspora_handle ILIKE ?
|
||||
SQL
|
||||
else
|
||||
where_clause = <<-SQL
|
||||
profiles.full_name LIKE ? OR
|
||||
people.diaspora_handle LIKE ?
|
||||
SQL
|
||||
end
|
||||
where_clause = <<-SQL
|
||||
profiles.full_name #{like_operator} ? OR
|
||||
people.diaspora_handle #{like_operator} ?
|
||||
SQL
|
||||
|
||||
q_tokens = query.to_s.strip.gsub(/(\s|$|^)/) { "%#{$1}" }
|
||||
[where_clause, [q_tokens, q_tokens]]
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ class ServiceUser < ActiveRecord::Base
|
|||
self.contact = self.service.user.contact_for(self.person)
|
||||
end
|
||||
|
||||
self.invitation = Invitation.joins(:recipient).where(:sender_id => self.service.user_id,
|
||||
:users => {:invitation_service => self.service.provider,
|
||||
:invitation_identifier => self.uid}).first
|
||||
self.invitation = Invitation.where(:sender_id => self.service.user_id,
|
||||
:service => self.service.provider,
|
||||
:identifier => self.uid).first
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -42,11 +42,31 @@ class Services::Facebook < Service
|
|||
su.attach_local_models
|
||||
su
|
||||
}
|
||||
ServiceUser.import(data, :on_duplicate_key_update => [:updated_at, :contact_id, :person_id, :request_id, :invitation_id, :photo_url, :name, :username])
|
||||
|
||||
|
||||
if postgres?
|
||||
# Take the naive approach to inserting our new visibilities for now.
|
||||
data.each do |su|
|
||||
if existing = ServiceUser.find_by_uid(su.uid)
|
||||
update_hash = OVERRIDE_FIELDS_ON_FB_UPDATE.inject({}) do |acc, element|
|
||||
acc[element] = su.send(element)
|
||||
acc
|
||||
end
|
||||
|
||||
existing.update_attributes(update_hash)
|
||||
else
|
||||
su.save
|
||||
end
|
||||
end
|
||||
else
|
||||
ServiceUser.import(data, :on_duplicate_key_update => OVERRIDE_FIELDS_ON_FB_UPDATE + [:updated_at])
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
OVERRIDE_FIELDS_ON_FB_UPDATE = [:contact_id, :person_id, :request_id, :invitation_id, :photo_url, :name, :username]
|
||||
|
||||
def prevent_service_users_from_being_empty
|
||||
if self.service_users.blank?
|
||||
self.save_friends
|
||||
|
|
|
|||
|
|
@ -59,24 +59,46 @@ class User < ActiveRecord::Base
|
|||
:invitation_service,
|
||||
:invitation_identifier
|
||||
|
||||
# Sometimes we access the person in a strange way and need to do this
|
||||
# @note we should make this method depricated.
|
||||
#
|
||||
# @return [Person]
|
||||
def save_person!
|
||||
self.person.save if self.person && self.person.changed?
|
||||
self.person
|
||||
|
||||
# @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
|
||||
end
|
||||
|
||||
if existing_user.nil?
|
||||
i = Invitation.where(:service => service, :identifier => identifier).first
|
||||
existing_user = i.recipient if i
|
||||
end
|
||||
|
||||
existing_user
|
||||
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
|
||||
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
|
||||
end
|
||||
|
||||
def self.create_from_invitation!(invitation)
|
||||
user = User.new
|
||||
user.generate_keys
|
||||
user.send(:generate_invitation_token)
|
||||
user.email = invitation.identifier if invitation.service == 'email'
|
||||
# we need to make a custom validator here to make this safer
|
||||
user.save(:validate => false)
|
||||
user
|
||||
end
|
||||
|
||||
|
||||
def update_user_preferences(pref_hash)
|
||||
if self.disable_mail
|
||||
UserPreference::VALID_EMAIL_TYPES.each{|x| self.user_preferences.find_or_create_by_email_type(x)}
|
||||
|
|
@ -291,19 +313,6 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
###Invitations############
|
||||
def invite_user(aspect_id, service, identifier, invite_message = "")
|
||||
if aspect = aspects.find(aspect_id)
|
||||
Invitation.invite(:service => service,
|
||||
:identifier => identifier,
|
||||
:from => self,
|
||||
:into => aspect,
|
||||
:message => invite_message)
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
# This method is called when an invited user accepts his invitation
|
||||
#
|
||||
# @param [Hash] opts the options to accept the invitation with
|
||||
|
|
@ -312,25 +321,29 @@ class User < ActiveRecord::Base
|
|||
# @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
|
||||
begin
|
||||
if self.invited?
|
||||
self.setup(opts)
|
||||
self.invitation_token = nil
|
||||
self.password = opts[:password]
|
||||
self.password_confirmation = opts[:password_confirmation]
|
||||
self.save!
|
||||
invitations_to_me.each{|invitation| invitation.share_with!}
|
||||
log_hash[:status] = "success"
|
||||
Rails.logger.info log_hash
|
||||
log_hash[:inviter] = invitations_to_me.first.sender.diaspora_handle if invitations_to_me.first && invitations_to_me.first.sender
|
||||
|
||||
self.reload # Because to_request adds a request and saves elsewhere
|
||||
self
|
||||
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
|
||||
rescue Exception => e
|
||||
log_hash[:status] = "failure"
|
||||
Rails.logger.info log_hash
|
||||
raise e
|
||||
|
||||
log_hash[:status] = "success"
|
||||
Rails.logger.info(log_hash)
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -344,28 +357,22 @@ class User < ActiveRecord::Base
|
|||
def setup(opts)
|
||||
self.username = opts[:username]
|
||||
self.email = opts[:email]
|
||||
self.language ||= 'en'
|
||||
self.valid?
|
||||
errors = self.errors
|
||||
errors.delete :person
|
||||
return if errors.size > 0
|
||||
|
||||
opts[:person] ||= {}
|
||||
unless opts[:person][:profile].is_a?(Profile)
|
||||
opts[:person][:profile] ||= Profile.new
|
||||
opts[:person][:profile] = Profile.new(opts[:person][:profile])
|
||||
end
|
||||
|
||||
self.person = Person.new(opts[:person])
|
||||
self.person.diaspora_handle = "#{opts[:username]}@#{AppConfig[:pod_uri].authority}"
|
||||
self.person.url = AppConfig[:pod_url]
|
||||
|
||||
|
||||
self.serialized_private_key = User.generate_key if self.serialized_private_key.blank?
|
||||
self.person.serialized_public_key = OpenSSL::PKey::RSA.new(self.serialized_private_key).public_key
|
||||
|
||||
self.set_person(Person.new(opts[:person] || {} ))
|
||||
self.generate_keys
|
||||
self
|
||||
end
|
||||
|
||||
def set_person(person)
|
||||
person.url = AppConfig[:pod_url]
|
||||
person.diaspora_handle = "#{self.username}@#{AppConfig[:pod_uri].authority}"
|
||||
self.person = person
|
||||
end
|
||||
|
||||
def seed_aspects
|
||||
self.aspects.create(:name => I18n.t('aspects.seed.family'))
|
||||
self.aspects.create(:name => I18n.t('aspects.seed.friends'))
|
||||
|
|
@ -379,10 +386,6 @@ class User < ActiveRecord::Base
|
|||
aq
|
||||
end
|
||||
|
||||
def self.generate_key
|
||||
key_size = (Rails.env == 'test' ? 512 : 4096)
|
||||
OpenSSL::PKey::RSA::generate(key_size)
|
||||
end
|
||||
|
||||
def encryption_key
|
||||
OpenSSL::PKey::RSA.new(serialized_private_key)
|
||||
|
|
@ -433,4 +436,34 @@ class User < ActiveRecord::Base
|
|||
i += 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Generate public/private keys for User and associated Person
|
||||
def generate_keys
|
||||
key_size = (Rails.env == 'test' ? 512 : 4096)
|
||||
|
||||
self.serialized_private_key = OpenSSL::PKey::RSA::generate(key_size) if self.serialized_private_key.blank?
|
||||
|
||||
if self.person && self.person.serialized_public_key.blank?
|
||||
self.person.serialized_public_key = OpenSSL::PKey::RSA.new(self.serialized_private_key).public_key
|
||||
end
|
||||
end
|
||||
|
||||
# Sometimes we access the person in a strange way and need to do this
|
||||
# @note we should make this method depricated.
|
||||
#
|
||||
# @return [Person]
|
||||
def save_person!
|
||||
self.person.save if self.person && self.person.changed?
|
||||
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
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
- @invs = @resource.invitations_to_me
|
||||
-if @invs.count > 0
|
||||
-unless @invs.first.admin?
|
||||
!!!
|
||||
%html
|
||||
%head
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ el:
|
|||
no_account_till: "Ο λογαριασμός σας δεν θα δημιουργηθεί μέχρι να μεταβείτε στον παρακάτω σύνδεσμο και συνδεθείτε. "
|
||||
subject: "Έχετε προσκληθεί να συμμετάσχετε στο Diaspora!"
|
||||
inviters:
|
||||
accept_at: ", στο %{url}, μπορείτε να το αποδεχτείτε, μέσω του επόμενου συνδέσμου."
|
||||
accept_at: "στο %{url}, μπορείτε να το αποδεχτείτε, μέσω του παρακάτω συνδέσμου."
|
||||
has_invited_you: "Ο χρήστης %{name} σας προσκάλεσε να γίνετε μέλος του Diaspora"
|
||||
have_invited_you: "Ο χρήστης %{names} σας κάλεσε να γίνετε μέλος του Diaspora"
|
||||
reset_password_instructions:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ pt-PT:
|
|||
no_account_till: "A sua conta não será criada até que aceda à hiperligação acima e se registe."
|
||||
subject: "Foi convidado para se juntar ao Diaspora!"
|
||||
inviters:
|
||||
accept_at: ", em %{url}, pode aceitar através da seguinte hiperligação:"
|
||||
accept_at: "em %{url}, pode aceitar através da seguinte hiperligação:"
|
||||
has_invited_you: "%{name} convidou-o para se juntar ao Diaspora"
|
||||
have_invited_you: "%{names} convidaram-no para se juntar ao Diaspora"
|
||||
reset_password_instructions:
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ el:
|
|||
person:
|
||||
invalid: "είναι άκυρη."
|
||||
username:
|
||||
invalid: "is invalid. We only allow letters, numbers, and underscores"
|
||||
invalid: "μη έγκυρο. Επιτρέπονται μόνο γράμματα, νούμερα και \"κάτω παύλες\" (_)"
|
||||
taken: "είναι ήδη σε χρήση."
|
||||
ago: "%{time} πριν"
|
||||
all_aspects: "Όλες οι πτυχές"
|
||||
|
|
@ -253,7 +253,7 @@ el:
|
|||
tagline_first_half: "Μοιραστείτε ό,τι θέλετε,"
|
||||
tagline_second_half: "με όποιον θέλετε."
|
||||
invitations:
|
||||
a_facebook_user: "A Facebook user"
|
||||
a_facebook_user: "Ένας χρήστης του Facebook"
|
||||
check_token:
|
||||
not_found: "Το σύμβολο της πρόσκλησης δεν βρέθηκε"
|
||||
create:
|
||||
|
|
@ -392,7 +392,7 @@ el:
|
|||
other: "Οι χρήστες %{actors} άρχισαν να διαμοιράζονται μαζί σας."
|
||||
zero: "Οι χρήστες %{actors} άρχισαν να διαμοιράζονται μαζί σας."
|
||||
notifier:
|
||||
a_post_you_shared: "a post."
|
||||
a_post_you_shared: "μια δημοσίευση."
|
||||
click_here: "πατήστε εδώ"
|
||||
comment_on_post:
|
||||
reply: "Απαντήστε ή δείτε τη δημοσίευση του χρήστη %{name} >"
|
||||
|
|
@ -473,7 +473,7 @@ el:
|
|||
fail: "Λυπούμαστε, δεν ήταν δυνατή η εύρεση του %{handle}."
|
||||
zero: "κανένα άτομο"
|
||||
photos:
|
||||
comment_email_subject: "%{name}'s photo"
|
||||
comment_email_subject: "φωτογραφία του χρήστη %{name}"
|
||||
create:
|
||||
integrity_error: "Η μεταφόρτωση της φωτογραφίας απέτυχε. Είστε σίγουρος/η ότι ήταν φωτογραφία;"
|
||||
runtime_error: "Η μεταφόρτωση της φωτογραφίας απέτυχε. Είστε σίγουρος/η πως φορέσατε ζώνη ασφαλείας πριν ξεκινήσετε;"
|
||||
|
|
@ -501,7 +501,7 @@ el:
|
|||
edit: "Επεξεργασία"
|
||||
edit_delete_photo: "Επεξεργασία περιγραφής φωτογραφίας / διαγραφή φωτογραφίας"
|
||||
make_profile_photo: "ορισμός ως φωτογραφίας προφίλ"
|
||||
show_original_post: "Show original post"
|
||||
show_original_post: "Προβολή αρχικής δημοσίευσης"
|
||||
update_photo: "Ενημέρωση Φωτογραφίας"
|
||||
update:
|
||||
error: "Αποτυχία επεξεργασίας φωτογραφίας."
|
||||
|
|
@ -577,7 +577,7 @@ el:
|
|||
new_request_to_person:
|
||||
sent: "εστάλη!"
|
||||
reshares:
|
||||
comment_email_subject: "%{resharer}'s reshare of %{author}'s post"
|
||||
comment_email_subject: "κοινοποίηση της δημοσίευσης του %{author} από τον %{resharer}"
|
||||
create:
|
||||
failure: "Υπήρξε κάποιο σφάλμα κατά την κοινοποίηση αυτής της δημοσίευσης."
|
||||
reshare:
|
||||
|
|
@ -600,8 +600,8 @@ el:
|
|||
failure:
|
||||
error: "εμφανίστηκε ένα σφάλμα κατά τη σύνδεση με αυτή την υπηρεσία"
|
||||
finder:
|
||||
no_friends: "No Facebook friends found."
|
||||
service_friends: "%{service} Friends"
|
||||
no_friends: "Δεν βρέθηκαν φίλοι στο Facebook. "
|
||||
service_friends: "%{service} Φίλοι"
|
||||
index:
|
||||
connect_to_facebook: "Σύνδεση με Facebook"
|
||||
connect_to_tumblr: "Σύνδεση με το Tumblr"
|
||||
|
|
@ -616,7 +616,7 @@ el:
|
|||
join_me_on_diaspora: "Συνδεθείτε μαζί μου στο DIASPORA*"
|
||||
remote_friend:
|
||||
invite: "πρόσκληση"
|
||||
not_on_diaspora: "Not yet on Diaspora"
|
||||
not_on_diaspora: "Όχι ακόμα στο Diaspora"
|
||||
resend: "αποστολή ξανά"
|
||||
settings: "Ρυθμίσεις"
|
||||
shared:
|
||||
|
|
@ -746,11 +746,11 @@ el:
|
|||
your_email: "Το email σας"
|
||||
your_handle: "Το αναγνωριστικό σας στο diaspora"
|
||||
getting_started:
|
||||
aspects: "aspects"
|
||||
aspects: "πτυχές"
|
||||
connect_to: "Συνδεθείτε με"
|
||||
connect_to_your_other_social_networks: "Συνδεθείτε με άλλα κοινωνικά δίκτυα"
|
||||
connect_with_people: "Συνδεθείτε με ενδιαφέροντα άτομα"
|
||||
connect_with_people_explanation_pt1: "Connect with people by placing them into one or more of your"
|
||||
connect_with_people_explanation_pt1: "Συνδεθείτε με άτομα τοποθετώντας τα σε μια ή περισσότερες από τις "
|
||||
connect_with_people_explanation_pt2: "Aspects are an intuitive way to group new and familar faces, private to you, allowing you to filter down or share with subsets of your contacts easily."
|
||||
featured_tags: "Αξιόλογες ετικέτες"
|
||||
featured_users: "Αξιόλογοι χρήστες"
|
||||
|
|
|
|||
|
|
@ -249,6 +249,9 @@ en:
|
|||
other: "%{count} new messages"
|
||||
create:
|
||||
sent: "Message sent"
|
||||
fail: "Invalid message"
|
||||
new_message:
|
||||
fail: "Invalid message"
|
||||
destroy:
|
||||
success: "Conversation successfully removed"
|
||||
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ pt-PT:
|
|||
content_2: "Give it to anyone and they'll be able to find you on Diaspora."
|
||||
heading: "Diaspora ID"
|
||||
donate: "Donate"
|
||||
handle_explanation: "Este é o seu endereço do Diaspora. Tal como um endereço de email, pode dá-lo a quem deseja que o contacte."
|
||||
handle_explanation: "Esta é a sua identificação do Diaspora. Tal como um endereço de email, pode dá-la a quem deseja que o contacte."
|
||||
keep_us_running: "Keep %{pod} running fast, buy our servers their monthly coffee fix!"
|
||||
no_contacts: "Não há contactos"
|
||||
no_tags: "No tags"
|
||||
|
|
@ -134,7 +134,7 @@ pt-PT:
|
|||
try_adding_some_more_contacts: "You can search (top) or invite (right) more contacts."
|
||||
you_should_add_some_more_contacts: "You should add some more contacts!"
|
||||
no_posts_message:
|
||||
start_talking: "Ainda ninguém disse nada. Dê início à conversa!"
|
||||
start_talking: "Ainda ninguém disse nada!"
|
||||
one: "1 aspecto"
|
||||
other: "%{count} aspectos"
|
||||
seed:
|
||||
|
|
@ -207,7 +207,7 @@ pt-PT:
|
|||
many: "%{count} novas mensagens"
|
||||
one: "1 nova mensagem"
|
||||
other: "%{count} novas mensagens"
|
||||
zero: "não há novas mensagens"
|
||||
zero: "Não há novas mensagens"
|
||||
index:
|
||||
create_a_new_message: "criar uma nova mensagem"
|
||||
inbox: "Caixa de Entrada"
|
||||
|
|
@ -267,7 +267,7 @@ pt-PT:
|
|||
accept_your_invitation: "Accept your invitation"
|
||||
your_account_awaits: "Your account awaits!"
|
||||
new:
|
||||
already_invited: "Já foi convidado"
|
||||
already_invited: "As pessoas seguintes não aceitaram o seu convite:"
|
||||
aspect: "Aspecto"
|
||||
comma_seperated_plz: "Pode inserir vários endereços de email separados por vírgulas."
|
||||
if_they_accept_info: "se aceitarem, serão adicionados ao aspecto para o qual os convidou."
|
||||
|
|
@ -343,7 +343,7 @@ pt-PT:
|
|||
many: "%{count} novas notificações"
|
||||
one: "1 nova notificação"
|
||||
other: "%{count} novas notificações"
|
||||
zero: "não há novas notificações"
|
||||
zero: "Não há novas notificações"
|
||||
index:
|
||||
and: "e"
|
||||
and_others:
|
||||
|
|
@ -531,8 +531,8 @@ pt-PT:
|
|||
your_photo: "A sua fotografia"
|
||||
your_private_profile: "O seu perfil privado"
|
||||
your_public_profile: "O seu perfil público"
|
||||
your_tags: "Você: em 5 #tags"
|
||||
your_tags_placeholder: "p.ex. #diaspora #varrer #gatos #música"
|
||||
your_tags: "Descreva-se em 5 palavras"
|
||||
your_tags_placeholder: "como #filmes #gatos #viagens #professor #novaiorque"
|
||||
update:
|
||||
failed: "Falhou ao actualizar o perfil"
|
||||
updated: "Perfil actualizado"
|
||||
|
|
@ -550,7 +550,7 @@ pt-PT:
|
|||
update: "Actualizar"
|
||||
new:
|
||||
create_my_account: "Create my account"
|
||||
enter_email: "Introduza um endereço de e-mail"
|
||||
enter_email: "Introduza um endereço de email"
|
||||
enter_password: "Introduza uma palavra-passe"
|
||||
enter_password_again: "Introduza de novo a mesma palavra-passe"
|
||||
enter_username: "Escolha um nome de utilizador (apenas letras, números e underscores)"
|
||||
|
|
@ -622,8 +622,8 @@ pt-PT:
|
|||
shared:
|
||||
add_contact:
|
||||
add_new_contact: "Add a new contact"
|
||||
create_request: "Encontrar através do endereço do Diaspora"
|
||||
diaspora_handle: "diaspora@handle.org"
|
||||
create_request: "Encontrar através da identificação do Diaspora"
|
||||
diaspora_handle: "diaspora@pod.org"
|
||||
enter_a_diaspora_username: "Introduza um nome de utilizador do Diaspora:"
|
||||
know_email: "Sabe os seus endereços de email? Deveria convidá-los"
|
||||
your_diaspora_username_is: "O seu nome de utilizador do Diaspora é: %{diaspora_handle}"
|
||||
|
|
@ -633,7 +633,7 @@ pt-PT:
|
|||
logged_in_as: "iniciou sessão como %{name}"
|
||||
your_aspects: "os seus aspectos"
|
||||
invitations:
|
||||
by_email: "Por Email"
|
||||
by_email: "Por email"
|
||||
dont_have_now: "Não tem nenhum agora, mas terá mais convites brevemente!"
|
||||
from_facebook: "do Facebook"
|
||||
invitations_left: "ainda tem %{count}"
|
||||
|
|
@ -660,7 +660,7 @@ pt-PT:
|
|||
share: "Partilhar"
|
||||
share_with: "partilhar com"
|
||||
upload_photos: "Upload photos"
|
||||
whats_on_your_mind: "em que está a pensar?"
|
||||
whats_on_your_mind: "Em que está a pensar?"
|
||||
reshare:
|
||||
reshare: "Voltar a partilhar"
|
||||
stream_element:
|
||||
|
|
@ -686,7 +686,7 @@ pt-PT:
|
|||
other: "por favor não utilize mais de %{count} caracteres ao escrever as suas mensagens de estado"
|
||||
zero: "por favor não utilize mais de %{count} caracteres ao escrever as suas mensagens de estado"
|
||||
stream_helper:
|
||||
hide_comments: "ocultar comentários"
|
||||
hide_comments: "Ocultar todos comentários"
|
||||
show_more_comments: "Show %{number} more comments"
|
||||
tag_followings:
|
||||
create:
|
||||
|
|
@ -727,8 +727,8 @@ pt-PT:
|
|||
also_commented: "...alguém também comenta na publicação do seu contacto?"
|
||||
change: "Alterar"
|
||||
change_email: "Change E-Mail"
|
||||
change_language: "Mudar de Idioma"
|
||||
change_password: "Alterar a Palavra-passe"
|
||||
change_language: "Mudar de idioma"
|
||||
change_password: "Alterar a palavra-passe"
|
||||
close_account: "Encerrar a Conta"
|
||||
comment_on_post: "...alguém comenta as suas publicações?"
|
||||
current_password: "Palavra-passe actual"
|
||||
|
|
@ -739,12 +739,12 @@ pt-PT:
|
|||
export_data: "Exportar Dados"
|
||||
liked: "...alguém gosta da sua publicação?"
|
||||
mentioned: "...é mencionado numa publicação?"
|
||||
new_password: "Nova Palavra-passe"
|
||||
new_password: "Nova palavra-passe"
|
||||
private_message: "...recebe uma mensagem privada?"
|
||||
receive_email_notifications: "Receber notificações por email quando..."
|
||||
started_sharing: "...alguém começa a partilhar consigo?"
|
||||
your_email: "O seu endereço de email"
|
||||
your_handle: "O seu endereço do Diaspora"
|
||||
your_handle: "A sua identificação do Diaspora"
|
||||
getting_started:
|
||||
aspects: "aspects"
|
||||
connect_to: "Connect to"
|
||||
|
|
@ -757,7 +757,7 @@ pt-PT:
|
|||
fill_out_your_profile: "Fill out your profile"
|
||||
find_friends: "Find friends"
|
||||
find_friends_from_facebook: "find friends from Facebook"
|
||||
finished: "Terminado!"
|
||||
finished: "Terminado"
|
||||
follow_your_interests: "Follow your interests"
|
||||
hashtag_explanation: "Hashtags allow you to talk about and follow your interests. They're also a great way to find new people on Diaspora."
|
||||
profile_description: "Make it easier for people to find you by filling out your profile information."
|
||||
|
|
@ -770,17 +770,17 @@ pt-PT:
|
|||
photo: "Photo"
|
||||
tags: "Tags"
|
||||
see_all_featured_users: "See all featured users"
|
||||
welcome: "Bem-vindo(a) ao Diaspora!"
|
||||
welcome: "Bem-vindo(a)!"
|
||||
welcome_with_name: "Welcome, %{name}!"
|
||||
public:
|
||||
does_not_exist: "O utilizador %{username} não existe!"
|
||||
update:
|
||||
email_notifications_changed: "As notificações por email foram alteradas"
|
||||
language_changed: "O Idioma Foi Alterado"
|
||||
language_not_changed: "Falha ao Alterar o Idioma"
|
||||
language_changed: "O idioma foi alterado"
|
||||
language_not_changed: "Falha ao alterar o idioma"
|
||||
password_changed: "A palavra-passe foi alterada. Já pode iniciar sessão com a sua nova palavra-passe."
|
||||
password_not_changed: "Falhou ao alterar a palavra-passe"
|
||||
unconfirmed_email_changed: "E-Mail Changed. Needs activation."
|
||||
unconfirmed_email_changed: "O endereço de email foi alterado. É necessária activação."
|
||||
unconfirmed_email_not_changed: "E-Mail Change Failed"
|
||||
webfinger:
|
||||
fetch_failed: "erro a obter perfil webfinger profile para %{profile_url}"
|
||||
|
|
|
|||
|
|
@ -750,8 +750,8 @@ zh-TW:
|
|||
connect_to: "連結至"
|
||||
connect_to_your_other_social_networks: "與其他社交網站連結"
|
||||
connect_with_people: "與酷咖連結"
|
||||
connect_with_people_explanation_pt1: "Connect with people by placing them into one or more of your"
|
||||
connect_with_people_explanation_pt2: "Aspects are an intuitive way to group new and familar faces, private to you, allowing you to filter down or share with subsets of your contacts easily."
|
||||
connect_with_people_explanation_pt1: "為了和別人聯繫, 將他們放入你的任何一個或多個"
|
||||
connect_with_people_explanation_pt2: "面向是區分新人或熟人的直覺方式, 並且只有你自己知道, 讓你可以輕易過濾他們, 或只和部份聯絡人分享."
|
||||
featured_tags: "特色標籤"
|
||||
featured_users: "特色使用者"
|
||||
fill_out_your_profile: "填寫個人檔案"
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ el:
|
|||
no_more: "Δεν υπάρχουν άλλες δημοσιεύσεις."
|
||||
publisher:
|
||||
at_least_one_aspect: "Πρέπει να κάνετε δημοσίευση σε τουλάχιστον μια πτυχή"
|
||||
limited: "Limited - your post will only be seen by people you are sharing with"
|
||||
public: "Public - your post will be visible to everyone and found by search engines"
|
||||
limited: "Περιορισμένο - οι δημοσιεύσεις σας θα είναι ορατές μόνο από τα άτομα με τα οποία διαμοιράζεστε. "
|
||||
public: "Δημόσιο - οι δημοσιεύσεις σας θα είναι ορατές στον καθένα και θα μπορούν να βρεθούν από τις μηχανές αναζήτησης."
|
||||
reshares:
|
||||
duplicate: "Έχετε ήδη κοινοποιήσει αυτή τη δημοσίευση!"
|
||||
search_for: "Αναζήτηση για {{name}}"
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ pt-PT:
|
|||
no_more: "Não há mais publicações."
|
||||
publisher:
|
||||
at_least_one_aspect: "Tem de publicar para pelo menos um aspecto"
|
||||
limited: "Limited - your post will only be seen by people you are sharing with"
|
||||
public: "Public - your post will be visible to everyone and found by search engines"
|
||||
limited: "Limitado - a sua publicação só será vista pelas pessoas com as quais a está partilhar"
|
||||
public: "Público - A sua publicação vai ser visível para todos e encontrada por motores de busca"
|
||||
reshares:
|
||||
duplicate: "You've already reshared that post!"
|
||||
duplicate: "Já republicou essa publicação!"
|
||||
search_for: "Procurar por {{name}}"
|
||||
show_more: "mostrar mais"
|
||||
timeago:
|
||||
|
|
|
|||
|
|
@ -18,10 +18,12 @@ SQL
|
|||
SQL
|
||||
|
||||
#There are some duplicate likes.
|
||||
keeper_likes = Like.group(:target_id, :author_id, :target_type).having('COUNT(*) > 1')
|
||||
keeper_likes.each do |like|
|
||||
l = Like.arel_table
|
||||
Like.where(:target_id => like.target_id, :author_id => like.author_id, :target_type => like.target_type).where(l[:id].not_eq(like.id)).delete_all
|
||||
if Like.count > 0
|
||||
keeper_likes = Like.group(:target_id, :author_id, :target_type).having('COUNT(*) > 1')
|
||||
keeper_likes.each do |like|
|
||||
l = Like.arel_table
|
||||
Like.where(:target_id => like.target_id, :author_id => like.author_id, :target_type => like.target_type).where(l[:id].not_eq(like.id)).delete_all
|
||||
end
|
||||
end
|
||||
add_index :likes, [:target_id, :author_id, :target_type], :unique => true
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
class AddFullNameToProfile < ActiveRecord::Migration
|
||||
class Profile < ActiveRecord::Base; end
|
||||
def self.up
|
||||
add_column :profiles, :full_name, :string, :limit => 70
|
||||
|
||||
|
|
@ -8,7 +9,13 @@ class AddFullNameToProfile < ActiveRecord::Migration
|
|||
remove_index :profiles, [:first_name, :searchable]
|
||||
remove_index :profiles, [:last_name, :searchable]
|
||||
|
||||
execute("UPDATE profiles SET full_name=LOWER(CONCAT(first_name, ' ', last_name))")
|
||||
if Profile.count > 0
|
||||
if postgres?
|
||||
execute("UPDATE profiles SET full_name=LOWER(first_name || ' ' || last_name)")
|
||||
else
|
||||
execute("UPDATE profiles SET full_name=LOWER(CONCAT(first_name, ' ', last_name))")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.down
|
||||
|
|
|
|||
17
db/migrate/20110816061820_add_fields_to_invitations.rb
Normal file
17
db/migrate/20110816061820_add_fields_to_invitations.rb
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
class AddFieldsToInvitations < ActiveRecord::Migration
|
||||
def self.up
|
||||
add_column :invitations, :service, :string
|
||||
add_column :invitations, :identifier, :string
|
||||
add_column :invitations, :admin, :boolean, :default => false
|
||||
change_column :invitations, :recipient_id, :integer, :null => true
|
||||
change_column :invitations, :sender_id, :integer, :null => true
|
||||
end
|
||||
|
||||
def self.down
|
||||
remove_column :invitations, :service
|
||||
remove_column :invitations, :identifier
|
||||
remove_column :invitations, :admin
|
||||
change_column :invitations, :recipient_id, :integer, :null => false
|
||||
change_column :invitations, :sender_id, :integer, :null => false
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20110815210933) do
|
||||
ActiveRecord::Schema.define(:version => 20110816061820) do
|
||||
|
||||
create_table "aspect_memberships", :force => true do |t|
|
||||
t.integer "aspect_id", :null => false
|
||||
|
|
@ -99,11 +99,14 @@ ActiveRecord::Schema.define(:version => 20110815210933) do
|
|||
|
||||
create_table "invitations", :force => true do |t|
|
||||
t.text "message"
|
||||
t.integer "sender_id", :null => false
|
||||
t.integer "recipient_id", :null => false
|
||||
t.integer "sender_id"
|
||||
t.integer "recipient_id"
|
||||
t.integer "aspect_id"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "service"
|
||||
t.string "identifier"
|
||||
t.boolean "admin", :default => false
|
||||
end
|
||||
|
||||
add_index "invitations", ["aspect_id"], :name => "index_invitations_on_aspect_id"
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ require 'factory_girl_rails'
|
|||
require File.join(File.dirname(__FILE__), "..", "spec", "helper_methods")
|
||||
include HelperMethods
|
||||
|
||||
alice = Factory(:user_with_aspect, :username => "alice", :password => 'evankorth', :invites => 10)
|
||||
bob = Factory(:user_with_aspect, :username => "bob", :password => 'evankorth', :invites => 10)
|
||||
eve = Factory(:user_with_aspect, :username => "eve", :password => 'evankorth', :invites => 10)
|
||||
alice = Factory(:user_with_aspect, :username => "alice", :password => 'evankorth')
|
||||
bob = Factory(:user_with_aspect, :username => "bob", :password => 'evankorth')
|
||||
eve = Factory(:user_with_aspect, :username => "eve", :password => 'evankorth')
|
||||
|
||||
print "Creating seeded users... "
|
||||
alice.person.profile.update_attributes(:first_name => "Alice", :last_name => "Smith",
|
||||
|
|
|
|||
|
|
@ -16,3 +16,7 @@ Feature: private messages
|
|||
And I should see "Greetings" within "#conversation_show"
|
||||
And "Alice Awesome" should be part of active conversation
|
||||
And I should see "hello, alice!" within ".stream"
|
||||
|
||||
Scenario: send an empty message
|
||||
Given I send a message with subject "Greetings" and text " " to "Alice Awesome"
|
||||
Then I should not see "Greetings" within "#conversation_inbox"
|
||||
|
|
|
|||
|
|
@ -35,13 +35,15 @@ Given /^a user named "([^\"]*)" with email "([^\"]*)"$/ do |name, email|
|
|||
end
|
||||
|
||||
Given /^I have been invited by an admin$/ do
|
||||
@me = Invitation.create_invitee(:service => 'email', :identifier => "new_invitee@example.com")
|
||||
i = Invitation.create!(:admin => true, :service => 'email', :identifier => "new_invitee@example.com")
|
||||
@me = i.attach_recipient!
|
||||
end
|
||||
|
||||
Given /^I have been invited by a user$/ do
|
||||
@inviter = Factory(:user)
|
||||
aspect = @inviter.aspects.create(:name => "Rocket Scientists")
|
||||
@me = @inviter.invite_user(aspect.id, 'email', "new_invitee@example.com", "Hey, tell me about your rockets!")
|
||||
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!
|
||||
end
|
||||
|
||||
When /^I click on my name$/ do
|
||||
|
|
|
|||
|
|
@ -21,9 +21,17 @@ module RakeHelpers
|
|||
churn_through = n
|
||||
backer_name = backers[n+offset][1].to_s.strip
|
||||
backer_email = backers[n+offset][0].to_s.strip
|
||||
unless User.find_by_email(backer_email) || User.find_by_invitation_identifier(backer_email)
|
||||
|
||||
possible_user = User.find_by_email(backer_email)
|
||||
possible_invite = Invitation.find_by_identifier(backer_email)
|
||||
possible_user ||= possible_invite.recipient if possible_invite.present?
|
||||
|
||||
unless possible_user
|
||||
puts "#{n}: sending email to: #{backer_name} #{backer_email}" unless Rails.env == 'test'
|
||||
Invitation.create_invitee(:service => 'email', :identifier => backer_email, :name => backer_name ) unless test
|
||||
unless test
|
||||
i = Invitation.new(:service => 'email', :identifier => backer_email, :admin => true)
|
||||
i.send!
|
||||
end
|
||||
else
|
||||
puts "user with the email exists: #{backer_email} , #{backer_name} " unless Rails.env == 'test'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace :backup do
|
|||
|
||||
puts "Dumping Mysql at #{Time.now.to_s}"
|
||||
`mkdir -p /tmp/backup/mysql`
|
||||
`nice mysqldump --single-transaction --user=#{user} --password=#{password} #{database} > /tmp/backup/mysql/backup.txt `
|
||||
`nice mysqldump --single-transaction --quick --user=#{user} --password=#{password} #{database} > /tmp/backup/mysql/backup.txt `
|
||||
|
||||
puts "Gzipping dump at #{Time.now.to_s}"
|
||||
tar_name = "mysql_#{Time.now.to_i}.tar"
|
||||
|
|
@ -36,7 +36,6 @@ namespace :backup do
|
|||
if file.write File.open("/tmp/backup/" + tar_name)
|
||||
puts("event=backup status=success type=mysql")
|
||||
`rm /tmp/backup/#{tar_name}`
|
||||
`rm -rf /tmp/backup/mysql/`
|
||||
|
||||
files = mysql_container.objects
|
||||
files.sort!.pop(NUMBER_OF_DAYS * 24)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
var AspectFilters = {
|
||||
selectedGUIDS: [],
|
||||
requests: 0,
|
||||
activeRequest: null,
|
||||
initialize: function(){
|
||||
AspectFilters.initializeSelectedGUIDS();
|
||||
AspectFilters.interceptAspectLinks();
|
||||
|
|
@ -39,8 +39,6 @@ var AspectFilters = {
|
|||
$('html, body').animate({scrollTop:0}, 'fast');
|
||||
},
|
||||
switchToAspect: function(aspectLi){
|
||||
AspectFilters.requests++;
|
||||
|
||||
var guid = aspectLi.attr('data-guid');
|
||||
|
||||
// select correct aspect in filter list & deselect others
|
||||
|
|
@ -55,8 +53,6 @@ var AspectFilters = {
|
|||
$("#aspect_nav a.aspect_selector").click(function(e){
|
||||
e.preventDefault();
|
||||
|
||||
AspectFilters.requests++;
|
||||
|
||||
// loading animation
|
||||
AspectFilters.fadeOut();
|
||||
|
||||
|
|
@ -128,11 +124,15 @@ var AspectFilters = {
|
|||
history.pushState(null, document.title, newURL);
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
try {
|
||||
AspectFilters.activeRequest.abort();
|
||||
} catch(e) {} finally {
|
||||
AspectFilters.activeRequest = null;
|
||||
}
|
||||
AspectFilters.activeRequest = $.ajax({
|
||||
url : newURL,
|
||||
dataType : 'script',
|
||||
success : function(data){
|
||||
AspectFilters.requests--;
|
||||
// fill in publisher
|
||||
// (not cached because this element changes)
|
||||
|
||||
|
|
@ -155,9 +155,7 @@ var AspectFilters = {
|
|||
Diaspora.widgets.publish("stream/reloaded");
|
||||
|
||||
// fade contents back in
|
||||
if(AspectFilters.requests === 0){
|
||||
AspectFilters.fadeIn();
|
||||
}
|
||||
AspectFilters.fadeIn();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
|||
8
public/stylesheets/vendor/facebox.css
vendored
8
public/stylesheets/vendor/facebox.css
vendored
|
|
@ -12,9 +12,9 @@
|
|||
-webkit-border-radius:2px;
|
||||
-moz-border-radius:2px;
|
||||
border-radius:2px;
|
||||
-webkit-box-shadow:0 0 12px rgba(0,0,0,0.8);
|
||||
-moz-box-shadow:0 0 12px rgba(0,0,0,0.8);
|
||||
box-shadow:0 0 12px rgba(0,0,0,0.8);
|
||||
-webkit-box-shadow:0 0 10px rgba(0,0,0,0.8), 0 2px 200px rgba(255,255,255,0.2);
|
||||
-moz-box-shadow:0 0 10px rgba(0,0,0,0.8), 0 2px 200px rgba(255,255,255,0.2);;
|
||||
box-shadow:0 0 10px rgba(0,0,0,0.8), 0 2px 200px rgba(255,255,255,0.2);;
|
||||
}
|
||||
|
||||
#facebox .content {
|
||||
|
|
@ -73,6 +73,6 @@
|
|||
}
|
||||
|
||||
.facebox_overlayBG {
|
||||
background-color: #fff;
|
||||
background-color: #000;
|
||||
z-index: 99;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,19 +85,11 @@ describe AdminsController do
|
|||
end
|
||||
|
||||
it 'invites a new user' do
|
||||
Invitation.should_receive(:create_invitee).with(:service => 'email', :identifier => 'bob@moms.com')
|
||||
Invitation.should_receive(:create)
|
||||
get :admin_inviter, :identifier => 'bob@moms.com'
|
||||
response.should redirect_to user_search_path
|
||||
flash.notice.should include("invitation sent")
|
||||
end
|
||||
|
||||
it 'passes an existing user to create_invitee' do
|
||||
Factory.create(:user, :email => 'bob@moms.com')
|
||||
bob = User.where(:email => 'bob@moms.com').first
|
||||
Invitation.should_receive(:find_existing_user).with('email', 'bob@moms.com').and_return(bob)
|
||||
Invitation.should_receive(:create_invitee).with(:service => 'email', :identifier => 'bob@moms.com', :existing_user => bob)
|
||||
get :admin_inviter, :identifier => 'bob@moms.com'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ describe ContactsController do
|
|||
|
||||
it 'will return the contacts for multiple aspects' do
|
||||
get :index, :aspect_ids => bob.aspect_ids, :format => 'json'
|
||||
assigns[:people].should == bob.contacts.map(&:person)
|
||||
assigns[:people].map(&:id).should =~ bob.contacts.map{|c| c.person.id}
|
||||
response.should be_success
|
||||
end
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ describe ContactsController do
|
|||
aspect.contacts << bob.contact_for(eve.person)
|
||||
get :index, :format => 'json', :aspect_ids => bob.aspect_ids
|
||||
assigns[:people].map{|p| p.id}.uniq.should == assigns[:people].map{|p| p.id}
|
||||
assigns[:people].should == bob.contacts.map(&:person)
|
||||
assigns[:people].map(&:id).should =~ bob.contacts.map{|c| c.person.id}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -54,47 +54,75 @@ describe ConversationsController do
|
|||
end
|
||||
|
||||
describe '#create' do
|
||||
before do
|
||||
@hash = {
|
||||
:conversation => {
|
||||
:subject => "secret stuff",
|
||||
:text => 'text'},
|
||||
:contact_ids => [alice.contacts.first.id]
|
||||
}
|
||||
end
|
||||
|
||||
it 'creates a conversation' do
|
||||
lambda {
|
||||
post :create, @hash
|
||||
}.should change(Conversation, :count).by(1)
|
||||
end
|
||||
|
||||
it 'creates a message' do
|
||||
lambda {
|
||||
post :create, @hash
|
||||
}.should change(Message, :count).by(1)
|
||||
end
|
||||
|
||||
it 'sets the author to the current_user' do
|
||||
@hash[:author] = Factory.create(:user)
|
||||
post :create, @hash
|
||||
Message.first.author.should == alice.person
|
||||
Conversation.first.author.should == alice.person
|
||||
end
|
||||
|
||||
it 'dispatches the conversation' do
|
||||
cnv = Conversation.create(
|
||||
{
|
||||
:author => alice.person,
|
||||
:participant_ids => [alice.contacts.first.person.id, alice.person.id],
|
||||
:subject => 'not spam',
|
||||
:messages_attributes => [ {:author => alice.person, :text => 'cool stuff'} ]
|
||||
context 'with a valid conversation' do
|
||||
before do
|
||||
@hash = {
|
||||
:conversation => {
|
||||
:subject => "secret stuff",
|
||||
:text => 'text debug'
|
||||
},
|
||||
:contact_ids => [alice.contacts.first.id]
|
||||
}
|
||||
)
|
||||
p = Postzord::Dispatch.new(alice, cnv)
|
||||
Postzord::Dispatch.stub!(:new).and_return(p)
|
||||
p.should_receive(:post)
|
||||
post :create, @hash
|
||||
end
|
||||
|
||||
it 'creates a conversation' do
|
||||
lambda {
|
||||
post :create, @hash
|
||||
}.should change(Conversation, :count).by(1)
|
||||
end
|
||||
|
||||
it 'creates a message' do
|
||||
lambda {
|
||||
post :create, @hash
|
||||
}.should change(Message, :count).by(1)
|
||||
end
|
||||
|
||||
it 'sets the author to the current_user' do
|
||||
@hash[:author] = Factory.create(:user)
|
||||
post :create, @hash
|
||||
Message.first.author.should == alice.person
|
||||
Conversation.first.author.should == alice.person
|
||||
end
|
||||
|
||||
it 'dispatches the conversation' do
|
||||
cnv = Conversation.create(
|
||||
{
|
||||
:author => alice.person,
|
||||
:participant_ids => [alice.contacts.first.person.id, alice.person.id],
|
||||
:subject => 'not spam',
|
||||
:messages_attributes => [ {:author => alice.person, :text => 'cool stuff'} ]
|
||||
}
|
||||
)
|
||||
|
||||
p = Postzord::Dispatch.new(alice, cnv)
|
||||
Postzord::Dispatch.stub!(:new).and_return(p)
|
||||
p.should_receive(:post)
|
||||
post :create, @hash
|
||||
end
|
||||
end
|
||||
|
||||
context 'with empty text' do
|
||||
before do
|
||||
@hash = {
|
||||
:conversation => {
|
||||
:subject => 'secret stuff',
|
||||
:text => ' '
|
||||
},
|
||||
:contact_ids => [alice.contacts.first.id]
|
||||
}
|
||||
end
|
||||
|
||||
it 'does not create a conversation' do
|
||||
lambda {
|
||||
post :create, @hash
|
||||
}.should_not change(Conversation, :count).by(1)
|
||||
end
|
||||
|
||||
it 'does not create a message' do
|
||||
lambda {
|
||||
post :create, @hash
|
||||
}.should_not change(Message, :count).by(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ describe InvitationsController 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))
|
||||
|
|
@ -19,43 +20,37 @@ describe InvitationsController do
|
|||
describe "#create" do
|
||||
before do
|
||||
sign_in :user, @user
|
||||
@invite = {:invite_message=>"test", :aspect_id=> @aspect.id.to_s, :email=>"abc@example.com"}
|
||||
@controller.stub!(:current_user).and_return(@user)
|
||||
request.env["HTTP_REFERER"]= 'http://test.host/cats/foo'
|
||||
end
|
||||
|
||||
it 'calls the resque job Job::InviteUser' do
|
||||
Resque.should_receive(:enqueue)
|
||||
post :create, :user => @invite
|
||||
it 'saves and invitation' do
|
||||
expect {
|
||||
post :create, :user => @invite
|
||||
}.should change(Invitation, :count).by(1)
|
||||
end
|
||||
|
||||
it 'handles a comma seperated list of emails' do
|
||||
Resque.should_receive(:enqueue).twice()
|
||||
post :create, :user => @invite.merge(
|
||||
expect{
|
||||
post :create, :user => @invite.merge(
|
||||
:email => "foofoofoofoo@example.com, mbs@gmail.com")
|
||||
}.should change(Invitation, :count).by(2)
|
||||
end
|
||||
|
||||
it 'handles a comma seperated list of emails with whitespace' do
|
||||
Resque.should_receive(:enqueue).twice()
|
||||
post :create, :user => @invite.merge(
|
||||
:email => "foofoofoofoo@example.com , mbs@gmail.com")
|
||||
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[:error].should_not be_empty
|
||||
flash[:error].should =~ /foo\.com/
|
||||
flash[:error].should =~ /lala@foo/
|
||||
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
|
||||
open_bit = AppConfig[:open_invitations]
|
||||
AppConfig[:open_invitations] = true
|
||||
|
||||
Resque.should_receive(:enqueue).once
|
||||
post :create, :user => @invite
|
||||
|
||||
expect{
|
||||
post :create, :user => @invite
|
||||
}.to change(Invitation, :count).by(1)
|
||||
AppConfig[:open_invitations] = open_bit
|
||||
end
|
||||
|
||||
|
|
@ -67,16 +62,19 @@ describe InvitationsController do
|
|||
it 'strips out your own email' do
|
||||
lambda {
|
||||
post :create, :user => @invite.merge(:email => @user.email)
|
||||
}.should_not change(User, :count)
|
||||
}.should_not change(Invitation, :count)
|
||||
|
||||
Resque.should_receive(:enqueue).once
|
||||
post :create, :user => @invite.merge(:email => "hello@example.org, #{@user.email}")
|
||||
expect{
|
||||
post :create, :user => @invite.merge(:email => "hello@example.org, #{@user.email}")
|
||||
}.should change(Invitation, :count).by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update" do
|
||||
before do
|
||||
@invited_user = @user.invite_user(@aspect.id, 'email', "a@a.com")
|
||||
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",
|
||||
|
|
@ -137,7 +135,8 @@ describe InvitationsController do
|
|||
@controller.stub!(:current_user).and_return(@user)
|
||||
request.env["HTTP_REFERER"]= 'http://test.host/cats/foo'
|
||||
|
||||
@invited_user = @user.invite_user(@aspect.id, 'email', "a@a.com", "")
|
||||
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
|
||||
|
|
@ -148,12 +147,24 @@ describe InvitationsController do
|
|||
end
|
||||
|
||||
it 'does not send an invitation for a different user' do
|
||||
@user2 = bob
|
||||
@aspect2 = @user2.aspects.create(:name => "cats")
|
||||
@user2.invite_user(@aspect2.id, 'email', "b@b.com", "")
|
||||
invitation2 = @user2.reload.invitations_from_me.first
|
||||
invitation2 = Factory(:invitation, :sender => bob, :service => 'email', :identifier => "a@a.com")
|
||||
|
||||
Resque.should_not_receive(:enqueue)
|
||||
put :resend, :id => invitation2.id
|
||||
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_empty
|
||||
flash[:notice].should =~ /foo\.com/
|
||||
flash[:notice].should =~ /lala@foo/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -28,15 +28,34 @@ describe MessagesController do
|
|||
context "on my own post" do
|
||||
before do
|
||||
@cnv = Conversation.create(@create_hash)
|
||||
@message_hash = {:conversation_id => @cnv.id, :message => {:text => "here is something else"}}
|
||||
end
|
||||
|
||||
it 'redirects to conversation' do
|
||||
lambda{
|
||||
post :create, @message_hash
|
||||
}.should change(Message, :count).by(1)
|
||||
response.code.should == '302'
|
||||
response.should redirect_to(conversations_path(:conversation_id => @cnv))
|
||||
context "with a valid message" do
|
||||
before do
|
||||
@message_hash = {:conversation_id => @cnv.id, :message => {:text => "here is something else"}}
|
||||
end
|
||||
|
||||
it 'redirects to conversation' do
|
||||
lambda{
|
||||
post :create, @message_hash
|
||||
}.should change(Message, :count).by(1)
|
||||
response.code.should == '302'
|
||||
response.should redirect_to(conversations_path(:conversation_id => @cnv))
|
||||
end
|
||||
end
|
||||
|
||||
context "with an empty message" do
|
||||
before do
|
||||
@message_hash = {:conversation_id => @cnv.id, :message => {:text => " "}}
|
||||
end
|
||||
|
||||
it 'redirects to conversation' do
|
||||
lambda{
|
||||
post :create, @message_hash
|
||||
}.should_not change(Message, :count).by(1)
|
||||
response.code.should == '302'
|
||||
response.should redirect_to(conversations_path(:conversation_id => @cnv))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ describe ServicesController do
|
|||
end
|
||||
|
||||
it 'does not create a duplicate invitation' do
|
||||
inv = Invitation.create!(:sender_id => @user.id, :recipient_id => eve.id, :aspect_id => @user.aspects.first.id)
|
||||
inv = Invitation.create!(:sender => @user, :recipient => eve, :aspect => @user.aspects.first, :identifier => eve.email)
|
||||
@invite_params[:invitation_id] = inv.id
|
||||
|
||||
lambda {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Factory.define :person do |p|
|
|||
p.sequence(:url) { |n| AppConfig[:pod_url] }
|
||||
p.serialized_public_key OpenSSL::PKey::RSA.generate(1024).public_key.export
|
||||
p.after_build do |person|
|
||||
person.profile ||= Factory.build(:profile, :person => person)
|
||||
person.profile = Factory.build(:profile, :person => person) unless person.profile.first_name.present?
|
||||
end
|
||||
p.after_create do |person|
|
||||
person.profile.save
|
||||
|
|
@ -96,6 +96,15 @@ Factory.define :reshare do |r|
|
|||
r.association(:author, :factory => :person)
|
||||
end
|
||||
|
||||
Factory.define :invitation do |i|
|
||||
i.service "email"
|
||||
i.identifier "bob.smith@smith.com"
|
||||
i.association :sender, :factory => :user_with_aspect
|
||||
i.after_build do |i|
|
||||
i.aspect = i.sender.aspects.first
|
||||
end
|
||||
end
|
||||
|
||||
Factory.define :service do |service|
|
||||
service.nickname "sirrobertking"
|
||||
service.type "Services::Twitter"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ describe GettingStartedHelper do
|
|||
it 'returns true if the current user has filled out all 7 suggested fields (from getting started)' do
|
||||
profile = @current_user.person.profile
|
||||
profile.update_attributes!(
|
||||
{:first_name => "alice", :last_name => "smith", :image_url => "abcd.jpg", :birthday => Date.new,
|
||||
{:first_name => "alice", :last_name => "smith", :image_url => "abcd.jpg", :birthday => Time.now,
|
||||
:gender => "cow", :location => "san fran", :tag_string => "#sup", :bio => "holler" })
|
||||
has_completed_profile?.should be_true
|
||||
end
|
||||
|
|
@ -59,7 +59,7 @@ describe GettingStartedHelper do
|
|||
end
|
||||
|
||||
it 'returns false if the current_user has less than 2 contacts (inclusive)' do
|
||||
@current_user.contacts.delete_all
|
||||
@current_user.contacts.destroy_all
|
||||
has_few_contacts?.should be_false
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ describe('AspectFilters', function(){
|
|||
it('initializes selectedGUIDS', function(){
|
||||
expect(AspectFilters.selectedGUIDS).toEqual([]);
|
||||
});
|
||||
it('initializes requests', function(){
|
||||
expect(AspectFilters.requests).toEqual(0);
|
||||
it('initializes activeRequest', function(){
|
||||
expect(AspectFilters.activeRequest).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@ describe RakeHelpers do
|
|||
Devise.mailer.deliveries = []
|
||||
end
|
||||
it 'should send emails to each backer' do
|
||||
Invitation.should_receive(:create_invitee).exactly(3).times
|
||||
process_emails(@csv, 100, 1, false)
|
||||
expect{
|
||||
process_emails(@csv, 100, 1, false)
|
||||
}.to change(User, :count).by(3)
|
||||
end
|
||||
|
||||
it 'should not send the email to the same email twice' do
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# Copyright (c) 2011, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
|
|
@ -6,7 +6,6 @@ require 'spec_helper'
|
|||
|
||||
describe Invitation do
|
||||
let(:user) { alice }
|
||||
let(:aspect) { user.aspects.first }
|
||||
|
||||
before do
|
||||
@email = 'maggie@example.com'
|
||||
|
|
@ -14,292 +13,130 @@ describe Invitation do
|
|||
end
|
||||
describe 'validations' do
|
||||
before do
|
||||
aspect
|
||||
@invitation = Invitation.new(:sender => user, :recipient => eve, :aspect => aspect)
|
||||
@invitation = Factory.build(:invitation, :sender => user, :recipient => eve, :aspect => user.aspects.first)
|
||||
end
|
||||
|
||||
it 'is valid' do
|
||||
@invitation.sender.should == user
|
||||
@invitation.recipient.should == eve
|
||||
@invitation.aspect.should == aspect
|
||||
@invitation.aspect.should == user.aspects.first
|
||||
@invitation.should be_valid
|
||||
end
|
||||
it 'is from a user' do
|
||||
@invitation.sender = nil
|
||||
@invitation.should_not be_valid
|
||||
end
|
||||
it 'is to a user' do
|
||||
@invitation.recipient = nil
|
||||
@invitation.should_not be_valid
|
||||
end
|
||||
it 'is into an aspect' do
|
||||
@invitation.aspect = nil
|
||||
|
||||
it 'ensures the sender is placing the recipient into one of his aspects' do
|
||||
@invitation.aspect = Factory(:aspect)
|
||||
@invitation.should_not be_valid
|
||||
end
|
||||
end
|
||||
|
||||
it 'has a message' do
|
||||
@invitation = Invitation.new(:sender => user, :recipient => eve, :aspect => aspect)
|
||||
@invitation = Factory.build(:invitation, :sender => user, :recipient => eve, :aspect => user.aspects.first)
|
||||
@invitation.message = "!"
|
||||
@invitation.message.should == "!"
|
||||
end
|
||||
|
||||
describe '.find_existing_user' do
|
||||
let(:inv) { Invitation.find_existing_user(@type, @identifier) }
|
||||
|
||||
context 'send a request to an existing' do
|
||||
context 'active user' do
|
||||
it 'by email' do
|
||||
@identifier = alice.email
|
||||
@type = 'email'
|
||||
inv.should == alice
|
||||
end
|
||||
|
||||
it 'by service' do
|
||||
uid = '123324234'
|
||||
alice.services << Services::Facebook.new(:uid => uid)
|
||||
alice.save
|
||||
|
||||
@type = 'facebook'
|
||||
@identifier = uid
|
||||
|
||||
inv.should == alice
|
||||
end
|
||||
end
|
||||
|
||||
context 'invited user' do
|
||||
it 'by email' do
|
||||
@identifier = alice.email
|
||||
@type = 'email'
|
||||
|
||||
alice.invitation_identifier = @identifier
|
||||
alice.invitation_service = @type
|
||||
alice.save
|
||||
inv.should == alice
|
||||
end
|
||||
|
||||
it 'by service' do
|
||||
fb_id = 'abc123'
|
||||
alice.invitation_service = 'facebook'
|
||||
alice.invitation_identifier = fb_id
|
||||
alice.save
|
||||
|
||||
@identifier = fb_id
|
||||
@type = 'facebook'
|
||||
inv.should == alice
|
||||
end
|
||||
end
|
||||
describe 'the invite process' do
|
||||
before do
|
||||
end
|
||||
end
|
||||
|
||||
describe '.invite' do
|
||||
it 'creates an invitation' do
|
||||
it 'works for a new user' do
|
||||
invite = Invitation.new(:sender => alice, :aspect => alice.aspects.first, :service => 'email', :identifier => 'foo@bar.com')
|
||||
lambda {
|
||||
Invitation.invite(:service => 'email', :identifier => @email, :from => user, :into => aspect)
|
||||
}.should change(Invitation, :count).by(1)
|
||||
end
|
||||
|
||||
it 'associates the invitation with the inviter' do
|
||||
lambda {
|
||||
Invitation.invite(:service => 'email', :identifier => @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(:service => 'email', :identifier => @email, :from => user, :into => aspect)
|
||||
new_user.invitations_to_me.count.should == 1
|
||||
end
|
||||
|
||||
it 'creates a user' do
|
||||
lambda {
|
||||
Invitation.invite(:from => user, :service => 'email', :identifier => @email, :into => aspect)
|
||||
invite.save
|
||||
invite.send!
|
||||
}.should change(User, :count).by(1)
|
||||
end
|
||||
|
||||
it 'returns the new user' do
|
||||
new_user = Invitation.invite(:from => user, :service => 'email', :identifier => @email, :into => aspect)
|
||||
new_user.is_a?(User).should be_true
|
||||
new_user.email.should == @email
|
||||
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)
|
||||
lambda {
|
||||
invite.send!
|
||||
}.should_not change(User, :count)
|
||||
end
|
||||
|
||||
it 'adds the inviter to the invited_user' do
|
||||
new_user = Invitation.invite(:from => user, :service => 'email', :identifier => @email, :into => aspect)
|
||||
new_user.invitations_to_me.first.sender.should == user
|
||||
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
|
||||
|
||||
it 'adds an optional message' do
|
||||
message = "How've you been?"
|
||||
new_user = Invitation.invite(:from => user, :service => 'email', :identifier => @email, :into => aspect, :message => message)
|
||||
new_user.invitations_to_me.first.message.should == message
|
||||
it 'handles the case when that user has an invite but not a user' do
|
||||
pending
|
||||
end
|
||||
|
||||
it 'sends a contact request to a user with that email into the aspect' do
|
||||
user.should_receive(:share_with).with(eve.person, aspect)
|
||||
Invitation.invite(:from => user, :service => 'email', :identifier => eve.email, :into => aspect)
|
||||
it 'handles the case where that user has an invite but has not yet accepted' do
|
||||
pending
|
||||
end
|
||||
|
||||
context 'invalid email' do
|
||||
it 'return a user with errors' do
|
||||
new_user = Invitation.invite(:service => 'email', :identifier => "fkjlsdf", :from => user, :into => aspect)
|
||||
new_user.should have(1).errors_on(:email)
|
||||
new_user.should_not be_persisted
|
||||
end
|
||||
it 'generate the invitation token and pass it to the user' do
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
describe '.create_invitee' do
|
||||
context "when we're resending an invitation" do
|
||||
before do
|
||||
@valid_params = {:from => user,
|
||||
:service => 'email',
|
||||
:identifier => @email,
|
||||
:into => aspect,
|
||||
:message => @message}
|
||||
@invitee = Invitation.create_invitee(:service => 'email', :identifier => @email)
|
||||
@valid_params[:existing_user] = @invitee
|
||||
end
|
||||
|
||||
it "does not create a user" do
|
||||
expect { Invitation.create_invitee(@valid_params) }.should_not change(User, :count)
|
||||
end
|
||||
|
||||
it "sends mail" do
|
||||
expect {
|
||||
Invitation.create_invitee(@valid_params)
|
||||
}.should change { Devise.mailer.deliveries.size }.by(1)
|
||||
end
|
||||
|
||||
it "does not set the key" do
|
||||
expect {
|
||||
Invitation.create_invitee(@valid_params)
|
||||
}.should_not change { @invitee.reload.serialized_private_key }
|
||||
end
|
||||
|
||||
it "does not change the invitation token" do
|
||||
old_token = @invitee.invitation_token
|
||||
Invitation.create_invitee(@valid_params)
|
||||
@invitee.reload.invitation_token.should == old_token
|
||||
end
|
||||
end
|
||||
context 'with an inviter' do
|
||||
before do
|
||||
@message = "whatever"
|
||||
@valid_params = {:from => user, :service => 'email', :identifier => @email, :into => aspect, :message => @message}
|
||||
end
|
||||
|
||||
it "sends mail" do
|
||||
expect {
|
||||
Invitation.create_invitee(@valid_params)
|
||||
}.should change { Devise.mailer.deliveries.size }.by(1)
|
||||
end
|
||||
|
||||
it "includes the message in the email" do
|
||||
Invitation.create_invitee(@valid_params)
|
||||
Devise.mailer.deliveries.last.to_s.should include(@message)
|
||||
end
|
||||
|
||||
it "has no translation missing" do
|
||||
Invitation.create_invitee(@valid_params)
|
||||
Devise.mailer.deliveries.last.body.raw_source.should_not match(/(translation_missing.+)/)
|
||||
end
|
||||
|
||||
it "doesn't create a user if the email is invalid" do
|
||||
new_user = Invitation.create_invitee(@valid_params.merge(:identifier => 'fdfdfdfdf'))
|
||||
new_user.should_not be_persisted
|
||||
new_user.should have(1).error_on(:email)
|
||||
end
|
||||
|
||||
it "does not save a user with an empty string email" do
|
||||
@valid_params[:service] = 'facebook'
|
||||
@valid_params[:identifier] = '3423423'
|
||||
Invitation.create_invitee(@valid_params)
|
||||
@valid_params[:identifier] = 'dfadsfdas'
|
||||
expect { Invitation.create_invitee(@valid_params) }.should_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
context 'with no inviter' do
|
||||
it 'sends an email that includes the right things' do
|
||||
Invitation.create_invitee(:service => 'email', :identifier => @email)
|
||||
Devise.mailer.deliveries.first.to_s.should include("Email not displaying correctly?")
|
||||
end
|
||||
it 'creates a user' do
|
||||
expect {
|
||||
Invitation.create_invitee(:service => 'email', :identifier => @email)
|
||||
}.should change(User, :count).by(1)
|
||||
end
|
||||
it 'sends email to the invited user' do
|
||||
expect {
|
||||
Invitation.create_invitee(:service => 'email', :identifier => @email)
|
||||
}.should change { Devise.mailer.deliveries.size }.by(1)
|
||||
end
|
||||
it 'does not create an invitation' do
|
||||
expect {
|
||||
Invitation.create_invitee(:service => 'email', :identifier => @email)
|
||||
}.should_not change(Invitation, :count)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.resend' do
|
||||
|
||||
describe '.batch_invite' do
|
||||
before do
|
||||
aspect
|
||||
user.invite_user(aspect.id, 'email', "a@a.com", "")
|
||||
@invitation = user.reload.invitations_from_me.first
|
||||
@emails = ['max@foo.com', 'bob@mom.com']
|
||||
@opts = {:aspect => eve.aspects.first, :sender => eve, :service => 'email'}
|
||||
end
|
||||
|
||||
it 'returns an array of invites based on the emails passed in' do
|
||||
invites = Invitation.batch_invite(@emails, @opts)
|
||||
invites.count.should be 2
|
||||
invites.all?{|x| x.persisted?}.should be_true
|
||||
end
|
||||
|
||||
it 'shares with people who are already on the pod and does not create an invite for them' do
|
||||
Factory(:user, :email => @emails.first)
|
||||
invites = nil
|
||||
expect{
|
||||
invites = Invitation.batch_invite(@emails, @opts)
|
||||
}.to change(eve.contacts, :count).by(1)
|
||||
invites.count.should be 1
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
describe '#resend' do
|
||||
before do
|
||||
@invitation = Factory(:invitation, :sender => alice, :aspect => alice.aspects.first, :service => 'email', :identifier => 'a@a.com')
|
||||
end
|
||||
|
||||
it 'sends another email' do
|
||||
lambda { @invitation.resend }.should change(Devise.mailer.deliveries, :count).by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#share_with!' do
|
||||
before do
|
||||
@new_user = Invitation.invite(:from => user, :service => 'email', :identifier => @email, :into => aspect)
|
||||
acceptance_params = {:invitation_token => "abc",
|
||||
:username => "user",
|
||||
:email => @email,
|
||||
: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.share_with!
|
||||
}.should change(Invitation, :count).by(-1)
|
||||
end
|
||||
|
||||
it 'creates a contact for the inviter and invitee' do
|
||||
lambda {
|
||||
@invitation.share_with!
|
||||
}.should change(Contact, :count).by(2)
|
||||
@invitation.resend
|
||||
}.should change(Devise.mailer.deliveries, :count).by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#recipient_identifier' do
|
||||
it 'calls email if the invitation_service is email' do
|
||||
alice.invite_user(aspect.id, 'email', "a@a.com", "")
|
||||
invitation = alice.reload.invitations_from_me.first
|
||||
invitation.recipient_identifier.should == 'a@a.com'
|
||||
email = 'abc@abc.com'
|
||||
invitation = Factory(:invitation, :sender => alice, :service => 'email', :identifier => email, :aspect => alice.aspects.first)
|
||||
invitation.recipient_identifier.should == email
|
||||
end
|
||||
it 'gets the name if the invitation_service is facebook' do
|
||||
alice.services << Services::Facebook.new(:uid => "13234895")
|
||||
alice.reload.services(true).first.service_users.create(:uid => "23526464", :photo_url => 'url', :name => "Remote User")
|
||||
alice.invite_user(aspect.id, 'facebook', "23526464", '')
|
||||
invitation = alice.reload.invitations_from_me.first
|
||||
invitation.recipient_identifier.should == "Remote User"
|
||||
end
|
||||
it 'does not error if the facebook user is not recorded' do
|
||||
alice.services << Services::Facebook.new(:uid => "13234895")
|
||||
alice.reload.services(true).first.service_users.create(:uid => "23526464", :photo_url => 'url', :name => "Remote User")
|
||||
alice.invite_user(aspect.id, 'facebook', "23526464", '')
|
||||
alice.services.first.service_users.delete_all
|
||||
invitation = alice.reload.invitations_from_me.first
|
||||
invitation.recipient_identifier.should == "A Facebook user"
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -4,20 +4,14 @@ describe Job::Mail::InviteUserByEmail do
|
|||
before do
|
||||
@sender = alice
|
||||
@email = 'bob@bob.com'
|
||||
@aspect_id = alice.aspects.first.id
|
||||
@aspect = alice.aspects.first
|
||||
@message = 'invite message'
|
||||
|
||||
User.stub(:find){ |id|
|
||||
if id == @sender.id
|
||||
@sender
|
||||
else
|
||||
nil
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
it 'calls invite_user with email param' do
|
||||
@sender.should_receive(:invite_user).with(@aspect_id, 'email', @email, @message)
|
||||
Job::Mail::InviteUserByEmail.perform(@sender.id, @email, @aspect_id, @message)
|
||||
invitation = Invitation.create(:sender => @sender, :identifier => @email, :service => "email", :aspect => @aspect, :message => @message)
|
||||
invitation.should_receive(:send!)
|
||||
Invitation.stub(:find).and_return(invitation)
|
||||
Job::Mail::InviteUserByEmail.perform(invitation.id)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,17 +5,13 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Job::ResendInvitation do
|
||||
describe '#perfom_delegate' do
|
||||
describe '#perfom' do
|
||||
it 'should call .resend on the object' do
|
||||
user = alice
|
||||
aspect = user.aspects.create(:name => "cats")
|
||||
user.invite_user(aspect.id, 'email', "a@a.com", "")
|
||||
invitation = user.reload.invitations_from_me.first
|
||||
invite = Factory(:invitation, :service => 'email', :identifier => 'foo@bar.com')
|
||||
|
||||
#Notification.should_receive(:notify).with(instance_of(User), instance_of(StatusMessage), instance_of(Person))
|
||||
Invitation.stub(:where).with(:id => invitation.id ).and_return([invitation])
|
||||
invitation.should_receive(:resend)
|
||||
Job::ResendInvitation.perform(invitation.id)
|
||||
Invitation.stub(:find).and_return(invite)
|
||||
invite.should_receive(:resend)
|
||||
Job::ResendInvitation.perform(invite.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,6 +11,15 @@ describe Person do
|
|||
@person = Factory.create(:person)
|
||||
end
|
||||
|
||||
it 'always has a profile' do
|
||||
Person.new.profile.should_not be_nil
|
||||
end
|
||||
|
||||
it 'does not save automatically' do
|
||||
Person.new.persisted?.should be_false
|
||||
Person.new.profile.persisted?.should be_false
|
||||
end
|
||||
|
||||
context 'scopes' do
|
||||
describe '.for_json' do
|
||||
it 'does not select public keys' do
|
||||
|
|
@ -144,7 +153,7 @@ describe Person do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'xml' do
|
||||
describe 'XML' do
|
||||
before do
|
||||
@xml = @person.to_xml.to_s
|
||||
end
|
||||
|
|
|
|||
|
|
@ -69,12 +69,12 @@ JSON
|
|||
|
||||
it 'attaches local models' do
|
||||
@service.save_friends
|
||||
@service.service_users.first.person.should == @user2.person
|
||||
@service.service_users.where(:uid => @user2_fb_id).first.person.should == @user2.person
|
||||
end
|
||||
|
||||
it 'overwrites local model information' do
|
||||
@service.save_friends
|
||||
su = @service.service_users.first
|
||||
su = @service.service_users.where(:uid => @user2_fb_id).first
|
||||
su.person.should == @user2.person
|
||||
su.contact.should == nil
|
||||
|
||||
|
|
|
|||
|
|
@ -1,90 +0,0 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe User do
|
||||
context "creating invites" do
|
||||
before do
|
||||
@aspect = eve.aspects.first
|
||||
@email = "bob@bob.com"
|
||||
end
|
||||
|
||||
it 'requires your aspect' do
|
||||
lambda {
|
||||
eve.invite_user(alice.aspects.first.id, "email", "maggie@example.com")
|
||||
}.should raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
it 'takes a service parameter' do
|
||||
@invite_params = {:service => 'email'}
|
||||
Invitation.should_receive(:invite).with(hash_including(@invite_params))
|
||||
eve.invite_user(@aspect.id, 'email', @email)
|
||||
end
|
||||
|
||||
it 'takes an indentifier parameter' do
|
||||
@invite_params = {:identifier => @email}
|
||||
Invitation.should_receive(:invite).with(hash_including(@invite_params))
|
||||
eve.invite_user(@aspect.id, 'email', @email)
|
||||
end
|
||||
|
||||
it 'calls Invitation.invite' do
|
||||
Invitation.should_receive(:invite)
|
||||
eve.invite_user(@aspect.id, 'email', @email)
|
||||
end
|
||||
|
||||
it 'has an invitation' do
|
||||
eve.invite_user(@aspect.id, 'email', @email).invitations_to_me.count.should == 1
|
||||
end
|
||||
|
||||
it 'creates it with an email' do
|
||||
eve.invite_user(@aspect.id, 'email', @email).email.should == @email
|
||||
end
|
||||
|
||||
it "throws if you try to add someone you're connected to" do
|
||||
connect_users(eve, @aspect, alice, alice.aspects.first)
|
||||
lambda {
|
||||
eve.invite_user(@aspect.id, 'email', alice.email)
|
||||
}.should raise_error ActiveRecord::RecordNotUnique
|
||||
end
|
||||
|
||||
it 'does not invite people I already invited' do
|
||||
eve.invite_user(@aspect.id, 'email', "email1@example.com")
|
||||
lambda {
|
||||
eve.invite_user(@aspect.id, 'email', "email1@example.com")
|
||||
}.should raise_error /You already invited this person/
|
||||
end
|
||||
end
|
||||
|
||||
describe "#accept_invitation!" do
|
||||
before do
|
||||
invite_pre = Invitation.invite(:from => eve, :service => 'email', :identifier => 'invitee@example.org', :into => eve.aspects.first).reload
|
||||
@person_count = Person.count
|
||||
@invited_user = invite_pre.accept_invitation!(: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
|
||||
@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
|
||||
|
||||
it 'resolves incoming invitations into contact requests' do
|
||||
eve.contacts.where(:person_id => @invited_user.person.id).count.should == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -318,6 +318,76 @@ 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' do
|
||||
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'update_user_preferences' do
|
||||
before do
|
||||
@pref_count = UserPreference::VALID_EMAIL_TYPES.count
|
||||
|
|
@ -484,14 +554,14 @@ describe User do
|
|||
|
||||
describe '#destroy' do
|
||||
it 'removes invitations from the user' do
|
||||
alice.invite_user alice.aspects.first.id, 'email', 'blah@blah.blah'
|
||||
Factory(:invitation, :sender => alice)
|
||||
lambda {
|
||||
alice.destroy
|
||||
}.should change {alice.invitations_from_me(true).count }.by(-1)
|
||||
end
|
||||
|
||||
it 'removes invitations to the user' do
|
||||
Invitation.create(:sender_id => eve.id, :recipient_id => alice.id, :aspect_id => eve.aspects.first.id)
|
||||
Invitation.create!(:sender => eve, :recipient => alice, :identifier => alice.email, :aspect => eve.aspects.first)
|
||||
lambda {
|
||||
alice.destroy
|
||||
}.should change {alice.invitations_to_me(true).count }.by(-1)
|
||||
|
|
@ -810,6 +880,52 @@ describe User do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#accept_invitation!" do
|
||||
before do
|
||||
fantasy_resque do
|
||||
@invitation = Factory.create(: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
|
||||
@retraction = mock
|
||||
|
|
|
|||
Loading…
Reference in a new issue