apipie-rails 0.3.6 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/build.yml +67 -0
  3. data/.github/workflows/rubocop-challenger.yml +28 -0
  4. data/.gitignore +2 -0
  5. data/.rubocop.yml +37 -0
  6. data/.rubocop_todo.yml +1991 -0
  7. data/CHANGELOG.md +246 -2
  8. data/PROPOSAL_FOR_RESPONSE_DESCRIPTIONS.md +244 -0
  9. data/README.rst +646 -25
  10. data/Rakefile +0 -5
  11. data/apipie-rails.gemspec +14 -9
  12. data/app/controllers/apipie/apipies_controller.rb +51 -20
  13. data/app/public/apipie/javascripts/bundled/bootstrap-collapse.js +70 -41
  14. data/app/public/apipie/javascripts/bundled/bootstrap.js +1033 -479
  15. data/app/public/apipie/javascripts/bundled/jquery.js +5 -5
  16. data/app/public/apipie/stylesheets/bundled/bootstrap-responsive.min.css +9 -12
  17. data/app/public/apipie/stylesheets/bundled/bootstrap.min.css +9 -689
  18. data/app/views/apipie/apipies/_method_detail.erb +21 -0
  19. data/app/views/apipie/apipies/_params.html.erb +4 -2
  20. data/app/views/apipie/apipies/index.html.erb +5 -1
  21. data/app/views/apipie/apipies/resource.html.erb +3 -0
  22. data/app/views/layouts/apipie/apipie.html.erb +1 -1
  23. data/config/locales/en.yml +1 -0
  24. data/config/locales/fr.yml +31 -0
  25. data/config/locales/it.yml +31 -0
  26. data/config/locales/ja.yml +31 -0
  27. data/config/locales/ko.yml +31 -0
  28. data/config/locales/pt-BR.yml +1 -1
  29. data/gemfiles/Gemfile.rails50 +10 -0
  30. data/gemfiles/Gemfile.rails51 +10 -0
  31. data/gemfiles/Gemfile.rails52 +10 -0
  32. data/gemfiles/Gemfile.rails60 +17 -0
  33. data/gemfiles/Gemfile.rails61 +17 -0
  34. data/gemfiles/Gemfile.rails70 +17 -0
  35. data/lib/apipie/apipie_module.rb +22 -4
  36. data/lib/apipie/application.rb +54 -25
  37. data/lib/apipie/configuration.rb +26 -4
  38. data/lib/apipie/core_ext/route.rb +9 -0
  39. data/lib/apipie/dsl_definition.rb +168 -16
  40. data/lib/apipie/error_description.rb +9 -2
  41. data/lib/apipie/errors.rb +34 -0
  42. data/lib/apipie/extractor/collector.rb +4 -0
  43. data/lib/apipie/extractor/recorder.rb +14 -12
  44. data/lib/apipie/extractor/writer.rb +86 -58
  45. data/lib/apipie/extractor.rb +5 -5
  46. data/lib/apipie/generator/generator.rb +2 -0
  47. data/lib/apipie/generator/swagger/swagger.rb +2 -0
  48. data/lib/apipie/generator/swagger/type.rb +16 -0
  49. data/lib/apipie/generator/swagger/type_extractor.rb +70 -0
  50. data/lib/apipie/generator/swagger/warning.rb +77 -0
  51. data/lib/apipie/generator/swagger/warning_writer.rb +48 -0
  52. data/lib/apipie/markup.rb +14 -11
  53. data/lib/apipie/method_description/api.rb +12 -0
  54. data/lib/apipie/method_description/apis_service.rb +82 -0
  55. data/lib/apipie/method_description.rb +51 -49
  56. data/lib/apipie/param_description.rb +63 -5
  57. data/lib/apipie/resource_description.rb +11 -4
  58. data/lib/apipie/response_description.rb +131 -0
  59. data/lib/apipie/response_description_adapter.rb +200 -0
  60. data/lib/apipie/routes_formatter.rb +1 -1
  61. data/lib/apipie/rspec/response_validation_helper.rb +194 -0
  62. data/lib/apipie/static_dispatcher.rb +5 -2
  63. data/lib/apipie/swagger_generator.rb +717 -0
  64. data/lib/apipie/tag_list_description.rb +11 -0
  65. data/lib/apipie/validator.rb +83 -9
  66. data/lib/apipie/version.rb +1 -1
  67. data/lib/apipie-rails.rb +15 -4
  68. data/lib/generators/apipie/install/install_generator.rb +1 -1
  69. data/lib/generators/apipie/views_generator.rb +1 -1
  70. data/lib/tasks/apipie.rake +115 -15
  71. data/rel-eng/gem_release.ipynb +398 -0
  72. data/spec/controllers/apipies_controller_spec.rb +79 -14
  73. data/spec/controllers/concerns_controller_spec.rb +2 -2
  74. data/spec/controllers/extended_controller_spec.rb +14 -0
  75. data/spec/controllers/included_param_group_controller_spec.rb +13 -0
  76. data/spec/controllers/memes_controller_spec.rb +10 -0
  77. data/spec/controllers/users_controller_spec.rb +139 -76
  78. data/spec/dummy/Rakefile +1 -1
  79. data/spec/dummy/app/controllers/application_controller.rb +5 -1
  80. data/spec/dummy/app/controllers/concerns_controller.rb +1 -1
  81. data/spec/dummy/app/controllers/extended_controller.rb +14 -0
  82. data/spec/dummy/app/controllers/extending_concern.rb +10 -0
  83. data/spec/dummy/app/controllers/included_param_group_controller.rb +19 -0
  84. data/spec/dummy/app/controllers/overridden_concerns_controller.rb +2 -2
  85. data/spec/dummy/app/controllers/pets_controller.rb +408 -0
  86. data/spec/dummy/app/controllers/pets_using_auto_views_controller.rb +73 -0
  87. data/spec/dummy/app/controllers/pets_using_self_describing_classes_controller.rb +95 -0
  88. data/spec/dummy/app/controllers/{concerns/sample_controller.rb → sample_controller.rb} +5 -7
  89. data/spec/dummy/app/controllers/tagged_cats_controller.rb +32 -0
  90. data/spec/dummy/app/controllers/tagged_dogs_controller.rb +15 -0
  91. data/spec/dummy/app/controllers/twitter_example_controller.rb +5 -0
  92. data/spec/dummy/app/controllers/users_controller.rb +26 -12
  93. data/spec/dummy/app/helpers/random_param_group.rb +8 -0
  94. data/spec/dummy/components/test_engine/Gemfile +6 -0
  95. data/spec/dummy/components/test_engine/app/controllers/test_engine/application_controller.rb +4 -0
  96. data/spec/dummy/components/test_engine/app/controllers/test_engine/memes_controller.rb +37 -0
  97. data/spec/dummy/components/test_engine/config/routes.rb +3 -0
  98. data/spec/dummy/components/test_engine/db/.gitkeep +0 -0
  99. data/spec/dummy/components/test_engine/lib/test_engine.rb +7 -0
  100. data/spec/dummy/components/test_engine/test_engine.gemspec +11 -0
  101. data/spec/dummy/config/application.rb +6 -4
  102. data/spec/dummy/config/boot.rb +2 -2
  103. data/spec/dummy/config/environment.rb +1 -1
  104. data/spec/dummy/config/environments/development.rb +3 -3
  105. data/spec/dummy/config/environments/production.rb +3 -3
  106. data/spec/dummy/config/environments/test.rb +3 -5
  107. data/spec/dummy/config/initializers/apipie.rb +5 -3
  108. data/spec/dummy/config/routes.rb +25 -1
  109. data/spec/dummy/config.ru +1 -1
  110. data/spec/dummy/script/rails +2 -2
  111. data/spec/lib/application_spec.rb +1 -1
  112. data/spec/lib/extractor/writer_spec.rb +37 -7
  113. data/spec/lib/file_handler_spec.rb +25 -0
  114. data/spec/lib/generator/swagger/type_extractor_spec.rb +61 -0
  115. data/spec/lib/generator/swagger/warning_spec.rb +51 -0
  116. data/spec/lib/generator/swagger/warning_writer_spec.rb +59 -0
  117. data/spec/lib/method_description/apis_service_spec.rb +60 -0
  118. data/spec/lib/method_description_spec.rb +34 -0
  119. data/spec/lib/param_description_spec.rb +90 -4
  120. data/spec/lib/rake_spec.rb +2 -4
  121. data/spec/lib/swagger/openapi_2_0_schema.json +1607 -0
  122. data/spec/lib/swagger/rake_swagger_spec.rb +154 -0
  123. data/spec/lib/swagger/response_validation_spec.rb +104 -0
  124. data/spec/lib/swagger/swagger_dsl_spec.rb +658 -0
  125. data/spec/lib/validator_spec.rb +59 -1
  126. data/spec/lib/validators/array_validator_spec.rb +28 -8
  127. data/spec/spec_helper.rb +49 -3
  128. data/spec/support/custom_bool_validator.rb +17 -0
  129. metadata +104 -99
  130. data/.travis.yml +0 -12
  131. data/Gemfile +0 -7
  132. data/Gemfile.rails32 +0 -6
  133. data/Gemfile.rails40 +0 -5
  134. data/Gemfile.rails41 +0 -5
  135. data/Gemfile.rails42 +0 -5
  136. data/lib/apipie/client/generator.rb +0 -135
