request_handler 2.2.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +8 -2
  3. data/.rubocop.yml +13 -14
  4. data/.rubocop_todo.yml +105 -0
  5. data/CHANGELOG.md +10 -1
  6. data/Gemfile +1 -10
  7. data/Guardfile +4 -4
  8. data/Rakefile +7 -6
  9. data/bin/console +3 -3
  10. data/lib/request_handler/base.rb +42 -38
  11. data/lib/request_handler/body_parser.rb +5 -4
  12. data/lib/request_handler/builder/base.rb +1 -1
  13. data/lib/request_handler/builder/body_builder.rb +1 -1
  14. data/lib/request_handler/builder/fieldsets_builder.rb +2 -2
  15. data/lib/request_handler/builder/fieldsets_resource_builder.rb +1 -1
  16. data/lib/request_handler/builder/filter_builder.rb +1 -1
  17. data/lib/request_handler/builder/headers_builder.rb +1 -1
  18. data/lib/request_handler/builder/include_options_builder.rb +1 -1
  19. data/lib/request_handler/builder/multipart_builder.rb +2 -2
  20. data/lib/request_handler/builder/multipart_resource_builder.rb +1 -1
  21. data/lib/request_handler/builder/options_builder.rb +12 -10
  22. data/lib/request_handler/builder/page_builder.rb +2 -2
  23. data/lib/request_handler/builder/page_resource_builder.rb +1 -1
  24. data/lib/request_handler/builder/query_builder.rb +1 -1
  25. data/lib/request_handler/builder/sort_options_builder.rb +1 -1
  26. data/lib/request_handler/concerns/config_helper.rb +2 -2
  27. data/lib/request_handler/config.rb +3 -3
  28. data/lib/request_handler/document_parser.rb +6 -6
  29. data/lib/request_handler/error.rb +17 -1
  30. data/lib/request_handler/fieldsets_parser.rb +28 -24
  31. data/lib/request_handler/filter_parser.rb +15 -13
  32. data/lib/request_handler/header_parser.rb +10 -9
  33. data/lib/request_handler/include_option_parser.rb +18 -17
  34. data/lib/request_handler/json_api_document_parser.rb +31 -15
  35. data/lib/request_handler/json_parser.rb +4 -3
  36. data/lib/request_handler/multipart_parser.rb +20 -15
  37. data/lib/request_handler/option_parser.rb +3 -3
  38. data/lib/request_handler/page_parser.rb +33 -25
  39. data/lib/request_handler/query_parser.rb +6 -6
  40. data/lib/request_handler/schema_parser.rb +20 -17
  41. data/lib/request_handler/sort_option_parser.rb +19 -15
  42. data/lib/request_handler/validation/definition_engine.rb +8 -6
  43. data/lib/request_handler/validation/dry_engine.rb +9 -7
  44. data/lib/request_handler/validation/engine.rb +4 -3
  45. data/lib/request_handler/validation/errors.rb +2 -0
  46. data/lib/request_handler/validation/result.rb +1 -0
  47. data/lib/request_handler/version.rb +1 -1
  48. data/lib/request_handler.rb +8 -8
  49. data/request_handler.gemspec +42 -36
  50. metadata +179 -52
  51. data/lib/request_handler/base_parser.rb +0 -9
@@ -4,7 +4,7 @@ module RequestHandler
4
4
  module Concerns
5
5
  module ConfigHelper
6
6
  def lookup!(hash, key)
7
- lookup(hash, key) || (raise NoConfigAvailableError, key.to_sym => 'is not configured')
7
+ lookup(hash, key) || (raise NoConfigAvailableError.new(key.to_sym => "is not configured"))
8
8
  end
9
9
 
10
10
  def lookup(config, key)
@@ -12,7 +12,7 @@ module RequestHandler
12
12
  end
13
13
 
14
14
  def symbolize_key(key)
15
- key.split('.').map(&:to_sym)
15
+ key.split(".").map(&:to_sym)
16
16
  end
17
17
 
18
18
  def deep_to_h(obj)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'docile'
3
+ require "docile"
4
4
 
