apiculture 0.1.7 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apiculture
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julik Tarkhanov
@@ -9,24 +9,24 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-06-28 00:00:00.000000000 Z
12
+ date: 2023-11-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: mustermann
15
+ name: builder
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
18
  - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '1'
20
+ version: '3'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '1'
27
+ version: '3'
28
28
  - !ruby/object:Gem::Dependency
29
- name: builder
29
+ name: github-markup
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - "~>"
@@ -40,21 +40,21 @@ dependencies:
40
40
  - !ruby/object:Gem::Version
41
41
  version: '3'
42
42
  - !ruby/object:Gem::Dependency
43
- name: rdiscount
43
+ name: mustache
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - "~>"
47
47
  - !ruby/object:Gem::Version
48
- version: '2'
48
+ version: '1'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
- version: '2'
55
+ version: '1'
56
56
  - !ruby/object:Gem::Dependency
57
- name: github-markup
57
+ name: mustermann
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
60
  - - "~>"
@@ -68,61 +68,61 @@ dependencies:
68
68
  - !ruby/object:Gem::Version
69
69
  version: '3'
70
70
  - !ruby/object:Gem::Dependency
71
- name: mustache
71
+ name: rdiscount
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: '1'
76
+ version: '2'
77
77
  type: :runtime
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: '1'
83
+ version: '2'
84
84
  - !ruby/object:Gem::Dependency
85
- name: rack-test
85
+ name: bundler
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - ">="
88
+ - - "~>"
89
89
  - !ruby/object:Gem::Version
90
- version: '0'
90
+ version: '2.0'
91
91
  type: :development
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
- - - ">="
95
+ - - "~>"
96
96
  - !ruby/object:Gem::Version
97
- version: '0'
97
+ version: '2.0'
98
98
  - !ruby/object:Gem::Dependency
99
- name: rspec
99
+ name: cgi
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - "~>"
102
+ - - ">="
103
103
  - !ruby/object:Gem::Version
104
- version: '3'
104
+ version: '0'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - "~>"
109
+ - - ">="
110
110
  - !ruby/object:Gem::Version
111
- version: '3'
111
+ version: '0'
112
112
  - !ruby/object:Gem::Dependency
113
- name: rdoc
113
+ name: rack-test
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
- - - "~>"
116
+ - - ">="
117
117
  - !ruby/object:Gem::Version
118
- version: '6.0'
118
+ version: '0'
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
- - - "~>"
123
+ - - ">="
124
124
  - !ruby/object:Gem::Version
125
- version: '6.0'
125
+ version: '0'
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: rake
128
128
  requirement: !ruby/object:Gem::Requirement
@@ -138,33 +138,33 @@ dependencies:
138
138
  - !ruby/object:Gem::Version
139
139
  version: '0'
140
140
  - !ruby/object:Gem::Dependency
141
- name: bundler
141
+ name: rdoc
142
142
  requirement: !ruby/object:Gem::Requirement
143
143
  requirements:
144
144
  - - "~>"
145
145
  - !ruby/object:Gem::Version
146
- version: '1.0'
146
+ version: '6.0'
147
147
  type: :development
148
148
  prerelease: false
149
149
  version_requirements: !ruby/object:Gem::Requirement
150
150
  requirements:
151
151
  - - "~>"
152
152
  - !ruby/object:Gem::Version
153
- version: '1.0'
153
+ version: '6.0'
154
154
  - !ruby/object:Gem::Dependency
155
- name: simplecov
155
+ name: rspec
156
156
  requirement: !ruby/object:Gem::Requirement
157
157
  requirements:
158
- - - ">="
158
+ - - "~>"
159
159
  - !ruby/object:Gem::Version
160
- version: '0'
160
+ version: '3'
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'
167
+ version: '3'
168
168
  description: A toolkit for building REST APIs on top of Rack
169
169
  email: me@julik.nl
170
170
  executables: []
