potassium 6.0.0 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/README.md +41 -45
  4. data/lib/potassium/assets/.eslintrc.json +13 -4
  5. data/lib/potassium/assets/.github/pull_request_template.md +9 -0
  6. data/lib/potassium/assets/README.yml +6 -0
  7. data/lib/potassium/assets/app/graphql/graphql_controller.rb +55 -0
  8. data/lib/potassium/assets/app/graphql/mutations/login_mutation.rb +23 -0
  9. data/lib/potassium/assets/app/graphql/queries/base_query.rb +4 -0
  10. data/lib/potassium/assets/app/graphql/types/base/base_argument.rb +4 -0
  11. data/lib/potassium/assets/app/graphql/types/base/base_enum.rb +4 -0
  12. data/lib/potassium/assets/app/graphql/types/base/base_field.rb +5 -0
  13. data/lib/potassium/assets/app/graphql/types/base/base_input_object.rb +5 -0
  14. data/lib/potassium/assets/app/graphql/types/base/base_interface.rb +7 -0
  15. data/lib/potassium/assets/app/graphql/types/base/base_object.rb +5 -0
  16. data/lib/potassium/assets/app/graphql/types/base/base_scalar.rb +4 -0
  17. data/lib/potassium/assets/app/graphql/types/base/base_union.rb +4 -0
  18. data/lib/potassium/assets/app/graphql/types/mutation_type.rb +10 -0
  19. data/lib/potassium/assets/app/graphql/types/query_type.rb +13 -0
  20. data/lib/potassium/assets/app/uploaders/base_uploader.rb +1 -3
  21. data/lib/potassium/assets/config/graphql_playground.rb +20 -0
  22. data/lib/potassium/assets/config/puma.rb +1 -1
  23. data/lib/potassium/assets/config/shrine.rb +4 -1
  24. data/lib/potassium/assets/redis.yml +1 -2
  25. data/lib/potassium/assets/testing/rails_helper.rb +2 -0
  26. data/lib/potassium/cli/commands/create.rb +11 -19
  27. data/lib/potassium/cli_options.rb +59 -7
  28. data/lib/potassium/newest_version_ensurer.rb +19 -36
  29. data/lib/potassium/node_version_ensurer.rb +30 -0
  30. data/lib/potassium/recipes/api.rb +91 -27
  31. data/lib/potassium/recipes/background_processor.rb +34 -1
  32. data/lib/potassium/recipes/database.rb +4 -0
  33. data/lib/potassium/recipes/draper.rb +0 -9
  34. data/lib/potassium/recipes/file_storage.rb +1 -0
  35. data/lib/potassium/recipes/front_end.rb +62 -0
  36. data/lib/potassium/recipes/github.rb +93 -15
  37. data/lib/potassium/version.rb +1 -1
  38. data/potassium.gemspec +2 -1
  39. data/spec/features/api_spec.rb +25 -0
  40. data/spec/features/background_processor_spec.rb +12 -1
  41. data/spec/features/draper_spec.rb +1 -6
  42. data/spec/features/file_storage_spec.rb +5 -0
  43. data/spec/features/front_end_spec.rb +14 -0
  44. data/spec/features/github_spec.rb +53 -8
  45. data/spec/features/graphql_spec.rb +71 -0
  46. data/spec/spec_helper.rb +1 -0
  47. data/spec/support/fake_octokit.rb +31 -0
  48. metadata +40 -8
  49. data/lib/potassium/assets/api/api_error_concern.rb +0 -32
  50. data/lib/potassium/assets/api/base_controller.rb +0 -7
  51. data/lib/potassium/assets/api/draper_responder.rb +0 -62
  52. data/lib/potassium/assets/api/responder.rb +0 -41
