power_api 0.2.0 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +104 -0
  3. data/.circleci/setup-rubygems.sh +3 -0
  4. data/.rubocop.yml +0 -1
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +19 -1
  7. data/Gemfile +2 -0
  8. data/Gemfile.lock +189 -166
  9. data/README.md +365 -103
  10. data/app/controllers/power_api/base_controller.rb +0 -1
  11. data/app/helpers/power_api/application_helper.rb +57 -0
  12. data/bin/clean_test_app +2 -0
  13. data/lib/generators/power_api/controller/controller_generator.rb +27 -15
  14. data/lib/generators/power_api/exposed_api_config/USAGE +5 -0
  15. data/lib/generators/power_api/exposed_api_config/exposed_api_config_generator.rb +58 -0
  16. data/lib/generators/power_api/install/install_generator.rb +2 -44
  17. data/lib/generators/power_api/internal_api_config/USAGE +5 -0
  18. data/lib/generators/power_api/internal_api_config/internal_api_config_generator.rb +31 -0
  19. data/lib/generators/power_api/version/version_generator.rb +2 -2
  20. data/lib/power_api/engine.rb +6 -1
  21. data/lib/power_api/errors.rb +2 -0
  22. data/lib/power_api/generator_helper/active_record_resource.rb +10 -6
  23. data/lib/power_api/generator_helper/ams_helper.rb +5 -11
  24. data/lib/power_api/generator_helper/api_helper.rb +61 -0
  25. data/lib/power_api/generator_helper/controller_helper.rb +45 -15
  26. data/lib/power_api/generator_helper/routes_helper.rb +22 -7
  27. data/lib/power_api/generator_helper/rspec_controller_helper.rb +306 -0
  28. data/lib/power_api/generator_helper/swagger_helper.rb +14 -24
  29. data/lib/power_api/generator_helpers.rb +2 -1
  30. data/lib/power_api/version.rb +1 -1
  31. data/power_api.gemspec +3 -2
  32. data/spec/dummy/Rakefile +1 -1
  33. data/spec/dummy/app/assets/config/manifest.js +0 -2
  34. data/spec/dummy/app/controllers/api/base_controller.rb +2 -0
  35. data/spec/dummy/app/controllers/api/internal/base_controller.rb +5 -0
  36. data/spec/dummy/app/controllers/api/internal/blogs_controller.rb +36 -0
  37. data/spec/dummy/app/controllers/application_controller.rb +0 -1
  38. data/spec/dummy/app/{assets/javascripts → javascript/packs}/application.js +2 -0
  39. data/spec/dummy/app/jobs/application_job.rb +5 -0
  40. data/spec/dummy/app/serializers/api/internal/blog_serializer.rb +12 -0
  41. data/spec/dummy/app/views/layouts/application.html.erb +3 -2
  42. data/spec/dummy/bin/rails +2 -2
  43. data/spec/dummy/bin/rake +2 -2
  44. data/spec/dummy/bin/setup +7 -12
  45. data/spec/dummy/config/application.rb +12 -16
  46. data/spec/dummy/config/boot.rb +1 -1
  47. data/spec/dummy/config/cable.yml +2 -2
  48. data/spec/dummy/config/database.yml +8 -16
  49. data/spec/dummy/config/environment.rb +1 -1
  50. data/spec/dummy/config/environments/development.rb +28 -6
  51. data/spec/dummy/config/environments/production.rb +45 -16
  52. data/spec/dummy/config/environments/test.rb +24 -7
  53. data/spec/dummy/config/initializers/active_model_serializers.rb +1 -0
  54. data/spec/dummy/config/initializers/api_pagination.rb +32 -0
  55. data/spec/dummy/config/initializers/assets.rb +0 -2
  56. data/spec/dummy/config/initializers/backtrace_silencers.rb +4 -3
  57. data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
  58. data/spec/dummy/config/initializers/filter_parameter_logging.rb +3 -1
  59. data/spec/dummy/config/initializers/permissions_policy.rb +11 -0
  60. data/spec/dummy/config/locales/en.yml +1 -1
  61. data/spec/dummy/config/puma.rb +14 -27
  62. data/spec/dummy/config/routes.rb +2 -7
  63. data/spec/dummy/config/storage.yml +34 -0
  64. data/spec/dummy/config.ru +2 -1
  65. data/spec/dummy/spec/helpers/power_api/application_helper_spec.rb +171 -0
  66. data/spec/dummy/spec/lib/power_api/generator_helper/ams_helper_spec.rb +50 -12
  67. data/spec/dummy/spec/lib/power_api/generator_helper/api_helper_spec.rb +115 -0
  68. data/spec/dummy/spec/lib/power_api/generator_helper/controller_helper_spec.rb +126 -34
  69. data/spec/dummy/spec/lib/power_api/generator_helper/routes_helper_spec.rb +29 -5
  70. data/spec/dummy/spec/lib/power_api/generator_helper/rspec_controller_helper_spec.rb +559 -0
  71. data/spec/dummy/spec/lib/power_api/generator_helper/swagger_helper_spec.rb +10 -20
  72. data/spec/dummy/spec/support/shared_examples/active_record_resource_atrributes.rb +22 -3
  73. metadata +114 -87
  74. data/.hound.yml +0 -4
  75. data/.travis.yml +0 -16
  76. data/app/controllers/concerns/api/versioned.rb +0 -36
  77. data/lib/power_api/generator_helper/version_helper.rb +0 -16
  78. data/spec/dummy/app/assets/javascripts/cable.js +0 -13
  79. data/spec/dummy/app/controllers/concerns/api/versioned_spec.rb +0 -64
  80. data/spec/dummy/bin/bundle +0 -3
  81. data/spec/dummy/bin/update +0 -29
  82. data/spec/dummy/bin/yarn +0 -11
  83. data/spec/dummy/config/secrets.yml +0 -32
  84. data/spec/dummy/config/spring.rb +0 -6
  85. data/spec/dummy/spec/lib/power_api/generator_helper/version_helper_spec.rb +0 -55
@@ -1,9 +1,9 @@
1
- # rubocop:disable Layout/AlignArguments
1
+ # rubocop:disable Layout/AlignParameters
2
2
  module PowerApi::GeneratorHelper::RoutesHelper
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- include PowerApi::GeneratorHelper::VersionHelper
6
+ include PowerApi::GeneratorHelper::ApiHelper
7
7
  include PowerApi::GeneratorHelper::ResourceHelper
8
8
  include PowerApi::GeneratorHelper::TemplateBuilderHelper
9
9
  end
@@ -13,13 +13,19 @@ module PowerApi::GeneratorHelper::RoutesHelper
13
13
  end
14
14
 
15
15
  def routes_line_to_inject_new_version
16
- return "routes.draw do\n" if first_version?
16
+ return routes_first_line if first_version?
17
17
 
18
18
  "'/api' do\n"
19
19
  end
20
20
 
21
- def api_version_routes_line_regex
22
- /Api::V#{version_number}[^\n]*/
21
+ def routes_first_line
22
+ "routes.draw do\n"
23
+ end
24
+
25
+ def api_current_route_namespace_line_regex
26
+ return /#{version_class}[^\n]*/ if versioned_api?
27
+
28
+ /namespace :internal[^\n]*/
23
29
  end
24
30
 
25
31
  def parent_resource_routes_line_regex
@@ -32,6 +38,15 @@ module PowerApi::GeneratorHelper::RoutesHelper
32
38
  new_version_route_tpl
33
39
  end
34
40
 
41
+ def internal_route_tpl
42
+ concat_tpl_statements(
43
+ "namespace :api, defaults: { format: :json } do",
44
+ "namespace :internal do",
45
+ "end",
46
+ "end\n"
47
+ )
48
+ end
49
+
35
50
  def resource_route_tpl(actions: [], is_parent: false)
