cucumber for comment retractions, modified views

This commit is contained in:
Raphael Sofaer 2011-03-25 16:09:02 -07:00
parent fef226156c
commit aed190dc6d
16 changed files with 159 additions and 71 deletions

View file

@ -34,7 +34,7 @@ class CommentsController < ApplicationController
render(:json => json, :status => 201)
}
format.html{ render :nothing => true, :status => 201 }
format.mobile{ redirect_to status_message_path(@comment.post_id) }
format.mobile{ redirect_to @comment.post }
end
else
render :nothing => true, :status => 422
@ -44,4 +44,23 @@ class CommentsController < ApplicationController
end
end
def destroy
if @comment = Comment.where(:id => params[:id]).first
if current_user.owns?(@comment) || current_user.owns?(@comment.parent)
current_user.retract(@comment)
respond_to do |format|
format.mobile{ redirect_to @comment.post }
format.js {render :nothing => true, :status => 204}
end
else
respond_to do |format|
format.mobile {redirect_to :back}
format.js {render :nothing => true, :status => 401}
end
end
else
render :nothing => true, :status => 404
end
end
end

View file

@ -48,7 +48,7 @@ module SocketsHelper
v = render_to_string(:partial => 'people/person', :locals => person_hash)
elsif object.is_a? Comment
v = render_to_string(:partial => 'comments/comment', :locals => {:comment => object, :person => object.author})
v = render_to_string(:partial => 'comments/comment', :locals => {:comment => object, :person => object.author, :current_user => user})
elsif object.is_a? Like
v = render_to_string(:partial => 'likes/likes', :locals => {:likes => object.post.likes, :dislikes => object.post.dislikes})

View file

@ -7,6 +7,7 @@ class RelayableRetraction
include Diaspora::Webhooks
include Diaspora::Encryptable
xml_name :relayable_retraction
xml_attr :target_guid
xml_attr :target_type
xml_attr :sender_handle
@ -37,6 +38,10 @@ class RelayableRetraction
@sender.diaspora_handle
end
def diaspora_handle
self.sender_handle
end
def subscribers(user)
self.target.subscribers(user)
end

View file

@ -3,6 +3,9 @@
-# the COPYRIGHT file.
%li.comment.posted{:data=>{:guid => comment.id}, :class => ("hidden" if(defined? hidden))}
- if current_user.owns?(comment) || current_user.owns?(comment.post)
.right.controls
= link_to image_tag('deletelabel.png'), comment_path(comment), :confirm => t('are_you_sure'), :method => :delete, :remote => true, :class => "delete comment_delete", :title => t('delete')
= person_image_link(comment.author)
.content
.from

View file

@ -6,6 +6,9 @@
.right
%span.time
= comment.created_at ? time_ago_in_words(comment.created_at) : time_ago_in_words(Time.now)
.controls
= link_to image_tag('deletelabel.png'), comment, :confirm => t('are_you_sure'), :method => :delete, :class => "delete comment_delete", :title => t('delete')
= person_image_link(comment.author)
.content

View file

@ -2,7 +2,7 @@
-# licensed under the Affero General Public License version 3 or later. See
-# the COPYRIGHT file.
= form_tag( comments_path, :id => "new_comment_on_#{post_id}", :class => 'new_comment', :remote => true) do
= form_tag( comments_path, :id => "new_comment_on_#{post_id}", :class => 'new_comment') do
= hidden_field_tag :post_id, post_id, :id => "post_id_on_#{post_id}"
= text_area_tag :text, nil, :rows => 2, :class => "comment_box",:id => "comment_text_on_#{post_id}"

View file

@ -4,11 +4,11 @@
.stream_element{:data=>{:guid=>post.id}}
- if current_user && post.author.owner_id == current_user.id
.right.hidden.controls
.right.controls
- reshare_aspects = aspects_without_post(all_aspects, post)
- unless reshare_aspects.empty?
= render 'shared/reshare', :aspects => reshare_aspects, :post => post
= link_to image_tag('deletelabel.png'), status_message_path(post), :confirm => t('are_you_sure'), :method => :delete, :remote => true, :class => "delete", :title => t('delete')
= link_to image_tag('deletelabel.png'), status_message_path(post), :confirm => t('are_you_sure'), :method => :delete, :remote => true, :class => "delete stream_element_delete", :title => t('delete')
= person_image_link(post.author, :size => :thumb_small)

View file

@ -4,7 +4,7 @@
Diaspora::Application.routes.draw do
resources :status_messages, :only => [:new, :create, :destroy, :show]
resources :comments, :only => [:create]
resources :comments, :only => [:create, :destroy]
resources :requests, :only => [:destroy, :create]
resource :likes, :only => [:create]

View file

@ -47,3 +47,17 @@ Feature: commenting
And I press "comment"
Then I should see "hahaha" within "li.comment div.content"
And I should see "less than a minute ago" within "li.comment time"
Scenario: delete a post
When I sign in as "bob@bob.bob"
And I am on "alice@alice.alice"'s page
Then I should see "Look at this dog"
When I focus the comment field
And I fill in "comment" with "is that a poodle?"
And I press "comment"
And I wait for the ajax to finish
When I hover over the comment
And I preemptively confirm the alert
And I click to delete the first comment
And I wait for the ajax to finish
Then I should not see "is that a poodle?"

View file

@ -28,10 +28,12 @@ Feature: posting
Given I expand the publisher
When I fill in "status_message_fake_text" with "I am eating a yogurt"
And I press "Share"
And I wait for the ajax to finish
And I follow "All aspects"
And I hover over the post
And I preemptively confirm the alert
And I click to delete the first post
And I wait for the ajax to finish
And I follow "All aspects"
Then I should not see "I am eating a yogurt"

View file

@ -36,12 +36,21 @@ When /^I append "([^"]*)" to the publisher$/ do |stuff|
end
end
And /^I hover over the post$/ do
page.execute_script('$(".stream_element").first().mouseover()')
And /^I hover over the (\w*)$/ do |element|
if element == 'post'
name = 'stream_element'
elsif element == 'comment'
name = 'comment.posted'
end
page.execute_script("$(\".#{name}\").first().mouseover()")
end
When /^I click to delete the first post$/ do
page.execute_script('$(".stream_element").first().find(".delete").click()')
page.execute_script('$(".stream_element").first().find(".stream_element_delete").click()')
end
When /^I click to delete the first comment$/ do
page.execute_script('$(".comment.posted").first().find(".comment_delete").click()')
end
And /^I click "([^"]*)" button$/ do |arg1|

View file

@ -58,7 +58,7 @@ var Stream = {
json = $.parseJSON(json);
WebSocketReceiver.processLike(json.post_id, json.html);
});
$('.like_it, .dislike_it').live('ajax:failure', function(data, html, xhr) {
Diaspora.widgets.alert.alert('Failed to like/dislike!');
$(this).parent().fadeIn('fast');
@ -106,8 +106,24 @@ var Stream = {
Diaspora.widgets.alert.alert('Failed to post message!');
});
$(".stream").find(".delete").live('ajax:success', function(data, html, xhr) {
$(this).parents(".stream_element").hide('blind', { direction: 'vertical' }, 300);
$(".stream").find(".stream_element_delete", ".stream_element").live('ajax:success', function(data, html, xhr) {
var target = $(this).parents(".stream_element");
target.hide('blind', { direction: 'vertical' }, 300, function(){ $(this).remove() });
});
$(".stream").find(".comment_delete", ".comment").live('ajax:success', function(data, html, xhr) {
var element = $(this),
target = element.parents(".comment"),
post = element.closest('.stream_element'),
toggler = post.find('.show_post_comments');
target.hide('blind', { direction: 'vertical' }, 300, function(){
$(this).remove();
toggler.html(
toggler.html().replace(/\d+/,$('.comments', post).find('li').length -1)
);
});
});
},

View file

@ -98,7 +98,6 @@ var WebSocketReceiver = {
var post = $("*[data-guid='"+postId+"']'"),
prevComments = $('.comment.posted', post);
if(prevComments.length > 0) {
prevComments.last().after(
$(html).fadeIn("fast", function(){})

View file

@ -249,13 +249,6 @@ header
:bottom 1px solid #ddd
:top 1px solid #fff
&:hover
.right
:display inline
.from
a
:color $blue
.youtube-player, .vimeo-player
:border none
:height 370px
@ -398,7 +391,6 @@ header
:margin
:top -1px
.delete
@include opacity(0.6)
:padding 5px
@ -406,6 +398,27 @@ header
&:hover
@include opacity(1)
.right
:position absolute
:right 12px
.controls
:display none
:z-index 6
:color #999
a
:color #999
:font
:weight normal
&:hover, .comment:hover
> .controls
:display inline
.from
a
:color $blue
.time,
.timeago
:color #999
@ -595,6 +608,9 @@ div.dislikes
a
:color #444
.right
:right 4px
form
:margin
:top -5px
@ -635,9 +651,6 @@ div.dislikes
:min-height 2.4em
.comments
time
:margin
:right -15px
.timeago
:color #999
@ -691,32 +704,6 @@ a.paginate, #infscr-loading
#main_stream .pagination
:display none
.stream_element
.right
:position absolute
:right 12px
&.controls
:z-index 6
:background
:color $background
:font
:size 12px
:color #999
:padding
:left 100px
a
:color #999
:font
:weight normal
&:hover
.controls
:display inline
.stream_element:hover
.right
:display inline
.request_buttons
:position absolute
:right 0

View file

@ -8,13 +8,11 @@ describe CommentsController do
render_views
before do
@user1 = alice
@user2 = bob
@aspect1 = alice.aspects.first
@aspect2 = bob.aspects.first
@aspect1 = @user1.aspects.first
@aspect2 = @user2.aspects.first
sign_in :user, @user1
@controller.stub(:current_user).and_return(alice)
sign_in :user, alice
end
describe '#create' do
@ -24,7 +22,7 @@ describe CommentsController do
}
context "on my own post" do
before do
@post = @user1.post :status_message, :text => 'GIANTS', :to => @aspect1.id
@post = alice.post :status_message, :text => 'GIANTS', :to => @aspect1.id
end
it 'responds to format js' do
post :create, comment_hash.merge(:format => 'js')
@ -35,7 +33,7 @@ describe CommentsController do
context "on a post from a contact" do
before do
@post = @user2.post :status_message, :text => 'GIANTS', :to => @aspect2.id
@post = bob.post :status_message, :text => 'GIANTS', :to => @aspect2.id
end
it 'comments' do
post :create, comment_hash
@ -45,10 +43,10 @@ describe CommentsController do
new_user = Factory.create(:user)
comment_hash[:author_id] = new_user.person.id.to_s
post :create, comment_hash
Comment.find_by_text(comment_hash[:text]).author_id.should == @user1.person.id
Comment.find_by_text(comment_hash[:text]).author_id.should == alice.person.id
end
it "doesn't overwrite id" do
old_comment = @user1.comment("hello", :on => @post)
old_comment = alice.comment("hello", :on => @post)
comment_hash[:id] = old_comment.id
post :create, comment_hash
old_comment.reload.text.should == 'hello'
@ -59,10 +57,53 @@ describe CommentsController do
@post = eve.post :status_message, :text => 'GIANTS', :to => eve.aspects.first.id
end
it 'posts no comment' do
@user1.should_not_receive(:comment)
alice.should_not_receive(:comment)
post :create, comment_hash
response.code.should == '422'
end
end
end
describe '#destroy' do
context 'your post' do
before do
@message = alice.post(:status_message, :text => "hey", :to => @aspect1.id)
@comment = alice.comment("hey", :on => @message)
@comment2 = bob.comment("hey", :on => @message)
@comment3 = eve.comment("hey", :on => @message)
end
it 'lets the user delete his comment' do
alice.should_receive(:retract).with(@comment)
delete :destroy, :format => "js", :id => @comment.id
response.status.should == 204
end
it "lets the user destroy other people's comments" do
alice.should_receive(:retract).with(@comment2)
delete :destroy, :format => "js", :id => @comment2.id
response.status.should == 204
end
end
context "another user's post" do
before do
@message = bob.post(:status_message, :text => "hey", :to => bob.aspects.first.id)
@comment = alice.comment("hey", :on => @message)
@comment2 = bob.comment("hey", :on => @message)
@comment3 = eve.comment("hey", :on => @message)
end
it 'let the user delete his comment' do
alice.should_receive(:retract).with(@comment)
delete :destroy, :format => "js", :id => @comment.id
response.status.should == 204
end
it 'does not let the user destroy comments he does not own' do
alice.should_not_receive(:retract).with(@comment2)
delete :destroy, :format => "js", :id => @comment3.id
response.status.should == 401
end
end
end
end

View file

@ -44,14 +44,4 @@ describe Retraction do
end
end
end
describe 'dispatching' do
it 'should dispatch a retraction on delete' do
Factory.create(:person)
m = mock()
m.should_receive(:post)
Postzord::Dispatch.should_receive(:new).with(instance_of(User), instance_of(Retraction)).and_return(m)
post.destroy
end
end
end