@@ -0,0 +1,71 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "GraphQL" do
4
+ context 'when using only graphql' do
5
+ before :all do
6
+ drop_dummy_database
7
+ remove_project_directory
8
+ create_dummy_project("api" => :graphql)
9
+ end
10
+
11
+ it "adds graphql related gems to Gemfile" do
12
+ gemfile_content = IO.read("#{project_path}/Gemfile")
13
+ expect(gemfile_content).to include("gem 'graphql'")
14
+ expect(gemfile_content).to include("gem 'graphql_playground-rails'")
15
+ expect(gemfile_content).not_to include("gem 'graphiql'")
16
+ end
17
+
18
+ it 'installs and sets up graphql' do
19
+ schema = IO.read(
20
+ "#{project_path}/app/graphql/#{PotassiumTestHelpers::APP_NAME.dasherize.tr('-', '_')}_schema.rb"
21
+ )
22
+ expect(schema).to include(
23
+ "class #{PotassiumTestHelpers::APP_NAME.titleize.delete(' ')}Schema < GraphQL::Schema"
24
+ )
25
+
26
+ base_mutation = IO.read("#{project_path}/app/graphql/mutations/base_mutation.rb")
27
+ expect(base_mutation).to include('Types::Base::Base')
28
+ expect(base_mutation).not_to include('input_object_class')
29
+ expect(base_mutation).not_to include('RelayClassic')
30
+
31
+ controller = IO.read("#{project_path}/app/controllers/graphql_controller.rb")
32
+ expect(controller).to include('skip_before_action :verify_authenticity_token')
33
+ end
34
+
35
+ it 'sets up graphql playground' do
36
+ routes = IO.read("#{project_path}/config/routes.rb")
37
+ expect(routes).to include(
38
+ 'mount GraphqlPlayground::Rails::Engine, at: "/graphiql", graphql_path: "/graphql"'
39
+ )
40
+ config = IO.read("#{project_path}/config/initializers/graphql_playground.rb")
41
+ expect(config).to include('GraphqlPlayground::Rails.configure do |config|')
42
+ end
43
+ end
44
+
45
+ context 'when using authentication' do
46
+ before :all do
47
+ drop_dummy_database
48
+ remove_project_directory
49
+ create_dummy_project("api" => :graphql, "devise": true)
50
+ end
51
+
52
+ it 'gathers jwt gem' do
53
+ gemfile_content = IO.read("#{project_path}/Gemfile")
54
+ expect(gemfile_content).to include("gem 'jwt'")
55
+ end
56
+
57
+ it 'Adds auth related mutation and controller' do
58
+ controller = IO.read("#{project_path}/app/controllers/graphql_controller.rb")
59
+ expect(controller).to include('get_current_user')
60
+ expect(controller).to include(
61
+ "#{PotassiumTestHelpers::APP_NAME.titleize.delete(' ')}Schema.execute"
62
+ )
63
+
64
+ mutation_type = IO.read("#{project_path}/app/graphql/types/mutation_type.rb")
65
+ expect(mutation_type).to include('field :login, mutation: Mutations::LoginMutation')
66
+
67
+ login_mutation = IO.read("#{project_path}/app/graphql/mutations/login_mutation.rb")
68
+ expect(login_mutation).to include('class Mutations::LoginMutation < Mutations::BaseMutation')
69
+ end
70
+ end
71
+ end
@@ -33,5 +33,6 @@ RSpec.configure do |config|
33
33
  config.before(:each) do
34
34
  FakeGithub.clear!
35
35
  FakeHeroku.clear!
36
+ FakeOctokit.clear!
36
37
  end
37
38
  end
@@ -0,0 +1,31 @@
1
+ class FakeOctokit
2
+ RECORDER = File.expand_path(File.join('..', '..', 'tmp', 'octokit'), File.dirname(__FILE__))
3
+
4
+ def initialize(options); end
5
+
6
+ def create_repository(repo_name, options)
7
+ File.open(RECORDER, 'a') do |file|
8
+ file.write "#{repo_name}, #{options.map { |key, value| "#{key}: #{value}" }}"
9
+ end
10
+ end
11
+
12
+ def self.clear!
13
+ FileUtils.rm_rf RECORDER
14
+ end
15
+
16
+ def self.has_created_repo?(repo_name)
17
+ File.read(RECORDER).include? repo_name
18
+ end
19
+
20
+ def self.has_created_private_repo?(repo_name)
21
+ has_created_repo?(repo_name) && File.read(RECORDER).include?("private: true")
22
+ end
23
+
24
+ def self.has_created_repo_for_org?(repo_name, org_name)
25
+ has_created_repo?(repo_name) && File.read(RECORDER).include?("organization: #{org_name}")
26
+ end
27
+
28
+ def self.has_created_private_repo_for_org?(repo_name, org_name)
29
+ has_created_private_repo?(repo_name) && has_created_repo_for_org?(repo_name, org_name)
30
+ end
31
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: potassium
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0
4
+ version: 6.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - juliogarciag
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-25 00:00:00.000000000 Z
11
+ date: 2021-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: '13.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: '13.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0.2'
167
+ - !ruby/object:Gem::Dependency
168
+ name: octokit
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '4.18'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '4.18'
167
181
  - !ruby/object:Gem::Dependency
168
182
  name: rails
169
183
  requirement: !ruby/object:Gem::Requirement
@@ -223,6 +237,7 @@ files:
223
237
  - lib/potassium/assets/.editorconfig
224
238
  - lib/potassium/assets/.env.development.erb
225
239
  - lib/potassium/assets/.eslintrc.json
240
+ - lib/potassium/assets/.github/pull_request_template.md
226
241
  - lib/potassium/assets/.pryrc