36
51
  res = (is_parent ? parent_resource : resource).plural
37
52
  line = "resources :#{res}"
@@ -83,9 +98,9 @@ module PowerApi::GeneratorHelper::RoutesHelper
83
98
  end
84
99
 
85
100
  def api_version_params
86
- "module: 'Api::V#{version_number}', \
101
+ "module: '#{version_class}', \
87
102
  path: { value: 'v#{version_number}' }, \
88
103
  defaults: { format: 'json' }"
89
104
  end
90
105
  end
91
- # rubocop:enable Layout/AlignArguments
106
+ # rubocop:enable Layout/AlignParameters
@@ -0,0 +1,306 @@
1
+ # rubocop:disable Metrics/ModuleLength
2
+ # rubocop:disable Metrics/MethodLength
3
+ # rubocop:disable Layout/AlignParameters
4
+ module PowerApi::GeneratorHelper::RspecControllerHelper
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include PowerApi::GeneratorHelper::ApiHelper
9
+ include PowerApi::GeneratorHelper::ResourceHelper
10
+ include PowerApi::GeneratorHelper::TemplateBuilderHelper
11
+ end
12
+
13
+ def resource_spec_path
14
+ "spec/requests/#{api_file_path}/#{resource.plural}_spec.rb"
15
+ end
16
+
17
+ def resource_spec_tpl
18
+ concat_tpl_statements(
19
+ "require 'rails_helper'\n",
20
+ concat_tpl_statements(
21
+ spec_initial_describe_line,
22
+ spec_authenticated_resource_tpl,
23
+ spec_let_parent_resource_tpl,
24
+ spec_index_tpl,
25
+ spec_create_tpl,
26
+ spec_show_tpl,
27
+ spec_update_tpl,
28
+ spec_destroy_tpl,
29
+ "end\n"
30
+ )
31
+ )
32
+ end
33
+
34
+ private
35
+
36
+ def spec_initial_describe_line
37
+ "RSpec.describe '#{api_class}::#{resource.camel_plural}Controllers', type: :request do"
38
+ end
39
+
40
+ def spec_authenticated_resource_tpl
41
+ return unless authenticated_resource?
42
+
43
+ res_name = authenticated_resource.snake_case
44
+ "let(:#{res_name}) { create(:#{res_name}) }"
45
+ end
46
+
47
+ def spec_let_parent_resource_tpl
48
+ return unless parent_resource?
49
+
50
+ concat_tpl_statements(
51
+ "let(:#{parent_resource.snake_case}) { create(:#{parent_resource.snake_case}) }",
52
+ "let(:#{parent_resource.id}) { #{parent_resource.snake_case}.id }\n"
53
+ )
54
+ end
55
+
56
+ def spec_index_tpl
57
+ return unless index?
58
+
59
+ concat_tpl_statements(
60
+ "describe 'GET /index' do",
61
+ "let!(:#{resource.plural}) { #{spec_index_creation_list_tpl} }",
62
+ "let(:collection) { JSON.parse(response.body)['#{resource.plural}'] }",
63
+ "let(:params) { {} }\n",
64
+ spec_perform_tpl,
65
+ with_authorized_resource_context,
66
+ perform_block_tpl,
67
+ "it { expect(collection.count).to eq(5) }",
68
+ "it { expect(response.status).to eq(200) }",
69
+ if authenticated_resource?
70
+ "end\n"
71
+ end,
72
+ unauthorized_spec_tpl,
73
+ "end\n"
74
+ )
75
+ end
76
+
77
+ def spec_create_tpl
78
+ return unless create?
79
+
80
+ concat_tpl_statements(
81
+ "describe 'POST /create' do",
82
+ "let(:params) do",
83
+ "{",
84
+ "#{resource.snake_case}: {#{resource_parameters}",
85
+ "}",
86
+ "}",
87
+ "end\n",
88
+ let_resource_attrs,
89
+ spec_perform_tpl(http_verb: 'post'),
90
+ with_authorized_resource_context,
91
+ perform_block_tpl,
92
+ "it { expect(attributes).to include(params[:#{resource.snake_case}]) }",
93
+ "it { expect(response.status).to eq(201) }",
94
+ spec_invalid_attrs_test_tpl,
95
+ if authenticated_resource?
96
+ "end\n"
97
+ end,
98
+ unauthorized_spec_tpl,
99
+ "end\n"
100
+ )
101
+ end
102
+
103
+ def spec_show_tpl
104
+ return unless show?
105
+
106
+ concat_tpl_statements(
107
+ "describe 'GET /show' do",
108
+ spec_let_existent_resource_tpl,
109
+ "let(:#{resource.snake_case}_id) { #{resource.snake_case}.id.to_s }\n",
110
+ let_resource_attrs,
111
+ spec_perform_tpl(http_verb: 'get', params: false, single_resource: true),
112
+ with_authorized_resource_context,
113
+ perform_block_tpl,
114
+ "it { expect(response.status).to eq(200) }",
115
+ "context 'with resource not found' do",
116
+ "let(:#{resource.snake_case}_id) { '666' }",
117
+ "it { expect(response.status).to eq(404) }",
118
+ "end",
119
+ if authenticated_resource?
120
+ "end\n"
121
+ end,
122
+ unauthorized_spec_tpl,
123
+ "end\n"
124
+ )
125
+ end
126
+
127
+ def spec_update_tpl
128
+ return unless update?
129
+
130
+ concat_tpl_statements(
131
+ "describe 'PUT /update' do",
132
+ spec_let_existent_resource_tpl,
133
+ "let(:#{resource.snake_case}_id) { #{resource.snake_case}.id.to_s }\n",
134
+ "let(:params) do",
135
+ "{",
136
+ "#{resource.snake_case}: {#{resource_parameters}",
137
+ "}",
138
+ "}",
139
+ "end\n",
140
+ let_resource_attrs,
141
+ spec_perform_tpl(http_verb: 'put', params: true, single_resource: true),
142
+ with_authorized_resource_context,
143
+ perform_block_tpl,
144
+ "it { expect(attributes).to include(params[:#{resource.snake_case}]) }",
145
+ "it { expect(response.status).to eq(200) }",
146
+ spec_invalid_attrs_test_tpl,
147
+ "context 'with resource not found' do",
148
+ "let(:#{resource.snake_case}_id) { '666' }",
149
+ "it { expect(response.status).to eq(404) }",
150
+ "end",
151
+ if authenticated_resource?
152
+ "end\n"
153
+ end,
154
+ unauthorized_spec_tpl,
155
+ "end\n"
156
+ )
157
+ end
158
+
159
+ def spec_destroy_tpl
160
+ return unless destroy?
161
+
162
+ concat_tpl_statements(
163
+ "describe 'DELETE /destroy' do",
164
+ spec_let_existent_resource_tpl,
165
+ "let(:#{resource.snake_case}_id) { #{resource.snake_case}.id.to_s }\n",
166
+ spec_perform_tpl(http_verb: 'get', params: false, single_resource: true),
167
+ with_authorized_resource_context,
168
+ perform_block_tpl,
169
+ "it { expect(response.status).to eq(200) }",
170
+ "context 'with resource not found' do",
171
+ "let(:#{resource.snake_case}_id) { '666' }",
172
+ "it { expect(response.status).to eq(404) }",
173
+ "end",
174
+ if authenticated_resource?
175
+ "end\n"
176
+ end,
177
+ unauthorized_spec_tpl,
178
+ "end\n"
179
+ )
180
+ end
181
+
182
+ def spec_let_existent_resource_tpl
183
+ statement = ["let(:#{resource.snake_case}) { create(:#{resource.snake_case}"]
184
+ load_owner_resource_factory_option(statement)
185
+ statement.join(', ') + ') }'
186
+ end
187
+
188
+ def spec_invalid_attrs_test_tpl
189
+ return if resource.required_resource_attributes.blank?
190
+
191
+ concat_tpl_statements(
192
+ "context 'with invalid attributes' do",
193
+ "let(:params) do",
194
+ "{",
195
+ "#{resource.snake_case}: {#{invalid_resource_params}}",
196
+ "}",
197
+ "end\n",
198
+ "it { expect(response.status).to eq(400) }",
199
+ "end\n"
200
+ )
201
+ end
202
+
203
+ def with_authorized_resource_context
204
+ if authenticated_resource?
205
+ "context 'with authorized #{authenticated_resource.snake_case}' do"
206
+ end
207
+ end
208
+
209
+ def let_resource_attrs
210
+ concat_tpl_statements(
211
+ "let(:attributes) do",
212
+ "JSON.parse(response.body)['#{resource.snake_case}'].symbolize_keys",
213
+ "end"
214
+ )
215
+ end
216
+
217
+ def perform_block_tpl(auth: true)
218
+ concat_tpl_statements(
219
+ "before do",
220
+ if auth && authenticated_resource?
221
+ "sign_in(#{authenticated_resource.snake_case})"
222
+ end,
223
+ "perform",
224
+ "end\n"
225
+ )
226
+ end
227
+
228
+ def spec_perform_tpl(http_verb: 'get', params: true, single_resource: false)
229
+ body = "#{http_verb} '/#{spec_collection_path(single_resource)}"
230
+ body += "/' + #{resource.snake_case}_id" if single_resource
231
+ body += "'" unless single_resource
232
+ body += ", params: params" if params
233
+
234
+ concat_tpl_statements(
235
+ "def perform",
236
+ body,
237
+ "end\n"
238
+ )
239
+ end
240
+
241
+ def spec_collection_path(single_resource)
242
+ path = ["api"]
243
+ path << (versioned_api? ? "v#{version_number}" : "internal")
244
+
245
+ if parent_resource? && !single_resource
246
+ path << parent_resource.plural
247
+ path << "' + #{parent_resource.snake_case}.id.to_s + '"
248
+ end
249
+
250
+ path << resource.plural
251
+ path.join("/")
252
+ end
253
+
254
+ def spec_index_creation_list_tpl
255
+ statement = ["create_list(:#{resource.snake_case}, 5"]
256
+ load_owner_resource_factory_option(statement)
257
+ statement.join(', ') + ')'
258
+ end
259
+
260
+ def load_owner_resource_factory_option(statement)
261
+ if parent_resource?
262
+ statement << "#{parent_resource.snake_case}: #{parent_resource.snake_case}"
263
+ end
264
+
265
+ if owned_by_authenticated_resource?
266
+ statement << "#{authenticated_resource.snake_case}: #{authenticated_resource.snake_case}"
267
+ end
268
+ end
269
+
270
+ def unauthorized_spec_tpl
271
+ return unless authenticated_resource?
272
+
273
+ authenticated_resource_name = authenticated_resource.snake_case
274
+ concat_tpl_statements(
275
+ "context 'with unauthenticated #{authenticated_resource_name}' do",
276
+ "before { perform }\n",
277
+ "it { expect(response.status).to eq(401) }",
278
+ "end\n"
279
+ )
280
+ end
281
+
282
+ def resource_parameters
283
+ attrs = if resource.required_resource_attributes.any?
284
+ resource.required_resource_attributes
285
+ else
286
+ resource.optional_resource_attributes
287
+ end
288
+
289
+ for_each_attribute(attrs) do |attr|
290
+ "#{attr[:name]}: #{attr[:example]},"
291
+ end
292
+ end
293
+
294
+ def for_each_attribute(attributes)
295
+ attributes.inject("") do |memo, attr|
296
+ next memo if parent_resource && attr[:name] == parent_resource.id.to_sym
297
+
298
+ memo += "\n"
299
+ memo += yield(attr)
300
+ memo
301
+ end.delete_suffix(",")
302
+ end
303
+ end
304
+ # rubocop:enable Metrics/ModuleLength
305
+ # rubocop:enable Metrics/MethodLength
306
+ # rubocop:enable Layout/AlignParameters
@@ -1,11 +1,11 @@
1
1
  # rubocop:disable Metrics/ModuleLength
