likes/dislikes WIP TODO: better icons, better styling, integration on photo show page
This commit is contained in:
parent
69c0d8e1d9
commit
1b1a23aa8f
26 changed files with 447 additions and 13 deletions
|
|
@ -31,7 +31,7 @@ class AspectsController < ApplicationController
|
|||
@aspect_ids = @aspects.map{|a| a.id}
|
||||
|
||||
@posts = StatusMessage.joins(:aspects).where(:pending => false,
|
||||
:aspects => {:id => @aspect_ids}).includes(:comments, :photos).select('DISTINCT `posts`.*').paginate(
|
||||
:aspects => {:id => @aspect_ids}).includes(:comments, :photos, :likes, :dislikes).select('DISTINCT `posts`.*').paginate(
|
||||
:page => params[:page], :per_page => 15, :order => sort_order + ' DESC')
|
||||
@fakes = PostsFake.new(@posts)
|
||||
|
||||
|
|
|
|||
|
|
@ -37,10 +37,10 @@ class CommentsController < ApplicationController
|
|||
format.mobile{ redirect_to status_message_path(@comment.post_id) }
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => 406
|
||||
render :nothing => true, :status => 422
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => 406
|
||||
render :nothing => true, :status => 422
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
44
app/controllers/likes_controller.rb
Normal file
44
app/controllers/likes_controller.rb
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
class LikesController < ApplicationController
|
||||
include ApplicationHelper
|
||||
before_filter :authenticate_user!
|
||||
|
||||
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, :on => 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 {
|
||||
json = { :post_id => @like.post_id,
|
||||
:html => render_to_string(
|
||||
:partial => 'likes/likes',
|
||||
:locals => {
|
||||
:likes => @like.post.likes,
|
||||
:dislikes => @like.post.dislikes
|
||||
}
|
||||
)
|
||||
}
|
||||
render(:json => json, :status => 201)
|
||||
}
|
||||
format.html { render :nothing => true, :status => 201 }
|
||||
format.mobile { redirect_to status_message_path(@like.post_id) }
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => 422
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => 422
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -111,10 +111,10 @@ class PhotosController < ApplicationController
|
|||
:status => 201}
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => 406
|
||||
render :nothing => true, :status => 422
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => 406
|
||||
render :nothing => true, :status => 422
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
10
app/helpers/likes_helper.rb
Normal file
10
app/helpers/likes_helper.rb
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
module LikesHelper
|
||||
def likes_list likes
|
||||
links = likes.collect { |like| link_to "#{h(like.author.name.titlecase)}", person_path(like.author) }
|
||||
links.join(", ").html_safe
|
||||
end
|
||||
end
|
||||
|
|
@ -50,6 +50,9 @@ module SocketsHelper
|
|||
elsif object.is_a? Comment
|
||||
v = render_to_string(:partial => 'comments/comment', :locals => {:comment => object, :person => object.author})
|
||||
|
||||
elsif object.is_a? Like
|
||||
v = render_to_string(:partial => 'likes/likes', :locals => {:likes => object.post.likes, :dislikes => object.post.dislikes})
|
||||
|
||||
elsif object.is_a? Notification
|
||||
v = render_to_string(:partial => 'notifications/popup', :locals => {:note => object, :person => opts[:actor]})
|
||||
|
||||
|
|
@ -74,6 +77,10 @@ module SocketsHelper
|
|||
|
||||
end
|
||||
|
||||
if object.is_a? Like
|
||||
action_hash[:post_guid] = object.post.guid
|
||||
end
|
||||
|
||||
action_hash[:mine?] = object.author && (object.author.owner_id == uid) if object.respond_to?(:author)
|
||||
|
||||
I18n.locale = old_locale unless user.nil?
|
||||
|
|
|
|||
42
app/models/like.rb
Normal file
42
app/models/like.rb
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
class Like < ActiveRecord::Base
|
||||
require File.join(Rails.root, 'lib/diaspora/web_socket')
|
||||
include ROXML
|
||||
|
||||
include Diaspora::Webhooks
|
||||
include Diaspora::Relayable
|
||||
include Diaspora::Guid
|
||||
|
||||
include Diaspora::Socketable
|
||||
|
||||
xml_attr :positive
|
||||
xml_attr :diaspora_handle
|
||||
|
||||
belongs_to :post
|
||||
belongs_to :author, :class_name => 'Person'
|
||||
|
||||
validates_uniqueness_of :post_id, :scope => :author_id
|
||||
|
||||
def diaspora_handle
|
||||
self.author.diaspora_handle
|
||||
end
|
||||
|
||||
def diaspora_handle= nh
|
||||
self.author = Webfinger.new(nh).fetch
|
||||
end
|
||||
|
||||
def parent_class
|
||||
Post
|
||||
end
|
||||
|
||||
def parent
|
||||
self.post
|
||||
end
|
||||
|
||||
def parent= parent
|
||||
self.post = parent
|
||||
end
|
||||
end
|
||||
|
|
@ -14,6 +14,8 @@ class Post < ActiveRecord::Base
|
|||
xml_attr :created_at
|
||||
|
||||
has_many :comments, :order => 'created_at ASC'
|
||||
has_many :likes, :conditions => '`likes`.`positive` = 1'
|
||||
has_many :dislikes, :conditions => '`likes`.`positive` = 0', :class_name => 'Like'
|
||||
has_many :post_visibilities
|
||||
has_many :aspects, :through => :post_visibilities
|
||||
has_many :mentions, :dependent => :destroy
|
||||
|
|
|
|||
|
|
@ -176,6 +176,32 @@ class User < ActiveRecord::Base
|
|||
comment
|
||||
end
|
||||
|
||||
######## Liking ########
|
||||
def build_like(positive, options = {})
|
||||
like = Like.new(:author_id => self.person.id,
|
||||
:positive => positive,
|
||||
:post => options[:on])
|
||||
like.set_guid
|
||||
#sign like as liker
|
||||
like.author_signature = like.sign_with_key(self.encryption_key)
|
||||
|
||||
if !like.post_id.blank? && person.owns?(like.parent)
|
||||
#sign like as post owner
|
||||
like.parent_author_signature = like.sign_with_key(self.encryption_key)
|
||||
end
|
||||
|
||||
like
|
||||
end
|
||||
|
||||
def liked?(post)
|
||||
[post.likes, post.dislikes].each do |likes|
|
||||
likes.each do |like|
|
||||
return true if like.author_id == self.person.id
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
######### Mailer #######################
|
||||
def mail(job, *args)
|
||||
pref = job.to_s.gsub('Job::Mail', '').underscore
|
||||
|
|
|
|||
17
app/views/likes/_likes.haml
Normal file
17
app/views/likes/_likes.haml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
-# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
-# licensed under the Affero General Public License version 3 or later. See
|
||||
-# the COPYRIGHT file.
|
||||
|
||||
- if likes.length > 0
|
||||
.likes
|
||||
= image_tag('icons/happy_smiley.png')
|
||||
= link_to t('.people_like_this', :count => likes.length), "#", :class => "expand_likes"
|
||||
%span.hidden.likes_list
|
||||
= likes_list(likes)
|
||||
|
||||
- if dislikes.length > 0
|
||||
.dislikes
|
||||
= image_tag('icons/sad_smiley.png')
|
||||
= link_to t('.people_dislike_this', :count => dislikes.length), "#", :class => "expand_dislikes"
|
||||
%span.hidden.dislikes_list
|
||||
= likes_list(dislikes)
|
||||
|
|
@ -66,5 +66,13 @@
|
|||
= t('_comments')
|
||||
|
||||
#photo_stream.stream.show
|
||||
- if (defined?(current_user) && !current_user.liked?(@parent))
|
||||
%span.like_links
|
||||
= link_to t('shared.stream_element.like'), {:controller => "likes", :action => "create", :positive => 'true', :post_id => @parent.id }, :class => "like_it", :remote => true
|
||||
|
|
||||
= link_to t('shared.stream_element.dislike'), {:controller => "likes", :action => "create", :positive => 'false', :post_id => @parent.id }, :class => "dislike_it", :remote => true
|
||||
|
||||
%div{:data=>{:guid=>@parent.id}}
|
||||
.likes_container
|
||||
= render "likes/likes", :post_id => @parent.id, :likes => @parent.likes, :dislikes => @parent.dislikes
|
||||
= render "comments/comments", :post_id => @parent.id, :comments => @parent.comments, :always_expanded => true
|
||||
|
|
|
|||
|
|
@ -32,6 +32,15 @@
|
|||
= link_to(how_long_ago(post), status_message_path(post))
|
||||
|
||||
- unless (defined?(@commenting_disabled) && @commenting_disabled)
|
||||
= link_to t('comments.new_comment.comment').downcase, '#', :class => 'focus_comment_textarea'
|
||||
= link_to t('comments.new_comment.comment'), '#', :class => 'focus_comment_textarea'
|
||||
- if (defined?(current_user) && !current_user.liked?(post))
|
||||
%span.like_links
|
||||
|
|
||||
= link_to t('.like'), {:controller => "likes", :action => "create", :positive => 'true', :post_id => post.id }, :class => "like_it", :remote => true
|
||||
|
|
||||
= link_to t('.dislike'), {:controller => "likes", :action => "create", :positive => 'false', :post_id => post.id }, :class => "dislike_it", :remote => true
|
||||
|
||||
.likes_container
|
||||
= render "likes/likes", :post_id => post.id, :likes => post.likes, :dislikes => post.dislikes, :current_user => current_user
|
||||
|
||||
= render "comments/comments", :post_id => post.id, :comments => post.comments, :current_user => current_user, :condensed => true, :commenting_disabled => (defined?(@commenting_disabled) && @commenting_disabled)
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ en:
|
|||
many: "%{count} comments"
|
||||
other: "%{count} comments"
|
||||
new_comment:
|
||||
comment: "Comment"
|
||||
comment: "comment"
|
||||
commenting: "Commenting..."
|
||||
|
||||
contacts:
|
||||
|
|
@ -262,6 +262,22 @@ en:
|
|||
toggle: "toggle mobile site"
|
||||
public_feed: "Public Diaspora Feed for %{name}"
|
||||
|
||||
|
||||
likes:
|
||||
likes:
|
||||
people_like_this:
|
||||
zero: "no people liked this"
|
||||
one: "1 person liked this"
|
||||
few: "%{count} people liked this"
|
||||
many: "%{count} people liked this"
|
||||
other: "%{count} people liked this"
|
||||
people_dislike_this:
|
||||
zero: "no people disliked this"
|
||||
one: "1 person disliked this"
|
||||
few: "%{count} people disliked this"
|
||||
many: "%{count} people disliked this"
|
||||
other: "%{count} people disliked this"
|
||||
|
||||
notifications:
|
||||
request_accepted: "accepted your share request."
|
||||
new_request: "offered to share with you."
|
||||
|
|
@ -537,6 +553,9 @@ en:
|
|||
contact_list:
|
||||
all_contacts: "All contacts"
|
||||
cannot_remove: "Cannot remove person from last aspect. (If you want to disconnect from this person you must remove contact.)"
|
||||
stream_element:
|
||||
like: "I like this"
|
||||
dislike: "I dislike this"
|
||||
|
||||
status_messages:
|
||||
new:
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ Diaspora::Application.routes.draw do
|
|||
resources :status_messages, :only => [:new, :create, :destroy, :show]
|
||||
resources :comments, :only => [:create]
|
||||
resources :requests, :only => [:destroy, :create]
|
||||
match '/likes' => 'likes#create'
|
||||
resources :likes, :only => [:create]
|
||||
|
||||
match 'tags/:name' => 'tags#show'
|
||||
resources :tags, :only => [:show]
|
||||
|
|
|
|||
21
db/migrate/201110319172136_add_likes.rb
Normal file
21
db/migrate/201110319172136_add_likes.rb
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
class AddLikes < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :likes do |t|
|
||||
t.boolean :positive, :default => true
|
||||
t.integer :post_id
|
||||
t.integer :author_id
|
||||
t.string :guid
|
||||
t.text :author_signature
|
||||
t.text :parent_author_signature
|
||||
t.timestamps
|
||||
end
|
||||
add_index :likes, :guid, :unique => true
|
||||
add_index :likes, :post_id
|
||||
add_foreign_key(:likes, :posts, :dependant => :delete)
|
||||
add_foreign_key(:likes, :people, :column => :author_id, :dependant => :delete)
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :likes
|
||||
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 => 20110319005509) do
|
||||
ActiveRecord::Schema.define(:version => 201110319172136) do
|
||||
|
||||
create_table "aspect_memberships", :force => true do |t|
|
||||
t.integer "aspect_id", :null => false
|
||||
|
|
@ -105,6 +105,21 @@ ActiveRecord::Schema.define(:version => 20110319005509) do
|
|||
add_index "invitations", ["recipient_id"], :name => "index_invitations_on_recipient_id"
|
||||
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.integer "author_id"
|
||||
t.string "guid"
|
||||
t.text "author_signature"
|
||||
t.text "parent_author_signature"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
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"
|
||||
|
||||
create_table "mentions", :force => true do |t|
|
||||
t.integer "post_id", :null => false
|
||||
t.integer "person_id", :null => false
|
||||
|
|
@ -342,6 +357,9 @@ ActiveRecord::Schema.define(:version => 20110319005509) do
|
|||
add_foreign_key "invitations", "users", :name => "invitations_recipient_id_fk", :column => "recipient_id", :dependent => :delete
|
||||
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"
|
||||
add_foreign_key "likes", "posts", :name => "likes_post_id_fk"
|
||||
|
||||
add_foreign_key "notification_actors", "notifications", :name => "notification_actors_notification_id_fk", :dependent => :delete
|
||||
|
||||
add_foreign_key "posts", "people", :name => "posts_author_id_fk", :column => "author_id", :dependent => :delete
|
||||
|
|
|
|||
BIN
public/images/icons/happy_smiley.png
Normal file
BIN
public/images/icons/happy_smiley.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 493 B |
BIN
public/images/icons/sad_smiley.png
Normal file
BIN
public/images/icons/sad_smiley.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 507 B |
|
|
@ -39,6 +39,32 @@ var Stream = {
|
|||
}
|
||||
});
|
||||
|
||||
// like/dislike
|
||||
$stream.delegate("a.expand_likes", "click", function(evt) {
|
||||
evt.preventDefault();
|
||||
$(this).siblings('.likes_list').fadeToggle('fast');
|
||||
});
|
||||
|
||||
$stream.delegate("a.expand_dislikes", "click", function(evt) {
|
||||
evt.preventDefault();
|
||||
$(this).siblings('.dislikes_list').fadeToggle('fast');
|
||||
});
|
||||
|
||||
$(".like_it, .dislike_it").live('ajax:loading', function(data, json, xhr) {
|
||||
$(this).parent().fadeOut('fast');
|
||||
});
|
||||
|
||||
$(".like_it, .dislike_it").live('ajax:success', function(data, json, xhr) {
|
||||
$(this).parent().detach();
|
||||
json = $.parseJSON(json);
|
||||
WebSocketReceiver.processLike(json.post_id, json.html);
|
||||
});
|
||||
|
||||
$('.like_it, .dislike_it').live('ajax:failure', function(data, html, xhr) {
|
||||
Diaspora.widgets.alert.alert('Failed to like/dislike!');
|
||||
$(this).parent().fadeIn('fast');
|
||||
});
|
||||
|
||||
// reshare button action
|
||||
$stream.delegate(".reshare_button", "click", function(evt) {
|
||||
evt.preventDefault();
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@ var WebSocketReceiver = {
|
|||
'my_post?': obj['my_post?']
|
||||
});
|
||||
|
||||
} else if (obj['class']=="likes") {
|
||||
WebSocketReceiver.processLike(obj.post_id, obj.html)
|
||||
|
||||
} else {
|
||||
WebSocketReceiver.processPost(obj['class'], obj.post_id, obj.html, obj.aspect_ids);
|
||||
}
|
||||
|
|
@ -116,6 +119,11 @@ var WebSocketReceiver = {
|
|||
Diaspora.widgets.timeago.updateTimeAgo();
|
||||
},
|
||||
|
||||
processLike: function(postId, html) {
|
||||
var post = $("*[data-guid='"+postId+"']");
|
||||
$(".likes_container", post).fadeOut('fast').html(html).fadeIn('fast');
|
||||
},
|
||||
|
||||
processPost: function(className, postId, html, aspectIds) {
|
||||
if(WebSocketReceiver.onPageForAspects(aspectIds)) {
|
||||
WebSocketReceiver.addPostToStream(postId, html);
|
||||
|
|
|
|||
|
|
@ -563,7 +563,9 @@ header
|
|||
:align right
|
||||
|
||||
ul.comments,
|
||||
ul.show_comments
|
||||
ul.show_comments,
|
||||
div.likes,
|
||||
div.dislikes
|
||||
:margin 0
|
||||
:top 0.5em
|
||||
:padding 0
|
||||
|
|
@ -2320,7 +2322,9 @@ h3,h4
|
|||
:position relative
|
||||
:z-index 10
|
||||
|
||||
ul.show_comments
|
||||
ul.show_comments,
|
||||
div.likes,
|
||||
div.dislikes
|
||||
:margin
|
||||
:bottom -0.5em
|
||||
> li
|
||||
|
|
@ -2852,3 +2856,16 @@ h1.tag
|
|||
.share_with
|
||||
:background
|
||||
:color rgb(245,245,245)
|
||||
|
||||
.likes_container
|
||||
.likes,
|
||||
.dislikes
|
||||
:border-bottom 1px solid white
|
||||
a
|
||||
:padding 1px
|
||||
:vertical-align middle
|
||||
:font-size smaller
|
||||
img
|
||||
:width 12px
|
||||
:height 12px
|
||||
:margin-left 0.5em
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ describe CommentsController do
|
|||
it 'posts no comment' do
|
||||
@user1.should_not_receive(:comment)
|
||||
post :create, comment_hash
|
||||
response.code.should == '406'
|
||||
response.code.should == '422'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
68
spec/controllers/likes_controller_spec.rb
Normal file
68
spec/controllers/likes_controller_spec.rb
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe LikesController do
|
||||
render_views
|
||||
|
||||
before do
|
||||
@user1 = alice
|
||||
@user2 = bob
|
||||
|
||||
@aspect1 = @user1.aspects.first
|
||||
@aspect2 = @user2.aspects.first
|
||||
|
||||
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}"}
|
||||
}
|
||||
context "on my own post" do
|
||||
before do
|
||||
@post = @user1.post :status_message, :text => "AWESOME", :to => @aspect1.id
|
||||
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
|
||||
@post = @user2.post :status_message, :text => "AWESOME", :to => @aspect2.id
|
||||
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, :on => @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
|
||||
end
|
||||
|
|
@ -162,9 +162,9 @@ describe PhotosController do
|
|||
response.code.should == "201"
|
||||
end
|
||||
|
||||
it 'should return a 406 on failure' do
|
||||
it 'should return a 422 on failure' do
|
||||
get :make_profile_photo, :photo_id => @bobs_photo.id
|
||||
response.code.should == "406"
|
||||
response.code.should == "422"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
80
spec/models/like_spec.rb
Normal file
80
spec/models/like_spec.rb
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
require 'spec_helper'
|
||||
require File.join(Rails.root, "spec", "shared_behaviors", "relayable")
|
||||
|
||||
describe Like do
|
||||
before do
|
||||
@alices_aspect = alice.aspects.first
|
||||
@bobs_aspect = bob.aspects.first
|
||||
|
||||
@bob = bob
|
||||
@eve = eve
|
||||
@status = alice.post(:status_message, :text => "hello", :to => @alices_aspect.id)
|
||||
end
|
||||
|
||||
describe 'User#like' do
|
||||
it "should be able to like on one's own status" do
|
||||
alice.like(1, :on => @status)
|
||||
@status.reload.likes.first.positive.should == true
|
||||
end
|
||||
|
||||
it "should be able to like on a contact's status" do
|
||||
bob.like(0, :on => @status)
|
||||
@status.reload.dislikes.first.positive.should == false
|
||||
end
|
||||
|
||||
it "does not allow multiple likes" do
|
||||
lambda {
|
||||
alice.like(1, :on => @status)
|
||||
alice.like(0, :on => @status)
|
||||
}.should raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe 'xml' do
|
||||
before do
|
||||
@liker = Factory.create(:user)
|
||||
@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, :on => @post
|
||||
@xml = @like.to_xml.to_s
|
||||
end
|
||||
it 'serializes the sender handle' do
|
||||
@xml.include?(@liker.diaspora_handle).should be_true
|
||||
end
|
||||
it' serializes the post_guid' do
|
||||
@xml.should include(@post.guid)
|
||||
end
|
||||
describe 'marshalling' do
|
||||
before do
|
||||
@marshalled_like = Like.from_xml(@xml)
|
||||
end
|
||||
it 'marshals the author' do
|
||||
@marshalled_like.author.should == @liker.person
|
||||
end
|
||||
it 'marshals the post' do
|
||||
@marshalled_like.post.should == @post
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'it is relayable' do
|
||||
before do
|
||||
@local_luke, @local_leia, @remote_raphael = set_up_friends
|
||||
@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, :on => @local_parent)
|
||||
@object_by_recipient = @local_leia.build_like(1, :on => @local_parent)
|
||||
@dup_object_by_parent_author = @object_by_parent_author.dup
|
||||
|
||||
@object_on_remote_parent = @local_luke.like(0, :on => @remote_parent)
|
||||
end
|
||||
it_should_behave_like 'it is relayable'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -37,6 +37,16 @@ class User
|
|||
end
|
||||
end
|
||||
|
||||
def like(positive, options ={})
|
||||
fantasy_resque do
|
||||
l = build_like(positive, options)
|
||||
if l.save!
|
||||
Postzord::Dispatch.new(self, l).post
|
||||
end
|
||||
l
|
||||
end
|
||||
end
|
||||
|
||||
def post_at_time(time)
|
||||
p = self.post(:status_message, :text => 'hi', :to => self.aspects.first)
|
||||
p.created_at = time
|
||||
|
|
|
|||
Loading…
Reference in a new issue