swagger_autogenerate 1.1.1 → 1.1.2
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 +1 -0
- data/Gemfile.lock +1 -1
- data/lib/swagger_autogenerate/configuration.rb +8 -1
- data/lib/swagger_autogenerate/swagger_trace.rb +175 -25
- data/lib/swagger_autogenerate/version.rb +1 -1
- data/lib/swagger_autogenerate.rb +14 -5
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fa0e0d56334a728cbd835bf8ecf0cf4b2c330eb62aeb92e6b9bc20d1251ed5cd
|
|
4
|
+
data.tar.gz: c5869ad74ec90bffdb1a58bdfbb52645849b14f88e81e876f5b856d280dab536
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7766553dbaa81ee1506f36727411a24e36d9dd7c73bc4733a2bc034be406b2c94e4526f7c73467e1d383cf3e566fecaa6ea592a06627f4a5778dba61cd5f142e
|
|
7
|
+
data.tar.gz: ab857ce41cc465f94b961c61d2f3bbeb48195c8bf5472152c43524384caa57313325b852df8417e2c07489fed8ae0e656c941d9c91a395ea6e16895ace7a990c
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
module SwaggerAutogenerate
|
|
2
2
|
class Configuration
|
|
3
|
-
attr_accessor :with_config, :with_multiple_examples, :with_example_description,
|
|
3
|
+
attr_accessor :with_config, :with_multiple_examples, :with_rspec_examples, :with_example_description,
|
|
4
4
|
:with_response_description, :swagger_environment_variable,
|
|
5
5
|
:environment_name, :security, :swagger_config, :response_status
|
|
6
6
|
|
|
7
7
|
def initialize
|
|
8
8
|
@with_config = true
|
|
9
9
|
@with_multiple_examples = true
|
|
10
|
+
@with_rspec_examples = true
|
|
11
|
+
# remove this when we do not need it any more
|
|
10
12
|
@with_example_description = true
|
|
11
13
|
@with_response_description = true
|
|
12
14
|
@swagger_environment_variable = 'SWAGGER'
|
|
@@ -78,4 +80,9 @@ module SwaggerAutogenerate
|
|
|
78
80
|
def self.configure
|
|
79
81
|
yield(configuration)
|
|
80
82
|
end
|
|
83
|
+
|
|
84
|
+
def self.extract_description(full_rspec_description)
|
|
85
|
+
parts = full_rspec_description.split(' ')
|
|
86
|
+
parts&.length > 1 ? parts[2..-1].join(" ") : full_rspec_description
|
|
87
|
+
end
|
|
81
88
|
end
|
|
@@ -5,7 +5,7 @@ module SwaggerAutogenerate
|
|
|
5
5
|
def initialize(request, response)
|
|
6
6
|
@with_config = ::SwaggerAutogenerate.configuration.with_config
|
|
7
7
|
@with_multiple_examples = ::SwaggerAutogenerate.configuration.with_multiple_examples
|
|
8
|
-
@
|
|
8
|
+
@with_rspec_examples = ::SwaggerAutogenerate.configuration.with_rspec_examples
|
|
9
9
|
@with_response_description = ::SwaggerAutogenerate.configuration.with_response_description
|
|
10
10
|
@security = ::SwaggerAutogenerate.configuration.security
|
|
11
11
|
@swagger_config = ::SwaggerAutogenerate.configuration.swagger_config
|
|
@@ -39,7 +39,7 @@ module SwaggerAutogenerate
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
41
|
attr_reader :request, :response, :current_path, :yaml_file, :configuration,
|
|
42
|
-
:with_config, :with_multiple_examples, :
|
|
42
|
+
:with_config, :with_multiple_examples, :with_rspec_examples,
|
|
43
43
|
:with_response_description, :security, :response_status, :swagger_config
|
|
44
44
|
|
|
45
45
|
# main methods
|
|
@@ -88,6 +88,13 @@ module SwaggerAutogenerate
|
|
|
88
88
|
data['paths'] = paths
|
|
89
89
|
organize_result(data['paths'])
|
|
90
90
|
data = data.to_hash
|
|
91
|
+
# handel examples names
|
|
92
|
+
example_title = full_rspec_description.present? ? full_rspec_description : 'example-0'
|
|
93
|
+
old_examples = data['paths'][current_path][request.method.downcase]['responses'][response.status.to_s]['content']['application/json']['examples']
|
|
94
|
+
current_example = old_examples[example_title]
|
|
95
|
+
new_example(example_title, current_example, old_examples, data['paths'], true)
|
|
96
|
+
# result
|
|
97
|
+
|
|
91
98
|
result = add_quotes_to_dates(YAML.dump(data))
|
|
92
99
|
file.write(result)
|
|
93
100
|
end
|
|
@@ -209,17 +216,24 @@ module SwaggerAutogenerate
|
|
|
209
216
|
}
|
|
210
217
|
end
|
|
211
218
|
|
|
212
|
-
def convert_to_multipart(payload)
|
|
219
|
+
def convert_to_multipart(payload, main_key = nil, index = nil)
|
|
220
|
+
payload_keys.push(main_key) if main_key.present?
|
|
213
221
|
payload.each do |key, value|
|
|
214
222
|
if value.is_a?(Hash)
|
|
215
223
|
payload_keys.push(key)
|
|
216
224
|
convert_to_multipart(value)
|
|
225
|
+
elsif value.is_a?(Array)
|
|
226
|
+
value.each_with_index { |v, index| convert_to_multipart(v, key, index) }
|
|
217
227
|
else
|
|
218
228
|
keys = payload_keys.clone
|
|
219
229
|
first_key = keys.shift
|
|
220
|
-
|
|
221
|
-
|
|
230
|
+
if index.present?
|
|
231
|
+
keys.each { |inner_key| first_key = "#{first_key}[#{inner_key}][#{index}]" }
|
|
232
|
+
else
|
|
233
|
+
keys.each { |inner_key| first_key = "#{first_key}[#{inner_key}]" }
|
|
234
|
+
end
|
|
222
235
|
|
|
236
|
+
first_key = "#{first_key}[#{key}]"
|
|
223
237
|
payload_hash.merge!({ first_key => { 'type' => schema_type(value), 'example' => example(value) } })
|
|
224
238
|
end
|
|
225
239
|
end
|
|
@@ -230,6 +244,8 @@ module SwaggerAutogenerate
|
|
|
230
244
|
data.map do |key, value|
|
|
231
245
|
if value.is_a?(Hash)
|
|
232
246
|
hash_data.merge!({ key => value })
|
|
247
|
+
elsif value.is_a?(Array)
|
|
248
|
+
value.each_with_index { |v, index| convert_to_multipart(v, key) }
|
|
233
249
|
else
|
|
234
250
|
payload_hash.merge!({ key => { 'type' => schema_type(value), 'example' => example(value) } })
|
|
235
251
|
end
|
|
@@ -250,10 +266,93 @@ module SwaggerAutogenerate
|
|
|
250
266
|
}
|
|
251
267
|
end
|
|
252
268
|
|
|
269
|
+
def json_to_content_form_data(json)
|
|
270
|
+
{
|
|
271
|
+
'multipart/form-data' => {
|
|
272
|
+
'schema' => build_properties(json)
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def build_properties(json)
|
|
278
|
+
case json
|
|
279
|
+
when Hash
|
|
280
|
+
hash_properties = json.transform_values { |value| build_properties(value) if value.present? }
|
|
281
|
+
hash_properties = hash_properties.delete_if { |_k, v| !v.present? }
|
|
282
|
+
|
|
283
|
+
hashs = {
|
|
284
|
+
'type' => 'object',
|
|
285
|
+
'properties' => hash_properties
|
|
286
|
+
}
|
|
287
|
+
when Array
|
|
288
|
+
item_schemas = json.map { |item| build_properties(item) }
|
|
289
|
+
merged_schema = merge_array_schemas(item_schemas)
|
|
290
|
+
|
|
291
|
+
if merged_schema[:type] == 'object'
|
|
292
|
+
{ 'type' => 'array', 'items' => merged_schema }
|
|
293
|
+
else
|
|
294
|
+
{ 'type' => 'array', 'items' => { 'oneOf' => item_schemas.uniq } }
|
|
295
|
+
end
|
|
296
|
+
when String
|
|
297
|
+
{ 'type' => 'string', 'example' => json }
|
|
298
|
+
when Integer
|
|
299
|
+
{ 'type' => 'integer', 'example' => json }
|
|
300
|
+
when Float
|
|
301
|
+
{ 'type' => 'number', 'example' => json }
|
|
302
|
+
when TrueClass, FalseClass
|
|
303
|
+
{ 'type' => 'boolean', 'example' => json }
|
|
304
|
+
else
|
|
305
|
+
{ 'type' => 'string', 'example' => json.to_s }
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
def merge_array_schemas(schemas)
|
|
310
|
+
return {} if schemas.empty?
|
|
311
|
+
|
|
312
|
+
# Attempt to merge all schemas into a single schema
|
|
313
|
+
schemas.reduce do |merged, schema|
|
|
314
|
+
merge_properties(merged, schema)
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def merge_properties(old_data, new_data)
|
|
319
|
+
return old_data unless old_data.is_a?(Hash) && new_data.is_a?(Hash)
|
|
320
|
+
|
|
321
|
+
merged = old_data.dup
|
|
322
|
+
new_data.each do |key, value|
|
|
323
|
+
merged[key] = if merged[key].is_a?(Hash) && value.is_a?(Hash)
|
|
324
|
+
merge_properties(merged[key], value)
|
|
325
|
+
else
|
|
326
|
+
value
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
merged
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def content_application_json_schema_properties(data)
|
|
333
|
+
hash_data = {}
|
|
334
|
+
data.map do |key, value|
|
|
335
|
+
if value.is_a?(Hash)
|
|
336
|
+
hash_data.merge!({ key => value })
|
|
337
|
+
elsif value.is_a?(Array)
|
|
338
|
+
value.each_with_index { |v, index| convert_to_multipart(v, key, index) }
|
|
339
|
+
else
|
|
340
|
+
payload_hash.merge!({ key => { 'type' => schema_type(value), 'example' => example(value) } })
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
convert_to_multipart(hash_data)
|
|
345
|
+
converted_payload = @payload_hash.clone
|
|
346
|
+
@payload_hash = nil
|
|
347
|
+
@payload_keys = nil
|
|
348
|
+
|
|
349
|
+
converted_payload
|
|
350
|
+
end
|
|
351
|
+
|
|
253
352
|
def content_body(data)
|
|
254
353
|
hash = {}
|
|
255
354
|
# hash.merge!(content_json(data))
|
|
256
|
-
hash.merge!(
|
|
355
|
+
hash.merge!(json_to_content_form_data(data))
|
|
257
356
|
|
|
258
357
|
{ 'content' => hash }
|
|
259
358
|
end
|
|
@@ -351,19 +450,18 @@ module SwaggerAutogenerate
|
|
|
351
450
|
end
|
|
352
451
|
|
|
353
452
|
def content_json_example(data)
|
|
354
|
-
|
|
453
|
+
example_title = full_rspec_description.present? ? full_rspec_description : 'example-0'
|
|
454
|
+
|
|
455
|
+
{
|
|
355
456
|
'application/json' => {
|
|
356
457
|
'schema' => { 'type' => 'object' },
|
|
357
458
|
'examples' => {
|
|
358
|
-
|
|
459
|
+
example_title => {
|
|
359
460
|
'value' => data
|
|
360
461
|
}
|
|
361
462
|
}
|
|
362
463
|
}
|
|
363
464
|
}
|
|
364
|
-
hash['application/json']['examples']['example-0']['description'] = "payload => #{example_description}" if with_example_description && !example_description.empty?
|
|
365
|
-
|
|
366
|
-
hash
|
|
367
465
|
end
|
|
368
466
|
|
|
369
467
|
def example_description
|
|
@@ -396,20 +494,48 @@ module SwaggerAutogenerate
|
|
|
396
494
|
@payload_hash ||= {}
|
|
397
495
|
end
|
|
398
496
|
|
|
399
|
-
def new_example
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
last_example =
|
|
405
|
-
last_example
|
|
406
|
-
|
|
407
|
-
|
|
497
|
+
def new_example(example_title, current_example, old_examples, all_paths = yaml_file['paths'], with_schema_properties = false)
|
|
498
|
+
if !old_examples.value?(current_example)
|
|
499
|
+
last_example = handel_name_last_example(old_examples)
|
|
500
|
+
last_example ||= example_title
|
|
501
|
+
last_example = example_title unless with_multiple_examples
|
|
502
|
+
all_paths[current_path][request.method.downcase]['responses'][response.status.to_s]['content']['application/json']['examples'][last_example] = current_example
|
|
503
|
+
add_properties_to_schema(last_example, all_paths[current_path])
|
|
504
|
+
elsif with_schema_properties
|
|
505
|
+
add_properties_to_schema(full_rspec_description.present? ? full_rspec_description : 'example-0', all_paths[current_path])
|
|
408
506
|
end
|
|
409
507
|
|
|
410
508
|
true
|
|
411
509
|
end
|
|
412
510
|
|
|
511
|
+
def handel_name_last_example(old_examples)
|
|
512
|
+
last_example = old_examples.keys.last
|
|
513
|
+
last_example += '-1' if json_example_plus_one(last_example) == last_example
|
|
514
|
+
json_example_plus_one(last_example)
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
def add_properties_to_schema(last_example, main_path = yaml_file['paths'][current_path])
|
|
518
|
+
parameters = {}
|
|
519
|
+
parameters.merge!(request_parameters.values.first, query_parameters.values.first, path_parameters.values.first)
|
|
520
|
+
hash = {
|
|
521
|
+
last_example => build_properties(parameters.as_json)
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
main_path[request.method.downcase]['responses'][response.status.to_s].deep_merge!(
|
|
525
|
+
{
|
|
526
|
+
'content' => {
|
|
527
|
+
'application/json' => {
|
|
528
|
+
'schema' => {
|
|
529
|
+
'description' => 'These are the payloads for each example',
|
|
530
|
+
'type' => 'object',
|
|
531
|
+
'properties' => hash
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
)
|
|
537
|
+
end
|
|
538
|
+
|
|
413
539
|
def apply_yaml_file_changes
|
|
414
540
|
(check_path || check_method || check_status) &&
|
|
415
541
|
(check_parameters || check_parameter) &&
|
|
@@ -438,24 +564,29 @@ module SwaggerAutogenerate
|
|
|
438
564
|
def check_path
|
|
439
565
|
unless old_paths.key?(current_path)
|
|
440
566
|
yaml_file['paths'].merge!({ current_path => paths[current_path] })
|
|
567
|
+
update_example_title(true)
|
|
441
568
|
end
|
|
442
569
|
end
|
|
443
570
|
|
|
444
571
|
def check_method
|
|
445
572
|
unless old_paths[current_path].key?(request.method.downcase)
|
|
446
573
|
yaml_file['paths'][current_path][request.method.downcase] = { 'responses' => swagger_response }
|
|
574
|
+
update_example_title(true)
|
|
447
575
|
end
|
|
448
576
|
end
|
|
449
577
|
|
|
450
578
|
def check_status
|
|
579
|
+
example_title = full_rspec_description.present? ? full_rspec_description : 'example-0'
|
|
451
580
|
if old_paths[current_path][request.method.downcase]['responses'].present?
|
|
452
581
|
if old_paths[current_path][request.method.downcase]['responses']&.key?(response.status.to_s)
|
|
453
|
-
|
|
582
|
+
update_example_title
|
|
454
583
|
else
|
|
455
584
|
yaml_file['paths'][current_path][request.method.downcase]['responses'].merge!(swagger_response)
|
|
585
|
+
update_example_title(true)
|
|
456
586
|
end
|
|
457
587
|
else
|
|
458
588
|
yaml_file['paths'][current_path][request.method.downcase]['responses'] = swagger_response
|
|
589
|
+
update_example_title
|
|
459
590
|
end
|
|
460
591
|
end
|
|
461
592
|
|
|
@@ -481,12 +612,31 @@ module SwaggerAutogenerate
|
|
|
481
612
|
|
|
482
613
|
def check_request_body
|
|
483
614
|
if paths[current_path][request.method.downcase]['requestBody'].present?
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
615
|
+
param_current_hash = paths[current_path][request.method.downcase]['requestBody']['content']['multipart/form-data']['schema']['properties']
|
|
616
|
+
param_current_file = yaml_file['paths'][current_path][request.method.downcase]['requestBody']['content']['multipart/form-data']['schema']['properties']
|
|
617
|
+
if param_current_hash.present? && param_current_file.present?
|
|
618
|
+
param_names = param_current_hash.keys - param_current_file.keys
|
|
619
|
+
param_names.each do |param_name|
|
|
620
|
+
param = paths[current_path][request.method.downcase]['requestBody']['content']['multipart/form-data']['schema']['properties'].select { |parameter| parameter == param_name }
|
|
621
|
+
yaml_file['paths'][current_path][request.method.downcase]['requestBody']['content']['multipart/form-data']['schema']['properties'].merge!(param)
|
|
622
|
+
end
|
|
488
623
|
end
|
|
489
624
|
end
|
|
490
625
|
end
|
|
626
|
+
|
|
627
|
+
def update_example_title(with_schema_properties = false)
|
|
628
|
+
example_title = full_rspec_description.present? ? full_rspec_description : 'example-0'
|
|
629
|
+
current_example = swagger_response[response.status.to_s]['content']['application/json']['examples'][example_title]
|
|
630
|
+
old_examples = old_paths[current_path][request.method.downcase]['responses'][response.status.to_s]['content']['application/json']['examples']
|
|
631
|
+
new_example(example_title, current_example, old_examples, yaml_file['paths'], with_schema_properties)
|
|
632
|
+
end
|
|
633
|
+
|
|
634
|
+
def full_rspec_description
|
|
635
|
+
with_rspec_examples ? SwaggerAutogenerate::SwaggerTrace.rspec_description : nil
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
class << self
|
|
639
|
+
attr_accessor :rspec_description
|
|
640
|
+
end
|
|
491
641
|
end
|
|
492
642
|
end
|
data/lib/swagger_autogenerate.rb
CHANGED
|
@@ -8,14 +8,23 @@ module SwaggerAutogenerate
|
|
|
8
8
|
def process_action(*args)
|
|
9
9
|
super
|
|
10
10
|
|
|
11
|
-
if
|
|
11
|
+
if SwaggerAutogenerate.allow_swagger?
|
|
12
12
|
SwaggerTrace.new(request, response).call
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
def self.allow_swagger?
|
|
18
|
+
ENV[SwaggerTrace.swagger_environment_variable].present? && Rails.env.send("#{SwaggerTrace.environment_name.to_s}?")
|
|
19
|
+
end
|
|
16
20
|
end
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
if defined?(RSpec) && SwaggerAutogenerate.allow_swagger?
|
|
23
|
+
require 'rspec/rails'
|
|
24
|
+
|
|
25
|
+
RSpec.configure do |config|
|
|
26
|
+
config.before(:each) do |example|
|
|
27
|
+
SwaggerAutogenerate::SwaggerTrace.rspec_description = SwaggerAutogenerate.extract_description(example.metadata[:full_description])
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: swagger_autogenerate
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- MohammedBuraiah
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-
|
|
11
|
+
date: 2024-08-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Generating Swagger YAML Automatically Based on Existing Test Cases in
|
|
14
14
|
Ruby on Rails
|