graphql_devise 0.14.1 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +118 -0
  3. data/Appraisals +26 -6
  4. data/CHANGELOG.md +72 -6
  5. data/README.md +184 -69
  6. data/Rakefile +2 -1
  7. data/app/controllers/graphql_devise/concerns/additional_controller_methods.rb +72 -0
  8. data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +5 -27
  9. data/app/controllers/graphql_devise/graphql_controller.rb +1 -1
  10. data/app/helpers/graphql_devise/mailer_helper.rb +2 -2
  11. data/app/models/graphql_devise/concerns/additional_model_methods.rb +21 -0
  12. data/app/models/graphql_devise/concerns/model.rb +6 -9
  13. data/app/views/graphql_devise/mailer/confirmation_instructions.html.erb +7 -1
  14. data/graphql_devise.gemspec +1 -1
  15. data/lib/generators/graphql_devise/install_generator.rb +1 -1
  16. data/lib/graphql_devise.rb +20 -6
  17. data/lib/graphql_devise/concerns/controller_methods.rb +3 -3
  18. data/lib/graphql_devise/default_operations/mutations.rb +14 -8
  19. data/lib/graphql_devise/default_operations/resolvers.rb +2 -2
  20. data/lib/graphql_devise/model/with_email_updater.rb +34 -8
  21. data/lib/graphql_devise/mount_method/operation_preparer.rb +6 -6
  22. data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +6 -4
  23. data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +7 -5
  24. data/lib/graphql_devise/mount_method/operation_preparers/{resource_name_setter.rb → resource_klass_setter.rb} +4 -4
  25. data/lib/graphql_devise/mount_method/operation_sanitizer.rb +13 -1
  26. data/lib/graphql_devise/mutations/confirm_registration_with_token.rb +30 -0
  27. data/lib/graphql_devise/mutations/register.rb +60 -0
  28. data/lib/graphql_devise/mutations/resend_confirmation_with_token.rb +44 -0
  29. data/lib/graphql_devise/mutations/sign_up.rb +1 -1
  30. data/lib/graphql_devise/resolvers/confirm_account.rb +1 -1
  31. data/lib/graphql_devise/resource_loader.rb +26 -11
  32. data/lib/graphql_devise/schema_plugin.rb +31 -10
  33. data/lib/graphql_devise/version.rb +1 -1
  34. data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +13 -2
  35. data/spec/dummy/app/graphql/dummy_schema.rb +8 -6
  36. data/spec/dummy/app/graphql/mutations/register.rb +14 -0
  37. data/spec/dummy/app/graphql/types/query_type.rb +5 -0
  38. data/spec/dummy/config/routes.rb +7 -5
  39. data/spec/dummy/db/migrate/20200623003142_create_schema_users.rb +0 -1
  40. data/spec/dummy/db/migrate/20210516211417_add_vip_to_users.rb +5 -0
  41. data/spec/dummy/db/schema.rb +4 -4
  42. data/spec/generators/graphql_devise/install_generator_spec.rb +1 -1
  43. data/spec/graphql/user_queries_spec.rb +3 -1
  44. data/spec/graphql_devise/model/with_email_updater_spec.rb +97 -68
  45. data/spec/requests/graphql_controller_spec.rb +12 -11
  46. data/spec/requests/mutations/confirm_registration_with_token_spec.rb +117 -0
  47. data/spec/requests/mutations/register_spec.rb +166 -0
  48. data/spec/requests/mutations/resend_confirmation_with_token_spec.rb +137 -0
  49. data/spec/requests/queries/introspection_query_spec.rb +149 -0
  50. data/spec/requests/user_controller_spec.rb +86 -25
  51. data/spec/services/mount_method/operation_preparer_spec.rb +5 -5
  52. data/spec/services/mount_method/operation_preparers/custom_operation_preparer_spec.rb +5 -5
  53. data/spec/services/mount_method/operation_preparers/default_operation_preparer_spec.rb +5 -5
  54. data/spec/services/mount_method/operation_preparers/{resource_name_setter_spec.rb → resource_klass_setter_spec.rb} +6 -6
  55. data/spec/services/mount_method/operation_sanitizer_spec.rb +3 -3
  56. data/spec/services/resource_loader_spec.rb +5 -5
  57. data/spec/support/contexts/graphql_request.rb +11 -3
  58. metadata +29 -12
  59. data/.travis.yml +0 -86
