DC DG; created feedback view; moved jasmine fixtures; modified jasmine spec helper; jasmine is green

This commit is contained in:
danielgrippi 2011-12-17 20:26:58 -08:00 committed by Dennis Collinson
parent 03aa7d9d5f
commit 1ffdfa8465
13 changed files with 158 additions and 126 deletions

View file

@ -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")

View file

@ -0,0 +1,13 @@
<div class="info">
<% if(like) { %>
<a href="#" class="like_action unlike" rel='nofollow'>
Unlike
</a>
<% } else { %>
<a href="#" class="like_action like" rel='nofollow'>
Like
</a>
<% } %>
·
</div>

View file

@ -46,59 +46,7 @@
</div>
<% } %>
<div class="info">
<% if(provider_display_name != null) { %>
<span class="via">
via <%= provider_display_name %>
-
</span>
<% } %>
<span class="post_scope" title="<%= public ? 'Viewable to anyone on the web' : 'Only certain people can see this'%>">
<%= public ? "Public" : "Limited" %>
-
</span>
<% if(user_like) { %>
<a href="#" class="like_action unlike" data-id="<%= user_like.id %>" rel='nofollow'>
Unlike
</a>
<% } else { %>
<a href="#" class="like_action like" rel='nofollow'>
Like
</a>
<% } %>
·
<% if(public && author.id != current_user.id) { %>
<% if(root) {
var rootGuid = root.guid;
} else {
var rootGuid = guid;
} %>
<a href="/reshares?root_guid=<%= rootGuid %>" class="reshare_action" data-confirm="Reshare Bob Grimm's post?" data-method="post" data-remote="true" rel="nofollow">
Reshare
</a>
·
<% } %>
<a href="#" class="focus_comment_textarea">
Comment
</a>
</div>
<div class="likes on_post">
<div class="likes_container">
<% if(likes_count > 0){ %>
<img alt="Heart" src="/images/icons/heart.png">
<a href="#" class="expand_likes">
<%= likes_count %> like
</a>
<% } %>
</div>
</div>
<div class="comments"> </div>
<div class="feedback"> </div>
</div>
</div>

View file

@ -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();
}
},
})

View file

@ -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(); }

View file

@ -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;
}
});

View file

@ -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

View file

@ -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);
})
})
})
})

View file

@ -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() {

View file

@ -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');
})
})
})
})

View file

@ -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];

View file

@ -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();
@ -97,6 +98,6 @@ spec.retrieveFixture = function(fixtureName) {
return xhr.responseText;
};
spec.loadFixtureCount = 0;
spec.cachedFixtures = {};