diff --git a/app/views/templates/_templates.haml b/app/views/templates/_templates.haml
index 3c2f9e3a2..33292f5ea 100644
--- a/app/views/templates/_templates.haml
+++ b/app/views/templates/_templates.haml
@@ -5,6 +5,9 @@
%script{:id => "header-template", :type => 'text/template'}
!= File.read("#{Rails.root}/app/views/templates/header.ujs")
+%script{:id => "feedback-template", :type => 'text/template'}
+ != File.read("#{Rails.root}/app/views/templates/feedback.ujs")
+
%script{:id => "stream-element-template", :type => 'text/template'}
!= File.read("#{Rails.root}/app/views/templates/stream_element.ujs")
diff --git a/app/views/templates/feedback.ujs b/app/views/templates/feedback.ujs
new file mode 100644
index 000000000..bded74e90
--- /dev/null
+++ b/app/views/templates/feedback.ujs
@@ -0,0 +1,13 @@
+
+
diff --git a/app/views/templates/stream_element.ujs b/app/views/templates/stream_element.ujs
index 1ad9f5991..aeb91c8e5 100644
--- a/app/views/templates/stream_element.ujs
+++ b/app/views/templates/stream_element.ujs
@@ -46,59 +46,7 @@
<% } %>
-
- <% if(provider_display_name != null) { %>
-
- via <%= provider_display_name %>
- -
-
- <% } %>
-
-
- <%= public ? "Public" : "Limited" %>
- -
-
-
- <% if(user_like) { %>
-
- Unlike
-
- <% } else { %>
-
- Like
-
- <% } %>
- ·
-
- <% if(public && author.id != current_user.id) { %>
- <% if(root) {
- var rootGuid = root.guid;
- } else {
- var rootGuid = guid;
- } %>
-
- Reshare
-
- ·
- <% } %>
-
-
-
-
-
-
-
+
diff --git a/public/javascripts/app/views/feedback_view.js b/public/javascripts/app/views/feedback_view.js
new file mode 100644
index 000000000..3b89fcf56
--- /dev/null
+++ b/public/javascripts/app/views/feedback_view.js
@@ -0,0 +1,30 @@
+App.Views.Feedback = App.Views.StreamObject.extend({
+ template_name: "#feedback-template",
+
+ events: {
+ "click .like_action": "toggleLike",
+ },
+
+ initialize : function() {
+ var user_like = this.model.get("user_like")
+ this.like = user_like && this.model.likes.get(user_like.id);
+
+ this.model.likes.bind("change", this.render, this);
+ this.model.likes.bind("remove", this.render, this);
+ this.model.likes.bind("add", this.render, this);
+ },
+
+ presenter : function(){
+ return _.extend(this.defaultPresenter, {like : this.like});
+ },
+
+ toggleLike: function(evt) {
+ if(evt) { evt.preventDefault(); }
+
+ if(this.like){
+ this.like.destroy();
+ } else {
+ this.like = this.model.likes.create();
+ }
+ },
+})
diff --git a/public/javascripts/app/views/post_view.js b/public/javascripts/app/views/post_view.js
index e2ecabe80..abc0ee614 100644
--- a/public/javascripts/app/views/post_view.js
+++ b/public/javascripts/app/views/post_view.js
@@ -6,7 +6,6 @@ App.Views.Post = App.Views.StreamObject.extend({
"click .focus_comment_textarea": "focusCommentTextarea",
"click .shield a": "removeNsfwShield",
"click .remove_post": "destroyModel",
- "click .like_action": "toggleLike",
"click .expand_likes": "expandLikes",
"click .block_user": "blockUser"
},
@@ -58,33 +57,6 @@ App.Views.Post = App.Views.StreamObject.extend({
return this;
},
- toggleLike: function(evt) {
- if(evt) { evt.preventDefault(); }
-
- var link = $(evt.target);
- var post = this.model;
-
- if(link.hasClass('like')) {
- var like = this.model.likes.create();
- if(like) {
- this.model.set({
- user_like : like,
- likes_count : post.get("likes_count") + 1
- });
- }
- } else {
- this.model.likes.get(link.data("id")).destroy({
- success : function(){
- post.set({
- user_like : null,
- likes_count : post.get("likes_count") - 1
- });
- }
- });
- }
-
- return this;
- },
expandLikes: function(evt){
if(evt) { evt.preventDefault(); }
diff --git a/public/javascripts/app/views/stream_object_view.js b/public/javascripts/app/views/stream_object_view.js
index 4d6eb82f1..c8ec672bf 100644
--- a/public/javascripts/app/views/stream_object_view.js
+++ b/public/javascripts/app/views/stream_object_view.js
@@ -1,6 +1,5 @@
App.Views.StreamObject = Backbone.View.extend({
initialize: function(options) {
- this.model = options.model;
this.model.bind('remove', this.remove, this);
this.model.bind('change', this.render, this);
},
@@ -10,18 +9,22 @@ App.Views.StreamObject = Backbone.View.extend({
this.model.destroy();
},
- context : function(){
- var modelJson = this.model ? this.model.toJSON() : {}
- return $.extend(modelJson, App.user());
+ presenter : function(){
+ return this.defaultPresenter()
},
- renderTemplate : function(){
- this.template = _.template($(this.template_name).html());
- $(this.el).html(this.template(this.context()));
- return this;
+ defaultPresenter : function(){
+ var modelJson = this.model ? this.model.toJSON() : {}
+ return _.extend(modelJson, App.user());
},
render : function() {
return this.renderTemplate()
+ },
+
+ renderTemplate : function(){
+ this.template = _.template($(this.template_name).html());
+ $(this.el).html(this.template(this.presenter()));
+ return this;
}
});
diff --git a/spec/controllers/jasmine_fixtures/stream_spec.rb b/spec/controllers/jasmine_fixtures/stream_spec.rb
new file mode 100644
index 000000000..89a5f42b5
--- /dev/null
+++ b/spec/controllers/jasmine_fixtures/stream_spec.rb
@@ -0,0 +1,25 @@
+# Copyright (c) 2010-2011, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe MultisController do
+ describe '#index' do
+ before do
+ sign_in :user, alice
+ end
+
+ it 'generates the multti_stream_json fixture' do
+ alice.post(:status_message, :text => "hella infos yo!", :to => alice.aspects.first.id)
+ alice.post(:reshare, :root_guid => Factory(:status_message, :public => true).guid, :to => 'all')
+ post_to_be_liked = alice.post(:status_message, :text => "you're gonna love this.'", :to => alice.aspects.first.id)
+
+ alice.like(1, :target => post_to_be_liked)
+
+ get :index, :format => :json
+ response.should be_success
+ save_fixture(response.body, "multi_stream_json")
+ end
+ end
+end
diff --git a/spec/jasmine_fixtures/template_spec.rb b/spec/controllers/jasmine_fixtures/template_spec.rb
similarity index 100%
rename from spec/jasmine_fixtures/template_spec.rb
rename to spec/controllers/jasmine_fixtures/template_spec.rb
diff --git a/spec/javascripts/app/views/feedback_view_spec.js b/spec/javascripts/app/views/feedback_view_spec.js
new file mode 100644
index 000000000..5bcbabc6e
--- /dev/null
+++ b/spec/javascripts/app/views/feedback_view_spec.js
@@ -0,0 +1,71 @@
+describe("App.views.Feedback", function(){
+ beforeEach(function(){
+ window.current_user = App.user({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]);
+ 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"); }
+ })
+
+ context("when the user likes the post", function(){
+ beforeEach(function(){
+ this.view.render();
+ })
+
+ it("the like action should be 'Unlike'", function(){
+ expect(this.link().text()).toContain('Unlike');
+ })
+
+ it("destroys ths like when Unlike is clicked", function(){
+ spyOn(this.view.like, "destroy")
+ this.link().click();
+ expect(this.view.like.destroy).toHaveBeenCalled()
+ });
+
+ })
+
+ context("when the user doesn't yet like the post", function(){
+ beforeEach(function(){
+ this.view.like = null;
+ this.view.render();
+ })
+
+ it("the like action should be 'Like'", 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);
+ })
+ })
+ })
+})
+
diff --git a/spec/javascripts/app/views/header_view_spec.js b/spec/javascripts/app/views/header_view_spec.js
index 70509b489..3a35cffb2 100644
--- a/spec/javascripts/app/views/header_view_spec.js
+++ b/spec/javascripts/app/views/header_view_spec.js
@@ -1,15 +1,10 @@
describe("App.Views.Header", function() {
beforeEach(function() {
// should be jasmine helper
-
window.current_user = App.user({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}});
spec.loadFixture("aspects_index");
-
this.view = new App.Views.Header().render();
-
- console.log(this.view);
-
});
describe("#toggleDropdown", function() {
diff --git a/spec/javascripts/app/views/post_view_spec.js b/spec/javascripts/app/views/post_view_spec.js
index 2ae8eb60b..11ff8f56c 100644
--- a/spec/javascripts/app/views/post_view_spec.js
+++ b/spec/javascripts/app/views/post_view_spec.js
@@ -6,7 +6,6 @@ describe("App.views.Post", function(){
window.current_user = App.user({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}});
var posts = $.parseJSON(spec.readFixture("multi_stream_json"))["posts"][0];
- spec.loadFixture("underscore_templates");
this.collection = new App.Collections.Stream(posts);
this.statusMessage = this.collection.models[0];
@@ -51,32 +50,5 @@ describe("App.views.Post", function(){
expect(statusElement.find(".reshare_action").html()).toBeNull();
})
})
-
- context("Like link", function(){
- beforeEach(function(){
- this.view = new App.Views.Post({model : this.statusMessage})
- this.link = function(){ return this.view.$(".like_action"); }
- })
-
- it("clicking 'Like' toggles appropriately", function(){
- this.statusMessage.set({user_like : null});
- this.view.render();
-
- expect(this.link().text()).toContain('Like');
- this.link().click();
- expect(this.link().text()).toContain('Unlike');
- expect($(this.view.el).html()).toContain('1 like');
- })
-
- it("clicking 'Unlike' toggles appropriately", function(){
- this.statusMessage.set({user_like : { id : 1 }});
- this.view.render();
-
- expect(this.link().text()).toContain('Unlike');
- this.link().click();
- expect(this.link().text()).toContain('Like');
- expect($(this.view.el).html()).toNotContain('1 Like');
- })
- })
})
})
diff --git a/spec/javascripts/app/views/stream_view_spec.js b/spec/javascripts/app/views/stream_view_spec.js
index b1fcda671..e36d1841e 100644
--- a/spec/javascripts/app/views/stream_view_spec.js
+++ b/spec/javascripts/app/views/stream_view_spec.js
@@ -6,7 +6,6 @@ describe("App.views.Stream", function(){
window.current_user = App.user({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}});
var posts = $.parseJSON(spec.readFixture("multi_stream_json"))["posts"];
- spec.loadFixture("underscore_templates");
this.collection = new App.Collections.Stream(posts);
this.statusMessage = this.collection.models[0];
diff --git a/spec/javascripts/helpers/SpecHelper.js b/spec/javascripts/helpers/SpecHelper.js
index ccb456878..547aeee4d 100644
--- a/spec/javascripts/helpers/SpecHelper.js
+++ b/spec/javascripts/helpers/SpecHelper.js
@@ -10,7 +10,8 @@
//});
beforeEach(function() {
- $('#jasmine_content').empty();
+ $('#jasmine_content').html(spec.readFixture("underscore_templates"));
+
// NOTE Commented (as well as in afterEach) to keep the listeners from rails.js alive.
//spec.clearLiveEventBindings();
jasmine.Clock.useMock();
@@ -22,7 +23,7 @@ beforeEach(function() {
self.directionDetector = self.instantiate("DirectionDetector");
});
};
-
+
var Page = Diaspora.Pages["TestPage"];
$.extend(Page.prototype, Diaspora.EventBroker.extend(Diaspora.BaseWidget));
@@ -97,6 +98,6 @@ spec.retrieveFixture = function(fixtureName) {
return xhr.responseText;
};
+
spec.loadFixtureCount = 0;
spec.cachedFixtures = {};
-