@@ -6,19 +6,30 @@ module Api
6
6
  include GraphqlDevise::Concerns::SetUserByToken
7
7
 
8
8
  def graphql
9
- result = DummySchema.execute(params[:query], execute_params(params))
9
+ result = DummySchema.execute(params[:query], **execute_params(params))
10
10
 
11
11
  render json: result unless performed?
12
12
  end
13
13
 
14
14
  def interpreter
15
- render json: InterpreterSchema.execute(params[:query], execute_params(params))
15
+ render json: InterpreterSchema.execute(params[:query], **execute_params(params))
16
16
  end
17
17
 
18
18
  def failing_resource_name
19
19
  render json: DummySchema.execute(params[:query], context: graphql_context([:user, :fail]))
20
20
  end
21
21
 
22
+ def controller_auth
23
+ result = DummySchema.execute(
24
+ params[:query],
25
+ operation_name: params[:operationName],
26
+ variables: ensure_hash(params[:variables]),
27
+ context: gql_devise_context(SchemaUser, User)
28
+ )
29
+
30
+ render json: result unless performed?
31
+ end
32
+
22
33
  private
23
34
 
24
35
  def execute_params(item)
@@ -2,21 +2,23 @@
2
2
 
3
3
  class DummySchema < GraphQL::Schema