2
2
  # rubocop:disable Metrics/MethodLength
3
- # rubocop:disable Layout/AlignArguments
3
+ # rubocop:disable Layout/AlignParameters
4
4
  module PowerApi::GeneratorHelper::SwaggerHelper
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- include PowerApi::GeneratorHelper::VersionHelper
8
+ include PowerApi::GeneratorHelper::ApiHelper
9
9
  include PowerApi::GeneratorHelper::ResourceHelper
10
10
  include PowerApi::GeneratorHelper::SimpleTokenAuthHelper
11
11
  include PowerApi::GeneratorHelper::TemplateBuilderHelper
@@ -118,44 +118,32 @@ module PowerApi::GeneratorHelper::SwaggerHelper
118
118
  <<~SCHEMA
119
119
  #{swagger_model_definition_const} = {
120
120
  type: :object,
121
- properties: {
122
- id: { type: :string, example: '1' },
123
- type: { type: :string, example: '#{resource.snake_case}' },
124
- attributes: {
125
- type: :object,
126
- properties: {#{get_swagger_schema_attributes_definitions}
127
- },
128
- required: [#{get_swagger_schema_attributes_names}
129
- ]
130
- }
121
+ properties: {#{get_swagger_schema_attributes_definitions}
131
122
  },
132
- required: [
133
- :id,
134
- :type,
135
- :attributes
123
+ required: [#{get_swagger_schema_attributes_names}
136
124
  ]
137
125
  }
138
126
 
139
127
  #{swagger_collection_definition_const} = {
140
128
  type: "object",
141
129
  properties: {
142
- data: {
130
+ #{resource.plural}: {
143
131
  type: "array",
144
132
  items: { "$ref" => "#/definitions/#{resource.snake_case}" }
145
133
  }
146
134
  },
147
135
  required: [
148
- :data
136
+ :#{resource.plural}
149
137
  ]
150
138
  }
