diff --git a/app/controllers/api/v0/likes_controller.rb b/app/controllers/api/v0/likes_controller.rb new file mode 100644 index 000000000..e23808238 --- /dev/null +++ b/app/controllers/api/v0/likes_controller.rb @@ -0,0 +1,47 @@ +module Api + module V0 + class LikesController < Api::V0::BaseController + before_action only: %i(create destroy) do + require_access_token %w(read write) + end + + rescue_from ActiveRecord::RecordNotFound do + render json: I18n.t("likes.not_found"), status: 404 + end + + rescue_from ActiveRecord::RecordInvalid do + render json: I18n.t("likes.create.fail"), status: 404 + 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_and_author_id!(params[:id], current_user.person.id) + current_user.retract(@like) + render nothing: true, status: 204 + end + + private + + 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 + end + end + end +end diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index 8d81d0c1b..f720819b3 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -630,8 +630,22 @@ en: likes: create: error: "Failed to like." + fail: "Like creation has failed" destroy: error: "Failed to unlike." + people_like_this: + zero: "No likes" + one: "%{count} like" + other: "%{count} likes" + people_like_this_comment: + zero: "No likes" + one: "%{count} like" + other: "%{count} likes" + people_dislike_this: + zero: "No dislikes" + one: "%{count} dislike" + other: "%{count} dislikes" + not_found: "Post or like not found" notifications: started_sharing: diff --git a/config/routes.rb b/config/routes.rb index 60748c434..6271f6df9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -225,6 +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) end get "activity" => "streams#activity", :as => "activity_stream" get "stream" => "streams#multi", :as => "stream" diff --git a/spec/integration/api/likes_controller_spec.rb b/spec/integration/api/likes_controller_spec.rb new file mode 100644 index 000000000..772f38566 --- /dev/null +++ b/spec/integration/api/likes_controller_spec.rb @@ -0,0 +1,40 @@ +require "spec_helper" + +describe Api::V0::LikesController do + let(:auth) { FactoryGirl.create(:auth_with_read_and_write) } + let!(:access_token) { auth.create_access_token.to_s } + + before do + @status = auth.user.post(:status_message, text: "This is a status message", public: true, to: "all") + end + + describe "#create" do + it "returns the expected author" do + post api_v0_post_likes_path(post_id: @status.id), 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: 9999999), access_token: access_token + expect(response.body).to eq("Post or like not found") + end + end + + describe "#delete" do + before do + post api_v0_post_likes_path(post_id: @status.id), access_token: access_token + @like_id = JSON.parse(response.body)["id"] + end + + it "succeeds" do + delete api_v0_post_like_path(post_id: @status.id, id: @like_id), access_token: access_token + expect(response).to be_success + end + + it "fails on random like id" do + delete api_v0_post_like_path(post_id: @status.id, id: 99999999), access_token: access_token + expect(response.body).to eq("Post or like not found") + end + end +end