request_handler 0.11.0 → 0.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1d0758f2d7885ad1d5bc730ab95fbc00428effed
4
- data.tar.gz: bc11401b7013aa968bd7d22a4d86b674fedf147f
3
+ metadata.gz: a6cf97cca0464ee4cd04d685441600aadfa55197
4
+ data.tar.gz: dde5d38dac0cf15bb3103a78862219d0fcc26925
5
5
  SHA512:
6
- metadata.gz: e9d5ab0fd020c635be86bfd6c028768c9c6eb6c9e401be243bb3118c7a4e98f1af7db529cf44d5e41fcd178562c805042cc8a60d96a26ce5554cfcc2004da0d8
7
- data.tar.gz: 5273a2cbf95cb99f33d243f174832a9597a27b0280785b0ea39f5a4ee0d6e3fd8bf2478b80b4e170d92658c5d41901e3b78fda8224c2190c7a7c2c6cbda58a91
6
+ metadata.gz: 9d0f9d84f1864af7c3ba99ae27d225ba3fcb6afc8e35c447916e5ef9d84eb7438cc861295429fd715f7667f5fc5689c27d4923b1c8cb185a12d53eea7f7fce11
7
+ data.tar.gz: afdf18bfb0c580d0a63a4053a6717a5d78cd69f154e9d93de058e190461a6707d31c62abd30e8b6d84116a96b7b0d2dc3f172581581d74d9b039e03eeaa6894e
data/.rubocop.yml CHANGED
@@ -1,6 +1,8 @@
1
1
  # minitest specifics
2
2
  AllCops:
3
- TargetRubyVersion: 2.1
3
+ TargetRubyVersion: 2.2
4
+ Exclude:
5
+ - Dangerfile
4
6
  Metrics/LineLength:
5
7
  Max: 119
6
8
  Metrics/MethodLength:
@@ -13,5 +15,7 @@ Style/ClassAndModuleChildren:
13
15
  Exclude:
14
16
  - test/**/*
15
17
 
18
+ Metrics/BlockLength:
19
+ Enabled: false
16
20
  Style/Documentation:
17
21
  Enabled: false
data/.travis.yml CHANGED
@@ -1,11 +1,10 @@
1
1
  language: ruby
2
2
  cache: bundler
3
3
  rvm:
4
- - 2.1.10
5
- - 2.2.6
6
- - 2.3.3
7
- - 2.4.0
8
- - jruby-9.1.7.0
4
+ - 2.2.7
5
+ - 2.3.4
6
+ - 2.4.1
7
+ - jruby-9.1.8.0
9
8
  jdk:
10
9
  - oraclejdk8
11
10
  env:
@@ -13,24 +12,21 @@ env:
13
12
  - "JRUBY_OPTS='-Xcompile.invokedynamic=true --debug'"
14
13
  matrix:
15
14
  exclude:
16
- - rvm: 2.1.10
15
+ - rvm: 2.2.7
17
16
  jdk: oraclejdk8
18
17
  env: "JRUBY_OPTS='-Xcompile.invokedynamic=true --debug'"
19
- - rvm: 2.2.6
18
+ - rvm: 2.3.4
20
19
  jdk: oraclejdk8
21
20
  env: "JRUBY_OPTS='-Xcompile.invokedynamic=true --debug'"
22
- - rvm: 2.3.3
23
- jdk: oraclejdk8
24
- env: "JRUBY_OPTS='-Xcompile.invokedynamic=true --debug'"
25
- - rvm: 2.4.0
21
+ - rvm: 2.4.1
26
22
  jdk: oraclejdk8
27
23
  env: "JRUBY_OPTS='-Xcompile.invokedynamic=true --debug'"
28
24
  allow_failures:
29
- - rvm: jruby-9.1.7.0
25
+ - rvm: jruby-9.1.8.0
30
26
  jdk: oraclejdk8
31
27
  env: "JRUBY_OPTS='-Xcompile.invokedynamic=true --debug'"
32
28
  before_install:
33
29
  - gem update --system
34
- - gem install bundler -v 1.13.6
30
+ - gem install bundler -v 1.14.6
35
31
  before_script:
36
32
  - bundle exec danger
data/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@ Changelog
3
3
 
4
4
  ## master
5
5
 