5
5
  module RequestHandler
6
6
  class Config
@@ -11,7 +11,7 @@ module RequestHandler
11
11
  attr_accessor :config
12
12
 
13
13
  def lookup!(key)
14
- lookup(key) || (raise NoConfigAvailableError, key.to_sym => 'is not configured')
14
+ lookup(key) || (raise NoConfigAvailableError.new(key.to_sym => "is not configured"))
15
15
  end
16
16
 
17
17
  def lookup(key)
@@ -21,7 +21,7 @@ module RequestHandler
21
21
  private
22
22
 
23
23
  def symbolize_key(key)
24
- key.split('.').map(&:to_sym)
24
+ key.split(".").map(&:to_sym)
25
25
  end
26
26
 
27
27
  def deep_to_h(obj)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'request_handler/json_api_document_parser'
4
- require 'request_handler/json_parser'
3
+ require "request_handler/json_api_document_parser"
4
+ require "request_handler/json_parser"
5
5
 
6
6
  module RequestHandler
7
7
  module DocumentParser
@@ -12,13 +12,13 @@ module RequestHandler
12
12
  type = type.to_sym unless type.nil?
13
13
  PARSER_MAPPING
14
14
  .fetch(type) { raise InternalArgumentError.new(detail: "parser for type '#{type}' not found") }
15
- .new(args)
15
+ .new(**args)
16
16
  end
17
17
 
18
18
  PARSER_MAPPING = {
19
- nil => JsonApiDocumentParser, # no config defaults to jsonapi
20
- :jsonapi => JsonApiDocumentParser,
21
- :json => JsonParser
19
+ nil => JsonApiDocumentParser, # no config defaults to jsonapi
20
+ :jsonapi => JsonApiDocumentParser,
21
+ :json => JsonParser
22
22
  }.freeze
23
23
  end
24
24
  end
@@ -3,6 +3,7 @@
3
3
  module RequestHandler
4
4
  class BaseError < StandardError
5
5
  attr_reader :errors
6
+
6
7
  def initialize(errors)
7
8
  @errors = errors
8
9
  super(message)
@@ -11,13 +12,16 @@ module RequestHandler
11
12
  def message
12
13
  errors.map do |key, value|
13
14
  "#{key}: #{value}"
14
- end.join(', ')
15
+ end.join(", ")
15
16
  end
16
17
  end
18
+
17
19
  class InternalBaseError < BaseError
18
20
  end
21
+
19
22
  class ExternalBaseError < BaseError
20
23
  end
24
+
21
25
  class JsonApiError < ExternalBaseError
22
26
  def message
23
27
  @errors.map do |error|
@@ -29,31 +33,43 @@ module RequestHandler
29
33
  RequestHandler.configuration.raise_jsonapi_errors ? @errors : []
30
34
  end
31
35
  end
36
+
32
37
  class MissingArgumentError < InternalBaseError
33
38
  end
39
+
34
40
  class ExternalArgumentError < JsonApiError
35
41
  end
42
+
36
43
  class InternalArgumentError < InternalBaseError
37
44
  end
45
+
38
46
  class SchemaValidationError < JsonApiError
39
47
  end
48
+
40
49
  class OptionNotAllowedError < JsonApiError
41
50
  end
51
+
42
52
  class NoConfigAvailableError < InternalBaseError
43
53
  end
44
54
 
45
55
  class BodyParamsError < ExternalArgumentError
46
56
  end
57
+
47
58
  class FieldsetsParamsError < ExternalArgumentError
48
59
  end
60
+
49
61
  class FilterParamsError < ExternalArgumentError
50
62
  end
63
+
51
64
  class IncludeParamsError < ExternalArgumentError
52
65
  end
66
+
53
67
  class PageParamsError < ExternalArgumentError
54
68
  end
69
+
55
70
  class SortParamsError < ExternalArgumentError
56
71
  end
72
+
57
73
  class MultipartParamsError < ExternalArgumentError
58
74
  end
59
75
  end
