Skip to content

Commit

Permalink
feat: add QuoteCheck ErrorDetails custom feedbacks route
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasleger committed Dec 26, 2024
1 parent 3699313 commit 0e1b65a
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 5 deletions.
14 changes: 13 additions & 1 deletion app/controllers/api/v1/quote_check_feedbacks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module V1
class QuoteCheckFeedbacksController < BaseController
before_action :authorize_request
before_action :quote_check
before_action :validation_error_details, if: -> { params[:validation_error_detail_id].present? }

def create
@quote_check_feedback = quote_check.feedbacks.create!(quote_check_feedback_params)
Expand All @@ -22,7 +23,18 @@ def quote_check
end

def quote_check_feedback_params
params.permit(:validation_error_details_id, :is_helpful, :comment)
raw_params = params.permit(:validation_error_details_id, :is_helpful, :comment)
return raw_params unless defined?(@validation_error_details)

raw_params.merge(validation_error_details_id: @validation_error_details.fetch("id"))
end

def validation_error_details
# validation_error_detail_id is in singular in path params
@validation_error_details ||= quote_check.validation_error_details.detect do |details|
details.fetch("id") == params[:validation_error_detail_id]
end || raise(ActiveRecord::RecordNotFound,
"Couldn't find ValidationErrorDetails with 'id'=#{params[:validation_error_detail_id]}")
end
end
end
Expand Down
6 changes: 6 additions & 0 deletions config/routes/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@
resources :profiles, only: %i[index]
resources :quote_checks, only: %i[create show] do
resources :feedbacks, only: %i[create], controller: "quote_check_feedbacks"
resources :quote_check_validation_error_details,
path: "error_details",
as: :validation_error_details,
only: %i[] do
resources :feedbacks, only: %i[create], controller: "quote_check_feedbacks"
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/quote_validator/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def add_error(code,
end

error_details << {
id: "#{quote_id}##{error_details.count + 1}",
id: [quote_id, error_details.count + 1].compact.join("-"),
code:,
category:, type:,
title: title || I18n.t("quote_validator.errors.#{code}"),
Expand Down
2 changes: 1 addition & 1 deletion spec/factories/quote_checks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
validation_errors { validation_error_details&.map { |error_detail| error_detail.fetch(:code) } || [] }
validation_error_details do
[{
id: "#1",
id: "1",
code: "something"
}]
end
Expand Down
5 changes: 3 additions & 2 deletions spec/requests/api/v1/quote_check_feedbacks_doc_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
required: %w[validation_error_details_id is_helpful]
}

let(:quote_check_id) { create(:quote_check, :invalid).id }
let(:quote_check) { create(:quote_check, :invalid) }
let(:quote_check_id) { quote_check.id }
let(:quote_check_feedback) do
build(:quote_check_feedback, quote_check: QuoteCheck.find(quote_check_id)).attributes
build(:quote_check_feedback, quote_check: quote_check).attributes
end

response "201", "Retour téléversé" do
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# frozen_string_literal: true

require "swagger_helper"

describe "Devis API" do
path "/quote_checks/{quote_check_id}/error_details/{error_details_id}/feedbacks" do
# TODO: i18n?
post "Déposer un retour" do
tags "Devis"
security [basic_auth: []]
consumes "application/json"
produces "application/json"

parameter name: :quote_check_id, in: :path, type: :string
parameter name: :error_details_id, in: :path, type: :string
parameter name: :quote_check_feedback, in: :body, schema: {
type: :object,
properties: {
is_helpful: { type: :boolean, nullable: false },
comment: {
type: :string,
nullable: true,
maxLength: QuoteCheckFeedback.validators_on(:comment).detect do |validator|
validator.is_a?(ActiveModel::Validations::LengthValidator)
end&.options&.[](:maximum)
}
},
required: %w[is_helpful]
}

let(:quote_check) { create(:quote_check, :invalid) }
let(:quote_check_id) { quote_check.id }
let(:error_details_id) { quote_check.validation_error_details.first.fetch("id") }
let(:quote_check_feedback) do
build(:quote_check_feedback, quote_check: quote_check).attributes
end

response "201", "Retour téléversé" do
schema "$ref" => "#/components/schemas/quote_check_feedback"

# See https://github.com/rswag/rswag/issues/316
let(:Authorization) { basic_auth_header.fetch("Authorization") } # rubocop:disable RSpec/VariableName

run_test!
end

response "422", "missing params" do
schema "$ref" => "#/components/schemas/api_error"

let(:quote_check_feedback) do
build(:quote_check_feedback).attributes
.except("validation_error_details_id")
.merge("is_helpful" => nil)
end

let(:Authorization) { basic_auth_header.fetch("Authorization") } # rubocop:disable RSpec/VariableName

run_test!
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# frozen_string_literal: true

# spec/controllers/posts_controller_spec.rb
require "rails_helper"

RSpec.describe "/api/v1/quote_checks/:quote_check_id/error_details/:validation_error_detail_id/feedbacks" do
let(:quote_check) { create(:quote_check, :invalid) }
let(:validation_error_details_id) { quote_check.validation_error_details.first.fetch("id") }
let(:quote_check_id) { quote_check.id }

let(:json) { response.parsed_body }

describe "POST /api/v1/quote_checks/:quote_check_id/error_details/:validation_error_detail_id/feedbacks" do
let(:quote_check_feedback_params) do
{
is_helpful: false,
comment: "FAUX"
}
end

# rubocop:disable RSpec/ExampleLength
it "returns a successful response" do
post api_v1_quote_check_validation_error_detail_feedbacks_url(
quote_check_id: quote_check_id,
validation_error_detail_id: validation_error_details_id
), params: quote_check_feedback_params,
headers: basic_auth_header
expect(response).to be_successful
end

it "returns a created response" do
post api_v1_quote_check_validation_error_detail_feedbacks_url(
quote_check_id: quote_check_id,
validation_error_detail_id: validation_error_details_id
), params: quote_check_feedback_params,
headers: basic_auth_header
expect(response).to have_http_status(:created)
end

it "returns the QuoteCheckFeedback" do
post api_v1_quote_check_validation_error_detail_feedbacks_url(
quote_check_id: quote_check_id,
validation_error_detail_id: validation_error_details_id
), params: quote_check_feedback_params,
headers: basic_auth_header
expect(json.fetch("quote_check_id")).to eq(quote_check_id)
end

it "creates a QuoteCheckFeedback" do
expect do
post api_v1_quote_check_validation_error_detail_feedbacks_url(
quote_check_id: quote_check_id,
validation_error_detail_id: validation_error_details_id
), params: quote_check_feedback_params,
headers: basic_auth_header
end.to change(QuoteCheckFeedback, :count).by(1)
end

context "with wrong error details id" do
it "returns a not found response" do
post api_v1_quote_check_validation_error_detail_feedbacks_url(
quote_check_id: quote_check_id,
validation_error_detail_id: "wrong"
),
params: quote_check_feedback_params,
headers: basic_auth_header
expect(response).to have_http_status(:not_found)
end
end
# rubocop:enable RSpec/ExampleLength
end
end
46 changes: 46 additions & 0 deletions swagger/v1/mon-devis-sans-oublis_api_v1_swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,52 @@ paths:
required:
- validation_error_details_id
- is_helpful
"/quote_checks/{quote_check_id}/error_details/{error_details_id}/feedbacks":
post:
summary: Déposer un retour
tags:
- Devis
security:
- basic_auth: []
parameters:
- name: quote_check_id
in: path
required: true
schema:
type: string
- name: error_details_id
in: path
required: true
schema:
type: string
responses:
'201':
description: Retour téléversé
content:
application/json:
schema:
"$ref": "#/components/schemas/quote_check_feedback"
'422':
description: missing params
content:
application/json:
schema:
"$ref": "#/components/schemas/api_error"
requestBody:
content:
application/json:
schema:
type: object
properties:
is_helpful:
type: boolean
nullable: false
comment:
type: string
nullable: true
maxLength: 1000
required:
- is_helpful
"/quote_checks":
post:
summary: Téléverser un devis
Expand Down

0 comments on commit 0e1b65a

Please sign in to comment.