151
139
 
152
140
  #{swagger_resource_definition_const} = {
153
141
  type: "object",
154
142
  properties: {
155
- data: { "$ref" => "#/definitions/#{resource.snake_case}" }
143
+ #{resource.snake_case}: { "$ref" => "#/definitions/#{resource.snake_case}" }
156
144
  },
157
145
  required: [
158
- :data
146
+ :#{resource.snake_case}
159
147
  ]
160
148
  }
161
149
  SCHEMA
@@ -268,7 +256,7 @@ swagger_doc: 'v#{version_number}/swagger.json' do"
268
256
  "response '200', '#{resource.plural_titleized} retrieved' do",
269
257
  "schema('$ref' => '#/definitions/#{resource.plural}_collection')\n",
270
258
  "run_test! do |response|",
271
- "expect(JSON.parse(response.body)['data'].count).to eq(expected_collection_count)",
259
+ "expect(JSON.parse(response.body)['#{resource.plural}'].count).to eq(expected_collection_count)",
272
260
  "end",
273
261
  "end\n",
274
262
  spec_tpl_invalid_credentials,
@@ -452,7 +440,7 @@ swagger_doc: 'v#{version_number}/swagger.json' do"
452
440
  def get_swagger_schema_attributes_definitions
453
441
  for_each_schema_attribute(resource.resource_attributes) do |attr|
