Merge branch 'like-comments'
This commit is contained in:
commit
be5f3bf95e
41 changed files with 374 additions and 231 deletions
|
|
@ -31,8 +31,6 @@ class AdminsController < ApplicationController
|
|||
|
||||
def stats
|
||||
@popular_tags = ActsAsTaggableOn::Tagging.joins(:tag).limit(15).count(:group => :tag, :order => 'count(taggings.id) DESC')
|
||||
@most_liked_posts = Post.where(:type => ['StatusMessage', 'ActivityStreams::Photo'],
|
||||
:public => true).order('likes_count DESC').limit(15).all
|
||||
@new_posts = Post.where(:type => ['StatusMessage','ActivityStreams::Photo'],
|
||||
:public => true).order('created_at DESC').limit(15).all
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,17 +9,16 @@ class LikesController < ApplicationController
|
|||
respond_to :html, :mobile, :json
|
||||
|
||||
def create
|
||||
target = current_user.find_visible_post_by_id params[:post_id]
|
||||
positive = (params[:positive] == 'true') ? true : false
|
||||
if target
|
||||
@like = current_user.build_like(:positive => positive, :post => target)
|
||||
@like = current_user.build_like(:positive => positive, :target => target)
|
||||
|
||||
if @like.save
|
||||
Rails.logger.info("event=create type=like user=#{current_user.diaspora_handle} status=success like=#{@like.id} positive=#{positive}")
|
||||
Postzord::Dispatch.new(current_user, @like).post
|
||||
|
||||
respond_to do |format|
|
||||
format.js { render :status => 201 }
|
||||
format.js { render 'likes/update', :status => 201 }
|
||||
format.html { render :nothing => true, :status => 201 }
|
||||
format.mobile { redirect_to post_path(@like.post_id) }
|
||||
end
|
||||
|
|
@ -32,8 +31,12 @@ class LikesController < ApplicationController
|
|||
end
|
||||
|
||||
def destroy
|
||||
if @like = Like.where(:id => params[:id], :author_id => current_user.person.id, :post_id => params[:post_id]).first
|
||||
if @like = Like.where(:id => params[:id], :author_id => current_user.person.id).first
|
||||
current_user.retract(@like)
|
||||
respond_to do |format|
|
||||
format.all{}
|
||||
format.js{ render 'likes/update' }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.mobile {redirect_to :back}
|
||||
|
|
@ -43,11 +46,21 @@ class LikesController < ApplicationController
|
|||
end
|
||||
|
||||
def index
|
||||
if target = current_user.find_visible_post_by_id(params[:post_id])
|
||||
if target
|
||||
@likes = target.likes.includes(:author => :profile)
|
||||
render :layout => false
|
||||
else
|
||||
render :nothing => true, :status => 404
|
||||
end
|
||||
end
|
||||
|
||||
def target
|
||||
@target ||= if params[:post_id]
|
||||
current_user.find_visible_post_by_id(params[:post_id])
|
||||
else
|
||||
comment = Comment.find(params[:comment_id])
|
||||
comment = nil unless current_user.find_visible_post_by_id(comment.post_id)
|
||||
comment
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
class SessionsController < Devise::SessionsController
|
||||
|
||||
after_filter :enqueue_update, :only => :create
|
||||
#after_filter :enqueue_update, :only => :create
|
||||
|
||||
protected
|
||||
def enqueue_update
|
||||
|
|
|
|||
|
|
@ -8,11 +8,25 @@ module LikesHelper
|
|||
links.join(", ").html_safe
|
||||
end
|
||||
|
||||
def like_action(post, current_user=current_user)
|
||||
if current_user.liked?(post)
|
||||
link_to t('shared.stream_element.unlike'), post_like_path(post, current_user.like_for(post)), :method => :delete, :class => 'unlike', :remote => true
|
||||
def like_action(target, current_user=current_user)
|
||||
|
||||
target = target.model if target.instance_of?(PostsFake::Fake)
|
||||
|
||||
if target.instance_of?(Comment)
|
||||
if current_user.liked?(target)
|
||||
link_to t('shared.stream_element.unlike'), comment_like_path(target, current_user.like_for(target)), :method => :delete, :class => 'unlike', :remote => true
|
||||
else
|
||||
link_to t('shared.stream_element.like'), comment_likes_path(target, :positive => 'true'), :method => :post, :class => 'like', :remote => true
|
||||
end
|
||||
|
||||
else
|
||||
link_to t('shared.stream_element.like'), post_likes_path(post, :positive => 'true'), :method => :post, :class => 'like', :remote => true
|
||||
|
||||
if current_user.liked?(target)
|
||||
link_to t('shared.stream_element.unlike'), post_like_path(target, current_user.like_for(target)), :method => :delete, :class => 'unlike', :remote => true
|
||||
else
|
||||
link_to t('shared.stream_element.like'), post_likes_path(target, :positive => 'true'), :method => :post, :class => 'like', :remote => true
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ class Comment < ActiveRecord::Base
|
|||
|
||||
include Diaspora::Socketable
|
||||
include Diaspora::Taggable
|
||||
include Diaspora::Likeable
|
||||
|
||||
acts_as_taggable_on :tags
|
||||
extract_tags_from :text
|
||||
|
|
|
|||
|
|
@ -8,18 +8,27 @@ class Like < ActiveRecord::Base
|
|||
|
||||
include Diaspora::Webhooks
|
||||
include Diaspora::Guid
|
||||
include Diaspora::Relayable
|
||||
|
||||
xml_attr :target_type
|
||||
include Diaspora::Relayable
|
||||
include Diaspora::Socketable
|
||||
|
||||
xml_attr :positive
|
||||
xml_attr :diaspora_handle
|
||||
|
||||
belongs_to :post, :counter_cache => true
|
||||
belongs_to :target, :polymorphic => true
|
||||
belongs_to :author, :class_name => 'Person'
|
||||
|
||||
validates_uniqueness_of :post_id, :scope => :author_id
|
||||
validates_presence_of :author, :post
|
||||
validates_uniqueness_of :target_id, :scope => [:target_type, :author_id]
|
||||
validates_presence_of :author, :target
|
||||
|
||||
after_create do
|
||||
self.target.update_likes_counter
|
||||
end
|
||||
|
||||
after_destroy do
|
||||
self.target.update_likes_counter
|
||||
end
|
||||
|
||||
def diaspora_handle
|
||||
self.author.diaspora_handle
|
||||
|
|
@ -30,18 +39,20 @@ class Like < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def parent_class
|
||||
Post
|
||||
self.target_type.constantize
|
||||
end
|
||||
|
||||
def parent
|
||||
self.post
|
||||
self.target
|
||||
end
|
||||
|
||||
def parent= parent
|
||||
self.post = parent
|
||||
self.target = parent
|
||||
end
|
||||
|
||||
def notification_type(user, person)
|
||||
Notifications::Liked if self.post.author == user.person && user.person != person
|
||||
#TODO(dan) need to have a notification for likes on comments, until then, return nil
|
||||
return nil if self.target_type == "Comment"
|
||||
Notifications::Liked if self.target.author == user.person && user.person != person
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class Notification < ActiveRecord::Base
|
|||
if target.respond_to? :notification_type
|
||||
if note_type = target.notification_type(recipient, actor)
|
||||
if(target.is_a? Comment) || (target.is_a? Like)
|
||||
n = note_type.concatenate_or_create(recipient, target.post, actor, note_type)
|
||||
n = note_type.concatenate_or_create(recipient, target.parent, actor, note_type)
|
||||
else
|
||||
n = note_type.make_notification(recipient, target, actor, note_type)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ class Post < ActiveRecord::Base
|
|||
include Diaspora::Webhooks
|
||||
include Diaspora::Guid
|
||||
|
||||
include Diaspora::Likeable
|
||||
|
||||
xml_attr :diaspora_handle
|
||||
xml_attr :public
|
||||
xml_attr :created_at
|
||||
|
||||
has_many :comments, :dependent => :destroy
|
||||
has_many :likes, :conditions => {:positive => true}, :dependent => :delete_all
|
||||
has_many :dislikes, :conditions => {:positive => false}, :class_name => 'Like', :dependent => :delete_all
|
||||
|
||||
has_many :aspect_visibilities
|
||||
has_many :aspects, :through => :aspect_visibilities
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ class StatusMessage < Post
|
|||
|
||||
serialize :youtube_titles, Hash
|
||||
|
||||
before_create :build_tags
|
||||
after_create :create_mentions
|
||||
|
||||
def text(opts = {})
|
||||
|
|
|
|||
|
|
@ -183,26 +183,26 @@ class User < ActiveRecord::Base
|
|||
|
||||
# Check whether the user has liked a post. Extremely inefficient if the post's likes are not loaded.
|
||||
# @param [Post] post
|
||||
def liked?(post)
|
||||
if post.likes.loaded?
|
||||
if self.like_for(post)
|
||||
def liked?(target)
|
||||
if target.likes.loaded?
|
||||
if self.like_for(target)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
else
|
||||
Like.exists?(:author_id => self.person.id, :post_id => post.id)
|
||||
Like.exists?(:author_id => self.person.id, :target_type => target.class.base_class.to_s, :target_id => target.id)
|
||||
end
|
||||
end
|
||||
|
||||
# Get the user's like of a post, if there is one. Extremely inefficient if the post's likes are not loaded.
|
||||
# @param [Post] post
|
||||
# @return [Like]
|
||||
def like_for(post)
|
||||
if post.likes.loaded?
|
||||
return post.likes.detect{ |like| like.author_id == self.person.id }
|
||||
def like_for(target)
|
||||
if target.likes.loaded?
|
||||
return target.likes.detect{ |like| like.author_id == self.person.id }
|
||||
else
|
||||
return Like.where(:author_id => self.person.id, :post_id => post.id).first
|
||||
return Like.where(:author_id => self.person.id, :target_type => target.class.base_class.to_s, :target_id => target.id).first
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -215,13 +215,11 @@ class User < ActiveRecord::Base
|
|||
end
|
||||
|
||||
######### Posts and Such ###############
|
||||
def retract(post)
|
||||
if post.respond_to?(:relayable?) && post.relayable?
|
||||
aspects = post.parent.aspects
|
||||
retraction = RelayableRetraction.build(self, post)
|
||||
def retract(target)
|
||||
if target.respond_to?(:relayable?) && target.relayable?
|
||||
retraction = RelayableRetraction.build(self, target)
|
||||
else
|
||||
aspects = post.aspects
|
||||
retraction = Retraction.for(post)
|
||||
retraction = Retraction.for(target)
|
||||
end
|
||||
|
||||
mailman = Postzord::Dispatch.new(self, retraction)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
%li.comment.posted{:data=>{:guid => comment.id}, :class => ("hidden" if(defined? hidden))}
|
||||
%li.comment.posted{:id => comment.guid, :class => ("hidden" if(defined? hidden))}
|
||||
- if current_user && (current_user.owns?(comment) || current_user.owns?(post))
|
||||
.right.controls
|
||||
= link_to image_tag('deletelabel.png'), post_comment_path(comment.post_id, comment), :confirm => t('are_you_sure'), :method => :delete, :remote => true, :class => "delete comment_delete", :title => t('delete')
|
||||
|
|
@ -16,7 +16,18 @@
|
|||
%span{:class => direction_for(comment.text)}
|
||||
= markdownify(Diaspora::Taggable.format_tags(comment.text), :youtube_maps => comment.youtube_titles)
|
||||
|
||||
%br
|
||||
.comment_info
|
||||
%time.timeago{:datetime => comment.created_at}
|
||||
= comment.created_at ? timeago(comment.created_at) : timeago(Time.now)
|
||||
·
|
||||
|
||||
.likes
|
||||
= render "likes/likes_container", :target_id => comment.id, :likes_count => comment.likes_count
|
||||
|
||||
- if comment.likes_count > 0
|
||||
·
|
||||
|
||||
- unless (defined?(@commenting_disabled) && @commenting_disabled)
|
||||
%span.like_action
|
||||
= like_action(comment, current_user)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
- unless comments_expanded
|
||||
%ul.show_comments{:class => ("hidden" if post.comments.size <= 3)}
|
||||
%li
|
||||
%b= comment_toggle( post)
|
||||
= comment_toggle( post)
|
||||
|
||||
%ul.comments{:id => post.id, :class => ('loaded' if post.comments.size <= 3)}
|
||||
-if post.comments.size > 3 && !comments_expanded
|
||||
|
|
@ -14,5 +14,5 @@
|
|||
= render :partial => 'comments/comment', :collection => post.comments, :locals => {:post => post}
|
||||
|
||||
- unless @commenting_disabled
|
||||
.new_comment_form_wrapper{:class => ( 'hidden' if post.comments.size == 0)}
|
||||
.new_comment_form_wrapper{:class => ('hidden' if post.comments.size == 0)}
|
||||
= new_comment_form(post.id, current_user)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
WebSocketReceiver.processComment(<%= @comment.post_id %>,
|
||||
<%= @comment.id %>,
|
||||
WebSocketReceiver.processComment("<%= @comment.post.guid %>",
|
||||
"<%= @comment.guid%>",
|
||||
"<%= escape_javascript(render(:partial => 'comments/comment', :locals => { :comment => @comment, :person => current_user.person}))%>",
|
||||
false);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,13 @@
|
|||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
- if likes_count > 0
|
||||
.likes_container
|
||||
.likes
|
||||
= image_tag('icons/heart.svg')
|
||||
= link_to t('likes.likes.people_like_this', :count => likes_count), post_likes_path(post_id), :class => "expand_likes"
|
||||
%span.hidden.likes_list
|
||||
/= render 'likes/likes', :likes => likes
|
||||
.likes_container
|
||||
- if likes_count > 0
|
||||
= image_tag('icons/heart.svg')
|
||||
- if defined?(likes_index_link) && likes_index_link
|
||||
= link_to t('likes.likes.people_like_this', :count => likes_count), post_likes_path(target_id), :class => "expand_likes"
|
||||
- else
|
||||
= t('likes.likes.people_like_this', :count => likes_count)
|
||||
%span.hidden.likes_list
|
||||
/= render 'likes/likes', :likes => likes
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
$(".like_action", ".stream_element[data-guid=<%=@like.post_id%>]").html("<%= escape_javascript(like_action(@like.post))%>");
|
||||
|
||||
WebSocketReceiver.processLike("<%=@like.post_id%>", "<%= escape_javascript(render("likes/likes_container", :post_id => @like.post_id, :likes_count => @like.post.likes.count)) %>");
|
||||
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
$(".like_action", ".stream_element[data-guid=<%=@like.post_id%>]").html("<%= escape_javascript(like_action(@like.post))%>");
|
||||
WebSocketReceiver.processLike("<%=@like.post_id%>", "<%= escape_javascript(render("likes/likes_container", :post_id => @like.post_id, :likes_count => @like.post.likes.count)) %>");
|
||||
|
||||
2
app/views/likes/update.js.erb
Normal file
2
app/views/likes/update.js.erb
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
$(".like_action", "#<%=@like.target.guid%>").first().html("<%= escape_javascript(like_action(@like.target))%>");
|
||||
WebSocketReceiver.processLike("<%=@like.target.guid%>", "<%= escape_javascript(render("likes/likes_container", :target_id => @like.target_id, :likes_count => @like.target.likes_count)) %>");
|
||||
|
|
@ -4,12 +4,11 @@
|
|||
= t('.liked', :name => "#{@sender.name} (#{@sender.diaspora_handle})")
|
||||
|
||||
%p
|
||||
= @like.post.formatted_message(:plain_text => true)
|
||||
= @like.target.formatted_message(:plain_text => true)
|
||||
%p
|
||||
|
||||
%br
|
||||
= link_to t('.sign_in'), post_url(@like.post)
|
||||
|
||||
= link_to t('.sign_in'), post_url(@like.target)
|
||||
%br
|
||||
= t('notifier.love')
|
||||
%br
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
!= t('notifier.liked.liked', :name => "#{@sender.name} (#{@sender.diaspora_handle})")
|
||||
|
||||
!= @like.post.formatted_message(:plain_text => true)
|
||||
!= @like.target.formatted_message(:plain_text => true)
|
||||
|
||||
!= t('notifier.love')
|
||||
!= t('notifier.diaspora')
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
var target = $(".stream_element[data-guid=<%= escape_javascript(@post.id.to_s) %>]")
|
||||
var target = $("#<%= @post.guid %>")
|
||||
target.find(".sm_body").toggleClass("hidden");
|
||||
target.find(".undo_text").toggleClass("hidden");
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
var target = $(".stream_element[data-guid=<%= escape_javascript(@post.id.to_s) %>]")
|
||||
var target = $("#<%= @post.guid %>")
|
||||
target.hide('blind', { direction: 'vertical' }, 300, function(){ target.remove() });
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
.stream_element{:data=>{:guid=>post.id}}
|
||||
.stream_element{:id => post.guid}
|
||||
- if current_user && post.author.owner_id == current_user.id
|
||||
.right.controls
|
||||
= link_to image_tag('deletelabel.png'), post_path(post), :confirm => t('are_you_sure'), :method => :delete, :remote => true, :class => "delete stream_element_delete", :title => t('delete')
|
||||
|
|
@ -55,8 +55,7 @@
|
|||
·
|
||||
= link_to t('comments.new_comment.comment'), '#', :class => 'focus_comment_textarea'
|
||||
|
||||
.likes
|
||||
- if post.likes_count > 0
|
||||
= render "likes/likes_container", :post_id => post.id, :likes_count => post.likes_count, :current_user => current_user
|
||||
.likes.on_post
|
||||
= render "likes/likes_container", :target_id => post.id, :likes_count => post.likes_count, :current_user => current_user, :likes_index_link => true
|
||||
|
||||
= render "comments/comments", :post => post, :current_user => current_user, :commenting_disabled => (defined?(@commenting_disabled) && @commenting_disabled)
|
||||
|
|
|
|||
|
|
@ -8,4 +8,4 @@
|
|||
:all_aspects => current_user.aspects
|
||||
}
|
||||
),
|
||||
:post_id => @status_message.id}.to_json.html_safe%>
|
||||
:post_id => @status_message.guid}.to_json.html_safe%>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,12 @@ Diaspora::Application.routes.draw do
|
|||
resources :comments, :only => [:create, :destroy, :index]
|
||||
end
|
||||
|
||||
# roll up likes into a nested resource above
|
||||
resources :comments, :only => [:create, :destroy] do
|
||||
resources :likes, :only => [:create, :destroy, :index]
|
||||
end
|
||||
|
||||
|
||||
get 'bookmarklet' => 'status_messages#bookmarklet'
|
||||
get 'p/:id' => 'publics#post', :as => 'public_post'
|
||||
|
||||
|
|
|
|||
37
db/migrate/20110707234802_likes_on_comments.rb
Normal file
37
db/migrate/20110707234802_likes_on_comments.rb
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
class LikesOnComments < ActiveRecord::Migration
|
||||
class Likes < ActiveRecord::Base; end
|
||||
def self.up
|
||||
remove_foreign_key :likes, :posts
|
||||
|
||||
add_column :likes, :target_type, :string, :limit => 60, :null => false
|
||||
rename_column :likes, :post_id, :target_id
|
||||
|
||||
add_column :comments, :likes_count, :integer, :default => 0, :null => false
|
||||
|
||||
execute <<SQL
|
||||
UPDATE likes
|
||||
SET target_type = 'Post'
|
||||
SQL
|
||||
execute <<SQL
|
||||
UPDATE posts
|
||||
SET likes_count = (SELECT COUNT(*) FROM likes WHERE likes.target_id = posts.id AND likes.target_type = 'Post')
|
||||
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
|
||||
end
|
||||
add_index :likes, [:target_id, :author_id, :target_type], :unique => true
|
||||
end
|
||||
|
||||
def self.down
|
||||
remove_column :comments, :likes_count
|
||||
|
||||
remove_column :likes, :target_type
|
||||
rename_column :likes, :target_id, :post_id
|
||||
add_index :likes, :post_id
|
||||
remove_index :likes, :target_id
|
||||
end
|
||||
end
|
||||
20
db/schema.rb
20
db/schema.rb
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 20110707221112) do
|
||||
ActiveRecord::Schema.define(:version => 20110707234802) do
|
||||
|
||||
create_table "aspect_memberships", :force => true do |t|
|
||||
t.integer "aspect_id", :null => false
|
||||
|
|
@ -46,15 +46,16 @@ ActiveRecord::Schema.define(:version => 20110707221112) do
|
|||
add_index "aspects", ["user_id"], :name => "index_aspects_on_user_id"
|
||||
|
||||
create_table "comments", :force => true do |t|
|
||||
t.text "text", :null => false
|
||||
t.integer "post_id", :null => false
|
||||
t.integer "author_id", :null => false
|
||||
t.string "guid", :null => false
|
||||
t.text "text", :null => false
|
||||
t.integer "post_id", :null => false
|
||||
t.integer "author_id", :null => false
|
||||
t.string "guid", :null => false
|
||||
t.text "author_signature"
|
||||
t.text "parent_author_signature"
|
||||
t.text "youtube_titles"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.integer "likes_count", :default => 0, :null => false
|
||||
end
|
||||
|
||||
add_index "comments", ["author_id"], :name => "index_comments_on_person_id"
|
||||
|
|
@ -109,19 +110,21 @@ ActiveRecord::Schema.define(:version => 20110707221112) do
|
|||
add_index "invitations", ["sender_id"], :name => "index_invitations_on_sender_id"
|
||||
|
||||
create_table "likes", :force => true do |t|
|
||||
t.boolean "positive", :default => true
|
||||
t.integer "post_id"
|
||||
t.boolean "positive", :default => true
|
||||
t.integer "target_id"
|
||||
t.integer "author_id"
|
||||
t.string "guid"
|
||||
t.text "author_signature"
|
||||
t.text "parent_author_signature"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.string "target_type", :limit => 60, :null => false
|
||||
end
|
||||
|
||||
add_index "likes", ["author_id"], :name => "likes_author_id_fk"
|
||||
add_index "likes", ["guid"], :name => "index_likes_on_guid", :unique => true
|
||||
add_index "likes", ["post_id"], :name => "index_likes_on_post_id"
|
||||
add_index "likes", ["target_id", "author_id", "target_type"], :name => "index_likes_on_target_id_and_author_id_and_target_type", :unique => true
|
||||
add_index "likes", ["target_id"], :name => "index_likes_on_post_id"
|
||||
|
||||
create_table "mentions", :force => true do |t|
|
||||
t.integer "post_id", :null => false
|
||||
|
|
@ -418,7 +421,6 @@ ActiveRecord::Schema.define(:version => 20110707221112) do
|
|||
add_foreign_key "invitations", "users", :name => "invitations_sender_id_fk", :column => "sender_id", :dependent => :delete
|
||||
|
||||
add_foreign_key "likes", "people", :name => "likes_author_id_fk", :column => "author_id", :dependent => :delete
|
||||
add_foreign_key "likes", "posts", :name => "likes_post_id_fk", :dependent => :delete
|
||||
|
||||
add_foreign_key "messages", "conversations", :name => "messages_conversation_id_fk", :dependent => :delete
|
||||
add_foreign_key "messages", "people", :name => "messages_author_id_fk", :column => "author_id", :dependent => :delete
|
||||
|
|
|
|||
20
lib/diaspora/likeable.rb
Normal file
20
lib/diaspora/likeable.rb
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
module Diaspora
|
||||
module Likeable
|
||||
def self.included(model)
|
||||
model.instance_eval do
|
||||
has_many :likes, :conditions => {:positive => true}, :dependent => :delete_all, :as => :target
|
||||
has_many :dislikes, :conditions => {:positive => false}, :class_name => 'Like', :dependent => :delete_all, :as => :target
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Integer]
|
||||
def update_likes_counter
|
||||
self.likes_count = self.likes.count
|
||||
self.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -55,7 +55,7 @@ module Diaspora
|
|||
Postzord::Dispatch.new(user, object).post
|
||||
end
|
||||
|
||||
object.socket_to_user(user, :aspect_ids => object.parent.aspect_ids) if object.respond_to? :socket_to_user
|
||||
object.socket_to_user(user) if object.respond_to? :socket_to_user
|
||||
if object.after_receive(user, person)
|
||||
object
|
||||
end
|
||||
|
|
@ -69,16 +69,18 @@ module Diaspora
|
|||
#sign relayable as model creator
|
||||
self.author_signature = self.sign_with_key(author.owner.encryption_key)
|
||||
|
||||
if !self.post_id.blank? && self.author.owns?(self.parent)
|
||||
if !self.parent.blank? && self.author.owns?(self.parent)
|
||||
#sign relayable as parent object owner
|
||||
self.parent_author_signature = sign_with_key(author.owner.encryption_key)
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Boolean]
|
||||
def verify_parent_author_signature
|
||||
verify_signature(self.parent_author_signature, self.parent.author)
|
||||
end
|
||||
|
||||
# @return [Boolean]
|
||||
def signature_valid?
|
||||
verify_signature(self.author_signature, self.author)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ module Diaspora
|
|||
cattr_accessor :field_with_tags
|
||||
end
|
||||
model.instance_eval do
|
||||
before_create :build_tags
|
||||
|
||||
def extract_tags_from sym
|
||||
self.field_with_tags = sym
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module Diaspora
|
|||
module Querying
|
||||
|
||||
def find_visible_post_by_id( id, opts={} )
|
||||
post = Post.where(:id => id).joins(:contacts).where(:contacts => {:user_id => self.id}).where(opts).first
|
||||
post = Post.where(:id => id).joins(:contacts).where(:contacts => {:user_id => self.id}).where(opts).select("posts.*").first
|
||||
post ||= Post.where(:id => id, :author_id => self.person.id).where(opts).first
|
||||
post ||= Post.where(:id => id, :public => true).where(opts).first
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,14 +4,11 @@
|
|||
*/
|
||||
|
||||
var ContentUpdater = {
|
||||
elementWithGuid: function(selector, guid) {
|
||||
return $(selector + "[data-guid='" + guid + "']");
|
||||
},
|
||||
addPostToStream: function(html) {
|
||||
var streamElement = $(html);
|
||||
var postId = streamElement.attr("data-guid");
|
||||
var postGUID = $(streamElement).attr('id');
|
||||
|
||||
if($(".stream_element[data-guid='" + postId + "']").length === 0) {
|
||||
if($("#"+postGUID).length === 0) {
|
||||
if($("#no_posts").length) {
|
||||
$("#no_posts").detach();
|
||||
}
|
||||
|
|
@ -20,19 +17,19 @@ var ContentUpdater = {
|
|||
streamElement.find("label").inFieldLabels();
|
||||
});
|
||||
|
||||
Diaspora.widgets.publish("stream/postAdded", [postId]);
|
||||
Diaspora.widgets.publish("stream/postAdded", [postGUID]);
|
||||
Diaspora.widgets.timeago.updateTimeAgo();
|
||||
Diaspora.widgets.directionDetector.updateBinds();
|
||||
}
|
||||
},
|
||||
|
||||
addLikesToPost: function(postId, html) {
|
||||
var post = ContentUpdater.elementWithGuid("div", postId);
|
||||
addLikesToPost: function(postGUID, html) {
|
||||
var post = $("#" + postGUID);
|
||||
|
||||
$(".likes_container", post)
|
||||
.fadeOut("fast")
|
||||
.html(html)
|
||||
.fadeIn("fast");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ var View = {
|
|||
|
||||
/* notification routing */
|
||||
$("#notification").delegate('.hard_object_link', 'click', function(evt){
|
||||
var post = $("*[data-guid='"+ $(this).attr('data-ref') +"']"),
|
||||
var post = $("#"+ $(this).attr('data-ref')),
|
||||
lastComment = post.find('.comment.posted').last();
|
||||
|
||||
if(post.length > 0){
|
||||
|
|
|
|||
|
|
@ -33,7 +33,12 @@ var WebSocketReceiver = {
|
|||
WebSocketReceiver.processPerson(obj);
|
||||
|
||||
} else {
|
||||
WSR.debug("got a " + obj['class'] + " for aspects " + obj.aspect_ids);
|
||||
debug_string = "got a " + obj['class'];
|
||||
if(obj.aspect_ids !== undefined){
|
||||
debug_string += " for aspects " + obj.aspect_ids;
|
||||
}
|
||||
|
||||
WSR.debug(debug_string);
|
||||
|
||||
if (obj['class']=="retractions") {
|
||||
WebSocketReceiver.processRetraction(obj.post_id);
|
||||
|
|
@ -77,7 +82,7 @@ var WebSocketReceiver = {
|
|||
},
|
||||
|
||||
processRetraction: function(post_id){
|
||||
$("*[data-guid='" + post_id + "']").fadeOut(400, function() {
|
||||
$("#" + post_id).fadeOut(400, function() {
|
||||
$(this).remove();
|
||||
});
|
||||
if($("#main_stream")[0].childElementCount === 0) {
|
||||
|
|
@ -85,11 +90,10 @@ var WebSocketReceiver = {
|
|||
}
|
||||
},
|
||||
|
||||
processComment: function(postId, commentId, html, opts) {
|
||||
processComment: function(postGUID, commentGUID, html, opts) {
|
||||
|
||||
if( $(".comment[data-guid='"+commentId+"']").length === 0 ) {
|
||||
|
||||
var post = $("*[data-guid='"+postId+"']'"),
|
||||
if( $("#"+commentGUID).length === 0 ) {
|
||||
var post = $("#"+postGUID),
|
||||
prevComments = $('.comment.posted', post);
|
||||
|
||||
if(prevComments.length > 0) {
|
||||
|
|
@ -123,9 +127,8 @@ var WebSocketReceiver = {
|
|||
Diaspora.widgets.directionDetector.updateBinds();
|
||||
},
|
||||
|
||||
processLike: function(postId, html) {
|
||||
var post = $("*[data-guid='"+postId+"']");
|
||||
$('.likes', post).html(html);
|
||||
processLike: function(targetGUID, html) {
|
||||
$('.likes', "#" + targetGUID).first().html(html);
|
||||
},
|
||||
|
||||
processPost: function(className, postId, html, aspectIds) {
|
||||
|
|
|
|||
|
|
@ -302,10 +302,10 @@ ul.as-selections
|
|||
:height 370px
|
||||
:width 500px
|
||||
|
||||
time
|
||||
:font
|
||||
:weight normal
|
||||
:size smaller
|
||||
.comment
|
||||
.comment_info
|
||||
:font
|
||||
:size smaller
|
||||
|
||||
.from
|
||||
a
|
||||
|
|
@ -667,9 +667,23 @@ form.new_comment
|
|||
:display inline-block
|
||||
|
||||
|
||||
.comments
|
||||
.timeago
|
||||
:color #999
|
||||
.comment
|
||||
.likes,
|
||||
.likes_container
|
||||
:display inline
|
||||
:padding 0
|
||||
:margin 0
|
||||
:font
|
||||
:size 10px
|
||||
a
|
||||
:font
|
||||
:weight normal
|
||||
|
||||
img
|
||||
:margin 0
|
||||
:height 9px
|
||||
:width 9px
|
||||
:top 1px
|
||||
|
||||
.stream.show
|
||||
ul.comments
|
||||
|
|
@ -816,6 +830,7 @@ label
|
|||
:cursor pointer
|
||||
|
||||
#publisher
|
||||
|
||||
:z-index 0
|
||||
:color #999
|
||||
:position relative
|
||||
|
|
@ -2210,6 +2225,11 @@ ul.show_comments
|
|||
:border
|
||||
:top 1px dotted #aaa
|
||||
|
||||
ul.show_comments,
|
||||
.likes_container
|
||||
a
|
||||
:color #999
|
||||
|
||||
.likes_container
|
||||
:margin
|
||||
:bottom -4px
|
||||
|
|
@ -2217,18 +2237,11 @@ ul.show_comments
|
|||
|
||||
ul.show_comments,
|
||||
.likes_container
|
||||
*
|
||||
:font
|
||||
:weight bold
|
||||
:color #999
|
||||
|
||||
img
|
||||
:position relative
|
||||
:top 3px
|
||||
:top 2px
|
||||
:height 12px
|
||||
:width 12px
|
||||
:margin
|
||||
:left 0.5em
|
||||
|
||||
.mark_all_read
|
||||
:position relative
|
||||
|
|
|
|||
|
|
@ -15,108 +15,122 @@ describe LikesController do
|
|||
sign_in :user, @user1
|
||||
end
|
||||
|
||||
describe '#create' do
|
||||
let(:like_hash) {
|
||||
{:positive => 1,
|
||||
:post_id => "#{@post.id}"}
|
||||
}
|
||||
let(:dislike_hash) {
|
||||
{:positive => 0,
|
||||
:post_id => "#{@post.id}"}
|
||||
}
|
||||
[Comment, Post].each do |class_const|
|
||||
context class_const.to_s do
|
||||
let(:id_field){
|
||||
"#{class_const.to_s.underscore}_id"
|
||||
}
|
||||
|
||||
context "on my own post" do
|
||||
before do
|
||||
@post = @user1.post :status_message, :text => "AWESOME", :to => @aspect1.id
|
||||
describe '#create' do
|
||||
let(:like_hash) {
|
||||
{:positive => 1,
|
||||
id_field => "#{@target.id}"}
|
||||
}
|
||||
let(:dislike_hash) {
|
||||
{:positive => 0,
|
||||
id_field => "#{@target.id}"}
|
||||
}
|
||||
|
||||
context "on my own post" do
|
||||
before do
|
||||
@target = @user1.post :status_message, :text => "AWESOME", :to => @aspect1.id
|
||||
|
||||
@target = @user1.comment "hey", :post => @target if class_const == Comment
|
||||
end
|
||||
|
||||
it 'responds to format js' do
|
||||
post :create, like_hash.merge(:format => 'js')
|
||||
response.code.should == '201'
|
||||
end
|
||||
end
|
||||
|
||||
context "on a post from a contact" do
|
||||
before do
|
||||
@target = @user2.post :status_message, :text => "AWESOME", :to => @aspect2.id
|
||||
@target = @user2.comment "hey", :post => @target if class_const == Comment
|
||||
end
|
||||
|
||||
it 'likes' do
|
||||
post :create, like_hash
|
||||
response.code.should == '201'
|
||||
end
|
||||
|
||||
it 'dislikes' do
|
||||
post :create, dislike_hash
|
||||
response.code.should == '201'
|
||||
end
|
||||
|
||||
it "doesn't post multiple times" do
|
||||
@user1.like(1, :target => @target)
|
||||
post :create, dislike_hash
|
||||
response.code.should == '422'
|
||||
end
|
||||
end
|
||||
|
||||
context "on a post from a stranger" do
|
||||
before do
|
||||
@target = eve.post :status_message, :text => "AWESOME", :to => eve.aspects.first.id
|
||||
@target = eve.comment "hey", :post => @target if class_const == Comment
|
||||
end
|
||||
|
||||
it "doesn't post" do
|
||||
@user1.should_not_receive(:like)
|
||||
post :create, like_hash
|
||||
response.code.should == '422'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'responds to format js' do
|
||||
post :create, like_hash.merge(:format => 'js')
|
||||
response.code.should == '201'
|
||||
end
|
||||
end
|
||||
describe '#index' do
|
||||
before do
|
||||
@message = alice.post(:status_message, :text => "hey", :to => @aspect1.id)
|
||||
@message = alice.comment( "hey", :post => @message) if class_const == Comment
|
||||
end
|
||||
it 'returns a 404 for a post not visible to the user' do
|
||||
sign_in eve
|
||||
get :index, id_field => @message.id
|
||||
end
|
||||
|
||||
context "on a post from a contact" do
|
||||
before do
|
||||
@post = @user2.post :status_message, :text => "AWESOME", :to => @aspect2.id
|
||||
it 'returns an array of likes for a post' do
|
||||
like = bob.build_like(:positive => true, :target => @message)
|
||||
like.save!
|
||||
|
||||
get :index, id_field => @message.id
|
||||
assigns[:likes].map(&:id).should == @message.likes.map(&:id)
|
||||
end
|
||||
|
||||
it 'returns an empty array for a post with no likes' do
|
||||
get :index, id_field => @message.id
|
||||
assigns[:likes].should == []
|
||||
end
|
||||
end
|
||||
|
||||
it 'likes' do
|
||||
post :create, like_hash
|
||||
response.code.should == '201'
|
||||
describe '#destroy' do
|
||||
before do
|
||||
@message = bob.post(:status_message, :text => "hey", :to => @aspect1.id)
|
||||
@message = bob.comment( "hey", :post => @message) if class_const == Comment
|
||||
@like = alice.build_like(:positive => true, :target => @message)
|
||||
@like.save
|
||||
end
|
||||
|
||||
it 'lets a user destroy their like' do
|
||||
expect {
|
||||
delete :destroy, :format => "js", id_field => @like.target_id, :id => @like.id
|
||||
}.should change(Like, :count).by(-1)
|
||||
response.status.should == 200
|
||||
end
|
||||
|
||||
it 'does not let a user destroy other likes' do
|
||||
like2 = eve.build_like(:positive => true, :target => @message)
|
||||
like2.save
|
||||
|
||||
expect {
|
||||
delete :destroy, :format => "js", id_field => like2.target_id, :id => like2.id
|
||||
}.should_not change(Like, :count)
|
||||
|
||||
response.status.should == 403
|
||||
end
|
||||
end
|
||||
|
||||
it 'dislikes' do
|
||||
post :create, dislike_hash
|
||||
response.code.should == '201'
|
||||
end
|
||||
|
||||
it "doesn't post multiple times" do
|
||||
@user1.like(1, :post => @post)
|
||||
post :create, dislike_hash
|
||||
response.code.should == '422'
|
||||
end
|
||||
end
|
||||
|
||||
context "on a post from a stranger" do
|
||||
before do
|
||||
@post = eve.post :status_message, :text => "AWESOME", :to => eve.aspects.first.id
|
||||
end
|
||||
|
||||
it "doesn't post" do
|
||||
@user1.should_not_receive(:like)
|
||||
post :create, like_hash
|
||||
response.code.should == '422'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#index' do
|
||||
before do
|
||||
@message = alice.post(:status_message, :text => "hey", :to => @aspect1.id)
|
||||
end
|
||||
it 'returns a 404 for a post not visible to the user' do
|
||||
sign_in eve
|
||||
get :index, :post_id => @message.id
|
||||
end
|
||||
|
||||
it 'returns an array of likes for a post' do
|
||||
like = bob.build_like(:positive => true, :post => @message)
|
||||
like.save!
|
||||
|
||||
get :index, :post_id => @message.id
|
||||
assigns[:likes].map(&:id).should == @message.likes.map(&:id)
|
||||
end
|
||||
|
||||
it 'returns an empty array for a post with no likes' do
|
||||
get :index, :post_id => @message.id
|
||||
assigns[:likes].should == []
|
||||
end
|
||||
end
|
||||
|
||||
describe '#destroy' do
|
||||
before do
|
||||
@message = bob.post(:status_message, :text => "hey", :to => @aspect1.id)
|
||||
@like = alice.build_like(:positive => true, :post => @message)
|
||||
@like.save
|
||||
end
|
||||
|
||||
it 'lets a user destroy their like' do
|
||||
expect {
|
||||
delete :destroy, :format => "js", :post_id => @like.post_id, :id => @like.id
|
||||
}.should change(Like, :count).by(-1)
|
||||
response.status.should == 200
|
||||
end
|
||||
|
||||
it 'does not let a user destroy other likes' do
|
||||
like2 = eve.build_like(:positive => true, :post => @message)
|
||||
like2.save
|
||||
|
||||
expect {
|
||||
delete :destroy, :format => "js", :post_id => like2.post_id, :id => like2.id
|
||||
}.should_not change(Like, :count)
|
||||
|
||||
response.status.should == 403
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ end
|
|||
|
||||
Factory.define :like do |x|
|
||||
x.association :author, :factory => :person
|
||||
x.association :post, :factory => :status_message
|
||||
x.association :target, :factory => :status_message
|
||||
end
|
||||
|
||||
Factory.define :user do |u|
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ describe NotificationsHelper do
|
|||
@person = Factory(:person)
|
||||
@post = Factory(:status_message, :author => @user.person)
|
||||
@person2 = Factory(:person)
|
||||
@notification = Notification.notify(@user, Factory(:like, :author => @person, :post => @post), @person)
|
||||
@notification = Notification.notify(@user, Factory(:like, :author => @person2, :post => @post), @person2)
|
||||
|
||||
@notification = Notification.notify(@user, Factory(:like, :author => @person, :target => @post), @person)
|
||||
@notification = Notification.notify(@user, Factory(:like, :author => @person2, :target => @post), @person2)
|
||||
end
|
||||
|
||||
describe '#notification_people_link' do
|
||||
context 'formatting' do
|
||||
include ActionView::Helpers::SanitizeHelper
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ describe Notifier do
|
|||
describe ".liked" do
|
||||
before do
|
||||
@sm = Factory(:status_message, :author => alice.person)
|
||||
@like = @sm.likes.create(:author => bob.person)
|
||||
@like = @sm.likes.create!(:author => bob.person)
|
||||
@mail = Notifier.liked(alice.id, @like.author.id, @like.id)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -21,26 +21,26 @@ describe Like do
|
|||
|
||||
describe 'User#like' do
|
||||
it "should be able to like on one's own status" do
|
||||
alice.like(1, :post => @status)
|
||||
alice.like(1, :target => @status)
|
||||
@status.reload.likes.first.positive.should == true
|
||||
end
|
||||
|
||||
it "should be able to like on a contact's status" do
|
||||
bob.like(0, :post => @status)
|
||||
bob.like(0, :target => @status)
|
||||
@status.reload.dislikes.first.positive.should == false
|
||||
end
|
||||
|
||||
it "does not allow multiple likes" do
|
||||
lambda {
|
||||
alice.like(1, :post => @status)
|
||||
alice.like(0, :post => @status)
|
||||
alice.like(1, :target => @status)
|
||||
alice.like(0, :target => @status)
|
||||
}.should raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe '#notification_type' do
|
||||
before do
|
||||
@like = @alice.like(1, :post => @status)
|
||||
@like = @alice.like(1, :target => @status)
|
||||
end
|
||||
|
||||
it 'should be notifications liked if you are the post owner' do
|
||||
|
|
@ -59,9 +59,16 @@ describe Like do
|
|||
describe 'counter cache' do
|
||||
it 'increments the counter cache on its post' do
|
||||
lambda {
|
||||
@alice.like(1, :post => @status)
|
||||
@alice.like(1, :target => @status)
|
||||
}.should change{ @status.reload.likes_count }.by(1)
|
||||
end
|
||||
|
||||
it 'increments the counter cache on its comment' do
|
||||
comment = Factory(:comment, :post => @status)
|
||||
lambda {
|
||||
@alice.like(1, :target => comment)
|
||||
}.should change{ comment.reload.likes_count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'xml' do
|
||||
|
|
@ -70,7 +77,7 @@ describe Like do
|
|||
@liker_aspect = @liker.aspects.create(:name => "dummies")
|
||||
connect_users(alice, @alices_aspect, @liker, @liker_aspect)
|
||||
@post = alice.post :status_message, :text => "huhu", :to => @alices_aspect.id
|
||||
@like = @liker.like 0, :post => @post
|
||||
@like = @liker.like 0, :target => @post
|
||||
@xml = @like.to_xml.to_s
|
||||
end
|
||||
it 'serializes the sender handle' do
|
||||
|
|
@ -87,7 +94,7 @@ describe Like do
|
|||
@marshalled_like.author.should == @liker.person
|
||||
end
|
||||
it 'marshals the post' do
|
||||
@marshalled_like.post.should == @post
|
||||
@marshalled_like.target.should == @post
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -98,11 +105,11 @@ describe Like do
|
|||
@remote_parent = Factory.create(:status_message, :author => @remote_raphael)
|
||||
@local_parent = @local_luke.post :status_message, :text => "foobar", :to => @local_luke.aspects.first
|
||||
|
||||
@object_by_parent_author = @local_luke.like(1, :post => @local_parent)
|
||||
@object_by_recipient = @local_leia.build_like(:positive => 1, :post => @local_parent)
|
||||
@object_by_parent_author = @local_luke.like(1, :target => @local_parent)
|
||||
@object_by_recipient = @local_leia.build_like(:positive => 1, :target => @local_parent)
|
||||
@dup_object_by_parent_author = @object_by_parent_author.dup
|
||||
|
||||
@object_on_remote_parent = @local_luke.like(0, :post => @remote_parent)
|
||||
@object_on_remote_parent = @local_luke.like(0, :target => @remote_parent)
|
||||
end
|
||||
it_should_behave_like 'it is relayable'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -96,8 +96,8 @@ describe Notification do
|
|||
it 'concatinates the like notifications' do
|
||||
p = Factory(:status_message, :author => @user.person)
|
||||
person2 = Factory(:person)
|
||||
notification = Notification.notify(@user, Factory(:like, :author => @person, :post => p), @person)
|
||||
notification2 = Notification.notify(@user, Factory(:like, :author => person2, :post => p), person2)
|
||||
notification = Notification.notify(@user, Factory(:like, :author => @person, :target => p), @person)
|
||||
notification2 = Notification.notify(@user, Factory(:like, :author => person2, :target => p), person2)
|
||||
notification.id.should == notification2.id
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -569,8 +569,8 @@ describe User do
|
|||
before do
|
||||
@message = alice.post(:status_message, :text => "cool", :to => alice.aspects.first)
|
||||
@message2 = bob.post(:status_message, :text => "uncool", :to => bob.aspects.first)
|
||||
@like = alice.like(true, :post => @message)
|
||||
@like2 = bob.like(true, :post => @message)
|
||||
@like = alice.like(true, :target => @message)
|
||||
@like2 = bob.like(true, :target => @message)
|
||||
end
|
||||
|
||||
describe '#like_for' do
|
||||
|
|
|
|||
Loading…
Reference in a new issue