require "pact_broker/api/decorators/base_decorator" # Decorates the individual validation error message Dry::Validation::Message module PactBroker module Api module Decorators class EmbeddedErrorProblemJsonDecorator < BaseDecorator property :type, getter: -> (decorator:, user_options:, **) { decorator.type(user_options[:base_url]) } property :title, exec_context: :decorator property :text, as: :detail property :pointer, exec_context: :decorator property :parameter, exec_context: :decorator # dry-validation doesn't support validating a top level array, so we wrap # the json patch operations array in a hash with the key :_ops to validate it. # When we render the error, we have to remove the /_ops prefix from the pointer. # For contracts where we validate the path and the body together using _path and _body # we also need to remove the first key from the path. # It's possible the pointer should have a # at the start of it as per https://www.rfc-editor.org/rfc/rfc6901 :shrug: def pointer if is_path_error? nil # _ops, _path or _body for use when we need to hack the way dry-validation schemas work elsif represented.path.first.to_s.start_with?("_") "/" + represented.path[1..-1].join("/") else "/" + represented.path.join("/") end end def parameter if is_path_error? represented.path.last.to_s else nil end end def title if is_path_error? "Invalid path segment" else "Invalid body parameter" end end # @param [String] base_url def type(base_url) if is_path_error? "#{base_url}/#{path_type}" else "#{base_url}/#{body_type}" end end def path_type if represented.text.include?("missing") "problems/missing-request-parameter" elsif represented.text.include?("format") "problems/invalid-request-parameter-format" else "problems/invalid-request-parameter-value" end end def body_type if represented.text.include?("missing") "problems/missing-body-property" elsif represented.text.include?("format") "problems/invalid-body-property-format" else "problems/invalid-body-property-value" end end def is_path_error? represented.path.first == :_path end end end end end