@@ -175,6 +175,7 @@ extra_rdoc_files:
175
175
  files:
176
176
  - ".gitignore"
177
177
  - ".travis.yml"
178
+ - CHANGELOG.md
178
179
  - Gemfile
179
180
  - LICENSE.txt
180
181
  - README.md
@@ -195,12 +196,6 @@ files:
195
196
  - lib/apiculture/sinatra_instance_methods.rb
196
197
  - lib/apiculture/timestamp_promise.rb
197
198
  - lib/apiculture/version.rb
198
- - spec/apiculture/action_spec.rb
199
- - spec/apiculture/app_documentation_spec.rb
200
- - spec/apiculture/method_documentation_spec.rb
201
- - spec/apiculture/openapi_documentation_spec.rb
202
- - spec/apiculture_spec.rb
203
- - spec/spec_helper.rb
204
199
  homepage: https://github.com/WeTransfer/apiculture
205
200
  licenses:
206
201
  - MIT
@@ -221,7 +216,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
216
  - !ruby/object:Gem::Version
222
217
  version: '0'
223
218
  requirements: []
224
- rubygems_version: 3.0.9
219
+ rubygems_version: 3.4.6
225
220
  signing_key:
226
221
  specification_version: 4
227
222
  summary: Sweet API sauce on top of Rack