454
442
  opts = ["example: #{attr[:example]}"]
455
- opts << "'x-nullable': true" unless attr[:required]
443
+ opts << "'x-nullable': true" unless attr[:required] || attr[:name] == :id
456
444
  opts
457
445
 
458
446
  "#{attr[:name]}: { type: :#{attr[:swagger_type]}, #{opts.join(', ')} },"
@@ -460,7 +448,9 @@ swagger_doc: 'v#{version_number}/swagger.json' do"
460
448
  end
461
449
 
462
450
  def get_swagger_schema_attributes_names
463
- for_each_schema_attribute(resource.required_resource_attributes) do |attr|
451
+ for_each_schema_attribute(
452
+ resource.required_resource_attributes(include_id: true)
453
+ ) do |attr|
464
454
  ":#{attr[:name]},"
465
455
  end
466
456
  end
@@ -475,4 +465,4 @@ swagger_doc: 'v#{version_number}/swagger.json' do"
475
465
  end
476
466
  # rubocop:enable Metrics/ModuleLength
477
467
  # rubocop:enable Metrics/MethodLength
478
- # rubocop:enable Layout/AlignArguments
468
+ # rubocop:enable Layout/AlignParameters
@@ -2,8 +2,9 @@ module PowerApi
2
2
  class GeneratorHelpers
3
3
  include GeneratorHelper::ControllerActionsHelper
4
4
  include GeneratorHelper::ResourceHelper
5
- include GeneratorHelper::VersionHelper
5
+ include GeneratorHelper::ApiHelper
6
6
  include GeneratorHelper::SwaggerHelper
7
+ include GeneratorHelper::RspecControllerHelper
7
8
  include GeneratorHelper::AmsHelper
8
9
  include GeneratorHelper::ControllerHelper
9
10
  include GeneratorHelper::RoutesHelper
@@ -1,3 +1,3 @@
1
1
  module PowerApi
2
- VERSION = '0.2.0'
2
+ VERSION = '2.0.2'
3
3
  end
data/power_api.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  s.test_files = Dir["spec/**/*"]
21
21
 
22
- s.add_dependency "rails", ">= 4.2.0"
22
+ s.add_dependency "rails", ">= 6.0"
23
23
 
24
24
  s.add_dependency "active_model_serializers", "~> 0.10.0"
25
25
  s.add_dependency "api-pagination"
@@ -37,8 +37,9 @@ Gem::Specification.new do |s|
37
37
  s.add_development_dependency "pry"
38
38
  s.add_development_dependency "pry-rails"
39
39
  s.add_development_dependency "rspec-rails"
40
+ s.add_development_dependency "rspec_junit_formatter"
40
41
  s.add_development_dependency "rswag-specs"
41
42
  s.add_development_dependency "rubocop", "0.65.0"
42
43
  s.add_development_dependency "rubocop-rspec"
43
- s.add_development_dependency "sqlite3", "~> 1.3.0"
44
+ s.add_development_dependency "sqlite3", "~> 1.4.2"
44
45
  end
data/spec/dummy/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  # Add your own tasks in files placed in lib/tasks ending in .rake,
2
2
  # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
3
 
4
- require_relative 'config/application'
4
+ require_relative "config/application"
5
5
 
6
6
  Rails.application.load_tasks
@@ -1,5 +1,3 @@
1
-
2
1
  //= link_tree ../images
3
- //= link_directory ../javascripts .js
4
2
  //= link_directory ../stylesheets .css
5
3
  //= link power_api_manifest.js
@@ -0,0 +1,2 @@
1
+ class Api::BaseController < PowerApi::BaseController
2
+ end
@@ -0,0 +1,5 @@
1
+ class Api::Internal::BaseController < Api::BaseController
2
+ before_action do
3
+ self.namespace_for_serializer = ::Api::Internal
4
+ end
5
+ end
@@ -0,0 +1,36 @@
1
+ class Api::Internal::BlogsController < Api::Internal::BaseController
2
+ def index
3
+ respond_with Blog.all
4
+ end
5
+
6
+ def show
7
+ respond_with blog
8
+ end
9
+
10
+ def create
11
+ respond_with Blog.create!(blog_params)
12
+ end
13
+
14
+ def update
15
+ blog.update!(blog_params)
16
+ respond_with blog
17
+ end
18
+
19
+ def destroy
20
+ respond_with blog.destroy!
21
+ end
22
+
23
+ private
24
+
25
+ def blog
26
+ @blog ||= Blog.find_by!(id: params[:id])
27
+ end
28
+
29
+ def blog_params
30
+ params.require(:blog).permit(
31
+ :title,
32
+ :body,
33
+ :portfolio_id
34
+ )
35
+ end
36
+ end
@@ -1,3 +1,2 @@
1
1
  class ApplicationController < ActionController::Base
