diff --git a/app/controllers/likes_controller.rb b/app/controllers/likes_controller.rb index e3f10b43d2445e5173925065327f2bb580716e3d..51c9567a1fc6d9f04ecc0f4421f93471d624c947 100644 --- a/app/controllers/likes_controller.rb +++ b/app/controllers/likes_controller.rb @@ -19,7 +19,7 @@ class LikesController < ApplicationController respond_to do |format| format.html { render :nothing => true, :status => 201 } format.mobile { redirect_to post_path(@like.post_id) } - format.json{ render :json => @like.as_api_response(:backbone), :status => 201 } + format.json{ render :json => @like.parent.as_api_response(:backbone), :status => 201 } end else render :nothing => true, :status => 422 diff --git a/app/views/templates/feedback.jst b/app/views/templates/feedback.jst index c4acbf103f3bfd9fec0a72ea32efa7b72533b7f3..97d1ce36e21ca213fcbd93537c80239c6d482d90 100644 --- a/app/views/templates/feedback.jst +++ b/app/views/templates/feedback.jst @@ -8,7 +8,7 @@ </a> ยท -<% if(public && author.id != current_user.id) { %> +<% if(public && author.id != current_user.id && (post_type == "Reshare" ? root : true)) { %> <a href="#" class="reshare_action" rel='nofollow'> Reshare </a> diff --git a/public/javascripts/app/models/post.js b/public/javascripts/app/models/post.js index 581289b95eefda3474031f00d7a637380da57229..6347248f3daf216b03fc19cb3d584c9db0a167ec 100644 --- a/public/javascripts/app/models/post.js +++ b/public/javascripts/app/models/post.js @@ -15,6 +15,15 @@ app.models.Post = Backbone.Model.extend({ } }, + toggleLike : function() { + var userLike = this.get("user_like") + if(userLike) { + this.unlike() + } else { + this.like() + } + }, + createdAt : function() { return +new Date(this.get("created_at")) / 1000; }, @@ -33,5 +42,14 @@ app.models.Post = Backbone.Model.extend({ } else { return this.get("author"); } + }, + + unlike : function() { + this.get("user_like").destroy(); + this.set({ user_like : null }); + }, + + like : function() { + this.set({ user_like : this.likes.create() }); } }); diff --git a/public/javascripts/app/views/feedback_view.js b/public/javascripts/app/views/feedback_view.js index 9cd8dcf99d0e10bbd0368b9c0e979ae74c501e72..ffc27091ba79cc2e9c7102ab7b4305f1a053e362 100644 --- a/public/javascripts/app/views/feedback_view.js +++ b/public/javascripts/app/views/feedback_view.js @@ -10,35 +10,19 @@ app.views.Feedback = app.views.StreamObject.extend({ toggleLike: function(evt) { if(evt) { evt.preventDefault(); } - - var userLike = this.model.get("user_like"); - - if(userLike) { - this.model.likes.get(userLike.id).destroy({ - success : $.proxy(function() { - this.model.set({user_like : null, likes_count : this.model.get("likes_count") - 1}); - }, this) - }); - } else { - this.model.likes.create({}, { - success : $.proxy(function(like) { - this.model.set({user_like : like, likes_count : this.model.get("likes_count") + 1}); // this should be in a callback... - }, this) - }); - } + this.model.toggleLike(); }, resharePost : function(evt){ if(evt) { evt.preventDefault(); } + if(!window.confirm("Reshare " + this.model.baseAuthor().name + "'s post?")) { return } - if(window.confirm("Reshare " + this.model.baseAuthor().name + "'s post?")) { - var reshare = new app.models.Reshare(); - reshare.save({root_guid : this.model.baseGuid()}, { - success : function(){ - app.stream.collection.add(reshare.toJSON()); - } - }); - return reshare; - } + var reshare = new app.models.Reshare(); + reshare.save({root_guid : this.model.baseGuid()}, { + success : function(){ + app.stream.collection.add(reshare.toJSON()); + } + }); + return reshare; } }) diff --git a/spec/javascripts/app/models/post_spec.js b/spec/javascripts/app/models/post_spec.js index 970b5852b06aed365bcb7d15b8c252bb4c42eda3..4eef317cc686fdb30dcbeffc915c2b55640e4991 100644 --- a/spec/javascripts/app/models/post_spec.js +++ b/spec/javascripts/app/models/post_spec.js @@ -29,6 +29,45 @@ describe("app.models.Post", function() { }) }) + describe("toggleLike", function(){ + it("calls unliked when the user_like exists", function(){ + this.post.set({user_like : "123"}); + spyOn(this.post, "unlike").andReturn(true); + + this.post.toggleLike(); + expect(this.post.unlike).toHaveBeenCalled(); + }) + + it("calls liked when the user_like does not exist", function(){ + this.post.set({user_like : null}); + spyOn(this.post, "like").andReturn(true); + + this.post.toggleLike(); + expect(this.post.like).toHaveBeenCalled(); + }) + }) + + describe("like", function(){ + it("calls create on the likes collection", function(){ + spyOn(this.post.likes, "create"); + + this.post.like(); + expect(this.post.likes.create).toHaveBeenCalled(); + }) + }) + + describe("unlike", function(){ + it("calls destroy on the likes collection", function(){ + var like = new app.models.Like(); + this.post.set({user_like : like}) + + spyOn(like, "destroy"); + + this.post.unlike(); + expect(like.destroy).toHaveBeenCalled(); + }) + }) + describe("baseAuthor", function(){ it("returns the post's guid if the post does not have a root", function() { this.post.attributes.root = null; diff --git a/spec/javascripts/app/views/feedback_view_spec.js b/spec/javascripts/app/views/feedback_view_spec.js index 58ad9b460fa86ae5ab526ca5850f03dae4a70db3..5f0a30a9495e1b8b35059ec5d09653c57958399b 100644 --- a/spec/javascripts/app/views/feedback_view_spec.js +++ b/spec/javascripts/app/views/feedback_view_spec.js @@ -11,63 +11,42 @@ describe("app.views.Feedback", function(){ describe(".render", function(){ beforeEach(function(){ this.link = function(){ return this.view.$(".like_action"); } + this.view.render(); }) context("likes", function(){ - context("when the user likes the post", function(){ - beforeEach(function(){ - this.view.render(); - }) + it("calls 'toggleLike' on the target post", function(){ + this.view.render(); + spyOn(this.post, "toggleLike"); + this.link().click(); + expect(this.post.toggleLike).toHaveBeenCalled(); + }) + + context("when the user likes the post", function(){ it("the like action should be 'Unlike'", function(){ expect(this.link().text()).toContain('Unlike'); }) - - it("removes like when Unlike is clicked", function() { - var likeModel = new app.models.Like(this.view.model.get("user_like")); - spyOn(this.view.model.likes, "get").andReturn(likeModel); - spyOn(likeModel, "destroy"); - - this.link().click(); - expect(likeModel.destroy).toHaveBeenCalled(); - }) }) + context("when the user doesn't yet like the post", function(){ beforeEach(function(){ this.view.model.set({user_like : null}); this.view.render(); }) - it("contains a .like_action", function(){ - expect($(this.view.el).html()).toContain("like_action"); - }) - it("the like action should be 'Like'", function(){ expect(this.link().text()).toContain('Like'); }) it("allows for unliking a just-liked post", function(){ - var like = new app.models.Like({id : 2}); - - spyOn(this.post.likes, "create").andReturn(like); - expect(this.link().text()).toContain('Like'); - this.link().click(); - this.view.render(); + this.link().click(); expect(this.link().text()).toContain('Unlike'); - // spying + stubbing for destroy - var likeModel = new app.models.Like(this.view.model.get("user_like")); - spyOn(this.view.model.likes, "get").andReturn(likeModel); - spyOn(likeModel, "destroy").andReturn(function(){ - this.view.model.set({user_like : null}) - }); - this.link().click(); - - this.view.render(); expect(this.link().text()).toContain('Like'); }) }) @@ -88,7 +67,7 @@ describe("app.views.Feedback", function(){ }); it("does not show a reshare_action link if the original post has been deleted", function(){ - this.post.attributes.root = null + this.post.set({post_type : "Reshare", root : null}) this.view.render(); expect($(this.view.el).html()).not.toContain('reshare_action');