request_handler 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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
  - - ">="