@@ -1,45 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- describe Apiculture::Action do
4
- context '.new' do
5
- it 'exposes the methods of the object given as a first argument to initialize' do
6
- action_class = Class.new(described_class)
7
- fake_app = double('Apiculture::App', something: 'value')
8
- action = action_class.new(fake_app)
9
- expect(action).to respond_to(:something)
10
- expect(action.something).to eq('value')
11
- end
12
-
13
- it 'converts keyword arguments to instance variables' do
14
- action_class = Class.new(described_class)
15
- action = action_class.new(nil, foo: 'a string')
16
- expect(action.instance_variable_get('@foo')).to eq('a string')
17
- end
18
- end
19
-
20
- it 'responds to perform()' do
21
- expect(described_class.new(nil)).to respond_to(:perform)
22
- end
23
-
24
- it 'can use bail() to throw a Sinatra halt' do
25
- fake_app = double('Apiculture::App')
26
- expect(fake_app).to receive(:json_halt).with('Failure', status: 400)
27
- action_class = Class.new(described_class)
28
- action_class.new(fake_app).bail "Failure"
29
- end
30
-
31
- it 'can use bail() to throw a Sinatra halt with a custom status' do
32
- fake_app = double('Apiculture::App')
33
- expect(fake_app).to receive(:json_halt).with("Failure", status: 417)
34
-
35
- action_class = Class.new(described_class)
36
- action_class.new(fake_app).bail "Failure", status: 417
37
- end
38
-
39
- it 'can use bail() to throw a Sinatra halt with extra JSON attributes' do
40
- fake_app = double('Apiculture::App')
41
- expect(fake_app).to receive(:json_halt).with("Failure", status: 417, message: "Totale")
42
- action_class = Class.new(described_class)
43
- action_class.new(fake_app).bail "Failure", status: 417, message: 'Totale'
44
- end
45
- end
@@ -1,126 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- describe "Apiculture.api_documentation" do
4
- let(:app) do
5
- Class.new(Apiculture::App) do
6
- extend Apiculture
7
-
8
- markdown_string 'This API is very important. Because it has to do with pancakes.'
9
-
10
- documentation_build_time!
11
-
12
- desc 'Order a pancake'
13
- required_param :diameter, "Diameter of the pancake. The pancake will be **bold**", Integer
14
- param :topping, 'Type of topping', String
15
- pancake_response_info = <<~EOS
16
- When the pancake has been baked successfully
17
- The pancake will have the following properties:
18
-
19
- * It is going to be round
20
- * It is going to be delicious
21
- EOS
22
- responds_with 200, pancake_response_info, { id: 'abdef..c21' }
23
- api_method :post, '/pancakes' do
24
- end
25
-
26
- desc 'Check the pancake status'
27
- route_param :id, 'Pancake ID to check status on'
28
- responds_with 200, 'When the pancake is found', { status: 'Baking' }
29
- responds_with 404, 'When no such pancake exists', { status: 'No such pancake' }
30
- api_method :get, '/pancake/:id' do
31
- end
32
-
33
- desc 'Throw away the pancake'
34
- route_param :id, 'Pancake ID to delete'
35
- api_method :delete, '/pancake/:id' do
36
- end
37
-
38
- desc 'Pancake ingredients are in the URL'
39
- route_param :topping_id, 'Pancake topping ID', Integer, cast: :to_i
40
- api_method :get, '/pancake/with/:topping_id' do |topping_id|
41
- end
42
- end
43
- end
44
-
45
- it 'generates app documentation as HTML without the body element' do
46
- docco = app.api_documentation
47
- generated_html = docco.to_html_fragment
48
-
49
- expect(generated_html).not_to include('<body')
50
- expect(generated_html).to include('Pancake ID to check status on')
51
- expect(generated_html).to include('Pancake ID to delete')
52
- end
53
-
54
- it 'generates app documentation in HTML' do
55
- docco = app.api_documentation
56
- generated_html = docco.to_html
57
-
58
- if ENV['SHOW_TEST_DOC']
59
- File.open('t.html', 'w') do |f|
60
- f.write(generated_html)
61
- f.flush
62
- `open #{f.path}`
63
- end
64
- end
65
-
66
- expect(generated_html).to include('<body')
67
- expect(generated_html).to include('Pancake ID to check status on')
68
- expect(generated_html).to include('When the pancake has been baked successfully')
69
- expect(generated_html).to include('"id": "abdef..c21"')
70
- expect(generated_html).to end_with("\n")
71
- end
72
-
73
- it 'generates app documentation in Markdown' do
74
- docco = app.api_documentation
75
- generated_markdown = docco.to_markdown
76
-
77
- expect(generated_markdown).not_to include('<body')
78
- expect(generated_markdown).to include('## POST /pancakes')
79
- end
80
-
81
- it 'generates app documentation honoring the mount point' do
82
- overridden = Class.new(Apiculture::App) do
83
- extend Apiculture
84
- mounted_at '/api/v2/'
85
- api_method :get, '/pancakes' do
86
- end
87
- end
88
-
89
- generated_markdown = overridden.api_documentation.to_markdown
90
- expect(generated_markdown).to include('## GET /api/v2/pancakes')
91
- end
92
-
93
- it 'generates app documentation injecting the inline Markdown strings' do
94
- app_class = Class.new(Apiculture::App) do
95
- extend Apiculture
96
- markdown_string '# This describes important stuff'
97
- api_method :get, '/pancakes' do
98
- end
99
- markdown_string '# This describes even more important stuff'
100
- markdown_string 'This is a paragraph'
101
- end
102
-
103
- generated_html = app_class.api_documentation.to_html
104
- expect(generated_html).to include('<h2>GET /pancakes</h2>')
105
- expect(generated_html).to include('<h1>This describes even more important stuff')
106
- expect(generated_html).to include('<h1>This describes important stuff')
107
- expect(generated_html).to include('<p>This is a paragraph')
108
- end
109
-
110
- context 'with a file containing Markdown that has to be spliced into the docs' do
111
- before(:each) { File.open('./TEST.md', 'w') { |f| f << "# This is an important header" } }
112
- after(:each) { File.unlink('./TEST.md') }
113
- it 'splices the contents of the file using markdown_file' do
114
- app_class = Class.new(Apiculture::App) do
115
- extend Apiculture
116
- markdown_file './TEST.md'
117
- api_method :get, '/pancakes' do
118
- end
119
- end
120
-
121
- generated_html = app_class.api_documentation.to_html
122
- expect(generated_html).to include('<h2>GET /pancakes</h2>')
123
- expect(generated_html).to include('<h1>This is an important header')
124
- end
125
- end
126
- end
@@ -1,102 +0,0 @@
1
- require_relative '../spec_helper'
2
- require_relative '../../lib/apiculture/method_documentation'
3
-
4
- describe Apiculture::MethodDocumentation do
5
- it 'generates HTML from an ActionDefinition with path, verb and both route and request params' do
6
- definition = Apiculture::ActionDefinition.new
7
-
8
- definition.description = "This action bakes pancakes"
9
- definition.parameters << Apiculture::Parameter.new(:name, 'Pancake name', true, String, :to_s)
10
- definition.parameters << Apiculture::Parameter.new(:thickness, 'Pancake **thick**ness', false, Float, :to_f)
11
- definition.parameters << Apiculture::Parameter.new(:diameter, 'Pancake diameter', false, Integer, :to_i)
12
-
13
- definition.route_parameters << Apiculture::RouteParameter.new(:pan_id, 'ID of the pancake frying pan')
14
- definition.http_verb = 'get'
15
- definition.path = '/pancake/:pan_id/bake'
16
- definition.responses << Apiculture::PossibleResponse.new(200, "Pancake has been baked", {diameter: 10, unit: "cm"})
17
- definition.responses << Apiculture::PossibleResponse.new(417, "Frying pan too cold", "ERR_NO_HEAT")
18
-
19
- documenter = described_class.new(definition)
20
-
21
- generated_html = documenter.to_html_fragment
22
- generated_markdown = documenter.to_markdown
23
-
24
- expect(generated_html).not_to include('<body>')
25
-
26
- expect(generated_html).to include('<h2>GET /pancake/:pan_id/bake</h2>')
27
- expect(generated_html).to include('<p>This action bakes pancakes</p>')
28
- expect(generated_html).to include('<h3>URL parameters</h3>')
29
- expect(generated_html).to include('ID of the pancake frying pan')
30
- expect(generated_html).to include('<h3>Request parameters</h3>')
31
- expect(generated_html).to include('<p>Pancake name</p>')
32
- expect(generated_html).to include('<p>Pancake has been baked</p>')
33
- expect(generated_html).to include('<p>Frying pan too cold</p>')
34
- end
35
-
36
- it 'generates HTML from an ActionDefinition without route params' do
37
- definition = Apiculture::ActionDefinition.new
38
-
39
- definition.description = "This action bakes pancakes"
40
- definition.parameters << Apiculture::Parameter.new(:name, 'Pancake name', true, String, :to_s)
41
- definition.parameters << Apiculture::Parameter.new(:thickness, 'Pancake **thick**ness', false, Float, :to_f)
42
- definition.parameters << Apiculture::Parameter.new(:diameter, 'Pancake diameter', false, Integer, :to_i)
43
-
44
- definition.http_verb = 'get'
45
- definition.path = '/pancake'
46
-
47
- documenter = described_class.new(definition)
48
- generated_html = documenter.to_html_fragment
49
-
50
- expect(generated_html).not_to include('<h3>URL parameters</h3>')
51
- end
52
-
53
- it 'generates HTML from an ActionDefinition without request params' do
54
- definition = Apiculture::ActionDefinition.new
55
-
56
- definition.description = "This action bakes pancakes"
57
-
58
- definition.route_parameters << Apiculture::RouteParameter.new(:pan_id, 'ID of the pancake frying pan')
59
- definition.http_verb = 'get'
60
- definition.path = '/pancake/:pan_id/bake'
61
-
62
- documenter = described_class.new(definition)
63
-
64
- generated_html = documenter.to_html_fragment
65
- generated_markdown = documenter.to_markdown
66
-
67
- expect(generated_html).not_to include('<h3>Request parameters</h3>')
68
- end
69
-
70
- it 'generates HTML from an ActionDefinition with a casted route param' do
71
- definition = Apiculture::ActionDefinition.new
72
-
73
- definition.description = "This adds a topping to a pancake"
74
-
75
- definition.route_parameters << Apiculture::RouteParameter.new(:topping_id, 'ID of the pancake topping', Integer, cast: :to_i)
76
- definition.http_verb = 'get'
77
- definition.path = '/pancake/:topping_id'
78
-
79
- documenter = described_class.new(definition)
80
-
81
- generated_html = documenter.to_html_fragment
82
- generated_markdown = documenter.to_markdown
83
- expect(generated_html).to include('<h3>URL parameters</h3>')
84
- expect(generated_html).to include('Type after cast')
85
- end
86
-
87
-
88
- it 'generates Markdown from an ActionDefinition with a mountpoint' do
89
- definition = Apiculture::ActionDefinition.new
90
-
91
- definition.description = "This action bakes pancakes"
92
-
93
- definition.route_parameters << Apiculture::RouteParameter.new(:pan_id, 'ID of the pancake frying pan')
94
- definition.http_verb = 'get'
95
- definition.path = '/pancake/:pan_id/bake'
96
-
97
- documenter = described_class.new(definition, '/api/v1')
98
-
99
- generated_markdown = documenter.to_markdown
100
- expect(generated_markdown).to include('## GET /api/v1/pancake/:pan_id')
101
- end
102
- end
@@ -1,197 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- describe 'Apiculture.api_documentation' do
4
- let!(:test_class) do
5
- class PancakeApi < Apiculture::App
6
- extend Apiculture
7
-
8
- documentation_build_time!
9
-
10
- desc 'Order a pancake'
11
- required_param :diameter, 'Diameter of the pancake. The pancake will be **bold**', Integer
12
- param :topping, 'Type of topping', String
13
- pancake_response_info = <<~EOS
14
- When the pancake has been baked successfully
15
- The pancake will have the following properties:
16
-
17
- * It is going to be round
18
- * It is going to be delicious
19
- EOS
20
- responds_with 200, pancake_response_info, { id: 'abdef..c21' }
21
- api_method :post, '/pancakes' do
22
- end
23
-
24
- desc 'Check the pancake status'
25
- route_param :id, 'Pancake ID to check status on'
26
- responds_with 200, 'When the pancake is found', { status: 'Baking' }
27
- responds_with 404, 'When no such pancake exists', { status: 'No such pancake' }
28
- api_method :get, '/pancake/:id' do
29
- end
30
-
31
- desc 'Throw away the pancake'
32
- route_param :id, 'Pancake ID to delete'
33
- api_method :delete, '/pancake/:id' do
34
- end
35
-
36
- desc 'Pancake ingredients are in the URL'
37
- route_param :topping_id, 'Pancake topping ID', Integer, cast: :to_i
38
- api_method :get, '/pancake/with/:topping_id' do |topping_id|
39
- end
40
- end
41
- end
42
-
43
- let(:documentation) { PancakeApi.api_documentation }
44
- let(:open_api_map) { documentation.to_openapi.spec }
45
-
46
- describe '.to_openapi' do
47
- it 'will have openapi version' do
48
- expect(open_api_map).to include(openapi: '3.0.0')
49
- end
50
-
51
- describe 'info' do
52
- let(:info) { open_api_map.fetch(:info) }
53
-
54
- it 'will not to be empty' do
55
- expect(info).not_to be_empty
56
- end
57
-
58
- it 'will have title' do
59
- expect(info).to include(title: 'PancakeApi')
60
- end
61
-
62
- it 'will have version' do
63
- expect(info).to include(version: '0.0.1')
64
- end
65
-
66
- it 'will have description' do
67
- expect(info).to include(:description)
68
- expect(info[:description]).to include('PancakeApi Documentation built on')
69
- end
70
- end
71
-
72
- describe 'paths' do
73
- let(:paths) { open_api_map.fetch(:paths) }
74
-
75
- it 'will have paths' do
76
- expect(paths).not_to be_empty
77
- end
78
-
79
- it 'will have 4 paths' do
80
- expect(paths.size).to eq(3)
81
- end
82
-
83
- context 'POST /pancakes' do
84
- let(:post_pancakes) { paths.dig('/pancakes', :post) }
85
-
86
- it 'will have route' do
87
- expect(post_pancakes).not_to be_empty
88
- end
89
-
90
- describe 'request body content' do
91
- let(:request_content) { post_pancakes.dig(:requestBody, :content) }
92
- it 'will have correct JSON content type' do
93
- expect(request_content).to have_key(:'application/json')
94
- end
95
-
96
- describe 'schema' do
97
- let(:schema) { request_content.dig(:'application/json', :schema) }
98
- it 'will have type' do
99
- expect(schema).to include(type: :object)
100
- end
101
-
102
- it 'will have required parameters' do
103
- expect(schema).to include(required: [:diameter])
104
- end
105
-
106
- describe 'properties' do
107
- let(:properties) { schema.fetch(:properties) }
108
- it 'will have all properties' do
109
- expect(properties).to have_key :diameter
110
- expect(properties).to have_key :topping
111
- end
112
- end
113
- end
114
- end
115
- end
116
-
117
- context 'GET /pancake/:id' do
118
- let(:get_pancake_by_id_path) { paths.dig('/pancake/{id}', :get) }
119
- it 'will have route' do
120
- expect(get_pancake_by_id_path).not_to be_empty
121
- end
122
-
123
- it 'will have summary' do
124
- expect(get_pancake_by_id_path).to include(summary: 'Check the pancake status')
125
- end
126
-
127
- it 'will have a description' do
128
- expect(get_pancake_by_id_path).to include(description: 'Check the pancake status')
129
- end
130
-
131
- it 'will have operationId' do
132
- expect(get_pancake_by_id_path).to have_key :operationId
133
- end
134
-
135
- describe 'parameters' do
136
- let(:parameter) { get_pancake_by_id_path.fetch(:parameters).first }
137
-
138
- it 'will contain parameter' do
139
- expect(parameter).not_to be_empty
140
- end
141
-
142
- it 'will have required propertie' do
143
- expect(parameter).to include(required: true)
144
- end
145
-
146
- it 'will indicate a path parameter' do
147
- expect(parameter).to include(in: :path)
148
- end
149
-
150
- describe 'schema' do
151
- let(:schema) { parameter.fetch(:schema) }
152
- it 'will have object type' do
153
- expect(schema).to include(type: 'string')
154
- end
155
-
156
- it 'will have an example' do
157
- expect(schema).to include(example: 'string')
158
- end
159
- end
160
- end
161
-
162
- describe 'responses' do
163
- let(:responses) { get_pancake_by_id_path.fetch(:responses) }
164
-
165
- it 'will contain all responses by response code' do
166
- expect(responses).to have_key('200')
167
- expect(responses).to have_key('404')
168
- end
169
-
170
- describe 'response 200' do
171
- let(:response_200) { responses.fetch('200') }
172
-
173
- it 'will have description' do
174
- expect(response_200).to include(description: 'When the pancake is found')
175
- end
176
-
177
- it 'will have correct content type' do
178
- expect(response_200.fetch(:content)).to have_key(:'application/json')
179
- end
180
-
181
- describe 'schema' do
182
- let(:schema) { response_200.dig(:content, :'application/json', :schema) }
183
-
184
- it 'will have object type' do
185
- expect(schema).to include(type: 'object')
186
- end
187
-
188
- it 'will have properties' do
189
- expect(schema).to have_key :properties
190
- end
191
- end
192
- end
193
- end
194
- end
195
- end
196
- end
197
- end