graphql 1.9.11 → 1.9.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (286) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/ast/query_complexity.rb +0 -8
  3. data/lib/graphql/analysis/ast/query_depth.rb +0 -8
  4. data/lib/graphql/analysis/ast/visitor.rb +26 -24
  5. data/lib/graphql/execution.rb +1 -0
  6. data/lib/graphql/execution/errors.rb +60 -0
  7. data/lib/graphql/execution/interpreter/runtime.rb +21 -17
  8. data/lib/graphql/static_validation/rules/fields_will_merge.rb +15 -8
  9. data/lib/graphql/version.rb +1 -1
  10. metadata +5 -556
  11. data/spec/dummy/Gemfile +0 -12
  12. data/spec/dummy/README.md +0 -24
  13. data/spec/dummy/Rakefile +0 -7
  14. data/spec/dummy/app/assets/config/manifest.js +0 -1
  15. data/spec/dummy/app/assets/javascripts/application.js +0 -66
  16. data/spec/dummy/app/channels/application_cable/channel.rb +0 -5
  17. data/spec/dummy/app/channels/application_cable/connection.rb +0 -5
  18. data/spec/dummy/app/channels/graphql_channel.rb +0 -116
  19. data/spec/dummy/app/controllers/application_controller.rb +0 -4
  20. data/spec/dummy/app/controllers/pages_controller.rb +0 -5
  21. data/spec/dummy/app/helpers/application_helper.rb +0 -3
  22. data/spec/dummy/app/jobs/application_job.rb +0 -3
  23. data/spec/dummy/app/views/layouts/application.html.erb +0 -12
  24. data/spec/dummy/app/views/pages/show.html +0 -16
  25. data/spec/dummy/bin/bundle +0 -4
  26. data/spec/dummy/bin/rails +0 -5
  27. data/spec/dummy/bin/rake +0 -5
  28. data/spec/dummy/bin/setup +0 -31
  29. data/spec/dummy/bin/update +0 -27
  30. data/spec/dummy/bin/yarn +0 -12
  31. data/spec/dummy/config.ru +0 -6
  32. data/spec/dummy/config/application.rb +0 -30
  33. data/spec/dummy/config/boot.rb +0 -4
  34. data/spec/dummy/config/cable.yml +0 -10
  35. data/spec/dummy/config/environment.rb +0 -6
  36. data/spec/dummy/config/environments/development.rb +0 -40
  37. data/spec/dummy/config/environments/production.rb +0 -76
  38. data/spec/dummy/config/environments/test.rb +0 -37
  39. data/spec/dummy/config/initializers/application_controller_renderer.rb +0 -9
  40. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -8
  41. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -6
  42. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -5
  43. data/spec/dummy/config/initializers/inflections.rb +0 -17
  44. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  45. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -10
  46. data/spec/dummy/config/locales/en.yml +0 -33
  47. data/spec/dummy/config/puma.rb +0 -57
  48. data/spec/dummy/config/routes.rb +0 -4
  49. data/spec/dummy/config/secrets.yml +0 -32
  50. data/spec/dummy/package.json +0 -5
  51. data/spec/dummy/public/404.html +0 -67
  52. data/spec/dummy/public/422.html +0 -67
  53. data/spec/dummy/public/500.html +0 -66
  54. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  55. data/spec/dummy/public/apple-touch-icon.png +0 -0
  56. data/spec/dummy/public/favicon.ico +0 -0
  57. data/spec/dummy/public/robots.txt +0 -1
  58. data/spec/dummy/test/application_system_test_case.rb +0 -6
  59. data/spec/dummy/test/system/action_cable_subscription_test.rb +0 -45
  60. data/spec/dummy/test/test_helper.rb +0 -4
  61. data/spec/fixtures/upgrader/account.original.rb +0 -19
  62. data/spec/fixtures/upgrader/account.transformed.rb +0 -20
  63. data/spec/fixtures/upgrader/blame_range.original.rb +0 -43
  64. data/spec/fixtures/upgrader/blame_range.transformed.rb +0 -30
  65. data/spec/fixtures/upgrader/date_time.original.rb +0 -24
  66. data/spec/fixtures/upgrader/date_time.transformed.rb +0 -23
  67. data/spec/fixtures/upgrader/delete_project.original.rb +0 -28
  68. data/spec/fixtures/upgrader/delete_project.transformed.rb +0 -27
  69. data/spec/fixtures/upgrader/gist_order_field.original.rb +0 -14
  70. data/spec/fixtures/upgrader/gist_order_field.transformed.rb +0 -13
  71. data/spec/fixtures/upgrader/increment_count.original.rb +0 -59
  72. data/spec/fixtures/upgrader/increment_count.transformed.rb +0 -50
  73. data/spec/fixtures/upgrader/mutation.original.rb +0 -28
  74. data/spec/fixtures/upgrader/mutation.transformed.rb +0 -28
  75. data/spec/fixtures/upgrader/photo.original.rb +0 -10
  76. data/spec/fixtures/upgrader/photo.transformed.rb +0 -12
  77. data/spec/fixtures/upgrader/release_order.original.rb +0 -15
  78. data/spec/fixtures/upgrader/release_order.transformed.rb +0 -14
  79. data/spec/fixtures/upgrader/starrable.original.rb +0 -49
  80. data/spec/fixtures/upgrader/starrable.transformed.rb +0 -46
  81. data/spec/fixtures/upgrader/subscribable.original.rb +0 -55
  82. data/spec/fixtures/upgrader/subscribable.transformed.rb +0 -51
  83. data/spec/fixtures/upgrader/type_x.original.rb +0 -65
  84. data/spec/fixtures/upgrader/type_x.transformed.rb +0 -56
  85. data/spec/graphql/analysis/analyze_query_spec.rb +0 -261
  86. data/spec/graphql/analysis/ast/field_usage_spec.rb +0 -51
  87. data/spec/graphql/analysis/ast/max_query_complexity_spec.rb +0 -120
  88. data/spec/graphql/analysis/ast/max_query_depth_spec.rb +0 -134
  89. data/spec/graphql/analysis/ast/query_complexity_spec.rb +0 -299
  90. data/spec/graphql/analysis/ast/query_depth_spec.rb +0 -108
  91. data/spec/graphql/analysis/ast_spec.rb +0 -296
  92. data/spec/graphql/analysis/field_usage_spec.rb +0 -62
  93. data/spec/graphql/analysis/max_query_complexity_spec.rb +0 -102
  94. data/spec/graphql/analysis/max_query_depth_spec.rb +0 -103
  95. data/spec/graphql/analysis/query_complexity_spec.rb +0 -301
  96. data/spec/graphql/analysis/query_depth_spec.rb +0 -81
  97. data/spec/graphql/argument_spec.rb +0 -159
  98. data/spec/graphql/authorization_spec.rb +0 -974
  99. data/spec/graphql/backtrace_spec.rb +0 -206
  100. data/spec/graphql/base_type_spec.rb +0 -171
  101. data/spec/graphql/boolean_type_spec.rb +0 -21
  102. data/spec/graphql/compatibility/execution_specification_spec.rb +0 -4
  103. data/spec/graphql/compatibility/lazy_execution_specification_spec.rb +0 -4
  104. data/spec/graphql/compatibility/query_parser_specification_spec.rb +0 -6
  105. data/spec/graphql/compatibility/schema_parser_specification_spec.rb +0 -6
  106. data/spec/graphql/define/assign_argument_spec.rb +0 -61
  107. data/spec/graphql/define/instance_definable_spec.rb +0 -203
  108. data/spec/graphql/directive/skip_directive_spec.rb +0 -9
  109. data/spec/graphql/directive_spec.rb +0 -295
  110. data/spec/graphql/enum_type_spec.rb +0 -158
  111. data/spec/graphql/execution/execute_spec.rb +0 -303
  112. data/spec/graphql/execution/instrumentation_spec.rb +0 -212
  113. data/spec/graphql/execution/interpreter_spec.rb +0 -485
  114. data/spec/graphql/execution/lazy/lazy_method_map_spec.rb +0 -57
  115. data/spec/graphql/execution/lazy_spec.rb +0 -247
  116. data/spec/graphql/execution/lookahead_spec.rb +0 -390
  117. data/spec/graphql/execution/multiplex_spec.rb +0 -222
  118. data/spec/graphql/execution/typecast_spec.rb +0 -47
  119. data/spec/graphql/execution_error_spec.rb +0 -329
  120. data/spec/graphql/field_spec.rb +0 -246
  121. data/spec/graphql/float_type_spec.rb +0 -16
  122. data/spec/graphql/function_spec.rb +0 -152
  123. data/spec/graphql/id_type_spec.rb +0 -33
  124. data/spec/graphql/input_object_type_spec.rb +0 -25
  125. data/spec/graphql/int_type_spec.rb +0 -35
  126. data/spec/graphql/interface_type_spec.rb +0 -196
  127. data/spec/graphql/internal_representation/print_spec.rb +0 -41
  128. data/spec/graphql/internal_representation/rewrite_spec.rb +0 -381
  129. data/spec/graphql/introspection/directive_type_spec.rb +0 -66
  130. data/spec/graphql/introspection/input_value_type_spec.rb +0 -144
  131. data/spec/graphql/introspection/introspection_query_spec.rb +0 -64
  132. data/spec/graphql/introspection/schema_type_spec.rb +0 -57
  133. data/spec/graphql/introspection/type_type_spec.rb +0 -155
  134. data/spec/graphql/language/block_string_spec.rb +0 -70
  135. data/spec/graphql/language/definition_slice_spec.rb +0 -226
  136. data/spec/graphql/language/document_from_schema_definition_spec.rb +0 -770
  137. data/spec/graphql/language/equality_spec.rb +0 -84
  138. data/spec/graphql/language/generation_spec.rb +0 -38
  139. data/spec/graphql/language/lexer_spec.rb +0 -153
  140. data/spec/graphql/language/nodes_spec.rb +0 -67
  141. data/spec/graphql/language/parser_spec.rb +0 -183
  142. data/spec/graphql/language/printer_spec.rb +0 -215
  143. data/spec/graphql/language/visitor_spec.rb +0 -419
  144. data/spec/graphql/list_type_spec.rb +0 -57
  145. data/spec/graphql/non_null_type_spec.rb +0 -48
  146. data/spec/graphql/object_type_spec.rb +0 -197
  147. data/spec/graphql/query/arguments_spec.rb +0 -346
  148. data/spec/graphql/query/context_spec.rb +0 -292
  149. data/spec/graphql/query/executor_spec.rb +0 -341
  150. data/spec/graphql/query/literal_input_spec.rb +0 -91
  151. data/spec/graphql/query/result_spec.rb +0 -29
  152. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +0 -109
  153. data/spec/graphql/query_spec.rb +0 -803
  154. data/spec/graphql/rake_task_spec.rb +0 -59
  155. data/spec/graphql/scalar_type_spec.rb +0 -66
  156. data/spec/graphql/schema/argument_spec.rb +0 -186
  157. data/spec/graphql/schema/build_from_definition_spec.rb +0 -1197
  158. data/spec/graphql/schema/catchall_middleware_spec.rb +0 -32
  159. data/spec/graphql/schema/directive/feature_spec.rb +0 -81
  160. data/spec/graphql/schema/directive/transform_spec.rb +0 -39
  161. data/spec/graphql/schema/enum_spec.rb +0 -83
  162. data/spec/graphql/schema/enum_value_spec.rb +0 -24
  163. data/spec/graphql/schema/field_extension_spec.rb +0 -159
  164. data/spec/graphql/schema/field_spec.rb +0 -319
  165. data/spec/graphql/schema/finder_spec.rb +0 -135
  166. data/spec/graphql/schema/input_object_spec.rb +0 -421
  167. data/spec/graphql/schema/instrumentation_spec.rb +0 -43
  168. data/spec/graphql/schema/interface_spec.rb +0 -215
  169. data/spec/graphql/schema/introspection_system_spec.rb +0 -80
  170. data/spec/graphql/schema/list_spec.rb +0 -73
  171. data/spec/graphql/schema/loader_spec.rb +0 -350
  172. data/spec/graphql/schema/member/accepts_definition_spec.rb +0 -115
  173. data/spec/graphql/schema/member/build_type_spec.rb +0 -63
  174. data/spec/graphql/schema/member/scoped_spec.rb +0 -217
  175. data/spec/graphql/schema/member/type_system_helpers_spec.rb +0 -63
  176. data/spec/graphql/schema/middleware_chain_spec.rb +0 -57
  177. data/spec/graphql/schema/mutation_spec.rb +0 -150
  178. data/spec/graphql/schema/non_null_spec.rb +0 -46
  179. data/spec/graphql/schema/object_spec.rb +0 -355
  180. data/spec/graphql/schema/printer_spec.rb +0 -883
  181. data/spec/graphql/schema/relay_classic_mutation_spec.rb +0 -252
  182. data/spec/graphql/schema/rescue_middleware_spec.rb +0 -88
  183. data/spec/graphql/schema/resolver_spec.rb +0 -743
  184. data/spec/graphql/schema/scalar_spec.rb +0 -101
  185. data/spec/graphql/schema/subscription_spec.rb +0 -505
  186. data/spec/graphql/schema/timeout_middleware_spec.rb +0 -188
  187. data/spec/graphql/schema/timeout_spec.rb +0 -206
  188. data/spec/graphql/schema/traversal_spec.rb +0 -222
  189. data/spec/graphql/schema/type_expression_spec.rb +0 -39
  190. data/spec/graphql/schema/union_spec.rb +0 -72
  191. data/spec/graphql/schema/unique_within_type_spec.rb +0 -44
  192. data/spec/graphql/schema/validation_spec.rb +0 -355
  193. data/spec/graphql/schema/warden_spec.rb +0 -926
  194. data/spec/graphql/schema_spec.rb +0 -169
  195. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +0 -466
  196. data/spec/graphql/static_validation/rules/argument_names_are_unique_spec.rb +0 -44
  197. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +0 -112
  198. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +0 -35
  199. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +0 -42
  200. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +0 -167
  201. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +0 -66
  202. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +0 -740
  203. data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +0 -28
  204. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +0 -52
  205. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +0 -42
  206. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +0 -123
  207. data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +0 -24
  208. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +0 -56
  209. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +0 -61
  210. data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +0 -39
  211. data/spec/graphql/static_validation/rules/no_definitions_are_present_spec.rb +0 -62
  212. data/spec/graphql/static_validation/rules/operation_names_are_valid_spec.rb +0 -82
  213. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +0 -98
  214. data/spec/graphql/static_validation/rules/required_input_object_attributes_are_present_spec.rb +0 -86
  215. data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +0 -34
  216. data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +0 -188
  217. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +0 -196
  218. data/spec/graphql/static_validation/rules/variable_names_are_unique_spec.rb +0 -23
  219. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +0 -236
  220. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +0 -78
  221. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +0 -81
  222. data/spec/graphql/static_validation/type_stack_spec.rb +0 -29
  223. data/spec/graphql/static_validation/validator_spec.rb +0 -204
  224. data/spec/graphql/string_type_spec.rb +0 -80
  225. data/spec/graphql/subscriptions/serialize_spec.rb +0 -49
  226. data/spec/graphql/subscriptions_spec.rb +0 -540
  227. data/spec/graphql/tracing/new_relic_tracing_spec.rb +0 -84
  228. data/spec/graphql/tracing/platform_tracing_spec.rb +0 -141
  229. data/spec/graphql/tracing/prometheus_tracing_spec.rb +0 -42
  230. data/spec/graphql/tracing/scout_tracing_spec.rb +0 -17
  231. data/spec/graphql/tracing/skylight_tracing_spec.rb +0 -63
  232. data/spec/graphql/tracing_spec.rb +0 -52
  233. data/spec/graphql/types/big_int_spec.rb +0 -24
  234. data/spec/graphql/types/iso_8601_date_time_spec.rb +0 -137
  235. data/spec/graphql/types/relay/base_edge_spec.rb +0 -33
  236. data/spec/graphql/union_type_spec.rb +0 -211
  237. data/spec/graphql/upgrader/member_spec.rb +0 -583
  238. data/spec/graphql/upgrader/schema_spec.rb +0 -82
  239. data/spec/integration/mongoid/graphql/relay/mongo_relation_connection_spec.rb +0 -528
  240. data/spec/integration/mongoid/spec_helper.rb +0 -2
  241. data/spec/integration/mongoid/star_trek/data.rb +0 -126
  242. data/spec/integration/mongoid/star_trek/schema.rb +0 -424
  243. data/spec/integration/rails/data.rb +0 -110
  244. data/spec/integration/rails/generators/base_generator_test.rb +0 -7
  245. data/spec/integration/rails/generators/graphql/enum_generator_spec.rb +0 -30
  246. data/spec/integration/rails/generators/graphql/install_generator_spec.rb +0 -238
  247. data/spec/integration/rails/generators/graphql/interface_generator_spec.rb +0 -34
  248. data/spec/integration/rails/generators/graphql/loader_generator_spec.rb +0 -59
  249. data/spec/integration/rails/generators/graphql/mutation_generator_spec.rb +0 -71
  250. data/spec/integration/rails/generators/graphql/object_generator_spec.rb +0 -54
  251. data/spec/integration/rails/generators/graphql/scalar_generator_spec.rb +0 -28
  252. data/spec/integration/rails/generators/graphql/union_generator_spec.rb +0 -67
  253. data/spec/integration/rails/graphql/input_object_spec.rb +0 -19
  254. data/spec/integration/rails/graphql/input_object_type_spec.rb +0 -364
  255. data/spec/integration/rails/graphql/query/variables_spec.rb +0 -375
  256. data/spec/integration/rails/graphql/relay/array_connection_spec.rb +0 -309
  257. data/spec/integration/rails/graphql/relay/base_connection_spec.rb +0 -101
  258. data/spec/integration/rails/graphql/relay/connection_instrumentation_spec.rb +0 -80
  259. data/spec/integration/rails/graphql/relay/connection_resolve_spec.rb +0 -79
  260. data/spec/integration/rails/graphql/relay/connection_type_spec.rb +0 -106
  261. data/spec/integration/rails/graphql/relay/edge_spec.rb +0 -10
  262. data/spec/integration/rails/graphql/relay/mutation_spec.rb +0 -387
  263. data/spec/integration/rails/graphql/relay/node_spec.rb +0 -263
  264. data/spec/integration/rails/graphql/relay/page_info_spec.rb +0 -111
  265. data/spec/integration/rails/graphql/relay/range_add_spec.rb +0 -117
  266. data/spec/integration/rails/graphql/relay/relation_connection_spec.rb +0 -837
  267. data/spec/integration/rails/graphql/schema_spec.rb +0 -507
  268. data/spec/integration/rails/graphql/tracing/active_support_notifications_tracing_spec.rb +0 -62
  269. data/spec/integration/rails/spec_helper.rb +0 -25
  270. data/spec/spec_helper.rb +0 -116
  271. data/spec/support/dummy/data.rb +0 -45
  272. data/spec/support/dummy/schema.rb +0 -519
  273. data/spec/support/error_bubbling_helpers.rb +0 -23
  274. data/spec/support/global_id.rb +0 -23
  275. data/spec/support/jazz.rb +0 -778
  276. data/spec/support/lazy_helpers.rb +0 -192
  277. data/spec/support/magic_cards/schema.graphql +0 -33
  278. data/spec/support/minimum_input_object.rb +0 -21
  279. data/spec/support/new_relic.rb +0 -27
  280. data/spec/support/parser/filename_example.graphql +0 -5
  281. data/spec/support/parser/filename_example_error_1.graphql +0 -4
  282. data/spec/support/parser/filename_example_error_2.graphql +0 -5
  283. data/spec/support/parser/filename_example_invalid_utf8.graphql +0 -1
  284. data/spec/support/skylight.rb +0 -39
  285. data/spec/support/star_wars/schema.rb +0 -464
  286. data/spec/support/static_validation_helpers.rb +0 -32
@@ -1,101 +0,0 @@
1
- # frozen_string_literal: true
2
- require "spec_helper"
3
-
4
- describe GraphQL::Schema::Scalar do
5
- describe ".path" do
6
- it "is the name" do
7
- assert_equal "String", GraphQL::Types::String.path
8
- end
9
- end
10
-
11
- describe "in queries" do
12
- it "becomes output" do
13
- query_str = <<-GRAPHQL
14
- {
15
- find(id: "Musician/Herbie Hancock") {
16
- ... on Musician {
17
- name
18
- favoriteKey
19
- }
20
- }
21
- }
22
- GRAPHQL
23
-
24
- res = Jazz::Schema.execute(query_str)
25
- assert_equal "B♭", res["data"]["find"]["favoriteKey"]
26
- end
27
-
28
- it "can be input" do
29
- query_str = <<-GRAPHQL
30
- {
31
- inspectKey(key: "F♯") {
32
- root
33
- isSharp
34
- isFlat
35
- }
36
- }
37
- GRAPHQL
38
-
39
- res = Jazz::Schema.execute(query_str)
40
- key_info = res["data"]["inspectKey"]
41
- assert_equal "F", key_info["root"]
42
- assert_equal true, key_info["isSharp"]
43
- assert_equal false, key_info["isFlat"]
44
- end
45
-
46
- it "can be nested JSON" do
47
- query_str = <<-GRAPHQL
48
- {
49
- echoJson(input: {foo: [{bar: "baz"}]})
50
- }
51
- GRAPHQL
52
-
53
- res = Jazz::Schema.execute(query_str)
54
- assert_equal({"foo" => [{"bar" => "baz"}]}, res["data"]["echoJson"])
55
- end
56
-
57
- it "can be a JSON array" do
58
- query_str = <<-GRAPHQL
59
- {
60
- echoFirstJson(input: [{foo: "bar"}, {baz: "boo"}])
61
- }
62
- GRAPHQL
63
-
64
- res = Jazz::Schema.execute(query_str)
65
- assert_equal({"foo" => "bar"}, res["data"]["echoFirstJson"])
66
- end
67
-
68
- it "can be a JSON array even if the GraphQL type is not an array" do
69
- query_str = <<-GRAPHQL
70
- {
71
- echoJson(input: [{foo: "bar"}])
72
- }
73
- GRAPHQL
74
-
75
- res = Jazz::Schema.execute(query_str)
76
- assert_equal([{"foo" => "bar"}], res["data"]["echoJson"])
77
- end
78
-
79
- it "can be JSON with a nested enum" do
80
- query_str = <<-GRAPHQL
81
- {
82
- echoJson(input: [{foo: WOODWIND}])
83
- }
84
- GRAPHQL
85
-
86
- res = Jazz::Schema.execute(query_str)
87
- assert_equal([{"foo" => "WOODWIND"}], res["data"]["echoJson"])
88
- end
89
-
90
- it "cannot be JSON with a nested variable" do
91
- query_str = <<-GRAPHQL
92
- {
93
- echoJson(input: [{foo: $var}])
94
- }
95
- GRAPHQL
96
-
97
- res = Jazz::Schema.execute(query_str)
98
- assert_includes(res["errors"][0]["message"], "Argument 'input' on Field 'echoJson' has an invalid value")
99
- end
100
- end
101
- end
@@ -1,505 +0,0 @@
1
- # frozen_string_literal: true
2
- require "spec_helper"
3
-
4
- describe GraphQL::Schema::Subscription do
5
- class SubscriptionFieldSchema < GraphQL::Schema
6
- TOOTS = []
7
- ALL_USERS = {
8
- "dhh" => {handle: "dhh", private: false},
9
- "matz" => {handle: "matz", private: false},
10
- "_why" => {handle: "_why", private: true},
11
- }
12
-
13
- USERS = {}
14
-
15
- class User < GraphQL::Schema::Object
16
- field :handle, String, null: false
17
- field :private, Boolean, null: false
18
- end
19
-
20
- class Toot < GraphQL::Schema::Object
21
- field :handle, String, null: false
22
- field :body, String, null: false
23
- end
24
-
25
- class Query < GraphQL::Schema::Object
26
- field :toots, [Toot], null: false
27
-
28
- def toots
29
- TOOTS
30
- end
31
- end
32
-
33
- class BaseSubscription < GraphQL::Schema::Subscription
34
- end
35
-
36
- class TootWasTooted < BaseSubscription
37
- argument :handle, String, required: true, loads: User, as: :user
38
- field :toot, Toot, null: false
39
- field :user, User, null: false
40
- # Can't subscribe to private users
41
- def authorized?(user:)
42
- if user[:private]
43
- raise GraphQL::ExecutionError, "Can't subscribe to private user"
44
- else
45
- true
46
- end
47
- end
48
-
49
- def subscribe(user:)
50
- if context[:prohibit_subscriptions]
51
- raise GraphQL::ExecutionError, "You don't have permission to subscribe"
52
- else
53
- # Default is to return :no_response
54
- super
55
- end
56
- end
57
-
58
- def update(user:)
59
- if context[:viewer] == user
60
- # don't update for one's own toots.
61
- # (IRL it would make more sense to implement this in `#subscribe`)
62
- :no_update
63
- else
64
- # This assumes that trigger object can fulfill `{toot:, user:}`,
65
- # for testing that the default implementation is `return object`
66
- super
67
- end
68
- end
69
- end
70
-
71
- class DirectTootWasTooted < BaseSubscription
72
- subscription_scope :viewer
73
- field :toot, Toot, null: false
74
- field :user, User, null: false
75
- end
76
-
77
- # Test initial response, which returns all users
78
- class UsersJoined < BaseSubscription
79
- class UsersJoinedManualPayload < GraphQL::Schema::Object
80
- field :users, [User], null: true,
81
- description: "Includes newly-created users, or all users on the initial load"
82
- end
83
-
84
- payload_type UsersJoinedManualPayload
85
-
86
- def subscribe
87
- { users: USERS.values }
88
- end
89
-
90
- # Test returning a custom object from #update
91
- def update
92
- { users: object[:new_users] }
93
- end
94
- end
95
-
96
- # Like above, but doesn't override #subscription,
97
- # to make sure it works without arguments
98
- class NewUsersJoined < BaseSubscription
99
- field :users, [User], null: true,
100
- description: "Includes newly-created users, or all users on the initial load"
101
- end
102
-
103
- class Subscription < GraphQL::Schema::Object
104
- extend GraphQL::Subscriptions::SubscriptionRoot
105
- field :toot_was_tooted, subscription: TootWasTooted
106
- field :direct_toot_was_tooted, subscription: DirectTootWasTooted
107
- field :users_joined, subscription: UsersJoined
108
- field :new_users_joined, subscription: NewUsersJoined
109
- end
110
-
111
- class Mutation < GraphQL::Schema::Object
112
- field :toot, Toot, null: false do
113
- argument :body, String, required: true
114
- end
115
-
116
- def toot(body:)
117
- handle = context[:viewer][:handle]
118
- toot = { handle: handle, body: body }
119
- TOOTS << toot
120
- SubscriptionFieldSchema.trigger(:toot_was_tooted, {handle: handle}, toot)
121
- end
122
- end
123
-
124
- query(Query)
125
- mutation(Mutation)
126
- subscription(Subscription)
127
- use GraphQL::Execution::Interpreter
128
- use GraphQL::Analysis::AST
129
-
130
- def self.object_from_id(id, ctx)
131
- USERS[id]
132
- end
133
-
134
-
135
- class InMemorySubscriptions < GraphQL::Subscriptions
136
- SUBSCRIPTION_REGISTRY = {}
137
-
138
- EVENT_REGISTRY = Hash.new { |h, k| h[k] = [] }
139
-
140
- def write_subscription(query, events)
141
- query.context[:subscription_mailbox] = []
142
- subscription_id = build_id
143
- events.each do |ev|
144
- EVENT_REGISTRY[ev.topic] << subscription_id
145
- end
146
- SUBSCRIPTION_REGISTRY[subscription_id] = [query, events]
147
- end
148
-
149
- def each_subscription_id(event)
150
- EVENT_REGISTRY[event.topic].each do |sub_id|
151
- yield(sub_id)
152
- end
153
- end
154
-
155
- def read_subscription(subscription_id)
156
- query, _events = SUBSCRIPTION_REGISTRY[subscription_id]
157
- {
158
- query_string: query.query_string,
159
- context: query.context.to_h,
160
- variables: query.provided_variables,
161
- operation_name: query.selected_operation_name,
162
- }
163
- end
164
-
165
- def deliver(subscription_id, result)
166
- query, _events = SUBSCRIPTION_REGISTRY[subscription_id]
167
- query.context[:subscription_mailbox] << result
168
- end
169
-
170
- def delete_subscription(subscription_id)
171
- _query, events = SUBSCRIPTION_REGISTRY.delete(subscription_id)
172
- events.each do |ev|
173
- EVENT_REGISTRY[ev.topic].delete(subscription_id)
174
- end
175
- end
176
- end
177
-
178
- use InMemorySubscriptions
179
- end
180
-
181
- def exec_query(*args)
182
- SubscriptionFieldSchema.execute(*args)
183
- end
184
-
185
- def in_memory_subscription_count
186
- SubscriptionFieldSchema::InMemorySubscriptions::SUBSCRIPTION_REGISTRY.size
187
- end
188
-
189
- before do
190
- # Reset databases
191
- SubscriptionFieldSchema::TOOTS.clear
192
- # Reset in order:
193
- SubscriptionFieldSchema::USERS.clear
194
- SubscriptionFieldSchema::ALL_USERS.map do |k, v|
195
- SubscriptionFieldSchema::USERS[k] = v.dup
196
- end
197
-
198
- SubscriptionFieldSchema::InMemorySubscriptions::SUBSCRIPTION_REGISTRY.clear
199
- SubscriptionFieldSchema::InMemorySubscriptions::EVENT_REGISTRY.clear
200
- end
201
-
202
- it "generates a return type" do
203
- return_type = SubscriptionFieldSchema::TootWasTooted.payload_type
204
- assert_equal "TootWasTootedPayload", return_type.graphql_name
205
- assert_equal ["toot", "user"], return_type.fields.keys
206
- end
207
-
208
- it "can use a premade `payload_type`" do
209
- return_type = SubscriptionFieldSchema::UsersJoined.payload_type
210
- assert_equal "UsersJoinedManualPayload", return_type.graphql_name
211
- assert_equal ["users"], return_type.fields.keys
212
- assert_equal SubscriptionFieldSchema::UsersJoined::UsersJoinedManualPayload, return_type
213
- end
214
-
215
- describe "initial subscription" do
216
- it "calls #subscribe for the initial subscription and returns the result" do
217
- res = exec_query <<-GRAPHQL
218
- subscription {
219
- usersJoined {
220
- users {
221
- handle
222
- }
223
- }
224
- }
225
- GRAPHQL
226
-
227
- assert_equal ["dhh", "matz", "_why"], res["data"]["usersJoined"]["users"].map { |u| u["handle"] }
228
- assert_equal 1, in_memory_subscription_count
229
- end
230
-
231
- it "rejects the subscription if #subscribe raises an error" do
232
- res = exec_query <<-GRAPHQL, context: { prohibit_subscriptions: true }
233
- subscription {
234
- tootWasTooted(handle: "matz") {
235
- toot { body }
236
- }
237
- }
238
- GRAPHQL
239
-
240
- expected_response = {
241
- "data"=>nil,
242
- "errors"=>[
243
- {
244
- "message"=>"You don't have permission to subscribe",
245
- "locations"=>[{"line"=>2, "column"=>9}],
246
- "path"=>["tootWasTooted"]
247
- }
248
- ]
249
- }
250
-
251
- assert_equal(expected_response, res)
252
- assert_equal 0, in_memory_subscription_count
253
- end
254
-
255
- it "doesn't subscribe if `loads:` fails" do
256
- res = exec_query <<-GRAPHQL
257
- subscription {
258
- tootWasTooted(handle: "jack") {
259
- toot { body }
260
- }
261
- }
262
- GRAPHQL
263
-
264
- expected_response = {
265
- "data" => nil,
266
- "errors" => [
267
- {
268
- "message"=>"No object found for `handle: \"jack\"`",
269
- "locations"=>[{"line"=>2, "column"=>9}],
270
- "path"=>["tootWasTooted"]
271
- }
272
- ]
273
- }
274
- assert_equal(expected_response, res)
275
- assert_equal 0, in_memory_subscription_count
276
- end
277
-
278
- it "rejects if #authorized? fails" do
279
- res = exec_query <<-GRAPHQL
280
- subscription {
281
- tootWasTooted(handle: "_why") {
282
- toot { body }
283
- }
284
- }
285
- GRAPHQL
286
- expected_response = {
287
- "data"=>nil,
288
- "errors"=>[
289
- {
290
- "message"=>"Can't subscribe to private user",
291
- "locations"=>[{"line"=>2, "column"=>9}],
292
- "path"=>["tootWasTooted"]
293
- },
294
- ],
295
- }
296
- assert_equal(expected_response, res)
297
- end
298
-
299
- it "sends no initial response if :no_response is returned, which is the default" do
300
- assert_equal 0, in_memory_subscription_count
301
-
302
- res = exec_query <<-GRAPHQL
303
- subscription {
304
- tootWasTooted(handle: "matz") {
305
- toot { body }
306
- }
307
- }
308
- GRAPHQL
309
- assert_equal({"data" => {}}, res)
310
- assert_equal 1, in_memory_subscription_count
311
- end
312
-
313
- it "works when there are no arguments" do
314
- assert_equal 0, in_memory_subscription_count
315
-
316
- res = exec_query <<-GRAPHQL
317
- subscription {
318
- newUsersJoined {
319
- users {
320
- handle
321
- }
322
- }
323
- }
324
- GRAPHQL
325
- assert_equal({"data" => {}}, res)
326
- assert_equal 1, in_memory_subscription_count
327
- end
328
- end
329
-
330
- describe "updates" do
331
- it "updates with `object` by default" do
332
- res = exec_query <<-GRAPHQL
333
- subscription {
334
- tootWasTooted(handle: "matz") {
335
- toot { body }
336
- }
337
- }
338
- GRAPHQL
339
- assert_equal 1, in_memory_subscription_count
340
- obj = OpenStruct.new(toot: { body: "I am a C programmer" }, user: SubscriptionFieldSchema::USERS["matz"])
341
- SubscriptionFieldSchema.subscriptions.trigger(:toot_was_tooted, {handle: "matz"}, obj)
342
-
343
- mailbox = res.context[:subscription_mailbox]
344
- update_payload = mailbox.first
345
- assert_equal "I am a C programmer", update_payload["data"]["tootWasTooted"]["toot"]["body"]
346
- end
347
-
348
- it "updates with the returned value" do
349
- res = exec_query <<-GRAPHQL
350
- subscription {
351
- usersJoined {
352
- users {
353
- handle
354
- }
355
- }
356
- }
357
- GRAPHQL
358
-
359
- assert_equal 1, in_memory_subscription_count
360
- SubscriptionFieldSchema.subscriptions.trigger(:users_joined, {}, {new_users: [{handle: "eileencodes"}, {handle: "tenderlove"}]})
361
-
362
- update = res.context[:subscription_mailbox].first
363
- assert_equal [{"handle" => "eileencodes"}, {"handle" => "tenderlove"}], update["data"]["usersJoined"]["users"]
364
- end
365
-
366
- it "skips the update if `:no_update` is returned, but updates other subscribers" do
367
- query_str = <<-GRAPHQL
368
- subscription {
369
- tootWasTooted(handle: "matz") {
370
- toot { body }
371
- }
372
- }
373
- GRAPHQL
374
-
375
- res1 = exec_query(query_str)
376
- res2 = exec_query(query_str, context: { viewer: SubscriptionFieldSchema::USERS["matz"] })
377
- assert_equal 2, in_memory_subscription_count
378
-
379
- obj = OpenStruct.new(toot: { body: "Merry Christmas, here's a new Ruby version" }, user: SubscriptionFieldSchema::USERS["matz"])
380
- SubscriptionFieldSchema.subscriptions.trigger(:toot_was_tooted, {handle: "matz"}, obj)
381
-
382
- mailbox1 = res1.context[:subscription_mailbox]
383
- mailbox2 = res2.context[:subscription_mailbox]
384
- # The anonymous viewer got an update:
385
- assert_equal "Merry Christmas, here's a new Ruby version", mailbox1.first["data"]["tootWasTooted"]["toot"]["body"]
386
- # But not matz:
387
- assert_equal [], mailbox2
388
- end
389
-
390
- it "unsubscribes if a `loads:` argument is not found" do
391
- res = exec_query <<-GRAPHQL
392
- subscription {
393
- tootWasTooted(handle: "matz") {
394
- toot { body }
395
- }
396
- }
397
- GRAPHQL
398
- assert_equal 1, in_memory_subscription_count
399
- obj = OpenStruct.new(toot: { body: "I am a C programmer" }, user: SubscriptionFieldSchema::USERS["matz"])
400
- SubscriptionFieldSchema.subscriptions.trigger(:toot_was_tooted, {handle: "matz"}, obj)
401
-
402
- # Get 1 successful update
403
- mailbox = res.context[:subscription_mailbox]
404
- assert_equal 1, mailbox.size
405
- update_payload = mailbox.first
406
- assert_equal "I am a C programmer", update_payload["data"]["tootWasTooted"]["toot"]["body"]
407
-
408
- # Then cause a not-found and update again
409
- matz = SubscriptionFieldSchema::USERS.delete("matz")
410
- obj = OpenStruct.new(toot: { body: "Merry Christmas, here's a new Ruby version" }, user: matz)
411
- SubscriptionFieldSchema.subscriptions.trigger(:toot_was_tooted, {handle: "matz"}, obj)
412
- # there was no subsequent update
413
- assert_equal 1, mailbox.size
414
- # The database was cleaned up
415
- assert_equal 0, in_memory_subscription_count
416
- end
417
-
418
- it "sends an error if `#authorized?` fails" do
419
- res = exec_query <<-GRAPHQL
420
- subscription {
421
- tootWasTooted(handle: "matz") {
422
- toot { body }
423
- }
424
- }
425
- GRAPHQL
426
- assert_equal 1, in_memory_subscription_count
427
- matz = SubscriptionFieldSchema::USERS["matz"]
428
- obj = OpenStruct.new(toot: { body: "I am a C programmer" }, user: matz)
429
- SubscriptionFieldSchema.subscriptions.trigger(:toot_was_tooted, {handle: "matz"}, obj)
430
-
431
- # Get 1 successful update
432
- mailbox = res.context[:subscription_mailbox]
433
- assert_equal 1, mailbox.size
434
- update_payload = mailbox.first
435
- assert_equal "I am a C programmer", update_payload["data"]["tootWasTooted"]["toot"]["body"]
436
-
437
- # Cause an authorized failure
438
- matz[:private] = true
439
- obj = OpenStruct.new(toot: { body: "Merry Christmas, here's a new Ruby version" }, user: matz)
440
- SubscriptionFieldSchema.subscriptions.trigger(:toot_was_tooted, {handle: "matz"}, obj)
441
- assert_equal 2, mailbox.size
442
- assert_equal ["Can't subscribe to private user"], mailbox.last["errors"].map { |e| e["message"] }
443
- # The subscription remains in place
444
- assert_equal 1, in_memory_subscription_count
445
- end
446
- end
447
-
448
- describe "`subscription_scope` method" do
449
- it "provdes a subscription scope that is recognized in the schema" do
450
- scoped_subscription = SubscriptionFieldSchema::get_field("Subscription", "directTootWasTooted")
451
-
452
- assert_equal :viewer, scoped_subscription.subscription_scope
453
- end
454
-
455
- it "provides a subscription scope that is used in execution" do
456
- res = exec_query <<-GRAPHQL, context: { viewer: :me }
457
- subscription {
458
- directTootWasTooted {
459
- toot { body }
460
- }
461
- }
462
- GRAPHQL
463
- assert_equal 1, in_memory_subscription_count
464
-
465
- # Only the subscription with scope :me should be in the mailbox
466
- obj = OpenStruct.new(toot: { body: "Hello from matz!" }, user: SubscriptionFieldSchema::USERS["matz"])
467
- SubscriptionFieldSchema.subscriptions.trigger(:direct_toot_was_tooted, {}, obj, scope: :me)
468
- SubscriptionFieldSchema.subscriptions.trigger(:direct_toot_was_tooted, {}, obj, scope: :not_me)
469
- mailbox = res.context[:subscription_mailbox]
470
-
471
- assert_equal 1, mailbox.length
472
-
473
- expected_response = {
474
- "data" => {
475
- "directTootWasTooted" => {
476
- "toot" => {
477
- "body" => "Hello from matz!"
478
- }
479
- }
480
- }
481
- }
482
-
483
- assert_equal expected_response, mailbox.first
484
- end
485
-
486
- it "allows for proper inheritance of the class's configuration in subclasses" do
487
- # Make a subclass without an explicit configuration
488
- class DirectTootSubclass < SubscriptionFieldSchema::DirectTootWasTooted
489
- end
490
- # Then check if the field options got the inherited value
491
- direct_toot_options = DirectTootSubclass.field_options
492
- assert_equal :viewer, direct_toot_options[:subscription_scope]
493
- end
494
-
495
- it "allows for setting the subscription scope value to nil" do
496
- class PrivateSubscription < SubscriptionFieldSchema::BaseSubscription
497
- subscription_scope :private
498
- end
499
-
500
- PrivateSubscription.subscription_scope nil
501
-
502
- assert_nil PrivateSubscription.subscription_scope
503
- end
504
- end
505
- end