skooma 0.2.2 → 0.3.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
  SHA256:
3
- metadata.gz: d780ea317b116a8bdafac72f240b68366cf6f2892ea671f29ed51dd48a198093
4
- data.tar.gz: '078593785c8fc17c73c171616131880dbeaf1b85923e593a3612eb9b2309ff0d'
3
+ metadata.gz: 9f8caa0911924b17126cad7544d4c54e4fe3f819c6b21c3489cd47180bb69996
4
+ data.tar.gz: 052a2f72272a02b99cb44f62b6a1b1a319ca1c743742c66125d4da4ae9b402c1
5
5
  SHA512:
6
- metadata.gz: f16cb70ad584c45615c4c376ebbab69e48caca0daa32c687d55c9c96453b3a608096afeedc45a7286e0e4ace4c2dc500c2d36ed013d0b951d915b60bbba42a63
7
- data.tar.gz: c301176ff04134e0e6d18c57e4e0ced55f1dca82d8ff807eefa820cc02f8227101275ccf43b4e3b60c6716b19d7da94f714da37435f417995e97faf44f2b20d3
6
+ metadata.gz: 4392d35e7aade0d2683f38ef782ed6b2b980aee835ea489f173202ff75627a4cff4bc3ae522bb9e06ed6b69d7b073a08520902a3a6388cd22f3e8321bbedbb08
7
+ data.tar.gz: 990bfcb689cd4ad8f76060c955abf9ce01fd3513a54499592136045d1f87f3000575356b1d0e7ddea78b16cc76e516d099dfeda18c35c36426a6426e933068ea
data/CHANGELOG.md CHANGED
@@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning].
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2024-04-09
11
+
12
+ ### Changed
13
+
14
+ - BREAKING CHANGE: Pass `headers` parameter to registered `BodyParsers`. ([@skryukov])
15
+
16
+ ```ruby
17
+ # Before:
18
+ Skooma::BodyParsers.register("application/xml", ->(body) { Hash.from_xml(body) })
19
+ # After:
20
+ Skooma::BodyParsers.register("application/xml", ->(body, headers:) { Hash.from_xml(body) })
21
+ ```
22
+ ### Fixed
23
+
24
+ - Fix wrong path when combined with Rails exceptions_app. ([@ursm])
25
+
26
+ ## [0.2.3] - 2024-01-18
27
+
28
+ ### Added
29
+
30
+ - Add support for multiple OpenAPI documents. ([@skryukov])
31
+
32
+ ### Fixed
33
+
34
+ - Fix `Skooma::Error: Missing name key /request` by setting `content` and `required` keyword dependencies. ([@skryukov])
35
+
10
36
  ## [0.2.2] - 2024-01-04
11
37
 
12
38
  ### Added
@@ -58,8 +84,11 @@ end
58
84
  - Initial implementation. ([@skryukov])
59
85
 
60
86
  [@skryukov]: https://github.com/skryukov
87
+ [@ursm]: https://github.com/ursm
61
88
 
62
- [Unreleased]: https://github.com/skryukov/skooma/compare/v0.2.2...HEAD
89
+ [Unreleased]: https://github.com/skryukov/skooma/compare/v0.3.0...HEAD
90
+ [0.3.0]: https://github.com/skryukov/skooma/compare/v0.2.3...v0.3.0
91
+ [0.2.3]: https://github.com/skryukov/skooma/compare/v0.2.2...v0.2.3
63
92
  [0.2.2]: https://github.com/skryukov/skooma/compare/v0.2.1...v0.2.2
64
93
  [0.2.1]: https://github.com/skryukov/skooma/compare/v0.2.0...v0.2.1
65
94
  [0.2.0]: https://github.com/skryukov/skooma/compare/v0.1.0...v0.2.0
@@ -3,7 +3,7 @@
3
3
  module Skooma
4
4
  module BodyParsers
5
5
  class << self
6
- DEFAULT_PARSER = ->(body) { body }
6
+ DEFAULT_PARSER = ->(body, **_options) { body }
7
7
 
8
8
  def [](media_type)
9
9
  parsers[media_type.to_s.strip.downcase] || DEFAULT_PARSER
@@ -20,7 +20,7 @@ module Skooma
20
20
  self.parsers = {}
21
21
 
22
22
  module JSONParser
23
- def self.call(body)
23
+ def self.call(body, **_options)
24
24
  JSON.parse(body)
25
25
  rescue JSON::ParserError
26
26
  body
@@ -9,7 +9,7 @@ module Skooma
9
9
  def call(env, response = nil, with_response: true, with_request: true)
10
10
  result = {
11
11
  "method" => env["REQUEST_METHOD"].downcase,
12
- "path" => env["PATH_INFO"]
12
+ "path" => env["action_dispatch.original_path"] || env["PATH_INFO"]
13
13
  }
14
14
  result["request"] = map_request(env) if with_request
15
15
  result["response"] = map_response(response) if response && with_response
@@ -23,10 +23,19 @@ module Skooma
23
23
  {
24
24
  "query" => env["rack.request.query_string"] || env["QUERY_STRING"],
25
25
  "headers" => env.select { |k, _| k.start_with?("HTTP_") || PLAIN_HEADERS.include?(k) }.transform_keys { |k| k.sub(REGEXP_HTTP, "").split("_").map(&:capitalize).join("-") },
26
- "body" => env["RAW_POST_DATA"]
26
+ "body" => env["RAW_POST_DATA"] || read_rack_input(env["rack.input"])
27
27
  }
