From 3268726a9ad5b2fc5df81ab2426d4f23f00f00e8 Mon Sep 17 00:00:00 2001 From: danielgrippi Date: Thu, 29 Dec 2011 00:09:58 -0500 Subject: [PATCH] added LikesInfo view; simplified Feedback view (not sure how to mock the jasmine specs correctly... ugh) --- app/views/templates/_templates.haml | 3 ++ app/views/templates/feedback.ujs | 2 +- app/views/templates/likes_info.ujs | 6 +++ app/views/templates/stream_element.ujs | 1 + public/javascripts/app/views/feedback_view.js | 31 +++++------ .../javascripts/app/views/likes_info_view.js | 8 +++ public/javascripts/app/views/post_view.js | 48 +---------------- .../app/views/feedback_view_spec.js | 52 +++++-------------- spec/javascripts/app/views/likes_info_spec.js | 25 +++++++++ 9 files changed, 72 insertions(+), 104 deletions(-) create mode 100644 app/views/templates/likes_info.ujs create mode 100644 public/javascripts/app/views/likes_info_view.js create mode 100644 spec/javascripts/app/views/likes_info_spec.js diff --git a/app/views/templates/_templates.haml b/app/views/templates/_templates.haml index 506642d37..848b28618 100644 --- a/app/views/templates/_templates.haml +++ b/app/views/templates/_templates.haml @@ -29,3 +29,6 @@ %script{:id => "activity-streams-photo-template", :type => 'text/template'} != File.read("#{Rails.root}/app/views/templates/activity-streams-photo.ujs") +%script{:id => "likes-info-template", :type => 'text/template'} + != File.read("#{Rails.root}/app/views/templates/likes_info.ujs") + diff --git a/app/views/templates/feedback.ujs b/app/views/templates/feedback.ujs index f3ddd4f0b..fca230265 100644 --- a/app/views/templates/feedback.ujs +++ b/app/views/templates/feedback.ujs @@ -1,6 +1,6 @@
ยท diff --git a/app/views/templates/likes_info.ujs b/app/views/templates/likes_info.ujs new file mode 100644 index 000000000..88c55cba9 --- /dev/null +++ b/app/views/templates/likes_info.ujs @@ -0,0 +1,6 @@ +<% if(likes_count > 0) { %> + Heart + + <%= likes_count %> Like + +<% } %> diff --git a/app/views/templates/stream_element.ujs b/app/views/templates/stream_element.ujs index 894c04a94..13ef5ec15 100644 --- a/app/views/templates/stream_element.ujs +++ b/app/views/templates/stream_element.ujs @@ -48,6 +48,7 @@ <% } %> +
diff --git a/public/javascripts/app/views/feedback_view.js b/public/javascripts/app/views/feedback_view.js index b1dbc5eb7..6aecaa03a 100644 --- a/public/javascripts/app/views/feedback_view.js +++ b/public/javascripts/app/views/feedback_view.js @@ -6,30 +6,23 @@ app.views.Feedback = app.views.StreamObject.extend({ "click .reshare_action": "resharePost" }, - initialize : function() { - var user_like = this.model.get("user_like") - this.like = user_like && this.model.likes.get(user_like.id); - - _.each(["change", "remove", "add"], function(listener) { - this.model.likes.bind(listener, this.render, this); - }, this) - }, - - presenter : function(){ - return _.extend(this.defaultPresenter(), {like : this.like}); - }, - toggleLike: function(evt) { if(evt) { evt.preventDefault(); } - if(this.like){ - this.like.destroy({ - success : function() { - this.like = null; - }.apply(this) + 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.like = this.model.likes.create(); + 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) + }); } }, diff --git a/public/javascripts/app/views/likes_info_view.js b/public/javascripts/app/views/likes_info_view.js new file mode 100644 index 000000000..32302e841 --- /dev/null +++ b/public/javascripts/app/views/likes_info_view.js @@ -0,0 +1,8 @@ +app.views.LikesInfo = app.views.StreamObject.extend({ + + template_name : "#likes-info-template", + + className : "likes_container", + + events: { } +}); diff --git a/public/javascripts/app/views/post_view.js b/public/javascripts/app/views/post_view.js index b5f7be150..7b6077f39 100644 --- a/public/javascripts/app/views/post_view.js +++ b/public/javascripts/app/views/post_view.js @@ -6,12 +6,12 @@ app.views.Post = app.views.StreamObject.extend({ "click .focus_comment_textarea": "focusCommentTextarea", "click .shield a": "removeNsfwShield", "click .remove_post": "destroyModel", - "click .expand_likes": "expandLikes", "click .block_user": "blockUser" }, subviews : { ".feedback" : "feedbackView", + ".likes" : "likesInfoView", ".comments" : "commentStreamView" }, @@ -24,6 +24,7 @@ app.views.Post = app.views.StreamObject.extend({ initialize : function() { // commentStream view this.commentStreamView = new app.views.CommentStream({ model : this.model}); + this.likesInfoView = new app.views.LikesInfo({ model : this.model}); // feedback view if(window.app.user().current_user) { @@ -70,51 +71,6 @@ app.views.Post = app.views.StreamObject.extend({ return this; }, - expandLikes: function(evt){ - if(evt) { evt.preventDefault(); } - - var self = this; - - this.model.likes.fetch({ - success: function(){ - // this should be broken out - - self.$(".expand_likes").remove(); - var likesView = Backbone.View.extend({ - - tagName: 'span', - - initialize: function(options){ - this.collection = options.collection; - _.bindAll(this, "render", "appendLike"); - }, - - render: function(){ - _.each(this.collection.models, this.appendLike) - return this; - }, - - appendLike: function(model){ - $(this.el).append("", { - href : "/person/" + model.get("author")["id"] - }).html($("", { - src : model.get("author")["avatar"]["small"], - "class" : "avatar" - })); - } - }); - - var view = new likesView({collection : self.model.likes}); - - self.$('.likes_container').removeClass("hidden") - .append(view.render().el); - - } - }); - - return this; - }, - blockUser: function(evt){ if(evt) { evt.preventDefault(); } diff --git a/spec/javascripts/app/views/feedback_view_spec.js b/spec/javascripts/app/views/feedback_view_spec.js index 55b7798f7..524e6a52a 100644 --- a/spec/javascripts/app/views/feedback_view_spec.js +++ b/spec/javascripts/app/views/feedback_view_spec.js @@ -8,25 +8,6 @@ describe("app.views.Feedback", function(){ this.view = new app.views.Feedback({model: this.post}); }); - it("has a like from the post", function(){ - var like = this.post.likes.models[0]; - - expect(like).toBeDefined(); - expect(this.view.like).toBe(like); - }) - - it("rerends when the post is liked", function(){ - spyOn(this.view, "render") - this.post.likes.trigger("add"); - expect(this.view.render); - }) - - it("rerends when the post is unliked", function(){ - spyOn(this.view, "render") - this.view.like.trigger("destroy"); - expect(this.view.render); - }) - describe(".render", function(){ beforeEach(function(){ this.link = function(){ return this.view.$(".like_action"); } @@ -42,21 +23,18 @@ describe("app.views.Feedback", function(){ }) it("removes like when Unlike is clicked", function() { - this.link().click(); - expect(this.view.like).toBeNull(); - }) + var likeModel = new app.models.Like(this.view.model.get("user_like")); + spyOn(this.view.model.likes, "get").andReturn(likeModel); + spyOn(likeModel, "destroy"); - // strange that this is failing... maybe we need to spy on Backbone.sync here? - // it("destroys ths like when Unlike is clicked", function(){ - // spyOn(this.view.like, "destroy").andReturn($.noop()); - // this.link().click(); - // expect(this.view.like.destroy).toHaveBeenCalled() - // }); + this.link().click(); + expect(likeModel.destroy).toHaveBeenCalled(); + }) }) context("when the user doesn't yet like the post", function(){ beforeEach(function(){ - this.view.like = null; + this.view.model.set({user_like : null}); this.view.render(); }) @@ -68,13 +46,6 @@ describe("app.views.Feedback", function(){ expect(this.link().text()).toContain('Like'); }) - it("likes the post when the link is clicked", function(){ - var like = { party : "time"} - spyOn(this.post.likes, "create").andReturn(like); - this.link().click() - expect(this.view.like).toBe(like); - }) - it("allows for unliking a just-liked post", function(){ var like = new app.models.Like({id : 2}); @@ -83,11 +54,16 @@ describe("app.views.Feedback", function(){ expect(this.link().text()).toContain('Like'); this.link().click(); - spyOn(this.view.like, "destroy").andReturn($.noop()); - this.view.render(); 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(); diff --git a/spec/javascripts/app/views/likes_info_spec.js b/spec/javascripts/app/views/likes_info_spec.js new file mode 100644 index 000000000..d58183b1b --- /dev/null +++ b/spec/javascripts/app/views/likes_info_spec.js @@ -0,0 +1,25 @@ +describe("app.views.LikesInfo", function(){ + beforeEach(function(){ + window.current_user = app.user({id : -1, name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}}); + + var posts = $.parseJSON(spec.readFixture("multi_stream_json"))["posts"]; + this.post = new app.models.Post(posts[2]); // post with a like + this.view = new app.views.LikesInfo({model: this.post}); + }); + + describe(".render", function(){ + it("displays a the like count if it is above zero", function() { + this.view.render(); + + expect($(this.view.el).text()).toContain(this.view.model.get("likes_count")) + }) + + it("does not display the like count if it is zero", function() { + this.post.save({likes_count : 0}); + this.view.render(); + + expect($(this.view.el).html().trim()).toBe(""); + }) + }) +}) +