227
242
  - lib/potassium/assets/.rubocop.yml
228
243
  - lib/potassium/assets/.stylelintrc.json
@@ -237,10 +252,19 @@ files:
237
252
  - lib/potassium/assets/active_admin/comment_policy.rb
238
253
  - lib/potassium/assets/active_admin/init_activeadmin_vue.rb
239
254
  - lib/potassium/assets/active_admin/pundit_page_policy.rb
240
- - lib/potassium/assets/api/api_error_concern.rb
241
- - lib/potassium/assets/api/base_controller.rb
242
- - lib/potassium/assets/api/draper_responder.rb
243
- - lib/potassium/assets/api/responder.rb
255
+ - lib/potassium/assets/app/graphql/graphql_controller.rb
256
+ - lib/potassium/assets/app/graphql/mutations/login_mutation.rb
257
+ - lib/potassium/assets/app/graphql/queries/base_query.rb
258
+ - lib/potassium/assets/app/graphql/types/base/base_argument.rb
259
+ - lib/potassium/assets/app/graphql/types/base/base_enum.rb
260
+ - lib/potassium/assets/app/graphql/types/base/base_field.rb
261
+ - lib/potassium/assets/app/graphql/types/base/base_input_object.rb
262
+ - lib/potassium/assets/app/graphql/types/base/base_interface.rb
263
+ - lib/potassium/assets/app/graphql/types/base/base_object.rb
264
+ - lib/potassium/assets/app/graphql/types/base/base_scalar.rb
265
+ - lib/potassium/assets/app/graphql/types/base/base_union.rb
266
+ - lib/potassium/assets/app/graphql/types/mutation_type.rb
267
+ - lib/potassium/assets/app/graphql/types/query_type.rb
244
268
  - lib/potassium/assets/app/javascript/app.spec.js
245
269
  - lib/potassium/assets/app/mailers/application_mailer.rb
246
270
  - lib/potassium/assets/app/uploaders/base_uploader.rb
@@ -252,6 +276,7 @@ files:
252
276
  - lib/potassium/assets/bin/update.erb
253
277
  - lib/potassium/assets/config/database_mysql.yml.erb
254
278
  - lib/potassium/assets/config/database_postgresql.yml.erb
279
+ - lib/potassium/assets/config/graphql_playground.rb
255
280
  - lib/potassium/assets/config/mailer.rb.erb
256
281
  - lib/potassium/assets/config/puma.rb
257
282
  - lib/potassium/assets/config/secrets.yml.erb
@@ -292,6 +317,7 @@ files:
292
317
  - lib/potassium/helpers/template-helpers.rb
293
318
  - lib/potassium/helpers/variable-helpers.rb
294
319
  - lib/potassium/newest_version_ensurer.rb
320
+ - lib/potassium/node_version_ensurer.rb
295
321
  - lib/potassium/recipe.rb
296
322
  - lib/potassium/recipes/admin.rb
297
323
  - lib/potassium/recipes/annotate.rb
@@ -342,6 +368,7 @@ files:
342
368
  - potassium.gemspec
343
369
  - spec/fakes/bin/heroku
344
370
  - spec/fakes/bin/hub
371
+ - spec/features/api_spec.rb
345
372
  - spec/features/background_processor_spec.rb
346
373
  - spec/features/ci_spec.rb
347
374
  - spec/features/data_migrate_spec.rb
@@ -352,6 +379,7 @@ files:
352
379
  - spec/features/file_storage_spec.rb
353
380
  - spec/features/front_end_spec.rb
354
381
  - spec/features/github_spec.rb
382
+ - spec/features/graphql_spec.rb
355
383
  - spec/features/heroku_spec.rb
356
384
  - spec/features/i18n_spec.rb
357
385
  - spec/features/mailer_spec.rb
@@ -363,6 +391,7 @@ files:
363
391
  - spec/spec_helper.rb
364
392
  - spec/support/fake_github.rb
365
393
  - spec/support/fake_heroku.rb
394
+ - spec/support/fake_octokit.rb
366
395
  - spec/support/potassium_test_helpers.rb
367
396
  homepage: https://github.com/platanus/potassium
368
397
  licenses:
@@ -390,6 +419,7 @@ summary: An application generator from Platanus
390
419
  test_files:
391
420
  - spec/fakes/bin/heroku
392
421
  - spec/fakes/bin/hub
422
+ - spec/features/api_spec.rb
393
423
  - spec/features/background_processor_spec.rb
394
424
  - spec/features/ci_spec.rb
395
425
  - spec/features/data_migrate_spec.rb
@@ -400,6 +430,7 @@ test_files:
400
430
  - spec/features/file_storage_spec.rb
401
431
  - spec/features/front_end_spec.rb
