apipie-rails-jq 1.4.3.pre.beta.pre.jq.1

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.
Files changed (258) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/build.yml +32 -0
  3. data/.github/workflows/rubocop-challenger.yml +26 -0
  4. data/.github/workflows/rubocop.yml +18 -0
  5. data/.gitignore +16 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +132 -0
  8. data/.rubocop_todo.yml +1967 -0
  9. data/.vscode/settings.json +3 -0
  10. data/APACHE-LICENSE-2.0 +202 -0
  11. data/CHANGELOG.md +693 -0
  12. data/Gemfile +19 -0
  13. data/MIT-LICENSE +20 -0
  14. data/NOTICE +4 -0
  15. data/PROPOSAL_FOR_RESPONSE_DESCRIPTIONS.md +244 -0
  16. data/README.md +2088 -0
  17. data/Rakefile +8 -0
  18. data/apipie-rails.gemspec +44 -0
  19. data/app/controllers/apipie/apipies_controller.rb +184 -0
  20. data/app/helpers/apipie_helper.rb +10 -0
  21. data/app/public/apipie/javascripts/apipie.js +6 -0
  22. data/app/public/apipie/javascripts/bundled/bootstrap-collapse.js +167 -0
  23. data/app/public/apipie/javascripts/bundled/bootstrap.js +2280 -0
  24. data/app/public/apipie/javascripts/bundled/jquery.js +2 -0
  25. data/app/public/apipie/javascripts/bundled/prettify.js +28 -0
  26. data/app/public/apipie/stylesheets/application.css +7 -0
  27. data/app/public/apipie/stylesheets/bundled/bootstrap-responsive.min.css +9 -0
  28. data/app/public/apipie/stylesheets/bundled/bootstrap.min.css +9 -0
  29. data/app/public/apipie/stylesheets/bundled/prettify.css +30 -0
  30. data/app/views/apipie/apipies/_deprecation.html.erb +16 -0
  31. data/app/views/apipie/apipies/_disqus.html.erb +13 -0
  32. data/app/views/apipie/apipies/_errors.html.erb +23 -0
  33. data/app/views/apipie/apipies/_headers.html.erb +26 -0
  34. data/app/views/apipie/apipies/_languages.erb +6 -0
  35. data/app/views/apipie/apipies/_metadata.erb +1 -0
  36. data/app/views/apipie/apipies/_method_detail.erb +63 -0
  37. data/app/views/apipie/apipies/_params.html.erb +49 -0
  38. data/app/views/apipie/apipies/_params_plain.html.erb +21 -0
  39. data/app/views/apipie/apipies/apipie_404.html.erb +17 -0
  40. data/app/views/apipie/apipies/apipie_checksum.json.erb +1 -0
  41. data/app/views/apipie/apipies/getting_started.html.erb +6 -0
  42. data/app/views/apipie/apipies/index.html.erb +56 -0
  43. data/app/views/apipie/apipies/method.html.erb +41 -0
  44. data/app/views/apipie/apipies/plain.html.erb +77 -0
  45. data/app/views/apipie/apipies/resource.html.erb +80 -0
  46. data/app/views/apipie/apipies/static.html.erb +103 -0
  47. data/app/views/layouts/apipie/apipie.html.erb +27 -0
  48. data/config/locales/de.yml +28 -0
  49. data/config/locales/en.yml +41 -0
  50. data/config/locales/es.yml +28 -0
  51. data/config/locales/fr.yml +31 -0
  52. data/config/locales/it.yml +41 -0
  53. data/config/locales/ja.yml +31 -0
  54. data/config/locales/ko.yml +32 -0
  55. data/config/locales/pl.yml +28 -0
  56. data/config/locales/pt-BR.yml +28 -0
  57. data/config/locales/ru.yml +28 -0
  58. data/config/locales/tr.yml +28 -0
  59. data/config/locales/zh-CN.yml +28 -0
  60. data/config/locales/zh-TW.yml +28 -0
  61. data/gemfiles/Gemfile.tools +9 -0
  62. data/images/screenshot-1.png +0 -0
  63. data/images/screenshot-2.png +0 -0
  64. data/lib/apipie/apipie_module.rb +83 -0
  65. data/lib/apipie/application.rb +499 -0
  66. data/lib/apipie/configuration.rb +196 -0
  67. data/lib/apipie/core_ext/route.rb +9 -0
  68. data/lib/apipie/dsl_definition.rb +630 -0
  69. data/lib/apipie/error_description.rb +46 -0
  70. data/lib/apipie/errors.rb +86 -0
  71. data/lib/apipie/extractor/collector.rb +116 -0
  72. data/lib/apipie/extractor/recorder.rb +193 -0
  73. data/lib/apipie/extractor/writer.rb +454 -0
  74. data/lib/apipie/extractor.rb +181 -0
  75. data/lib/apipie/generator/config.rb +12 -0
  76. data/lib/apipie/generator/generator.rb +2 -0
  77. data/lib/apipie/generator/swagger/computed_interface_id.rb +23 -0
  78. data/lib/apipie/generator/swagger/config.rb +80 -0
  79. data/lib/apipie/generator/swagger/context.rb +38 -0
  80. data/lib/apipie/generator/swagger/method_description/api_decorator.rb +20 -0
  81. data/lib/apipie/generator/swagger/method_description/api_schema_service.rb +89 -0
  82. data/lib/apipie/generator/swagger/method_description/decorator.rb +22 -0
  83. data/lib/apipie/generator/swagger/method_description/parameters_service.rb +139 -0
  84. data/lib/apipie/generator/swagger/method_description/response_schema_service.rb +46 -0
  85. data/lib/apipie/generator/swagger/method_description/response_service.rb +71 -0
  86. data/lib/apipie/generator/swagger/method_description.rb +2 -0
  87. data/lib/apipie/generator/swagger/operation_id.rb +51 -0
  88. data/lib/apipie/generator/swagger/param_description/builder.rb +114 -0
  89. data/lib/apipie/generator/swagger/param_description/composite.rb +119 -0
  90. data/lib/apipie/generator/swagger/param_description/description.rb +15 -0
  91. data/lib/apipie/generator/swagger/param_description/in.rb +37 -0
  92. data/lib/apipie/generator/swagger/param_description/name.rb +18 -0
  93. data/lib/apipie/generator/swagger/param_description/path_params_composite.rb +61 -0
  94. data/lib/apipie/generator/swagger/param_description/referenced_composite.rb +36 -0
  95. data/lib/apipie/generator/swagger/param_description/type.rb +132 -0
  96. data/lib/apipie/generator/swagger/param_description.rb +18 -0
  97. data/lib/apipie/generator/swagger/path_decorator.rb +36 -0
  98. data/lib/apipie/generator/swagger/referenced_definitions.rb +17 -0
  99. data/lib/apipie/generator/swagger/resource_description_collection.rb +30 -0
  100. data/lib/apipie/generator/swagger/resource_description_composite.rb +56 -0
  101. data/lib/apipie/generator/swagger/schema.rb +63 -0
  102. data/lib/apipie/generator/swagger/swagger.rb +2 -0
  103. data/lib/apipie/generator/swagger/type.rb +16 -0
  104. data/lib/apipie/generator/swagger/type_extractor.rb +51 -0
  105. data/lib/apipie/generator/swagger/warning.rb +74 -0
  106. data/lib/apipie/generator/swagger/warning_writer.rb +54 -0
  107. data/lib/apipie/helpers.rb +73 -0
  108. data/lib/apipie/markup.rb +52 -0
  109. data/lib/apipie/method_description/api.rb +12 -0
  110. data/lib/apipie/method_description/apis_service.rb +82 -0
  111. data/lib/apipie/method_description.rb +230 -0
  112. data/lib/apipie/middleware/checksum_in_headers.rb +35 -0
  113. data/lib/apipie/param_description/deprecation.rb +24 -0
  114. data/lib/apipie/param_description.rb +313 -0
  115. data/lib/apipie/railtie.rb +9 -0
  116. data/lib/apipie/resource_description.rb +152 -0
  117. data/lib/apipie/response_description.rb +157 -0
  118. data/lib/apipie/response_description_adapter.rb +202 -0
  119. data/lib/apipie/routes_formatter.rb +33 -0
  120. data/lib/apipie/routing.rb +16 -0
  121. data/lib/apipie/rspec/response_validation_helper.rb +194 -0
  122. data/lib/apipie/see_description.rb +39 -0
  123. data/lib/apipie/static_dispatcher.rb +75 -0
  124. data/lib/apipie/swagger_generator.rb +45 -0
  125. data/lib/apipie/tag_list_description.rb +11 -0
  126. data/lib/apipie/validator.rb +552 -0
  127. data/lib/apipie/version.rb +3 -0
  128. data/lib/apipie-rails.rb +60 -0
  129. data/lib/generators/apipie/install/README +6 -0
  130. data/lib/generators/apipie/install/install_generator.rb +25 -0
  131. data/lib/generators/apipie/install/templates/initializer.rb.erb +7 -0
  132. data/lib/generators/apipie/views_generator.rb +11 -0
  133. data/lib/tasks/apipie.rake +355 -0
  134. data/rel-eng/gem_release.ipynb +398 -0
  135. data/rel-eng/packages/.readme +3 -0
  136. data/rel-eng/packages/rubygem-apipie-rails +1 -0
  137. data/rel-eng/tito.props +5 -0
  138. data/spec/controllers/api/v1/architectures_controller_spec.rb +29 -0
  139. data/spec/controllers/api/v2/architectures_controller_spec.rb +19 -0
  140. data/spec/controllers/api/v2/empty_middle_controller_spec.rb +23 -0
  141. data/spec/controllers/api/v2/nested/resources_controller_spec.rb +27 -0
  142. data/spec/controllers/api/v2/sub/footguns_controller_spec.rb +19 -0
  143. data/spec/controllers/concerns_controller_spec.rb +42 -0
  144. data/spec/controllers/extended_controller_spec.rb +14 -0
  145. data/spec/controllers/included_param_group_controller_spec.rb +13 -0
  146. data/spec/controllers/pets_controller_spec.rb +98 -0
  147. data/spec/controllers/users_controller_spec.rb +794 -0
  148. data/spec/dummy/Rakefile +7 -0
  149. data/spec/dummy/app/controllers/api/base_controller.rb +4 -0
  150. data/spec/dummy/app/controllers/api/v1/architectures_controller.rb +43 -0
  151. data/spec/dummy/app/controllers/api/v1/base_controller.rb +11 -0
  152. data/spec/dummy/app/controllers/api/v2/architectures_controller.rb +31 -0
  153. data/spec/dummy/app/controllers/api/v2/base_controller.rb +17 -0
  154. data/spec/dummy/app/controllers/api/v2/empty_middle_controller.rb +14 -0
  155. data/spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb +32 -0
  156. data/spec/dummy/app/controllers/api/v2/nested/resources_controller.rb +33 -0
  157. data/spec/dummy/app/controllers/api/v2/sub/footguns_controller.rb +30 -0
  158. data/spec/dummy/app/controllers/application_controller.rb +18 -0
  159. data/spec/dummy/app/controllers/concerns_controller.rb +8 -0
  160. data/spec/dummy/app/controllers/extended_controller.rb +14 -0
  161. data/spec/dummy/app/controllers/extending_concern.rb +10 -0
  162. data/spec/dummy/app/controllers/files_controller.rb +5 -0
  163. data/spec/dummy/app/controllers/included_param_group_controller.rb +19 -0
  164. data/spec/dummy/app/controllers/overridden_concerns_controller.rb +31 -0
  165. data/spec/dummy/app/controllers/pets_controller.rb +408 -0
  166. data/spec/dummy/app/controllers/pets_using_auto_views_controller.rb +73 -0
  167. data/spec/dummy/app/controllers/pets_using_self_describing_classes_controller.rb +95 -0
  168. data/spec/dummy/app/controllers/sample_controller.rb +39 -0
  169. data/spec/dummy/app/controllers/tagged_cats_controller.rb +32 -0
  170. data/spec/dummy/app/controllers/tagged_dogs_controller.rb +15 -0
  171. data/spec/dummy/app/controllers/twitter_example_controller.rb +307 -0
  172. data/spec/dummy/app/controllers/users_controller.rb +310 -0
  173. data/spec/dummy/app/helpers/random_param_group.rb +8 -0
  174. data/spec/dummy/app/views/layouts/application.html.erb +21 -0
  175. data/spec/dummy/components/test_engine/Gemfile +6 -0
  176. data/spec/dummy/components/test_engine/app/controllers/test_engine/application_controller.rb +4 -0
  177. data/spec/dummy/components/test_engine/app/controllers/test_engine/memes_controller.rb +37 -0
  178. data/spec/dummy/components/test_engine/config/routes.rb +3 -0
  179. data/spec/dummy/components/test_engine/db/.gitkeep +0 -0
  180. data/spec/dummy/components/test_engine/lib/test_engine.rb +7 -0
  181. data/spec/dummy/components/test_engine/test_engine.gemspec +11 -0
  182. data/spec/dummy/config/application.rb +47 -0
  183. data/spec/dummy/config/boot.rb +12 -0
  184. data/spec/dummy/config/database.yml +21 -0
  185. data/spec/dummy/config/environment.rb +8 -0
  186. data/spec/dummy/config/environments/development.rb +25 -0
  187. data/spec/dummy/config/environments/production.rb +49 -0
  188. data/spec/dummy/config/environments/test.rb +33 -0
  189. data/spec/dummy/config/initializers/apipie.rb +110 -0
  190. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  191. data/spec/dummy/config/initializers/inflections.rb +10 -0
  192. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  193. data/spec/dummy/config/initializers/secret_token.rb +8 -0
  194. data/spec/dummy/config/initializers/session_store.rb +8 -0
  195. data/spec/dummy/config/locales/en.yml +5 -0
  196. data/spec/dummy/config/routes.rb +61 -0
  197. data/spec/dummy/config.ru +4 -0
  198. data/spec/dummy/db/.gitkeep +0 -0
  199. data/spec/dummy/doc/apipie_examples.json +1 -0
  200. data/spec/dummy/doc/users/desc_from_file.md +1 -0
  201. data/spec/dummy/public/404.html +26 -0
  202. data/spec/dummy/public/422.html +26 -0
  203. data/spec/dummy/public/500.html +26 -0
  204. data/spec/dummy/public/favicon.ico +0 -0
  205. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  206. data/spec/dummy/script/rails +6 -0
  207. data/spec/lib/apipie/apipies_controller_spec.rb +345 -0
  208. data/spec/lib/apipie/application_spec.rb +62 -0
  209. data/spec/lib/apipie/configuration_spec.rb +38 -0
  210. data/spec/lib/apipie/extractor/collector_spec.rb +57 -0
  211. data/spec/lib/apipie/extractor/recorder/middleware_spec.rb +44 -0
  212. data/spec/lib/apipie/extractor/recorder_spec.rb +77 -0
  213. data/spec/lib/apipie/extractor/writer_spec.rb +112 -0
  214. data/spec/lib/apipie/extractor_spec.rb +9 -0
  215. data/spec/lib/apipie/file_handler_spec.rb +25 -0
  216. data/spec/lib/apipie/generator/swagger/config_spec.rb +19 -0
  217. data/spec/lib/apipie/generator/swagger/context_spec.rb +56 -0
  218. data/spec/lib/apipie/generator/swagger/method_description/api_schema_service_spec.rb +119 -0
  219. data/spec/lib/apipie/generator/swagger/method_description/response_schema_service_spec.rb +105 -0
  220. data/spec/lib/apipie/generator/swagger/method_description/response_service_spec.rb +62 -0
  221. data/spec/lib/apipie/generator/swagger/operation_id_spec.rb +63 -0
  222. data/spec/lib/apipie/generator/swagger/param_description/builder_spec.rb +245 -0
  223. data/spec/lib/apipie/generator/swagger/param_description/composite_spec.rb +95 -0
  224. data/spec/lib/apipie/generator/swagger/param_description/description_spec.rb +79 -0
  225. data/spec/lib/apipie/generator/swagger/param_description/in_spec.rb +86 -0
  226. data/spec/lib/apipie/generator/swagger/param_description/name_spec.rb +81 -0
  227. data/spec/lib/apipie/generator/swagger/param_description/type_spec.rb +210 -0
  228. data/spec/lib/apipie/generator/swagger/param_description_spec.rb +28 -0
  229. data/spec/lib/apipie/generator/swagger/path_decorator_spec.rb +57 -0
  230. data/spec/lib/apipie/generator/swagger/referenced_definitions_spec.rb +35 -0
  231. data/spec/lib/apipie/generator/swagger/resource_description_composite_spec.rb +37 -0
  232. data/spec/lib/apipie/generator/swagger/resource_descriptions_collection_spec.rb +57 -0
  233. data/spec/lib/apipie/generator/swagger/schema_spec.rb +89 -0
  234. data/spec/lib/apipie/generator/swagger/type_extractor_spec.rb +38 -0
  235. data/spec/lib/apipie/generator/swagger/warning_spec.rb +51 -0
  236. data/spec/lib/apipie/generator/swagger/warning_writer_spec.rb +71 -0
  237. data/spec/lib/apipie/method_description/apis_service_spec.rb +60 -0
  238. data/spec/lib/apipie/method_description_spec.rb +133 -0
  239. data/spec/lib/apipie/no_documented_method_spec.rb +17 -0
  240. data/spec/lib/apipie/param_description/deprecation_spec.rb +31 -0
  241. data/spec/lib/apipie/param_description_spec.rb +671 -0
  242. data/spec/lib/apipie/param_group_spec.rb +61 -0
  243. data/spec/lib/apipie/resource_description_spec.rb +91 -0
  244. data/spec/lib/apipie/response_description/response_object_spec.rb +22 -0
  245. data/spec/lib/apipie/response_description_spec.rb +56 -0
  246. data/spec/lib/apipie/response_does_not_match_swagger_schema_spec.rb +35 -0
  247. data/spec/lib/apipie/swagger_generator_spec.rb +94 -0
  248. data/spec/lib/apipie/validator_spec.rb +149 -0
  249. data/spec/lib/rake_spec.rb +69 -0
  250. data/spec/lib/swagger/openapi_2_0_schema.json +1614 -0
  251. data/spec/lib/swagger/rake_swagger_spec.rb +159 -0
  252. data/spec/lib/swagger/swagger_dsl_spec.rb +664 -0
  253. data/spec/lib/validators/array_validator_spec.rb +85 -0
  254. data/spec/spec_helper.rb +92 -0
  255. data/spec/support/custom_bool_validator.rb +17 -0
  256. data/spec/support/rake.rb +21 -0
  257. data/spec/test_engine/memes_controller_spec.rb +10 -0
  258. metadata +499 -0
