graphql_devise 0.14.0 → 0.16.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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +118 -0
- data/Appraisals +39 -5
- data/CHANGELOG.md +68 -6
- data/README.md +150 -51
- data/Rakefile +2 -1
- data/app/controllers/graphql_devise/concerns/additional_controller_methods.rb +72 -0
- data/app/controllers/graphql_devise/concerns/set_user_by_token.rb +5 -27
- data/app/controllers/graphql_devise/graphql_controller.rb +1 -1
- data/app/helpers/graphql_devise/mailer_helper.rb +2 -2
- data/app/models/graphql_devise/concerns/additional_model_methods.rb +21 -0
- data/app/models/graphql_devise/concerns/model.rb +6 -9
- data/docs/usage/reset_password_flow.md +90 -0
- data/graphql_devise.gemspec +2 -2
- data/lib/generators/graphql_devise/install_generator.rb +1 -1
- data/lib/graphql_devise.rb +20 -6
- data/lib/graphql_devise/concerns/controller_methods.rb +3 -3
- data/lib/graphql_devise/mount_method/operation_preparer.rb +6 -6
- data/lib/graphql_devise/mount_method/operation_preparers/custom_operation_preparer.rb +6 -4
- data/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb +6 -4
- data/lib/graphql_devise/mount_method/operation_preparers/{resource_name_setter.rb → resource_klass_setter.rb} +4 -4
- data/lib/graphql_devise/resolvers/confirm_account.rb +1 -1
- data/lib/graphql_devise/resource_loader.rb +26 -11
- data/lib/graphql_devise/schema_plugin.rb +41 -18
- data/lib/graphql_devise/version.rb +1 -1
- data/spec/dummy/app/controllers/api/v1/graphql_controller.rb +13 -2
- data/spec/dummy/app/graphql/dummy_schema.rb +4 -3
- data/spec/dummy/app/graphql/types/query_type.rb +5 -0
- data/spec/dummy/config/routes.rb +2 -1
- data/spec/dummy/db/migrate/20200623003142_create_schema_users.rb +0 -1
- data/spec/dummy/db/migrate/20210516211417_add_vip_to_users.rb +5 -0
- data/spec/dummy/db/schema.rb +4 -4
- data/spec/generators/graphql_devise/install_generator_spec.rb +1 -1
- data/spec/graphql/user_queries_spec.rb +120 -0
- data/spec/requests/graphql_controller_spec.rb +12 -11
- data/spec/requests/queries/introspection_query_spec.rb +149 -0
- data/spec/requests/user_controller_spec.rb +93 -32
- data/spec/services/mount_method/operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/custom_operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/default_operation_preparer_spec.rb +5 -5
- data/spec/services/mount_method/operation_preparers/{resource_name_setter_spec.rb → resource_klass_setter_spec.rb} +6 -6
- data/spec/services/resource_loader_spec.rb +5 -5
- data/spec/support/contexts/graphql_request.rb +11 -3
- data/spec/support/contexts/schema_test.rb +14 -0
- metadata +25 -14
- data/.travis.yml +0 -79
@@ -4,23 +4,25 @@ module GraphqlDevise
|
|
4
4
|
module MountMethod
|
5
5
|
module OperationPreparers
|
6
6
|
class DefaultOperationPreparer
|
7
|
-
def initialize(selected_operations:, custom_keys:,
|
7
|
+
def initialize(selected_operations:, custom_keys:, model:, preparer:)
|
8
8
|
@selected_operations = selected_operations
|
9
9
|
@custom_keys = custom_keys
|
10
|
-
@
|
10
|
+
@model = model
|
11
11
|
@preparer = preparer
|
12
12
|
end
|
13
13
|
|
14
14
|
def call
|
15
|
+
mapping_name = GraphqlDevise.to_mapping_name(@model)
|
16
|
+
|
15
17
|
@selected_operations.except(*@custom_keys).each_with_object({}) do |(action, operation_info), result|
|
16
|
-
mapped_action = "#{
|
18
|
+
mapped_action = "#{mapping_name}_#{action}"
|
17
19
|
operation = operation_info[:klass]
|
18
20
|
options = operation_info.except(:klass)
|
19
21
|
|
20
22
|
result[mapped_action.to_sym] = [
|
21
23
|
OperationPreparers::GqlNameSetter.new(mapped_action),
|
22
24
|
@preparer,
|
23
|
-
OperationPreparers::
|
25
|
+
OperationPreparers::ResourceKlassSetter.new(@model)
|
24
26
|
].reduce(child_class(operation)) do |prepared_operation, preparer|
|
25
27
|
preparer.call(prepared_operation, **options)
|
26
28
|
end
|
@@ -3,13 +3,13 @@
|
|
3
3
|
module GraphqlDevise
|
4
4
|
module MountMethod
|
5
5
|
module OperationPreparers
|
6
|
-
class
|
7
|
-
def initialize(
|
8
|
-
@
|
6
|
+
class ResourceKlassSetter
|
7
|
+
def initialize(klass)
|
8
|
+
@klass = klass
|
9
9
|
end
|
10
10
|
|
11
11
|
def call(operation, **)
|
12
|
-
operation.instance_variable_set(:@
|
12
|
+
operation.instance_variable_set(:@resource_klass, @klass)
|
13
13
|
|
14
14
|
operation
|
15
15
|
end
|
@@ -10,12 +10,27 @@ module GraphqlDevise
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def call(query, mutation)
|
13
|
-
mapping_name = @resource.to_s.underscore.tr('/', '_').to_sym
|
14
|
-
|
15
13
|
# clean_options responds to all keys defined in GraphqlDevise::MountMethod::SUPPORTED_OPTIONS
|
16
14
|
clean_options = GraphqlDevise::MountMethod::OptionSanitizer.new(@options).call!
|
17
15
|
|
18
|
-
|
16
|
+
model = if @resource.is_a?(String)
|
17
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
|
18
|
+
Providing a String as the model you want to mount is deprecated and will be removed in a future version of
|
19
|
+
this gem. Please use the actual model constant instead.
|
20
|
+
|
21
|
+
EXAMPLE
|
22
|
+
|
23
|
+
GraphqlDevise::ResourceLoader.new(User) # instead of GraphqlDevise::ResourceLoader.new('User')
|
24
|
+
|
25
|
+
mount_graphql_devise_for User # instead of mount_graphql_devise_for 'User'
|
26
|
+
DEPRECATION
|
27
|
+
@resource.constantize
|
28
|
+
else
|
29
|
+
@resource
|
30
|
+
end
|
31
|
+
|
32
|
+
# Necesary when mounting a resource via route file as Devise forces the reloading of routes
|
33
|
+
return clean_options if GraphqlDevise.resource_mounted?(model) && @routing
|
19
34
|
|
20
35
|
validate_options!(clean_options)
|
21
36
|
|
@@ -23,7 +38,7 @@ module GraphqlDevise
|
|
23
38
|
"Types::#{@resource}Type".safe_constantize ||
|
24
39
|
GraphqlDevise::Types::AuthenticatableType
|
25
40
|
|
26
|
-
prepared_mutations = prepare_mutations(
|
41
|
+
prepared_mutations = prepare_mutations(model, clean_options, authenticatable_type)
|
27
42
|
|
28
43
|
if prepared_mutations.any? && mutation.blank?
|
29
44
|
raise GraphqlDevise::Error, 'You need to provide a mutation type unless all mutations are skipped'
|
@@ -33,7 +48,7 @@ module GraphqlDevise
|
|
33
48
|
mutation.field(action, mutation: prepared_mutation, authenticate: false)
|
34
49
|
end
|
35
50
|
|
36
|
-
prepared_resolvers = prepare_resolvers(
|
51
|
+
prepared_resolvers = prepare_resolvers(model, clean_options, authenticatable_type)
|
37
52
|
|
38
53
|
if prepared_resolvers.any? && query.blank?
|
39
54
|
raise GraphqlDevise::Error, 'You need to provide a query type unless all queries are skipped'
|
@@ -43,17 +58,17 @@ module GraphqlDevise
|
|
43
58
|
query.field(action, resolver: resolver, authenticate: false)
|
44
59
|
end
|
45
60
|
|
46
|
-
GraphqlDevise.add_mapping(
|
47
|
-
GraphqlDevise.mount_resource(
|
61
|
+
GraphqlDevise.add_mapping(GraphqlDevise.to_mapping_name(@resource).to_sym, @resource)
|
62
|
+
GraphqlDevise.mount_resource(model) if @routing
|
48
63
|
|
49
64
|
clean_options
|
50
65
|
end
|
51
66
|
|
52
67
|
private
|
53
68
|
|
54
|
-
def prepare_resolvers(
|
69
|
+
def prepare_resolvers(model, clean_options, authenticatable_type)
|
55
70
|
GraphqlDevise::MountMethod::OperationPreparer.new(
|
56
|
-
|
71
|
+
model: model,
|
57
72
|
custom: clean_options.operations,
|
58
73
|
additional_operations: clean_options.additional_queries,
|
59
74
|
preparer: GraphqlDevise::MountMethod::OperationPreparers::ResolverTypeSetter.new(authenticatable_type),
|
@@ -63,9 +78,9 @@ module GraphqlDevise
|
|
63
78
|
).call
|
64
79
|
end
|
65
80
|
|
66
|
-
def prepare_mutations(
|
81
|
+
def prepare_mutations(model, clean_options, authenticatable_type)
|
67
82
|
GraphqlDevise::MountMethod::OperationPreparer.new(
|
68
|
-
|
83
|
+
model: model,
|
69
84
|
custom: clean_options.operations,
|
70
85
|
additional_operations: clean_options.additional_mutations,
|
71
86
|
preparer: GraphqlDevise::MountMethod::OperationPreparers::MutationFieldSetter.new(authenticatable_type),
|
@@ -2,18 +2,20 @@
|
|
2
2
|
|
3
3
|
module GraphqlDevise
|
4
4
|
class SchemaPlugin
|
5
|
+
# NOTE: Based on GQL-Ruby docs https://graphql-ruby.org/schema/introspection.html
|
6
|
+
INTROSPECTION_FIELDS = ['__schema', '__type', '__typename']
|
5
7
|
DEFAULT_NOT_AUTHENTICATED = ->(field) { raise GraphqlDevise::AuthenticationError, "#{field} field requires authentication" }
|
6
8
|
|
7
|
-
def initialize(query: nil, mutation: nil, authenticate_default: true, resource_loaders: [], unauthenticated_proc: DEFAULT_NOT_AUTHENTICATED)
|
9
|
+
def initialize(query: nil, mutation: nil, authenticate_default: true, public_introspection: !Rails.env.production?, resource_loaders: [], unauthenticated_proc: DEFAULT_NOT_AUTHENTICATED)
|
8
10
|
@query = query
|
9
11
|
@mutation = mutation
|
10
12
|
@resource_loaders = resource_loaders
|
11
13
|
@authenticate_default = authenticate_default
|
14
|
+
@public_introspection = public_introspection
|
12
15
|
@unauthenticated_proc = unauthenticated_proc
|
13
16
|
|
14
17
|
# Must happen on initialize so operations are loaded before the types are added to the schema on GQL < 1.10
|
15
18
|
load_fields
|
16
|
-
reconfigure_warden!
|
17
19
|
end
|
18
20
|
|
19
21
|
def use(schema_definition)
|
@@ -24,14 +26,27 @@ module GraphqlDevise
|
|
24
26
|
# Authenticate only root level queries
|
25
27
|
return yield unless event == 'execute_field' && path(trace_data).count == 1
|
26
28
|
|
27
|
-
field
|
28
|
-
|
29
|
-
context
|
29
|
+
field = traced_field(trace_data)
|
30
|
+
auth_required = authenticate_option(field, trace_data)
|
31
|
+
context = context_from_data(trace_data)
|
30
32
|
|
31
|
-
if
|
32
|
-
|
33
|
-
|
34
|
-
|
33
|
+
if context.key?(:resource_name)
|
34
|
+
ActiveSupport::Deprecation.warn(<<-DEPRECATION.strip_heredoc, caller)
|
35
|
+
Providing `resource_name` as part of the GQL context, or doing so by using the `graphql_context(resource_name)`
|
36
|
+
method on your controller is deprecated and will be removed in a future version of this gem.
|
37
|
+
Please use `gql_devise_context` in you controller instead.
|
38
|
+
|
39
|
+
EXAMPLE
|
40
|
+
include GraphqlDevise::Concerns::SetUserByToken
|
41
|
+
|
42
|
+
DummySchema.execute(params[:query], context: gql_devise_context(User))
|
43
|
+
DummySchema.execute(params[:query], context: gql_devise_context(User, Admin))
|
44
|
+
DEPRECATION
|
45
|
+
end
|
46
|
+
|
47
|
+
if auth_required && !(public_introspection && introspection_field?(field))
|
48
|
+
context = set_current_resource(context)
|
49
|
+
raise_on_missing_resource(context, field, auth_required)
|
35
50
|
end
|
36
51
|
|
37
52
|
yield
|
@@ -39,10 +54,13 @@ module GraphqlDevise
|
|
39
54
|
|
40
55
|
private
|
41
56
|
|
57
|
+
attr_reader :public_introspection
|
58
|
+
|
42
59
|
def set_current_resource(context)
|
43
|
-
controller
|
44
|
-
resource_names
|
45
|
-
|
60
|
+
controller = context[:controller]
|
61
|
+
resource_names = Array(context[:resource_name])
|
62
|
+
|
63
|
+
context[:current_resource] ||= resource_names.find do |resource_name|
|
46
64
|
unless Devise.mappings.key?(resource_name)
|
47
65
|
raise(
|
48
66
|
GraphqlDevise::Error,
|
@@ -57,8 +75,12 @@ module GraphqlDevise
|
|
57
75
|
context
|
58
76
|
end
|
59
77
|
|
60
|
-
def raise_on_missing_resource(context, field)
|
78
|
+
def raise_on_missing_resource(context, field, auth_required)
|
61
79
|
@unauthenticated_proc.call(field.name) if context[:current_resource].blank?
|
80
|
+
|
81
|
+
if auth_required.respond_to?(:call) && !auth_required.call(context[:current_resource])
|
82
|
+
@unauthenticated_proc.call(field.name)
|
83
|
+
end
|
62
84
|
end
|
63
85
|
|
64
86
|
def context_from_data(trace_data)
|
@@ -88,16 +110,13 @@ module GraphqlDevise
|
|
88
110
|
end
|
89
111
|
|
90
112
|
def authenticate_option(field, trace_data)
|
91
|
-
if trace_data[:context]
|
113
|
+
auth_required = if trace_data[:context]
|
92
114
|
field.metadata[:authenticate]
|
93
115
|
else
|
94
116
|
field.graphql_definition.metadata[:authenticate]
|
95
117
|
end
|
96
|
-
end
|
97
118
|
|
98
|
-
|
99
|
-
Devise.class_variable_set(:@@warden_configured, nil)
|
100
|
-
Devise.configure_warden!
|
119
|
+
auth_required.nil? ? @authenticate_default : auth_required
|
101
120
|
end
|
102
121
|
|
103
122
|
def load_fields
|
@@ -107,6 +126,10 @@ module GraphqlDevise
|
|
107
126
|
resource_loader.call(@query, @mutation)
|
108
127
|
end
|
109
128
|
end
|
129
|
+
|
130
|
+
def introspection_field?(field)
|
131
|
+
INTROSPECTION_FIELDS.include?(field.name)
|
132
|
+
end
|
110
133
|
end
|
111
134
|
end
|
112
135
|
|
@@ -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,9 +2,10 @@
|
|
2
2
|
|
3
3
|
class DummySchema < GraphQL::Schema
|
4
4
|
use GraphqlDevise::SchemaPlugin.new(
|
5
|
-
query:
|
6
|
-
mutation:
|
7
|
-
|
5
|
+
query: Types::QueryType,
|
6
|
+
mutation: Types::MutationType,
|
7
|
+
public_introspection: true,
|
8
|
+
resource_loaders: [
|
8
9
|
GraphqlDevise::ResourceLoader.new(
|
9
10
|
'User',
|
10
11
|
only: [
|
@@ -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
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -11,7 +11,7 @@ Rails.application.routes.draw do
|
|
11
11
|
}
|
12
12
|
|
13
13
|
mount_graphql_devise_for(
|
14
|
-
|
14
|
+
Admin,
|
15
15
|
authenticatable_type: Types::CustomAdminType,
|
16
16
|
skip: [:sign_up, :check_password_token],
|
17
17
|
operations: {
|
@@ -37,4 +37,5 @@ Rails.application.routes.draw do
|
|
37
37
|
post '/api/v1/graphql', to: 'api/v1/graphql#graphql'
|
38
38
|
post '/api/v1/interpreter', to: 'api/v1/graphql#interpreter'
|
39
39
|
post '/api/v1/failing', to: 'api/v1/graphql#failing_resource_name'
|
40
|
+
post '/api/v1/controller_auth', to: 'api/v1/graphql#controller_auth'
|
40
41
|
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
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -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:
|
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(
|
36
|
+
assert_file 'app/graphql/gqld_dummy_schema.rb', /\s+#{Regexp.escape("GraphqlDevise::ResourceLoader.new(Admin)")}/
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
RSpec.describe 'Users controller specs' do
|
6
|
+
include_context 'with graphql schema test'
|
7
|
+
|
8
|
+
let(:schema) { DummySchema }
|
9
|
+
let(:user) { create(:user, :confirmed) }
|
10
|
+
let(:field) { 'privateField' }
|
11
|
+
let(:public_message) { 'Field does not require authentication' }
|
12
|
+
let(:private_message) { 'Field will always require authentication' }
|
13
|
+
let(:private_error) do
|
14
|
+
{
|
15
|
+
message: "#{field} field requires authentication",
|
16
|
+
extensions: { code: 'AUTHENTICATION_ERROR' }
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'publicField' do
|
21
|
+
let(:query) do
|
22
|
+
<<-GRAPHQL
|
23
|
+
query {
|
24
|
+
publicField
|
25
|
+
}
|
26
|
+
GRAPHQL
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when using a regular schema' do
|
30
|
+
it 'does not require authentication' do
|
31
|
+
expect(response[:data][:publicField]).to eq(public_message)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'privateField' do
|
37
|
+
let(:query) do
|
38
|
+
<<-GRAPHQL
|
39
|
+
query {
|
40
|
+
privateField
|
41
|
+
}
|
42
|
+
GRAPHQL
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when using a regular schema' do
|
46
|
+
context 'when user is authenticated' do
|
47
|
+
let(:resource) { user }
|
48
|
+
|
49
|
+
it 'allows to perform the query' do
|
50
|
+
expect(response[:data][:privateField]).to eq(private_message)
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when using a SchemaUser' do
|
54
|
+
let(:resource) { create(:schema_user, :confirmed) }
|
55
|
+
|
56
|
+
it 'allows to perform the query' do
|
57
|
+
expect(response[:data][:privateField]).to eq(private_message)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when using an interpreter schema' do
|
64
|
+
let(:schema) { InterpreterSchema }
|
65
|
+
|
66
|
+
context 'when user is authenticated' do
|
67
|
+
let(:resource) { user }
|
68
|
+
|
69
|
+
it 'allows to perform the query' do
|
70
|
+
expect(response[:data][:privateField]).to eq(private_message)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe 'user' do
|
77
|
+
let(:user_data) { { email: user.email, id: user.id } }
|
78
|
+
let(:query) do
|
79
|
+
<<-GRAPHQL
|
80
|
+
query {
|
81
|
+
user(
|
82
|
+
id: #{user.id}
|
83
|
+
) {
|
84
|
+
id
|
85
|
+
email
|
86
|
+
}
|
87
|
+
}
|
88
|
+
GRAPHQL
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when using a regular schema' do
|
92
|
+
context 'when user is authenticated' do
|
93
|
+
let(:resource) { user }
|
94
|
+
|
95
|
+
it 'allows to perform the query' do
|
96
|
+
expect(response[:data][:user]).to match(**user_data)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'when using an interpreter schema' do
|
102
|
+
let(:schema) { InterpreterSchema }
|
103
|
+
|
104
|
+
context 'when user is authenticated' do
|
105
|
+
let(:resource) { user }
|
106
|
+
|
107
|
+
it 'allows to perform the query' do
|
108
|
+
expect(response[:data][:user]).to match(**user_data)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'when user is not authenticated' do
|
113
|
+
# Interpreter schema fields are public unless specified otherwise (plugin setting)
|
114
|
+
it 'allows to perform the query' do
|
115
|
+
expect(response[:data][:user]).to match(**user_data)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|