power_api 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,468 +0,0 @@
1
- # rubocop:disable Metrics/ModuleLength
2
- # rubocop:disable Metrics/MethodLength
3
- # rubocop:disable Layout/AlignParameters
4
- module PowerApi::GeneratorHelper::SwaggerHelper
5
- extend ActiveSupport::Concern
6
-
7
- included do
8
- include PowerApi::GeneratorHelper::ApiHelper
9
- include PowerApi::GeneratorHelper::ResourceHelper
10
- include PowerApi::GeneratorHelper::SimpleTokenAuthHelper
11
- include PowerApi::GeneratorHelper::TemplateBuilderHelper
12
- include PowerApi::GeneratorHelper::ControllerActionsHelper
13
- end
14
-
15
- def swagger_helper_path
16
- "spec/swagger_helper.rb"
17
- end
18
-
19
- def spec_swagger_path
20
- "spec/swagger/.gitkeep"
21
- end
22
-
23
- def spec_integration_path
24
- "spec/integration/.gitkeep"
25
- end
26
-
27
- def rswag_ui_initializer_path
28
- "config/initializers/rswag-ui.rb"
29
- end
30
-
31
- def swagger_schemas_path
32
- "spec/swagger/v#{version_number}/schemas/.gitkeep"
33
- end
34
-
35
- def swagger_resource_spec_path
36
- "spec/integration/api/v#{version_number}/#{resource.plural}_spec.rb"
37
- end
38
-
39
- def swagger_version_definition_path
40
- "spec/swagger/v#{version_number}/definition.rb"
41
- end
42
-
43
- def swagger_resource_schema_path
44
- "spec/swagger/v#{version_number}/schemas/#{resource.snake_case}_schema.rb"
45
- end
46
-
47
- def rswag_ui_configure_line
48
- "Rswag::Ui.configure do |c|\n"
49
- end
50
-
51
- def swagger_helper_api_definition_line
52
- "config.swagger_docs = {\n"
53
- end
54
-
55
- def swagger_definition_line_to_inject_schema
56
- /definitions: {/
57
- end
58
-
59
- def rswag_ui_initializer_tpl
60
- <<~INITIALIZER
61
- Rswag::Ui.configure do |c|
62
- end
63
- INITIALIZER
64
- end
65
-
66
- def swagger_helper_tpl
67
- <<~SWAGGER
68
- require 'rails_helper'
69
-
70
- Dir[::Rails.root.join("spec/swagger/**/schemas/*.rb")].each { |f| require f }
71
- Dir[::Rails.root.join("spec/swagger/**/definition.rb")].each { |f| require f }
72
-
73
- RSpec.configure do |config|
74
- # Specify a root folder where Swagger JSON files are generated
75
- # NOTE: If you're using the rswag-api to serve API descriptions, you'll need
76
- # to ensure that it's confiugred to serve Swagger from the same folder
77
- config.swagger_root = Rails.root.to_s + '/swagger'
78
-
79
- # Define one or more Swagger documents and provide global metadata for each one
80
- # When you run the 'rswag:specs:to_swagger' rake task, the complete Swagger will
81
- # be generated at the provided relative path under swagger_root
82
- # By default, the operations defined in spec files are added to the first
83
- # document below. You can override this behavior by adding a swagger_doc tag to the
84
- # the root example_group in your specs, e.g. describe '...', swagger_doc: 'v2/swagger.json'
85
- config.swagger_docs = {
86
- }
87
- end
88
- SWAGGER
89
- end
90
-
91
- def rswag_ui_swagger_endpoint
92
- " c.swagger_endpoint '/api-docs/v#{version_number}/swagger.json', \
93
- 'API V#{version_number} Docs'\n"
94
- end
95
-
96
- def swagger_helper_api_definition
97
- content = " 'v#{version_number}/swagger.json' => API_V#{version_number}"
98
- content = "#{content}," unless first_version?
99
- "#{content}\n"
100
- end
101
-
102
- def swagger_definition_tpl
103
- <<~DEFINITION
104
- API_V#{version_number} = {
105
- swagger: '2.0',
106
- info: {
107
- title: 'API V#{version_number}',
108
- version: 'v#{version_number}'
109
- },
110
- basePath: '/api/v#{version_number}',
111
- definitions: {
112
- }
113
- }
114
- DEFINITION
115
- end
116
-
117
- def swagger_schema_tpl
118
- <<~SCHEMA
119
- #{swagger_model_definition_const} = {
120
- type: :object,
121
- properties: {#{get_swagger_schema_attributes_definitions}
122
- },
123
- required: [#{get_swagger_schema_attributes_names}
124
- ]
125
- }
126
-
127
- #{swagger_collection_definition_const} = {
128
- type: "object",
129
- properties: {
130
- #{resource.plural}: {
131
- type: "array",
132
- items: { "$ref" => "#/definitions/#{resource.snake_case}" }
133
- }
134
- },
135
- required: [
136
- :#{resource.plural}
137
- ]
138
- }
139
-
140
- #{swagger_resource_definition_const} = {
141
- type: "object",
142
- properties: {
143
- #{resource.snake_case}: { "$ref" => "#/definitions/#{resource.snake_case}" }
144
- },
145
- required: [
146
- :#{resource.snake_case}
147
- ]
148
- }
149
- SCHEMA
150
- end
151
-
152
- def swagger_definition_entry
153
- [
154
- "\n #{resource.snake_case}: #{swagger_model_definition_const},",
155
- "\n #{resource.plural}_collection: #{swagger_collection_definition_const},",
156
- "\n #{resource.snake_case}_resource: #{swagger_resource_definition_const},"
157
- ].join
158
- end
159
-
160
- def swagger_resource_spec_tpl
161
- concat_tpl_statements(
162
- "require 'swagger_helper'\n",
163
- concat_tpl_statements(
164
- spec_tpl_initial_describe_line,
165
- spec_tpl_authenticated_resource,
166
- spec_tpl_let_parent_resource,
167
- spec_tpl_collection_path_statements,
168
- spec_tpl_resource_path_statements,
169
- "end\n"
170
- )
171
- )
172
- end
173
-
174
- private
175
-
176
- def spec_tpl_initial_describe_line
177
- "describe 'API V#{version_number} #{resource.plural_titleized}', \
178
- swagger_doc: 'v#{version_number}/swagger.json' do"
179
- end
180
-
181
- def spec_tpl_authenticated_resource
182
- return unless authenticated_resource?
183
-
184
- res_name = authenticated_resource.snake_case
185
- concat_tpl_statements(
186
- "let(:#{res_name}) { create(:#{res_name}) }",
187
- "let(:#{res_name}_email) { #{res_name}.email }",
188
- "let(:#{res_name}_token) { #{res_name}.authentication_token }\n"
189
- )
190
- end
191
-
192
- def spec_tpl_collection_path_statements
193
- return unless collection_actions?
194
-
195
- concat_tpl_statements(
196
- "path '/#{spec_tpl_collection_path}' do",
197
- spec_tpl_parent_resource_parameter,
198
- spec_tpl_authenticated_resource_params,
199
- spec_tpl_index,
200
- spec_tpl_create,
201
- "end\n"
202
- )
203
- end
204
-
205
- def spec_tpl_collection_path
206
- return resource.plural unless parent_resource?
207
-
208
- "#{parent_resource.plural}/{#{parent_resource.id}}/#{resource.plural}"
209
- end
210
-
211
- def spec_tpl_resource_path_statements
212
- return unless resource_actions?
213
-
214
- concat_tpl_statements(
215
- "path '/#{resource.plural}/{id}' do",
216
- spec_tpl_authenticated_resource_params,
217
- spec_tpl_let_existent_resource,
218
- spec_tpl_show,
219
- spec_tpl_update,
220
- spec_tpl_destroy,
221
- "end\n"
222
- )
223
- end
224
-
225
- def spec_tpl_let_existent_resource
226
- statement = ["let(:existent_#{resource.snake_case}) { create(:#{resource.snake_case}"]
227
- load_owner_resource_option(statement)
228
-
229
- concat_tpl_statements(
230
- "parameter name: :id, in: :path, type: :integer\n",
231
- "#{statement.join(', ')}) }",
232
- "let(:id) { existent_#{resource.snake_case}.id }\n"
233
- )
234
- end
235
-
236
- def spec_tpl_authenticated_resource_params
237
- return unless authenticated_resource?
238
-
239
- res_name = authenticated_resource.snake_case
240
- concat_tpl_statements(
241
- "parameter name: :#{res_name}_email, in: :query, type: :string",
242
- "parameter name: :#{res_name}_token, in: :query, type: :string\n"
243
- )
244
- end
245
-
246
- def spec_tpl_index
247
- return unless index?
248
-
249
- concat_tpl_statements(
250
- "get 'Retrieves #{resource.plural_titleized}' do",
251
- "description 'Retrieves all the #{resource.plural}'",
252
- "produces 'application/json'\n",
253
- "let(:collection_count) { 5 }",
254
- "let(:expected_collection_count) { collection_count }\n",
255
- "before { #{spec_tpl_index_creation_list} }",
256
- "response '200', '#{resource.plural_titleized} retrieved' do",
257
- "schema('$ref' => '#/definitions/#{resource.plural}_collection')\n",
258
- "run_test! do |response|",
259
- "expect(JSON.parse(response.body)['#{resource.plural}'].count).to eq(expected_collection_count)",
260
- "end",
261
- "end\n",
262
- spec_tpl_invalid_credentials,
263
- "end\n"
264
- )
265
- end
266
-
267
- def spec_tpl_index_creation_list
268
- statement = ["create_list(:#{resource.snake_case}, collection_count"]
269
- load_owner_resource_option(statement)
270
- statement.join(', ') + ')'
271
- end
272
-
273
- def load_owner_resource_option(statement)
274
- if parent_resource?
275
- statement << "#{parent_resource.snake_case}: #{parent_resource.snake_case}"
276
- end
277
-
278
- if owned_by_authenticated_resource?
279
- statement << "#{authenticated_resource.snake_case}: #{authenticated_resource.snake_case}"
280
- end
281
- end
282
-
283
- def spec_tpl_create
284
- return unless create?
285
-
286
- concat_tpl_statements(
287
- "post 'Creates #{resource.titleized}' do",
288
- "description 'Creates #{resource.titleized}'",
289
- "consumes 'application/json'",
290
- "produces 'application/json'",
291
- "parameter(name: :#{resource.snake_case}, in: :body)\n",
292
- "response '201', '#{resource.snake_case} created' do",
293
- "let(:#{resource.snake_case}) do",
294
- "{#{resource_params}}",
295
- "end\n",
296
- "run_test!",
297
- "end\n",
298
- spec_tpl_create_invalid_attrs_test,
299
- spec_tpl_invalid_credentials(with_body: true),
300
- "end\n"
301
- )
302
- end
303
-
304
- def spec_tpl_parent_resource_parameter
305
- return unless parent_resource?
306
-
307
- "parameter name: :#{parent_resource.id}, in: :path, type: :integer"
308
- end
309
-
310
- def spec_tpl_let_parent_resource
311
- return unless parent_resource?
312
-
313
- concat_tpl_statements(
314
- "let(:#{parent_resource.snake_case}) { create(:#{parent_resource.snake_case}) }",
315
- "let(:#{parent_resource.id}) { #{parent_resource.snake_case}.id }\n"
316
- )
317
- end
318
-
319
- def spec_tpl_show
320
- return unless show?
321
-
322
- concat_tpl_statements(
323
- "get 'Retrieves #{resource.titleized}' do",
324
- "produces 'application/json'\n",
325
- "response '200', '#{resource.snake_case} retrieved' do",
326
- "schema('$ref' => '#/definitions/#{resource.snake_case}_resource')\n",
327
- "run_test!",
328
- "end\n",
329
- "response '404', 'invalid #{resource.snake_case} id' do",
330
- "let(:id) { 'invalid' }",
331
- "run_test!",
332
- "end\n",
333
- spec_tpl_invalid_credentials,
334
- "end\n"
335
- )
336
- end
337
-
338
- def spec_tpl_update
339
- return unless update?
340
-
341
- concat_tpl_statements(
342
- "put 'Updates #{resource.titleized}' do",
343
- "description 'Updates #{resource.titleized}'",
344
- "consumes 'application/json'",
345
- "produces 'application/json'",
346
- "parameter(name: :#{resource.snake_case}, in: :body)\n",
347
- "response '200', '#{resource.snake_case} updated' do",
348
- "let(:#{resource.snake_case}) do",
349
- "{#{resource_params}}",
350
- "end\n",
351
- "run_test!",
352
- "end\n",
353
- spec_tpl_update_invalid_attrs_test,
354
- spec_tpl_invalid_credentials(with_body: true),
355
- "end\n"
356
- )
357
- end
358
-
359
- def spec_tpl_destroy
360
- return unless destroy?
361
-
362
- concat_tpl_statements(
363
- "delete 'Deletes #{resource.titleized}' do",
364
- "produces 'application/json'",
365
- "description 'Deletes specific #{resource.snake_case}'\n",
366
- "response '204', '#{resource.snake_case} deleted' do",
367
- "run_test!",
368
- "end\n",
369
- "response '404', '#{resource.snake_case} not found' do",
370
- "let(:id) { 'invalid' }\n",
371
- "run_test!",
372
- "end\n",
373
- spec_tpl_invalid_credentials,
374
- "end\n"
375
- )
376
- end
377
-
378
- def spec_tpl_invalid_credentials(with_body: false)
379
- return unless authenticated_resource?
380
-
381
- authenticated_resource_name = authenticated_resource.snake_case
382
- concat_tpl_statements(
383
- "response '401', '#{authenticated_resource_name} unauthorized' do",
384
- with_body ? "let(:#{resource.snake_case}) { {} }" : nil,
385
- "let(:user_token) { 'invalid' }\n",
386
- "run_test!",
387
- "end\n"
388
- )
389
- end
390
-
391
- def spec_tpl_update_invalid_attrs_test
392
- spec_tpl_create_invalid_attrs_test
393
- end
394
-
395
- def spec_tpl_create_invalid_attrs_test
396
- return if resource.required_resource_attributes.blank?
397
-
398
- concat_tpl_statements(
399
- "response '400', 'invalid attributes' do",
400
- "let(:#{resource.snake_case}) do",
401
- "{#{invalid_resource_params}}",
402
- "end\n",
403
- "run_test!",
404
- "end\n"
405
- )
406
- end
407
-
408
- def resource_params
409
- attrs = if resource.required_resource_attributes.any?
410
- resource.required_resource_attributes
411
- else
412
- resource.optional_resource_attributes
413
- end
414
-
415
- for_each_schema_attribute(attrs) do |attr|
416
- "#{attr[:name]}: #{attr[:example]},"
417
- end
418
- end
419
-
420
- def invalid_resource_params
421
- return unless resource.required_resource_attributes.any?
422
-
423
- for_each_schema_attribute([resource.required_resource_attributes.first]) do |attr|
424
- "#{attr[:name]}: nil,"
425
- end
426
- end
427
-
428
- def swagger_model_definition_const
429
- "#{resource.upcase}_SCHEMA"
430
- end
431
-
432
- def swagger_collection_definition_const
433
- "#{resource.upcase_plural}_COLLECTION_SCHEMA"
434
- end
435
-
436
- def swagger_resource_definition_const
437
- "#{resource.upcase}_RESOURCE_SCHEMA"
438
- end
439
-
440
- def get_swagger_schema_attributes_definitions
441
- for_each_schema_attribute(resource.resource_attributes) do |attr|
442
- opts = ["example: #{attr[:example]}"]
443
- opts << "'x-nullable': true" unless attr[:required] || attr[:name] == :id
444
- opts
445
-
446
- "#{attr[:name]}: { type: :#{attr[:swagger_type]}, #{opts.join(', ')} },"
447
- end
448
- end
449
-
450
- def get_swagger_schema_attributes_names
451
- for_each_schema_attribute(
452
- resource.required_resource_attributes(include_id: true)
453
- ) do |attr|
454
- ":#{attr[:name]},"
455
- end
456
- end
457
-
458
- def for_each_schema_attribute(attributes)
459
- attributes.inject("") do |memo, attr|
460
- memo += "\n"
461
- memo += yield(attr)
462
- memo
463
- end.delete_suffix(",")
464
- end
465
- end
466
- # rubocop:enable Metrics/ModuleLength
467
- # rubocop:enable Metrics/MethodLength
468
- # rubocop:enable Layout/AlignParameters