power_api 2.0.0 → 2.1.0

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.
@@ -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