request_handler 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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