4
4
  use GraphqlDevise::SchemaPlugin.new(
5
- query: Types::QueryType,
6
- mutation: Types::MutationType,
7
- resource_loaders: [
5
+ query: Types::QueryType,
6
+ mutation: Types::MutationType,
7
+ public_introspection: true,
8
+ resource_loaders: [
8
9
  GraphqlDevise::ResourceLoader.new(
9
- 'User',
10
+ User,
10
11
  only: [
11
12
  :login,
12
13
  :confirm_account,
13
14
  :send_password_reset,
14
15
  :resend_confirmation,
16
+ :resend_confirmation_with_token,
15
17
  :check_password_token
16
18
  ]
17
19
  ),
18
- GraphqlDevise::ResourceLoader.new('Guest', only: [:logout]),
19
- GraphqlDevise::ResourceLoader.new('SchemaUser')
20
+ GraphqlDevise::ResourceLoader.new(Guest, only: [:logout]),
21
+ GraphqlDevise::ResourceLoader.new(SchemaUser)
20
22
  ]
21
23
  )
22
24
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mutations
4
+ class Register < GraphqlDevise::Mutations::Register
5
+ argument :name, String, required: false
6
+
7
+ field :user, Types::UserType, null: true
8
+
9
+ def resolve(email:, **attrs)
10
+ original_payload = super
11
+ original_payload.merge(user: original_payload[:authenticatable])
12
+ end
13
+ end
14
+ end
@@ -5,6 +5,7 @@ module Types
5
5
  field :user, resolver: Resolvers::UserShow
6
6
  field :public_field, String, null: false, authenticate: false
7
7
  field :private_field, String, null: false, authenticate: true
8
+ field :vip_field, String, null: false, authenticate: ->(user) { user.is_a?(User) && user.vip? }
8
9
 
9
10
  def public_field
10
11
  'Field does not require authentication'
@@ -13,5 +14,9 @@ module Types
13
14
  def private_field
14
15
  'Field will always require authentication'
15
16
  end
17
+
18
+ def vip_field
19
+ 'Field available only for VIP Users'
20
+ end
16
21
  end
17
22
  end
@@ -2,8 +2,9 @@
2
2
 
3
3
  Rails.application.routes.draw do
4
4
  mount_graphql_devise_for 'User', at: '/api/v1/graphql_auth', operations: {
5
- login: Mutations::Login,
6
- sign_up: Mutations::SignUp
5
+ login: Mutations::Login,
6
+ sign_up: Mutations::SignUp,
7
+ register: Mutations::Register
7
8
  }, additional_mutations: {
8
9
  register_confirmed_user: Mutations::RegisterConfirmedUser
9
10
  }, additional_queries: {
@@ -11,9 +12,9 @@ Rails.application.routes.draw do
11
12
  }
12
13
 
13
14
  mount_graphql_devise_for(
14
- 'Admin',
15
+ Admin,
15
16
  authenticatable_type: Types::CustomAdminType,
16
- skip: [:sign_up, :check_password_token],
17
+ skip: [:sign_up, :register, :check_password_token],
17
18
  operations: {
18
19
  confirm_account: Resolvers::ConfirmAdminAccount,
19
20
  update_password_with_token: Mutations::ResetAdminPasswordWithToken
@@ -23,7 +24,7 @@ Rails.application.routes.draw do
23
24
 
24
25
  mount_graphql_devise_for(
25
26
  'Guest',
26
- only: [:login, :logout, :sign_up],
27
+ only: [:login, :logout, :sign_up, :register],
27
28
  at: '/api/v1/guest/graphql_auth'
28
29
  )
29
30
 
@@ -37,4 +38,5 @@ Rails.application.routes.draw do
37
38
  post '/api/v1/graphql', to: 'api/v1/graphql#graphql'
38
39
  post '/api/v1/interpreter', to: 'api/v1/graphql#interpreter'
39
40
  post '/api/v1/failing', to: 'api/v1/graphql#failing_resource_name'
41
+ post '/api/v1/controller_auth', to: 'api/v1/graphql#controller_auth'
40
42
  end
@@ -41,6 +41,5 @@ class CreateSchemaUsers < ActiveRecord::Migration[6.0]
41
41
  add_index :schema_users, [:uid, :provider], unique: true
42
42
  add_index :schema_users, :reset_password_token, unique: true
43
43
  add_index :schema_users, :confirmation_token, unique: true
44
- add_index :schema_users, :unlock_token, unique: true
45
44
  end
46
45
  end
@@ -0,0 +1,5 @@
1
+ class AddVipToUsers < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :users, :vip, :boolean, null: false, default: false
4
+ end
5
+ end
@@ -2,15 +2,15 @@
2
2
  # of editing this file, please use the migrations feature of Active Record to
3
3
  # incrementally modify your database, and then regenerate this schema definition.
4
4
  #
5
- # This file is the source Rails uses to define your schema when running `rails
6
- # db:schema:load`. When creating a new database, `rails db:schema:load` tends to
5
+ # This file is the source Rails uses to define your schema when running `bin/rails
6
+ # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7
7
  # be faster and is potentially less error prone than running all of your
8
8
  # migrations from scratch. Old migrations may fail to apply correctly if those
9
9
  # migrations use external dependencies or application code.
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 2020_06_23_003142) do
13
+ ActiveRecord::Schema.define(version: 2021_05_16_211417) do
14
14
 
15
15
  create_table "admins", force: :cascade do |t|
16
16
  t.string "provider", default: "email", null: false
@@ -73,7 +73,6 @@ ActiveRecord::Schema.define(version: 2020_06_23_003142) do
73
73
  t.text "tokens"
74
74
  t.datetime "created_at", precision: 6, null: false
75
75
  t.datetime "updated_at", precision: 6, null: false
76
- t.index "\"unlock_token\"", name: "index_schema_users_on_unlock_token", unique: true
77
76
  t.index ["confirmation_token"], name: "index_schema_users_on_confirmation_token", unique: true
78
77
  t.index ["email"], name: "index_schema_users_on_email", unique: true
79
78
  t.index ["reset_password_token"], name: "index_schema_users_on_reset_password_token", unique: true
@@ -106,6 +105,7 @@ ActiveRecord::Schema.define(version: 2020_06_23_003142) do
106
105
  t.datetime "created_at", null: false
107
106
  t.datetime "updated_at", null: false
108
107
  t.boolean "auth_available", default: true, null: false
108
+ t.boolean "vip", default: false, null: false
109
109
  t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
110
110
  t.index ["email"], name: "index_users_on_email", unique: true
111
111
  t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
@@ -33,7 +33,7 @@ RSpec.describe GraphqlDevise::InstallGenerator, type: :generator do
33
33
 
34
34
  assert_file 'app/controllers/application_controller.rb', /^\s{2}include GraphqlDevise::Concerns::SetUserByToken/
35
35
 
36
- assert_file 'app/graphql/gqld_dummy_schema.rb', /\s+#{Regexp.escape("GraphqlDevise::ResourceLoader.new('Admin')")}/
36
+ assert_file 'app/graphql/gqld_dummy_schema.rb', /\s+#{Regexp.escape("GraphqlDevise::ResourceLoader.new(Admin)")}/
37
37
  end
38
38
  end
39
39
 
@@ -78,7 +78,9 @@ RSpec.describe 'Users controller specs' do
78
78
  let(:query) do
79
79
  <<-GRAPHQL
80
80
  query {
81
- user(id: #{user.id}) {
81
+ user(
82
+ id: #{user.id}
83
+ ) {
82
84
  id
83
85
  email
84
86
  }
@@ -4,6 +4,57 @@ require 'rails_helper'
4
4
 
5
5
  RSpec.describe GraphqlDevise::Model::WithEmailUpdater do
6
6
  describe '#call' do
7
+ shared_examples 'all required arguments are provided' do |base_attributes|
8
+ let(:attributes) { base_attributes.merge(email: 'new@gmail.com', name: 'Updated Name') }
9
+
10
+ it 'postpones email update' do
11
+ expect do
12
+ updater
13
+ resource.reload
14
+ end.to not_change(resource, :email).from(resource.email).and(
15
+ not_change(resource, :uid).from(resource.uid)
16
+ ).and(
17
+ change(resource, :unconfirmed_email).from(nil).to('new@gmail.com')
18
+ ).and(
19
+ change(resource, :name).from(resource.name).to('Updated Name')
20
+ )
21
+ end
22
+
23
+ it 'sends out a confirmation email to the unconfirmed_email' do
24
+ expect { updater }.to change(ActionMailer::Base.deliveries, :count).by(1)
25
+
26
+ email = ActionMailer::Base.deliveries.first
27
+ expect(email.to).to contain_exactly('new@gmail.com')
28
+ end
29
+
30
+ context 'when email value is the same on the DB' do
31
+ let(:attributes) { base_attributes.merge(email: resource.email, name: 'changed') }
32
+
33
+ it 'updates attributes and does not send confirmation email' do
34
+ expect do
35
+ updater
36
+ resource.reload
37
+ end.to change(resource, :name).from(resource.name).to('changed').and(
38
+ not_change(resource, :email).from(resource.email)
39
+ ).and(
40
+ not_change(ActionMailer::Base.deliveries, :count).from(0)
41
+ )
42
+ end
43
+ end
44
+
45
+ context 'when provided params are invalid' do
46
+ let(:attributes) { base_attributes.merge(email: 'newgmail.com', name: '') }
47
+
48
+ it 'returns false and adds errors to the model' do
49
+ expect(updater).to be_falsey
50
+ expect(resource.errors.full_messages).to contain_exactly(
51
+ 'Email is not an email',
52
+ "Name can't be blank"
53
+ )
54
+ end
55
+ end
56
+ end
57
+
7
58
  subject(:updater) { described_class.new(resource, attributes).call }
8
59
 
9
60
  context 'when the model does not have an unconfirmed_email column' do
@@ -38,90 +89,68 @@ RSpec.describe GraphqlDevise::Model::WithEmailUpdater do
38
89
  end
39
90
 
40
91
  context 'when attributes contain email' do
41
- context 'when schema_url is missing' do
42
- let(:attributes) { { email: 'new@gmail.com', name: 'Updated Name' } }
43
-
44
- it 'raises an error' do
45
- expect { updater }.to raise_error(
46
- GraphqlDevise::Error,
47
- 'Method `update_with_email` requires attributes `confirmation_success_url` and `schema_url` for email reconfirmation to work'
48
- )
49
- end
92
+ context 'when confirmation_success_url is used' do
93
+ it_behaves_like 'all required arguments are provided', schema_url: 'http://localhost/test', confirmation_success_url: 'https://google.com'
50
94
 
51
- context 'when email will not change' do
52
- let(:attributes) { { email: resource.email, name: 'changed' } }
53
-
54
- it 'updates name and does not raise an error' do
55
- expect do
56
- updater
57
- resource.reload
58
- end.to change(resource, :name).from(resource.name).to('changed').and(
59
- not_change(resource, :email).from(resource.email)
60
- ).and(
61
- not_change(ActionMailer::Base.deliveries, :count).from(0)
95
+ context 'when confirmation_success_url is missing and no default is set' do
96
+ let(:attributes) { { email: 'new@gmail.com', name: 'Updated Name', schema_url: 'http://localhost/test' } }
97
+
98
+ before { allow(DeviseTokenAuth).to receive(:default_confirm_success_url).and_return(nil) }
99
+
100
+ it 'raises an error' do
101
+ expect { updater }.to raise_error(
102
+ GraphqlDevise::Error,
103
+ 'Method `update_with_email` requires attribute `confirmation_url` for email reconfirmation to work'
62
104
  )
63
105
  end
106
+
107
+ context 'when email will not change' do
108
+ let(:attributes) { { email: resource.email, name: 'changed', confirmation_success_url: 'https://google.com' } }
109
+
110
+ it 'updates name and does not raise an error' do
111
+ expect do
112
+ updater
113
+ resource.reload
114
+ end.to change(resource, :name).from(resource.name).to('changed').and(
115
+ not_change(resource, :email).from(resource.email)
116
+ ).and(
117
+ not_change(ActionMailer::Base.deliveries, :count).from(0)
118
+ )
119
+ end
120
+ end
64
121
  end
65
122
  end
66
123
 
67
- context 'when only confirmation_success_url is missing' do
68
- let(:attributes) { { email: 'new@gmail.com', name: 'Updated Name', schema_url: 'http://localhost/test' } }
124
+ context 'when confirm_url is used' do
125
+ it_behaves_like 'all required arguments are provided', confirmation_url: 'https://google.com'
69
126
 
70
- it 'uses DTA default_confirm_success_url on the email' do
71
- expect { updater }.to change(ActionMailer::Base.deliveries, :count).by(1)
72
-
73
- email = ActionMailer::Base.deliveries.first
74
- expect(email.body.decoded).to include(CGI.escape('https://google.com'))
127
+ context 'when arguments hash has strings as keys' do
128
+ it_behaves_like 'all required arguments are provided', 'confirmation_url' => 'https://google.com'
75
129
  end
76
130
  end
77
131
 
78
- context 'when both required urls are provided' do
79
- let(:attributes) { { email: 'new@gmail.com', name: 'Updated Name', schema_url: 'http://localhost/test', confirmation_success_url: 'https://google.com' } }
80
-
81
- it 'postpones email update' do
82
- expect do
83
- updater
84
- resource.reload
85
- end.to not_change(resource, :email).from(resource.email).and(
86
- not_change(resource, :uid).from(resource.uid)
87
- ).and(
88
- change(resource, :unconfirmed_email).from(nil).to('new@gmail.com')
89
- ).and(
90
- change(resource, :name).from(resource.name).to('Updated Name')
91
- )
92
- end
93
-
94
- it 'sends out a confirmation email to the unconfirmed_email' do
95
- expect { updater }.to change(ActionMailer::Base.deliveries, :count).by(1)
132
+ context 'when no confirmation url is provided is provided' do
133
+ context 'when schema_url is provided' do
134
+ let(:attributes) { { email: 'new@gmail.com', name: 'Updated Name', schema_url: 'http://localhost/test' } }
96
135
 
97
- email = ActionMailer::Base.deliveries.first
98
- expect(email.to).to contain_exactly('new@gmail.com')
99
- end
136
+ it 'uses DTA default_confirm_success_url on the email with redirect flow' do
137
+ expect { updater }.to change(ActionMailer::Base.deliveries, :count).by(1)
100
138
 
101
- context 'when email value is the same on the DB' do
102
- let(:attributes) { { email: resource.email, name: 'changed', schema_url: 'http://localhost/test', confirmation_success_url: 'https://google.com' } }
103
-
104
- it 'updates attributes and does not send confirmation email' do
105
- expect do
106
- updater
107
- resource.reload
108
- end.to change(resource, :name).from(resource.name).to('changed').and(
109
- not_change(resource, :email).from(resource.email)
110
- ).and(
111
- not_change(ActionMailer::Base.deliveries, :count).from(0)
112
- )
139
+ email = ActionMailer::Base.deliveries.first
140
+ expect(email.body.decoded).to include(CGI.escape('https://google.com'))
141
+ expect(email.body.decoded).to include(CGI.escape('ConfirmAccount('))
113
142
  end
114
143
  end
115
144
 
116
- context 'when provided params are invalid' do
117
- let(:attributes) { { email: 'newgmail.com', name: '', schema_url: 'http://localhost/test', confirmation_success_url: 'https://google.com' } }
145
+ context 'when schema_url is not provided' do
146
+ let(:attributes) { { email: 'new@gmail.com', name: 'Updated Name' } }
118
147
 
119
- it 'returns false and adds errors to the model' do
120
- expect(updater).to be_falsey
121
- expect(resource.errors.full_messages).to contain_exactly(
122
- 'Email is not an email',
123
- "Name can't be blank"
124
- )
148
+ it 'uses DTA default_confirm_success_url on the email and new confirmation flow' do
149
+ expect { updater }.to change(ActionMailer::Base.deliveries, :count).by(1)
150
+
151
+ email = ActionMailer::Base.deliveries.first
152
+ expect(email.body.decoded).to include(CGI.escape('https://google.com'))
153
+ expect(email.body.decoded).to include('?confirmationToken=')
125
154
  end
126
155
  end
127
156
  end
@@ -6,20 +6,13 @@ RSpec.describe GraphqlDevise::GraphqlController do
6
6
  let(:password) { 'password123' }
7
7
  let(:user) { create(:user, :confirmed, password: password) }
8
8
  let(:params) { { query: query, variables: variables } }
9
- let(:request_params) do
10
- if Rails::VERSION::MAJOR >= 5
11
- { params: params }
12
- else
13
- params
14
- end
15
- end
16
9
 
17
10
  context 'when variables are a string' do
18
11
  let(:variables) { "{\"email\": \"#{user.email}\"}" }
19
12
  let(:query) { "mutation($email: String!) { userLogin(email: $email, password: \"#{password}\") { user { email name signInCount } } }" }
20
13
 
21
14
  it 'parses the string variables' do
22
- post '/api/v1/graphql_auth', request_params
15
+ post_request('/api/v1/graphql_auth')
23
16
 
24
17
  expect(json_response).to match(
25
18
  data: { userLogin: { user: { email: user.email, name: user.name, signInCount: 1 } } }
@@ -31,7 +24,7 @@ RSpec.describe GraphqlDevise::GraphqlController do
31
24
  let(:query) { "mutation { userLogin(email: \"#{user.email}\", password: \"#{password}\") { user { email name signInCount } } }" }
32
25
 
33
26
  it 'returns an empty hash as variables' do
34
- post '/api/v1/graphql_auth', request_params
27
+ post_request('/api/v1/graphql_auth')
35
28
 
36
29
  expect(json_response).to match(
37
30
  data: { userLogin: { user: { email: user.email, name: user.name, signInCount: 1 } } }
@@ -46,7 +39,7 @@ RSpec.describe GraphqlDevise::GraphqlController do
46
39
 
47
40
  it 'raises an error' do
48
41
  expect do
49
- post '/api/v1/graphql_auth', request_params
42
+ post_request('/api/v1/graphql_auth')
50
43
  end.to raise_error(ArgumentError)
51
44
  end
52
45
  end
@@ -62,7 +55,7 @@ RSpec.describe GraphqlDevise::GraphqlController do
62
55
  end
63
56
 
64
57
  it 'executes multiple queries in the same request' do
65
- post '/api/v1/graphql_auth', request_params
58
+ post_request('/api/v1/graphql_auth')
66
59
 
67
60
  expect(json_response).to match(
68
61
  [
@@ -79,4 +72,12 @@ RSpec.describe GraphqlDevise::GraphqlController do
79
72
  )
80
73
  end
81
74
  end
75
+
76
+ def post_request(path)
77
+ if Rails::VERSION::MAJOR >= 5
78
+ post(path, params: params)
79
+ else
80
+ post(path, params)
81
+ end
82
+ end
82
83
  end