Likes API endpoint complete
This commit is contained in:
parent
a56d998499
commit
7ee9565a04
7 changed files with 182 additions and 9 deletions
|
|
@ -5,6 +5,8 @@ module Api
|
|||
class BaseController < ApplicationController
|
||||
include Api::OpenidConnect::ProtectedResourceEndpoint
|
||||
|
||||
protect_from_forgery unless: -> { request.format.json? }
|
||||
|
||||
protected
|
||||
|
||||
rescue_from Exception do |e|
|
||||
|
|
|
|||
|
|
@ -3,31 +3,55 @@
|
|||
module Api
|
||||
module V1
|
||||
class LikesController < Api::V1::BaseController
|
||||
before_action only: %i[show] do
|
||||
require_access_token %w[read]
|
||||
end
|
||||
|
||||
before_action only: %i[create destroy] do
|
||||
require_access_token %w[write]
|
||||
end
|
||||
|
||||
rescue_from ActiveRecord::RecordNotFound do
|
||||
render json: I18n.t("likes.not_found"), status: :not_found
|
||||
render json: I18n.t("api.endpoint_errors.posts.post_not_found"), status: :not_found
|
||||
end
|
||||
|
||||
rescue_from ActiveRecord::RecordInvalid do
|
||||
render json: I18n.t("likes.create.fail"), status: :not_found
|
||||
render json: I18n.t("api.endpoint_errors.likes.user_not_allowed_to_like"), status: :not_found
|
||||
end
|
||||
|
||||
def show
|
||||
likes = like_service.find_for_post(params[:post_id])
|
||||
render json: likes.map {|x| like_json(x) }
|
||||
end
|
||||
|
||||
def create
|
||||
like_service.create(params[:post_id])
|
||||
head :no_content, status: 204
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
return render json: I18n.t("api.endpoint_errors.likes.like_exists"), status: :unprocessable_entity if
|
||||
e.message == "Validation failed: Target has already been taken"
|
||||
raise
|
||||
else
|
||||
head :no_content
|
||||
end
|
||||
|
||||
def destroy
|
||||
like_service.unlike_post(params[:post_id])
|
||||
head :no_content, status: 204
|
||||
success = like_service.unlike_post(params[:post_id])
|
||||
if success
|
||||
head :no_content
|
||||
else
|
||||
render json: I18n.t("api.endpoint_errors.likes.no_like"), status: :not_found
|
||||
end
|
||||
end
|
||||
|
||||
def like_service
|
||||
@like_service ||= LikeService.new(current_user)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def like_json(like)
|
||||
LikesPresenter.new(like).as_api_json
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
10
app/presenters/likes_presenter.rb
Normal file
10
app/presenters/likes_presenter.rb
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class LikesPresenter < BasePresenter
|
||||
def as_api_json
|
||||
{
|
||||
guid: @presentable.guid,
|
||||
author: PersonPresenter.new(@presentable.author).as_api_json
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
@ -950,6 +950,13 @@ en:
|
|||
contact_developer: "You should contact the developer of the application and include the following detailed error message:"
|
||||
login_required: "You must first login before you can authorize this application"
|
||||
could_not_authorize: "The application could not be authorized"
|
||||
endpoint_errors:
|
||||
likes:
|
||||
user_not_allowed_to_like: "User is not allowed to like"
|
||||
like_exists: "Like already exists"
|
||||
no_like: "Like doesn’t exist"
|
||||
posts:
|
||||
post_not_found: "Post with provided guid could not be found"
|
||||
|
||||
error:
|
||||
not_found: "No record found for given id."
|
||||
|
|
@ -1361,3 +1368,5 @@ en:
|
|||
disabled: "Not available"
|
||||
open: "Open"
|
||||
closed: "Closed"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ Rails.application.routes.draw do
|
|||
resources :comments, only: %i[create index destroy] do
|
||||
post "report" => "comments#report"
|
||||
end
|
||||
resource :likes, only: %i[create destroy]
|
||||
resource :likes, only: %i[show create destroy]
|
||||
end
|
||||
resources :conversations, only: %i[show index create destroy] do
|
||||
resources :messages, only: %i[index create]
|
||||
|
|
|
|||
|
|
@ -15,6 +15,47 @@ describe Api::V1::LikesController do
|
|||
)
|
||||
end
|
||||
|
||||
describe "#show" do
|
||||
context "with right post id" do
|
||||
it "succeeds in getting empty likes" do
|
||||
get(
|
||||
api_v1_post_likes_path(post_id: @status.guid),
|
||||
params: {access_token: access_token}
|
||||
)
|
||||
expect(response.status).to eq(200)
|
||||
likes = response_body(response)
|
||||
expect(likes.length).to eq(0)
|
||||
end
|
||||
|
||||
it "succeeds in getting post with likes" do
|
||||
like_service(bob).create(@status.guid)
|
||||
like_service(auth.user).create(@status.guid)
|
||||
like_service(alice).create(@status.guid)
|
||||
get(
|
||||
api_v1_post_likes_path(post_id: @status.guid),
|
||||
params: {access_token: access_token}
|
||||
)
|
||||
expect(response.status).to eq(200)
|
||||
likes = response_body(response)
|
||||
expect(likes.length).to eq(3)
|
||||
confirm_like_format(likes, alice)
|
||||
confirm_like_format(likes, bob)
|
||||
confirm_like_format(likes, auth.user)
|
||||
end
|
||||
end
|
||||
|
||||
context "with wrong post id" do
|
||||
it "fails at getting likes" do
|
||||
get(
|
||||
api_v1_post_likes_path(post_id: "badguid"),
|
||||
params: {access_token: access_token}
|
||||
)
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
context "with right post id" do
|
||||
it "succeeeds in liking post" do
|
||||
|
|
@ -27,6 +68,25 @@ describe Api::V1::LikesController do
|
|||
expect(likes.length).to eq(1)
|
||||
expect(likes[0].author.id).to eq(auth.user.person.id)
|
||||
end
|
||||
|
||||
it "fails in liking already liked post" do
|
||||
post(
|
||||
api_v1_post_likes_path(post_id: @status.guid),
|
||||
params: {access_token: access_token}
|
||||
)
|
||||
expect(response.status).to eq(204)
|
||||
|
||||
post(
|
||||
api_v1_post_likes_path(post_id: @status.guid),
|
||||
params: {access_token: access_token}
|
||||
)
|
||||
expect(response.status).to eq(422)
|
||||
expect(response.body).to eq(I18n.t("api.endpoint_errors.likes.like_exists"))
|
||||
|
||||
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
|
||||
|
||||
context "with wrong post id" do
|
||||
|
|
@ -36,11 +96,12 @@ describe Api::V1::LikesController do
|
|||
params: {access_token: access_token}
|
||||
)
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
describe "#delete" do
|
||||
before do
|
||||
post(
|
||||
api_v1_post_likes_path(post_id: @status.guid),
|
||||
|
|
@ -58,6 +119,24 @@ describe Api::V1::LikesController do
|
|||
likes = like_service.find_for_post(@status.guid)
|
||||
expect(likes.length).to eq(0)
|
||||
end
|
||||
|
||||
it "fails at unliking post user didn't like" do
|
||||
delete(
|
||||
api_v1_post_likes_path(post_id: @status.guid),
|
||||
params: {access_token: access_token}
|
||||
)
|
||||
expect(response.status).to eq(204)
|
||||
|
||||
delete(
|
||||
api_v1_post_likes_path(post_id: @status.guid),
|
||||
params: {access_token: access_token}
|
||||
)
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.body).to eq(I18n.t("api.endpoint_errors.likes.no_like"))
|
||||
|
||||
likes = like_service.find_for_post(@status.guid)
|
||||
expect(likes.length).to eq(0)
|
||||
end
|
||||
end
|
||||
|
||||
context "with wrong post id" do
|
||||
|
|
@ -67,11 +146,28 @@ describe Api::V1::LikesController do
|
|||
params: {access_token: access_token}
|
||||
)
|
||||
expect(response.status).to eq(404)
|
||||
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def like_service
|
||||
LikeService.new(auth.user)
|
||||
private
|
||||
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
def confirm_like_format(likes, user)
|
||||
like = likes.find {|like_element| like_element["author"]["guid"] == user.guid }
|
||||
author = like["author"]
|
||||
expect(author["diaspora_id"]).to eq(user.diaspora_handle)
|
||||
expect(author["name"]).to eq(user.name)
|
||||
expect(author["avatar"]).to eq(user.profile.image_url)
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
|
||||
def like_service(user=auth.user)
|
||||
LikeService.new(user)
|
||||
end
|
||||
|
||||
def response_body(response)
|
||||
JSON.parse(response.body)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
32
spec/presenters/likes_presenter_spec.rb
Normal file
32
spec/presenters/likes_presenter_spec.rb
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe LikesPresenter do
|
||||
before do
|
||||
@status = alice.post(
|
||||
:status_message,
|
||||
text: "This is a status message from alice",
|
||||
public: true,
|
||||
to: "all"
|
||||
)
|
||||
bobs_like_service = LikeService.new(bob)
|
||||
like = bobs_like_service.create(@status.guid)
|
||||
@presenter = LikesPresenter.new(like, bob)
|
||||
end
|
||||
|
||||
describe "#as_api_json" do
|
||||
it "works" do
|
||||
expect(@presenter.as_api_json).to be_present
|
||||
end
|
||||
|
||||
it "confirm API V1 compliance" do
|
||||
like = @presenter.as_api_json
|
||||
expect(like.has_key?(:guid)).to be_truthy
|
||||
author = like[:author]
|
||||
expect(author).not_to be_nil
|
||||
expect(author).to include(guid: bob.guid)
|
||||
expect(author).to include(diaspora_id: bob.diaspora_handle)
|
||||
expect(author).to include(name: bob.name)
|
||||
expect(author).to include(avatar: bob.profile.image_url)
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue