graphql_client 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.rubocop-http---shopify-github-io-ruby-style-guide-rubocop-yml +1133 -0
  4. data/.rubocop.yml +24 -0
  5. data/.travis.yml +6 -0
  6. data/CHANGELOG.md +3 -0
  7. data/CODE_OF_CONDUCT.md +45 -0
  8. data/CONTRIBUTING.md +28 -0
  9. data/CONTRIBUTING_DEVELOPER_CERTIFICATE_OF_ORIGIN.txt +37 -0
  10. data/Gemfile +8 -0
  11. data/LICENSE.md +21 -0
  12. data/README.md +96 -0
  13. data/Rakefile +13 -0
  14. data/bin/graphql-client +79 -0
  15. data/bin/rake +17 -0
  16. data/circle.yml +3 -0
  17. data/dev.yml +7 -0
  18. data/graphql_ruby_client.gemspec +26 -0
  19. data/lib/graphql_client.rb +46 -0
  20. data/lib/graphql_client/adapters/http_adapter.rb +72 -0
  21. data/lib/graphql_client/base.rb +53 -0
  22. data/lib/graphql_client/config.rb +42 -0
  23. data/lib/graphql_client/deserialization.rb +36 -0
  24. data/lib/graphql_client/error.rb +22 -0
  25. data/lib/graphql_client/graph_connection.rb +21 -0
  26. data/lib/graphql_client/graph_node.rb +24 -0
  27. data/lib/graphql_client/graph_object.rb +56 -0
  28. data/lib/graphql_client/introspection_query.rb +80 -0
  29. data/lib/graphql_client/query/add_inline_fragment.rb +42 -0
  30. data/lib/graphql_client/query/argument.rb +30 -0
  31. data/lib/graphql_client/query/document.rb +86 -0
  32. data/lib/graphql_client/query/field.rb +91 -0
  33. data/lib/graphql_client/query/fragment.rb +41 -0
  34. data/lib/graphql_client/query/has_selection_set.rb +72 -0
  35. data/lib/graphql_client/query/inline_fragment.rb +35 -0
  36. data/lib/graphql_client/query/mutation_document.rb +20 -0
  37. data/lib/graphql_client/query/operation.rb +46 -0
  38. data/lib/graphql_client/query/operations/mutation_operation.rb +17 -0
  39. data/lib/graphql_client/query/operations/query_operation.rb +17 -0
  40. data/lib/graphql_client/query/query_document.rb +20 -0
  41. data/lib/graphql_client/query/selection_set.rb +53 -0
  42. data/lib/graphql_client/response.rb +21 -0
  43. data/lib/graphql_client/response_connection.rb +18 -0
  44. data/lib/graphql_client/response_object.rb +32 -0
  45. data/lib/graphql_client/schema_patches.rb +17 -0
  46. data/lib/graphql_client/version.rb +7 -0
  47. data/shipit.rubygems.yml +1 -0
  48. data/shipit.yml +4 -0
  49. data/test/graphql_client/adapters/http_adapter_test.rb +111 -0
  50. data/test/graphql_client/config_test.rb +68 -0
  51. data/test/graphql_client/graph_connection_test.rb +8 -0
  52. data/test/graphql_client/graph_node_test.rb +8 -0
  53. data/test/graphql_client/graph_object_query_transforming_test.rb +156 -0
  54. data/test/graphql_client/graph_object_test.rb +142 -0
  55. data/test/graphql_client/graphql_client_test.rb +41 -0
  56. data/test/graphql_client/http_client_test.rb +52 -0
  57. data/test/graphql_client/query/add_inline_fragment_test.rb +57 -0
  58. data/test/graphql_client/query/arguments_test.rb +89 -0
  59. data/test/graphql_client/query/document_test.rb +246 -0
  60. data/test/graphql_client/query/field_test.rb +163 -0
  61. data/test/graphql_client/query/fragment_test.rb +45 -0
  62. data/test/graphql_client/query/inline_fragment_test.rb +37 -0
  63. data/test/graphql_client/query/mutation_document_test.rb +30 -0
  64. data/test/graphql_client/query/mutation_operation_test.rb +89 -0
  65. data/test/graphql_client/query/query_document_test.rb +30 -0
  66. data/test/graphql_client/query/query_operation_test.rb +262 -0
  67. data/test/graphql_client/query/selection_set_test.rb +116 -0
  68. data/test/graphql_client/response_connection_test.rb +50 -0
  69. data/test/graphql_client/response_object_test.rb +109 -0
  70. data/test/graphql_client/response_test.rb +67 -0
  71. data/test/support/fixtures/schema.json +13710 -0
  72. data/test/test_helper.rb +37 -0
  73. metadata +227 -0
@@ -0,0 +1,163 @@
1
+ require 'test_helper'
2
+
3
+ module GraphQL
4
+ module Client
5
+ module Query
6
+ class FieldTest < Minitest::Test
7
+ def setup
8
+ @schema = GraphQLSchema.new(schema_fixture('schema.json'))
9
+ @document = Document.new(@schema)
10
+ end
11
+
12
+ def test_validates_arguments
13
+ field_defn = @schema.query_root.field('shop')
14
+
15
+ assert_raises Field::INVALID_ARGUMENTS do
16
+ Field.new(field_defn, document: @document, arguments: { id: 2 })
17
+ end
18
+ end
19
+
20
+ def test_add_arguments_merges_new_arguments_with_existing_ones
21
+ shop = @schema.query_root.field('shop')
22
+ products_defn = schema_type(shop.type).field('products')
23
+ field = Field.new(products_defn, document: @document, arguments: { first: 5 })
24
+
25
+ field.add_arguments(first: 10, after: 'cursor')
26
+
27
+ first_arg = Argument.new(10)
28
+ after_arg = Argument.new('cursor')
29
+
30
+ assert_equal({ first: first_arg, after: after_arg }, field.arguments)
31
+ end
32
+
33
+ def test_add_field_creates_field_and_adds_to_selection_set
34
+ field_defn = @schema.query_root.field('shop')
35
+ field = Field.new(field_defn, document: @document, arguments: {})
36
+
37
+ name = field.add_field('name')
38
+
39
+ assert_equal({ 'name' => name }, field.selection_set.fields)
40
+ end
41
+
42
+ def test_add_field_does_not_add_duplicate_fields
43
+ field_defn = @schema.query_root.field('shop')
44
+ field = Field.new(field_defn, document: @document, arguments: {})
45
+
46
+ field.add_field('name')
47
+ new_name = field.add_field('name')
48
+
49
+ assert_equal({ 'name' => new_name }, field.selection_set.fields)
50
+ end
51
+
52
+ def test_add_field_allows_multiple_fields_of_same_type_with_aliases
53
+ field_defn = @schema.query_root.field('shop')
54
+ field = Field.new(field_defn, document: @document, arguments: {})
55
+
56
+ name = field.add_field('name')
57
+ myname = field.add_field('name', as: 'myname')
58
+
59
+ assert_equal({ 'name' => name, 'myname' => myname }, field.selection_set.fields)
60
+ end
61
+
62
+ def test_add_fields_creates_multiple_fields
63
+ field_defn = @schema.query_root.field('shop')
64
+ field = Field.new(field_defn, document: @document, arguments: {})
65
+
66
+ field.add_fields('name', 'termsOfService')
67
+
68
+ assert_equal %w(name termsOfService), field.selection_set.fields.keys
69
+ end
70
+
71
+ def test_add_field_uses_as_alias_name
72
+ field_defn = @schema.query_root.field('shop')
73
+ field = Field.new(field_defn, document: @document, arguments: {}, as: 'myshop')
74
+
75
+ field.add_field('name')
76
+
77
+ query_string = <<~QUERY
78
+ myshop: shop {
79
+ name
80
+ }
81
+ QUERY
82
+
83
+ assert_equal query_string.chomp, field.to_query
84
+ end
85
+
86
+ def test_name_returns_alias_if_set
87
+ field_defn = @schema.query_root.field('shop')
88
+ field = Field.new(field_defn, document: @document, as: 'myshop')
89
+
90
+ assert_equal 'myshop', field.name
91
+ end
92
+
93
+ def test_name_defaults_to_field_name
94
+ field_defn = @schema.query_root.field('shop')
95
+ field = Field.new(field_defn, document: @document)
96
+
97
+ assert_equal 'shop', field.name
98
+ end
99
+
100
+ def test_resolver_type_is_the_fields_base_type
101
+ field_defn = @schema.query_root.field('shop')
102
+ field = Field.new(field_defn, document: @document, arguments: {})
103
+
104
+ assert_equal schema_type(field_defn.type), field.resolver_type
105
+ end
106
+
107
+ def test_to_query_is_the_graphql_query_string
108
+ field_defn = @schema.query_root.field('shop')
109
+ field = Field.new(field_defn, document: @document, arguments: {})
110
+
111
+ assert_equal 'shop', field.to_query
112
+ end
113
+
114
+ def test_to_query_includes_the_selection_set_selection_set
115
+ field_defn = @schema.query_root.field('shop')
116
+ field = Field.new(field_defn, document: @document, arguments: {})
117
+
118
+ field.add_field('name')
119
+
120
+ query_string = <<~QUERY
121
+ shop {
122
+ name
123
+ }
124
+ QUERY
125
+
126
+ assert_equal query_string.chomp, field.to_query
127
+ end
128
+
129
+ def test_to_query_includes_arguments
130
+ field_defn = @schema.query_root.field('shop')
131
+
132
+ shop = Field.new(field_defn, document: @document)
133
+ shop.add_field('name')
134
+
135
+ shop.add_connection('products', first: 5, after: 'cursor') do |products|
136
+ products.add_field('title')
137
+ end
138
+
139
+ query_string = <<~QUERY
140
+ shop {
141
+ name
142
+ products(first: 5, after: "cursor") {
143
+ edges {
144
+ cursor
145
+ node {
146
+ id
147
+ title
148
+ }
149
+ }
150
+ pageInfo {
151
+ hasPreviousPage
152
+ hasNextPage
153
+ }
154
+ }
155
+ }
156
+ QUERY
157
+
158
+ assert_equal query_string.chomp, shop.to_query
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ module GraphQL
4
+ module Client
5
+ module Query
6
+ class FragmentTest < Minitest::Test
7
+ def setup
8
+ @schema = GraphQLSchema.new(schema_fixture('schema.json'))
9
+ @document = Document.new(@schema)
10
+ end
11
+
12
+ def test_resolver_type_is_the_type
13
+ shop = @schema.type('Shop')
14
+ fragment = Fragment.new('shopFields', shop, document: @document)
15
+
16
+ assert_equal shop, fragment.resolver_type
17
+ end
18
+
19
+ def test_to_definition
20
+ shop = @schema.type('Shop')
21
+ fragment = Fragment.new('shopFields', shop, document: @document)
22
+ fragment.add_field('name')
23
+
24
+ definition_string = <<~QUERY
25
+ fragment shopFields on Shop {
26
+ name
27
+ }
28
+ QUERY
29
+
30
+ assert_equal definition_string, fragment.to_definition
31
+ end
32
+
33
+ def test_to_query_is_the_fragment_spread
34
+ shop = @schema.type('Shop')
35
+
36
+ fragment = Fragment.new('shopFields', shop, document: @document) do |f|
37
+ f.add_field('name')
38
+ end
39
+
40
+ assert_equal '...shopFields', fragment.to_query
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,37 @@
1
+ require 'test_helper'
2
+
3
+ module GraphQL
4
+ module Client
5
+ module Query
6
+ class InlineFragmentTest < Minitest::Test
7
+ def setup
8
+ @schema = GraphQLSchema.new(schema_fixture('schema.json'))
9
+ @document = Document.new(@schema)
10
+ end
11
+
12
+ def test_resolver_type_is_the_type
13
+ shop = @schema.type('Shop')
14
+ inline_fragment = InlineFragment.new(shop, document: @document)
15
+
16
+ assert_equal shop, inline_fragment.resolver_type
17
+ end
18
+
19
+ def test_to_query
20
+ shop = @schema.type('Shop')
21
+
22
+ inline_fragment = InlineFragment.new(shop, document: @document) do |f|
23
+ f.add_field('name')
24
+ end
25
+
26
+ query_string = <<~QUERY
27
+ ... on Shop {
28
+ name
29
+ }
30
+ QUERY
31
+
32
+ assert_equal query_string.chomp, inline_fragment.to_query
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+
3
+ module GraphQL
4
+ module Client
5
+ module Query
6
+ class QueryDocumentTest < Minitest::Test
7
+ def setup
8
+ @schema = GraphQLSchema.new(schema_fixture('schema.json'))
9
+ end
10
+
11
+ def test_new_creates_a_document_with_a_mutation_operation
12
+ mutation_operation = MutationDocument.new(@schema)
13
+
14
+ assert_equal mutation_operation, mutation_operation.document.operations['default']
15
+ assert_instance_of MutationOperation, mutation_operation
16
+ end
17
+
18
+ def test_new_yields_mutation_operation
19
+ mutation_operation_object = nil
20
+
21
+ mutation_operation = MutationDocument.new(@schema) do |q|
22
+ mutation_operation_object = q
23
+ end
24
+
25
+ assert_equal mutation_operation_object, mutation_operation
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,89 @@
1
+ require 'test_helper'
2
+
3
+ module GraphQL
4
+ module Client
5
+ module Query
6
+ class MutationOperationTest < Minitest::Test
7
+ def setup
8
+ @schema = GraphQLSchema.new(schema_fixture('schema.json'))
9
+ @graphql_schema = GraphQL::Schema::Loader.load(schema_fixture('schema.json'))
10
+ end
11
+
12
+ def test_initialize_yields_self
13
+ document = Document.new(@schema)
14
+ query_object = nil
15
+
16
+ query = MutationOperation.new(document) do |q|
17
+ query_object = q
18
+ end
19
+
20
+ assert_equal query_object, query
21
+ end
22
+
23
+ def test_resolver_type_is_the_schemas_mutation_root
24
+ mock_schema = Minitest::Mock.new
25
+ document = Document.new(mock_schema)
26
+
27
+ query = MutationOperation.new(document)
28
+
29
+ mock_schema.expect(:mutation_root_name, 'mutationRoot')
30
+ mock_schema.expect(:type, nil, ['mutationRoot'])
31
+
32
+ query.resolver_type
33
+
34
+ assert mock_schema.verify
35
+ end
36
+
37
+ def test_to_query_handles_multiple_nested_selection_set
38
+ document = Document.new(@schema)
39
+
40
+ query = MutationOperation.new(document) do |q|
41
+ q.add_field('customerCreate', input: { email: 'email', password: 'password' }) do |mutation|
42
+ mutation.add_field('customer') do |customer|
43
+ customer.add_field('email')
44
+ end
45
+ end
46
+ end
47
+
48
+ query_string = <<~QUERY
49
+ mutation {
50
+ customerCreate(input: { email: "email", password: "password" }) {
51
+ customer {
52
+ email
53
+ }
54
+ }
55
+ }
56
+ QUERY
57
+
58
+ assert_equal query_string, query.to_query
59
+ assert_valid_query query_string, @graphql_schema
60
+ end
61
+
62
+ def test_to_query_handles_variables
63
+ document = Document.new(@schema)
64
+
65
+ query = MutationOperation.new(document, variables: { email: 'String!' }) do |q|
66
+ q.add_field('customerCreate', input: { email: '$email', password: 'password' }) do |mutation|
67
+ mutation.add_field('customer') do |customer|
68
+ customer.add_field('email')
69
+ end
70
+ end
71
+ end
72
+
73
+ query_string = <<~QUERY
74
+ mutation($email: String!) {
75
+ customerCreate(input: { email: $email, password: \"password\" }) {
76
+ customer {
77
+ email
78
+ }
79
+ }
80
+ }
81
+ QUERY
82
+
83
+ assert_equal query_string, query.to_query
84
+ assert_valid_query query_string, @graphql_schema, variables: { 'email' => 'email' }
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+
3
+ module GraphQL
4
+ module Client
5
+ module Query
6
+ class QueryDocumentTest < Minitest::Test
7
+ def setup
8
+ @schema = GraphQLSchema.new(schema_fixture('schema.json'))
9
+ end
10
+
11
+ def test_new_creates_a_document_with_a_query_operation
12
+ query_operation = QueryDocument.new(@schema)
13
+
14
+ assert_equal query_operation, query_operation.document.operations['default']
15
+ assert_instance_of QueryOperation, query_operation
16
+ end
17
+
18
+ def test_new_yields_query_operation
19
+ query_operation_object = nil
20
+
21
+ query_operation = QueryDocument.new(@schema) do |q|
22
+ query_operation_object = q
23
+ end
24
+
25
+ assert_equal query_operation_object, query_operation
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,262 @@
1
+ require 'test_helper'
2
+
3
+ module GraphQL
4
+ module Client
5
+ module Query
6
+ class QueryOperationTest < Minitest::Test
7
+ def setup
8
+ @schema = GraphQLSchema.new(schema_fixture('schema.json'))
9
+ @graphql_schema = GraphQL::Schema::Loader.load(schema_fixture('schema.json'))
10
+ end
11
+
12
+ def test_initialize_yields_self
13
+ query_object = nil
14
+ document = Document.new(@schema)
15
+
16
+ query = QueryOperation.new(document) do |q|
17
+ query_object = q
18
+ end
19
+
20
+ assert_equal query_object, query
21
+ end
22
+
23
+ def test_resolver_type_is_the_schemas_query_root
24
+ mock_schema = Minitest::Mock.new
25
+ document = Document.new(mock_schema)
26
+ query = QueryOperation.new(document)
27
+
28
+ mock_schema.expect(:query_root_name, 'queryRoot')
29
+ mock_schema.expect(:type, nil, ['queryRoot'])
30
+
31
+ query.resolver_type
32
+
33
+ assert mock_schema.verify
34
+ end
35
+
36
+ def test_to_query_with_a_single_query_field
37
+ document = Document.new(@schema)
38
+
39
+ query = QueryOperation.new(document) do |q|
40
+ q.add_field('shop') do |s|
41
+ s.add_field('productByHandle', handle: "test") do |product|
42
+ product.add_field('title')
43
+ end
44
+ end
45
+ end
46
+
47
+ query_string = <<~QUERY
48
+ query {
49
+ shop {
50
+ productByHandle(handle: "test") {
51
+ id
52
+ title
53
+ }
54
+ }
55
+ }
56
+ QUERY
57
+
58
+ assert_equal query_string, query.to_query
59
+ assert_valid_query query_string, @graphql_schema
60
+ end
61
+
62
+ def test_to_query_with_a_field_alias
63
+ document = Document.new(@schema)
64
+
65
+ query = QueryOperation.new(document) do |q|
66
+ q.add_field('shop') do |s|
67
+ s.add_field('productByHandle', handle: 'test', as: 'userProduct') do |product|
68
+ product.add_field('title')
69
+ end
70
+ end
71
+ end
72
+
73
+ query_string = <<~QUERY
74
+ query {
75
+ shop {
76
+ userProduct: productByHandle(handle: \"test\") {
77
+ id
78
+ title
79
+ }
80
+ }
81
+ }
82
+ QUERY
83
+
84
+ assert_equal query_string, query.to_query
85
+ assert_valid_query query_string, @graphql_schema
86
+ end
87
+
88
+ def test_to_query_handles_multiple_nested_query_fields
89
+ document = Document.new(@schema)
90
+
91
+ query = QueryOperation.new(document) do |q|
92
+
93
+ q.add_field('shop') do |shop|
94
+ shop.add_field('name')
95
+
96
+ shop.add_field('privacyPolicy') do |policy|
97
+ policy.add_field('body')
98
+ end
99
+
100
+ shop.add_field('productByHandle', handle: 'test') do |product|
101
+ product.add_field('title')
102
+ end
103
+ end
104
+ end
105
+
106
+ query_string = <<~QUERY
107
+ query {
108
+ shop {
109
+ name
110
+ privacyPolicy {
111
+ id
112
+ body
113
+ }
114
+ productByHandle(handle: "test") {
115
+ id
116
+ title
117
+ }
118
+ }
119
+ }
120
+ QUERY
121
+
122
+ assert_equal query_string, query.to_query
123
+ assert_valid_query query_string, @graphql_schema
124
+ end
125
+
126
+ def test_to_query_handles_add_fields
127
+ document = Document.new(@schema)
128
+
129
+ query = QueryOperation.new(document) do |q|
130
+ q.add_field('shop') do |shop|
131
+ shop.add_field('name')
132
+
133
+ shop.add_field('productByHandle', handle: 'test') do |product|
134
+ product.add_field('title')
135
+ end
136
+ end
137
+ end
138
+
139
+ query_string = <<~QUERY
140
+ query {
141
+ shop {
142
+ name
143
+ productByHandle(handle: "test") {
144
+ id
145
+ title
146
+ }
147
+ }
148
+ }
149
+ QUERY
150
+
151
+ assert_equal query_string, query.to_query
152
+ assert_valid_query query_string, @graphql_schema
153
+ end
154
+
155
+ def test_to_query_handles_connections
156
+ document = Document.new(@schema)
157
+
158
+ query = QueryOperation.new(document) do |q|
159
+ q.add_field('shop') do |s|
160
+ s.add_field('productByHandle', handle: 'test') do |product|
161
+ product.add_connection('images', first: 10) do |connection|
162
+ connection.add_field('src')
163
+ end
164
+ end
165
+ end
166
+ end
167
+
168
+ query_string = <<~QUERY
169
+ query {
170
+ shop {
171
+ productByHandle(handle: \"test\") {
172
+ id
173
+ images(first: 10) {
174
+ edges {
175
+ cursor
176
+ node {
177
+ src
178
+ }
179
+ }
180
+ pageInfo {
181
+ hasPreviousPage
182
+ hasNextPage
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
+ QUERY
189
+
190
+ assert_equal query_string, query.to_query
191
+ assert_valid_query query_string, @graphql_schema
192
+ end
193
+
194
+ def test_to_query_adds_node_id_if_type_implements_node
195
+ document = Document.new(@schema)
196
+
197
+ query = QueryOperation.new(document) do |q|
198
+ q.add_field('shop') do |s|
199
+ s.add_field('productByHandle', handle: 'test') do |product|
200
+ product.add_connection('variants', first: 10) do |connection|
201
+ connection.add_field('title')
202
+ end
203
+ end
204
+ end
205
+ end
206
+
207
+ query_string = <<~QUERY
208
+ query {
209
+ shop {
210
+ productByHandle(handle: \"test\") {
211
+ id
212
+ variants(first: 10) {
213
+ edges {
214
+ cursor
215
+ node {
216
+ id
217
+ title
218
+ }
219
+ }
220
+ pageInfo {
221
+ hasPreviousPage
222
+ hasNextPage
223
+ }
224
+ }
225
+ }
226
+ }
227
+ }
228
+ QUERY
229
+
230
+ assert_equal query_string, query.to_query
231
+ assert_valid_query query_string, @graphql_schema
232
+ end
233
+
234
+ def test_to_query_handles_variables
235
+ document = Document.new(@schema)
236
+
237
+ query = QueryOperation.new(document, variables: { productHandle: 'String!' }) do |q|
238
+ q.add_field('shop') do |shop|
239
+ shop.add_field('productByHandle', handle: '$productHandle') do |product|
240
+ product.add_field('title')
241
+ end
242
+ end
243
+ end
244
+
245
+ query_string = <<~QUERY
246
+ query($productHandle: String!) {
247
+ shop {
248
+ productByHandle(handle: $productHandle) {
249
+ id
250
+ title
251
+ }
252
+ }
253
+ }
254
+ QUERY
255
+
256
+ assert_equal query_string, query.to_query
257
+ assert_valid_query query_string, @graphql_schema, variables: { 'productHandle' => 'test' }
258
+ end
259
+ end
260
+ end
261
+ end
262
+ end