openapi_first 2.7.2 → 2.7.3
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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +39 -49
- data/lib/openapi_first/builder.rb +1 -1
- data/lib/openapi_first/file_loader.rb +1 -0
- data/lib/openapi_first/schema/hash.rb +2 -6
- data/lib/openapi_first/schema/validation_error.rb +1 -1
- data/lib/openapi_first/schema/validation_result.rb +1 -1
- data/lib/openapi_first/test.rb +2 -0
- data/lib/openapi_first/version.rb +1 -1
- data/lib/openapi_first.rb +2 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1df44d337ca5774bd5e85d09928e38ba0e37a9020ee8a4112d61cbc44281d01
|
4
|
+
data.tar.gz: 36afa88b1f939b18ed0d1396b414d698e66fd8c90eb3074f40e31d7beb5eaaf0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd7f57bda0e368f6d2ec35987266511492bc495591ce904cf44560e3397c5110b2c4f9cddb4bfabf0cdc2fbf6a9a002b558b5ba60ea77d5ac464366eebe2b153
|
7
|
+
data.tar.gz: 674c0da4c4bab2fcb674d581f930dcf6b298f1c87c26c02cbcd22503250b9d9bc280de899b35cb14244249f46a1800432a3a57ae4c7e42189dc7dc716da6483a
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
## Unreleased
|
4
4
|
|
5
|
+
## 2.7.3
|
6
|
+
|
7
|
+
- Accept loading OAD documents with numeric status codes. Fixes "Unknown reference" error. https://github.com/ahx/openapi_first/issues/367
|
8
|
+
|
9
|
+
- Support QUERY request method
|
10
|
+
OpenAPI 3.0, 3.1 does not support that, but this does
|
11
|
+
|
5
12
|
## 2.7.2
|
6
13
|
|
7
14
|
- Fix $ref-resolving for referenced arrays.
|
data/README.md
CHANGED
@@ -2,18 +2,17 @@
|
|
2
2
|
|
3
3
|
openapi_first is a Ruby gem for request / response validation and contract-testing against an [OpenAPI](https://www.openapis.org/) 3.0 or 3.1 API description. It makes an APIFirst workflow easy and reliable.
|
4
4
|
|
5
|
-
You can use openapi_first on production for [request validation](#request-validation) and in your tests to avoid API drift with it's request/response validation and coverage features.
|
5
|
+
You can use openapi_first on production for [request validation](#request-validation) and in your [tests](#contract-testing) to avoid API drift with it's request/response validation and coverage features.
|
6
6
|
|
7
7
|
## Contents
|
8
8
|
|
9
9
|
<!-- TOC -->
|
10
10
|
|
11
|
+
- [Contract testing](#contract-testing)
|
11
12
|
- [Rack Middlewares](#rack-middlewares)
|
12
13
|
- [Request validation](#request-validation)
|
13
14
|
- [Response validation](#response-validation)
|
14
|
-
- [
|
15
|
-
- [Coverage](#coverage)
|
16
|
-
- [Test assertions](#test-assertions)
|
15
|
+
- [Test assertions](#test-assertions)
|
17
16
|
- [Manual use](#manual-use)
|
18
17
|
- [Framework integration](#framework-integration)
|
19
18
|
- [Configuration](#configuration)
|
@@ -26,6 +25,41 @@ You can use openapi_first on production for [request validation](#request-valida
|
|
26
25
|
|
27
26
|
<!-- /TOC -->
|
28
27
|
|
28
|
+
## Contract Testing
|
29
|
+
|
30
|
+
You can see your OpenAPI API description as a contract that your clients can rely on as how your API behaves. There are two aspects of contract testing: Validation and Coverage. By validating requests and responses, you can avoid that your API implementation processes requests or returns responses that don't match your API description. To make sure your _whole_ API description is implemented, openapi_first can check that all of your API description is covered when you test your API with [rack-test](https://github.com/rack/rack-test).
|
31
|
+
|
32
|
+
Here is how to set it up:
|
33
|
+
|
34
|
+
1. Register all OpenAPI documents to track coverage for.
|
35
|
+
This should go at the top of your test helper file before loading your application code.
|
36
|
+
```ruby
|
37
|
+
require 'openapi_first'
|
38
|
+
OpenapiFirst::Test.setup do |test|
|
39
|
+
test.register('openapi/openapi.yaml')
|
40
|
+
# Optional: Make tests fail if coverage is below minimum
|
41
|
+
test.minimum_coverage = 100
|
42
|
+
# Optional: Skip certain responses, which are described in your API description, but need no test coverage
|
43
|
+
test.skip_response_coverage { it.status == '500' } #
|
44
|
+
end
|
45
|
+
```
|
46
|
+
2. Add an `app` method to your tests by including a Module. This `app` method wraps your application with silent request / response validation. This validates all requests/responses in your test run. (✷1)
|
47
|
+
```ruby
|
48
|
+
RSpec.configure do |config|
|
49
|
+
config.include OpenapiFirst::Test::Methods[MyApp], type: :request
|
50
|
+
end
|
51
|
+
```
|
52
|
+
Or add the `app` method yourself:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
def app
|
56
|
+
OpenapiFirst::Test.app(MyApp)
|
57
|
+
end
|
58
|
+
```
|
59
|
+
3. Run your tests. The Coverage feature will tell you about missing or invalid requests/responses.
|
60
|
+
|
61
|
+
(✷1): It does not matter what method of openapi_first you use to validate requests/responses. Instead of using `OpenapiFirstTest.app` to wrap your application, you could also use the [middlewares](#rack-middlewares) or [test assertion method](#test-assertions), but you would have to do that for all requests/responses defined in your API description to make coverage work.
|
62
|
+
|
29
63
|
## Rack Middlewares
|
30
64
|
|
31
65
|
### Request validation
|
@@ -135,51 +169,7 @@ use OpenapiFirst::Middlewares::ResponseValidation, 'openapi.yaml', raise_error:
|
|
135
169
|
|
136
170
|
If you are adopting OpenAPI you can use these options together with [hooks](#hooks) to get notified about requests/responses that do match your API description.
|
137
171
|
|
138
|
-
##
|
139
|
-
|
140
|
-
Here are two aspects of contract testing: Validation and Coverage
|
141
|
-
|
142
|
-
### Validation
|
143
|
-
|
144
|
-
By validating requests and responses, you can avoid that your API implementation processes requests or returns responses that don't match your API description. You can use [test assertions](#test-assertions) or [rack middlewares](#rack-middlewares) or manual validation to validate requests and responses with openapi_first.
|
145
|
-
|
146
|
-
### Coverage
|
147
|
-
|
148
|
-
To make sure your _whole_ API description is implemented, openapi_first ships with a coverage feature.
|
149
|
-
|
150
|
-
> [!NOTE]
|
151
|
-
> This is a brand new feature. ✨ Your feedback is very welcome.
|
152
|
-
|
153
|
-
This feature tracks all requests/responses that are validated via openapi_first and tells you about which request/responses are missing.
|
154
|
-
Here is how to set it up with [rack-test](https://github.com/rack/rack-test):
|
155
|
-
|
156
|
-
1. Register all OpenAPI documents to track coverage for. This should go at the top of your test helper file before loading your application code.
|
157
|
-
```ruby
|
158
|
-
require 'openapi_first'
|
159
|
-
OpenapiFirst::Test.setup do |test|
|
160
|
-
test.register('openapi/openapi.yaml')
|
161
|
-
test.minimum_coverage = 100 # (Optional) Setting this will lead to an `exit 2` if coverage is below minimum
|
162
|
-
test.skip_response_coverage { it.status == '500' } # (Optional) Skip certain responses
|
163
|
-
end
|
164
|
-
```
|
165
|
-
2. Add an `app` method to your tests, which wraps your application with silent request / response validation. This validates all requests/responses in your test run. (✷1)
|
166
|
-
|
167
|
-
```ruby
|
168
|
-
def app
|
169
|
-
OpenapiFirst::Test.app(MyApp)
|
170
|
-
end
|
171
|
-
```
|
172
|
-
3. Run your tests. The Coverage feature will tell you about missing request/responses.
|
173
|
-
|
174
|
-
Or you can generate a Module and include it in your rspec spec_helper.rb:
|
175
|
-
|
176
|
-
```ruby
|
177
|
-
config.include OpenapiFirst::Test::Methods[MyApp], type: :request
|
178
|
-
```
|
179
|
-
|
180
|
-
(✷1): It does not matter what method of openapi_first you use to validate requests/responses. Instead of using `OpenapiFirstTest.app` to wrap your application, you could also use the middlewares or [test assertion method](#test-assertions), but you would have to do that for all requests/responses defined in your API description to make coverage work.
|
181
|
-
|
182
|
-
### Test assertions
|
172
|
+
## Test assertions
|
183
173
|
|
184
174
|
openapi_first ships with a simple but powerful Test method to run request and response validation in your tests without using the middlewares. This is designed to be used with rack-test or Ruby on Rails integration tests or request specs.
|
185
175
|
|
@@ -14,7 +14,7 @@ module OpenapiFirst
|
|
14
14
|
# Builds parts of a Definition
|
15
15
|
# This knows how to read a resolved OpenAPI document and build {Request} and {Response} objects.
|
16
16
|
class Builder # rubocop:disable Metrics/ClassLength
|
17
|
-
REQUEST_METHODS = %w[get head post put patch delete trace options].freeze
|
17
|
+
REQUEST_METHODS = %w[get head post put patch delete trace options query].freeze
|
18
18
|
|
19
19
|
# Builds a router from a resolved OpenAPI document.
|
20
20
|
# @param contents [Hash] The OpenAPI document Hash.
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative 'validation_error'
|
4
4
|
|
5
5
|
module OpenapiFirst
|
6
|
-
|
6
|
+
module Schema
|
7
7
|
# A hash of Schemas
|
8
8
|
class Hash
|
9
9
|
# @param schema Hash of schemas
|
@@ -29,11 +29,7 @@ module OpenapiFirst
|
|
29
29
|
hook.call(root_value, key, schema.value, nil)
|
30
30
|
end
|
31
31
|
enum.chain(key_validation.map do |err|
|
32
|
-
data_pointer
|
33
|
-
err.merge(
|
34
|
-
'error' => JSONSchemer::Errors.pretty(err),
|
35
|
-
'data_pointer' => data_pointer
|
36
|
-
)
|
32
|
+
err.merge('data_pointer' => "/#{key}")
|
37
33
|
end)
|
38
34
|
end
|
39
35
|
ValidationResult.new(validations)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module OpenapiFirst
|
4
|
-
|
4
|
+
module Schema
|
5
5
|
# One of multiple validation errors. Returned by Schema::ValidationResult#errors.
|
6
6
|
ValidationError = Data.define(:value, :data_pointer, :schema_pointer, :type, :details, :schema) do
|
7
7
|
# This returns an error message for this specific error.
|
data/lib/openapi_first/test.rb
CHANGED
@@ -54,6 +54,8 @@ module OpenapiFirst
|
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
+
# Sets up OpenAPI test coverage and OAD registration.
|
58
|
+
# @yieldparam [OpenapiFirst::Test::Setup] setup A setup for configuration
|
57
59
|
def self.setup(&)
|
58
60
|
unless block_given?
|
59
61
|
raise ArgumentError, "Please provide a block to #{self.class}.setup to register you API descriptions"
|
data/lib/openapi_first.rb
CHANGED
@@ -64,8 +64,9 @@ module OpenapiFirst
|
|
64
64
|
|
65
65
|
# Parse a dereferenced Hash
|
66
66
|
# @return [Definition]
|
67
|
+
# TODO: This needs to work with unresolved contents as well
|
67
68
|
def self.parse(contents, only: nil, filepath: nil, &)
|
68
|
-
|
69
|
+
contents = JSON.parse(JSON.generate(contents)) # Deeply stringify keys, because of YAML. See https://github.com/ahx/openapi_first/issues/367
|
69
70
|
contents['paths'].filter!(&->(key, _) { only.call(key) }) if only
|
70
71
|
Definition.new(contents, filepath, &)
|
71
72
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openapi_first
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.7.
|
4
|
+
version: 2.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Haller
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: hana
|
@@ -162,7 +162,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
162
|
- !ruby/object:Gem::Version
|
163
163
|
version: '0'
|
164
164
|
requirements: []
|
165
|
-
rubygems_version: 3.6.
|
165
|
+
rubygems_version: 3.6.7
|
166
166
|
specification_version: 4
|
167
167
|
summary: OpenAPI based request validation, response validation, contract-testing and
|
168
168
|
coverage
|