6
+ ## 0.12.0
7
+
8
+ - support for multipart-requests
9
+ - update rubocop and fix danger check
10
+ - drop support for ruby 2.1 (dry-types does not support it anymore either which makes supporting it here pointless)
11
+ - adapt fieldset validation to allow all fields in addition to a specific enum
12
+ - no need for 'required' field in fieldsets_parser anymore
13
+ - throw different errors for each parser, all new errors inherit from ExternalArgumentError
14
+
6
15
  ## 0.11.0
7
16
 
8
17
  - Parse `included` array from request body
data/Dangerfile CHANGED
@@ -3,24 +3,24 @@
3
3
  # --------------------------------------------------------------------------------------------------------------------
4
4
  has_app_changes = !git.modified_files.grep(/lib/).empty?
5
5
  has_test_changes = !git.modified_files.grep(/spec/).empty?
6
- is_version_bump = git.modified_files.sort == ["CHANGELOG.md", "lib/request_handler/version.rb"].sort
6
+ is_version_bump = git.modified_files.sort == ['CHANGELOG.md', 'lib/request_handler/version.rb'].sort
7
7
 
8
8
  if has_app_changes && !has_test_changes && !is_version_bump
9
9
  warn("Tests were not updated. That's OK if you're refactoring existing code.", sticky: false)
10
10
  end
11
11
 
12
- if !git.modified_files.include?("CHANGELOG.md") && has_app_changes
12
+ if !git.modified_files.include?('CHANGELOG.md') && has_app_changes
13
13
  fail("Please include a CHANGELOG entry. \nYou can find it at [CHANGELOG.md](https://github.com/request_handler/request_handler/blob/master/CHANGELOG.md).")
14
14
  message "Note, we hard-wrap at 80 chars and use 2 spaces after the last line."
15
15
  end
16
16
 
17
17
  # Make it more obvious that a PR is a work in progress and shouldn't be merged yet
18
- warn("PR is classed as Work in Progress") if github.pr_title.include? "WIP"
18
+ warn('PR is classed as Work in Progress') if github.pr_title.include? 'WIP'
19
19
 
20
20
  # Warn when there is a big PR
21
- warn("Big PR") if git.lines_of_code > 500
21
+ warn('Big PR') if git.lines_of_code > 500
22
22
 
23
23
  commit_lint.check warn: :all, disable: [:subject_cap]
24
24
 
25
25
  # rubocop
26
- rubocop.lint "*"
26
+ rubocop.lint
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  source 'https://rubygems.org'
3
4
 
4
5
  # Specify your gem's dependencies in dry-request_handler.gemspec
data/Guardfile CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # A sample Guardfile
3
4
  # More info at https://github.com/guard/guard#readme
4
5
 
data/README.md CHANGED
@@ -272,6 +272,75 @@ The resulting `body_params` will be this:
272
272
  ]
273
273
  ```
274
274
 
275
+ ### Multipart requests
276
+ It is also possible to process and validate multipart requests, consisting of an arbitrary number of parts.
277
+
278
+ The following request handler accepts a question (which will be uploaded as a json-file) and an additional
279
+ file related to the question
280
+
281
+ ```ruby
282
+ class CreateQuestionHandler < RequestHandler::Base
283
+ options do
284
+ multipart do
285
+ question do
286
+ schema(
287
+ Dry::Validation.JSON do
288
+ required(:id).filled(:str?)
289
+ required(:type).filled(:str?)
290
+ required(:content).filled(:str?)
291
+ end
292
+ )
293
+ end
294
+
295
+ file do
296
+ # no validation necessary
297
+ end
298
+ end
299
+ end
300
+
301
+ def to_dto
302
+ # see the resulting multipart_params below
303
+ { multipart: multipart_params }
304
+ end
305
+ end
306
+ ```
307
+
308
+ Assuming that the request consists of a json file `question.json` containing
309
+ ``` json
310
+ {
311
+ "data": {
312
+ "id": "1",
313
+ "type": "questions",
314
+ "attributes": {
315
+ "content": "How much is the fish?"
316
+ }
317
+ }
318
+ }
319
+ ```
320
+
321
+ and an additional file `image.png`, the resulting `multipart_params` will be the following:
322
+
323
+ ``` ruby
324
+ {
325
+ question:
326
+ {
327
+ id: '1',
328
+ type: 'questions',
329
+ content: 'How much is the fish?'
330
+ },
331
+ file:
332
+ {
333
+ filename: 'image.png',
334
+ type: 'application/octet-stream'
335
+ name: 'file',
336
+ tempfile: #<Tempfile:/...>,
337
+ head: 'Content-Disposition: form-data;...'
338
+ }
339
+ }
340
+ ```
341
+
342
+ Please note that each part's content has to be uploaded as a separate file currently.
343
+
275
344
  ### Configuration
276
345
 
277
346
  The default logger and separator can be changed globally by using
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'bundler/gem_tasks'
3
4
 
4
5
  task :init do
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'request_handler/filter_parser'
3
4
  require 'request_handler/page_parser'
4
5
  require 'request_handler/include_option_parser'
5
6
  require 'request_handler/sort_option_parser'
6
7
  require 'request_handler/header_parser'
7
8
  require 'request_handler/body_parser'
9
+ require 'request_handler/multipart_parser'
8
10
  require 'request_handler/fieldsets_parser'
9
11
  require 'request_handler/helper'
10
12
  require 'confstruct'
@@ -55,6 +57,10 @@ module RequestHandler
55
57
  @body_params ||= parse_body_params
56
58
  end
57
59
 
60
+ def multipart_params
61
+ @multipart_params ||= parse_multipart_params
62
+ end
63
+
58
64
  def fieldsets_params
59
65
  @fieldsets_params ||= parse_fieldsets_params
60
66
  end
@@ -103,10 +109,17 @@ module RequestHandler
103
109
  ).run
104
110
  end
105
111
 
112
+ def parse_multipart_params
113
+ MultipartsParser.new(
114
+ request: request,
115
+ multipart_config: lookup!('multipart')
116
+ ).run
117
+ end
118
+
106
119
  def parse_fieldsets_params
107
120
  FieldsetsParser.new(params: params,
108
121
  allowed: lookup!('fieldsets.allowed'),
109
- required: lookup!('fieldsets.required')).run
122
+ required: lookup('fieldsets.required') || []).run
110
123
  end
111
124
 
112
125
  def fetch_defaults(key, default)
@@ -1,55 +1,29 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'request_handler/schema_parser'
3
4
  require 'request_handler/error'
5
+ require 'request_handler/json_api_document_parser'
4
6
  module RequestHandler
5
- class BodyParser < SchemaParser
7
+ class BodyParser
6
8
  def initialize(request:, schema:, schema_options: {}, included_schemas: {})
7
- raise MissingArgumentError, :"request.body" => 'is missing' if request.body.nil?
8
- super(schema: schema, schema_options: schema_options)
9
+ raise MissingArgumentError, "request.body": 'is missing' if request.body.nil?
9
10
  @request = request
11
+ @schema = schema
12
+ @schema_options = schema_options
10
13
  @included_schemas = included_schemas
11
14
  end
12
15
 
13
16
  def run
14
- body, *included = flattened_request_body
15
- unless included_schemas?
16
- raise SchemaValidationError, included: 'must be empty' unless included.empty?
17
- return validate_schema(body)
18
- end
19
-
20
- validate_schemas(body, included)
17
+ JsonApiDocumentParser.new(
18
+ document: request_body,
19
+ schema: schema,
20
+ schema_options: schema_options,
21
+ included_schemas: included_schemas
22
+ ).run
21
23
  end
22
24
 
23
25
  private
24
26
 
25
- def flattened_request_body
26
- body = request_body.fetch('data') do
27
- raise ExternalArgumentError, body: 'must contain data'
28
- end
29
- [flatten_resource!(body), *parse_included]
30
- end
31
-
32
- def flatten_resource!(resource)
33
- resource.merge!(resource.delete('attributes') { {} })
34
- relationships = flatten_relationship_resource_linkages(resource.delete('relationships') { {} })
35
- resource.merge!(relationships)
36
- end
37
-
38
- def flatten_relationship_resource_linkages(relationships)
39
- relationships.each_with_object({}) do |(k, v), memo|
40
- resource_linkage = v['data']
41
- next if resource_linkage.nil?
42
- memo[k] = resource_linkage
43
- end
44
- end
45
-
46
- def parse_included
47
- included = request_body.fetch('included') { [] }
48
- included.each do |hsh|
49
- flatten_resource!(hsh)
50
- end
51
- end
52
-
53
27
  def request_body
54
28
  b = request.body
55
29
  b.rewind
@@ -57,20 +31,6 @@ module RequestHandler
57
31
  b.empty? ? {} : MultiJson.load(b)
58
32
  end
59
33
 
60
- def included_schemas?
61
- !(included_schemas.nil? || included_schemas.empty?)
62
- end
63
-
64
- def validate_schemas(body, included)
65
- schemas = [validate_schema(body)]
66
- included_schemas.each do |type, schema|
67
- included.select { |inc| inc['type'] == type.to_s }.each do |inc|
68
- schemas << validate_schema(inc, with: schema)
69
- end
70
- end
71
- schemas
72
- end
73
-
74
- attr_reader :request, :included_schemas
34
+ attr_reader :request, :schema, :schema_options, :included_schemas
75
35
  end
76
36
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module RequestHandler
3
4
  class BaseError < StandardError
4
5
  attr_reader :errors
@@ -29,4 +30,19 @@ module RequestHandler
29
30
  end
30
31
  class NoConfigAvailableError < InternalBaseError
31
32
  end
33
+
34
+ class BodyParamsError < ExternalArgumentError
35
+ end
36
+ class FieldsetsParamsError < ExternalArgumentError
37
+ end
38
+ class FilterParamsError < ExternalArgumentError
39
+ end
40
+ class IncludeParamsError < ExternalArgumentError
41
+ end
42
+ class PageParamsError < ExternalArgumentError
43
+ end
44
+ class SortParamsError < ExternalArgumentError
45
+ end
46
+ class MultipartParamsError < ExternalArgumentError
47
+ end
32
48
  end
@@ -1,22 +1,24 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'request_handler/schema_parser'
3
4
  require 'request_handler/error'
4
5
  module RequestHandler
5
6
  class FieldsetsParser
6
7
  def initialize(params:, allowed: {}, required: [])
7
8
  @params = params
9
+ allowed.reject! { |_k, v| v == false }
8
10
  allowed.each_value do |option|
9
- raise InternalArgumentError, allowed: 'must be a Enum' unless option.is_a?(Dry::Types::Enum)
11
+ raise InternalArgumentError, allowed: 'must be a Enum or a Boolean' unless
12
+ option.is_a?(Dry::Types::Enum) || option.is_a?(TrueClass)
10
13
  end
11
14
  @allowed = allowed
12
- raise InternalArgumentError, allowed: 'must be an Array' unless required.is_a?(Array)
15
+ raise InternalArgumentError, required: 'must be an Array' unless required.is_a?(Array)
13
16
  @required = required
14
17
  end
15
18
 
16
19
  def run
17
20
  fields = params['fields']
18
21
  raise_missing_fields_param unless fields
19
-
20
22
  fieldsets = fields.to_h.each_with_object({}) do |(type, values), memo|
21
23
  type = type.to_sym
22
24
  raise_invalid_field_option(type)
@@ -34,14 +36,18 @@ module RequestHandler
34
36
  end
35
37
 
36
38
  def parse_option(type, option)
37
- allowed[type].call(option).to_sym
39
+ if allowed[type] == true
40
+ option.to_sym
41
+ else
42
+ allowed[type].call(option).to_sym
43
+ end
38
44
  rescue Dry::Types::ConstraintError
39
- raise ExternalArgumentError, fieldsets: "invalid field: <#{option}> for type: #{type}"
45
+ raise FieldsetsParamsError, fieldsets: "invalid field: <#{option}> for type: #{type}"
40
46
  end
41
47
 
42
48
  def check_required_fieldsets_types(fieldsets)
43
49
  return fieldsets if (required - fieldsets.keys).empty?
44
- raise ExternalArgumentError, fieldsets: 'missing required fieldsets parameter'
50
+ raise FieldsetsParamsError, fieldsets: 'missing required fieldsets parameter'
45
51
  end
46
52
 
47
53
  def raise_invalid_field_option(type)
@@ -51,7 +57,7 @@ module RequestHandler
51
57
 
52
58
  def raise_missing_fields_param
53
59
  return if required.empty?
54
- raise ExternalArgumentError, fieldsets: 'missing required fields options'
60
+ raise FieldsetsParamsError, fieldsets: 'missing required fields options'
55
61
  end
56
62
 
57
63
  attr_reader :params, :allowed, :required
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'request_handler/schema_parser'
3
4
  require 'request_handler/error'
4
5
  module RequestHandler
@@ -6,7 +7,7 @@ module RequestHandler
6
7
  def initialize(params:, schema:, additional_url_filter:, schema_options: {})
7
8
  super(schema: schema, schema_options: schema_options)
8
9
  @filter = params.fetch('filter') { {} }
9
- raise ExternalArgumentError, filter: 'must be a Hash' unless @filter.is_a?(Hash)
10
+ raise FilterParamsError, filter: 'must be a Hash' unless @filter.is_a?(Hash)
10
11
  Array(additional_url_filter).each do |key|
11
12
  key = key.to_s
12
13
  raise build_error(key) unless @filter[key].nil?
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'request_handler/error'
3
4
  module RequestHandler
4
5
  class HeaderParser
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module RequestHandler
3
4
  module Helper
4
5
  # extracted out of active_support
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'request_handler/option_parser'
3
4
  require 'request_handler/error'
4
5
  module RequestHandler
@@ -6,7 +7,7 @@ module RequestHandler
6
7
  def run
7
8
  return [] unless params.key?('include')
8
9
  options = fetch_options
9
- raise ExternalArgumentError, include: 'must not contain a space' if options.include? ' '
10
+ raise IncludeParamsError, include: 'must not contain a space' if options.include? ' '
10
11
  allowed_options(options.split(','))
11
12
  end
12
13
 
@@ -22,7 +23,7 @@ module RequestHandler
22
23
  end
23
24
 
24
25
  def fetch_options
25
- raise ExternalArgumentError, include_options: 'query paramter must not be empty' if empty_param?('include')
26
+ raise IncludeParamsError, include_options: 'query paramter must not be empty' if empty_param?('include')
26
27
  params.fetch('include') { '' }
27
28
  end
28
29
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'request_handler/schema_parser'
4
+ require 'request_handler/error'
5
+ module RequestHandler
6
+ class JsonApiDocumentParser < SchemaParser
7
+ def initialize(document:, schema:, schema_options: {}, included_schemas: {})
8
+ raise MissingArgumentError, "data": 'is missing' if document.nil?
9
+ super(schema: schema, schema_options: schema_options)
10
+ @document = document
11
+ @included_schemas = included_schemas
12
+ end
13
+
14
+ def run
15
+ resource, *included = flattened_document
16
+ unless included_schemas?
17
+ raise SchemaValidationError, included: 'must be empty' unless included.empty?
18
+ return validate_schema(resource)
19
+ end
20
+
21
+ validate_schemas(resource, included)
22
+ end
23
+
24
+ private
25
+
26
+ def flattened_document
27
+ resource = document.fetch('data') do
28
+ raise BodyParamsError, resource: 'must contain data'
29
+ end
30
+ [flatten_resource!(resource), *parse_included]
31
+ end
32
+
33
+ def flatten_resource!(resource)
34
+ resource.merge!(resource.delete('attributes') { {} })
35
+ relationships = flatten_relationship_resource_linkages(resource.delete('relationships') { {} })
36
+ resource.merge!(relationships)
37
+ end
38
+
39
+ def flatten_relationship_resource_linkages(relationships)
40
+ relationships.each_with_object({}) do |(k, v), memo|
41
+ resource_linkage = v['data']
42
+ next if resource_linkage.nil?
43
+ memo[k] = resource_linkage
44
+ end
45
+ end
46
+
47
+ def parse_included
48
+ included = document.fetch('included') { [] }
49
+ included.each do |hsh|
50
+ flatten_resource!(hsh)
51
+ end
52
+ end
53
+
54
+ def included_schemas?
55
+ !(included_schemas.nil? || included_schemas.empty?)
56
+ end
57
+
58
+ def validate_schemas(resource, included)
59
+ schemas = [validate_schema(resource)]
60
+ included_schemas.each do |type, schema|
61
+ included.select { |inc| inc['type'] == type.to_s }.each do |inc|
62
+ schemas << validate_schema(inc, with: schema)
63
+ end
64
+ end
65
+ schemas
66
+ end
67
+
68
+ attr_reader :document, :included_schemas
69
+ end
70
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'request_handler/error'
4
+ require 'request_handler/schema_parser'
5
+ require 'request_handler/error'
6
+ require 'request_handler/json_api_document_parser'
7
+ module RequestHandler
8
+ class MultipartsParser
9
+ def initialize(request:, multipart_config:)
10
+ @request = request
11
+ @params = request.params
12
+ @multipart_config = multipart_config
13
+ missing_arguments = []
14
+ missing_arguments << { multipart_config: 'is missing' } if multipart_config.nil?
15
+ raise MissingArgumentError, missing_arguments unless missing_arguments.empty?
16
+ end
17
+
18
+ def run
19
+ multipart_config.keys.each_with_object({}) do |name, memo|
20
+ params.fetch(name.to_s) { raise MultipartParamsError, multipart: 'missing' }
21
+ memo[name] = parse_part(name)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def parse_part(name)
28
+ params[name.to_s].fetch(:tempfile) { raise MultipartParamsError, multipart_file: 'missing' }
29
+ if lookup("#{name}.schema")
30
+ parse_data(name)
31
+ else
32
+ params[name.to_s]
33
+ end
34
+ end
35
+
36
+ def parse_data(name)
37
+ JsonApiDocumentParser.new(
38
+ document: load_json(name),
39
+ schema: lookup("#{name}.schema"),
40
+ schema_options: execute_options(lookup("#{name}.options")),
41
+ included_schemas: lookup("#{name}.included")
42
+ ).run
43
+ end
44
+
45
+ def load_json(name)
46
+ MultiJson.load(multipart_file(name).read)
47
+ rescue MultiJson::ParseError
48
+ raise MultipartParamsError, multipart_file: 'invalid'
49
+ end
50
+
51
+ def multipart_file(name)
52
+ params[name.to_s][:tempfile]
53
+ end
54
+
55
+ def lookup(key)
56
+ multipart_config.lookup!(key)
57
+ end
58
+
59
+ def execute_options(options)
60
+ return {} if options.nil?
61
+ return options unless options.respond_to?(:call)
62
+ options.call(self, request)
63
+ end
64
+
65
+ attr_reader :params, :request, :multipart_config
66
+ end
67
+ end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'request_handler/error'
3
4
  module RequestHandler
4
5
  class OptionParser
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'request_handler/error'
3
4
  module RequestHandler
4
5
  class PageParser
@@ -8,7 +9,7 @@ module RequestHandler
8
9
  missing_arguments << { page_config: 'is missing' } if page_config.nil?
9
10
  raise MissingArgumentError, missing_arguments unless missing_arguments.empty?
10
11
  @page_options = params.fetch('page') { {} }
11
- raise ExternalArgumentError, page: 'must be a Hash' unless @page_options.is_a?(Hash)
12
+ raise PageParamsError, page: 'must be a Hash' unless @page_options.is_a?(Hash)
12
13
  @config = page_config
13
14
  end
14
15
 
@@ -25,7 +26,7 @@ module RequestHandler
25
26
 
26
27
  private
27
28
 
28
- TOP_LEVEL_PAGE_KEYS = Set.new([:default_size, :max_size])
29
+ TOP_LEVEL_PAGE_KEYS = Set.new(%i[default_size max_size])
29
30
  attr_reader :page_options, :config
30
31
 
31
32
  def check_for_missing_options(config)
@@ -64,10 +65,10 @@ module RequestHandler
64
65
 
65
66
  def check_int(string:, error_msg:)
66
67
  output = Integer(string)
67
- raise ExternalArgumentError, error_msg unless output > 0
68
+ raise PageParamsError, error_msg unless output > 0
68
69
  output
69
70
  rescue ArgumentError
70
- raise ExternalArgumentError, error_msg
71
+ raise PageParamsError, error_msg
71
72
  end
72
73
 
73
74
  def apply_max_size_constraint(size, prefix)
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'request_handler/error'
3
4
  module RequestHandler
4
5
  class SchemaParser
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'request_handler/option_parser'
3
4
  require 'request_handler/error'
4
5
  require 'request_handler/sort_option'
@@ -7,12 +8,12 @@ module RequestHandler
7
8
  def run
8
9
  return [] unless params.key?('sort')
9
10
  sort_options = parse_options(fetch_options)
10
- raise ExternalArgumentError, sort_options: 'must be unique' if duplicates?(sort_options)
11
+ raise SortParamsError, sort_options: 'must be unique' if duplicates?(sort_options)
11
12
  sort_options
12
13
  end
13
14
 
14
15
  def fetch_options
15
- raise ExternalArgumentError, sort_options: 'the query paramter must not be empty' if empty_param?('sort')
16
+ raise SortParamsError, sort_options: 'the query paramter must not be empty' if empty_param?('sort')
16
17
  params.fetch('sort') { '' }.split(',')
17
18
  end
18
19
 
@@ -26,7 +27,7 @@ module RequestHandler
26
27
  end
27
28
 
28
29
  def parse_option(option)
29
- raise ExternalArgumentError, sort_options: 'must not contain a space' if option.include? ' '
30
+ raise SortParamsError, sort_options: 'must not contain a space' if option.include? ' '
30
31
  if option.start_with?('-')
31
32
  [option[1..-1], :desc]
32
33
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RequestHandler
4
- VERSION = '0.11.0'.freeze
4
+ VERSION = '0.12.0'.freeze
5
5
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'request_handler/version'
3
4
  require 'request_handler/base'
4
5
  require 'confstruct'
@@ -1,10 +1,9 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
+
3
4
  lib = File.expand_path('../lib', __FILE__)
4
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
6
  require 'request_handler/version'
6
-
7
- # rubocop:disable Metrics/BlockLength
8
7
  Gem::Specification.new do |spec|
9
8
  spec.name = 'request_handler'
10
9
  spec.version = RequestHandler::VERSION
@@ -15,7 +14,7 @@ Gem::Specification.new do |spec|
15
14
  spec.description = 'shared base for request_handler using dry-* gems'
16
15
  spec.homepage = 'https://github.com/runtastic/request_handler'
17
16
  spec.license = 'MIT'
18
- spec.required_ruby_version = '~> 2.1'
17
+ spec.required_ruby_version = '~> 2.2'
19
18
 
20
19
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
20
  f.match(%r{^(test|spec|features)/})
@@ -36,9 +35,11 @@ Gem::Specification.new do |spec|
36
35
  spec.add_development_dependency 'codecov'
37
36
 
38
37
  spec.add_development_dependency 'rubocop_runner', '~> 2.0'
39
- spec.add_development_dependency 'rubocop', '~> 0.46.0'
38
+ spec.add_development_dependency 'rubocop', '~> 0.48.1'
40
39
 
41
40
  spec.add_development_dependency 'guard'
42
41
  spec.add_development_dependency 'guard-rspec'
43
42
  spec.add_development_dependency 'guard-rubocop'
43
+
44
+ spec.add_development_dependency 'rack'
44
45
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: request_handler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Eger
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2017-03-17 00:00:00.000000000 Z
12
+ date: 2017-05-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: dry-validation
@@ -157,14 +157,14 @@ dependencies:
157
157
  requirements:
158
158
  - - "~>"
159
159
  - !ruby/object:Gem::Version
160
- version: 0.46.0
160
+ version: 0.48.1
161
161
  type: :development
162
162
  prerelease: false
163
163
  version_requirements: !ruby/object:Gem::Requirement
164
164
  requirements:
165
165
  - - "~>"
166
166
  - !ruby/object:Gem::Version
167
- version: 0.46.0
167
+ version: 0.48.1
168
168
  - !ruby/object:Gem::Dependency
169
169
  name: guard
170
170
  requirement: !ruby/object:Gem::Requirement
@@ -207,6 +207,20 @@ dependencies:
207
207
  - - ">="
208
208
  - !ruby/object:Gem::Version
209
209
  version: '0'
210
+ - !ruby/object:Gem::Dependency
211
+ name: rack
212
+ requirement: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ version: '0'
217
+ type: :development
218
+ prerelease: false
219
+ version_requirements: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
210
224
  description: shared base for request_handler using dry-* gems
211
225
  email:
212
226
  - andreas.eger@runtastic.com
@@ -238,6 +252,8 @@ files:
238
252
  - lib/request_handler/header_parser.rb
239
253
  - lib/request_handler/helper.rb
240
254
  - lib/request_handler/include_option_parser.rb
255
+ - lib/request_handler/json_api_document_parser.rb
256
+ - lib/request_handler/multipart_parser.rb
241
257
  - lib/request_handler/option_parser.rb
242
258
  - lib/request_handler/page_parser.rb
243
259
  - lib/request_handler/schema_parser.rb
@@ -257,7 +273,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
257
273
  requirements:
258
274
  - - "~>"
259
275
  - !ruby/object:Gem::Version
260
- version: '2.1'
276
+ version: '2.2'
261
277
  required_rubygems_version: !ruby/object:Gem::Requirement
262
278
  requirements:
263
279
  - - ">="