mirror of
https://github.com/diaspora/diaspora.git
synced 2026-01-08 22:58:08 -05:00
Introduce like-interactions.js
Adapt to latest development User likes Set css class for inline likes on comment Re-set participation on comment likes Co-authored-by: Thorsten Claus <ThorstenClaus@web.de>
This commit is contained in:
@@ -12,12 +12,17 @@ app.collections.Comments = Backbone.Collection.extend({
|
||||
|
||||
make : function(text) {
|
||||
var self = this;
|
||||
var comment = new app.models.Comment({ "text": text });
|
||||
var comment = new app.models.Comment({"text": text}, {post: this.post});
|
||||
|
||||
var deferred = comment.save({}, {
|
||||
url: "/posts/"+ this.post.id +"/comments",
|
||||
success: function() {
|
||||
comment.set({author: app.currentUser.toJSON(), parent: self.post });
|
||||
|
||||
// Need interactions after make
|
||||
comment.interactions = new app.models.Post.LikeInteractions(
|
||||
_.extend({comment: comment, post: self.post}, comment.get("interactions"))
|
||||
);
|
||||
self.add(comment);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4,10 +4,11 @@ app.collections.Likes = Backbone.Collection.extend({
|
||||
model: app.models.Like,
|
||||
|
||||
initialize : function(models, options) {
|
||||
this.url = (options.post != null) ?
|
||||
// A comment- like has a post reference and a comment reference
|
||||
this.url = (options.comment != null) ?
|
||||
// not delegating to post.url() because when it is in a stream collection it delegates to that url
|
||||
"/posts/" + options.post.id + "/likes" :
|
||||
"/comments/" + options.comment.id + "/likes";
|
||||
"/comments/" + options.comment.id + "/likes" :
|
||||
"/posts/" + options.post.id + "/likes";
|
||||
}
|
||||
});
|
||||
// @license-end
|
||||
|
||||
@@ -3,51 +3,15 @@
|
||||
app.models.Comment = Backbone.Model.extend({
|
||||
urlRoot: "/comments",
|
||||
|
||||
initialize: function() {
|
||||
this.likes = new app.collections.Likes(this.get("likes"), {comment: this});
|
||||
},
|
||||
|
||||
// Copied from Post.Interaction. To be merged in an "interactable" class once comments can be commented too
|
||||
likesCount: function() {
|
||||
return this.get("likes_count");
|
||||
},
|
||||
|
||||
userLike: function() {
|
||||
return this.likes.select(function(like) {
|
||||
return like.get("author") && like.get("author").guid === app.currentUser.get("guid");
|
||||
})[0];
|
||||
},
|
||||
|
||||
toggleLike: function() {
|
||||
if (this.userLike()) {
|
||||
this.unlike();
|
||||
} else {
|
||||
this.like();
|
||||
}
|
||||
},
|
||||
|
||||
like: function() {
|
||||
var self = this;
|
||||
this.likes.create({}, {
|
||||
success: function() {
|
||||
self.post.set({participation: true});
|
||||
self.trigger("change");
|
||||
self.set({"likes_count": self.get("likes_count") + 1});
|
||||
self.likes.trigger("change");
|
||||
},
|
||||
error: function(model, response) {
|
||||
app.flashMessages.handleAjaxError(response);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
unlike: function() {
|
||||
var self = this;
|
||||
this.userLike().destroy({success: function() {
|
||||
self.trigger("change");
|
||||
self.set({"likes_count": self.get("likes_count") - 1});
|
||||
self.likes.trigger("change");
|
||||
}});
|
||||
initialize: function(model, options) {
|
||||
options = options || {};
|
||||
this.post = model.post || options.post || this.collection.post;
|
||||
this.interactions = new app.models.Post.LikeInteractions(
|
||||
_.extend({comment: this, post: this.post}, this.get("interactions"))
|
||||
);
|
||||
this.likes = this.interactions.likes;
|
||||
this.likesCount = this.attributes.likes_count;
|
||||
this.userLike = this.interactions.userLike();
|
||||
}
|
||||
});
|
||||
// @license-end
|
||||
|
||||
@@ -1,75 +1,29 @@
|
||||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||
|
||||
//require ../post
|
||||
//= require ./like_interactions
|
||||
|
||||
app.models.Post.Interactions = Backbone.Model.extend({
|
||||
initialize : function(options){
|
||||
app.models.Post.Interactions = app.models.Post.LikeInteractions.extend({
|
||||
initialize: function(options) {
|
||||
app.models.Post.LikeInteractions.prototype.initialize.apply(this, arguments);
|
||||
this.post = options.post;
|
||||
this.comments = new app.collections.Comments(this.get("comments"), {post : this.post});
|
||||
this.likes = new app.collections.Likes(this.get("likes"), {post : this.post});
|
||||
this.reshares = new app.collections.Reshares(this.get("reshares"), {post : this.post});
|
||||
this.comments = new app.collections.Comments(this.get("comments"), {post: this.post});
|
||||
this.reshares = new app.collections.Reshares(this.get("reshares"), {post: this.post});
|
||||
},
|
||||
|
||||
likesCount : function(){
|
||||
return this.get("likes_count");
|
||||
},
|
||||
|
||||
resharesCount : function(){
|
||||
resharesCount: function() {
|
||||
return this.get("reshares_count");
|
||||
},
|
||||
|
||||
commentsCount : function(){
|
||||
commentsCount: function() {
|
||||
return this.get("comments_count");
|
||||
},
|
||||
|
||||
userLike : function(){
|
||||
return this.likes.select(function(like){
|
||||
return like.get("author") && like.get("author").guid === app.currentUser.get("guid");
|
||||
})[0];
|
||||
},
|
||||
|
||||
userReshare : function(){
|
||||
userReshare: function() {
|
||||
return this.reshares.select(function(reshare){
|
||||
return reshare.get("author") && reshare.get("author").guid === app.currentUser.get("guid");
|
||||
})[0];
|
||||
},
|
||||
|
||||
toggleLike : function() {
|
||||
if(this.userLike()) {
|
||||
this.unlike();
|
||||
} else {
|
||||
this.like();
|
||||
}
|
||||
},
|
||||
|
||||
like : function() {
|
||||
var self = this;
|
||||
this.likes.create({}, {
|
||||
success: function() {
|
||||
self.post.set({participation: true});
|
||||
self.trigger("change");
|
||||
self.set({"likes_count" : self.get("likes_count") + 1});
|
||||
self.likes.trigger("change");
|
||||
},
|
||||
error: function(model, response) {
|
||||
app.flashMessages.handleAjaxError(response);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
unlike : function() {
|
||||
var self = this;
|
||||
this.userLike().destroy({success : function() {
|
||||
self.post.set({participation: false});
|
||||
self.trigger('change');
|
||||
self.set({"likes_count" : self.get("likes_count") - 1});
|
||||
self.likes.trigger("change");
|
||||
},
|
||||
error: function(model, response) {
|
||||
app.flashMessages.handleAjaxError(response);
|
||||
}});
|
||||
},
|
||||
|
||||
comment: function(text, options) {
|
||||
var self = this;
|
||||
options = options || {};
|
||||
@@ -109,7 +63,7 @@ app.models.Post.Interactions = Backbone.Model.extend({
|
||||
});
|
||||
},
|
||||
|
||||
userCanReshare : function(){
|
||||
userCanReshare: function() {
|
||||
var isReshare = this.post.get("post_type") === "Reshare"
|
||||
, rootExists = (isReshare ? this.post.get("root") : true)
|
||||
, publicPost = this.post.get("public")
|
||||
|
||||
57
app/assets/javascripts/app/models/post/like_interactions.js
Normal file
57
app/assets/javascripts/app/models/post/like_interactions.js
Normal file
@@ -0,0 +1,57 @@
|
||||
// This class contains code extracted from interactions.js to factorize likes management between posts and comments
|
||||
|
||||
app.models.Post.LikeInteractions = Backbone.Model.extend({
|
||||
|
||||
initialize: function(options) {
|
||||
this.likes = new app.collections.Likes(this.get("likes"), options);
|
||||
this.post = options.post;
|
||||
},
|
||||
|
||||
likesCount: function() {
|
||||
return this.get("likes_count");
|
||||
},
|
||||
|
||||
userLike: function() {
|
||||
return this.likes.select(function(like) {
|
||||
return like.get("author") && like.get("author").guid === app.currentUser.get("guid");
|
||||
})[0];
|
||||
},
|
||||
|
||||
toggleLike: function() {
|
||||
if (this.userLike()) {
|
||||
this.unlike();
|
||||
} else {
|
||||
this.like();
|
||||
}
|
||||
},
|
||||
|
||||
like: function() {
|
||||
var self = this;
|
||||
this.likes.create({}, {
|
||||
success: function() {
|
||||
self.post.set({participation: true});
|
||||
self.trigger("change");
|
||||
self.set({"likes_count": self.get("likes_count") + 1});
|
||||
self.likes.trigger("change");
|
||||
},
|
||||
error: function(model, response) {
|
||||
app.flashMessages.handleAjaxError(response);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
unlike: function() {
|
||||
var self = this;
|
||||
this.userLike().destroy({
|
||||
success: function() {
|
||||
// TODO: If user unlikes a post and the last like of all comments, then set participation to false
|
||||
self.post.set({participation: false});
|
||||
self.trigger("change");
|
||||
self.set({"likes_count": self.get("likes_count") - 1});
|
||||
self.likes.trigger("change");
|
||||
},
|
||||
error: function(model, response) {
|
||||
app.flashMessages.handleAjaxError(response);
|
||||
}});
|
||||
}
|
||||
});
|
||||
@@ -6,7 +6,11 @@ app.views.Comment = app.views.Content.extend({
|
||||
className : "comment media",
|
||||
tooltipSelector: "time",
|
||||
|
||||
events : function() {
|
||||
subviews: {
|
||||
".likes-on-comment": "likesInfoView"
|
||||
},
|
||||
|
||||
events: function() {
|
||||
return _.extend({}, app.views.Content.prototype.events, {
|
||||
"click .comment_delete": "destroyModel",
|
||||
"click .comment_report": "report",
|
||||
@@ -14,33 +18,40 @@ app.views.Comment = app.views.Content.extend({
|
||||
});
|
||||
},
|
||||
|
||||
initialize : function(options){
|
||||
initialize: function(options) {
|
||||
this.templateName = options.templateName || this.templateName;
|
||||
this.model.interactions.on("change", this.render, this);
|
||||
this.model.on("change", this.render, this);
|
||||
},
|
||||
|
||||
presenter : function() {
|
||||
presenter: function() {
|
||||
return _.extend(this.defaultPresenter(), {
|
||||
canRemove: this.canRemove(),
|
||||
text: app.helpers.textFormatter(this.model.get("text"), this.model.get("mentioned_people"))
|
||||
text: app.helpers.textFormatter(this.model.get("text"), this.model.get("mentioned_people")),
|
||||
likesCount: this.model.attributes.likesCount,
|
||||
userLike: this.model.interactions.userLike()
|
||||
});
|
||||
},
|
||||
|
||||
ownComment : function() {
|
||||
ownComment: function() {
|
||||
return app.currentUser.authenticated() && this.model.get("author").diaspora_id === app.currentUser.get("diaspora_id");
|
||||
},
|
||||
|
||||
postOwner : function() {
|
||||
postOwner: function() {
|
||||
return app.currentUser.authenticated() && this.model.get("parent").author.diaspora_id === app.currentUser.get("diaspora_id");
|
||||
},
|
||||
|
||||
canRemove : function() {
|
||||
canRemove: function() {
|
||||
return app.currentUser.authenticated() && (this.ownComment() || this.postOwner());
|
||||
},
|
||||
|
||||
toggleLike: function(evt) {
|
||||
if (evt) { evt.preventDefault(); }
|
||||
this.model.toggleLike();
|
||||
this.model.interactions.toggleLike();
|
||||
},
|
||||
|
||||
likesInfoView: function() {
|
||||
return new app.views.LikesInfo({model: this.model});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ app.views.StreamPost = app.views.Post.extend({
|
||||
subviews : {
|
||||
".feedback": "feedbackView",
|
||||
".comments": "commentStreamView",
|
||||
".likes": "likesInfoView",
|
||||
".likes-on-post": "likesInfoView",
|
||||
".reshares": "resharesInfoView",
|
||||
".post-controls": "postControlsView",
|
||||
".post-content": "postContentView",
|
||||
|
||||
@@ -46,5 +46,8 @@
|
||||
{{~/if~}}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="likes likes-on-comment"> </div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
{{#unless preview}}
|
||||
<div class="feedback nsfw-hidden"> </div>
|
||||
<div class="likes nsfw-hidden"> </div>
|
||||
<div class="likes likes-on-post nsfw-hidden"> </div>
|
||||
<div class="reshares nsfw-hidden"> </div>
|
||||
<div class="comments nsfw-hidden"> </div>
|
||||
{{/unless}}
|
||||
|
||||
@@ -33,7 +33,7 @@ module Api
|
||||
post = post_service.find!(params.require(:post_id))
|
||||
raise ActiveRecord::RecordInvalid unless post.public? || private_read?
|
||||
|
||||
like_service.create(params[:post_id])
|
||||
like_service.create_for_post(params[:post_id])
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
if e.message == "Validation failed: Target has already been taken"
|
||||
return render_error 409, "Like already exists"
|
||||
|
||||
@@ -41,7 +41,12 @@ class LikesController < ApplicationController
|
||||
end
|
||||
|
||||
def index
|
||||
render json: like_service.find_for_post(params[:post_id])
|
||||
like = if params[:post_id]
|
||||
like_service.find_for_post(params[:post_id])
|
||||
else
|
||||
like_service.find_for_comment(params[:comment_id])
|
||||
end
|
||||
render json: like
|
||||
.includes(author: :profile)
|
||||
.as_api_response(:backbone)
|
||||
end
|
||||
|
||||
@@ -17,6 +17,10 @@ module User::SocialActions
|
||||
end
|
||||
end
|
||||
|
||||
def like_comment!(target, opts={})
|
||||
Like::Generator.new(self, target).create!(opts)
|
||||
end
|
||||
|
||||
def participate_in_poll!(target, answer, opts={})
|
||||
PollParticipation::Generator.new(self, target, answer).create!(opts).tap do
|
||||
update_or_create_participation!(target)
|
||||
|
||||
@@ -8,7 +8,8 @@ class CommentPresenter < BasePresenter
|
||||
text: message.plain_text_for_json,
|
||||
author: author.as_api_response(:backbone),
|
||||
created_at: created_at,
|
||||
mentioned_people: mentioned_people.as_api_response(:backbone)
|
||||
mentioned_people: mentioned_people.as_api_response(:backbone),
|
||||
interactions: build_interactions_json
|
||||
}
|
||||
end
|
||||
|
||||
@@ -19,11 +20,25 @@ class CommentPresenter < BasePresenter
|
||||
author: PersonPresenter.new(author).as_api_json,
|
||||
created_at: created_at,
|
||||
mentioned_people: build_mentioned_people_json,
|
||||
reported: current_user.present? && reports.where(user: current_user).exists?
|
||||
reported: current_user.present? && reports.where(user: current_user).exists?,
|
||||
interactions: build_interactions_json
|
||||
}
|
||||
end
|
||||
|
||||
def build_interactions_json
|
||||
{
|
||||
likes: as_api(likes),
|
||||
likes_count: likes_count
|
||||
}
|
||||
end
|
||||
|
||||
def build_mentioned_people_json
|
||||
mentioned_people.map {|m| PersonPresenter.new(m).as_api_json }
|
||||
end
|
||||
|
||||
def as_api(collection)
|
||||
collection.includes(author: :profile).map {|element|
|
||||
element.as_api_response(:backbone)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,8 +14,8 @@ class CommentService
|
||||
post_service.find!(post_id).comments.for_a_stream
|
||||
end
|
||||
|
||||
def find!(comment_guid)
|
||||
Comment.find_by!(guid: comment_guid)
|
||||
def find!(id_or_guid)
|
||||
Comment.find_by!(comment_key(id_or_guid) => id_or_guid)
|
||||
end
|
||||
|
||||
def destroy(comment_id)
|
||||
@@ -45,6 +45,11 @@ class CommentService
|
||||
|
||||
attr_reader :user
|
||||
|
||||
# We can assume a guid is at least 16 characters long as we have guids set to hex(8) since we started using them.
|
||||
def comment_key(id_or_guid)
|
||||
id_or_guid.to_s.length < 16 ? :id : :guid
|
||||
end
|
||||
|
||||
def post_service
|
||||
@post_service ||= PostService.new(user)
|
||||
end
|
||||
|
||||
@@ -12,7 +12,8 @@ class LikeService
|
||||
|
||||
def create_for_comment(comment_id)
|
||||
comment = comment_service.find!(comment_id)
|
||||
user.like!(comment)
|
||||
post_service.find!(comment.commentable_id) # checks implicit for visible posts
|
||||
user.like_comment!(comment)
|
||||
end
|
||||
|
||||
def destroy(like_id)
|
||||
@@ -30,6 +31,13 @@ class LikeService
|
||||
user ? likes.order(Arel.sql("author_id = #{user.person.id} DESC")) : likes
|
||||
end
|
||||
|
||||
def find_for_comment(comment_id)
|
||||
comment = comment_service.find!(comment_id)
|
||||
post_service.find!(comment.post.id) # checks implicit for visible posts
|
||||
likes = comment.likes
|
||||
user ? likes.order(Arel.sql("author_id = #{user.person.id} DESC")) : likes
|
||||
end
|
||||
|
||||
def unlike_post(post_id)
|
||||
likes = post_service.find!(post_id).likes
|
||||
likes = likes.order(Arel.sql("author_id = #{user.person.id} DESC"))
|
||||
@@ -41,6 +49,17 @@ class LikeService
|
||||
end
|
||||
end
|
||||
|
||||
def unlike_comment(comment_id)
|
||||
likes = comment_service.find!(comment_id).likes
|
||||
likes = likes.order(Arel.sql("author_id = #{user.person.id} DESC"))
|
||||
if !likes.empty? && user.owns?(likes[0])
|
||||
user.retract(likes[0])
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :user
|
||||
|
||||
@@ -101,9 +101,16 @@
|
||||
"type": "array",
|
||||
"items": { "$ref": "https://diaspora.software/api/v1/schema.json#/definitions/short_profile" }
|
||||
},
|
||||
"reported": { "type": "boolean" }
|
||||
"reported": { "type": "boolean" },
|
||||
"interactions": {
|
||||
"type": "object",
|
||||
"properties" : {
|
||||
"likes" : { "$ref": "https://diaspora.software/api/v1/schema.json#/definitions/likes"},
|
||||
"likes_count" : { "type": "integer"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["guid", "created_at", "author", "body", "reported"],
|
||||
"required": ["guid", "created_at", "author", "body", "reported", "interactions"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
|
||||
@@ -61,9 +61,9 @@ describe Api::V1::LikesController do
|
||||
end
|
||||
|
||||
it "succeeds in getting post with likes" do
|
||||
like_service(bob).create(@status.guid)
|
||||
like_service(auth.user).create(@status.guid)
|
||||
like_service(alice).create(@status.guid)
|
||||
like_service(bob).create_for_post(@status.guid)
|
||||
like_service(auth.user).create_for_post(@status.guid)
|
||||
like_service(alice).create_for_post(@status.guid)
|
||||
get(
|
||||
api_v1_post_likes_path(post_id: @status.guid),
|
||||
params: {access_token: access_token_minimum_scopes}
|
||||
@@ -112,7 +112,7 @@ describe Api::V1::LikesController do
|
||||
|
||||
describe "#create" do
|
||||
context "with right post id" do
|
||||
it "succeeeds in liking post" do
|
||||
it "succeeds in liking post" do
|
||||
post(
|
||||
api_v1_post_likes_path(post_id: @status.guid),
|
||||
params: {access_token: access_token}
|
||||
@@ -181,7 +181,7 @@ describe Api::V1::LikesController do
|
||||
|
||||
describe "#delete" do
|
||||
before do
|
||||
like_service.create(@status.guid)
|
||||
like_service.create_for_post(@status.guid)
|
||||
end
|
||||
|
||||
context "with right post id" do
|
||||
@@ -225,7 +225,7 @@ describe Api::V1::LikesController do
|
||||
|
||||
context "with improper credentials" do
|
||||
it "fails at unliking private post without private:read" do
|
||||
like_service(auth_public_only.user).create(@private_status.guid)
|
||||
like_service(auth_public_only.user).create_for_post(@private_status.guid)
|
||||
delete(
|
||||
api_v1_post_likes_path(post_id: @private_status.guid),
|
||||
params: {access_token: access_token}
|
||||
@@ -234,7 +234,7 @@ describe Api::V1::LikesController do
|
||||
end
|
||||
|
||||
it "fails in unliking post without interactions" do
|
||||
like_service(auth_minimum_scopes.user).create(@status.guid)
|
||||
like_service(auth_minimum_scopes.user).create_for_post(@status.guid)
|
||||
delete(
|
||||
api_v1_post_likes_path(post_id: @status.guid),
|
||||
params: {access_token: access_token_minimum_scopes}
|
||||
|
||||
@@ -43,13 +43,15 @@ var factory = {
|
||||
|
||||
comment : function(overrides) {
|
||||
var defaultAttrs = {
|
||||
"created_at" : "2012-01-04T00:55:30Z",
|
||||
"author" : this.author(),
|
||||
"guid" : this.guid(),
|
||||
"id" : this.id.next(),
|
||||
"text" : "This is a comment!"
|
||||
"created_at": "2012-01-04T00:55:30Z",
|
||||
"author": this.author(),
|
||||
"guid": this.guid(),
|
||||
"id": this.id.next(),
|
||||
"text": "This is a comment!"
|
||||
};
|
||||
|
||||
overrides = overrides || {};
|
||||
overrides.post = this.post();
|
||||
return new app.models.Comment(_.extend(defaultAttrs, overrides));
|
||||
},
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ describe LikesPresenter do
|
||||
to: "all"
|
||||
)
|
||||
bobs_like_service = LikeService.new(bob)
|
||||
like = bobs_like_service.create(@status.guid)
|
||||
like = bobs_like_service.create_for_post(@status.guid)
|
||||
@presenter = LikesPresenter.new(like, bob)
|
||||
end
|
||||
|
||||
|
||||
@@ -2,67 +2,129 @@
|
||||
|
||||
describe LikeService do
|
||||
let(:post) { alice.post(:status_message, text: "hello", to: alice.aspects.first) }
|
||||
let(:alice_comment) { CommentService.new(alice).create(post.id, "This is a wonderful post") }
|
||||
let(:bobs_comment) { CommentService.new(bob).create(post.id, "My post was better than yours") }
|
||||
|
||||
describe "#create" do
|
||||
describe "#create_for_post" do
|
||||
it "creates a like on my own post" do
|
||||
expect {
|
||||
LikeService.new(alice).create(post.id)
|
||||
LikeService.new(alice).create_for_post(post.id)
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "creates a like on a post of a contact" do
|
||||
expect {
|
||||
LikeService.new(bob).create(post.id)
|
||||
LikeService.new(bob).create_for_post(post.id)
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "attaches the like to the post" do
|
||||
like = LikeService.new(alice).create(post.id)
|
||||
like = LikeService.new(alice).create_for_post(post.id)
|
||||
expect(post.likes.first.id).to eq(like.id)
|
||||
end
|
||||
|
||||
it "fails if the post does not exist" do
|
||||
expect {
|
||||
LikeService.new(bob).create("unknown id")
|
||||
LikeService.new(bob).create_for_post("unknown id")
|
||||
}.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
it "fails if the user can't see the post" do
|
||||
expect {
|
||||
LikeService.new(eve).create(post.id)
|
||||
LikeService.new(eve).create_for_post(post.id)
|
||||
}.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
it "fails if the user already liked the post" do
|
||||
LikeService.new(alice).create(post.id)
|
||||
LikeService.new(alice).create_for_post(post.id)
|
||||
expect {
|
||||
LikeService.new(alice).create(post.id)
|
||||
LikeService.new(alice).create_for_post(post.id)
|
||||
}.to raise_error ActiveRecord::RecordInvalid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create_for_comment" do
|
||||
it "creates a like on a posts comment" do
|
||||
expect {
|
||||
LikeService.new(alice).create_for_comment(alice_comment.id)
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "creates a like on someone else comment" do
|
||||
expect {
|
||||
LikeService.new(alice).create_for_comment(bobs_comment.id)
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
it "attaches the like to the comment" do
|
||||
like = LikeService.new(alice).create_for_comment(bobs_comment.id)
|
||||
expect(bobs_comment.likes.first.id).to eq(like.id)
|
||||
end
|
||||
|
||||
it "fails if comment does not exist" do
|
||||
expect {
|
||||
LikeService.new(alice).create_for_comment("unknown_id")
|
||||
}.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
it "fails if user cant see post and its comments" do
|
||||
expect {
|
||||
LikeService.new(eve).create_for_comment(bobs_comment.id)
|
||||
}.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
it "fails if user already liked the comment" do
|
||||
LikeService.new(alice).create_for_comment(bobs_comment.id)
|
||||
expect {
|
||||
LikeService.new(alice).create_for_comment(bobs_comment.id)
|
||||
}.to raise_error ActiveRecord::RecordInvalid
|
||||
end
|
||||
end
|
||||
|
||||
describe "#destroy" do
|
||||
let(:like) { LikeService.new(bob).create(post.id) }
|
||||
context "for post like" do
|
||||
let(:like) { LikeService.new(bob).create_for_post(post.id) }
|
||||
|
||||
it "lets the user destroy their own like" do
|
||||
result = LikeService.new(bob).destroy(like.id)
|
||||
expect(result).to be_truthy
|
||||
it "lets the user destroy their own like" do
|
||||
result = LikeService.new(bob).destroy(like.id)
|
||||
expect(result).to be_truthy
|
||||
end
|
||||
|
||||
it "doesn't let the parent author destroy others likes" do
|
||||
result = LikeService.new(alice).destroy(like.id)
|
||||
expect(result).to be_falsey
|
||||
end
|
||||
|
||||
it "doesn't let someone destroy others likes" do
|
||||
result = LikeService.new(eve).destroy(like.id)
|
||||
expect(result).to be_falsey
|
||||
end
|
||||
|
||||
it "fails if the like doesn't exist" do
|
||||
expect {
|
||||
LikeService.new(bob).destroy("unknown id")
|
||||
}.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
end
|
||||
|
||||
it "doesn't let the parent author destroy others likes" do
|
||||
result = LikeService.new(alice).destroy(like.id)
|
||||
expect(result).to be_falsey
|
||||
end
|
||||
context "for comment like" do
|
||||
let(:like) { LikeService.new(bob).create_for_comment(alice_comment.id) }
|
||||
|
||||
it "doesn't let someone destroy others likes" do
|
||||
result = LikeService.new(eve).destroy(like.id)
|
||||
expect(result).to be_falsey
|
||||
end
|
||||
it "let the user destroy its own comment like" do
|
||||
result = LikeService.new(bob).destroy(like.id)
|
||||
expect(result).to be_truthy
|
||||
end
|
||||
|
||||
it "fails if the like doesn't exist" do
|
||||
expect {
|
||||
LikeService.new(bob).destroy("unknown id")
|
||||
}.to raise_error ActiveRecord::RecordNotFound
|
||||
it "doesn't let the parent author destroy other comment likes" do
|
||||
result = LikeService.new(alice).destroy(like.id)
|
||||
expect(result).to be_falsey
|
||||
end
|
||||
|
||||
it "fails if the like doesn't exist" do
|
||||
expect {
|
||||
LikeService.new(alice).destroy("unknown id")
|
||||
}.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -70,17 +132,17 @@ describe LikeService do
|
||||
context "with user" do
|
||||
it "returns likes for a public post" do
|
||||
post = alice.post(:status_message, text: "hello", public: true)
|
||||
like = LikeService.new(alice).create(post.id)
|
||||
like = LikeService.new(alice).create_for_post(post.id)
|
||||
expect(LikeService.new(eve).find_for_post(post.id)).to include(like)
|
||||
end
|
||||
|
||||
it "returns likes for a visible private post" do
|
||||
like = LikeService.new(alice).create(post.id)
|
||||
like = LikeService.new(alice).create_for_post(post.id)
|
||||
expect(LikeService.new(bob).find_for_post(post.id)).to include(like)
|
||||
end
|
||||
|
||||
it "doesn't return likes for a private post the user can not see" do
|
||||
LikeService.new(alice).create(post.id)
|
||||
LikeService.new(alice).create_for_post(post.id)
|
||||
expect {
|
||||
LikeService.new(eve).find_for_post(post.id)
|
||||
}.to raise_error ActiveRecord::RecordNotFound
|
||||
@@ -88,7 +150,7 @@ describe LikeService do
|
||||
|
||||
it "returns the user's like first" do
|
||||
post = alice.post(:status_message, text: "hello", public: true)
|
||||
[alice, bob, eve].map {|user| LikeService.new(user).create(post.id) }
|
||||
[alice, bob, eve].map {|user| LikeService.new(user).create_for_post(post.id) }
|
||||
|
||||
[alice, bob, eve].each do |user|
|
||||
expect(
|
||||
@@ -101,12 +163,12 @@ describe LikeService do
|
||||
context "without user" do
|
||||
it "returns likes for a public post" do
|
||||
post = alice.post(:status_message, text: "hello", public: true)
|
||||
like = LikeService.new(alice).create(post.id)
|
||||
like = LikeService.new(alice).create_for_post(post.id)
|
||||
expect(LikeService.new.find_for_post(post.id)).to include(like)
|
||||
end
|
||||
|
||||
it "doesn't return likes a for private post" do
|
||||
LikeService.new(alice).create(post.id)
|
||||
LikeService.new(alice).create_for_post(post.id)
|
||||
expect {
|
||||
LikeService.new.find_for_post(post.id)
|
||||
}.to raise_error Diaspora::NonPublic
|
||||
@@ -115,15 +177,68 @@ describe LikeService do
|
||||
|
||||
it "returns all likes of a post" do
|
||||
post = alice.post(:status_message, text: "hello", public: true)
|
||||
likes = [alice, bob, eve].map {|user| LikeService.new(user).create(post.id) }
|
||||
likes = [alice, bob, eve].map {|user| LikeService.new(user).create_for_post(post.id) }
|
||||
|
||||
expect(LikeService.new.find_for_post(post.id)).to match_array(likes)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#find_for_comment" do
|
||||
context "with user" do
|
||||
it "returns likes for a public post comment" do
|
||||
post = alice.post(:status_message, text: "hello", public: true)
|
||||
comment = CommentService.new(bob).create(post.id, "Hello comment")
|
||||
like = LikeService.new(alice).create_for_comment(comment.id)
|
||||
expect(LikeService.new(eve).find_for_comment(comment.id)).to include(like)
|
||||
end
|
||||
|
||||
it "returns likes for visible private post comments" do
|
||||
comment = CommentService.new(bob).create(post.id, "Hello comment")
|
||||
like = LikeService.new(alice).create_for_comment(comment.id)
|
||||
expect(LikeService.new(bob).find_for_comment(comment.id)).to include(like)
|
||||
end
|
||||
|
||||
it "doesn't return likes for a posts comment the user can not see" do
|
||||
expect {
|
||||
LikeService.new(eve).find_for_comment(alice_comment.id)
|
||||
}.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
it "returns the user's like first" do
|
||||
post = alice.post(:status_message, text: "hello", public: true)
|
||||
comment = CommentService.new(alice).create(post.id, "I like my own post")
|
||||
|
||||
[alice, bob, eve].map {|user| LikeService.new(user).create_for_comment(comment.id) }
|
||||
[alice, bob, eve].each do |user|
|
||||
expect(
|
||||
LikeService.new(user).find_for_comment(comment.id).first.author.id
|
||||
).to be user.person.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "without user" do
|
||||
it "returns likes for a comment on a public post" do
|
||||
post = alice.post(:status_message, text: "hello", public: true)
|
||||
comment = CommentService.new(bob).create(post.id, "I like my own post")
|
||||
like = LikeService.new(alice).create_for_comment(comment.id)
|
||||
expect(
|
||||
LikeService.new.find_for_comment(comment.id)
|
||||
).to include(like)
|
||||
end
|
||||
|
||||
it "doesn't return likes for a private post comment" do
|
||||
LikeService.new(alice).create_for_comment(alice_comment.id)
|
||||
expect {
|
||||
LikeService.new.find_for_comment(alice_comment.id)
|
||||
}.to raise_error Diaspora::NonPublic
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#unlike_post" do
|
||||
before do
|
||||
LikeService.new(alice).create(post.id)
|
||||
LikeService.new(alice).create_for_post(post.id)
|
||||
end
|
||||
|
||||
it "removes the like to the post" do
|
||||
@@ -131,4 +246,16 @@ describe LikeService do
|
||||
expect(post.likes.length).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#unlike_comment" do
|
||||
it "removes the like for a comment" do
|
||||
comment = CommentService.new(alice).create(post.id, "I like my own post")
|
||||
LikeService.new(alice).create_for_comment(comment.id)
|
||||
expect(comment.likes.length).to eq(1)
|
||||
|
||||
LikeService.new(alice).unlike_comment(comment.id)
|
||||
comment = CommentService.new(alice).find!(comment.id)
|
||||
expect(comment.likes.length).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user