diff --git a/app/controllers/api/v1/likes_controller.rb b/app/controllers/api/v1/likes_controller.rb index a450fff09..8a7cd0998 100644 --- a/app/controllers/api/v1/likes_controller.rb +++ b/app/controllers/api/v1/likes_controller.rb @@ -4,7 +4,7 @@ module Api module V1 class LikesController < Api::V1::BaseController before_action only: %i[create destroy] do - require_access_token %w[read write] + require_access_token %w[write] end rescue_from ActiveRecord::RecordNotFound do @@ -16,33 +16,17 @@ module Api end def create - @like = current_user.like!(target) if target - if @like - render json: @like.as_api_response(:backbone), status: 201 - else - render nothing: true, status: 422 - end - end - - def destroy - @like = Like.find_by!(id: params[:id], author_id: current_user.person.id) - current_user.retract(@like) + like_service.create(params[:post_id]) head :no_content, status: 204 end - private + def destroy + like_service.unlike_post(params[:post_id]) + head :no_content, status: 204 + end - def target - @target ||= if params[:post_id] - current_user.find_visible_shareable_by_id(Post, params[:post_id]).tap do |post| - raise(ActiveRecord::RecordNotFound.new) unless post - end - else - Comment.find(params[:comment_id]).tap do |comment| - shareable = current_user.find_visible_shareable_by_id(Post, comment.commentable_id) - raise(ActiveRecord::RecordNotFound.new) unless shareable - end - end + def like_service + @like_service ||= LikeService.new(current_user) end end end diff --git a/app/services/like_service.rb b/app/services/like_service.rb index b5623a048..9fb9bc670 100644 --- a/app/services/like_service.rb +++ b/app/services/like_service.rb @@ -25,6 +25,17 @@ class LikeService user ? likes.order("author_id = #{user.person.id} DESC") : likes end + def unlike_post(post_id) + likes = post_service.find!(post_id).likes + likes = likes.order("author_id = #{user.person.id} DESC") + if likes.empty? && user.owns?(likes[0]) + user.retract(likes[0]) + true + else + false + end + end + private attr_reader :user diff --git a/config/routes.rb b/config/routes.rb index 261d7f47a..c74280774 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -225,7 +225,7 @@ Rails.application.routes.draw do match "user", to: "users#show", via: %i[get post] resources :posts, only: %i[show create destroy] do resources :comments, only: %i[create destroy] - resources :likes, only: %i[create destroy] + resource :likes, only: %i[create destroy] end resources :conversations, only: %i[show index create destroy] do delete "visibility" => "conversation_visibilities#destroy" diff --git a/spec/integration/api/likes_controller_spec.rb b/spec/integration/api/likes_controller_spec.rb index d94fa39c1..148070ed3 100644 --- a/spec/integration/api/likes_controller_spec.rb +++ b/spec/integration/api/likes_controller_spec.rb @@ -15,61 +15,63 @@ describe Api::V1::LikesController do ) end - describe "#show" do - it "returns the likes for a given post" do - get( - api_v1_post_likes_path(post_id: @status.id), - params: {access_token: access_token} - ) + describe "#create" do + context "with right post id" do + it "succeeeds in liking post" do + post( + api_v1_post_likes_path(post_id: @status.guid), + params: {access_token: access_token} + ) + expect(response.status).to eq(204) + likes = like_service.find_for_post(@status.guid) + expect(likes.length).to eq(1) + expect(likes[0].author.id).to eq(auth.user.person.id) + end end - it "fails on random post id" do - get( - api_v1_post_likes_path(post_id: @status.id), - params: {access_token: access_token} - ) + context "with wrong post id" do + it "fails at liking post" do + post( + api_v1_post_likes_path(post_id: 99_999_999), + params: {access_token: access_token} + ) + expect(response.status).to eq(404) + end end end describe "#create" do - it "returns the expected author" do - post( - api_v1_post_likes_path(post_id: @status.id), - params: {access_token: access_token} - ) - json = JSON.parse(response.body) - expect(json["author"]["id"]).to eq(auth.user.person.id) - end - - it "fails on random post id" do - post api_v0_post_likes_path(post_id: 99_999_999), params: {access_token: access_token} - expect(response.body).to eq("Post or like not found") - end - end - - describe "#delete" do before do post( - api_v1_post_likes_path(post_id: @status.id), + api_v1_post_likes_path(post_id: @status.guid), params: {access_token: access_token} ) - @like_id = JSON.parse(response.body)["id"] end - it "succeeds" do - delete( - api_v1_post_like_path(post_id: @status.id, id: @like_id), - params: {access_token: access_token} - ) - expect(response).to be_success + context "with right post id" do + it "succeeds at unliking post" do + delete( + api_v1_post_likes_path(post_id: @status.guid), + params: {access_token: access_token} + ) + expect(response.status).to eq(204) + likes = like_service.find_for_post(@status.guid) + expect(likes.length).to eq(0) + end end - it "fails on random like id" do - delete( - api_v1_post_like_path(post_id: @status.id, id: 99_999_999), - params: {access_token: access_token} - ) - expect(response.body).to eq("Post or like not found") + context "with wrong post id" do + it "fails at unliking post" do + delete( + api_v1_post_likes_path(post_id: 99_999_999), + params: {access_token: access_token} + ) + expect(response.status).to eq(404) + end end end + + def like_service + LikeService.new(auth.user) + end end diff --git a/spec/services/like_service_spec.rb b/spec/services/like_service_spec.rb index 59d890fe0..d52e495d6 100644 --- a/spec/services/like_service_spec.rb +++ b/spec/services/like_service_spec.rb @@ -120,4 +120,15 @@ describe LikeService do expect(LikeService.new.find_for_post(post.id)).to match_array(likes) end end + + describe "#unlike_post" do + before do + LikeService.new(alice).create(post.id) + end + + it "removes the like to the post" do + LikeService.new(alice).unlike_post(post.id) + expect(post.likes.length).to eq(0) + end + end end