Add Poll Voting Method to Interactions Endpoint
This commit is contained in:
parent
32157036d3
commit
ff6d0064d0
8 changed files with 198 additions and 6 deletions
|
|
@ -51,11 +51,32 @@ module Api
|
|||
render json: I18n.t("api.endpoint_errors.posts.cant_report"), status: :unprocessable_entity
|
||||
end
|
||||
|
||||
def vote
|
||||
begin
|
||||
post = post_service.find!(params[:post_id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render json: I18n.t("api.endpoint_errors.posts.post_not_found"), status: :not_found
|
||||
return
|
||||
end
|
||||
poll_vote = poll_service.vote(post.id, params[:poll_answer_id])
|
||||
if poll_vote
|
||||
head :no_content
|
||||
else
|
||||
render json: I18n.t("api.endpoint_errors.interactions.cant_vote"), status: :unprocessable_entity
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid, ActiveRecord::RecordNotFound
|
||||
render json: I18n.t("api.endpoint_errors.interactions.cant_vote"), status: :unprocessable_entity
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def post_service
|
||||
@post_service ||= PostService.new(current_user)
|
||||
end
|
||||
|
||||
def poll_service
|
||||
@poll_service ||= PollParticipationService.new(current_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ class PollParticipationsController < ApplicationController
|
|||
before_action :authenticate_user!
|
||||
|
||||
def create
|
||||
answer = PollAnswer.find(params[:poll_answer_id])
|
||||
poll_participation = current_user.participate_in_poll!(target, answer) if target
|
||||
poll_participation = poll_service.vote(params[:post_id], params[:poll_answer_id])
|
||||
respond_to do |format|
|
||||
format.mobile { redirect_to stream_path }
|
||||
format.json { render json: poll_participation, :status => 201 }
|
||||
|
|
@ -19,9 +18,7 @@ class PollParticipationsController < ApplicationController
|
|||
|
||||
private
|
||||
|
||||
def target
|
||||
@target ||= if params[:post_id]
|
||||
current_user.find_visible_shareable_by_id(Post, params[:post_id]) || raise(ActiveRecord::RecordNotFound.new)
|
||||
end
|
||||
def poll_service
|
||||
@poll_service ||= PollParticipationService.new(current_user)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
18
app/services/poll_participation_service.rb
Normal file
18
app/services/poll_participation_service.rb
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PollParticipationService
|
||||
def initialize(user)
|
||||
@user = user
|
||||
end
|
||||
|
||||
def vote(post_id, answer_id)
|
||||
answer = PollAnswer.find(answer_id)
|
||||
@user.participate_in_poll!(target(post_id), answer) if target(post_id)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def target(post_id)
|
||||
@target ||= @user.find_visible_shareable_by_id(Post, post_id) || raise(ActiveRecord::RecordNotFound.new)
|
||||
end
|
||||
end
|
||||
|
|
@ -974,6 +974,7 @@ en:
|
|||
no_like: "Like doesn’t exist"
|
||||
interactions:
|
||||
cant_subscribe: "Can't subscribe to this post"
|
||||
cant_vote: "Can't vote on this post"
|
||||
notifications:
|
||||
not_found: "Notification with provided guid could not be found"
|
||||
cant_process: "Couldn't process the notifications request"
|
||||
|
|
|
|||
|
|
@ -236,6 +236,7 @@ Rails.application.routes.draw do
|
|||
post "mute" => "post_interactions#mute"
|
||||
post "hide" => "post_interactions#hide"
|
||||
post "report" => "post_interactions#report"
|
||||
post "vote" => "post_interactions#vote"
|
||||
end
|
||||
resources :conversations, only: %i[show index create destroy] do
|
||||
resources :messages, only: %i[index create]
|
||||
|
|
|
|||
38
spec/controllers/poll_participations_controller_spec.rb
Normal file
38
spec/controllers/poll_participations_controller_spec.rb
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe PollParticipationsController, type: :controller do
|
||||
let(:poll_post) { FactoryGirl.create(:status_message_with_poll, public: true) }
|
||||
let(:poll_answer) { poll_post.poll.poll_answers.first }
|
||||
|
||||
before do
|
||||
sign_in alice, scope: :user
|
||||
request.env["HTTP_ACCEPT"] = "application/json"
|
||||
end
|
||||
|
||||
describe "voting on poll" do
|
||||
it "succeeds" do
|
||||
post :create, params: {post_id: poll_post.id, poll_answer_id: poll_answer.id}
|
||||
expect(response.status).to eq(201)
|
||||
poll_participation = JSON.parse(response.body)["poll_participation"]
|
||||
expect(poll_participation["poll_answer_id"]).to eq(poll_answer.id)
|
||||
end
|
||||
|
||||
it "fails to vote twice" do
|
||||
post :create, params: {post_id: poll_post.id, poll_answer_id: poll_answer.id}
|
||||
expect(response.status).to eq(201)
|
||||
post :create, params: {post_id: poll_post.id, poll_answer_id: poll_answer.id}
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "fails with bad answer id" do
|
||||
expect {
|
||||
post :create, params: {post_id: poll_post.id, poll_answer_id: -1}
|
||||
}.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
||||
it "fails with bad post id" do
|
||||
expect { post :create, params: {post_id: -1, poll_answer_id: poll_answer.id} }
|
||||
.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -291,4 +291,91 @@ describe Api::V1::PostInteractionsController do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#vote" do
|
||||
before do
|
||||
base_params = {status_message: {text: "myText"}, public: true}
|
||||
poll_params = {poll_question: "something?", poll_answers: %w[yes no maybe]}
|
||||
merged_params = base_params.merge(poll_params)
|
||||
@poll_post = StatusMessageCreationService.new(alice).create(merged_params)
|
||||
@poll_answer = @poll_post.poll.poll_answers.first
|
||||
end
|
||||
|
||||
it "succeeds" do
|
||||
post(
|
||||
api_v1_post_vote_path(@poll_post.guid),
|
||||
params: {
|
||||
poll_answer_id: @poll_answer.id,
|
||||
access_token: access_token
|
||||
}
|
||||
)
|
||||
expect(response.status).to eq(204)
|
||||
expect(@poll_answer.reload.vote_count).to eq(1)
|
||||
end
|
||||
|
||||
it "fails to vote twice" do
|
||||
post(
|
||||
api_v1_post_vote_path(@poll_post.guid),
|
||||
params: {
|
||||
poll_answer_id: @poll_answer.id,
|
||||
access_token: access_token
|
||||
}
|
||||
)
|
||||
expect(response.status).to eq(204)
|
||||
post(
|
||||
api_v1_post_vote_path(@poll_post.guid),
|
||||
params: {
|
||||
poll_answer_id: @poll_answer.id,
|
||||
access_token: access_token
|
||||
}
|
||||
)
|
||||
expect(response.status).to eq(422)
|
||||
expect(response.body).to eq(I18n.t("api.endpoint_errors.interactions.cant_vote"))
|
||||
end
|
||||
|
||||
it "fails with bad answer id" do
|
||||
post(
|
||||
api_v1_post_vote_path(@poll_post.guid),
|
||||
params: {
|
||||
poll_answer_id: -1,
|
||||
access_token: access_token
|
||||
}
|
||||
)
|
||||
expect(response.status).to eq(422)
|
||||
expect(response.body).to eq(I18n.t("api.endpoint_errors.interactions.cant_vote"))
|
||||
end
|
||||
|
||||
it "fails with bad post id" do
|
||||
post(
|
||||
api_v1_post_vote_path("999_999_999"),
|
||||
params: {
|
||||
poll_answer_id: @poll_answer.id,
|
||||
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
|
||||
it "with read only token" do
|
||||
post(
|
||||
api_v1_post_vote_path(@poll_post.guid),
|
||||
params: {
|
||||
poll_answer_id: @poll_answer.id,
|
||||
access_token: access_token_read_only
|
||||
}
|
||||
)
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "with invalid token" do
|
||||
post(
|
||||
api_v1_post_vote_path(@poll_post.guid),
|
||||
params: {
|
||||
poll_answer_id: @poll_answer.id,
|
||||
access_token: "999_999_999"
|
||||
}
|
||||
)
|
||||
expect(response.status).to eq(401)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
29
spec/services/poll_participation_service_spec.rb
Normal file
29
spec/services/poll_participation_service_spec.rb
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe PollParticipationService do
|
||||
let(:poll_post) { FactoryGirl.create(:status_message_with_poll, public: true) }
|
||||
let(:poll_answer) { poll_post.poll.poll_answers.first }
|
||||
|
||||
describe "voting on poll" do
|
||||
it "succeeds" do
|
||||
expect(poll_service.vote(poll_post.id, poll_answer.id)).not_to be_nil
|
||||
end
|
||||
|
||||
it "fails to vote twice" do
|
||||
expect(poll_service.vote(poll_post.id, poll_answer.id)).not_to be_nil
|
||||
expect { poll_service.vote(poll_post.id, poll_answer.id) }.to raise_error(ActiveRecord::RecordInvalid)
|
||||
end
|
||||
|
||||
it "fails with bad answer id" do
|
||||
expect { poll_service.vote(poll_post.id, -2) }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
||||
it "fails with bad post id" do
|
||||
expect { poll_service.vote(-1, poll_answer.id) }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
def poll_service(user=alice)
|
||||
PollParticipationService.new(user)
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue