graphql 1.9.5 → 1.13.19

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.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

Files changed (659) hide show
  1. checksums.yaml +5 -5
  2. data/lib/generators/graphql/core.rb +21 -9
  3. data/lib/generators/graphql/enum_generator.rb +4 -10
  4. data/lib/generators/graphql/field_extractor.rb +31 -0
  5. data/lib/generators/graphql/input_generator.rb +50 -0
  6. data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
  7. data/lib/generators/graphql/install/templates/base_mutation.erb +10 -0
  8. data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
  9. data/lib/generators/graphql/install_generator.rb +48 -8
  10. data/lib/generators/graphql/interface_generator.rb +7 -7
  11. data/lib/generators/graphql/loader_generator.rb +1 -0
  12. data/lib/generators/graphql/mutation_create_generator.rb +22 -0
  13. data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
  14. data/lib/generators/graphql/mutation_generator.rb +6 -30
  15. data/lib/generators/graphql/mutation_update_generator.rb +22 -0
  16. data/lib/generators/graphql/object_generator.rb +28 -12
  17. data/lib/generators/graphql/orm_mutations_base.rb +40 -0
  18. data/lib/generators/graphql/relay.rb +63 -0
  19. data/lib/generators/graphql/relay_generator.rb +21 -0
  20. data/lib/generators/graphql/scalar_generator.rb +4 -2
  21. data/lib/generators/graphql/templates/base_argument.erb +6 -0
  22. data/lib/generators/graphql/templates/base_connection.erb +8 -0
  23. data/lib/generators/graphql/templates/base_edge.erb +8 -0
  24. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  25. data/lib/generators/graphql/templates/base_field.erb +7 -0
  26. data/lib/generators/graphql/templates/base_input_object.erb +3 -0
  27. data/lib/generators/graphql/templates/base_interface.erb +4 -0
  28. data/lib/generators/graphql/templates/base_object.erb +3 -0
  29. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  30. data/lib/generators/graphql/templates/base_union.erb +2 -0
  31. data/lib/generators/graphql/templates/enum.erb +7 -1
  32. data/lib/generators/graphql/templates/graphql_controller.erb +21 -12
  33. data/lib/generators/graphql/templates/input.erb +9 -0
  34. data/lib/generators/graphql/templates/interface.erb +6 -2
  35. data/lib/generators/graphql/templates/loader.erb +2 -0
  36. data/lib/generators/graphql/templates/mutation.erb +3 -1
  37. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  38. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  39. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  40. data/lib/generators/graphql/templates/node_type.erb +9 -0
  41. data/lib/generators/graphql/templates/object.erb +7 -3
  42. data/lib/generators/graphql/templates/query_type.erb +3 -3
  43. data/lib/generators/graphql/templates/scalar.erb +5 -1
  44. data/lib/generators/graphql/templates/schema.erb +23 -28
  45. data/lib/generators/graphql/templates/union.erb +6 -2
  46. data/lib/generators/graphql/type_generator.rb +47 -10
  47. data/lib/generators/graphql/union_generator.rb +5 -5
  48. data/lib/graphql/analysis/analyze_query.rb +7 -0
  49. data/lib/graphql/analysis/ast/analyzer.rb +34 -12
  50. data/lib/graphql/analysis/ast/field_usage.rb +29 -2
  51. data/lib/graphql/analysis/ast/max_query_complexity.rb +3 -3
  52. data/lib/graphql/analysis/ast/max_query_depth.rb +7 -3
  53. data/lib/graphql/analysis/ast/query_complexity.rb +179 -64
  54. data/lib/graphql/analysis/ast/query_depth.rb +16 -26
  55. data/lib/graphql/analysis/ast/visitor.rb +46 -32
  56. data/lib/graphql/analysis/ast.rb +23 -14
  57. data/lib/graphql/analysis/query_depth.rb +4 -17
  58. data/lib/graphql/argument.rb +16 -38
  59. data/lib/graphql/backtrace/inspect_result.rb +0 -1
  60. data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
  61. data/lib/graphql/backtrace/table.rb +44 -5
  62. data/lib/graphql/backtrace/traced_error.rb +0 -1
  63. data/lib/graphql/backtrace/tracer.rb +40 -9
  64. data/lib/graphql/backtrace.rb +28 -19
  65. data/lib/graphql/backwards_compatibility.rb +2 -1
  66. data/lib/graphql/base_type.rb +11 -5
  67. data/lib/graphql/boolean_type.rb +1 -1
  68. data/lib/graphql/coercion_error.rb +8 -0
  69. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +2 -2
  70. data/lib/graphql/compatibility/execution_specification.rb +1 -0
  71. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +1 -1
  72. data/lib/graphql/compatibility/lazy_execution_specification.rb +2 -0
  73. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +5 -9
  74. data/lib/graphql/compatibility/query_parser_specification.rb +2 -0
  75. data/lib/graphql/compatibility/schema_parser_specification.rb +2 -0
  76. data/lib/graphql/dataloader/null_dataloader.rb +22 -0
  77. data/lib/graphql/dataloader/request.rb +19 -0
  78. data/lib/graphql/dataloader/request_all.rb +19 -0
  79. data/lib/graphql/dataloader/source.rb +155 -0
  80. data/lib/graphql/dataloader.rb +308 -0
  81. data/lib/graphql/date_encoding_error.rb +16 -0
  82. data/lib/graphql/define/assign_enum_value.rb +1 -1
  83. data/lib/graphql/define/assign_global_id_field.rb +2 -2
  84. data/lib/graphql/define/assign_object_field.rb +3 -3
  85. data/lib/graphql/define/defined_object_proxy.rb +3 -0
  86. data/lib/graphql/define/instance_definable.rb +65 -110
  87. data/lib/graphql/define/type_definer.rb +5 -5
  88. data/lib/graphql/deprecated_dsl.rb +18 -5
  89. data/lib/graphql/deprecation.rb +9 -0
  90. data/lib/graphql/directive/deprecated_directive.rb +1 -12
  91. data/lib/graphql/directive/include_directive.rb +1 -1
  92. data/lib/graphql/directive/skip_directive.rb +1 -1
  93. data/lib/graphql/directive.rb +9 -6
  94. data/lib/graphql/enum_type.rb +14 -74
  95. data/lib/graphql/execution/directive_checks.rb +2 -2
  96. data/lib/graphql/execution/errors.rb +163 -0
  97. data/lib/graphql/execution/execute.rb +10 -3
  98. data/lib/graphql/execution/instrumentation.rb +1 -1
  99. data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
  100. data/lib/graphql/execution/interpreter/arguments.rb +88 -0
  101. data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
  102. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  103. data/lib/graphql/execution/interpreter/resolve.rb +37 -25
  104. data/lib/graphql/execution/interpreter/runtime.rb +737 -376
  105. data/lib/graphql/execution/interpreter.rb +42 -19
  106. data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
  107. data/lib/graphql/execution/lazy.rb +5 -1
  108. data/lib/graphql/execution/lookahead.rb +39 -114
  109. data/lib/graphql/execution/multiplex.rb +58 -29
  110. data/lib/graphql/execution.rb +1 -0
  111. data/lib/graphql/execution_error.rb +3 -2
  112. data/lib/graphql/field.rb +15 -119
  113. data/lib/graphql/filter.rb +1 -1
  114. data/lib/graphql/float_type.rb +1 -1
  115. data/lib/graphql/function.rb +6 -31
  116. data/lib/graphql/id_type.rb +1 -1
  117. data/lib/graphql/input_object_type.rb +11 -26
  118. data/lib/graphql/int_type.rb +1 -1
  119. data/lib/graphql/integer_decoding_error.rb +17 -0
  120. data/lib/graphql/integer_encoding_error.rb +18 -2
  121. data/lib/graphql/interface_type.rb +10 -24
  122. data/lib/graphql/internal_representation/document.rb +2 -2
  123. data/lib/graphql/internal_representation/rewrite.rb +1 -1
  124. data/lib/graphql/internal_representation/scope.rb +2 -2
  125. data/lib/graphql/internal_representation/visit.rb +2 -2
  126. data/lib/graphql/introspection/base_object.rb +2 -5
  127. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  128. data/lib/graphql/introspection/directive_type.rb +12 -6
  129. data/lib/graphql/introspection/entry_points.rb +9 -8
  130. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  131. data/lib/graphql/introspection/field_type.rb +9 -5
  132. data/lib/graphql/introspection/input_value_type.rb +41 -11
  133. data/lib/graphql/introspection/introspection_query.rb +6 -92
  134. data/lib/graphql/introspection/schema_type.rb +13 -12
  135. data/lib/graphql/introspection/type_type.rb +27 -17
  136. data/lib/graphql/introspection.rb +99 -0
  137. data/lib/graphql/invalid_null_error.rb +18 -0
  138. data/lib/graphql/language/block_string.rb +22 -7
  139. data/lib/graphql/language/cache.rb +37 -0
  140. data/lib/graphql/language/definition_slice.rb +21 -10
  141. data/lib/graphql/language/document_from_schema_definition.rb +126 -67
  142. data/lib/graphql/language/lexer.rb +180 -141
  143. data/lib/graphql/language/lexer.rl +75 -51
  144. data/lib/graphql/language/nodes.rb +92 -108
  145. data/lib/graphql/language/parser.rb +933 -897
  146. data/lib/graphql/language/parser.y +129 -103
  147. data/lib/graphql/language/printer.rb +11 -2
  148. data/lib/graphql/language/sanitized_printer.rb +222 -0
  149. data/lib/graphql/language/token.rb +1 -1
  150. data/lib/graphql/language/visitor.rb +11 -8
  151. data/lib/graphql/language.rb +3 -1
  152. data/lib/graphql/name_validator.rb +2 -7
  153. data/lib/graphql/non_null_type.rb +0 -10
  154. data/lib/graphql/object_type.rb +47 -58
  155. data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
  156. data/lib/graphql/pagination/array_connection.rb +77 -0
  157. data/lib/graphql/pagination/connection.rb +226 -0
  158. data/lib/graphql/pagination/connections.rb +160 -0
  159. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  160. data/lib/graphql/pagination/relation_connection.rb +226 -0
  161. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  162. data/lib/graphql/pagination.rb +6 -0
  163. data/lib/graphql/parse_error.rb +0 -1
  164. data/lib/graphql/query/arguments.rb +29 -19
  165. data/lib/graphql/query/arguments_cache.rb +1 -2
  166. data/lib/graphql/query/context.rb +81 -14
  167. data/lib/graphql/query/executor.rb +0 -1
  168. data/lib/graphql/query/fingerprint.rb +26 -0
  169. data/lib/graphql/query/input_validation_result.rb +32 -6
  170. data/lib/graphql/query/literal_input.rb +31 -10
  171. data/lib/graphql/query/null_context.rb +28 -8
  172. data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
  173. data/lib/graphql/query/serial_execution.rb +1 -0
  174. data/lib/graphql/query/validation_pipeline.rb +6 -4
  175. data/lib/graphql/query/variable_validation_error.rb +3 -3
  176. data/lib/graphql/query/variables.rb +51 -9
  177. data/lib/graphql/query.rb +97 -23
  178. data/lib/graphql/railtie.rb +9 -1
  179. data/lib/graphql/rake_task/validate.rb +3 -0
  180. data/lib/graphql/rake_task.rb +12 -9
  181. data/lib/graphql/relay/array_connection.rb +11 -13
  182. data/lib/graphql/relay/base_connection.rb +33 -16
  183. data/lib/graphql/relay/connection_instrumentation.rb +4 -4
  184. data/lib/graphql/relay/connection_type.rb +18 -4
  185. data/lib/graphql/relay/edge_type.rb +1 -0
  186. data/lib/graphql/relay/edges_instrumentation.rb +1 -2
  187. data/lib/graphql/relay/global_id_resolve.rb +1 -2
  188. data/lib/graphql/relay/mutation.rb +3 -87
  189. data/lib/graphql/relay/node.rb +5 -2
  190. data/lib/graphql/relay/page_info.rb +1 -1
  191. data/lib/graphql/relay/range_add.rb +27 -9
  192. data/lib/graphql/relay/relation_connection.rb +17 -15
  193. data/lib/graphql/relay/type_extensions.rb +2 -0
  194. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  195. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  196. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  197. data/lib/graphql/rubocop.rb +4 -0
  198. data/lib/graphql/scalar_type.rb +18 -62
  199. data/lib/graphql/schema/addition.rb +247 -0
  200. data/lib/graphql/schema/argument.rb +289 -11
  201. data/lib/graphql/schema/base_64_bp.rb +3 -2
  202. data/lib/graphql/schema/base_64_encoder.rb +2 -0
  203. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  204. data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
  205. data/lib/graphql/schema/build_from_definition.rb +323 -203
  206. data/lib/graphql/schema/built_in_types.rb +5 -5
  207. data/lib/graphql/schema/default_type_error.rb +2 -0
  208. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  209. data/lib/graphql/schema/directive/feature.rb +2 -2
  210. data/lib/graphql/schema/directive/flagged.rb +57 -0
  211. data/lib/graphql/schema/directive/include.rb +2 -2
  212. data/lib/graphql/schema/directive/skip.rb +2 -2
  213. data/lib/graphql/schema/directive/transform.rb +14 -2
  214. data/lib/graphql/schema/directive.rb +136 -6
  215. data/lib/graphql/schema/enum.rb +121 -12
  216. data/lib/graphql/schema/enum_value.rb +23 -6
  217. data/lib/graphql/schema/field/connection_extension.rb +46 -20
  218. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  219. data/lib/graphql/schema/field.rb +515 -191
  220. data/lib/graphql/schema/field_extension.rb +89 -2
  221. data/lib/graphql/schema/find_inherited_value.rb +36 -0
  222. data/lib/graphql/schema/finder.rb +16 -14
  223. data/lib/graphql/schema/input_object.rb +178 -34
  224. data/lib/graphql/schema/interface.rb +35 -25
  225. data/lib/graphql/schema/introspection_system.rb +111 -35
  226. data/lib/graphql/schema/late_bound_type.rb +3 -2
  227. data/lib/graphql/schema/list.rb +65 -1
  228. data/lib/graphql/schema/loader.rb +147 -97
  229. data/lib/graphql/schema/member/accepts_definition.rb +15 -3
  230. data/lib/graphql/schema/member/base_dsl_methods.rb +40 -45
  231. data/lib/graphql/schema/member/build_type.rb +19 -8
  232. data/lib/graphql/schema/member/cached_graphql_definition.rb +34 -2
  233. data/lib/graphql/schema/member/has_arguments.rb +212 -22
  234. data/lib/graphql/schema/member/has_ast_node.rb +20 -0
  235. data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
  236. data/lib/graphql/schema/member/has_directives.rb +98 -0
  237. data/lib/graphql/schema/member/has_fields.rb +113 -28
  238. data/lib/graphql/schema/member/has_interfaces.rb +100 -0
  239. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  240. data/lib/graphql/schema/member/has_validators.rb +31 -0
  241. data/lib/graphql/schema/member/instrumentation.rb +6 -2
  242. data/lib/graphql/schema/member/relay_shortcuts.rb +2 -2
  243. data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
  244. data/lib/graphql/schema/member/validates_input.rb +33 -0
  245. data/lib/graphql/schema/member.rb +11 -0
  246. data/lib/graphql/schema/middleware_chain.rb +1 -1
  247. data/lib/graphql/schema/mutation.rb +5 -1
  248. data/lib/graphql/schema/non_null.rb +37 -1
  249. data/lib/graphql/schema/object.rb +52 -37
  250. data/lib/graphql/schema/possible_types.rb +12 -7
  251. data/lib/graphql/schema/printer.rb +17 -34
  252. data/lib/graphql/schema/relay_classic_mutation.rb +51 -7
  253. data/lib/graphql/schema/resolver/has_payload_type.rb +36 -5
  254. data/lib/graphql/schema/resolver.rb +159 -59
  255. data/lib/graphql/schema/scalar.rb +43 -3
  256. data/lib/graphql/schema/subscription.rb +83 -25
  257. data/lib/graphql/schema/timeout.rb +123 -0
  258. data/lib/graphql/schema/timeout_middleware.rb +6 -3
  259. data/lib/graphql/schema/traversal.rb +2 -2
  260. data/lib/graphql/schema/type_expression.rb +21 -13
  261. data/lib/graphql/schema/type_membership.rb +48 -0
  262. data/lib/graphql/schema/union.rb +67 -6
  263. data/lib/graphql/schema/unique_within_type.rb +1 -2
  264. data/lib/graphql/schema/validation.rb +30 -8
  265. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  266. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  267. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  268. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  269. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  270. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  271. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  272. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  273. data/lib/graphql/schema/validator.rb +171 -0
  274. data/lib/graphql/schema/warden.rb +263 -30
  275. data/lib/graphql/schema/wrapper.rb +1 -1
  276. data/lib/graphql/schema.rb +1016 -256
  277. data/lib/graphql/static_validation/all_rules.rb +2 -0
  278. data/lib/graphql/static_validation/base_visitor.rb +17 -10
  279. data/lib/graphql/static_validation/definition_dependencies.rb +21 -13
  280. data/lib/graphql/static_validation/error.rb +3 -1
  281. data/lib/graphql/static_validation/literal_validator.rb +52 -27
  282. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +46 -79
  283. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +23 -6
  284. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
  285. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
  286. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
  287. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -2
  288. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
  289. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
  290. data/lib/graphql/static_validation/rules/fields_will_merge.rb +105 -55
  291. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  292. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  293. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  294. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  295. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  296. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  297. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  298. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +5 -3
  299. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +9 -10
  300. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
  301. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
  302. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
  303. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  304. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
  305. data/lib/graphql/static_validation/type_stack.rb +2 -2
  306. data/lib/graphql/static_validation/validation_context.rb +13 -3
  307. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  308. data/lib/graphql/static_validation/validator.rb +43 -9
  309. data/lib/graphql/static_validation.rb +1 -0
  310. data/lib/graphql/string_encoding_error.rb +13 -3
  311. data/lib/graphql/string_type.rb +1 -1
  312. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +123 -22
  313. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  314. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
  315. data/lib/graphql/subscriptions/event.rb +94 -26
  316. data/lib/graphql/subscriptions/instrumentation.rb +10 -6
  317. data/lib/graphql/subscriptions/serialize.rb +53 -6
  318. data/lib/graphql/subscriptions/subscription_root.rb +15 -5
  319. data/lib/graphql/subscriptions.rb +122 -54
  320. data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
  321. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  322. data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
  323. data/lib/graphql/tracing/data_dog_tracing.rb +32 -2
  324. data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
  325. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  326. data/lib/graphql/tracing/platform_tracing.rb +66 -7
  327. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
  328. data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
  329. data/lib/graphql/tracing/scout_tracing.rb +19 -0
  330. data/lib/graphql/tracing/skylight_tracing.rb +9 -0
  331. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  332. data/lib/graphql/tracing.rb +15 -35
  333. data/lib/graphql/types/big_int.rb +5 -1
  334. data/lib/graphql/types/int.rb +10 -3
  335. data/lib/graphql/types/iso_8601_date.rb +42 -0
  336. data/lib/graphql/types/iso_8601_date_time.rb +32 -8
  337. data/lib/graphql/types/relay/base_connection.rb +6 -88
  338. data/lib/graphql/types/relay/base_edge.rb +2 -37
  339. data/lib/graphql/types/relay/connection_behaviors.rb +174 -0
  340. data/lib/graphql/types/relay/default_relay.rb +31 -0
  341. data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
  342. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  343. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  344. data/lib/graphql/types/relay/node.rb +2 -4
  345. data/lib/graphql/types/relay/node_behaviors.rb +15 -0
  346. data/lib/graphql/types/relay/node_field.rb +4 -23
  347. data/lib/graphql/types/relay/nodes_field.rb +16 -18
  348. data/lib/graphql/types/relay/page_info.rb +2 -14
  349. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  350. data/lib/graphql/types/relay.rb +11 -3
  351. data/lib/graphql/types/string.rb +8 -2
  352. data/lib/graphql/types.rb +1 -0
  353. data/lib/graphql/unauthorized_error.rb +2 -2
  354. data/lib/graphql/union_type.rb +61 -46
  355. data/lib/graphql/unresolved_type_error.rb +2 -2
  356. data/lib/graphql/upgrader/member.rb +150 -112
  357. data/lib/graphql/upgrader/schema.rb +1 -0
  358. data/lib/graphql/version.rb +1 -1
  359. data/lib/graphql.rb +89 -18
  360. data/readme.md +4 -7
  361. metadata +115 -703
  362. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
  363. data/lib/graphql/literal_validation_error.rb +0 -6
  364. data/lib/graphql/types/relay/base_field.rb +0 -22
  365. data/lib/graphql/types/relay/base_interface.rb +0 -29
  366. data/lib/graphql/types/relay/base_object.rb +0 -26
  367. data/spec/dummy/Gemfile +0 -12
  368. data/spec/dummy/Gemfile.lock +0 -157
  369. data/spec/dummy/README.md +0 -24
  370. data/spec/dummy/Rakefile +0 -7
  371. data/spec/dummy/app/assets/config/manifest.js +0 -1
  372. data/spec/dummy/app/assets/javascripts/application.js +0 -66
  373. data/spec/dummy/app/channels/application_cable/channel.rb +0 -5
  374. data/spec/dummy/app/channels/application_cable/connection.rb +0 -5
  375. data/spec/dummy/app/channels/graphql_channel.rb +0 -116
  376. data/spec/dummy/app/controllers/application_controller.rb +0 -4
  377. data/spec/dummy/app/controllers/pages_controller.rb +0 -5
  378. data/spec/dummy/app/helpers/application_helper.rb +0 -3
  379. data/spec/dummy/app/jobs/application_job.rb +0 -3
  380. data/spec/dummy/app/views/layouts/application.html.erb +0 -12
  381. data/spec/dummy/app/views/pages/show.html +0 -16
  382. data/spec/dummy/bin/bundle +0 -4
  383. data/spec/dummy/bin/rails +0 -5
  384. data/spec/dummy/bin/rake +0 -5
  385. data/spec/dummy/bin/setup +0 -31
  386. data/spec/dummy/bin/update +0 -27
  387. data/spec/dummy/bin/yarn +0 -12
  388. data/spec/dummy/config/application.rb +0 -30
  389. data/spec/dummy/config/boot.rb +0 -4
  390. data/spec/dummy/config/cable.yml +0 -10
  391. data/spec/dummy/config/environment.rb +0 -6
  392. data/spec/dummy/config/environments/development.rb +0 -40
  393. data/spec/dummy/config/environments/production.rb +0 -76
  394. data/spec/dummy/config/environments/test.rb +0 -37
  395. data/spec/dummy/config/initializers/application_controller_renderer.rb +0 -9
  396. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -8
  397. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -6
  398. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -5
  399. data/spec/dummy/config/initializers/inflections.rb +0 -17
  400. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  401. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -10
  402. data/spec/dummy/config/locales/en.yml +0 -33
  403. data/spec/dummy/config/puma.rb +0 -57
  404. data/spec/dummy/config/routes.rb +0 -4
  405. data/spec/dummy/config/secrets.yml +0 -32
  406. data/spec/dummy/config.ru +0 -6
  407. data/spec/dummy/log/test.log +0 -199
  408. data/spec/dummy/package.json +0 -5
  409. data/spec/dummy/public/404.html +0 -67
  410. data/spec/dummy/public/422.html +0 -67
  411. data/spec/dummy/public/500.html +0 -66
  412. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  413. data/spec/dummy/public/apple-touch-icon.png +0 -0
  414. data/spec/dummy/public/favicon.ico +0 -0
  415. data/spec/dummy/public/robots.txt +0 -1
  416. data/spec/dummy/test/application_system_test_case.rb +0 -6
  417. data/spec/dummy/test/system/action_cable_subscription_test.rb +0 -45
  418. data/spec/dummy/test/test_helper.rb +0 -4
  419. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4w/4wzXRZrAkwKdgYaSE0pid5eB-fer8vSfSku_NPg4rMA.cache +0 -0
  420. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7I/7IHVBiJT06QSpgLpLoJIxboQ0B-D_tMTxsvoezBTV3Q.cache +0 -1
  421. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8w/8wY_SKagj8wHuwGNAAf6JnQ8joMbC6cEYpHrTAI8Urc.cache +0 -1
  422. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AK/AKzz1u6bGb4auXcrObA_g5LL-oV0ejNGa448AgAi_WQ.cache +0 -1
  423. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ET/ETW4uxvaYpruL8y6_ZptUH82ZowMaHIqvg5WexBFdEM.cache +0 -3
  424. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F1/F1TWpjjyA56k9Z90n5B3xRn7DUdGjX73QCkYC6k07JQ.cache +0 -0
  425. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +0 -2
  426. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +0 -2
  427. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ms/MsKSimH_UCB-H1tLvDABDHuvGciuoW6kVqQWDrXU5FQ.cache +0 -0
  428. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mt/Mtci-Kim50aPOmeClD4AIicKn1d1WJ0n454IjSd94sk.cache +0 -0
  429. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QH/QHt3Tc1Y6M66Oo_pDuMyWrQNs4Pp3SMeZR5K1wJj2Ts.cache +0 -1
  430. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/XU/XU4k1OXnfMils5SrirorPvDSyDSqiOWLZNtmAH1HH8k.cache +0 -0
  431. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ZI/ZIof7mZxWWCnraIFOCuV6a8QRWzKJXJnx2Xd7C0ZyX0.cache +0 -1
  432. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cG/cGc_puuPS5pZKgUcy1Y_i1L6jl5UtsiIrMH59rTzR6c.cache +0 -3
  433. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/df/dfro_B6bx3KP1Go-7jEOqqZ2j4hVRseXIc3es9PKQno.cache +0 -1
  434. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jO/jO1DfbqnG0mTULsjJJANc3fefrG2zt7DIMmcptMT628.cache +0 -1
  435. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pE/pE7gO6pQ-z187Swb4hT554wmqsq-cNzgPWLrCz-LQQQ.cache +0 -0
  436. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/r9/r9iU1l58a6rxkZSW5RSC52_tD-_UQuHxoMVnkfJ7Mhs.cache +0 -1
  437. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xi/xitPPFfPIyDMpaznV0sBBcw8eSCV8PJcLLWin78sCgE.cache +0 -0
  438. data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
  439. data/spec/fixtures/upgrader/account.original.rb +0 -19
  440. data/spec/fixtures/upgrader/account.transformed.rb +0 -20
  441. data/spec/fixtures/upgrader/blame_range.original.rb +0 -43
  442. data/spec/fixtures/upgrader/blame_range.transformed.rb +0 -30
  443. data/spec/fixtures/upgrader/date_time.original.rb +0 -24
  444. data/spec/fixtures/upgrader/date_time.transformed.rb +0 -23
  445. data/spec/fixtures/upgrader/delete_project.original.rb +0 -28
  446. data/spec/fixtures/upgrader/delete_project.transformed.rb +0 -27
  447. data/spec/fixtures/upgrader/gist_order_field.original.rb +0 -14
  448. data/spec/fixtures/upgrader/gist_order_field.transformed.rb +0 -13
  449. data/spec/fixtures/upgrader/increment_count.original.rb +0 -59
  450. data/spec/fixtures/upgrader/increment_count.transformed.rb +0 -50
  451. data/spec/fixtures/upgrader/photo.original.rb +0 -10
  452. data/spec/fixtures/upgrader/photo.transformed.rb +0 -12
  453. data/spec/fixtures/upgrader/release_order.original.rb +0 -15
  454. data/spec/fixtures/upgrader/release_order.transformed.rb +0 -14
  455. data/spec/fixtures/upgrader/starrable.original.rb +0 -49
  456. data/spec/fixtures/upgrader/starrable.transformed.rb +0 -46
  457. data/spec/fixtures/upgrader/subscribable.original.rb +0 -55
  458. data/spec/fixtures/upgrader/subscribable.transformed.rb +0 -51
  459. data/spec/fixtures/upgrader/type_x.original.rb +0 -65
  460. data/spec/fixtures/upgrader/type_x.transformed.rb +0 -56
  461. data/spec/graphql/analysis/analyze_query_spec.rb +0 -272
  462. data/spec/graphql/analysis/ast/field_usage_spec.rb +0 -51
  463. data/spec/graphql/analysis/ast/max_query_complexity_spec.rb +0 -120
  464. data/spec/graphql/analysis/ast/max_query_depth_spec.rb +0 -114
  465. data/spec/graphql/analysis/ast/query_complexity_spec.rb +0 -299
  466. data/spec/graphql/analysis/ast/query_depth_spec.rb +0 -108
  467. data/spec/graphql/analysis/ast_spec.rb +0 -269
  468. data/spec/graphql/analysis/field_usage_spec.rb +0 -62
  469. data/spec/graphql/analysis/max_query_complexity_spec.rb +0 -102
  470. data/spec/graphql/analysis/max_query_depth_spec.rb +0 -101
  471. data/spec/graphql/analysis/query_complexity_spec.rb +0 -301
  472. data/spec/graphql/analysis/query_depth_spec.rb +0 -81
  473. data/spec/graphql/argument_spec.rb +0 -159
  474. data/spec/graphql/authorization_spec.rb +0 -974
  475. data/spec/graphql/backtrace_spec.rb +0 -206
  476. data/spec/graphql/base_type_spec.rb +0 -171
  477. data/spec/graphql/boolean_type_spec.rb +0 -21
  478. data/spec/graphql/compatibility/execution_specification_spec.rb +0 -4
  479. data/spec/graphql/compatibility/lazy_execution_specification_spec.rb +0 -4
  480. data/spec/graphql/compatibility/query_parser_specification_spec.rb +0 -6
  481. data/spec/graphql/compatibility/schema_parser_specification_spec.rb +0 -6
  482. data/spec/graphql/define/assign_argument_spec.rb +0 -61
  483. data/spec/graphql/define/instance_definable_spec.rb +0 -203
  484. data/spec/graphql/directive/skip_directive_spec.rb +0 -9
  485. data/spec/graphql/directive_spec.rb +0 -295
  486. data/spec/graphql/enum_type_spec.rb +0 -158
  487. data/spec/graphql/execution/execute_spec.rb +0 -303
  488. data/spec/graphql/execution/instrumentation_spec.rb +0 -184
  489. data/spec/graphql/execution/interpreter_spec.rb +0 -485
  490. data/spec/graphql/execution/lazy/lazy_method_map_spec.rb +0 -57
  491. data/spec/graphql/execution/lazy_spec.rb +0 -247
  492. data/spec/graphql/execution/lookahead_spec.rb +0 -390
  493. data/spec/graphql/execution/multiplex_spec.rb +0 -211
  494. data/spec/graphql/execution/typecast_spec.rb +0 -47
  495. data/spec/graphql/execution_error_spec.rb +0 -325
  496. data/spec/graphql/field_spec.rb +0 -246
  497. data/spec/graphql/float_type_spec.rb +0 -16
  498. data/spec/graphql/function_spec.rb +0 -152
  499. data/spec/graphql/id_type_spec.rb +0 -33
  500. data/spec/graphql/input_object_type_spec.rb +0 -25
  501. data/spec/graphql/int_type_spec.rb +0 -35
  502. data/spec/graphql/interface_type_spec.rb +0 -196
  503. data/spec/graphql/internal_representation/print_spec.rb +0 -41
  504. data/spec/graphql/internal_representation/rewrite_spec.rb +0 -376
  505. data/spec/graphql/introspection/directive_type_spec.rb +0 -61
  506. data/spec/graphql/introspection/input_value_type_spec.rb +0 -144
  507. data/spec/graphql/introspection/introspection_query_spec.rb +0 -59
  508. data/spec/graphql/introspection/schema_type_spec.rb +0 -56
  509. data/spec/graphql/introspection/type_type_spec.rb +0 -155
  510. data/spec/graphql/language/block_string_spec.rb +0 -70
  511. data/spec/graphql/language/definition_slice_spec.rb +0 -226
  512. data/spec/graphql/language/document_from_schema_definition_spec.rb +0 -770
  513. data/spec/graphql/language/equality_spec.rb +0 -84
  514. data/spec/graphql/language/generation_spec.rb +0 -38
  515. data/spec/graphql/language/lexer_spec.rb +0 -135
  516. data/spec/graphql/language/nodes_spec.rb +0 -67
  517. data/spec/graphql/language/parser_spec.rb +0 -183
  518. data/spec/graphql/language/printer_spec.rb +0 -215
  519. data/spec/graphql/language/visitor_spec.rb +0 -419
  520. data/spec/graphql/list_type_spec.rb +0 -57
  521. data/spec/graphql/non_null_type_spec.rb +0 -48
  522. data/spec/graphql/object_type_spec.rb +0 -197
  523. data/spec/graphql/query/arguments_spec.rb +0 -346
  524. data/spec/graphql/query/context_spec.rb +0 -292
  525. data/spec/graphql/query/executor_spec.rb +0 -341
  526. data/spec/graphql/query/literal_input_spec.rb +0 -91
  527. data/spec/graphql/query/result_spec.rb +0 -29
  528. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +0 -109
  529. data/spec/graphql/query_spec.rb +0 -800
  530. data/spec/graphql/rake_task_spec.rb +0 -59
  531. data/spec/graphql/scalar_type_spec.rb +0 -66
  532. data/spec/graphql/schema/argument_spec.rb +0 -152
  533. data/spec/graphql/schema/build_from_definition_spec.rb +0 -1187
  534. data/spec/graphql/schema/catchall_middleware_spec.rb +0 -35
  535. data/spec/graphql/schema/directive/feature_spec.rb +0 -81
  536. data/spec/graphql/schema/directive/transform_spec.rb +0 -39
  537. data/spec/graphql/schema/enum_spec.rb +0 -83
  538. data/spec/graphql/schema/enum_value_spec.rb +0 -24
  539. data/spec/graphql/schema/field_extension_spec.rb +0 -137
  540. data/spec/graphql/schema/field_spec.rb +0 -301
  541. data/spec/graphql/schema/finder_spec.rb +0 -135
  542. data/spec/graphql/schema/input_object_spec.rb +0 -347
  543. data/spec/graphql/schema/instrumentation_spec.rb +0 -43
  544. data/spec/graphql/schema/interface_spec.rb +0 -215
  545. data/spec/graphql/schema/introspection_system_spec.rb +0 -56
  546. data/spec/graphql/schema/list_spec.rb +0 -46
  547. data/spec/graphql/schema/loader_spec.rb +0 -286
  548. data/spec/graphql/schema/member/accepts_definition_spec.rb +0 -115
  549. data/spec/graphql/schema/member/build_type_spec.rb +0 -63
  550. data/spec/graphql/schema/member/scoped_spec.rb +0 -217
  551. data/spec/graphql/schema/member/type_system_helpers_spec.rb +0 -63
  552. data/spec/graphql/schema/middleware_chain_spec.rb +0 -57
  553. data/spec/graphql/schema/mutation_spec.rb +0 -150
  554. data/spec/graphql/schema/non_null_spec.rb +0 -46
  555. data/spec/graphql/schema/object_spec.rb +0 -315
  556. data/spec/graphql/schema/printer_spec.rb +0 -869
  557. data/spec/graphql/schema/relay_classic_mutation_spec.rb +0 -252
  558. data/spec/graphql/schema/rescue_middleware_spec.rb +0 -88
  559. data/spec/graphql/schema/resolver_spec.rb +0 -714
  560. data/spec/graphql/schema/scalar_spec.rb +0 -101
  561. data/spec/graphql/schema/subscription_spec.rb +0 -440
  562. data/spec/graphql/schema/timeout_middleware_spec.rb +0 -188
  563. data/spec/graphql/schema/traversal_spec.rb +0 -222
  564. data/spec/graphql/schema/type_expression_spec.rb +0 -39
  565. data/spec/graphql/schema/union_spec.rb +0 -72
  566. data/spec/graphql/schema/unique_within_type_spec.rb +0 -44
  567. data/spec/graphql/schema/validation_spec.rb +0 -355
  568. data/spec/graphql/schema/warden_spec.rb +0 -926
  569. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +0 -413
  570. data/spec/graphql/static_validation/rules/argument_names_are_unique_spec.rb +0 -44
  571. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +0 -112
  572. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +0 -35
  573. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +0 -42
  574. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +0 -167
  575. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +0 -66
  576. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +0 -740
  577. data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +0 -28
  578. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +0 -52
  579. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +0 -42
  580. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +0 -123
  581. data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +0 -24
  582. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +0 -56
  583. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +0 -61
  584. data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +0 -39
  585. data/spec/graphql/static_validation/rules/no_definitions_are_present_spec.rb +0 -62
  586. data/spec/graphql/static_validation/rules/operation_names_are_valid_spec.rb +0 -82
  587. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +0 -73
  588. data/spec/graphql/static_validation/rules/required_input_object_attributes_are_present_spec.rb +0 -86
  589. data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +0 -34
  590. data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +0 -188
  591. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +0 -196
  592. data/spec/graphql/static_validation/rules/variable_names_are_unique_spec.rb +0 -23
  593. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +0 -236
  594. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +0 -78
  595. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +0 -81
  596. data/spec/graphql/static_validation/type_stack_spec.rb +0 -29
  597. data/spec/graphql/static_validation/validator_spec.rb +0 -204
  598. data/spec/graphql/string_type_spec.rb +0 -80
  599. data/spec/graphql/subscriptions/serialize_spec.rb +0 -49
  600. data/spec/graphql/subscriptions_spec.rb +0 -540
  601. data/spec/graphql/tracing/new_relic_tracing_spec.rb +0 -84
  602. data/spec/graphql/tracing/platform_tracing_spec.rb +0 -141
  603. data/spec/graphql/tracing/prometheus_tracing_spec.rb +0 -42
  604. data/spec/graphql/tracing/scout_tracing_spec.rb +0 -17
  605. data/spec/graphql/tracing/skylight_tracing_spec.rb +0 -63
  606. data/spec/graphql/tracing_spec.rb +0 -52
  607. data/spec/graphql/types/big_int_spec.rb +0 -24
  608. data/spec/graphql/types/iso_8601_date_time_spec.rb +0 -137
  609. data/spec/graphql/types/relay/base_edge_spec.rb +0 -33
  610. data/spec/graphql/union_type_spec.rb +0 -211
  611. data/spec/graphql/upgrader/member_spec.rb +0 -583
  612. data/spec/graphql/upgrader/schema_spec.rb +0 -82
  613. data/spec/integration/mongoid/graphql/relay/mongo_relation_connection_spec.rb +0 -528
  614. data/spec/integration/mongoid/spec_helper.rb +0 -2
  615. data/spec/integration/mongoid/star_trek/data.rb +0 -126
  616. data/spec/integration/mongoid/star_trek/schema.rb +0 -425
  617. data/spec/integration/rails/data.rb +0 -110
  618. data/spec/integration/rails/generators/base_generator_test.rb +0 -7
  619. data/spec/integration/rails/generators/graphql/enum_generator_spec.rb +0 -30
  620. data/spec/integration/rails/generators/graphql/install_generator_spec.rb +0 -218
  621. data/spec/integration/rails/generators/graphql/interface_generator_spec.rb +0 -34
  622. data/spec/integration/rails/generators/graphql/loader_generator_spec.rb +0 -59
  623. data/spec/integration/rails/generators/graphql/mutation_generator_spec.rb +0 -71
  624. data/spec/integration/rails/generators/graphql/object_generator_spec.rb +0 -54
  625. data/spec/integration/rails/generators/graphql/scalar_generator_spec.rb +0 -28
  626. data/spec/integration/rails/generators/graphql/union_generator_spec.rb +0 -67
  627. data/spec/integration/rails/graphql/input_object_type_spec.rb +0 -364
  628. data/spec/integration/rails/graphql/query/variables_spec.rb +0 -375
  629. data/spec/integration/rails/graphql/relay/array_connection_spec.rb +0 -290
  630. data/spec/integration/rails/graphql/relay/base_connection_spec.rb +0 -101
  631. data/spec/integration/rails/graphql/relay/connection_instrumentation_spec.rb +0 -80
  632. data/spec/integration/rails/graphql/relay/connection_resolve_spec.rb +0 -79
  633. data/spec/integration/rails/graphql/relay/connection_type_spec.rb +0 -106
  634. data/spec/integration/rails/graphql/relay/edge_spec.rb +0 -10
  635. data/spec/integration/rails/graphql/relay/mutation_spec.rb +0 -387
  636. data/spec/integration/rails/graphql/relay/node_spec.rb +0 -263
  637. data/spec/integration/rails/graphql/relay/page_info_spec.rb +0 -111
  638. data/spec/integration/rails/graphql/relay/range_add_spec.rb +0 -117
  639. data/spec/integration/rails/graphql/relay/relation_connection_spec.rb +0 -837
  640. data/spec/integration/rails/graphql/schema_spec.rb +0 -489
  641. data/spec/integration/rails/graphql/tracing/active_support_notifications_tracing_spec.rb +0 -62
  642. data/spec/integration/rails/spec_helper.rb +0 -25
  643. data/spec/integration/tmp/app/graphql/types/bird_type.rb +0 -7
  644. data/spec/spec_helper.rb +0 -116
  645. data/spec/support/dummy/data.rb +0 -45
  646. data/spec/support/dummy/schema.rb +0 -511
  647. data/spec/support/error_bubbling_helpers.rb +0 -23
  648. data/spec/support/global_id.rb +0 -23
  649. data/spec/support/jazz.rb +0 -772
  650. data/spec/support/lazy_helpers.rb +0 -192
  651. data/spec/support/magic_cards/schema.graphql +0 -33
  652. data/spec/support/minimum_input_object.rb +0 -21
  653. data/spec/support/new_relic.rb +0 -27
  654. data/spec/support/parser/filename_example.graphql +0 -5
  655. data/spec/support/parser/filename_example_error_1.graphql +0 -4
  656. data/spec/support/parser/filename_example_error_2.graphql +0 -5
  657. data/spec/support/skylight.rb +0 -39
  658. data/spec/support/star_wars/schema.rb +0 -465
  659. data/spec/support/static_validation_helpers.rb +0 -32
