Refactor likes controller using like service

This commit is contained in:
Steffen van Bergerem 2017-02-18 00:36:22 +01:00 committed by Benjamin Neff
parent f93124863f
commit 2772cb6e0c
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
2 changed files with 113 additions and 157 deletions

View file

@ -11,42 +11,27 @@ class LikesController < ApplicationController
:json :json
def create def create
begin like = like_service.create(params[:post_id])
@like = if target rescue ActiveRecord::RecordNotFound, ActiveRecord::RecordInvalid
current_user.like!(target)
end
rescue ActiveRecord::RecordNotFound, ActiveRecord::RecordInvalid => e
# do nothing
end
if @like
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 }
end
else
render text: I18n.t("likes.create.error"), status: 422 render text: I18n.t("likes.create.error"), status: 422
else
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 }
end end
end end
def destroy def destroy
begin if like_service.destroy(params[:id])
@like = Like.find_by_id_and_author_id!(params[:id], current_user.person.id) render nothing: true, status: 204
rescue ActiveRecord::RecordNotFound else
render text: I18n.t("likes.destroy.error"), status: 404 render text: I18n.t("likes.destroy.error"), status: 404
return
end
current_user.retract(@like)
respond_to do |format|
format.json { render :nothing => true, :status => 204 }
end end
end end
#I can go when the old stream goes.
def index def index
@likes = target.likes.includes(:author => :profile) @likes = like_service.find_for_post(params[:post_id]).includes(author: :profile)
@people = @likes.map(&:author) @people = @likes.map(&:author)
respond_to do |format| respond_to do |format|
@ -57,13 +42,7 @@ class LikesController < ApplicationController
private private
def target def like_service
@target ||= if params[:post_id] @like_service ||= LikeService.new(current_user)
current_user.find_visible_shareable_by_id(Post, params[:post_id]) || raise(ActiveRecord::RecordNotFound.new)
else
Comment.find(params[:comment_id]).tap do |comment|
raise(ActiveRecord::RecordNotFound.new) unless current_user.find_visible_shareable_by_id(Post, comment.commentable_id)
end
end
end end
end end

View file