@@ -1,24 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'request_handler/schema_parser'
4
- require 'request_handler/error'
3
+ require "request_handler/schema_parser"
4
+ require "request_handler/error"
5
5
  module RequestHandler
6
6
  class FieldsetsParser
7
7
  def initialize(params:, allowed: {}, required: [])
8
8
  @params = params
9
9
  allowed.reject! { |_k, v| v == false }
10
10
  allowed.each_pair do |_key, value|
11
- raise InternalArgumentError, allowed: 'must be a Schema or a Boolean' unless
11
+ raise InternalArgumentError.new(allowed: "must be a Schema or a Boolean") unless
12
12
  RequestHandler.configuration.validation_engine.valid_schema?(value) ||
13
- value.is_a?(TrueClass) || value.is_a?(FalseClass)
13
+ value.is_a?(TrueClass) || value.is_a?(FalseClass)
14
14
  end
15
15
  @allowed = allowed
16
- raise InternalArgumentError, required: 'must be an Array' unless required.is_a?(Array)
16
+ raise InternalArgumentError.new(required: "must be an Array") unless required.is_a?(Array)
17
+
17
18
  @required = required
18
19
  end
19
20
 
20
21
  def run
21
- fields = params['fields']
22
+ fields = params["fields"]
22
23
  raise_missing_fields_param unless fields
23
24
  fieldsets = fields.to_h.each_with_object({}) do |(type, values), memo|
24
25
  type = type.to_sym
@@ -31,7 +32,7 @@ module RequestHandler
31
32
  private
32
33
 
33
34
  def parse_options(type, values)
34
- values.split(',').map! do |option|
35
+ values.split(",").map! do |option|
35
36
  parse_option(type, option)
36
37
  end
37
38
  end
@@ -43,45 +44,48 @@ module RequestHandler
43
44
  RequestHandler.configuration.validation_engine.validate!(option, allowed[type]).output.to_sym
44
45
  end
45
46
  rescue Validation::Error
46
- raise FieldsetsParamsError, [{ code: 'INVALID_QUERY_PARAMETER',
47
- status: '400',
48
- detail: "allowed fieldset does not include '#{option}'",
49
- source: { parameter: "fields[#{type}]" } }]
47
+ raise FieldsetsParamsError.new([{ code: "INVALID_QUERY_PARAMETER",
48
+ status: "400",
49
+ detail: "allowed fieldset does not include '#{option}'",
50
+ source: { parameter: "fields[#{type}]" } }])
50
51
  end
51
52
 
52
53
  def check_required_fieldsets_types(fieldsets)
53
54
  missing = required - fieldsets.keys
54
55
  return fieldsets if missing.empty?
56
+
55
57
  raise_missing_fieldsets!(missing)
56
58
  end
57
59
 
58
60
  def raise_invalid_field_option(type)
59
- return if allowed.dig(type)
60
- raise OptionNotAllowedError, [
61
- {
62
- code: 'INVALID_QUERY_PARAMETER',
63
- status: '400',
64
- detail: "fieldset for '#{type}' not allowed",
65
- source: { parameter: "fields[#{type}]" }
66
- }
67
- ]
61
+ return if allowed[type]
62
+
63
+ raise OptionNotAllowedError.new([
64
+ {
65
+ code: "INVALID_QUERY_PARAMETER",
66
+ status: "400",
67
+ detail: "fieldset for '#{type}' not allowed",
68
+ source: { parameter: "fields[#{type}]" }
69
+ }
70
+ ])
68
71
  end
69
72
 
70
73
  def raise_missing_fields_param
71
74
  return if required.empty?
75
+
72
76
  raise_missing_fieldsets!(required)
73
77
  end
74
78
 
75
79
  def raise_missing_fieldsets!(missing)
76
80
  errors = missing.map do |type|
77
81
  {
78
- code: 'MISSING_QUERY_PARAMETER',
79
- status: '400',
80
- source: { parameter: '' },
82
+ code: "MISSING_QUERY_PARAMETER",
83
+ status: "400",
84
+ source: { parameter: "" },
81
85
  detail: "missing required parameter fields[#{type}]"
82
86
  }