@@ -1,926 +0,0 @@
1
- # frozen_string_literal: true
2
- require "spec_helper"
3
- include ErrorBubblingHelpers
4
-
5
- module MaskHelpers
6
- class BaseArgument < GraphQL::Schema::Argument
7
- accepts_definition :metadata
8
- end
9
-
10
- class BaseField < GraphQL::Schema::Field
11
- accepts_definition :metadata
12
- argument_class BaseArgument
13
- end
14
-
15
- class BaseObject < GraphQL::Schema::Object
16
- accepts_definition :metadata
17
- field_class BaseField
18
- end
19
-
20
- class BaseEnumValue < GraphQL::Schema::EnumValue
21
- accepts_definition :metadata
22
- end
23
-
24
- class BaseEnum < GraphQL::Schema::Enum
25
- accepts_definition :metadata
26
- enum_value_class BaseEnumValue
27
- end
28
-
29
- class BaseInputObject < GraphQL::Schema::InputObject
30
- accepts_definition :metadata
31
- argument_class BaseArgument
32
- end
33
-
34
- class BaseUnion < GraphQL::Schema::Union
35
- accepts_definition :metadata
36
- end
37
-
38
- module BaseInterface
39
- include GraphQL::Schema::Interface
40
- accepts_definition :metadata
41
- field_class BaseField
42
- end
43
-
44
- class MannerType < BaseEnum
45
- description "Manner of articulation for this sound"
46
- metadata :hidden_input_type, true
47
- value "STOP"
48
- value "AFFRICATE"
49
- value "FRICATIVE"
50
- value "APPROXIMANT"
51
- value "VOWEL"
52
- value "TRILL" do
53
- metadata :hidden_enum_value, true
54
- end
55
- end
56
-
57
- class LanguageType < BaseObject
58
- field :name, String, null: false
59
- field :families, [String], null: false
60
- field :phonemes, "[MaskHelpers::PhonemeType]", null: false
61
- field :graphemes, "[MaskHelpers::GraphemeType]", null: false
62
- end
63
-
64
- module LanguageMemberType
65
- include BaseInterface
66
- metadata :hidden_abstract_type, true
67
- description "Something that belongs to one or more languages"
68
- field :languages, [LanguageType], null: false
69
- end
70
-
71
- class GraphemeType < BaseObject
72
- description "A building block of spelling in a given language"
73
- implements LanguageMemberType
74
-
75
- field :name, String, null: false
76
- field :glyph, String, null: false
77
- field :languages, [LanguageType], null: false
78
- end
79
-
80
- class PhonemeType < BaseObject
81
- description "A building block of sound in a given language"
82
- metadata :hidden_type, true
83
- implements LanguageMemberType
84
-
85
- field :name, String, null: false
86
- field :symbol, String, null: false
87
- field :languages, [LanguageType], null: false
88
- field :manner, MannerType, null: false
89
- end
90
-
91
- class EmicUnitType < BaseUnion
92
- description "A building block of a word in a given language"
93
- possible_types GraphemeType, PhonemeType
94
- end
95
-
96
- class WithinInputType < BaseInputObject
97
- metadata :hidden_input_object_type, true
98
- argument :latitude, Float, required: true
99
- argument :longitude, Float, required: true
100
- argument :miles, Float, required: true do
101
- metadata :hidden_input_field, true
102
- end
103
- end
104
-
105
- class CheremeInput < BaseInputObject
106
- argument :name, String, required: false
107
- end
108
-
109
- class Chereme < BaseObject
110
- description "A basic unit of signed communication"
111
- field :name, String, null: false
112
- end
113
-
114
- class Character < BaseObject
115
- implements LanguageMemberType
116
- field :code, Int, null: false
117
- end
118
-
119
- class QueryType < BaseObject
120
- field :languages, [LanguageType], null: false do
121
- argument :within, WithinInputType, required: false, description: "Find languages nearby a point" do
122
- metadata :hidden_argument_with_input_object, true
123
- end
124
- end
125
-
126
- field :language, LanguageType, null: true do
127
- metadata :hidden_field, true
128
- argument :name, String, required: true do
129
- metadata :hidden_argument, true
130
- end
131
- end
132
-
133
- field :chereme, Chereme, null: false do
134
- metadata :hidden_field, true
135
- end
136
-
137
- field :phonemes, [PhonemeType], null: false do
138
- argument :manners, [MannerType], required: false, description: "Filter phonemes by manner of articulation"
139
- end
140
-
141
- field :phoneme, PhonemeType, null: true do
142
- description "Lookup a phoneme by symbol"
143
- argument :symbol, String, required: true
144
- end
145
-
146
- field :unit, EmicUnitType, null: true do
147
- description "Find an emic unit by its name"
148
- argument :name, String, required: true
149
- end
150
- end
151
-
152
- class MutationType < BaseObject
153
- field :add_phoneme, PhonemeType, null: true do
154
- argument :symbol, String, required: false
155
- end
156
-
157
- field :add_chereme, String, null: true do
158
- argument :chereme, CheremeInput, required: false do
159
- metadata :hidden_argument, true
160
- end
161
- end
162
- end
163
-
164
- module FilterInstrumentation
165
- def self.before_query(query)
166
- if query.context[:filters]
167
- query.merge_filters(
168
- only: query.context[:filters][:only],
169
- except: query.context[:filters][:except],
170
- )
171
- end
172
- end
173
-
174
- def self.after_query(q); end
175
- end
176
-
177
- class Schema < GraphQL::Schema
178
- query QueryType
179
- mutation MutationType
180
- subscription MutationType
181
- orphan_types [Character]
182
- def self.resolve_type(type, obj, ctx)
183
- PhonemeType
184
- end
185
-
186
- instrument :query, FilterInstrumentation
187
- if TESTING_INTERPRETER
188
- use GraphQL::Execution::Interpreter
189
- use GraphQL::Analysis::AST
190
- end
191
- end
192
-
193
- module Data
194
- UVULAR_TRILL = OpenStruct.new({name: "Uvular Trill", symbol: "ʀ", manner: "TRILL"})
195
- def self.unit(name:)
196
- UVULAR_TRILL
197
- end
198
- end
199
-
200
- def self.query_with_mask(str, mask, variables: {})
201
- run_query(str, except: mask, root_value: Data, variables: variables)
202
- end
203
-
204
- def self.run_query(str, options = {})
205
- Schema.execute(str, options.merge(root_value: Data))
206
- end
207
- end
208
-
209
-
210
- describe GraphQL::Schema::Warden do
211
- def type_names(introspection_result)
212
- introspection_result["data"]["__schema"]["types"].map { |t| t["name"] }
213
- end
214
-
215
- def possible_type_names(type_by_name_result)
216
- type_by_name_result["possibleTypes"].map { |t| t["name"] }
217
- end
218
-
219
- def field_type_names(schema_result)
220
- schema_result["types"]
221
- .map {|t| t["fields"] }
222
- .flatten
223
- .map { |f| f ? get_recursive_field_type_names(f["type"]) : [] }
224
- .flatten
225
- .uniq
226
- end
227
-
228
- def get_recursive_field_type_names(field_result)
229
- case field_result
230
- when Hash
231
- [field_result["name"]].concat(get_recursive_field_type_names(field_result["ofType"]))
232
- when nil
233
- []
234
- else
235
- raise "Unexpected field result: #{field_result}"
236
- end
237
- end
238
-
239
- def error_messages(query_result)
240
- query_result["errors"].map { |err| err["message"] }
241
- end
242
-
243
- describe "hiding root types" do
244
- let(:mask) { ->(m, ctx) { m == MaskHelpers::MutationType.graphql_definition } }
245
-
246
- it "acts as if the root doesn't exist" do
247
- query_string = %|mutation { addPhoneme(symbol: "ϕ") { name } }|
248
- res = MaskHelpers.query_with_mask(query_string, mask)
249
- assert MaskHelpers::Schema.mutation # it _does_ exist
250
- assert_equal 1, res["errors"].length
251
- assert_equal "Schema is not configured for mutations", res["errors"][0]["message"]
252
-
253
- query_string = %|subscription { addPhoneme(symbol: "ϕ") { name } }|
254
- res = MaskHelpers.query_with_mask(query_string, mask)
255
- assert MaskHelpers::Schema.subscription # it _does_ exist
256
- assert_equal 1, res["errors"].length
257
- assert_equal "Schema is not configured for subscriptions", res["errors"][0]["message"]
258
- end
259
-
260
- it "doesn't show in introspection" do
261
- query_string = <<-GRAPHQL
262
- {
263
- __schema {
264
- queryType {
265
- name
266
- }
267
- mutationType {
268
- name
269
- }
270
- subscriptionType {
271
- name
272
- }
273
- types {
274
- name
275
- }
276
- }
277
- }
278
- GRAPHQL
279
- res = MaskHelpers.query_with_mask(query_string, mask)
280
- assert_equal "Query", res["data"]["__schema"]["queryType"]["name"]
281
- assert_nil res["data"]["__schema"]["mutationType"]
282
- assert_nil res["data"]["__schema"]["subscriptionType"]
283
- type_names = res["data"]["__schema"]["types"].map { |t| t["name"] }
284
- refute type_names.include?("Mutation")
285
- refute type_names.include?("Subscription")
286
- end
287
- end
288
-
289
- describe "hiding fields" do
290
- let(:mask) {
291
- ->(member, ctx) { member.metadata[:hidden_field] || member.metadata[:hidden_type] }
292
- }
293
-
294
- it "hides types if no other fields are using it" do
295
- query_string = %|
296
- {
297
- Chereme: __type(name: "Chereme") { fields { name } }
298
- }
299
- |
300
-
301
- res = MaskHelpers.query_with_mask(query_string, mask)
302
- assert_nil res["data"]["Chereme"]
303
- end
304
-
305
- it "causes validation errors" do
306
- query_string = %|{ phoneme(symbol: "ϕ") { name } }|
307
- res = MaskHelpers.query_with_mask(query_string, mask)
308
- err_msg = res["errors"][0]["message"]
309
- assert_equal "Field 'phoneme' doesn't exist on type 'Query'", err_msg
310
-
311
- query_string = %|{ language(name: "Uyghur") { name } }|
312
- res = MaskHelpers.query_with_mask(query_string, mask)
313
- err_msg = res["errors"][0]["message"]
314
- assert_equal "Field 'language' doesn't exist on type 'Query'", err_msg
315
- end
316
-
317
- it "doesn't show in introspection" do
318
- query_string = %|
319
- {
320
- LanguageType: __type(name: "Language") { fields { name } }
321
- __schema {
322
- types {
323
- name
324
- fields {
325
- name
326
- }
327
- }
328
- }
329
- }|
330
-
331
- res = MaskHelpers.query_with_mask(query_string, mask)
332
-
333
- # Fields dont appear when finding the type by name
334
- language_fields = res["data"]["LanguageType"]["fields"].map {|f| f["name"] }
335
- assert_equal ["families", "graphemes", "name"], language_fields
336
-
337
- # Fields don't appear in the __schema result
338
- phoneme_fields = res["data"]["__schema"]["types"]
339
- .map { |t| (t["fields"] || []).select { |f| f["name"].start_with?("phoneme") } }
340
- .flatten
341
-
342
- assert_equal [], phoneme_fields
343
- end
344
- end
345
-
346
- describe "hiding types" do
347
- let(:whitelist) {
348
- ->(member, ctx) { !member.metadata[:hidden_type] }
349
- }
350
-
351
- it "hides types from introspection" do
352
- query_string = %|
353
- {
354
- Phoneme: __type(name: "Phoneme") { name }
355
- EmicUnit: __type(name: "EmicUnit") {
356
- possibleTypes { name }
357
- }
358
- LanguageMember: __type(name: "LanguageMember") {
359
- possibleTypes { name }
360
- }
361
- __schema {
362
- types {
363
- name
364
- fields {
365
- type {
366
- name
367
- ofType {
368
- name
369
- ofType {
370
- name
371
- }
372
- }
373
- }
374
- }
375
- }
376
- }
377
- }
378
- |
379
-
380
- res = MaskHelpers.run_query(query_string, only: whitelist)
381
-
382
- # It's not visible by name
383
- assert_nil res["data"]["Phoneme"]
384
-
385
- # It's not visible in `__schema`
386
- all_type_names = type_names(res)
387
- assert_equal false, all_type_names.include?("Phoneme")
388
-
389
- # No fields return it
390
- assert_equal false, field_type_names(res["data"]["__schema"]).include?("Phoneme")
391
-
392
- # It's not visible as a union or interface member
393
- assert_equal false, possible_type_names(res["data"]["EmicUnit"]).include?("Phoneme")
394
- assert_equal false, possible_type_names(res["data"]["LanguageMember"]).include?("Phoneme")
395
- end
396
-
397
- it "hides interfaces if all possible types are hidden" do
398
- sdl = %|
399
- type Query {
400
- a: String
401
- repository: Repository
402
- }
403
-
404
- type Repository implements Node {
405
- id: ID!
406
- }
407
-
408
- interface Node {
409
- id: ID!
410
- }
411
- |
412
-
413
- schema = GraphQL::Schema.from_definition(sdl)
414
-
415
- query_string = %|
416
- {
417
- Node: __type(name: "Node") { name }
418
- }
419
- |
420
-
421
- res = schema.execute(query_string)
422
- assert res["data"]["Node"]
423
-
424
- res = schema.execute(query_string, except: ->(m, _) { m.name == "Repository" })
425
- assert_nil res["data"]["Node"]
426
- end
427
-
428
- it "hides unions if all possible types are hidden or its references are hidden" do
429
- sdl = "
430
- type Query {
431
- bag: BagOfThings
432
- }
433
-
434
- type A {
435
- id: ID!
436
- }
437
-
438
- type B {
439
- id: ID!
440
- }
441
-
442
- type C {
443
- id: ID!
444
- }
445
-
446
- union BagOfThings = A | B | C
447
- "
448
-
449
- schema = GraphQL::Schema.from_definition(sdl)
450
- schema.orphan_types = []
451
-
452
- query_string = %|
453
- {
454
- BagOfThings: __type(name: "BagOfThings") { name }
455
- Query: __type(name: "Query") { fields { name } }
456
- }
457
- |
458
-
459
- res = schema.execute(query_string)
460
- assert res["data"]["BagOfThings"]
461
- assert_equal ["bag"], res["data"]["Query"]["fields"].map { |f| f["name"] }
462
-
463
- # Hide the union when all its possible types are gone. This will cause the field to be hidden too.
464
- res = schema.execute(query_string, except: ->(m, _) { ["A", "B", "C"].include?(m.name) })
465
- assert_nil res["data"]["BagOfThings"]
466
- assert_equal [], res["data"]["Query"]["fields"]
467
-
468
- res = schema.execute(query_string, except: ->(m, _) { m.name == "bag" })
469
- assert_nil res["data"]["BagOfThings"]
470
- assert_equal [], res["data"]["Query"]["fields"]
471
-
472
- # Unreferenced but still visible because orphan type
473
- schema.orphan_types = [schema.find("BagOfThings")]
474
- res = schema.execute(query_string, except: ->(m, _) { m.name == "bag" })
475
- assert res["data"]["BagOfThings"]
476
- end
477
-
478
- it "hides interfaces if all possible types are hidden or its references are hidden" do
479
- sdl = "
480
- type Query {
481
- node: Node
482
- }
483
-
484
- type A implements Node {
485
- id: ID!
486
- }
487
-
488
- type B implements Node {
489
- id: ID!
490
- }
491
-
492
- type C implements Node {
493
- id: ID!
494
- }
495
-
496
- interface Node {
497
- id: ID!
498
- }
499
- "
500
-
501
- schema = GraphQL::Schema.from_definition(sdl)
502
-
503
- query_string = %|
504
- {
505
- Node: __type(name: "Node") { name }
506
- Query: __type(name: "Query") { fields { name } }
507
- }
508
- |
509
-
510
- res = schema.execute(query_string)
511
- assert res["data"]["Node"]
512
- assert_equal ["node"], res["data"]["Query"]["fields"].map { |f| f["name"] }
513
-
514
- # When the possible types are all hidden, hide the interface and fields pointing to it
515
- res = schema.execute(query_string, except: ->(m, _) { ["A", "B", "C"].include?(m.name) })
516
- assert_nil res["data"]["Node"]
517
- assert_equal [], res["data"]["Query"]["fields"]
518
-
519
- # Even when it's not the return value of a field,
520
- # still show the interface since it allows code reuse
521
- res = schema.execute(query_string, except: ->(m, _) { m.name == "node" })
522
- assert_equal "Node", res["data"]["Node"]["name"]
523
- assert_equal [], res["data"]["Query"]["fields"]
524
- end
525
-
526
- it "can't be a fragment condition" do
527
- query_string = %|
528
- {
529
- unit(name: "bilabial trill") {
530
- ... on Phoneme { name }
531
- ... f1
532
- }
533
- }
534
-
535
- fragment f1 on Phoneme {
536
- name
537
- }
538
- |
539
-
540
- res = MaskHelpers.run_query(query_string, only: whitelist)
541
-
542
- expected_errors = [
543
- "No such type Phoneme, so it can't be a fragment condition",
544
- "No such type Phoneme, so it can't be a fragment condition",
545
- ]
546
- assert_equal expected_errors, error_messages(res)
547
- end
548
-
549
- it "can't be a resolve_type result" do
550
- query_string = %|
551
- {
552
- unit(name: "Uvular Trill") { __typename }
553
- }
554
- |
555
-
556
- assert_raises(GraphQL::UnresolvedTypeError) {
557
- MaskHelpers.run_query(query_string, only: whitelist)
558
- }
559
- end
560
-
561
- describe "hiding an abstract type" do
562
- let(:mask) {
563
- ->(member, ctx) { member.metadata[:hidden_abstract_type] }
564
- }
565
-
566
- it "isn't present in a type's interfaces" do
567
- query_string = %|
568
- {
569
- __type(name: "Phoneme") {
570
- interfaces { name }
571
- }
572
- }
573
- |
574
-
575
- res = MaskHelpers.query_with_mask(query_string, mask)
576
- interfaces_names = res["data"]["__type"]["interfaces"].map { |i| i["name"] }
577
- refute_includes interfaces_names, "LanguageMember"
578
- end
579
-
580
- it "hides implementations if they are not referenced anywhere else" do
581
- query_string = %|
582
- {
583
- __type(name: "Character") {
584
- fields { name }
585
- }
586
- }
587
- |
588
-
589
- res = MaskHelpers.query_with_mask(query_string, mask)
590
- type = res["data"]["__type"]
591
- assert_nil type
592
- end
593
- end
594
- end
595
-
596
- describe "hiding arguments" do
597
- let(:mask) {
598
- ->(member, ctx) { member.metadata[:hidden_argument] || member.metadata[:hidden_input_type] }
599
- }
600
-
601
- it "hides types if no other fields or arguments are using it" do
602
- query_string = %|
603
- {
604
- CheremeInput: __type(name: "CheremeInput") { fields { name } }
605
- }
606
- |
607
-
608
- res = MaskHelpers.query_with_mask(query_string, mask)
609
- assert_nil res["data"]["CheremeInput"]
610
- end
611
-
612
- it "isn't present in introspection" do
613
- query_string = %|
614
- {
615
- Query: __type(name: "Query") { fields { name, args { name } } }
616
- }
617
- |
618
- res = MaskHelpers.query_with_mask(query_string, mask)
619
-
620
- query_field_args = res["data"]["Query"]["fields"].each_with_object({}) { |f, memo| memo[f["name"]] = f["args"].map { |a| a["name"] } }
621
- # hidden argument:
622
- refute_includes query_field_args["language"], "name"
623
- # hidden input type:
624
- refute_includes query_field_args["phoneme"], "manner"
625
- end
626
-
627
- it "isn't valid in a query" do
628
- query_string = %|
629
- {
630
- language(name: "Catalan") { name }
631
- phonemes(manners: STOP) { symbol }
632
- }
633
- |
634
- res = MaskHelpers.query_with_mask(query_string, mask)
635
- expected_errors = [
636
- "Field 'language' doesn't accept argument 'name'",
637
- "Field 'phonemes' doesn't accept argument 'manners'",
638
- ]
639
- assert_equal expected_errors, error_messages(res)
640
- end
641
- end
642
-
643
- describe "hidding input type arguments" do
644
- let(:mask) {
645
- ->(member, ctx) { member.metadata[:hidden_input_field] }
646
- }
647
-
648
- it "isn't present in introspection" do
649
- query_string = %|
650
- {
651
- WithinInput: __type(name: "WithinInput") { inputFields { name } }
652
- }|
653
- res = MaskHelpers.query_with_mask(query_string, mask)
654
- input_field_names = res["data"]["WithinInput"]["inputFields"].map { |f| f["name"] }
655
- refute_includes input_field_names, "miles"
656
- end
657
-
658
- it "isn't a valid default value" do
659
- query_string = %|
660
- query findLanguages($nearby: WithinInput = {latitude: 1.0, longitude: 2.2, miles: 3.3}) {
661
- languages(within: $nearby) { name }
662
- }|
663
- res = MaskHelpers.query_with_mask(query_string, mask)
664
- expected_errors = ["Default value for $nearby doesn't match type WithinInput"]
665
- assert_equal expected_errors, error_messages(res)
666
- end
667
-
668
- describe "with error bubbling disabled" do
669
- it "isn't a valid literal input" do
670
- without_error_bubbling(MaskHelpers::Schema) do
671
- query_string = %|
672
- {
673
- languages(within: {latitude: 1.0, longitude: 2.2, miles: 3.3}) { name }
674
- }|
675
- res = MaskHelpers.query_with_mask(query_string, mask)
676
- expected_errors =
677
- [
678
- "InputObject 'WithinInput' doesn't accept argument 'miles'"
679
- ]
680
- assert_equal expected_errors, error_messages(res)
681
- end
682
- end
683
- end
684
-
685
- describe "with error bubbling enabled" do
686
- it "isn't a valid literal input" do
687
- with_error_bubbling(MaskHelpers::Schema) do
688
- query_string = %|
689
- {
690
- languages(within: {latitude: 1.0, longitude: 2.2, miles: 3.3}) { name }
691
- }|
692
- res = MaskHelpers.query_with_mask(query_string, mask)
693
- expected_errors =
694
- [
695
- "Argument 'within' on Field 'languages' has an invalid value. Expected type 'WithinInput'.",
696
- "InputObject 'WithinInput' doesn't accept argument 'miles'"
697
- ]
698
- assert_equal expected_errors, error_messages(res)
699
- end
700
- end
701
- end
702
-
703
- it "isn't a valid variable input" do
704
- query_string = %|
705
- query findLanguages($nearby: WithinInput!) {
706
- languages(within: $nearby) { name }
707
- }|
708
- res = MaskHelpers.query_with_mask(query_string, mask, variables: { "latitude" => 1.0, "longitude" => 2.2, "miles" => 3.3})
709
- expected_errors = ["Variable nearby of type WithinInput! was provided invalid value"]
710
- assert_equal expected_errors, error_messages(res)
711
- end
712
- end
713
-
714
- describe "hidding input types" do
715
- let(:mask) {
716
- ->(member, ctx) { member.metadata[:hidden_input_object_type] }
717
- }
718
-
719
- it "isn't present in introspection" do
720
- query_string = %|
721
- {
722
- WithinInput: __type(name: "WithinInput") { name }
723
- Query: __type(name: "Query") { fields { name, args { name } } }
724
- __schema {
725
- types { name }
726
- }
727
- }
728
- |
729
-
730
- res = MaskHelpers.query_with_mask(query_string, mask)
731
-
732
- assert_nil res["data"]["WithinInput"], "The type isn't accessible by name"
733
-
734
- languages_arg_names = res["data"]["Query"]["fields"].find { |f| f["name"] == "languages" }["args"].map { |a| a["name"] }
735
- refute_includes languages_arg_names, "within", "Arguments that point to it are gone"
736
-
737
- type_names = res["data"]["__schema"]["types"].map { |t| t["name"] }
738
- refute_includes type_names, "WithinInput", "It isn't in the schema's types"
739
- end
740
-
741
- it "isn't a valid input" do
742
- query_string = %|
743
- query findLanguages($nearby: WithinInput!) {
744
- languages(within: $nearby) { name }
745
- }
746
- |
747
-
748
- res = MaskHelpers.query_with_mask(query_string, mask)
749
- expected_errors = [
750
- "WithinInput isn't a defined input type (on $nearby)",
751
- "Field 'languages' doesn't accept argument 'within'",
752
- "Variable $nearby is declared by findLanguages but not used",
753
- ]
754
-
755
- assert_equal expected_errors, error_messages(res)
756
- end
757
- end
758
-
759
- describe "hiding enum values" do
760
- let(:mask) {
761
- ->(member, ctx) { member.metadata[:hidden_enum_value] }
762
- }
763
-
764
- it "isn't present in introspection" do
765
- query_string = %|
766
- {
767
- Manner: __type(name: "Manner") { enumValues { name } }
768
- __schema {
769
- types {
770
- enumValues { name }
771
- }
772
- }
773
- }
774
- |
775
-
776
- res = MaskHelpers.query_with_mask(query_string, mask)
777
-
778
- manner_values = res["data"]["Manner"]["enumValues"]
779
- .map { |v| v["name"] }
780
-
781
- schema_values = res["data"]["__schema"]["types"]
782
- .map { |t| t["enumValues"] || [] }
783
- .flatten
784
- .map { |v| v["name"] }
785
-
786
- refute_includes manner_values, "TRILL", "It's not present on __type"
787
- refute_includes schema_values, "TRILL", "It's not present in __schema"
788
- end
789
-
790
- it "isn't a valid literal input" do
791
- query_string = %|
792
- { phonemes(manners: [STOP, TRILL]) { symbol } }
793
- |
794
- res = MaskHelpers.query_with_mask(query_string, mask)
795
- # It's not a good error message ... but it's something!
796
- expected_errors = [
797
- "Argument 'manners' on Field 'phonemes' has an invalid value. Expected type '[Manner!]'.",
798
- ]
799
- assert_equal expected_errors, error_messages(res)
800
- end
801
-
802
- it "isn't a valid default value" do
803
- query_string = %|
804
- query getPhonemes($manners: [Manner!] = [STOP, TRILL]){ phonemes(manners: $manners) { symbol } }
805
- |
806
- res = MaskHelpers.query_with_mask(query_string, mask)
807
- expected_errors = ["Default value for $manners doesn't match type [Manner!]"]
808
- assert_equal expected_errors, error_messages(res)
809
- end
810
-
811
- it "isn't a valid variable input" do
812
- query_string = %|
813
- query getPhonemes($manners: [Manner!]!) {
814
- phonemes(manners: $manners) { symbol }
815
- }
816
- |
817
- res = MaskHelpers.query_with_mask(query_string, mask, variables: { "manners" => ["STOP", "TRILL"] })
818
- # It's not a good error message ... but it's something!
819
- expected_errors = [
820
- "Variable manners of type [Manner!]! was provided invalid value for 1 (Expected \"TRILL\" to be one of: STOP, AFFRICATE, FRICATIVE, APPROXIMANT, VOWEL)",
821
- ]
822
- assert_equal expected_errors, error_messages(res)
823
- end
824
-
825
- it "raises a runtime error" do
826
- query_string = %|
827
- {
828
- unit(name: "Uvular Trill") { ... on Phoneme { manner } }
829
- }
830
- |
831
- assert_raises(GraphQL::EnumType::UnresolvedValueError) {
832
- MaskHelpers.query_with_mask(query_string, mask)
833
- }
834
- end
835
- end
836
-
837
- describe "default_mask" do
838
- let(:default_mask) {
839
- ->(member, ctx) { member.metadata[:hidden_enum_value] }
840
- }
841
- let(:schema) {
842
- MaskHelpers::Schema.redefine(default_mask: default_mask)
843
- }
844
- let(:query_str) { <<-GRAPHQL
845
- {
846
- enum: __type(name: "Manner") { enumValues { name } }
847
- input: __type(name: "WithinInput") { name }
848
- }
849
- GRAPHQL
850
- }
851
-
852
- it "is additive with query filters" do
853
- query_except = ->(member, ctx) { member.metadata[:hidden_input_object_type] }
854
- res = schema.execute(query_str, except: query_except)
855
- assert_nil res["data"]["input"]
856
- enum_values = res["data"]["enum"]["enumValues"].map { |v| v["name"] }
857
- refute_includes enum_values, "TRILL"
858
- end
859
- end
860
-
861
- describe "multiple filters" do
862
- let(:visible_enum_value) { ->(member, ctx) { !member.metadata[:hidden_enum_value] } }
863
- let(:visible_abstract_type) { ->(member, ctx) { !member.metadata[:hidden_abstract_type] } }
864
- let(:hidden_input_object) { ->(member, ctx) { member.metadata[:hidden_input_object_type] } }
865
- let(:hidden_type) { ->(member, ctx) { member.metadata[:hidden_type] } }
866
-
867
- let(:query_str) { <<-GRAPHQL
868
- {
869
- enum: __type(name: "Manner") { enumValues { name } }
870
- input: __type(name: "WithinInput") { name }
871
- abstractType: __type(name: "Grapheme") { interfaces { name } }
872
- type: __type(name: "Phoneme") { name }
873
- }
874
- GRAPHQL
875
- }
876
-
877
- describe "multiple filters for execution" do
878
- it "applies all of them" do
879
- res = MaskHelpers.run_query(
880
- query_str,
881
- only: [visible_enum_value, visible_abstract_type],
882
- except: [hidden_input_object, hidden_type],
883
- )
884
- assert_nil res["data"]["input"]
885
- enum_values = res["data"]["enum"]["enumValues"].map { |v| v["name"] }
886
- assert_equal 5, enum_values.length
887
- refute_includes enum_values, "TRILL"
888
- # These are also filtered out:
889
- assert_equal 0, res["data"]["abstractType"]["interfaces"].length
890
- assert_nil res["data"]["type"]
891
- end
892
- end
893
-
894
- describe "adding filters in instrumentation" do
895
- it "applies only/except filters" do
896
- filters = {
897
- only: visible_enum_value,
898
- except: hidden_input_object,
899
- }
900
- res = MaskHelpers.run_query(query_str, context: { filters: filters })
901
- assert_nil res["data"]["input"]
902
- enum_values = res["data"]["enum"]["enumValues"].map { |v| v["name"] }
903
- assert_equal 5, enum_values.length
904
- refute_includes enum_values, "TRILL"
905
- # These are unaffected:
906
- assert_includes res["data"]["abstractType"]["interfaces"].map { |i| i["name"] }, "LanguageMember"
907
- assert_equal "Phoneme", res["data"]["type"]["name"]
908
- end
909
-
910
- it "applies multiple filters" do
911
- filters = {
912
- only: [visible_enum_value, visible_abstract_type],
913
- except: [hidden_input_object, hidden_type],
914
- }
915
- res = MaskHelpers.run_query(query_str, context: { filters: filters })
916
- assert_nil res["data"]["input"]
917
- enum_values = res["data"]["enum"]["enumValues"].map { |v| v["name"] }
918
- assert_equal 5, enum_values.length
919
- refute_includes enum_values, "TRILL"
920
- # These are also filtered out:
921
- assert_equal 0, res["data"]["abstractType"]["interfaces"].length
922
- assert_nil res["data"]["type"]
923
- end
924
- end
925
- end
926
- end