graphql_client 0.3.3

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.
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