83
87
  end
84
- raise FieldsetsParamsError, errors
88
+ raise FieldsetsParamsError.new(errors)
85
89
  end
86
90
 
87
91
  attr_reader :params, :allowed, :required
@@ -1,51 +1,53 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'request_handler/schema_parser'
4
- require 'request_handler/error'
3
+ require "request_handler/schema_parser"
4
+ require "request_handler/error"
5
5
  module RequestHandler
6
6
  class FilterParser < SchemaParser
7
7
  def initialize(params:, schema:, additional_url_filter:, schema_options: {})
8
8
  super(schema: schema, schema_options: schema_options)
9
- @filter = params.fetch('filter') { {} }
10
- raise FilterParamsError, [jsonapi_filter_syntax_error] unless @filter.is_a?(Hash)
9
+ @filter = params.fetch("filter") { {} }
10
+ raise FilterParamsError.new([jsonapi_filter_syntax_error]) unless @filter.is_a?(Hash)
11
+
11
12
  Array(additional_url_filter).each do |key|
12
13
  key = key.to_s
13
14
  raise build_error(key) unless @filter[key].nil?
14
- @filter[key] = params.fetch(key) { nil }
15
+
16
+ @filter[key] = params.fetch(key, nil)
15
17
  end
16
18
  end
17
19
 
18
20
  def run
19
21
  validate_schema(filter)
20
22
  rescue SchemaValidationError => e
21
- raise FilterParamsError, (e.errors.map do |schema_error|
23
+ raise FilterParamsError.new((e.errors.map do |schema_error|
22
24
  source_param = "filter[#{schema_error[:source][:pointer]}]"
23
25
  {
24
26
  detail: schema_error[:detail],
25
27
  **jsonapi_filter_base_error(source_param: source_param)
26
28
  }
27
- end)
29
+ end))
28
30
  end
29
31
 
30
32
  private
31
33
 
32
34
  def build_error(_key)
33
- InternalArgumentError.new(filter: 'the filter key was set twice')
35
+ InternalArgumentError.new(filter: "the filter key was set twice")
34
36
  end
35
37
 
36
38
  def jsonapi_filter_base_error(source_param:)
37
39
  {
38
- status: '400',
39
- code: 'INVALID_QUERY_PARAMETER',
40
+ status: "400",
41
+ code: "INVALID_QUERY_PARAMETER",
40
42
  source: { parameter: source_param }
41
43
  }
42
44
  end
43
45
 
44
46
  def jsonapi_filter_syntax_error
45
47
  {
46
- **jsonapi_filter_base_error(source_param: 'filter'),
47
- links: { about: 'https://jsonapi.org/recommendations/#filtering' },
48
- detail: 'Filter parameter must conform to JSON API recommendation'
48
+ **jsonapi_filter_base_error(source_param: "filter"),
49
+ links: { about: "https://jsonapi.org/recommendations/#filtering" },
50
+ detail: "Filter parameter must conform to JSON API recommendation"
49
51
  }
50
52
  end
51
53
 
@@ -1,16 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'request_handler/schema_parser'
4
- require 'request_handler/error'
3
+ require "request_handler/schema_parser"
4
+ require "request_handler/error"
5
5
 
6
6
  module RequestHandler
7
7
  class HeaderParser < SchemaParser
8
8
  def initialize(env:, schema: nil, schema_options: {})
9
9
  super(schema: schema, schema_options: schema_options) unless schema.nil?
10
10
 
11
- raise MissingArgumentError, env: 'is missing' if env.nil?
12
- @headers = Helper.deep_transform_keys_in_object(env.select { |k, _v| k.start_with?('HTTP_') }) do |k|
13
- k[5..-1].downcase.to_sym
11
+ raise MissingArgumentError.new(env: "is missing") if env.nil?
12
+
13
+ @headers = Helper.deep_transform_keys_in_object(env.select { |k, _v| k.start_with?("HTTP_") }) do |k|
14
+ k[5..].downcase.to_sym
14
15
  end
15
16
  end
16
17
 
@@ -25,22 +26,22 @@ module RequestHandler
25
26
  def validate_headers!
