add mutations to questions and reviews

This commit is contained in:
João Geonizeli
2022-07-21 15:10:49 -03:00
parent d38acaab98
commit 3ce6c421b1
18 changed files with 909 additions and 6 deletions

View File

@@ -4,5 +4,13 @@ module Mutations
field_class Types::BaseField
input_object_class Types::BaseInputObject
object_class Types::BaseObject
field :errors, [String],
null: false,
description: "Errors encountered during execution of the mutation."
def current_user
context[:current_user]
end
end
end

View File

@@ -0,0 +1,35 @@
# frozen_string_literal: true
module Mutations
class CreateQuestion < BaseMutation
field :question, Types::QuestionType, null: true
argument :question, Inputs::QuestionCreateInput, required: true
def resolve(question:)
question = question.to_h
reviewer_user_id = question.delete(:reviewer_user_id)
record = Question.new(question)
record.user_id = context[:current_user].id
policy = QuestionPolicy.new(context[:current_user], record)
raise Pundit::NotAuthorizedError unless policy.create?
ActiveRecord::Base.transaction do
record.save!
if reviewer_user_id.present? && question[:status] != "draft"
record.review_requests.create!(user_id: reviewer_user_id)
end
{ question: record, errors: [] }
rescue ActiveRecord::RecordInvalid
{ question: nil, errors: record.errors.full_messages }
end
rescue Pundit::NotAuthorizedError => e
{ question: nil, errors: [e.message] }
end
end
end

View File

@@ -0,0 +1,53 @@
# frozen_string_literal: true
module Mutations
class CreateReviewMessage < BaseMutation
field :review_message, Types::ReviewMessageType, null: true
argument :message, Inputs::ReviewMessageInput, required: true
def resolve(message:)
message = message.to_h
ActiveRecord::Base.transaction do
record = ReviewMessage.create!({
**message,
user_id: current_user.id,
})
update_question_status(record.question, message[:feedback_type])
update_review_requests(record.question, message[:feedback_type])
{ review_message: record, errors: [] }
rescue ActiveRecord::RecordInvalid => e
{ review_message: nil, errors: e.record.errors.full_messages }
end
rescue Pundit::NotAuthorizedError => e
{ review_message: nil, errors: [e.message] }
end
private
def update_question_status(question, feedback_type)
new_question_status = case feedback_type
when "request_changes"
"with_requested_changes"
when "approve"
"approved"
when "answer"
"waiting_review"
end
question.update!(status: new_question_status)
end
def update_review_requests(question, feedback_type)
return question.review_requests.update_all(answered: false) if feedback_type == "answer"
question
.review_requests
.where(user_id: current_user.id)
.update_all(answered: question.user_id != current_user.id)
end
end
end

View File

@@ -0,0 +1,26 @@
# frozen_string_literal: true
module Mutations
class DestroyQuestion < BaseMutation
field :deleted_question_id, ID, null: true
argument :question_id, ID, required: true
def resolve(question_id:)
question = Question.find_by(id: question_id)
reviewer = question.reviewer
raise Pundit::NotAuthorizedError unless QuestionPolicy.new(context[:current_user], question).destroy?
return { errors: question.errors.full_messages } unless question.destroy!
ReviewerMailer.with(question_id: question_id, recipient: reviewer)
.question_deleted_notification
.deliver if reviewer
{ deleted_question_id: question_id, errors: [] }
rescue Pundit::NotAuthorizedError => e
{ errors: [e.message] }
end
end
end

View File

@@ -0,0 +1,26 @@
# frozen_string_literal: true
module Mutations
class FinishQuestion < BaseMutation
field :question, Types::QuestionType, null: true
argument :question_id, ID, required: true
def resolve(input)
user = context[:current_user]
question = ::Question.find(input[:question_id])
raise Pundit::NotAuthorizedError unless QuestionPolicy.new(user, question).finish?
if question.update(status: :registered)
{ question: question, errors: [] }
else
{ question: nil, errors: question.errors.full_messages }
end
rescue Pundit::NotAuthorizedError => e
{ question: nil, errors: [e.message] }
end
end
end

View File

@@ -0,0 +1,37 @@
# frozen_string_literal: true
module Mutations
class UpdateQuestion < BaseMutation
field :question, Types::QuestionType, null: true
argument :question, Inputs::QuestionUpdateInput, required: true
def resolve(question:)
question = question.to_h
reviewer_user_id = question.delete(:reviewer_user_id)
record = Question.find(question[:id])
raise Pundit::NotAuthorizedError unless QuestionPolicy.new(context[:current_user], record).update?
ActiveRecord::Base.transaction do
record.update!(question)
if reviewer_user_id.present? && question[:status] != "draft"
review_request = record.review_requests.find_or_create_by!(
user_id: reviewer_user_id
)
review_request.update!(answered: false)
end
{ question: record, errors: [] }
rescue ActiveRecord::RecordInvalid
{ question: nil, errors: question.errors.full_messages }
end
rescue Pundit::NotAuthorizedError => e
{ question: nil, errors: [e.message] }
end
end
end