402
432
  - spec/features/github_spec.rb
433
+ - spec/features/graphql_spec.rb
403
434
  - spec/features/heroku_spec.rb
404
435
  - spec/features/i18n_spec.rb
405
436
  - spec/features/mailer_spec.rb
@@ -411,4 +442,5 @@ test_files:
411
442
  - spec/spec_helper.rb
412
443
  - spec/support/fake_github.rb
413
444
  - spec/support/fake_heroku.rb
445
+ - spec/support/fake_octokit.rb
414
446
  - spec/support/potassium_test_helpers.rb
@@ -1,32 +0,0 @@
1
- module ApiErrorConcern
2
- extend ActiveSupport::Concern
3
-
4
- included do
5
- rescue_from "Exception" do |exception|
6
- logger.error exception.message
7
- logger.error exception.backtrace.join("\n")
8
- respond_api_error(:internal_server_error, message: "server_error",
9
- type: exception.class.to_s,
10
- detail: exception.message)
11
- end
12
-
13
- rescue_from "ActiveRecord::RecordNotFound" do |exception|
14
- respond_api_error(:not_found, message: "record_not_found",
15
- detail: exception.message)
16
- end
17
-
18
- rescue_from "ActiveModel::ForbiddenAttributesError" do |exception|
19
- respond_api_error(:bad_request, message: "protected_attributes",
20
- detail: exception.message)
21
- end
22
-
23
- rescue_from "ActiveRecord::RecordInvalid" do |exception|
24
- respond_api_error(:bad_request, message: "invalid_attributes",
25
- errors: exception.record.errors)
26
- end
27
- end
28
-
29
- def respond_api_error(status, error = {})
30
- render json: error, status: status
31
- end
32
- end
@@ -1,7 +0,0 @@
1
- class Api::V1::BaseController < ApplicationController
2
- include ApiErrorConcern
3
-
4
- self.responder = ApiResponder
5
-
6
- respond_to :json
7
- end
@@ -1,62 +0,0 @@
1
- class ApiResponder < ActionController::Responder
2
- def respond
3
- return display_errors if has_errors?
4
- return head :no_content if delete?
5
-
6
- display resource, status_code: status_code
7
- end
8
-
9
- private
10
-
11
- def display(_resource, given_options = {})
12
- controller.render options.merge(given_options).merge(
13
- json: serializer.as_json
14
- )
15
- end
16
-
17
- def serializer
18
- serializer_class = ActiveModel::Serializer.serializer_for(resource)
19
- if serializer_class.present?
20
- serializer_options = infer_serializer(serializer_class).merge(options)
21
- serializer_class.new(decorated_resource, serializer_options)
22
- else
23
- decorated_resource
24
- end
25
- end
26
-
27
- def status_code
28
- return :created if post?
29
- :ok
30
- end
31
-
32
- def display_errors
33
- controller.render(
34
- status: :unprocessable_entity,
35
- json: { msg: "invalid_attributes", errors: format_errors }
36
- )
37
- end
38
-
39
- def format_errors
40
- resource.errors.as_json
41
- end
42
-
43
- def infer_serializer(serializer_class)
44
- if serializer_class == ActiveModel::ArraySerializer
45
- s = options.delete(:each_serializer) || "#{resource.klass}Serializer".constantize
46
- { each_serializer: s }
47
- else
48
- s = options.delete(:serializer) || "#{resource.class}Serializer".constantize
49
- { serializer: s }
50
- end
51
- end
52
-
53
- def decorated_resource
54
- if resource.respond_to?(:decorate)
55
- resource.decorate
56
- else
57
- resource
58
- end
59
- rescue Draper::UninferrableDecoratorError
60
- resource
61
- end
62
- end
@@ -1,41 +0,0 @@
1
- class ApiResponder < ActionController::Responder
2
- def respond
3
- return display_errors if has_errors?
4
- return head :no_content if delete?
5
-
6
- display resource, status_code: status_code
7
- end
8
-
9
- private
10
-
11
- def display(_resource, given_options = {})
12
- controller.render options.merge(given_options).merge(
13
- json: serializer.as_json
14
- )
15
- end
16
-
17
- def serializer
18
- serializer_class = ActiveModel::Serializer.serializer_for(resource)
19
- if serializer_class.present?
20
- serializer_class.new(resource, options)
21
- else
22
- resource
23
- end
24
- end
25
-
26
- def status_code
27
- return :created if post?
28
- :ok
29
- end
30
-
31
- def display_errors
32
- controller.render(
33
- status: :unprocessable_entity,
34
- json: { msg: "invalid_attributes", errors: format_errors }
35
- )
36
- end
37
-
38
- def format_errors
39
- resource.errors.as_json
40
- end
41
- end