26
27
  validate_schema(headers)
27
28
  rescue SchemaValidationError => e
28
- raise ExternalArgumentError, external_argument_error_params(e)
29
+ raise ExternalArgumentError.new(external_argument_error_params(e))
29
30
  end
30
31
 
31
32
  def external_argument_error_params(error)
32
33
  error.errors.map do |schema_error|
33
34
  header = schema_error[:source][:pointer]
34
35
  {
35
- status: '400',
36
- code: "#{headers[header.to_sym] ? 'INVALID' : 'MISSING'}_HEADER",
36
+ status: "400",
37
+ code: "#{headers[header.to_sym] ? 'INVALID' : 'MISSING'}_HEADER",
37
38
  detail: "#{format_header_name(header)} #{schema_error[:detail]}"
38
39
  }
39
40
  end
40
41
  end
41
42
 
42
43
  def format_header_name(name)
43
- name.split('_').map(&:capitalize).join('-')
44
+ name.split("_").map(&:capitalize).join("-")
44
45
  end
45
46
 
46
47
  attr_reader :headers
@@ -1,43 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'request_handler/option_parser'
4
- require 'request_handler/error'
3
+ require "request_handler/option_parser"
4
+ require "request_handler/error"
5
5
  module RequestHandler
6
6
  class IncludeOptionParser < OptionParser
7
7
  def run
8
- return [] unless params.key?('include')
8
+ return [] unless params.key?("include")
9
+
9
10
  options = fetch_options
10
- raise_error('INVALID_QUERY_PARAMETER', 'must not contain a space') if options.include?(' ')
11
- allowed_options(options.split(','))
11
+ raise_error("INVALID_QUERY_PARAMETER", "must not contain a space") if options.include?(" ")
12
+ allowed_options(options.split(","))
12
13
  end
13
14
 
14
15
  def allowed_options(options)
15
16
  options.map do |option|
16
- option.gsub!('.', ::RequestHandler.configuration.separator)
17
+ option.gsub!(".", ::RequestHandler.configuration.separator)
17
18
  begin
18
19
  RequestHandler.configuration.validation_engine.validate!(option, allowed_options_type).output.to_sym
19
20
  rescue Validation::Error
20
- raise_error('OPTION_NOT_ALLOWED', "#{option} is not an allowed include option", OptionNotAllowedError)
21
+ raise_error("OPTION_NOT_ALLOWED", "#{option} is not an allowed include option", OptionNotAllowedError)
21
22
  end
22
23
  end
23
24
  end
24
25
 
25
26
  def fetch_options
26
- raise_error('INVALID_QUERY_PARAMETER', 'must not be empty') if empty_param?('include')
27
- params.fetch('include') { '' }
27
+ raise_error("INVALID_QUERY_PARAMETER", "must not be empty") if empty_param?("include")
28
+ params.fetch("include", "")
28
29
  end
29
30
 
30
31
  private
31
32
 
32
33
  def raise_error(code, detail, error_klass = IncludeParamsError)
33
- raise error_klass, [
34
- {
35
- status: '400',
36
- code: code,
37
- detail: detail,
38
- source: { parameter: 'include' }
39
- }
40
- ]
34
+ raise error_klass.new([
35
+ {
36
+ status: "400",
37
+ code: code,
38
+ detail: detail,
39
+ source: { parameter: "include" }
40
+ }
41
+ ])
41
42
  end
42
43
  end
43
44
  end
@@ -1,13 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'request_handler/schema_parser'
4
- require 'request_handler/error'
3
+ require "request_handler/schema_parser"
4
+ require "request_handler/error"
5
5
  module RequestHandler
6
6
  class JsonApiDocumentParser < SchemaParser
7
7
  NON_ATTRIBUTE_MEMBERS = %i[id type meta links].freeze
8
+ # SEE: https://jsonapi.org/format/1.0/#document-resource-objects
9
+ VALID_DATA_MEMBERS = %w[id type attributes relationships links meta].freeze
8
10
 
9
11
  def initialize(document:, schema:, schema_options: {})