2
- protect_from_forgery with: :exception
3
2
  end
@@ -10,4 +10,6 @@
10
10
  // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
11
  // about supported directives.
12
12
  //
13
+ //= require rails-ujs
14
+ //= require activestorage
13
15
  //= require_tree .
@@ -1,2 +1,7 @@
1
1
  class ApplicationJob < ActiveJob::Base
2
+ # Automatically retry jobs that encountered a deadlock
3
+ # retry_on ActiveRecord::Deadlocked
4
+
5
+ # Most jobs are safe to ignore if the underlying records are no longer available
6
+ # discard_on ActiveJob::DeserializationError
2
7
  end
@@ -0,0 +1,12 @@
1
+ class Api::Internal::BlogSerializer < ActiveModel::Serializer
2
+ type :blog
3
+
4
+ attributes(
5
+ :id,
6
+ :title,
7
+ :body,
8
+ :created_at,
9
+ :updated_at,
10
+ :portfolio_id
11
+ )
12
+ end
@@ -2,10 +2,11 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Dummy</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
5
6
  <%= csrf_meta_tags %>
7
+ <%= csp_meta_tag %>
6
8
 
7
- <%= stylesheet_link_tag 'application', media: 'all' %>
8
- <%= javascript_include_tag 'application' %>
9
+ <%= stylesheet_link_tag 'application', media: 'all' %>
9
10
  </head>
10
11
 
11
12
  <body>
data/spec/dummy/bin/rails CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  APP_PATH = File.expand_path('../config/application', __dir__)
3
- require_relative '../config/boot'
4
- require 'rails/commands'
3
+ require_relative "../config/boot"
4
+ require "rails/commands"
data/spec/dummy/bin/rake CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- require_relative '../config/boot'
3
- require 'rake'
2
+ require_relative "../config/boot"
3
+ require "rake"
4
4
  Rake.application.run
data/spec/dummy/bin/setup CHANGED
@@ -1,34 +1,29 @@
1
1
  #!/usr/bin/env ruby
2
- require 'pathname'
3
- require 'fileutils'
4
- include FileUtils
2
+ require "fileutils"
5
3
 
6
4
  # path to your application root.
7
- APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
5
+ APP_ROOT = File.expand_path('..', __dir__)
8
6
 
9
7
  def system!(*args)
10
8
  system(*args) || abort("\n== Command #{args} failed ==")
11
9
  end
12
10
 
13
- chdir APP_ROOT do
14
- # This script is a starting point to setup your application.
11
+ FileUtils.chdir APP_ROOT do
12
+ # This script is a way to set up or update your development environment automatically.
13
+ # This script is idempotent, so that you can run it at any time and get an expectable outcome.
15
14
  # Add necessary setup steps to this file.
16
15
 
17
16
  puts '== Installing dependencies =='
18
17
  system! 'gem install bundler --conservative'
19
18
  system('bundle check') || system!('bundle install')
20
19
 
21
- # Install JavaScript dependencies if using Yarn
22
- # system('bin/yarn')
23
-
24
-
25
20
  # puts "\n== Copying sample files =="
26
21
  # unless File.exist?('config/database.yml')
27
- # cp 'config/database.yml.sample', 'config/database.yml'
22
+ # FileUtils.cp 'config/database.yml.sample', 'config/database.yml'
28
23
  # end
29
24
 
30
25
  puts "\n== Preparing database =="
31
- system! 'bin/rails db:setup'
26
+ system! 'bin/rails db:prepare'
32
27
 
33
28
  puts "\n== Removing old logs and tempfiles =="
34
29
  system! 'bin/rails log:clear tmp:clear'