@ -2,7 +2,7 @@
# licensed under the Affero General Public License version 3 or later. See # licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file. # the COPYRIGHT file.
describe LikesController, :type => :controller do describe LikesController, type: :controller do
before do before do
@alices_aspect = alice.aspects.where(:name => "generic").first @alices_aspect = alice.aspects.where(:name => "generic").first
@bobs_aspect = bob.aspects.where(:name => "generic").first @bobs_aspect = bob.aspects.where(:name => "generic").first
@ -10,137 +10,114 @@ describe LikesController, :type => :controller do
sign_in(alice, scope: :user) sign_in(alice, scope: :user)
end end
[Comment, Post].each do |class_const| describe "#create" do
context class_const.to_s do
let(:id_field){
"#{class_const.to_s.underscore}_id"
}
describe '#create' do
let(:like_hash) { let(:like_hash) {
{:positive => 1, {post_id: @target.id}
id_field => "#{@target.id}"}
}
let(:dislike_hash) {
{:positive => 0,
id_field => "#{@target.id}"}
} }
context "on my own post" do context "on my own post" do
it 'succeeds' do it "succeeds" do
@target = alice.post :status_message, :text => "AWESOME", :to => @alices_aspect.id @target = alice.post :status_message, text: "AWESOME", to: @alices_aspect.id
@target = alice.comment!(@target, "hey") if class_const == Comment post :create, like_hash.merge(format: :json)
post :create, like_hash.merge(:format => :json) expect(response.code).to eq("201")
expect(response.code).to eq('201')
end end
end end
context "on a post from a contact" do context "on a post from a contact" do
before do before do
@target = bob.post(:status_message, :text => "AWESOME", :to => @bobs_aspect.id) @target = bob.post(:status_message, text: "AWESOME", to: @bobs_aspect.id)
@target = bob.comment!(@target, "hey") if class_const == Comment
end end
it 'likes' do it "likes" do
post :create, like_hash post :create, like_hash
expect(response.code).to eq('201') expect(response.code).to eq("201")
end
it 'dislikes' do
post :create, dislike_hash
expect(response.code).to eq('201')
end end
it "doesn't post multiple times" do it "doesn't post multiple times" do
alice.like!(@target) alice.like!(@target)
post :create, dislike_hash post :create, like_hash
expect(response.code).to eq('422') expect(response.code).to eq("422")
end end
end end
context "on a post from a stranger" do context "on a post from a stranger" do
before do before do
@target = eve.post :status_message, :text => "AWESOME", :to => eve.aspects.first.id @target = eve.post :status_message, text: "AWESOME", to: eve.aspects.first.id
@target = eve.comment!(@target, "hey") if class_const == Comment
end end
it "doesn't post" do it "doesn't post" do
expect(alice).not_to receive(:like!) expect(alice).not_to receive(:like!)
post :create, like_hash post :create, like_hash
expect(response.code).to eq('422') expect(response.code).to eq("422")
end end
end end
context "when an the exception is raised" do context "when an the exception is raised" do
before do before do
@target = alice.post :status_message, :text => "AWESOME", :to => @alices_aspect.id @target = alice.post :status_message, text: "AWESOME", to: @alices_aspect.id
@target = alice.comment!(@target, "hey") if class_const == Comment
end end
it "should be catched when it means that the target is not found" do it "should be catched when it means that the target is not found" do
params = like_hash.merge(format: :json, id_field => -1) params = like_hash.merge(format: :json, post_id: -1)
post :create, params post :create, params
expect(response.code).to eq('422') expect(response.code).to eq("422")
end end
it "should not be catched when it is unexpected" do it "should not be catched when it is unexpected" do
@target = alice.post :status_message, :text => "AWESOME", :to => @alices_aspect.id @target = alice.post :status_message, text: "AWESOME", to: @alices_aspect.id
@target = alice.comment!(@target, "hey") if class_const == Comment
allow(alice).to receive(:like!).and_raise("something") allow(alice).to receive(:like!).and_raise("something")
allow(@controller).to receive(:current_user).and_return(alice) allow(@controller).to receive(:current_user).and_return(alice)
expect { post :create, like_hash.merge(:format => :json) }.to raise_error("something") expect { post :create, like_hash.merge(format: :json) }.to raise_error("something")
end end
end end
end end
describe '#index' do describe "#index" do
before do before do
@message = alice.post(:status_message, :text => "hey", :to => @alices_aspect.id) @message = alice.post(:status_message, text: "hey", to: @alices_aspect.id)
@message = alice.comment!(@message, "hey") if class_const == Comment
end end
it 'returns a 404 for a post not visible to the user' do it "returns a 404 for a post not visible to the user" do
sign_in eve sign_in eve
expect{get :index, id_field => @message.id}.to raise_error(ActiveRecord::RecordNotFound) expect {
get :index, post_id: @message.id
}.to raise_error(ActiveRecord::RecordNotFound)
end end
it 'returns an array of likes for a post' do it "returns an array of likes for a post" do
like = bob.like!(@message) bob.like!(@message)
get :index, id_field => @message.id get :index, post_id: @message.id
expect(assigns[:likes].map(&:id)).to eq(@message.likes.map(&:id)) expect(assigns[:likes].map(&:id)).to eq(@message.likes.map(&:id))
end end
it 'returns an empty array for a post with no likes' do it "returns an empty array for a post with no likes" do
get :index, id_field => @message.id get :index, post_id: @message.id
expect(assigns[:likes]).to eq([]) expect(assigns[:likes]).to eq([])
end end
end end
describe '#destroy' do describe "#destroy" do
before do before do
@message = bob.post(:status_message, :text => "hey", :to => @alices_aspect.id) @message = bob.post(:status_message, text: "hey", to: @alices_aspect.id)
@message = bob.comment!(@message, "hey") if class_const == Comment
@like = alice.like!(@message) @like = alice.like!(@message)
end end
it 'lets a user destroy their like' do it "lets a user destroy their like" do
current_user = controller.send(:current_user) current_user = controller.send(:current_user)
expect(current_user).to receive(:retract).with(@like) expect(current_user).to receive(:retract).with(@like)
delete :destroy, :format => :json, id_field => @like.target_id, :id => @like.id delete :destroy, format: :json, post_id: @message.id, id: @like.id
expect(response.status).to eq(204) expect(response.status).to eq(204)
end end
it 'does not let a user destroy other likes' do it "does not let a user destroy other likes" do
like2 = eve.like!(@message) like2 = eve.like!(@message)
like_count = Like.count like_count = Like.count
delete :destroy, :format => :json, id_field => like2.target_id, :id => like2.id delete :destroy, format: :json, post_id: @message.id, id: like2.id
expect(response.status).to eq(404) expect(response.status).to eq(404)
expect(response.body).to eq(I18n.t("likes.destroy.error")) expect(response.body).to eq(I18n.t("likes.destroy.error"))
expect(Like.count).to eq(like_count) expect(Like.count).to eq(like_count)
end end
end end
end end
end
end