10
- raise MissingArgumentError, "data": 'is missing' if document.nil?
12
+ raise MissingArgumentError.new(data: "is missing") if document.nil?
13
+
11
14
  super(schema: schema, schema_options: schema_options)
12
15
  @document = document
13
16
  end
@@ -20,25 +23,38 @@ module RequestHandler
20
23
  private
21
24
 
22
25
  def flattened_document
23
- resource = document.fetch('data') do
24
- raise BodyParamsError, [{ code: 'INVALID_JSON_API',
25
- status: '400',
26
- title: 'Body is not valid JSON API payload',
27
- detail: "Member 'data' is missing",
28
- source: { pointer: '/' } }]
26
+ resource = document.fetch("data") do
27
+ raise BodyParamsError.new([{ code: "INVALID_JSON_API",
28
+ status: "400",
29
+ title: "Body is not a valid JSON API payload",
30
+ detail: "Member 'data' is missing",
31
+ source: { pointer: "/" } }])
29
32
  end
33
+ validate_json_api_data_members(resource)
30
34
  flatten_resource!(resource)
31
35
  end
32
36
 
37
+ def validate_json_api_data_members(data)
38
+ data.each_key do |k|
39
+ next if VALID_DATA_MEMBERS.include?(k)
40
+
41
+ raise BodyParamsError.new([{ code: "INVALID_JSON_API",
42
+ status: "400",
43
+ title: "Body is not a valid JSON API payload",
44
+ detail: "Member 'data' contains invalid member!",
45
+ source: { pointer: "/data/#{k}" } }])
46
+ end
47
+ end
48
+
33
49
  def flatten_resource!(resource)
34
- resource.merge!(resource.delete('attributes') { {} })
35
- relationships = flatten_relationship_resource_linkages(resource.delete('relationships') { {} })
50
+ resource.merge!(resource.delete("attributes") { {} })
51
+ relationships = flatten_relationship_resource_linkages(resource.delete("relationships") { {} })
36
52
  resource.merge!(relationships)
37
53
  end
38
54
 
39
55
  def flatten_relationship_resource_linkages(relationships)
40
56
  relationships.each_with_object({}) do |(k, v), memo|
41
- resource_linkage = v['data']
57
+ resource_linkage = v["data"]
42
58
  memo[k] = resource_linkage
43
59
  end
44
60
  end
@@ -46,9 +62,9 @@ module RequestHandler
46
62
  def build_pointer(error)
47
63
  non_nested_identifier = error[:schema_pointer] == error[:element].to_s
48
64
  non_attribute_member = NON_ATTRIBUTE_MEMBERS.include?(error[:element])
49
- ['/data',
50
- ('attributes' unless non_attribute_member && non_nested_identifier),
51
- error[:schema_pointer]].compact.join('/')
65
+ ["/data",
66
+ ("attributes" unless non_attribute_member && non_nested_identifier),
67
+ error[:schema_pointer]].compact.join("/")
52
68
  end
53
69
 
54
70
  attr_reader :document
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'request_handler/schema_parser'
4
- require 'request_handler/error'
3
+ require "request_handler/schema_parser"
4
+ require "request_handler/error"
5
5
  module RequestHandler
6
6
  class JsonParser < SchemaParser
7
7
  def initialize(document:, schema:, schema_options: {})
8
- raise MissingArgumentError, "json": 'no content sent in document' if document.nil?
8
+ raise MissingArgumentError.new(json: "no content sent in document") if document.nil?
9
+
9
10
  super(schema: schema, schema_options: schema_options)
10
11
  @document = document
11
12
  end
@@ -1,23 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'request_handler/error'
4
- require 'request_handler/base_parser'
5
- require 'request_handler/schema_parser'
6
- require 'request_handler/document_parser'
3
+ require "request_handler/concerns/config_helper"
4
+ require "request_handler/document_parser"
5
+ require "request_handler/error"
6
+ require "request_handler/schema_parser"
7
7
 
8
8
  module RequestHandler