@@ -0,0 +1,154 @@
1
+ require 'spec_helper'
2
+ require "json-schema"
3
+
4
+ require File.expand_path('../../dummy/app/controllers/twitter_example_controller.rb', __dir__)
5
+ require File.expand_path('../../dummy/app/controllers/users_controller.rb', __dir__)
6
+ require File.expand_path('../../dummy/app/controllers/pets_controller.rb', __dir__)
7
+
8
+ describe 'rake tasks' do
9
+ include_context "rake"
10
+
11
+ let(:doc_path) { 'tmp/user_specified_doc_path' }
12
+
13
+ before do
14
+ Apipie.configuration.doc_path = doc_path
15
+ Apipie.configuration.swagger_suppress_warnings = true
16
+ allow(Apipie).to receive(:reload_documentation)
17
+ subject.invoke(*task_args)
18
+ end
19
+
20
+ describe 'static swagger specification files' do
21
+
22
+ after do
23
+ Dir["#{doc_output}*"].each { |static_file| FileUtils.rm_rf(static_file) }
24
+ end
25
+
26
+ let(:swagger_schema) do
27
+ File.read(File.join(File.dirname(__FILE__),"openapi_2_0_schema.json"))
28
+ end
29
+
30
+ let(:apidoc_swagger_json) do
31
+ # note: the filename ends with '_tmp' because this suffix is passed as a parameter to the rake task
32
+ File.read("#{doc_output}/schema_swagger_tmp.json")
33
+ end
34
+
35
+ let(:apidoc_swagger) do
36
+ JSON.parse(apidoc_swagger_json)
37
+ end
38
+
39
+ let(:doc_output) do
40
+ File.join(::Rails.root, doc_path, 'apidoc')
41
+ end
42
+
43
+ let(:ref_output) do
44
+ File.join(::Rails.root, doc_path, 'apidoc_ref')
45
+ end
46
+
47
+
48
+ def expect_param_def(http_method, path, param_name, field, value)
49
+ params = apidoc_swagger["paths"][path][http_method]["parameters"]
50
+ param = params.select {|p| p if p["name"]==param_name}[0]
51
+ expect(param[field]).to eq(value)
52
+ end
53
+
54
+ def expect_array_param_def(http_method, path, param_name, value)
55
+ params = apidoc_swagger["paths"][path][http_method]["parameters"]
56
+ param = params.select { |p| p if p["name"] == param_name }[0]
57
+
58
+ expect(param['type']).to eq('array')
59
+ expect(param['items']).to eq(
60
+ 'type' => 'string',
61
+ 'enum' => value
62
+ )
63
+ end
64
+
65
+ def expect_tags_def(http_method, path, value)
66
+ params = apidoc_swagger["paths"][path][http_method]["tags"]
67
+ expect(params).to eq(value)
68
+ end
69
+
70
+ def body_param_def(http_method, path, param_name)
71
+ params = apidoc_swagger["paths"][path][http_method]["parameters"]
72
+ body = params.select {|p| p if p["name"]=="body"}[0]
73
+ schema_properties = body["schema"]["properties"]
74
+ # print JSON.pretty_generate(schema_properties)
75
+ param = (schema_properties.select {|k,v| v if k == param_name })[param_name]
76
+ # print JSON.pretty_generate(param)
77
+ param
78
+ end
79
+
80
+ def expect_body_param_def(http_method, path, param_name, field, value)
81
+ param = body_param_def(http_method, path, param_name)
82
+ expect(param[field]).to eq(value)
83
+ end
84
+
85
+
86
+ describe 'apipie:static_swagger_json[development,json,_tmp]' do
87
+ it "generates static swagger files for the default version of apipie docs" do
88
+ # print apidoc_swagger_json
89
+
90
+ expect(apidoc_swagger["info"]["title"]).to eq("Test app (params in:body)")
91
+ expect(apidoc_swagger["info"]["version"]).to eq("#{Apipie.configuration.default_version}")
92
+ end
93
+
94
+ it "includes expected values in the generated swagger file" do
95
+ expect_param_def("get", "/twitter_example/{id}", "screen_name", "in", "query")
96
+ expect_param_def("put", "/users/{id}", "id", "in", "path")
97
+ expect_body_param_def("put", "/users/{id}", "oauth", "type", "string")
98
+ expect_body_param_def("put", "/users/{id}", "user", "type", "object")
99
+
100
+ user = body_param_def("put", "/users/{id}", "user")
101
+ expect(user["properties"]["name"]["type"]).to eq("string")
102
+
103
+ expect_param_def("get", "/users/by_department", "department", "in", "query")
104
+ expect_param_def("get", "/users/by_department", "department", "enum",
105
+ ["finance", "operations", "sales", "marketing", "HR"])
106
+
107
+ expect_tags_def("get", "/twitter_example/{id}/followers", %w[twitter_example following index search])
108
+ end
109
+
110
+ it "generates a valid swagger file" do
111
+ # print apidoc_swagger_json
112
+ expect(JSON::Validator.validate(swagger_schema, apidoc_swagger_json)).to be_truthy
113
+ end
114
+ end
115
+
116
+ describe 'apipie:static_swagger_json[development,form_data,_tmp]' do
117
+ it "generates static swagger files for the default version of apipie docs" do
118
+ # print apidoc_swagger_json
119
+
120
+ expect(apidoc_swagger["info"]["title"]).to eq("Test app (params in:formData)")
121
+ expect(apidoc_swagger["info"]["version"]).to eq("#{Apipie.configuration.default_version}")
122
+
123
+ end
124
+
125
+ it "includes expected values in the generated swagger file" do
126
+ expect_param_def("get", "/twitter_example/{id}", "screen_name", "in", "query")
127
+ expect_param_def("put", "/users/{id}", "id", "in", "path")
128
+ expect_param_def("put", "/users/{id}", "oauth", "in", "formData")
129
+ expect_param_def("get", "/users/by_department", "department", "in", "query")
130
+ expect_param_def("get", "/users/by_department", "department", "enum",
131
+ ["finance", "operations", "sales", "marketing", "HR"])
132
+
133
+ expect_param_def("get", "/users/in_departments", "departments", "in", "query")
134
+ expect_array_param_def("get", "/users/in_departments", "departments",
135
+ ["finance", "operations", "sales", "marketing", "HR"])
136
+
137
+ expect_tags_def("get", "/twitter_example/{id}/followers", %w[twitter_example following index search])
138
+
139
+ end
140
+
141
+ it "generates a valid swagger file" do
142
+ # print apidoc_swagger_json
143
+ expect(JSON::Validator.validate(swagger_schema, apidoc_swagger_json)).to be_truthy
144
+ end
145
+ end
146
+
147
+ describe 'apipie:did_swagger_change[development,form_data,_tmp]' do
148
+ it "keeps a reference file" do
149
+ expect(Pathname(ref_output).children.count).to eq(2) # one file for each language
150
+ end
151
+ end
152
+ end
153
+
154
+ end
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+ require 'rack/utils'
3
+ require 'rspec/expectations'
4
+ require 'apipie/rspec/response_validation_helper'
5
+ require "json-schema"
6
+
7
+ RSpec.describe PetsController, :type => :controller do
8
+ before :each do
9
+ Apipie.configuration.swagger_allow_additional_properties_in_response = false
10
+ end
11
+
12
+ it "does not raise error when rendered output matches the described response" do
13
+ response = get :return_and_validate_expected_response, format: :json
14
+ expect(response).to match_declared_responses
15
+ end
16
+
17
+ it "does not raise error when rendered output (array) matches the described response" do
18
+ response = get :return_and_validate_expected_array_response, format: :json
19
+ expect(response).to match_declared_responses
20
+ end
21
+
22
+ it "does not raises error when rendered output includes null in the response" do
23
+ response = get :return_and_validate_expected_response_with_null, format: :json
24
+ expect(response).to match_declared_responses
25
+ end
26
+
27
+ it "does not raise error when rendered output includes null (instead of an object) in the response" do
28
+ response = get :return_and_validate_expected_response_with_null_object, format: :json
29
+ expect(response).to match_declared_responses
30
+ end
31
+
32
+ it "raises error when a response field has the wrong type" do
33
+ response = get :return_and_validate_type_mismatch, format: :json
34
+ expect(response).not_to match_declared_responses
35
+ end
36
+
37
+ it "raises error when a response has a missing field" do
38
+ response = get :return_and_validate_missing_field, format: :json
39
+ expect(response).not_to match_declared_responses
40
+ end
41
+
42
+ it "raises error when a response has an extra property and 'swagger_allow_additional_properties_in_response' is false" do
43
+ response = get :return_and_validate_extra_property, format: :json
44
+ expect(response).not_to match_declared_responses
45
+ end
46
+
47
+ it "raises error when a response has is array instead of object" do
48
+ # note: this action returns HTTP 201, not HTTP 200!
49
+ response = get :return_and_validate_unexpected_array_response, format: :json
50
+ expect(response).not_to match_declared_responses
51
+ end
52
+
53
+ it "does not raise error when a response has an extra property and 'swagger_allow_additional_properties_in_response' is true" do
54
+ Apipie.configuration.swagger_allow_additional_properties_in_response = true
55
+ response = get :return_and_validate_extra_property, format: :json
56
+ expect(response).to match_declared_responses
57
+ end
58
+
59
+ it "does not raise error when a response has an extra field and 'additional_properties' is specified in the response" do
60
+ Apipie.configuration.swagger_allow_additional_properties_in_response = false
61
+ response = get :return_and_validate_allowed_extra_property, format: :json
62
+ expect(response).to match_declared_responses
63
+ end
64
+
65
+ it "raises error when a response sub-object has an extra field and 'additional_properties' is not specified on it, but specified on the top level of the response" do
66
+ Apipie.configuration.swagger_allow_additional_properties_in_response = false
67
+ response = get :sub_object_invalid_extra_property, format: :json
68
+ expect(response).not_to match_declared_responses
69
+ end
70
+
71
+ it "does not raise error when a response sub-object has an extra field and 'additional_properties' is specified on it" do
72
+ Apipie.configuration.swagger_allow_additional_properties_in_response = false
73
+ response = get :sub_object_allowed_extra_property, format: :json
74
+ expect(response).to match_declared_responses
75
+ end
76
+
77
+ describe "auto validation" do
78
+ auto_validate_rendered_views
79
+ it "raises exception when a response field has the wrong type and auto validation is turned on" do
80
+ expect { get :return_and_validate_type_mismatch, format: :json }.to raise_error(Apipie::ResponseDoesNotMatchSwaggerSchema)
81
+ end
82
+
83
+ it "does not raise an exception when calling an undocumented method" do
84
+ expect { get :undocumented_method, format: :json }.not_to raise_error
85
+ end
86
+
87
+ end
88
+
89
+
90
+ describe "with array field" do
91
+ it "no error for valid response" do
92
+ response = get :returns_response_with_valid_array, format: :json
93
+ expect(response).to match_declared_responses
94
+ end
95
+
96
+ it "error if type of element in the array is wrong" do
97
+ response = get :returns_response_with_invalid_array, format: :json
98
+ expect(response).not_to match_declared_responses
99
+ end
100
+ end
101
+
102
+
103
+
104
+ end