28
28
  end
29
29
 
30
+ def read_rack_input(input)
31
+ return nil unless input.respond_to?(:rewind)
32
+
33
+ input.rewind
34
+ raw_input = input.read
35
+ input.rewind
36
+ raw_input
37
+ end
38
+
30
39
  def map_response(response)
31
40
  status, headers, body = response.to_a
32
41
  full_body = +""
@@ -63,16 +63,16 @@ module Skooma
63
63
  data = {}
64
64
  data["status"] = JSONSkooma::JSONNode.new(value.fetch("status"), key: "status", parent: self)
65
65
  data["headers"] = Headers.new(value.fetch("headers", {}), key: "headers", parent: self)
66
- body_value = parse_body(value["body"], data["headers"]&.[]("Content-Type"))
66
+ body_value = parse_body(value["body"], data["headers"])
67
67
  data["body"] = Attribute.new(body_value, key: "body", parent: self)
68
68
  ["object", data]
69
69
  end
70
70
 
71
- def parse_body(body, content_type)
71
+ def parse_body(body, headers)
72
72
  return nil unless body
73
73
 
74
- parser = BodyParsers[content_type&.split(";")&.first]
75
- parser ? parser.call(body) : body
74
+ parser = BodyParsers[headers["Content-Type"]&.value&.split(";")&.first]
75
+ parser ? parser.call(body, headers: headers) : body
76
76
  end
77
77
  end
78
78
 
@@ -83,16 +83,16 @@ module Skooma
83
83
  data = {}
84
84
  data["query"] = Attribute.new(value.fetch("query", ""), key: "query", parent: self)
85
85
  data["headers"] = Headers.new(value.fetch("headers", {}), key: "headers", parent: self)
86
- body_value = parse_body(value["body"], data["headers"]&.[]("Content-Type"))
86
+ body_value = parse_body(value["body"], data["headers"])
87
87
  data["body"] = Attribute.new(body_value, key: "body", parent: self)
88
88
  ["object", data]
89
89
  end
90
90
 
91
- def parse_body(body, content_type)
91
+ def parse_body(body, headers)
92
92
  return nil unless body
93
93
 
94
- parser = BodyParsers[content_type&.split(";")&.first]
95
- parser ? parser.call(body) : body
94
+ parser = BodyParsers[headers["Content-Type"]&.value&.split(";")&.first]
95
+ parser ? parser.call(body, headers: headers) : body
96
96
  end
97
97
  end
98
98
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pp"
4
+
3
5
  module Skooma
4
6
  module Matchers
5
7
  class BeValidDocument
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "pp"
4
+
3
5
  module Skooma
4
6
  module Matchers
5
7
  class ConformRequestSchema
@@ -45,11 +45,13 @@ module Skooma
45
45
 
46
46
  registry = create_test_registry
47
47
  pathname = Pathname.new(openapi_path)
48
+ source_uri = "#{base_uri}#{path_prefix.delete_suffix("/")}"
49
+ source_uri += "/" unless source_uri.end_with?("/")
48
50
  registry.add_source(
49
- base_uri,
51
+ source_uri,
50
52
  JSONSkooma::Sources::Local.new(pathname.dirname.to_s)
51
53
  )
52
- schema = registry.schema(URI.parse("#{base_uri}#{pathname.basename}"), schema_class: Skooma::Objects::OpenAPI)
54
+ schema = registry.schema(URI.parse("#{source_uri}#{pathname.basename}"), schema_class: Skooma::Objects::OpenAPI)
53
55
  schema.path_prefix = path_prefix
54
56
 
55
57
  include DefaultHelperMethods
@@ -8,6 +8,7 @@ module Skooma
8
8
  self.key = "content"
9
9
  self.value_schema = :object_of_schemas
10
10
  self.schema_value_class = Objects::MediaType
11
+ self.depends_on = %w[in name style explode allowReserved allowEmptyValue]
11
12
 
12
13
  def evaluate(instance, result)
13
14
  return if instance.value.nil?
@@ -6,6 +6,7 @@ module Skooma
6
6
  module Keywords
7
7
  class Required < JSONSkooma::Keywords::Base
8
8
  self.key = "required"
9
+ self.depends_on = %w[in name style explode allowReserved allowEmptyValue]
9
10
 
10
11
  def evaluate(instance, result)
11
12
  if json.value && ValueParser.call(instance, result)&.value.nil?
@@ -13,7 +13,7 @@ module Skooma
13
13
  raise Error, "Missing `in` key #{result.path}" unless type
14
14
 
15
15
  key = result.sibling(instance, "name")&.annotation
16
- raise Error, "Missing `name` key #{instance.path}: #{key}" unless key
16
+ raise Error, "Missing `name` key #{result.path}" unless key
17
17
 
18
18
  case type
19
19
  when "query"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Skooma
4
- VERSION = "0.2.2"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: skooma
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Svyatoslav Kryukov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-04 00:00:00.000000000 Z
11
+ date: 2024-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zeitwerk