9
- class MultipartsParser < BaseParser
9
+ class MultipartsParser
10
+ include RequestHandler::Concerns::ConfigHelper
11
+
10
12
  def initialize(request:, multipart_config:)
11
13
  @request = request
12
14
  @params = request.params
13
15
  @multipart_config = multipart_config
14
- raise MissingArgumentError, [{ multipart_config: 'is missing' }] if multipart_config.nil?
16
+ raise MissingArgumentError.new([{ multipart_config: "is missing" }]) if multipart_config.nil?
15
17
  end
16
18
 
17
19
  def run
18
20
  deep_to_h(multipart_config).each_with_object({}) do |(name, config), indexed_parts|
19
21
  validate_presence!(name) if config[:required]
20
22
  next if params[name.to_s].nil?
23
+
21
24
  indexed_parts[name] = parse_part(name.to_s)
22
25
  end
23
26
  end
@@ -26,19 +29,20 @@ module RequestHandler
26
29
 
27
30
  def validate_presence!(sidecar_name)
28
31
  return if params.key?(sidecar_name.to_s)
32
+
29
33
  raise multipart_params_error("missing required sidecar resource: #{sidecar_name}")
30
34
  end
31
35
 
32
- def multipart_params_error(detail = '')
36
+ def multipart_params_error(detail = "")
33
37
  MultipartParamsError.new([{
34
- status: '400',
35
- code: 'INVALID_MULTIPART_REQUEST',
38
+ status: "400",
39
+ code: "INVALID_MULTIPART_REQUEST",
36
40
  detail: detail
37
41
  }])
38
42
  end
39
43
 
40
44
  def parse_part(name)
41
- params[name].fetch(:tempfile) { raise MultipartParamsError, [{ multipart_file: 'missing' }] }
45
+ params[name].fetch(:tempfile) { raise MultipartParamsError.new([{ multipart_file: "missing" }]) }
42
46
  if lookup(multipart_config, "#{name}.schema")
43
47
  parse_data(name)
44
48
  else
@@ -50,10 +54,10 @@ module RequestHandler
50
54
  data = load_json(name)
51
55
  type = lookup(multipart_config, "#{name}.type")
52
56
  DocumentParser.new(
53
- type: type,
54
- document: data,
55
- schema: lookup(multipart_config, "#{name}.schema"),
56
- schema_options: execute_options(lookup(multipart_config, "#{name}.options"))
57
+ type: type,
58
+ document: data,
59
+ schema: lookup(multipart_config, "#{name}.schema"),
60
+ schema_options: execute_options(lookup(multipart_config, "#{name}.options"))
57
61
  ).run
58
62
  end
59
63
 
@@ -63,7 +67,7 @@ module RequestHandler
63
67
  file = file.read
64
68
  MultiJson.load(file)
65
69
  rescue MultiJson::ParseError
66
- raise multipart_params_error('sidecar resource is not valid JSON')
70
+ raise multipart_params_error("sidecar resource is not valid JSON")
67
71
  end
68
72
 
69
73
  def multipart_file(name)
@@ -73,6 +77,7 @@ module RequestHandler
73
77
  def execute_options(options)
74
78
  return {} if options.nil?
75
79
  return options unless options.respond_to?(:call)
80
+
76
81
  options.call(self, request)
77
82
  end
78
83
 
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'request_handler/error'
3
+ require "request_handler/error"
4
4
  module RequestHandler
5
5
  class OptionParser
6
6
  def initialize(params:, allowed_options_type:)
7
7
  @params = params
8
8
  @allowed_options_type = allowed_options_type
9
- raise InternalArgumentError, allowed_options_type: 'must be a Schema' unless schema?
9
+ raise InternalArgumentError.new(allowed_options_type: "must be a Schema") unless schema?
10
10
  end
11
11
 
12
12
  private
@@ -16,7 +16,7 @@ module RequestHandler
16
16
  end
17
17
 
18
18
  def empty_param?(param)
19
- params.fetch(param) { nil } == ''
19
+ params.fetch(param, nil) == ""
20
20
  end
21
21
  attr_reader :params, :allowed_options_type
22
22
  end