@@ -0,0 +1,794 @@
1
+ require 'spec_helper'
2
+
3
+ def compare_hashes(h1, h2)
4
+ if h1.is_a? String
5
+ expect(h1).to eq(h2)
6
+ else
7
+ h1.each do |key, val|
8
+ case val
9
+ when Hash
10
+ compare_hashes val, h2[key]
11
+ when Array
12
+ val.each_with_index do |v, i|
13
+ compare_hashes val[i], h2[key][i]
14
+ end
15
+ else
16
+ expect(val).to eq(h2[key])
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ describe UsersController do
23
+
24
+ let(:dsl_data) { ActionController::Base.send(:_apipie_dsl_data_init) }
25
+
26
+ describe "resource description" do
27
+ subject do
28
+ Apipie.get_resource_description(UsersController, Apipie.configuration.default_version)
29
+ end
30
+
31
+ it "contains all resource methods" do
32
+ methods = subject._methods
33
+ expect(methods.keys).to include(:show)
34
+ expect(methods.keys).to include(:create_route)
35
+ expect(methods.keys).to include(:index)
36
+ expect(methods.keys).to include(:create)
37
+ expect(methods.keys).to include(:update)
38
+ expect(methods.keys).to include(:two_urls)
39
+ expect(methods.keys).to include(:action_with_headers)
40
+ expect(methods.keys).to include(:multiple_required_params)
41
+ end
42
+
43
+ it "contains info about resource" do
44
+ expect(subject._short_description).to eq('Site members')
45
+ expect(subject._id).to eq('users')
46
+ expect(subject._path).to eq('/users')
47
+ expect(subject._version).to eq('development')
48
+ expect(subject._name).to eq('Users')
49
+ expect(subject._formats).to eq(['json'])
50
+ end
51
+
52
+ it "contains params defined on resource level" do
53
+ expect(subject._params_args.count).to eq(2)
54
+ name, type, options = subject._params_args.first
55
+ expect(name).to eq(:id)
56
+ expect(type).to eq(Integer)
57
+ expect(options).to eq({:required=>false, :desc=>"User ID"})
58
+ end
59
+ end
60
+
61
+ describe "validators" do
62
+
63
+ context "validations are disabled" do
64
+ before do
65
+ Apipie.configuration.validate = false
66
+ Apipie.configuration.validate_value = true
67
+ Apipie.configuration.validate_presence = true
68
+ end
69
+
70
+ it "replies to valid request" do
71
+ get :show, :params => { :id => '5', :session => "secret_hash" }
72
+ assert_response :success
73
+ end
74
+
75
+ it "passes if required parameter is missing" do
76
+ expect { get :show, :params => { :id => 5 } }.not_to raise_error
77
+ end
78
+
79
+ end
80
+
81
+ context "validations are enabled" do
82
+ def reload_controllers
83
+ controllers_dirname = File.expand_path('../dummy/app/controllers', File.dirname(__FILE__))
84
+ Dir.glob("#{controllers_dirname}/**/*") { |file| load(file) if File.file?(file) }
85
+ end
86
+
87
+ shared_examples "validates correctly" do
88
+
89
+ context "only presence validations are enabled" do
90
+ before do
91
+ Apipie.configuration.validate_value = false
92
+ Apipie.configuration.validate_presence = true
93
+ Apipie.configuration.validate_key = false
94
+ end
95
+
96
+ it "replies to valid request" do
97
+ expect { get :show, :params => { :id => 5, :session => "secret_hash" }}.not_to raise_error
98
+ assert_response :success
99
+ end
100
+
101
+ it "fails if required parameter is missing" do
102
+ expect { get :show, :params => { :id => 5 }}.to raise_error(Apipie::ParamMissing, /session_parameter_is_required/)
103
+ end
104
+
105
+ it "fails if multiple required parameters are missing" do
106
+ expect { get :multiple_required_params }.to raise_error(Apipie::ParamMultipleMissing, /required_param1.*\n.*required_param2|required_param2.*\n.*required_parameter1/)
107
+ end
108
+
109
+ it "passes if required parameter has wrong type" do
110
+ expect { get :show, :params => { :id => 5 , :session => "secret_hash" }}.not_to raise_error
111
+ expect { get :show, :params => { :id => "ten" , :session => "secret_hash" }}.not_to raise_error
112
+ end
113
+
114
+ end
115
+
116
+ context "key validations are enabled" do
117
+ before do
118
+ Apipie.configuration.validate_value = false
119
+ Apipie.configuration.validate_presence = true
120
+ Apipie.configuration.validate_key = true
121
+ end
122
+
123
+ it "replies to valid request" do
124
+ expect { get :show, :params => { :id => 5, :session => 'secret_hash' }}.not_to raise_error
125
+ assert_response :success
126
+ end
127
+
128
+ it "fails if extra parameter is passed in" do
129
+ expect { get :show, :params => { :id => 5 , :badparam => 'badfoo', :session => "secret_hash" }}.to raise_error(Apipie::UnknownParam, /\bbadparam\b/)
130
+ end
131
+ end
132
+
133
+ context "key validations are enabled and skip on non-validated keys" do
134
+ before do
135
+ Apipie.configuration.validate_value = false
136
+ Apipie.configuration.validate_presence = true
137
+ Apipie.configuration.validate_key = true
138
+ Apipie.configuration.action_on_non_validated_keys = :skip
139
+ end
140
+
141
+ it "replies to valid request" do
142
+ expect { get :show, :params => { :id => 5, :session => 'secret_hash' }}.not_to raise_error
143
+ assert_response :success
144
+ end
145
+
146
+ it "deletes the param and not fail if an extra parameter is passed." do
147
+ expect { get :show, :params => { :id => 5 , :badparam => 'badfoo', :session => "secret_hash" }}.not_to raise_error
148
+ expect(controller.params.as_json).to eq({"session"=>"secret_hash", "id"=>"5", "controller"=>"users", "action"=>"show"})
149
+ end
150
+
151
+ after do
152
+ Apipie.configuration.action_on_non_validated_keys = :raise
153
+ end
154
+ end
155
+
156
+ context "presence and value validations are enabled" do
157
+ before do
158
+ Apipie.configuration.validate_value = true
159
+ Apipie.configuration.validate_presence = true
160
+ Apipie.configuration.validate_key = false
161
+ end
162
+
163
+ it "replies to valid request" do
164
+ get :show, :params => { :id => '5', :session => "secret_hash" }
165
+ assert_response :success
166
+ end
167
+
168
+ it "works with nil value for a required hash param" do
169
+ expect do
170
+ get :show, :params => { :id => '5', :session => "secret_hash", :hash_param => {:dummy_hash => nil} }
171
+ end.to raise_error(Apipie::ParamInvalid, /dummy_hash/)
172
+ assert_response :success
173
+ end
174
+
175
+ it "fails if required parameter is missing" do
176
+ expect { get :show, :params => { :id => 5 }}.to raise_error(Apipie::ParamMissing, /session_parameter_is_required/)
177
+ end
178
+
179
+ # old-style error rather than ParamInvalid
180
+ it "works with custom Type validator" do
181
+ expect do
182
+ get :show,
183
+ :params => { :id => "not a number", :session => "secret_hash" }
184
+ end.to raise_error(Apipie::ParamError, /id/)
185
+ end
186
+
187
+ it "works with Regexp validator" do
188
+ get :show, :params => { :id => 5, :session => "secret_hash", :regexp_param => "24 years" }
189
+ assert_response :success
190
+
191
+ expect do
192
+ get :show, :params => { :id => 5,
193
+ :session => "secret_hash",
194
+ :regexp_param => "ten years" }
195
+ end.to raise_error(Apipie::ParamInvalid, /regexp_param/)
196
+ end
197
+
198
+ it "works with Array validator" do
199
+ get :show, :params => { :id => 5, :session => "secret_hash", :array_param => "one" }
200
+ assert_response :success
201
+ get :show, :params => { :id => 5, :session => "secret_hash", :array_param => "two" }
202
+ assert_response :success
203
+ get :show, :params => { :id => 5, :session => "secret_hash", :array_param => '1' }
204
+ assert_response :success
205
+
206
+ expect do
207
+ get :show, :params => { :id => 5,
208
+ :session => "secret_hash",
209
+ :array_param => "blabla" }
210
+ end.to raise_error(Apipie::ParamInvalid, /array_param/)
211
+
212
+ expect do
213
+ get :show, :params => {
214
+ :id => 5,
215
+ :session => "secret_hash",
216
+ :array_param => 3 }
217
+ end.to raise_error(Apipie::ParamInvalid, /array_param/)
218
+ end
219
+
220
+ it "works with Proc validator" do
221
+ expect do
222
+ get :show,
223
+ :params => {
224
+ :id => 5,
225
+ :session => "secret_hash",
226
+ :proc_param => "asdgsag" }
227
+ end.to raise_error(Apipie::ParamInvalid, /proc_param/)
228
+
229
+ get :show,
230
+ :params => {
231
+ :id => 5,
232
+ :session => "secret_hash",
233
+ :proc_param => "param value"}
234
+ assert_response :success
235
+ end
236
+
237
+ it "works with Hash validator" do
238
+ post :create, params: { :user => { :name => "root", :pass => "12345", :membership => "standard" } }
239
+ assert_response :success
240
+
241
+ a = Apipie[UsersController, :create]
242
+ param = a.params_ordered.select {|p| p.name == :user }
243
+ expect(param.count).to eq(1)
244
+ expect(param.first.validator.class).to eq(Apipie::Validator::HashValidator)
245
+ hash_params = param.first.validator.params_ordered
246
+ expect(hash_params.count).to eq(4)
247
+ hash_params[0].name == :name
248
+ hash_params[1].name == :pass
249
+ hash_params[2].name == :membership
250
+
251
+ expect do
252
+ post :create, :params => { :user => { :name => "root", :pass => "12345", :membership => "____" } }
253
+ end.to raise_error(Apipie::ParamInvalid, /membership/)
254
+
255
+ # Should include both pass and name
256
+ expect do
257
+ post :create, :params => { :user => { :membership => "standard" } }
258
+ end.to raise_error(Apipie::ParamMultipleMissing, /pass.*\n.*name|name.*\n.*pass/)
259
+
260
+ expect do
261
+ post :create, :params => { :user => { :name => "root" } }
262
+ end.to raise_error(Apipie::ParamMissing, /pass/)
263
+
264
+ expect do
265
+ post :create, :params => { :user => "a string is not a hash" }
266
+ end.to raise_error(Apipie::ParamInvalid, /user/)
267
+
268
+ post :create, :params => { :user => { :name => "root", :pass => "pwd" } }
269
+ assert_response :success
270
+ end
271
+
272
+ it "supports Hash validator without specifying keys" do
273
+ params = Apipie[UsersController, :create].to_json[:params]
274
+ expect(params).to include(:name => "facts",
275
+ :full_name => "facts",
276
+ :validator => "Must be a Hash",
277
+ :description => "\n<p>Additional optional facts about the user</p>\n",
278
+ :required => false,
279
+ :allow_nil => true,
280
+ :allow_blank => false,
281
+ :metadata => nil,
282
+ :show => true,
283
+ :deprecated => false,
284
+ :expected_type => "hash",
285
+ :validations => [])
286
+ end
287
+
288
+ it "allows nil when allow_nil is set to true" do
289
+ post :create,
290
+ :params => {
291
+ :user => {
292
+ :name => "root",
293
+ :pass => "12345",
294
+ :membership => "standard",
295
+ },
296
+ :facts => { :test => 'test' }
297
+ }
298
+ assert_response :success
299
+ end
300
+
301
+ it "allows blank when allow_blank is set to true" do
302
+ post :create,
303
+ :params => {
304
+ :user => {
305
+ :name => "root",
306
+ :pass => "12345",
307
+ :membership => "standard"
308
+ },
309
+ :age => ""
310
+ }
311
+ assert_response :success
312
+ end
313
+
314
+ describe "nested elements" do
315
+
316
+ context "with valid input" do
317
+ it "succeeds" do
318
+ put :update,
319
+ :params => {
320
+ :id => 5,
321
+ :user => {
322
+ :name => "root",
323
+ :pass => "12345"
324
+ },
325
+ :comments => [
326
+ {
327
+ :comment => 'comment1'
328
+ },
329
+ {
330
+ :comment => 'comment2'
331
+ }
332
+ ]
333
+ }
334
+
335
+ assert_response :success
336
+ end
337
+ end
338
+ context "with bad input" do
339
+ it "raises an error" do
340
+ expect do
341
+ put :update,
342
+ :params => {
343
+ :id => 5,
344
+ :user => {
345
+ :name => "root",
346
+ :pass => "12345"
347
+ },
348
+ :comments => [
349
+ {
350
+ :comment => {:bad_input => 4}
351
+ },
352
+ {
353
+ :comment => {:bad_input => 5}
354
+ }
355
+ ]
356
+ }
357
+ end.to raise_error(Apipie::ParamInvalid)
358
+ end
359
+ end
360
+ it "works with empty array" do
361
+ put :update,
362
+ :params => {
363
+ :id => 5,
364
+ :user => {
365
+ :name => "root",
366
+ :pass => "12345"
367
+ },
368
+ :comments => [
369
+ ]
370
+ }
371
+
372
+ assert_response :success
373
+ end
374
+ end
375
+
376
+ end
377
+ end
378
+
379
+ context "using configuration.validate = true" do
380
+ before :all do
381
+ Apipie.configuration.validate = true
382
+ reload_controllers
383
+ end
384
+
385
+ it_behaves_like "validates correctly"
386
+ end
387
+
388
+ context "using configuration.validate = :implicitly" do
389
+ before :all do
390
+ Apipie.configuration.validate = :implicitly
391
+ reload_controllers
392
+ end
393
+
394
+ it_behaves_like "validates correctly"
395
+ end
396
+
397
+ context "using configuration.validate = :explicitly" do
398
+ before :all do
399
+ Apipie.configuration.validate = :explicitly
400
+ reload_controllers
401
+ end
402
+
403
+ it_behaves_like "validates correctly"
404
+ end
405
+ end
406
+
407
+ end
408
+
409
+ describe "method description" do
410
+
411
+ it "contains basic info about method" do
412
+ a = Apipie[UsersController, :create]
413
+ expect(a.apis.count).to eq(1)
414
+ expect(a.formats).to eq(['json'])
415
+ api = a.apis.first
416
+ expect(api.short_description).to eq("Create user")
417
+ expect(api.path).to eq("/users")
418
+ expect(api.http_method).to eq("POST")
419
+
420
+ b = Apipie.get_method_description(UsersController, :show)
421
+ expect(b).to eq(Apipie[UsersController, :show])
422
+ expect(b.method).to eq('show')
423
+ expect(b.resource._id).to eq('users')
424
+
425
+ expect(b.apis.count).to eq(1)
426
+ expect(b.formats).to eq(%w[json jsonp])
427
+ api = b.apis.first
428
+ expect(api.short_description).to eq("Show user profile")
429
+ expect(api.path).to eq("/users/:id")
430
+ expect(api.http_method).to eq("GET")
431
+ expect(b.full_description.length).to be > 400
432
+ end
433
+
434
+ context "Using routes.rb" do
435
+ it "contains basic info about method" do
436
+ a = Apipie[UsersController, :create_route]
437
+ expect(a.apis.count).to eq(1)
438
+ expect(a.formats).to eq(['json'])
439
+ api = a.apis.first
440
+ expect(api.short_description).to eq("Create user")
441
+ expect(api.path).to eq("/api/users/create_route")
442
+ expect(api.from_routes).to be_truthy
443
+ expect(api.http_method).to eq("POST")
444
+ end
445
+ end
446
+
447
+ context "contain :see option" do
448
+
449
+ context "the key is valid" do
450
+ it "contains reference to another method" do
451
+ api = Apipie[UsersController, :see_another]
452
+ expect(api.show).to be false
453
+ see = api.see.first
454
+ expect(see.see_url).to eql Apipie[UsersController, :create].doc_url
455
+ expect(see.link).to eql 'development#users#create'
456
+ expect(see.description).to eql 'development#users#create'
457
+
458
+ see_with_desc = api.see.last
459
+ expect(see_with_desc.see_url).to eql Apipie[UsersController, :index].doc_url
460
+ expect(see_with_desc.link).to eql 'development#users#index'
461
+ expect(see_with_desc.description).to eql 'very interesting method reference'
462
+
463
+ expect(Apipie['development#users#see_another']).to eql Apipie[UsersController, :see_another]
464
+ end
465
+ end
466
+
467
+ context "the key is not valid" do
468
+ it "raises exception" do
469
+ api = Apipie[UsersController, :see_another]
470
+ api.instance_variable_set :@see, [Apipie::SeeDescription.new(['doesnot#exist'])]
471
+ expect do
472
+ api.see.first.see_url
473
+ end.to raise_error(ArgumentError, /does not exist/)
474
+ api.instance_variable_set :@see, []
475
+ end
476
+ end
477
+ end
478
+
479
+ it "contains possible errors description" do
480
+ a = Apipie.get_method_description(UsersController, :show)
481
+
482
+ expect(a.errors[0].code).to eq(500)
483
+ expect(a.errors[0].description).to include("crashed")
484
+ expect(a.errors[1].code).to eq(401)
485
+ expect(a.errors[1].description).to eq("Unauthorized")
486
+ expect(a.errors[2].code).to eq(404)
487
+ expect(a.errors[2].description).to eq("Not Found")
488
+ end
489
+
490
+ it 'recognizes Rack symbols as error codes' do
491
+ a = Apipie.get_method_description(UsersController, :create)
492
+
493
+ error = a.errors.find { |e| e.code == 422 }
494
+ expect(error).to be
495
+ expect(error.description).to include("Unprocessable Entity")
496
+ end
497
+
498
+ it "contains all params description" do
499
+ a = Apipie.get_method_description(UsersController, :show)
500
+ expect(a.params.count).to eq(12)
501
+ expect(a.instance_variable_get('@params_ordered').count).to eq(10)
502
+ end
503
+
504
+ context 'headers' do
505
+ context 'for methods' do
506
+ let(:expected_required_header) do
507
+ {
508
+ name: :RequredHeaderName,
509
+ description: 'Required header description',
510
+ options: {
511
+ required: true
512
+ }
513
+ }
514
+ end
515
+
516
+ let(:expected_optional_header) do
517
+ {
518
+ name: :OptionalHeaderName,
519
+ description: 'Optional header description',
520
+ options: {
521
+ required: false,
522
+ type: "string"
523
+ }
524
+ }
525
+ end
526
+
527
+ let(:expected_header_with_default) do
528
+ {
529
+ name: :HeaderNameWithDefaultValue,
530
+ description: 'Header with default value',
531
+ options: {
532
+ required: true,
533
+ default: 'default value'
534
+ }
535
+ }
536
+ end
537
+
538
+ it 'contains all headers description in method doc' do
539
+ headers = Apipie.get_method_description(UsersController, :action_with_headers).headers
540
+ expect(headers).to be_an(Array)
541
+
542
+ compare_hashes headers[0], expected_required_header
543
+ compare_hashes headers[1], expected_optional_header
544
+ compare_hashes headers[2], expected_header_with_default
545
+ end
546
+ end
547
+
548
+ context 'for resource' do
549
+ let(:expected_resource_header) do
550
+ {
551
+ name: :CommonHeader,
552
+ description: 'Common header description',
553
+ options: {
554
+ required: true
555
+ }
556
+ }
557
+ end
558
+
559
+ it 'contains all headers description in resource doc' do
560
+ headers = Apipie.get_resource_description(UsersController)._headers
561
+ expect(headers).to be_an(Array)
562
+
563
+ compare_hashes headers[0], expected_resource_header
564
+ end
565
+ end
566
+ end
567
+
568
+ it "contains all api method description" do
569
+ method_description = Apipie[UsersController, :two_urls]
570
+ expect(method_description.class).to be(Apipie::MethodDescription)
571
+ expect(method_description.apis.count).to eq(2)
572
+ a1, a2 = method_description.apis
573
+
574
+ expect(a1.short_description).to eq('Get company users')
575
+ expect(a1.path).to eq('/company_users')
576
+ expect(a1.http_method).to eq('GET')
577
+
578
+ expect(a2.short_description).to eq('Get users working in given company')
579
+ expect(a2.path).to eq('/company/:id/users')
580
+ expect(a2.http_method).to eq('GET')
581
+ end
582
+
583
+ it "is described by valid json" do
584
+ json = Apipie[UsersController, :two_urls].to_json
585
+ expected_hash = {
586
+ :errors => [{:code=>404, :description=>"Missing", :metadata => {:some => "metadata"}},
587
+ {:code=>500, :description=>"Server crashed for some <%= reason %>"}],
588
+ :examples => [],
589
+ :doc_url => "#{Apipie.configuration.doc_base_url}/development/users/two_urls",
590
+ :formats=>["json"],
591
+ :full_description => '',
592
+ :params => [{:full_name=>"oauth",
593
+ :required=>false,
594
+ :allow_nil => false,
595
+ :allow_blank => false,
596
+ :validator=>"Must be a String",
597
+ :description=>"\n<p>Authorization</p>\n",
598
+ :name=>"oauth",
599
+ :show=>true,
600
+ :deprecated=>false,
601
+ :expected_type=>"string"},
602
+ {:validator=>"Must be a Hash",
603
+ :description=>"\n<p>Deprecated parameter not documented</p>\n",
604
+ :expected_type=>"hash",
605
+ :allow_nil=>false,
606
+ :allow_blank => false,
607
+ :name=>"legacy_param",
608
+ :required=>false,
609
+ :full_name=>"legacy_param",
610
+ :show=>false,
611
+ :deprecated=>false,
612
+ :params=>
613
+ [{:validator=>"Must be a Hash",
614
+ :description=>"\n<p>Param description for all methods</p>\n",
615
+ :expected_type=>"hash",
616
+ :allow_nil=>false,
617
+ :allow_blank => false,
618
+ :name=>"resource_param",
619
+ :required=>false,
620
+ :full_name=>"resource_param",
621
+ :deprecated=>false,
622
+ :show=>true,
623
+ :params=>
624
+ [{:required=>true,
625
+ :allow_nil => false,
626
+ :allow_blank => false,
627
+ :validator=>"Must be a String",
628
+ :description=>"\n<p>Username for login</p>\n",
629
+ :name=>"ausername", :full_name=>"resource_param[ausername]",
630
+ :show=>true,
631
+ :deprecated=>false,
632
+ :expected_type=>"string"},
633
+ {:required=>true,
634
+ :allow_nil => false,
635
+ :allow_blank => false,
636
+ :validator=>"Must be a String",
637
+ :description=>"\n<p>Password for login</p>\n",
638
+ :name=>"apassword", :full_name=>"resource_param[apassword]",
639
+ :show=>true,
640
+ :deprecated=>false,
641
+ :expected_type=>"string"}
642
+ ]}
643
+ ]
644
+ },
645
+ {:required=>false, :validator=>"Parameter has to be Integer.",
646
+ :allow_nil => false,
647
+ :allow_blank => false,
648
+ :description=>"\n<p>Company ID</p>\n",
649
+ :name=>"id", :full_name=>"id",
650
+ :show=>true,
651
+ :deprecated=>false,
652
+ :expected_type=>"numeric"},
653
+ ],
654
+ :name => 'two_urls',
655
+ :show => true,
656
+ :apis => [
657
+ {
658
+ :http_method => 'GET',
659
+ :short_description => 'Get company users',
660
+ :api_url => "#{Apipie.api_base_url}/company_users"
661
+ },{
662
+ :http_method => 'GET',
663
+ :short_description => 'Get users working in given company',
664
+ :api_url =>"#{Apipie.api_base_url}/company/:id/users"
665
+ }
666
+ ]
667
+ }
668
+
669
+ compare_hashes json, expected_hash
670
+ end
671
+
672
+ end
673
+
674
+ describe "examples" do
675
+
676
+ it "is able to load examples from yml file" do
677
+ expect(Apipie.get_method_description(UsersController, :show).examples).to eq [<<EOS1, <<EOS2].map(&:chomp)
678
+ GET /users/14?verbose=true
679
+ 200
680
+ {
681
+ "name": "Test User"
682
+ }
683
+ EOS1
684
+ GET /users/15
685
+ 404
686
+ EOS2
687
+ end
688
+
689
+ describe "document" do
690
+ it "is able to load document from markup file" do
691
+ expect(Apipie.get_method_description(UsersController, :desc_from_file).full_description).to include("description from document")
692
+ end
693
+ end
694
+ end
695
+
696
+ describe "param description" do
697
+
698
+ it "contains all specified information" do
699
+ a = Apipie.get_method_description(UsersController, :show)
700
+
701
+ param = a.params[:session]
702
+ expect(param.required).to eq(true)
703
+ expect(param.desc).to eq("\n<p>user is logged in</p>\n")
704
+ expect(param.validator.class).to be(Apipie::Validator::TypeValidator)
705
+ expect(param.validator.instance_variable_get("@type")).to eq(String)
706
+
707
+ param = a.params[:id]
708
+ expect(param.required).to eq(true)
709
+ expect(param.desc).to eq("\n<p>user id</p>\n")
710
+ expect(param.validator.class).to be(Apipie::Validator::IntegerValidator)
711
+ expect(param.validator.instance_variable_get("@type")).to eq(Integer)
712
+
713
+ param = a.params[:regexp_param]
714
+ expect(param.desc).to eq("\n<p>regexp param</p>\n")
715
+ expect(param.required).to eq(false)
716
+ expect(param.validator.class).to be(Apipie::Validator::RegexpValidator)
717
+ expect(param.validator.instance_variable_get("@regexp")).to eq(/^[0-9]* years/)
718
+
719
+ param = a.params[:array_param]
720
+ expect(param.desc).to eq("\n<p>array validator</p>\n")
721
+ expect(param.validator.class).to be(Apipie::Validator::EnumValidator)
722
+ expect(param.validator.instance_variable_get("@array")).to eq(%w[100 one two 1 2])
723
+
724
+ param = a.params[:proc_param]
725
+ expect(param.desc).to eq("\n<p>proc validator</p>\n")
726
+ expect(param.validator.class).to be(Apipie::Validator::ProcValidator)
727
+
728
+ param = a.params[:briefer_dsl]
729
+ expect(param.desc).to eq("\n<p>You dont need :desc =&gt; from now</p>\n")
730
+ expect(param.validator.class).to be(Apipie::Validator::TypeValidator)
731
+ end
732
+
733
+ end
734
+
735
+ describe "ignored option" do
736
+ class IgnoredController < ApplicationController; end
737
+
738
+ after do
739
+ Apipie.configuration.ignored = %w[]
740
+ end
741
+
742
+ describe "ignored action" do
743
+ before do
744
+ Apipie.configuration.ignored = %w[UsersController#ignore]
745
+ end
746
+
747
+ it "skips the listed actions from the documentation" do
748
+ Apipie.define_method_description(UsersController, :ignore, dsl_data)
749
+ expect(Apipie.get_method_description(UsersController, :ignore)).to be_nil
750
+
751
+ Apipie.define_method_description(UsersController, :dont_ignore, dsl_data)
752
+ expect(Apipie.get_method_description(UsersController, :dont_ignore)).not_to be_nil
753
+ end
754
+ end
755
+
756
+ describe "ignored controller" do
757
+ before do
758
+ Apipie.configuration.ignored = %w[IgnoredController]
759
+ end
760
+
761
+ it "skips the listed controller from the documentation" do
762
+ Apipie.define_method_description(IgnoredController, :ignore, dsl_data)
763
+ expect(Apipie.get_method_description(IgnoredController, :ignore)).to be_nil
764
+ Apipie.define_method_description(IgnoredController, :ignore, dsl_data)
765
+ expect(Apipie.get_method_description(IgnoredController, :ignore)).to be_nil
766
+ end
767
+ end
768
+ end
769
+
770
+ describe "Parameter processing / extraction" do
771
+ before do
772
+ Apipie.configuration.validate = true
773
+ Apipie.configuration.process_params = true
774
+ controllers_dirname = File.expand_path('../dummy/app/controllers', File.dirname(__FILE__))
775
+ Dir.glob("#{controllers_dirname}/**/*") { |file| load(file) if File.file?(file) }
776
+ end
777
+
778
+ it "process correctly the parameters" do
779
+ post :create, :params => {:user => {:name => 'dummy', :pass => 'dummy', :membership => 'standard' }, :facts => {:test => 'test'}}
780
+
781
+ expect(assigns(:api_params).with_indifferent_access).to eq({:user => {:name=>"dummy", :pass=>"dummy", :membership=>"standard"}, :facts => {:test => 'test'}}.with_indifferent_access)
782
+ end
783
+
784
+ it "ignore not described parameters" do
785
+ post :create, :params => {:user => {:name => 'dummy', :pass => 'dummy', :membership => 'standard', :id => 0}}
786
+
787
+ expect(assigns(:api_params).with_indifferent_access).to eq({:user => {:name=>"dummy", :pass=>"dummy", :membership=>"standard"}}.with_indifferent_access)
788
+ end
789
+
790
+ after do
791
+ Apipie.configuration.process_params = false
792
+ end
793
+ end
794
+ end