search_object_graphql 0.2 → 1.0.1
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/.rubocop.yml +9 -3
- data/.ruby-version +1 -1
- data/.travis.yml +2 -1
- data/CHANGELOG.md +24 -0
- data/README.md +13 -21
- data/example/app/controllers/graphql_controller.rb +3 -3
- data/example/app/graphql/resolvers/base_resolver.rb +6 -0
- data/example/app/graphql/resolvers/base_search_resolver.rb +1 -1
- data/example/app/graphql/resolvers/category_search.rb +1 -1
- data/example/app/graphql/resolvers/post_search.rb +1 -1
- data/example/app/graphql/types/category_type.rb +1 -1
- data/example/app/graphql/types/query_type.rb +1 -1
- data/lib/search_object/plugin/graphql.rb +15 -93
- data/lib/search_object/plugin/graphql/version.rb +1 -1
- data/spec/search_object/plugin/graphql_spec.rb +135 -116
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c82b2028e4c0234e7f8109dbe66cb37746efc7c39e17d7e31a02b10f3e975c5e
|
4
|
+
data.tar.gz: b9d2f3bb799b65943fbcd3d777a75e9a1c3348dd7a33b0064212e373f6bd7422
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a321cd52dfab7394ab746afa2b4d288be0a1beeec9eaa4286989fd0d63a4427f3153aa8aec2ebc42431daea0513b2604d6e123512a22e1cd394ef00ed330dc1c
|
7
|
+
data.tar.gz: 0e6a7c3a3a8a3695b4b2797aa0bcb26c5b98d3bd0bc8d91a605d2e26bafe6c58d001eb260d81fcc88d53c0f3b28f945bd6387ce3860bcd48412f781e38c4be1f
|
data/.rubocop.yml
CHANGED
@@ -7,15 +7,15 @@ AllCops:
|
|
7
7
|
- search_object.gemspec
|
8
8
|
|
9
9
|
# Disables "Line is too long"
|
10
|
-
LineLength:
|
10
|
+
Metrics/LineLength:
|
11
11
|
Enabled: false
|
12
12
|
|
13
13
|
# Disables Module has too many lines
|
14
|
-
ModuleLength:
|
14
|
+
Metrics/ModuleLength:
|
15
15
|
Enabled: false
|
16
16
|
|
17
17
|
# Disables "Missing top-level class documentation comment"
|
18
|
-
Documentation:
|
18
|
+
Style/Documentation:
|
19
19
|
Enabled: false
|
20
20
|
|
21
21
|
# Disables "Use each_with_object instead of inject"
|
@@ -49,3 +49,9 @@ RSpec/ExampleLength:
|
|
49
49
|
# Disables "Too many expectations."
|
50
50
|
RSpec/MultipleExpectations:
|
51
51
|
Enabled: false
|
52
|
+
|
53
|
+
Metrics/CyclomaticComplexity:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
Metrics/PerceivedComplexity:
|
57
|
+
Enabled: false
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.6.2
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## Version 1.0.1
|
4
|
+
|
5
|
+
* __[fix]__ `camelize` defaults to false when not specified (@haines)
|
6
|
+
|
7
|
+
## Version 1.0.0
|
8
|
+
|
9
|
+
* __[break]__ Removed support for defining types via `type` method (@rstankov)
|
10
|
+
* __[break]__ Require `GraphQL::Schema::Resolver` inheritance (@rstankov)
|
11
|
+
* __[break]__ Removed support for legacy `GraphQL::Function` (@rstankov)
|
12
|
+
* __[break]__ `type` creates type based on `GraphQL::Schema::Object`, not the deprecated `GraphQL::ObjectType.define` (@rstankov)
|
13
|
+
|
14
|
+
## Version 0.3.2
|
15
|
+
|
16
|
+
* __[feature]__ Added `camelize` argument to `option`, *`true` by default* (@glenbray)
|
17
|
+
|
18
|
+
## Version 0.3.1
|
19
|
+
|
20
|
+
* __[fix]__ Support for GraphQL gem version v1.9.16 (@ardinusawan)
|
21
|
+
|
22
|
+
## Version 0.3
|
23
|
+
|
24
|
+
* __[feature]__ Allow passing `required` key to option definition (@vfonic)
|
25
|
+
* __[fix]__ Support for GraphQL gem enums (@Postmodum37)
|
26
|
+
|
3
27
|
## Version 0.2
|
4
28
|
|
5
29
|
* Added support for GraphQL::Schema::Resolver (@rstankov)
|
data/README.md
CHANGED
@@ -39,6 +39,14 @@ Or install it yourself as:
|
|
39
39
|
|
40
40
|
$ gem install search_object_graphql
|
41
41
|
|
42
|
+
|
43
|
+
**Require manually in your project**
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
require 'search_object'
|
47
|
+
require 'search_object/plugin/graphql'
|
48
|
+
```
|
49
|
+
|
42
50
|
## Dependencies
|
43
51
|
|
44
52
|
- `SearchObject` >= 1.2
|
@@ -49,7 +57,7 @@ Or install it yourself as:
|
|
49
57
|
Just include the ```SearchObject.module``` and define your search options and their types:
|
50
58
|
|
51
59
|
```ruby
|
52
|
-
class PostResolver
|
60
|
+
class PostResolver < GraphQL::Schema::Resolver
|
53
61
|
include SearchObject.module(:graphql)
|
54
62
|
|
55
63
|
type [PostType], null: false
|
@@ -86,7 +94,7 @@ You can find example of most important features and plugins - [here](https://git
|
|
86
94
|
Search object itself can be documented, as well as its options:
|
87
95
|
|
88
96
|
```ruby
|
89
|
-
class PostResolver
|
97
|
+
class PostResolver < GraphQL::Schema::Resolver
|
90
98
|
include SearchObject.module(:graphql)
|
91
99
|
|
92
100
|
description 'Lists all posts'
|
@@ -99,7 +107,7 @@ end
|
|
99
107
|
### Default Values
|
100
108
|
|
101
109
|
```ruby
|
102
|
-
class PostResolver
|
110
|
+
class PostResolver < GraphQL::Schema::Resolver
|
103
111
|
include SearchObject.module(:graphql)
|
104
112
|
|
105
113
|
scope { Post.all }
|
@@ -113,7 +121,7 @@ end
|
|
113
121
|
Sometimes you want to scope posts based on parent object, it is accessible as `object` property:
|
114
122
|
|
115
123
|
```ruby
|
116
|
-
class PostResolver
|
124
|
+
class PostResolver < GraphQL::Schema::Resolver
|
117
125
|
include SearchObject.module(:graphql)
|
118
126
|
|
119
127
|
# lists only posts from certain category
|
@@ -160,7 +168,7 @@ end
|
|
160
168
|
Search objects can be used as [Relay Connections](https://graphql-ruby.org/relay/connections.html):
|
161
169
|
|
162
170
|
```ruby
|
163
|
-
class PostResolver
|
171
|
+
class PostResolver < GraphQL::Schema::Resolver
|
164
172
|
include SearchObject.module(:graphql)
|
165
173
|
|
166
174
|
type PostType.connection_type, null: false
|
@@ -173,22 +181,6 @@ end
|
|
173
181
|
field :posts, resolver: PostResolver
|
174
182
|
```
|
175
183
|
|
176
|
-
### Legacy Function Support
|
177
|
-
|
178
|
-
```ruby
|
179
|
-
class PostResolver
|
180
|
-
include SearchObject.module(:graphql)
|
181
|
-
|
182
|
-
type [PostType], null: false
|
183
|
-
|
184
|
-
# ...
|
185
|
-
end
|
186
|
-
```
|
187
|
-
|
188
|
-
```ruby
|
189
|
-
field :posts, function: PostResolver
|
190
|
-
```
|
191
|
-
|
192
184
|
## Contributing
|
193
185
|
|
194
186
|
1. Fork it
|
@@ -7,10 +7,10 @@ class GraphqlController < ApplicationController
|
|
7
7
|
context: {},
|
8
8
|
operation_name: params[:operationName])
|
9
9
|
render json: result
|
10
|
-
rescue StandardError =>
|
11
|
-
raise
|
10
|
+
rescue StandardError => e
|
11
|
+
raise e unless Rails.env.development?
|
12
12
|
|
13
|
-
handle_error_in_development
|
13
|
+
handle_error_in_development e
|
14
14
|
end
|
15
15
|
|
16
16
|
private
|
@@ -4,18 +4,19 @@ module SearchObject
|
|
4
4
|
module Plugin
|
5
5
|
module Graphql
|
6
6
|
def self.included(base)
|
7
|
+
raise NotIncludedInResolverError, base unless base.ancestors.include? GraphQL::Schema::Resolver
|
8
|
+
|
7
9
|
base.include SearchObject::Plugin::Enum
|
8
|
-
base.include ::GraphQL::Schema::Member::GraphQLTypeNames
|
9
10
|
base.extend ClassMethods
|
10
11
|
end
|
11
12
|
|
12
13
|
attr_reader :object, :context
|
13
14
|
|
14
|
-
def initialize(filters: {}, object: nil, context: {}, scope: nil)
|
15
|
+
def initialize(filters: {}, object: nil, context: {}, scope: nil, field: nil)
|
15
16
|
@object = object
|
16
17
|
@context = context
|
17
18
|
|
18
|
-
super filters: filters, scope: scope
|
19
|
+
super filters: filters, scope: scope, field: field
|
19
20
|
end
|
20
21
|
|
21
22
|
# NOTE(rstankov): GraphQL::Schema::Resolver interface
|
@@ -26,108 +27,29 @@ module SearchObject
|
|
26
27
|
end
|
27
28
|
|
28
29
|
module ClassMethods
|
29
|
-
KEYS = %i[type default description].freeze
|
30
30
|
def option(name, options = {}, &block)
|
31
|
-
config[:arguments] ||= {}
|
32
|
-
config[:arguments][name.to_s] = KEYS.inject({}) do |acc, key|
|
33
|
-
acc[key] = options[key] if options.key?(key)
|
34
|
-
acc
|
35
|
-
end
|
36
|
-
|
37
31
|
type = options.fetch(:type) { raise MissingTypeDefinitionError, name }
|
38
|
-
options[:enum] = type.values.keys if type.respond_to?(:values)
|
39
32
|
|
40
|
-
|
41
|
-
|
33
|
+
argument_options = { required: options[:required] || false }
|
34
|
+
argument_options[:camelize] = options[:camelize] if options.include?(:camelize)
|
35
|
+
argument_options[:default_value] = options[:default] if options.include?(:default)
|
36
|
+
argument_options[:description] = options[:description] if options.include?(:description)
|
42
37
|
|
43
|
-
|
44
|
-
return config[:type] if value == :default && !block_given?
|
38
|
+
argument(name.to_s, type, **argument_options)
|
45
39
|
|
46
|
-
|
47
|
-
config[:null] = null
|
48
|
-
end
|
49
|
-
|
50
|
-
def complexity(value = :default)
|
51
|
-
return config[:complexity] || 1 if value == :default
|
40
|
+
options[:enum] = type.values.map { |value, enum_value| enum_value.value || value } if type.respond_to?(:values)
|
52
41
|
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
def description(value = :default)
|
57
|
-
return config[:description] if value == :default
|
58
|
-
|
59
|
-
config[:description] = value
|
60
|
-
end
|
61
|
-
|
62
|
-
def deprecation_reason(value = :default)
|
63
|
-
return config[:deprecation_reason] if value == :default
|
64
|
-
|
65
|
-
config[:deprecation_reason] = value
|
66
|
-
end
|
67
|
-
|
68
|
-
# NOTE(rstankov): GraphQL::Function interface (deprecated in favour of GraphQL::Schema::Resolver)
|
69
|
-
# Documentation - http://graphql-ruby.org/guides
|
70
|
-
def call(object, args, context)
|
71
|
-
new(filters: args.to_h, object: object, context: context).results
|
42
|
+
super(name, options, &block)
|
72
43
|
end
|
73
44
|
|
74
|
-
# NOTE(rstankov): Used for GraphQL::Function
|
75
45
|
def types
|
76
46
|
GraphQL::Define::TypeDefiner.instance
|
77
47
|
end
|
48
|
+
end
|
78
49
|
|
79
|
-
|
80
|
-
def
|
81
|
-
|
82
|
-
argument = GraphQL::Argument.new
|
83
|
-
argument.name = name.to_s
|
84
|
-
argument.type = options.fetch(:type) { raise MissingTypeDefinitionError, name }
|
85
|
-
argument.default_value = options[:default] if options.key? :default
|
86
|
-
argument.description = options[:description] if options.key? :description
|
87
|
-
|
88
|
-
acc[name] = argument
|
89
|
-
acc
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
# NOTE(rstankov): Used for GraphQL::Schema::Resolver
|
94
|
-
def field_options
|
95
|
-
{
|
96
|
-
type: type,
|
97
|
-
description: description,
|
98
|
-
extras: [],
|
99
|
-
resolver_method: :resolve_with_support,
|
100
|
-
resolver_class: self,
|
101
|
-
deprecation_reason: deprecation_reason,
|
102
|
-
arguments: (config[:arguments] || {}).inject({}) do |acc, (name, options)|
|
103
|
-
acc[name] = ::GraphQL::Schema::Argument.new(
|
104
|
-
name: name.to_s,
|
105
|
-
type: options.fetch(:type) { raise MissingTypeDefinitionError, name },
|
106
|
-
description: options[:description],
|
107
|
-
required: !!options[:required],
|
108
|
-
default_value: options.fetch(:default) { ::GraphQL::Schema::Argument::NO_DEFAULT },
|
109
|
-
owner: self
|
110
|
-
)
|
111
|
-
acc
|
112
|
-
end,
|
113
|
-
null: !!config[:null],
|
114
|
-
complexity: complexity
|
115
|
-
}
|
116
|
-
end
|
117
|
-
|
118
|
-
# NOTE(rstankov): Used for GraphQL::Schema::Resolver
|
119
|
-
def visible?(_context)
|
120
|
-
true
|
121
|
-
end
|
122
|
-
|
123
|
-
# NOTE(rstankov): Used for GraphQL::Schema::Resolver
|
124
|
-
def accessible?(_context)
|
125
|
-
true
|
126
|
-
end
|
127
|
-
|
128
|
-
# NOTE(rstankov): Used for GraphQL::Schema::Resolver
|
129
|
-
def authorized?(_object, _context)
|
130
|
-
true
|
50
|
+
class NotIncludedInResolverError < ArgumentError
|
51
|
+
def initialize(base)
|
52
|
+
super "#{base.name} should inherit from GraphQL::Schema::Resolver. Current ancestors #{base.ancestors}"
|
131
53
|
end
|
132
54
|
end
|
133
55
|
|
@@ -5,17 +5,17 @@ require 'graphql'
|
|
5
5
|
require 'ostruct'
|
6
6
|
require 'search_object/plugin/graphql'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
{ 'id' => id }
|
12
|
-
end
|
8
|
+
Post = Struct.new(:id) do
|
9
|
+
def to_json(_options = {})
|
10
|
+
{ 'id' => id }
|
13
11
|
end
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
class PostType < GraphQL::Schema::Object
|
15
|
+
field :id, ID, null: false
|
16
|
+
end
|
18
17
|
|
18
|
+
describe SearchObject::Plugin::Graphql do
|
19
19
|
def define_schema(&block)
|
20
20
|
query_type = Class.new(GraphQL::Schema::Object) do
|
21
21
|
graphql_name 'Query'
|
@@ -31,7 +31,7 @@ describe SearchObject::Plugin::Graphql do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def define_search_class(&block)
|
34
|
-
Class.new do
|
34
|
+
Class.new(GraphQL::Schema::Resolver) do
|
35
35
|
include SearchObject.module(:graphql)
|
36
36
|
|
37
37
|
scope { [] }
|
@@ -52,6 +52,12 @@ describe SearchObject::Plugin::Graphql do
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
it 'requires class to inherit from GraphQL::Schema::Resolver' do
|
56
|
+
expect do
|
57
|
+
Class.new { include SearchObject.module(:graphql) }
|
58
|
+
end.to raise_error SearchObject::Plugin::Graphql::NotIncludedInResolverError
|
59
|
+
end
|
60
|
+
|
55
61
|
it 'can be used as GraphQL::Schema::Resolver' do
|
56
62
|
post_type = Class.new(GraphQL::Schema::Object) do
|
57
63
|
graphql_name 'Post'
|
@@ -62,7 +68,7 @@ describe SearchObject::Plugin::Graphql do
|
|
62
68
|
search_object = define_search_class do
|
63
69
|
scope { [Post.new('1'), Post.new('2'), Post.new('3')] }
|
64
70
|
|
65
|
-
type [post_type]
|
71
|
+
type [post_type], null: 1
|
66
72
|
|
67
73
|
option(:id, type: !types.ID) { |scope, value| scope.select { |p| p.id == value } }
|
68
74
|
end
|
@@ -80,34 +86,6 @@ describe SearchObject::Plugin::Graphql do
|
|
80
86
|
)
|
81
87
|
end
|
82
88
|
|
83
|
-
it 'can be used as GraphQL::Function' do
|
84
|
-
post_type = GraphQL::ObjectType.define do
|
85
|
-
name 'Post'
|
86
|
-
|
87
|
-
field :id, !types.ID
|
88
|
-
end
|
89
|
-
|
90
|
-
search_object = define_search_class do
|
91
|
-
scope { [Post.new('1'), Post.new('2'), Post.new('3')] }
|
92
|
-
|
93
|
-
type types[post_type]
|
94
|
-
|
95
|
-
option(:id, type: !types.ID) { |scope, value| scope.select { |p| p.id == value } }
|
96
|
-
end
|
97
|
-
|
98
|
-
schema = define_schema do
|
99
|
-
field :posts, function: search_object
|
100
|
-
end
|
101
|
-
|
102
|
-
result = schema.execute '{ posts(id: "2") { id } }'
|
103
|
-
|
104
|
-
expect(result).to eq(
|
105
|
-
'data' => {
|
106
|
-
'posts' => [Post.new('2').to_json]
|
107
|
-
}
|
108
|
-
)
|
109
|
-
end
|
110
|
-
|
111
89
|
it 'can access to parent object' do
|
112
90
|
search_object = define_search_class do
|
113
91
|
scope { object.posts }
|
@@ -164,81 +142,6 @@ describe SearchObject::Plugin::Graphql do
|
|
164
142
|
)
|
165
143
|
end
|
166
144
|
|
167
|
-
it 'can define a custom type' do
|
168
|
-
schema = define_search_class_and_return_schema do
|
169
|
-
type do
|
170
|
-
name 'Test'
|
171
|
-
|
172
|
-
field :title, types.String
|
173
|
-
end
|
174
|
-
|
175
|
-
description 'Test description'
|
176
|
-
end
|
177
|
-
|
178
|
-
result = schema.execute <<-SQL
|
179
|
-
{
|
180
|
-
__type(name: "Query") {
|
181
|
-
name
|
182
|
-
fields {
|
183
|
-
name
|
184
|
-
deprecationReason
|
185
|
-
type {
|
186
|
-
name
|
187
|
-
fields {
|
188
|
-
name
|
189
|
-
}
|
190
|
-
}
|
191
|
-
}
|
192
|
-
}
|
193
|
-
}
|
194
|
-
SQL
|
195
|
-
|
196
|
-
expect(result).to eq(
|
197
|
-
'data' => {
|
198
|
-
'__type' => {
|
199
|
-
'name' => 'Query',
|
200
|
-
'fields' => [{
|
201
|
-
'name' => 'posts',
|
202
|
-
'deprecationReason' => nil,
|
203
|
-
'type' => {
|
204
|
-
'name' => 'Test',
|
205
|
-
'fields' => [{
|
206
|
-
'name' => 'title'
|
207
|
-
}]
|
208
|
-
}
|
209
|
-
}]
|
210
|
-
}
|
211
|
-
}
|
212
|
-
)
|
213
|
-
end
|
214
|
-
|
215
|
-
it 'can be marked as deprecated' do
|
216
|
-
schema = define_search_class_and_return_schema do
|
217
|
-
type [PostType]
|
218
|
-
deprecation_reason 'Not needed any more'
|
219
|
-
end
|
220
|
-
|
221
|
-
result = schema.execute <<-QUERY
|
222
|
-
{
|
223
|
-
__type(name: "Query") {
|
224
|
-
name
|
225
|
-
fields {
|
226
|
-
name
|
227
|
-
}
|
228
|
-
}
|
229
|
-
}
|
230
|
-
QUERY
|
231
|
-
|
232
|
-
expect(result.to_h).to eq(
|
233
|
-
'data' => {
|
234
|
-
'__type' => {
|
235
|
-
'name' => 'Query',
|
236
|
-
'fields' => []
|
237
|
-
}
|
238
|
-
}
|
239
|
-
)
|
240
|
-
end
|
241
|
-
|
242
145
|
describe 'option' do
|
243
146
|
it 'converts GraphQL::Schema::Enum to SearchObject enum' do
|
244
147
|
schema = define_search_class_and_return_schema do
|
@@ -271,8 +174,8 @@ describe SearchObject::Plugin::Graphql do
|
|
271
174
|
|
272
175
|
it 'converts GraphQL::EnumType to SearchObject enum' do
|
273
176
|
schema = define_search_class_and_return_schema do
|
274
|
-
enum_type = GraphQL::
|
275
|
-
|
177
|
+
enum_type = Class.new(GraphQL::Schema::Enum) do
|
178
|
+
graphql_name 'TestEnum'
|
276
179
|
|
277
180
|
value 'PRICE'
|
278
181
|
value 'DATE'
|
@@ -314,9 +217,57 @@ describe SearchObject::Plugin::Graphql do
|
|
314
217
|
)
|
315
218
|
end
|
316
219
|
|
220
|
+
it 'sets default_value on the argument' do
|
221
|
+
schema = define_search_class_and_return_schema do
|
222
|
+
type PostType, null: true
|
223
|
+
|
224
|
+
option('option', type: types.String, default: 'default') { [] }
|
225
|
+
end
|
226
|
+
|
227
|
+
result = schema.execute <<~GRAPHQL
|
228
|
+
{
|
229
|
+
__type(name: "Query") {
|
230
|
+
name
|
231
|
+
fields {
|
232
|
+
args {
|
233
|
+
name
|
234
|
+
defaultValue
|
235
|
+
}
|
236
|
+
}
|
237
|
+
}
|
238
|
+
}
|
239
|
+
GRAPHQL
|
240
|
+
|
241
|
+
expect(result).to eq(
|
242
|
+
'data' => {
|
243
|
+
'__type' => {
|
244
|
+
'name' => 'Query',
|
245
|
+
'fields' => [{
|
246
|
+
'args' => [{
|
247
|
+
'name' => 'option',
|
248
|
+
'defaultValue' => '"default"'
|
249
|
+
}]
|
250
|
+
}]
|
251
|
+
}
|
252
|
+
}
|
253
|
+
)
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'accepts "required"' do
|
257
|
+
schema = define_search_class_and_return_schema do
|
258
|
+
option(:id, type: types.String, required: true) do |_scope, value|
|
259
|
+
[Post.new(value)]
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
result = schema.execute '{ posts { id } }'
|
264
|
+
|
265
|
+
expect(result['errors'][0]['message']).to eq("Field 'posts' is missing required arguments: id")
|
266
|
+
end
|
267
|
+
|
317
268
|
it 'accepts description' do
|
318
269
|
schema = define_search_class_and_return_schema do
|
319
|
-
type PostType
|
270
|
+
type PostType, null: true
|
320
271
|
|
321
272
|
option('option', type: types.String, description: 'what this argument does') { [] }
|
322
273
|
end
|
@@ -350,6 +301,74 @@ describe SearchObject::Plugin::Graphql do
|
|
350
301
|
)
|
351
302
|
end
|
352
303
|
|
304
|
+
it 'accepts camelize' do
|
305
|
+
schema = define_search_class_and_return_schema do
|
306
|
+
type PostType, null: true
|
307
|
+
|
308
|
+
option('option_field', type: types.String, camelize: false)
|
309
|
+
end
|
310
|
+
|
311
|
+
result = schema.execute <<-SQL
|
312
|
+
{
|
313
|
+
__type(name: "Query") {
|
314
|
+
name
|
315
|
+
fields {
|
316
|
+
args {
|
317
|
+
name
|
318
|
+
}
|
319
|
+
}
|
320
|
+
}
|
321
|
+
}
|
322
|
+
SQL
|
323
|
+
|
324
|
+
expect(result.to_h).to eq(
|
325
|
+
'data' => {
|
326
|
+
'__type' => {
|
327
|
+
'name' => 'Query',
|
328
|
+
'fields' => [{
|
329
|
+
'args' => [{
|
330
|
+
'name' => 'option_field'
|
331
|
+
}]
|
332
|
+
}]
|
333
|
+
}
|
334
|
+
}
|
335
|
+
)
|
336
|
+
end
|
337
|
+
|
338
|
+
it 'does not override the default camelize option' do
|
339
|
+
schema = define_search_class_and_return_schema do
|
340
|
+
type PostType, null: true
|
341
|
+
|
342
|
+
option('option_field', type: types.String)
|
343
|
+
end
|
344
|
+
|
345
|
+
result = schema.execute <<~GRAPHQL
|
346
|
+
{
|
347
|
+
__type(name: "Query") {
|
348
|
+
name
|
349
|
+
fields {
|
350
|
+
args {
|
351
|
+
name
|
352
|
+
}
|
353
|
+
}
|
354
|
+
}
|
355
|
+
}
|
356
|
+
GRAPHQL
|
357
|
+
|
358
|
+
expect(result.to_h).to eq(
|
359
|
+
'data' => {
|
360
|
+
'__type' => {
|
361
|
+
'name' => 'Query',
|
362
|
+
'fields' => [{
|
363
|
+
'args' => [{
|
364
|
+
'name' => 'optionField'
|
365
|
+
}]
|
366
|
+
}]
|
367
|
+
}
|
368
|
+
}
|
369
|
+
)
|
370
|
+
end
|
371
|
+
|
353
372
|
it 'raises error when no type is given' do
|
354
373
|
expect { define_search_class { option :name } }.to raise_error described_class::MissingTypeDefinitionError
|
355
374
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: search_object_graphql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Radoslav Stankov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -134,6 +134,7 @@ files:
|
|
134
134
|
- example/app/controllers/application_controller.rb
|
135
135
|
- example/app/controllers/graphql_controller.rb
|
136
136
|
- example/app/graphql/mutations/.keep
|
137
|
+
- example/app/graphql/resolvers/base_resolver.rb
|
137
138
|
- example/app/graphql/resolvers/base_search_resolver.rb
|
138
139
|
- example/app/graphql/resolvers/category_search.rb
|
139
140
|
- example/app/graphql/resolvers/post_search.rb
|
@@ -204,8 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
204
205
|
- !ruby/object:Gem::Version
|
205
206
|
version: '0'
|
206
207
|
requirements: []
|
207
|
-
|
208
|
-
rubygems_version: 2.7.6
|
208
|
+
rubygems_version: 3.0.3
|
209
209
|
signing_key:
|
210
210
|
specification_version: 4
|
211
211
|
summary: Maps search objects to GraphQL resolvers
|