Make Photos not inherit from Posts
This commit is contained in:
parent
02a3c3f88b
commit
bdeae54c6c
34 changed files with 481 additions and 331 deletions
25
Gemfile.lock
25
Gemfile.lock
|
|
@ -104,7 +104,7 @@ GEM
|
|||
xml-simple
|
||||
bcrypt-ruby (2.1.4)
|
||||
builder (2.1.2)
|
||||
bunny (0.7.6)
|
||||
bunny (0.7.8)
|
||||
capistrano (2.5.19)
|
||||
highline
|
||||
net-scp (>= 1.0.0)
|
||||
|
|
@ -128,14 +128,14 @@ GEM
|
|||
erubis
|
||||
extlib
|
||||
highline
|
||||
json (<= 1.4.6, >= 1.4.4)
|
||||
json (>= 1.4.4, <= 1.4.6)
|
||||
mixlib-authentication (>= 1.1.0)
|
||||
mixlib-cli (>= 1.1.0)
|
||||
mixlib-config (>= 1.1.2)
|
||||
mixlib-log (>= 1.2.0)
|
||||
moneta
|
||||
ohai (>= 0.5.7)
|
||||
rest-client (< 1.7.0, >= 1.0.4)
|
||||
rest-client (>= 1.0.4, < 1.7.0)
|
||||
uuidtools
|
||||
childprocess (0.2.2)
|
||||
ffi (~> 1.0.6)
|
||||
|
|
@ -164,7 +164,7 @@ GEM
|
|||
warden (~> 1.0.3)
|
||||
devise_invitable (0.5.0)
|
||||
devise (~> 1.3.1)
|
||||
rails (<= 3.2, >= 3.0.0)
|
||||
rails (>= 3.0.0, <= 3.2)
|
||||
diff-lcs (1.1.3)
|
||||
em-synchrony (0.2.0)
|
||||
eventmachine (>= 0.12.9)
|
||||
|
|
@ -181,7 +181,7 @@ GEM
|
|||
faraday (0.6.1)
|
||||
addressable (~> 2.2.4)
|
||||
multipart-post (~> 1.1.0)
|
||||
rack (< 2, >= 1.1.0)
|
||||
rack (>= 1.1.0, < 2)
|
||||
faraday-stack (0.1.3)
|
||||
faraday (~> 0.6)
|
||||
faraday_middleware (0.6.5)
|
||||
|
|
@ -211,7 +211,7 @@ GEM
|
|||
rspec-instafail (~> 0.1.8)
|
||||
ruby-progressbar (~> 0.0.10)
|
||||
gem_plugin (0.2.3)
|
||||
gherkin (2.5.1)
|
||||
gherkin (2.5.2)
|
||||
json (>= 1.4.6)
|
||||
haml (3.1.2)
|
||||
hashie (1.0.0)
|
||||
|
|
@ -281,7 +281,7 @@ GEM
|
|||
net-ssh (2.0.24)
|
||||
net-ssh-gateway (1.1.0)
|
||||
net-ssh (>= 1.99.1)
|
||||
newrelic_rpm (3.1.2)
|
||||
newrelic_rpm (3.2.0)
|
||||
nokogiri (1.4.3.1)
|
||||
oa-basic (0.2.6)
|
||||
oa-core (= 0.2.6)
|
||||
|
|
@ -318,7 +318,7 @@ GEM
|
|||
addressable (~> 2.2)
|
||||
ohai (0.5.8)
|
||||
extlib
|
||||
json (<= 1.4.6, >= 1.4.4)
|
||||
json (>= 1.4.4, <= 1.4.6)
|
||||
mixlib-cli
|
||||
mixlib-config
|
||||
mixlib-log
|
||||
|
|
@ -366,7 +366,8 @@ GEM
|
|||
rake (0.9.2)
|
||||
rash (0.3.0)
|
||||
hashie (~> 1.0.0)
|
||||
rdoc (3.9.4)
|
||||
rdoc (3.10)
|
||||
json (~> 1.4)
|
||||
redcarpet (2.0.0b5)
|
||||
redis (2.2.2)
|
||||
redis-namespace (0.8.0)
|
||||
|
|
@ -434,7 +435,7 @@ GEM
|
|||
sqlite3 (1.3.4)
|
||||
subexec (0.0.4)
|
||||
systemu (2.4.0)
|
||||
term-ansicolor (1.0.6)
|
||||
term-ansicolor (1.0.7)
|
||||
thin (1.2.11)
|
||||
daemons (>= 1.0.9)
|
||||
eventmachine (>= 0.12.6)
|
||||
|
|
@ -459,13 +460,13 @@ GEM
|
|||
uuidtools (2.1.2)
|
||||
vegas (0.1.8)
|
||||
rack (>= 1.0.0)
|
||||
warden (1.0.5)
|
||||
warden (1.0.6)
|
||||
rack (>= 1.0)
|
||||
webmock (1.6.2)
|
||||
addressable (>= 2.2.2)
|
||||
crack (>= 0.1.7)
|
||||
will_paginate (3.0.pre2)
|
||||
xml-simple (1.1.0)
|
||||
xml-simple (1.1.1)
|
||||
yard (0.7.2)
|
||||
yui-compressor (0.9.6)
|
||||
POpen4 (>= 0.1.4)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class ActivityStreams::PhotosController < ApplicationController
|
|||
end
|
||||
|
||||
def show
|
||||
@photo = current_user.find_visible_post_by_id(params[:id])
|
||||
@photo = current_user.find_visible_shareable_by_id(Photo, params[:id])
|
||||
respond_with @photo
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class CommentsController < ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
target = current_user.find_visible_post_by_id params[:post_id]
|
||||
target = current_user.find_visible_shareable_by_id Post, params[:post_id]
|
||||
text = params[:text]
|
||||
|
||||
if target
|
||||
|
|
@ -55,7 +55,7 @@ class CommentsController < ApplicationController
|
|||
end
|
||||
|
||||
def index
|
||||
@post = current_user.find_visible_post_by_id(params[:post_id])
|
||||
@post = current_user.find_visible_shareable_by_id(Post, params[:post_id])
|
||||
if @post
|
||||
@comments = @post.comments.includes(:author => :profile).order('created_at ASC')
|
||||
render :layout => false
|
||||
|
|
|
|||
|
|
@ -59,10 +59,10 @@ class LikesController < ApplicationController
|
|||
|
||||
def target
|
||||
@target ||= if params[:post_id]
|
||||
current_user.find_visible_post_by_id(params[:post_id])
|
||||
current_user.find_visible_shareable_by_id(Post, params[:post_id])
|
||||
else
|
||||
comment = Comment.find(params[:comment_id])
|
||||
comment = nil unless current_user.find_visible_post_by_id(comment.commentable_id)
|
||||
comment = nil unless current_user.find_visible_shareable_by_id(Post, comment.commentable_id)
|
||||
comment
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class PhotosController < ApplicationController
|
|||
@contacts_of_contact_count = 0
|
||||
end
|
||||
|
||||
@posts = current_user.posts_from(@person).where(:type => 'Photo').paginate(:page => params[:page])
|
||||
@posts = current_user.photos_from(@person).paginate(:page => params[:page])
|
||||
|
||||
render 'people/show'
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ class PhotosController < ApplicationController
|
|||
end
|
||||
|
||||
def destroy
|
||||
photo = current_user.posts.where(:id => params[:id]).first
|
||||
photo = current_user.photos.where(:id => params[:id]).first
|
||||
|
||||
if photo
|
||||
current_user.retract(photo)
|
||||
|
|
@ -148,7 +148,7 @@ class PhotosController < ApplicationController
|
|||
end
|
||||
|
||||
def edit
|
||||
if @photo = current_user.posts.where(:id => params[:id]).first
|
||||
if @photo = current_user.photos.where(:id => params[:id]).first
|
||||
respond_with @photo
|
||||
else
|
||||
redirect_to person_photos_path(current_user.person)
|
||||
|
|
@ -156,7 +156,7 @@ class PhotosController < ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
photo = current_user.posts.where(:id => params[:id]).first
|
||||
photo = current_user.photos.where(:id => params[:id]).first
|
||||
if photo
|
||||
if current_user.update_post( photo, params[:photo] )
|
||||
flash.now[:notice] = I18n.t 'photos.update.notice'
|
||||
|
|
@ -187,7 +187,7 @@ class PhotosController < ApplicationController
|
|||
end
|
||||
|
||||
def photo
|
||||
@photo ||= current_user.find_visible_post_by_id(params[:id], :type => 'Photo')
|
||||
@photo ||= current_user.find_visible_shareable_by_id(Photo, params[:id])
|
||||
end
|
||||
|
||||
def additional_photos
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class PostsController < ApplicationController
|
|||
key = params[:id].to_s.length <= 8 ? :id : :guid
|
||||
|
||||
if user_signed_in?
|
||||
@post = current_user.find_visible_post_by_id(params[:id], :key => key)
|
||||
@post = current_user.find_visible_shareable_by_id(Post, params[:id], :key => key)
|
||||
else
|
||||
@post = Post.where(key => params[:id], :public => true).includes(:author, :comments => :author).first
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ class Aspect < ActiveRecord::Base
|
|||
|
||||
has_many :aspect_visibilities
|
||||
has_many :posts, :through => :aspect_visibilities, :source => :shareable, :source_type => 'Post'
|
||||
has_many :photos, :through => :aspect_visibilities, :source => :shareable, :source_type => 'Photo'
|
||||
|
||||
validates :name, :presence => true, :length => { :maximum => 20 }
|
||||
|
||||
|
|
@ -24,5 +25,17 @@ class Aspect < ActiveRecord::Base
|
|||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
def << (shareable)
|
||||
case shareable
|
||||
when Post
|
||||
self.posts << shareable
|
||||
when Photo
|
||||
self.photos << shareable
|
||||
else
|
||||
raise "Unknown shareable type '#{shareable.class.base_class.to_s}'"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -54,9 +54,9 @@ class Contact < ActiveRecord::Base
|
|||
:into => aspects.first)
|
||||
end
|
||||
|
||||
def receive_post(post)
|
||||
ShareVisibility.create!(:shareable_id => post.id, :shareable_type => 'Post', :contact_id => self.id)
|
||||
post.socket_to_user(self.user, :aspect_ids => self.aspect_ids) if post.respond_to? :socket_to_user
|
||||
def receive_shareable(shareable)
|
||||
ShareVisibility.create!(:shareable_id => shareable.id, :shareable_type => shareable.class.base_class.to_s, :contact_id => self.id)
|
||||
shareable.socket_to_user(self.user, :aspect_ids => self.aspect_ids) if shareable.respond_to? :socket_to_user
|
||||
end
|
||||
|
||||
def contacts
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class Person < ActiveRecord::Base
|
|||
|
||||
has_many :contacts, :dependent => :destroy # Other people's contacts for this person
|
||||
has_many :posts, :foreign_key => :author_id, :dependent => :destroy # This person's own posts
|
||||
has_many :photos, :foreign_key => :author_id, :dependent => :destroy # This person's own photos
|
||||
has_many :comments, :foreign_key => :author_id, :dependent => :destroy # This person's own comments
|
||||
|
||||
belongs_to :owner, :class_name => 'User'
|
||||
|
|
@ -249,7 +250,7 @@ class Person < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def has_photos?
|
||||
self.posts.where(:type => "Photo").exists?
|
||||
self.photos.exists?
|
||||
end
|
||||
|
||||
def as_json( opts = {} )
|
||||
|
|
|
|||
|
|
@ -2,8 +2,12 @@
|
|||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
class Photo < Post
|
||||
class Photo < ActiveRecord::Base
|
||||
require 'carrierwave/orm/activerecord'
|
||||
|
||||
include Diaspora::Commentable
|
||||
include Diaspora::Shareable
|
||||
|
||||
mount_uploader :processed_image, ProcessedImage
|
||||
mount_uploader :unprocessed_image, UnprocessedImage
|
||||
|
||||
|
|
@ -40,7 +44,12 @@ class Photo < Post
|
|||
end
|
||||
|
||||
def self.diaspora_initialize(params = {})
|
||||
photo = super(params)
|
||||
photo = self.new params.to_hash
|
||||
photo.author = params[:author]
|
||||
photo.public = params[:public] if params[:public]
|
||||
photo.pending = params[:pending] if params[:pending]
|
||||
photo.diaspora_handle = photo.author.diaspora_handle
|
||||
|
||||
image_file = params.delete(:user_file)
|
||||
photo.random_string = ActiveSupport::SecureRandom.hex(10)
|
||||
photo.unprocessed_image.store! image_file
|
||||
|
|
|
|||
|
|
@ -3,20 +3,13 @@
|
|||
# the COPYRIGHT file.
|
||||
|
||||
class Post < ActiveRecord::Base
|
||||
require File.join(Rails.root, 'lib/diaspora/web_socket')
|
||||
include ApplicationHelper
|
||||
include ROXML
|
||||
include Diaspora::Webhooks
|
||||
include Diaspora::Guid
|
||||
|
||||
include Diaspora::Likeable
|
||||
include Diaspora::Commentable
|
||||
include Diaspora::Shareable
|
||||
|
||||
xml_attr :diaspora_handle
|
||||
xml_attr :provider_display_name
|
||||
xml_attr :public
|
||||
xml_attr :created_at
|
||||
|
||||
has_many :mentions, :dependent => :destroy
|
||||
|
||||
|
|
@ -25,14 +18,9 @@ class Post < ActiveRecord::Base
|
|||
|
||||
belongs_to :o_embed_cache
|
||||
|
||||
belongs_to :author, :class_name => 'Person'
|
||||
|
||||
validates :guid, :uniqueness => true
|
||||
|
||||
after_create :cache_for_author
|
||||
|
||||
#scopes
|
||||
scope :all_public, where(:public => true, :pending => false)
|
||||
scope :includes_for_a_stream, includes(:o_embed_cache, {:author => :profile}, :mentions => {:person => :profile}) #note should include root and photos, but i think those are both on status_message
|
||||
|
||||
def self.for_a_stream(max_time, order)
|
||||
|
|
@ -47,27 +35,6 @@ class Post < ActiveRecord::Base
|
|||
end
|
||||
#############
|
||||
|
||||
def diaspora_handle
|
||||
read_attribute(:diaspora_handle) || self.author.diaspora_handle
|
||||
end
|
||||
|
||||
def user_refs
|
||||
if AspectVisibility.exists?(:shareable_id => self.id, :shareable_type => 'Post')
|
||||
self.share_visibilities.count + 1
|
||||
else
|
||||
self.share_visibilities.count
|
||||
end
|
||||
end
|
||||
|
||||
def reshare_count
|
||||
@reshare_count ||= Post.where(:root_guid => self.guid).count
|
||||
end
|
||||
|
||||
def diaspora_handle= nd
|
||||
self.author = Person.where(:diaspora_handle => nd).first
|
||||
write_attribute(:diaspora_handle, nd)
|
||||
end
|
||||
|
||||
def self.diaspora_initialize params
|
||||
new_post = self.new params.to_hash
|
||||
new_post.author = params[:author]
|
||||
|
|
@ -77,23 +44,15 @@ class Post < ActiveRecord::Base
|
|||
new_post
|
||||
end
|
||||
|
||||
def reshare_count
|
||||
@reshare_count ||= Post.where(:root_guid => self.guid).count
|
||||
end
|
||||
|
||||
# @return Returns true if this Post will accept updates (i.e. updates to the caption of a photo).
|
||||
def mutable?
|
||||
false
|
||||
end
|
||||
|
||||
# The list of people that should receive this Post.
|
||||
#
|
||||
# @param [User] user The context, or dispatching user.
|
||||
# @return [Array<Person>] The list of subscribers to this post
|
||||
def subscribers(user)
|
||||
if self.public?
|
||||
user.contact_people
|
||||
else
|
||||
user.people_in_aspects(user.aspects_with_post(self.id))
|
||||
end
|
||||
end
|
||||
|
||||
def activity_streams?
|
||||
false
|
||||
end
|
||||
|
|
@ -106,12 +65,6 @@ class Post < ActiveRecord::Base
|
|||
I18n.t('notifier.a_post_you_shared')
|
||||
end
|
||||
|
||||
# @return [Integer]
|
||||
def update_comments_counter
|
||||
self.class.where(:id => self.id).
|
||||
update_all(:comments_count => self.comments.count)
|
||||
end
|
||||
|
||||
# @return [Boolean]
|
||||
def cache_for_author
|
||||
if self.should_cache_for_author?
|
||||
|
|
@ -126,72 +79,4 @@ class Post < ActiveRecord::Base
|
|||
self.triggers_caching? && RedisCache.configured? &&
|
||||
RedisCache.acceptable_types.include?(self.type) && user = self.author.owner
|
||||
end
|
||||
|
||||
|
||||
# @param [User] user The user that is receiving this post.
|
||||
# @param [Person] person The person who dispatched this post to the
|
||||
# @return [void]
|
||||
def receive(user, person)
|
||||
#exists locally, but you dont know about it
|
||||
#does not exsist locally, and you dont know about it
|
||||
#exists_locally?
|
||||
#you know about it, and it is mutable
|
||||
#you know about it, and it is not mutable
|
||||
self.class.transaction do
|
||||
local_post = persisted_post
|
||||
|
||||
if local_post && verify_persisted_post(local_post)
|
||||
self.receive_persisted(user, person, local_post)
|
||||
|
||||
elsif !local_post
|
||||
self.receive_non_persisted(user, person)
|
||||
|
||||
else
|
||||
Rails.logger.info("event=receive payload_type=#{self.class} update=true status=abort sender=#{self.diaspora_handle} reason='update not from post owner' existing_post=#{self.id}")
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# @return [Post,void]
|
||||
def persisted_post
|
||||
self.class.where(:guid => self.guid).first
|
||||
end
|
||||
|
||||
# @return [Boolean]
|
||||
def verify_persisted_post(persisted_post)
|
||||
persisted_post.author_id == self.author_id
|
||||
end
|
||||
|
||||
def receive_persisted(user, person, local_post)
|
||||
known_post = user.find_visible_post_by_id(self.guid, :key => :guid)
|
||||
if known_post
|
||||
if known_post.mutable?
|
||||
known_post.update_attributes(self.attributes)
|
||||
true
|
||||
else
|
||||
Rails.logger.info("event=receive payload_type=#{self.class} update=true status=abort sender=#{self.diaspora_handle} reason=immutable") #existing_post=#{known_post.id}")
|
||||
false
|
||||
end
|
||||
else
|
||||
user.contact_for(person).receive_post(local_post)
|
||||
user.notify_if_mentioned(local_post)
|
||||
Rails.logger.info("event=receive payload_type=#{self.class} update=true status=complete sender=#{self.diaspora_handle}") #existing_post=#{local_post.id}")
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def receive_non_persisted(user, person)
|
||||
if self.save
|
||||
user.contact_for(person).receive_post(self)
|
||||
user.notify_if_mentioned(self)
|
||||
Rails.logger.info("event=receive payload_type=#{self.class} update=false status=complete sender=#{self.diaspora_handle}")
|
||||
true
|
||||
else
|
||||
Rails.logger.info("event=receive payload_type=#{self.class} update=false status=abort sender=#{self.diaspora_handle} reason=#{self.errors.full_messages}")
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class Retraction
|
|||
def subscribers(user)
|
||||
unless self.type == 'Person'
|
||||
@subscribers ||= self.object.subscribers(user)
|
||||
@subscribers -= self.object.resharers
|
||||
@subscribers -= self.object.resharers unless self.object.is_a?(Photo)
|
||||
@subscribers
|
||||
else
|
||||
raise 'HAX: you must set the subscribers manaully before unfriending' if @subscribers.nil?
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class User < ActiveRecord::Base
|
|||
validates_associated :person
|
||||
|
||||
has_one :person, :foreign_key => :owner_id
|
||||
delegate :public_key, :posts, :owns?, :diaspora_handle, :name, :public_url, :profile, :first_name, :last_name, :to => :person
|
||||
delegate :public_key, :posts, :photos, :owns?, :diaspora_handle, :name, :public_url, :profile, :first_name, :last_name, :to => :person
|
||||
|
||||
has_many :invitations_from_me, :class_name => 'Invitation', :foreign_key => :sender_id, :dependent => :destroy
|
||||
has_many :invitations_to_me, :class_name => 'Invitation', :foreign_key => :recipient_id, :dependent => :destroy
|
||||
|
|
@ -207,7 +207,7 @@ class User < ActiveRecord::Base
|
|||
def add_to_streams(post, aspects_to_insert)
|
||||
post.socket_to_user(self, :aspect_ids => aspects_to_insert.map{|x| x.id}) if post.respond_to? :socket_to_user
|
||||
aspects_to_insert.each do |aspect|
|
||||
aspect.posts << post
|
||||
aspect << post
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
class ShareAnything < ActiveRecord::Migration
|
||||
def self.up
|
||||
remove_foreign_key :aspect_visibilities, :posts
|
||||
remove_index :aspect_visibilities, :post_id_and_aspect_id
|
||||
remove_index :aspect_visibilities, :post_id
|
||||
|
||||
change_table :aspect_visibilities do |t|
|
||||
t.rename :post_id, :shareable_id
|
||||
t.string :shareable_type, :default => 'Post', :null => false
|
||||
end
|
||||
|
||||
|
||||
remove_foreign_key :post_visibilities, :posts
|
||||
remove_index :post_visibilities, :contact_id_and_post_id
|
||||
remove_index :post_visibilities, :post_id_and_hidden_and_contact_id
|
||||
|
||||
change_table :post_visibilities do |t|
|
||||
t.rename :post_id, :shareable_id
|
||||
t.string :shareable_type, :default => 'Post', :null => false
|
||||
end
|
||||
rename_table :post_visibilities, :share_visibilities
|
||||
end
|
||||
|
||||
|
||||
|
||||
def self.down
|
||||
rename_column :aspect_visibilities, :shareable_id, :post_id
|
||||
add_foreign_key :aspect_visibilities, :posts
|
||||
add_index :aspect_visibilities, :post_id
|
||||
remove_column :aspect_visibilities, :shareable_type
|
||||
|
||||
rename_table :share_visibilities, :post_visibilities
|
||||
rename_column :post_visibilities, :shareable_id, :post_id
|
||||
add_foreign_key :post_visibilities, :posts
|
||||
add_index :post_visibilities, :post_id_and_post_id
|
||||
add_index :post_visibilities, [:contact_id, :post_id]
|
||||
add_index :post_visibilities, [:post_id, :hidden, :contact_id]
|
||||
add_index :post_visibilities, :post_id
|
||||
remove_column :post_visibilities, :shareable_type
|
||||
end
|
||||
end
|
||||
58
db/migrate/20111011195702_share_anything.rb
Normal file
58
db/migrate/20111011195702_share_anything.rb
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
class ShareAnything < ActiveRecord::Migration
|
||||
def self.up
|
||||
remove_foreign_key :aspect_visibilities, :posts
|
||||
remove_index :aspect_visibilities, :post_id_and_aspect_id
|
||||
remove_index :aspect_visibilities, :post_id
|
||||
|
||||
change_table :aspect_visibilities do |t|
|
||||
t.rename :post_id, :shareable_id
|
||||
t.string :shareable_type, :default => 'Post', :null => false
|
||||
end
|
||||
|
||||
add_index :aspect_visibilities, [:shareable_id, :shareable_type, :aspect_id], :name => 'shareable_and_aspect_id'
|
||||
add_index :aspect_visibilities, [:shareable_id, :shareable_type]
|
||||
|
||||
|
||||
remove_foreign_key :post_visibilities, :posts
|
||||
remove_index :post_visibilities, :contact_id_and_post_id
|
||||
remove_index :post_visibilities, :post_id_and_hidden_and_contact_id
|
||||
|
||||
change_table :post_visibilities do |t|
|
||||
t.rename :post_id, :shareable_id
|
||||
t.string :shareable_type, :default => 'Post', :null => false
|
||||
end
|
||||
|
||||
rename_table :post_visibilities, :share_visibilities
|
||||
add_index :share_visibilities, [:shareable_id, :shareable_type, :contact_id], :name => 'shareable_and_contact_id'
|
||||
add_index :share_visibilities, [:shareable_id, :shareable_type, :hidden, :contact_id], :name => 'shareable_and_hidden_and_contact_id'
|
||||
end
|
||||
|
||||
|
||||
def self.down
|
||||
remove_index :share_visibilities, :name => 'shareable_and_hidden_and_contact_id'
|
||||
remove_index :share_visibilities, :name => 'shareable_and_contact_id'
|
||||
rename_table :share_visibilities, :post_visibilities
|
||||
|
||||
change_table :post_visibilities do |t|
|
||||
t.remove :shareable_type
|
||||
t.rename :shareable_id, :post_id
|
||||
end
|
||||
|
||||
add_index :post_visibilities, [:post_id, :hidden, :contact_id]
|
||||
add_index :post_visibilities, [:contact_id, :post_id]
|
||||
add_foreign_key :post_visibilities, :posts
|
||||
|
||||
|
||||
remove_index :aspect_visibilities, [:shareable_id, :shareable_type]
|
||||
remove_index :aspect_visibilities, :name => 'shareable_and_aspect_id'
|
||||
|
||||
change_table :aspect_visibilities do |t|
|
||||
t.remove :shareable_type
|
||||
t.rename :shareable_id, :post_id
|
||||
end
|
||||
|
||||
add_index :aspect_visibilities, :post_id
|
||||
add_index :aspect_visibilities, [:post_id, :aspect_id]
|
||||
add_foreign_key :aspect_visibilities, :posts
|
||||
end
|
||||
end
|
||||
68
db/migrate/20111012215141_move_photos_to_their_own_table.rb
Normal file
68
db/migrate/20111012215141_move_photos_to_their_own_table.rb
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
class MovePhotosToTheirOwnTable < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table "photos", :force => true do |t|
|
||||
t.integer "author_id", :null => false
|
||||
t.boolean "public", :default => false, :null => false
|
||||
t.string "diaspora_handle"
|
||||
t.string "guid", :null => false
|
||||
t.boolean "pending", :default => false, :null => false
|
||||
t.text "text"
|
||||
t.text "remote_photo_path"
|
||||
t.string "remote_photo_name"
|
||||
t.string "random_string"
|
||||
t.string "processed_image"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "unprocessed_image"
|
||||
t.string "status_message_guid"
|
||||
t.integer "comments_count"
|
||||
end
|
||||
|
||||
execute <<SQL
|
||||
INSERT INTO photos
|
||||
SELECT id, author_id, public, diaspora_handle, guid, pending, text, remote_photo_path, remote_photo_name, random_string, processed_image,
|
||||
created_at, updated_at, unprocessed_image, status_message_guid, comments_count
|
||||
FROM posts
|
||||
WHERE type = 'Photo'
|
||||
SQL
|
||||
|
||||
execute "UPDATE aspect_visibilities AS av, photos SET av.shareable_type='Photo' WHERE av.shareable_id=photos.id"
|
||||
execute "UPDATE share_visibilities AS sv, photos SET sv.shareable_type='Photo' WHERE sv.shareable_id=photos.id"
|
||||
|
||||
# all your base are belong to us!
|
||||
execute "DELETE FROM posts WHERE type='Photo'"
|
||||
end
|
||||
|
||||
|
||||
def self.down
|
||||
execute <<SQL
|
||||
INSERT INTO posts
|
||||
SELECT NULL AS id, author_id, public, diaspora_handle, guid, pending, 'Photo' AS type, text, remote_photo_path, remote_photo_name, random_string,
|
||||
processed_image, NULL AS youtube_titles, created_at, updated_at, unprocessed_image, NULL AS object_url, NULL AS image_url, NULL AS image_height, NULL AS image_width, NULL AS provider_display_name,
|
||||
NULL AS actor_url, NULL AS objectId, NULL AS root_guid, status_message_guid, 0 AS likes_count, comments_count, NULL AS o_embed_cache_id
|
||||
FROM photos
|
||||
SQL
|
||||
|
||||
execute <<SQL
|
||||
UPDATE aspect_visibilities, posts, photos
|
||||
SET
|
||||
aspect_visibilities.shareable_id=posts.id,
|
||||
aspect_visibilities.shareable_type='Post'
|
||||
WHERE
|
||||
posts.guid=photos.guid AND
|
||||
photos.id=aspect_visibilities.shareable_id
|
||||
SQL
|
||||
|
||||
execute <<SQL
|
||||
UPDATE share_visibilities, posts, photos
|
||||
SET
|
||||
share_visibilities.shareable_id=posts.id,
|
||||
share_visibilities.shareable_type='Post'
|
||||
WHERE
|
||||
posts.guid=photos.guid AND
|
||||
photos.id=share_visibilities.shareable_id
|
||||
SQL
|
||||
|
||||
execute "DROP TABLE photos"
|
||||
end
|
||||
end
|
||||
24
db/schema.rb
24
db/schema.rb
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20111011193702) do
|
||||
ActiveRecord::Schema.define(:version => 20111012215141) do
|
||||
|
||||
create_table "aspect_memberships", :force => true do |t|
|
||||
t.integer "aspect_id", :null => false
|
||||
|
|
@ -32,6 +32,8 @@ ActiveRecord::Schema.define(:version => 20111011193702) do
|
|||
end
|
||||
|
||||
add_index "aspect_visibilities", ["aspect_id"], :name => "index_aspect_visibilities_on_aspect_id"
|
||||
add_index "aspect_visibilities", ["shareable_id", "shareable_type", "aspect_id"], :name => "shareable_and_aspect_id"
|
||||
add_index "aspect_visibilities", ["shareable_id", "shareable_type"], :name => "index_aspect_visibilities_on_shareable_id_and_shareable_type"
|
||||
|
||||
create_table "aspects", :force => true do |t|
|
||||
t.string "name", :null => false
|
||||
|
|
@ -242,6 +244,24 @@ ActiveRecord::Schema.define(:version => 20111011193702) do
|
|||
add_index "people", ["guid"], :name => "index_people_on_guid", :unique => true
|
||||
add_index "people", ["owner_id"], :name => "index_people_on_owner_id", :unique => true
|
||||
|
||||
create_table "photos", :force => true do |t|
|
||||
t.integer "author_id", :null => false
|
||||
t.boolean "public", :default => false, :null => false
|
||||
t.string "diaspora_handle"
|
||||
t.string "guid", :null => false
|
||||
t.boolean "pending", :default => false, :null => false
|
||||
t.text "text"
|
||||
t.text "remote_photo_path"
|
||||
t.string "remote_photo_name"
|
||||
t.string "random_string"
|
||||
t.string "processed_image"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "unprocessed_image"
|
||||
t.string "status_message_guid"
|
||||
t.integer "comments_count"
|
||||
end
|
||||
|
||||
create_table "pods", :force => true do |t|
|
||||
t.string "host"
|
||||
t.boolean "ssl"
|
||||
|
|
@ -350,6 +370,8 @@ ActiveRecord::Schema.define(:version => 20111011193702) do
|
|||
end
|
||||
|
||||
add_index "share_visibilities", ["contact_id"], :name => "index_post_visibilities_on_contact_id"
|
||||
add_index "share_visibilities", ["shareable_id", "shareable_type", "contact_id"], :name => "shareable_and_contact_id"
|
||||
add_index "share_visibilities", ["shareable_id", "shareable_type", "hidden", "contact_id"], :name => "shareable_and_hidden_and_contact_id"
|
||||
add_index "share_visibilities", ["shareable_id"], :name => "index_post_visibilities_on_post_id"
|
||||
|
||||
create_table "tag_followings", :force => true do |t|
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ module NavigationHelpers
|
|||
when /^my account settings page$/
|
||||
edit_user_path
|
||||
when /^the photo page for "([^\"]*)"'s latest post$/
|
||||
photo_path(User.find_by_email($1).posts.where(:type => "Photo").last)
|
||||
photo_path(User.find_by_email($1).photos.last)
|
||||
when /^the photo page for "([^\"]*)"'s post "([^\"]*)"$/
|
||||
photo_path(User.find_by_email($1).posts.find_by_text($2))
|
||||
when /^"(\/.*)"/
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ module PhotoMover
|
|||
FileUtils::mkdir_p temp_dir
|
||||
Dir.chdir 'tmp/exports'
|
||||
|
||||
photos = user.visible_posts.where(:author_id => user.person.id, :type => 'Photo')
|
||||
photos = user.visible_shareables(Post).where(:author_id => user.person.id, :type => 'Photo')
|
||||
|
||||
photos_dir = "#{user.id}/photos"
|
||||
FileUtils::mkdir_p photos_dir
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ module Diaspora
|
|||
def last_three_comments
|
||||
self.comments.order('created_at DESC').limit(3).includes(:author => :profile).reverse
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Integer]
|
||||
def update_comments_counter
|
||||
self.class.where(:id => self.id).
|
||||
update_all(:comments_count => self.comments.count)
|
||||
end
|
||||
# @return [Integer]
|
||||
def update_comments_counter
|
||||
self.class.where(:id => self.id).
|
||||
update_all(:comments_count => self.comments.count)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ module Diaspora
|
|||
}
|
||||
|
||||
xml.posts {
|
||||
user.visible_posts.find_all_by_author_id(user_person_id).each do |post|
|
||||
user.visible_shareables(Post).find_all_by_author_id(user_person_id).each do |post|
|
||||
#post.comments.each do |comment|
|
||||
# post_doc << comment.to_xml
|
||||
#end
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ class RedisCache
|
|||
:order => self.order
|
||||
})
|
||||
|
||||
sql = @user.visible_posts_sql(opts)
|
||||
sql = @user.visible_shareables_sql(Post, opts)
|
||||
hashes = Post.connection.select_all(sql)
|
||||
|
||||
# hashes are inserted into set in a single transaction
|
||||
|
|
|
|||
|
|
@ -4,14 +4,129 @@
|
|||
|
||||
module Diaspora
|
||||
module Shareable
|
||||
require File.join(Rails.root, 'lib/diaspora/web_socket')
|
||||
include Diaspora::Webhooks
|
||||
|
||||
def self.included(model)
|
||||
model.instance_eval do
|
||||
include ROXML
|
||||
include Diaspora::Guid
|
||||
|
||||
has_many :aspect_visibilities, :as => :shareable
|
||||
has_many :aspects, :through => :aspect_visibilities
|
||||
|
||||
has_many :share_visibilities, :as => :shareable
|
||||
has_many :contacts, :through => :share_visibilities
|
||||
|
||||
belongs_to :author, :class_name => 'Person'
|
||||
|
||||
validates :guid, :uniqueness => true
|
||||
|
||||
#scopes
|
||||
scope :all_public, where(:public => true, :pending => false)
|
||||
|
||||
xml_attr :diaspora_handle
|
||||
xml_attr :public
|
||||
xml_attr :created_at
|
||||
end
|
||||
|
||||
def diaspora_handle
|
||||
read_attribute(:diaspora_handle) || self.author.diaspora_handle
|
||||
end
|
||||
|
||||
def diaspora_handle= nd
|
||||
self.author = Person.where(:diaspora_handle => nd).first
|
||||
write_attribute(:diaspora_handle, nd)
|
||||
end
|
||||
|
||||
def user_refs
|
||||
if AspectVisibility.exists?(:shareable_id => self.id, :shareable_type => self.class.base_class.to_s)
|
||||
self.share_visibilities.count + 1
|
||||
else
|
||||
self.share_visibilities.count
|
||||
end
|
||||
end
|
||||
|
||||
# @param [User] user The user that is receiving this shareable.
|
||||
# @param [Person] person The person who dispatched this shareable to the
|
||||
# @return [void]
|
||||
def receive(user, person)
|
||||
#exists locally, but you dont know about it
|
||||
#does not exsist locally, and you dont know about it
|
||||
#exists_locally?
|
||||
#you know about it, and it is mutable
|
||||
#you know about it, and it is not mutable
|
||||
self.class.transaction do
|
||||
local_shareable = persisted_shareable
|
||||
|
||||
if local_shareable && verify_persisted_shareable(local_shareable)
|
||||
self.receive_persisted(user, person, local_shareable)
|
||||
|
||||
elsif !local_shareable
|
||||
self.receive_non_persisted(user, person)
|
||||
|
||||
else
|
||||
Rails.logger.info("event=receive payload_type=#{self.class} update=true status=abort sender=#{self.diaspora_handle} reason='update not from shareable owner' existing_shareable=#{self.id}")
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# The list of people that should receive this Shareable.
|
||||
#
|
||||
# @param [User] user The context, or dispatching user.
|
||||
# @return [Array<Person>] The list of subscribers to this shareable
|
||||
def subscribers(user)
|
||||
if self.public?
|
||||
user.contact_people
|
||||
else
|
||||
user.people_in_aspects(user.aspects_with_shareable(self.class, self.id))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
# @return [Shareable,void]
|
||||
def persisted_shareable
|
||||
self.class.where(:guid => self.guid).first
|
||||
end
|
||||
|
||||
# @return [Boolean]
|
||||
def verify_persisted_shareable(persisted_shareable)
|
||||
persisted_shareable.author_id == self.author_id
|
||||
end
|
||||
|
||||
def receive_persisted(user, person, local_shareable)
|
||||
known_shareable = user.find_visible_shareable_by_id(self.class.base_class, self.guid, :key => :guid)
|
||||
if known_shareable
|
||||
if known_shareable.mutable?
|
||||
known_shareable.update_attributes(self.attributes)
|
||||
true
|
||||
else
|
||||
Rails.logger.info("event=receive payload_type=#{self.class} update=true status=abort sender=#{self.diaspora_handle} reason=immutable") #existing_shareable=#{known_shareable.id}")
|
||||
false
|
||||
end
|
||||
else
|
||||
user.contact_for(person).receive_shareable(local_shareable)
|
||||
user.notify_if_mentioned(local_shareable)
|
||||
Rails.logger.info("event=receive payload_type=#{self.class} update=true status=complete sender=#{self.diaspora_handle}") #existing_shareable=#{local_shareable.id}")
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def receive_non_persisted(user, person)
|
||||
if self.save
|
||||
user.contact_for(person).receive_shareable(self)
|
||||
user.notify_if_mentioned(self)
|
||||
Rails.logger.info("event=receive payload_type=#{self.class} update=false status=complete sender=#{self.diaspora_handle}")
|
||||
true
|
||||
else
|
||||
Rails.logger.info("event=receive payload_type=#{self.class} update=false status=abort sender=#{self.diaspora_handle} reason=#{self.errors.full_messages}")
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,67 +8,76 @@ module Diaspora
|
|||
module UserModules
|
||||
module Querying
|
||||
|
||||
def find_visible_post_by_id( id, opts={} )
|
||||
def find_visible_shareable_by_id(klass, id, opts={} )
|
||||
key = opts.delete(:key) || :id
|
||||
post = Post.where(key => id).joins(:contacts).where(:contacts => {:user_id => self.id}).where(opts).select("posts.*").first
|
||||
post ||= Post.where(key => id, :author_id => self.person.id).where(opts).first
|
||||
post ||= Post.where(key => id, :public => true).where(opts).first
|
||||
post = klass.where(key => id).joins(:contacts).where(:contacts => {:user_id => self.id}).where(opts).select(klass.table_name+".*").first
|
||||
post ||= klass.where(key => id, :author_id => self.person.id).where(opts).first
|
||||
post ||= klass.where(key => id, :public => true).where(opts).first
|
||||
end
|
||||
|
||||
def visible_posts(opts={})
|
||||
opts = prep_opts(opts)
|
||||
post_ids = visible_post_ids(opts)
|
||||
Post.where(:id => post_ids).select('DISTINCT posts.*').limit(opts[:limit]).order(opts[:order_with_table])
|
||||
def visible_shareables(klass, opts={})
|
||||
opts = prep_opts(klass, opts)
|
||||
shareable_ids = visible_shareable_ids(klass, opts)
|
||||
klass.where(:id => shareable_ids).select('DISTINCT '+klass.to_s.tableize+'.*').limit(opts[:limit]).order(opts[:order_with_table])
|
||||
end
|
||||
|
||||
def visible_post_ids(opts={})
|
||||
opts = prep_opts(opts)
|
||||
def visible_shareable_ids(klass, opts={})
|
||||
opts = prep_opts(klass, opts)
|
||||
|
||||
if RedisCache.configured? && RedisCache.supported_order?(opts[:order_field]) && opts[:all_aspects?].present?
|
||||
cache = RedisCache.new(self, opts[:order_field])
|
||||
|
||||
cache.ensure_populated!(opts)
|
||||
post_ids = cache.post_ids(opts[:max_time], opts[:limit])
|
||||
name = klass.to_s.downcase
|
||||
shareable_ids = cache.send(name+"_ids", opts[:max_time], opts[:limit])
|
||||
end
|
||||
|
||||
if post_ids.blank? || post_ids.length < opts[:limit]
|
||||
visible_ids_from_sql(opts)
|
||||
if shareable_ids.blank? || shareable_ids.length < opts[:limit]
|
||||
visible_ids_from_sql(klass, opts)
|
||||
else
|
||||
post_ids
|
||||
shareable_ids
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Array<Integer>]
|
||||
def visible_ids_from_sql(opts={})
|
||||
opts = prep_opts(opts)
|
||||
Post.connection.select_values(visible_posts_sql(opts)).map { |id| id.to_i }
|
||||
def visible_ids_from_sql(klass, opts={})
|
||||
opts = prep_opts(klass, opts)
|
||||
klass.connection.select_values(visible_shareable_sql(klass, opts)).map { |id| id.to_i }
|
||||
end
|
||||
|
||||
def visible_posts_sql(opts={})
|
||||
opts = prep_opts(opts)
|
||||
select_clause ='DISTINCT posts.id, posts.updated_at AS updated_at, posts.created_at AS created_at'
|
||||
def visible_shareable_sql(klass, opts={})
|
||||
table = klass.table_name
|
||||
opts = prep_opts(klass, opts)
|
||||
select_clause ='DISTINCT %s.id, %s.updated_at AS updated_at, %s.created_at AS created_at' % [klass.table_name, klass.table_name, klass.table_name]
|
||||
|
||||
posts_from_others = Post.joins(:contacts).where( :pending => false, :type => opts[:type], :share_visibilities => {:hidden => opts[:hidden]}, :contacts => {:user_id => self.id})
|
||||
posts_from_self = self.person.posts.where(:pending => false, :type => opts[:type])
|
||||
conditions = {:pending => false, :share_visibilities => {:hidden => opts[:hidden]}, :contacts => {:user_id => self.id} }
|
||||
conditions[:type] = opts[:type] if opts.has_key?(:type)
|
||||
shareable_from_others = klass.joins(:contacts).where(conditions)
|
||||
|
||||
conditions = {:pending => false }
|
||||
conditions[:type] = opts[:type] if opts.has_key?(:type)
|
||||
shareable_from_self = self.person.send(klass.to_s.tableize).where(conditions)
|
||||
|
||||
if opts[:by_members_of]
|
||||
posts_from_others = posts_from_others.joins(:contacts => :aspect_memberships).where(
|
||||
shareable_from_others = shareable_from_others.joins(:contacts => :aspect_memberships).where(
|
||||
:aspect_memberships => {:aspect_id => opts[:by_members_of]})
|
||||
posts_from_self = posts_from_self.joins(:aspect_visibilities).where(:aspect_visibilities => {:aspect_id => opts[:by_members_of]})
|
||||
shareable_from_self = shareable_from_self.joins(:aspect_visibilities).where(:aspect_visibilities => {:aspect_id => opts[:by_members_of]})
|
||||
end
|
||||
|
||||
posts_from_others = posts_from_others.select(select_clause).order(opts[:order_with_table]).where(Post.arel_table[opts[:order_field]].lt(opts[:max_time]))
|
||||
posts_from_self = posts_from_self.select(select_clause).order(opts[:order_with_table]).where(Post.arel_table[opts[:order_field]].lt(opts[:max_time]))
|
||||
shareable_from_others = shareable_from_others.select(select_clause).order(opts[:order_with_table]).where(klass.arel_table[opts[:order_field]].lt(opts[:max_time]))
|
||||
shareable_from_self = shareable_from_self.select(select_clause).order(opts[:order_with_table]).where(klass.arel_table[opts[:order_field]].lt(opts[:max_time]))
|
||||
|
||||
"(#{posts_from_others.to_sql} LIMIT #{opts[:limit]}) UNION ALL (#{posts_from_self.to_sql} LIMIT #{opts[:limit]}) ORDER BY #{opts[:order]} LIMIT #{opts[:limit]}"
|
||||
"(#{shareable_from_others.to_sql} LIMIT #{opts[:limit]}) UNION ALL (#{shareable_from_self.to_sql} LIMIT #{opts[:limit]}) ORDER BY #{opts[:order]} LIMIT #{opts[:limit]}"
|
||||
end
|
||||
|
||||
def contact_for(person)
|
||||
return nil unless person
|
||||
contact_for_person_id(person.id)
|
||||
end
|
||||
def aspects_with_post(post_id)
|
||||
self.aspects.joins(:aspect_visibilities).where(:aspect_visibilities => {:shareable_id => post_id, :shareable_type => 'Post'})
|
||||
def aspects_with_shareable(base_class_name_or_class, shareable_id)
|
||||
base_class_name = base_class_name_or_class
|
||||
base_class_name = base_class_name_or_class.base_class.to_s if base_class_name_or_class.is_a?(Class)
|
||||
self.aspects.joins(:aspect_visibilities).where(:aspect_visibilities => {:shareable_id => shareable_id, :shareable_type => base_class_name})
|
||||
end
|
||||
|
||||
def contact_for_person_id(person_id)
|
||||
|
|
@ -105,36 +114,44 @@ module Diaspora
|
|||
end
|
||||
|
||||
def posts_from(person)
|
||||
return self.person.posts.where(:pending => false).order("created_at DESC") if person == self.person
|
||||
self.shareables_from(Post, person)
|
||||
end
|
||||
|
||||
def photos_from(person)
|
||||
self.shareables_from(Photo, person)
|
||||
end
|
||||
|
||||
def shareables_from(klass, person)
|
||||
return self.person.send(klass.table_name).where(:pending => false).order("created_at DESC") if person == self.person
|
||||
con = Contact.arel_table
|
||||
p = Post.arel_table
|
||||
post_ids = []
|
||||
p = klass.arel_table
|
||||
shareable_ids = []
|
||||
if contact = self.contact_for(person)
|
||||
post_ids = Post.connection.select_values(
|
||||
contact.share_visibilities.where(:hidden => false, :shareable_type => 'Post').select('share_visibilities.shareable_id').to_sql
|
||||
shareable_ids = klass.connection.select_values(
|
||||
contact.share_visibilities.where(:hidden => false, :shareable_type => klass.to_s).select('share_visibilities.shareable_id').to_sql
|
||||
)
|
||||
end
|
||||
post_ids += Post.connection.select_values(
|
||||
person.posts.where(:public => true).select('posts.id').to_sql
|
||||
shareable_ids += klass.connection.select_values(
|
||||
person.send(klass.table_name).where(:public => true).select(klass.table_name+'.id').to_sql
|
||||
)
|
||||
|
||||
Post.where(:id => post_ids, :pending => false).select('DISTINCT posts.*').order("posts.created_at DESC")
|
||||
klass.where(:id => shareable_ids, :pending => false).select('DISTINCT '+klass.table_name+'.*').order(klass.table_name+".created_at DESC")
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# @return [Hash]
|
||||
def prep_opts(opts)
|
||||
def prep_opts(klass, opts)
|
||||
defaults = {
|
||||
:type => Stream::Base::TYPES_OF_POST_IN_STREAM,
|
||||
:order => 'created_at DESC',
|
||||
:limit => 15,
|
||||
:hidden => false
|
||||
}
|
||||
defaults[:type] = Stream::Base::TYPES_OF_POST_IN_STREAM if klass == Post
|
||||
opts = defaults.merge(opts)
|
||||
|
||||
opts[:order_field] = opts[:order].split.first.to_sym
|
||||
opts[:order_with_table] = 'posts.' + opts[:order]
|
||||
opts[:order_with_table] = klass.table_name + '.' + opts[:order]
|
||||
|
||||
opts[:max_time] = Time.at(opts[:max_time]) if opts[:max_time].is_a?(Integer)
|
||||
opts[:max_time] ||= Time.now + 1
|
||||
|
|
|
|||
|
|
@ -37,12 +37,12 @@ class Stream::Aspect < Stream::Base
|
|||
|
||||
# @return [ActiveRecord::Association<Post>] AR association of posts
|
||||
def posts
|
||||
# NOTE(this should be something like Post.all_for_stream(@user, aspect_ids, {}) that calls visible_posts
|
||||
@posts ||= user.visible_posts(:all_aspects? => for_all_aspects?,
|
||||
:by_members_of => aspect_ids,
|
||||
:type => TYPES_OF_POST_IN_STREAM,
|
||||
:order => "#{order} DESC",
|
||||
:max_time => max_time
|
||||
# NOTE(this should be something like Post.all_for_stream(@user, aspect_ids, {}) that calls visible_shareables
|
||||
@posts ||= user.visible_shareables(Post, :all_aspects? => for_all_aspects?,
|
||||
:by_members_of => aspect_ids,
|
||||
:type => TYPES_OF_POST_IN_STREAM,
|
||||
:order => "#{order} DESC",
|
||||
:max_time => max_time
|
||||
).for_a_stream(max_time, order)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ describe "attack vectors" do
|
|||
zord.perform!
|
||||
}.should raise_error /not a valid object/
|
||||
|
||||
bob.visible_posts.include?(post_from_non_contact).should be_false
|
||||
bob.visible_shareables(Post).include?(post_from_non_contact).should be_false
|
||||
Post.count.should == post_count
|
||||
end
|
||||
end
|
||||
|
|
@ -42,7 +42,7 @@ describe "attack vectors" do
|
|||
zord.perform!
|
||||
}.should raise_error /not a valid object/
|
||||
|
||||
alice.reload.visible_posts.should_not include(StatusMessage.find(original_message.id))
|
||||
alice.reload.visible_shareables(Post).should_not include(StatusMessage.find(original_message.id))
|
||||
end
|
||||
|
||||
context 'malicious contact attack vector' do
|
||||
|
|
@ -78,11 +78,11 @@ describe "attack vectors" do
|
|||
zord.perform!
|
||||
|
||||
}.should_not change{
|
||||
bob.reload.visible_posts.count
|
||||
bob.reload.visible_shareables(Post).count
|
||||
}
|
||||
|
||||
original_message.reload.text.should == "store this!"
|
||||
bob.visible_posts.first.text.should == "store this!"
|
||||
bob.visible_shareables(Post).first.text.should == "store this!"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ describe "attack vectors" do
|
|||
zord = Postzord::Receiver::Private.new(bob, :salmon_xml => salmon_xml)
|
||||
zord.perform!
|
||||
|
||||
bob.visible_posts.count.should == 1
|
||||
bob.visible_shareables(Post).count.should == 1
|
||||
StatusMessage.count.should == 1
|
||||
|
||||
ret = Retraction.new
|
||||
|
|
@ -124,7 +124,7 @@ describe "attack vectors" do
|
|||
zord.perform!
|
||||
|
||||
StatusMessage.count.should == 1
|
||||
bob.visible_posts.count.should == 1
|
||||
bob.visible_shareables(Post).count.should == 1
|
||||
end
|
||||
|
||||
it "disregards retractions for non-existent posts that are from someone other than the post's author" do
|
||||
|
|
@ -154,7 +154,7 @@ describe "attack vectors" do
|
|||
zord = Postzord::Receiver::Private.new(bob, :salmon_xml => salmon_xml)
|
||||
zord.perform!
|
||||
|
||||
bob.visible_posts.count.should == 1
|
||||
bob.visible_shareables(Post).count.should == 1
|
||||
|
||||
ret = Retraction.new
|
||||
ret.post_guid = original_message.guid
|
||||
|
|
@ -167,7 +167,7 @@ describe "attack vectors" do
|
|||
zord.perform!
|
||||
}.should raise_error /not a valid object/
|
||||
|
||||
bob.reload.visible_posts.count.should == 1
|
||||
bob.reload.visible_shareables(Post).count.should == 1
|
||||
end
|
||||
|
||||
it 'it should not allow you to send retractions for other people' do
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ describe 'a user receives a post' do
|
|||
bob.dispatch_post(sm, :to => @bobs_aspect)
|
||||
end
|
||||
|
||||
alice.visible_posts.count.should == 1
|
||||
alice.visible_shareables(Post).count.should == 1
|
||||
end
|
||||
|
||||
context 'with mentions, ' do
|
||||
|
|
@ -153,14 +153,14 @@ describe 'a user receives a post' do
|
|||
end
|
||||
|
||||
it "adds a received post to the the contact" do
|
||||
alice.visible_posts.should include(@status_message)
|
||||
alice.visible_shareables(Post).should include(@status_message)
|
||||
@contact.posts.should include(@status_message)
|
||||
end
|
||||
|
||||
it 'removes posts upon forceful removal' do
|
||||
alice.remove_contact(@contact, :force => true)
|
||||
alice.reload
|
||||
alice.visible_posts.should_not include @status_message
|
||||
alice.visible_shareables(Post).should_not include @status_message
|
||||
end
|
||||
|
||||
context 'dependant delete' do
|
||||
|
|
@ -240,7 +240,7 @@ describe 'a user receives a post' do
|
|||
end
|
||||
|
||||
it 'should correctly attach the user already on the pod' do
|
||||
bob.reload.visible_posts.size.should == 1
|
||||
bob.reload.visible_shareables(Post).size.should == 1
|
||||
post_in_db = StatusMessage.find(@post.id)
|
||||
post_in_db.comments.should == []
|
||||
receive_with_zord(bob, alice.person, @xml)
|
||||
|
|
@ -264,7 +264,7 @@ describe 'a user receives a post' do
|
|||
remote_person
|
||||
}
|
||||
|
||||
bob.reload.visible_posts.size.should == 1
|
||||
bob.reload.visible_shareables(Post).size.should == 1
|
||||
post_in_db = StatusMessage.find(@post.id)
|
||||
post_in_db.comments.should == []
|
||||
|
||||
|
|
@ -336,7 +336,7 @@ describe 'a user receives a post' do
|
|||
zord = Postzord::Receiver::Private.new(bob, :salmon_xml => salmon_xml)
|
||||
zord.perform!
|
||||
|
||||
bob.visible_posts.include?(post).should be_true
|
||||
bob.visible_shareables(Post).include?(post).should be_true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -95,11 +95,12 @@ describe RedisCache do
|
|||
sql = "long_sql"
|
||||
order = "created_at DESC"
|
||||
@cache.should_receive(:order).and_return(order)
|
||||
bob.should_receive(:visible_posts_sql).with(hash_including(
|
||||
:type => RedisCache.acceptable_types,
|
||||
:limit => RedisCache::CACHE_LIMIT,
|
||||
:order => order)).
|
||||
and_return(sql)
|
||||
bob.should_receive(:visible_shareables_sql).with(Post,
|
||||
hash_including(
|
||||
:type => RedisCache.acceptable_types,
|
||||
:limit => RedisCache::CACHE_LIMIT,
|
||||
:order => order)).
|
||||
and_return(sql)
|
||||
|
||||
Post.connection.should_receive(:select_all).with(sql).and_return([])
|
||||
|
||||
|
|
|
|||
|
|
@ -52,25 +52,25 @@ describe Stream::Aspect do
|
|||
it 'calls visible posts for the given user' do
|
||||
stream = Stream::Aspect.new(@alice, [1,2])
|
||||
|
||||
@alice.should_receive(:visible_posts).and_return(stub.as_null_object)
|
||||
@alice.should_receive(:visible_shareables).and_return(stub.as_null_object)
|
||||
stream.posts
|
||||
end
|
||||
|
||||
it 'is called with 3 types' do
|
||||
stream = Stream::Aspect.new(@alice, [1,2], :order => 'created_at')
|
||||
@alice.should_receive(:visible_posts).with(hash_including(:type=> ['StatusMessage', 'Reshare', 'ActivityStreams::Photo'])).and_return(stub.as_null_object)
|
||||
stream = AspectStream.new(@alice, [1,2], :order => 'created_at')
|
||||
@alice.should_receive(:visible_shareables).with(Post, hash_including(:type=> ['StatusMessage', 'Reshare', 'ActivityStreams::Photo'])).and_return(stub.as_null_object)
|
||||
stream.posts
|
||||
end
|
||||
|
||||
it 'respects ordering' do
|
||||
stream = Stream::Aspect.new(@alice, [1,2], :order => 'created_at')
|
||||
@alice.should_receive(:visible_posts).with(hash_including(:order => 'created_at DESC')).and_return(stub.as_null_object)
|
||||
stream = AspectStream.new(@alice, [1,2], :order => 'created_at')
|
||||
@alice.should_receive(:visible_shareables).with(Post, hash_including(:order => 'created_at DESC')).and_return(stub.as_null_object)
|
||||
stream.posts
|
||||
end
|
||||
|
||||
it 'respects max_time' do
|
||||
stream = Stream::Aspect.new(@alice, [1,2], :max_time => 123)
|
||||
@alice.should_receive(:visible_posts).with(hash_including(:max_time => instance_of(Time))).and_return(stub.as_null_object)
|
||||
stream = AspectStream.new(@alice, [1,2], :max_time => 123)
|
||||
@alice.should_receive(:visible_shareables).with(Post, hash_including(:max_time => instance_of(Time))).and_return(stub.as_null_object)
|
||||
stream.posts
|
||||
end
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ describe Stream::Aspect do
|
|||
stream = Stream::Aspect.new(@alice, [1,2], :max_time => 123)
|
||||
all_aspects = mock
|
||||
stream.stub(:for_all_aspects?).and_return(all_aspects)
|
||||
@alice.should_receive(:visible_posts).with(hash_including(:all_aspects? => all_aspects)).and_return(stub.as_null_object)
|
||||
@alice.should_receive(:visible_shareables).with(Post, hash_including(:all_aspects? => all_aspects)).and_return(stub.as_null_object)
|
||||
stream.posts
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ describe 'making sure the spec runner works' do
|
|||
|
||||
it 'allows posting after running' do
|
||||
message = @user1.post(:status_message, :text => "Connection!", :to => @aspect1.id)
|
||||
@user2.reload.visible_posts.should include message
|
||||
@user2.reload.visible_shareables(Post).should include message
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ describe Post do
|
|||
describe "#receive" do
|
||||
it 'returns false if the post does not verify' do
|
||||
@post = Factory(:status_message, :author => bob.person)
|
||||
@post.should_receive(:verify_persisted_post).and_return(false)
|
||||
@post.should_receive(:verify_persisted_shareable).and_return(false)
|
||||
@post.receive(bob, eve.person).should == false
|
||||
end
|
||||
end
|
||||
|
|
@ -230,12 +230,12 @@ describe Post do
|
|||
before do
|
||||
@post = Factory.build(:status_message, :author => bob.person)
|
||||
@known_post = Post.new
|
||||
bob.stub(:contact_for).with(eve.person).and_return(stub(:receive_post => true))
|
||||
bob.stub(:contact_for).with(eve.person).and_return(stub(:receive_shareable => true))
|
||||
end
|
||||
|
||||
context "user knows about the post" do
|
||||
before do
|
||||
bob.stub(:find_visible_post_by_id).and_return(@known_post)
|
||||
bob.stub(:find_visible_shareable_by_id).and_return(@known_post)
|
||||
end
|
||||
|
||||
it 'updates attributes only if mutable' do
|
||||
|
|
@ -253,7 +253,7 @@ describe Post do
|
|||
|
||||
context "the user does not know about the post" do
|
||||
before do
|
||||
bob.stub(:find_visible_post_by_id).and_return(nil)
|
||||
bob.stub(:find_visible_shareable_by_id).and_return(nil)
|
||||
bob.stub(:notify_if_mentioned).and_return(true)
|
||||
end
|
||||
|
||||
|
|
@ -262,7 +262,7 @@ describe Post do
|
|||
end
|
||||
|
||||
it 'notifies the user if they are mentioned' do
|
||||
bob.stub(:contact_for).with(eve.person).and_return(stub(:receive_post => true))
|
||||
bob.stub(:contact_for).with(eve.person).and_return(stub(:receive_shareable => true))
|
||||
bob.should_receive(:notify_if_mentioned).and_return(true)
|
||||
|
||||
@post.send(:receive_persisted, bob, eve.person, @known_post).should == true
|
||||
|
|
@ -274,17 +274,17 @@ describe Post do
|
|||
context "the user does not know about the post" do
|
||||
before do
|
||||
@post = Factory.build(:status_message, :author => bob.person)
|
||||
bob.stub(:find_visible_post_by_id).and_return(nil)
|
||||
bob.stub(:find_visible_shareable_by_id).and_return(nil)
|
||||
bob.stub(:notify_if_mentioned).and_return(true)
|
||||
end
|
||||
|
||||
it "it receives the post from the contact of the author" do
|
||||
bob.should_receive(:contact_for).with(eve.person).and_return(stub(:receive_post => true))
|
||||
bob.should_receive(:contact_for).with(eve.person).and_return(stub(:receive_shareable => true))
|
||||
@post.send(:receive_non_persisted, bob, eve.person).should == true
|
||||
end
|
||||
|
||||
it 'notifies the user if they are mentioned' do
|
||||
bob.stub(:contact_for).with(eve.person).and_return(stub(:receive_post => true))
|
||||
bob.stub(:contact_for).with(eve.person).and_return(stub(:receive_shareable => true))
|
||||
bob.should_receive(:notify_if_mentioned).and_return(true)
|
||||
|
||||
@post.send(:receive_non_persisted, bob, eve.person).should == true
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ describe User do
|
|||
it 'saves post into visible post ids' do
|
||||
lambda {
|
||||
alice.add_to_streams(@post, @aspects)
|
||||
}.should change{alice.visible_posts(:by_members_of => @aspects).length}.by(1)
|
||||
alice.visible_posts(:by_members_of => @aspects).should include @post
|
||||
}.should change{alice.visible_shareables(Post, :by_members_of => @aspects).length}.by(1)
|
||||
alice.visible_shareables(Post, :by_members_of => @aspects).should include @post
|
||||
end
|
||||
|
||||
it 'saves post into each aspect in aspect_ids' do
|
||||
|
|
|
|||
|
|
@ -12,49 +12,50 @@ describe User do
|
|||
@bobs_aspect = bob.aspects.where(:name => "generic").first
|
||||
end
|
||||
|
||||
describe "#visible_post_ids" do
|
||||
describe "#visible_shareable_ids" do
|
||||
it "contains your public posts" do
|
||||
public_post = alice.post(:status_message, :text => "hi", :to => @alices_aspect.id, :public => true)
|
||||
alice.visible_post_ids.should include(public_post.id)
|
||||
alice.visible_shareable_ids(Post).should include(public_post.id)
|
||||
end
|
||||
|
||||
it "contains your non-public posts" do
|
||||
private_post = alice.post(:status_message, :text => "hi", :to => @alices_aspect.id, :public => false)
|
||||
alice.visible_post_ids.should include(private_post.id)
|
||||
alice.visible_shareable_ids(Post).should include(private_post.id)
|
||||
end
|
||||
|
||||
it "contains public posts from people you're following" do
|
||||
dogs = bob.aspects.create(:name => "dogs")
|
||||
bobs_public_post = bob.post(:status_message, :text => "hello", :public => true, :to => dogs.id)
|
||||
alice.visible_post_ids.should include(bobs_public_post.id)
|
||||
alice.visible_shareable_ids(Post).should include(bobs_public_post.id)
|
||||
end
|
||||
|
||||
it "contains non-public posts from people who are following you" do
|
||||
bobs_post = bob.post(:status_message, :text => "hello", :to => @bobs_aspect.id)
|
||||
alice.visible_post_ids.should include(bobs_post.id)
|
||||
alice.visible_shareable_ids(Post).should include(bobs_post.id)
|
||||
end
|
||||
|
||||
it "does not contain non-public posts from aspects you're not in" do
|
||||
dogs = bob.aspects.create(:name => "dogs")
|
||||
invisible_post = bob.post(:status_message, :text => "foobar", :to => dogs.id)
|
||||
alice.visible_post_ids.should_not include(invisible_post.id)
|
||||
alice.visible_shareable_ids(Post).should_not include(invisible_post.id)
|
||||
end
|
||||
|
||||
it "does not contain pending posts" do
|
||||
pending_post = bob.post(:status_message, :text => "hey", :public => true, :to => @bobs_aspect.id, :pending => true)
|
||||
pending_post.should be_pending
|
||||
alice.visible_post_ids.should_not include pending_post.id
|
||||
alice.visible_shareable_ids(Post).should_not include pending_post.id
|
||||
end
|
||||
|
||||
it "does not contain pending photos" do
|
||||
pending_photo = bob.post(:photo, :pending => true, :user_file=> File.open(photo_fixture_name), :to => @bobs_aspect)
|
||||
alice.visible_post_ids.should_not include pending_photo.id
|
||||
alice.visible_shareable_ids(Photo).should_not include pending_photo.id
|
||||
end
|
||||
|
||||
it "respects the :type option" do
|
||||
photo = bob.post(:photo, :pending => false, :user_file=> File.open(photo_fixture_name), :to => @bobs_aspect)
|
||||
alice.visible_post_ids(:type => "Photo").should include(photo.id)
|
||||
alice.visible_post_ids(:type => 'StatusMessage').should_not include(photo.id)
|
||||
post = bob.post(:status_message, :text => "hey", :public => true, :to => @bobs_aspect.id, :pending => false)
|
||||
reshare = bob.post(:reshare, :pending => false, :root_guid => post.guid, :to => @bobs_aspect)
|
||||
alice.visible_shareable_ids(Post, :type => "Reshare").should include(reshare.id)
|
||||
alice.visible_shareable_ids(Post, :type => 'StatusMessage').should_not include(reshare.id)
|
||||
end
|
||||
|
||||
it "does not contain duplicate posts" do
|
||||
|
|
@ -64,24 +65,24 @@ describe User do
|
|||
|
||||
bobs_post = bob.post(:status_message, :text => "hai to all my people", :to => [@bobs_aspect.id, bobs_other_aspect.id])
|
||||
|
||||
alice.visible_post_ids.length.should == 1
|
||||
alice.visible_post_ids.should include(bobs_post.id)
|
||||
alice.visible_shareable_ids(Post).length.should == 1
|
||||
alice.visible_shareable_ids(Post).should include(bobs_post.id)
|
||||
end
|
||||
|
||||
describe 'hidden posts' do
|
||||
before do
|
||||
aspect_to_post = bob.aspects.where(:name => "generic").first
|
||||
@status = bob.post(:status_message, :text=> "hello", :to => aspect_to_post)
|
||||
@vis = @status.share_visibilities.first
|
||||
@vis = @status.share_visibilities(Post).first
|
||||
end
|
||||
|
||||
it "pulls back non hidden posts" do
|
||||
alice.visible_post_ids.include?(@status.id).should be_true
|
||||
alice.visible_shareable_ids(Post).include?(@status.id).should be_true
|
||||
end
|
||||
|
||||
it "does not pull back hidden posts" do
|
||||
@vis.update_attributes(:hidden => true)
|
||||
alice.visible_post_ids.include?(@status.id).should be_false
|
||||
alice.visible_shareable_ids(Post).include?(@status.id).should be_false
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -98,16 +99,16 @@ describe User do
|
|||
it "gets populated with latest 100 posts" do
|
||||
cache = mock(:cache_exists? => true, :supported_order? => true, :ensure_populated! => mock, :post_ids => [])
|
||||
RedisCache.stub(:new).and_return(cache)
|
||||
@opts = alice.send(:prep_opts, @opts)
|
||||
@opts = alice.send(:prep_opts, Post, @opts)
|
||||
cache.should_receive(:ensure_populated!).with(hash_including(@opts))
|
||||
|
||||
alice.visible_post_ids(@opts)
|
||||
alice.visible_shareable_ids(Post, @opts)
|
||||
end
|
||||
|
||||
it 'does not get used if if all_aspects? option is not present' do
|
||||
RedisCache.should_not_receive(:new)
|
||||
|
||||
alice.visible_post_ids(@opts.merge({:all_aspects? => false}))
|
||||
alice.visible_shareable_ids(Post, @opts.merge({:all_aspects? => false}))
|
||||
end
|
||||
|
||||
describe "#ensure_populated_cache" do
|
||||
|
|
@ -124,14 +125,14 @@ describe User do
|
|||
it "reads from the cache" do
|
||||
@cache.should_receive(:post_ids).and_return([1,2,3])
|
||||
|
||||
alice.visible_post_ids(@opts.merge({:limit => 3})).should == [1,2,3]
|
||||
alice.visible_shareable_ids(Post, @opts.merge({:limit => 3})).should == [1,2,3]
|
||||
end
|
||||
|
||||
it "queries if maxtime is later than the last cached post" do
|
||||
@cache.stub(:post_ids).and_return([])
|
||||
alice.should_receive(:visible_ids_from_sql)
|
||||
|
||||
alice.visible_post_ids(@opts)
|
||||
alice.visible_shareable_ids(Post, @opts)
|
||||
end
|
||||
|
||||
it "does not get repopulated" do
|
||||
|
|
@ -144,8 +145,8 @@ describe User do
|
|||
it "defaults the opts" do
|
||||
time = Time.now
|
||||
Time.stub(:now).and_return(time)
|
||||
alice.send(:prep_opts, {}).should == {
|
||||
:type => Stream::Base::TYPES_OF_POST_IN_STREAM,
|
||||
alice.send(:prep_opts, Post, {}).should == {
|
||||
:type => BaseStream::TYPES_OF_POST_IN_STREAM,
|
||||
:order => 'created_at DESC',
|
||||
:limit => 15,
|
||||
:hidden => false,
|
||||
|
|
@ -156,7 +157,7 @@ describe User do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#visible_posts" do
|
||||
describe "#visible_shareables" do
|
||||
context 'with many posts' do
|
||||
before do
|
||||
bob.move_contact(eve.person, @bobs_aspect, bob.aspects.create(:name => 'new aspect'))
|
||||
|
|
@ -175,53 +176,53 @@ describe User do
|
|||
end
|
||||
|
||||
it 'works' do # The set up takes a looong time, so to save time we do several tests in one
|
||||
bob.visible_posts.length.should == 15 #it returns 15 by default
|
||||
bob.visible_posts.should == bob.visible_posts(:by_members_of => bob.aspects.map { |a| a.id }) # it is the same when joining through aspects
|
||||
bob.visible_shareables(Post).length.should == 15 #it returns 15 by default
|
||||
bob.visible_shareables(Post).should == bob.visible_shareables(Post, :by_members_of => bob.aspects.map { |a| a.id }) # it is the same when joining through aspects
|
||||
|
||||
# checks the default sort order
|
||||
bob.visible_posts.sort_by { |p| p.created_at }.map { |p| p.id }.should == bob.visible_posts.map { |p| p.id }.reverse #it is sorted updated_at desc by default
|
||||
bob.visible_shareables(Post).sort_by { |p| p.created_at }.map { |p| p.id }.should == bob.visible_shareables(Post).map { |p| p.id }.reverse #it is sorted updated_at desc by default
|
||||
|
||||
# It should respect the order option
|
||||
opts = {:order => 'created_at DESC'}
|
||||
bob.visible_posts(opts).first.created_at.should > bob.visible_posts(opts).last.created_at
|
||||
bob.visible_shareables(Post, opts).first.created_at.should > bob.visible_shareables(Post, opts).last.created_at
|
||||
|
||||
# It should respect the order option
|
||||
opts = {:order => 'updated_at DESC'}
|
||||
bob.visible_posts(opts).first.updated_at.should > bob.visible_posts(opts).last.updated_at
|
||||
bob.visible_shareables(Post, opts).first.updated_at.should > bob.visible_shareables(Post, opts).last.updated_at
|
||||
|
||||
# It should respect the limit option
|
||||
opts = {:limit => 40}
|
||||
bob.visible_posts(opts).length.should == 40
|
||||
bob.visible_posts(opts).should == bob.visible_posts(opts.merge(:by_members_of => bob.aspects.map { |a| a.id }))
|
||||
bob.visible_posts(opts).sort_by { |p| p.created_at }.map { |p| p.id }.should == bob.visible_posts(opts).map { |p| p.id }.reverse
|
||||
bob.visible_shareables(Post, opts).length.should == 40
|
||||
bob.visible_shareables(Post, opts).should == bob.visible_shareables(Post, opts.merge(:by_members_of => bob.aspects.map { |a| a.id }))
|
||||
bob.visible_shareables(Post, opts).sort_by { |p| p.created_at }.map { |p| p.id }.should == bob.visible_shareables(Post, opts).map { |p| p.id }.reverse
|
||||
|
||||
# It should paginate using a datetime timestamp
|
||||
last_time_of_last_page = bob.visible_posts.last.created_at
|
||||
last_time_of_last_page = bob.visible_shareables(Post).last.created_at
|
||||
opts = {:max_time => last_time_of_last_page}
|
||||
bob.visible_posts(opts).length.should == 15
|
||||
bob.visible_posts(opts).map { |p| p.id }.should == bob.visible_posts(opts.merge(:by_members_of => bob.aspects.map { |a| a.id })).map { |p| p.id }
|
||||
bob.visible_posts(opts).sort_by { |p| p.created_at}.map { |p| p.id }.should == bob.visible_posts(opts).map { |p| p.id }.reverse
|
||||
bob.visible_posts(opts).map { |p| p.id }.should == bob.visible_posts(:limit => 40)[15...30].map { |p| p.id } #pagination should return the right posts
|
||||
bob.visible_shareables(Post, opts).length.should == 15
|
||||
bob.visible_shareables(Post, opts).map { |p| p.id }.should == bob.visible_shareables(Post, opts.merge(:by_members_of => bob.aspects.map { |a| a.id })).map { |p| p.id }
|
||||
bob.visible_shareables(Post, opts).sort_by { |p| p.created_at}.map { |p| p.id }.should == bob.visible_shareables(Post, opts).map { |p| p.id }.reverse
|
||||
bob.visible_shareables(Post, opts).map { |p| p.id }.should == bob.visible_shareables(Post, :limit => 40)[15...30].map { |p| p.id } #pagination should return the right posts
|
||||
|
||||
# It should paginate using an integer timestamp
|
||||
opts = {:max_time => last_time_of_last_page.to_i}
|
||||
bob.visible_posts(opts).length.should == 15
|
||||
bob.visible_posts(opts).map { |p| p.id }.should == bob.visible_posts(opts.merge(:by_members_of => bob.aspects.map { |a| a.id })).map { |p| p.id }
|
||||
bob.visible_posts(opts).sort_by { |p| p.created_at}.map { |p| p.id }.should == bob.visible_posts(opts).map { |p| p.id }.reverse
|
||||
bob.visible_posts(opts).map { |p| p.id }.should == bob.visible_posts(:limit => 40)[15...30].map { |p| p.id } #pagination should return the right posts
|
||||
bob.visible_shareables(Post, opts).length.should == 15
|
||||
bob.visible_shareables(Post, opts).map { |p| p.id }.should == bob.visible_shareables(Post, opts.merge(:by_members_of => bob.aspects.map { |a| a.id })).map { |p| p.id }
|
||||
bob.visible_shareables(Post, opts).sort_by { |p| p.created_at}.map { |p| p.id }.should == bob.visible_shareables(Post, opts).map { |p| p.id }.reverse
|
||||
bob.visible_shareables(Post, opts).map { |p| p.id }.should == bob.visible_shareables(Post, :limit => 40)[15...30].map { |p| p.id } #pagination should return the right posts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#find_visible_post_by_id' do
|
||||
describe '#find_visible_shareable_by_id' do
|
||||
it "returns a post if you can see it" do
|
||||
bobs_post = bob.post(:status_message, :text => "hi", :to => @bobs_aspect.id, :public => false)
|
||||
alice.find_visible_post_by_id(bobs_post.id).should == bobs_post
|
||||
alice.find_visible_shareable_by_id(Post, bobs_post.id).should == bobs_post
|
||||
end
|
||||
it "returns nil if you can't see that post" do
|
||||
dogs = bob.aspects.create(:name => "dogs")
|
||||
invisible_post = bob.post(:status_message, :text => "foobar", :to => dogs.id)
|
||||
alice.find_visible_post_by_id(invisible_post.id).should be_nil
|
||||
alice.find_visible_shareable_by_id(Post, invisible_post.id).should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue