graphql 1.9.4 → 1.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/lib/graphql/execution/execute.rb +3 -0
  3. data/lib/graphql/execution/interpreter/runtime.rb +2 -2
  4. data/lib/graphql/execution/lookahead.rb +57 -22
  5. data/lib/graphql/introspection/input_value_type.rb +5 -1
  6. data/lib/graphql/language/parser.rb +57 -54
  7. data/lib/graphql/language/parser.y +12 -9
  8. data/lib/graphql/language/token.rb +1 -1
  9. data/lib/graphql/language/visitor.rb +1 -1
  10. data/lib/graphql/query/arguments.rb +3 -3
  11. data/lib/graphql/query/context.rb +6 -6
  12. data/lib/graphql/query/variable_validation_error.rb +14 -0
  13. data/lib/graphql/schema.rb +2 -2
  14. data/lib/graphql/schema/argument.rb +1 -1
  15. data/lib/graphql/schema/field.rb +6 -3
  16. data/lib/graphql/schema/object.rb +2 -2
  17. data/lib/graphql/schema/relay_classic_mutation.rb +1 -1
  18. data/lib/graphql/schema/rescue_middleware.rb +7 -2
  19. data/lib/graphql/schema/validation.rb +9 -4
  20. data/lib/graphql/static_validation/base_visitor.rb +8 -5
  21. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +3 -1
  22. data/lib/graphql/tracing.rb +3 -3
  23. data/lib/graphql/types.rb +1 -0
  24. data/lib/graphql/types/json.rb +25 -0
  25. data/lib/graphql/types/relay/base_edge.rb +3 -2
  26. data/lib/graphql/unauthorized_field_error.rb +1 -1
  27. data/lib/graphql/version.rb +1 -1
  28. data/spec/dummy/Gemfile.lock +157 -0
  29. data/spec/dummy/log/test.log +199 -0
  30. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4w/4wzXRZrAkwKdgYaSE0pid5eB-fer8vSfSku_NPg4rMA.cache +0 -0
  31. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7I/7IHVBiJT06QSpgLpLoJIxboQ0B-D_tMTxsvoezBTV3Q.cache +1 -0
  32. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8w/8wY_SKagj8wHuwGNAAf6JnQ8joMbC6cEYpHrTAI8Urc.cache +1 -0
  33. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AK/AKzz1u6bGb4auXcrObA_g5LL-oV0ejNGa448AgAi_WQ.cache +1 -0
  34. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ET/ETW4uxvaYpruL8y6_ZptUH82ZowMaHIqvg5WexBFdEM.cache +3 -0
  35. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F1/F1TWpjjyA56k9Z90n5B3xRn7DUdGjX73QCkYC6k07JQ.cache +0 -0
  36. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +2 -0
  37. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +2 -0
  38. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ms/MsKSimH_UCB-H1tLvDABDHuvGciuoW6kVqQWDrXU5FQ.cache +0 -0
  39. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mt/Mtci-Kim50aPOmeClD4AIicKn1d1WJ0n454IjSd94sk.cache +0 -0
  40. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QH/QHt3Tc1Y6M66Oo_pDuMyWrQNs4Pp3SMeZR5K1wJj2Ts.cache +1 -0
  41. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/XU/XU4k1OXnfMils5SrirorPvDSyDSqiOWLZNtmAH1HH8k.cache +0 -0
  42. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ZI/ZIof7mZxWWCnraIFOCuV6a8QRWzKJXJnx2Xd7C0ZyX0.cache +1 -0
  43. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cG/cGc_puuPS5pZKgUcy1Y_i1L6jl5UtsiIrMH59rTzR6c.cache +3 -0
  44. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/df/dfro_B6bx3KP1Go-7jEOqqZ2j4hVRseXIc3es9PKQno.cache +1 -0
  45. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jO/jO1DfbqnG0mTULsjJJANc3fefrG2zt7DIMmcptMT628.cache +1 -0
  46. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pE/pE7gO6pQ-z187Swb4hT554wmqsq-cNzgPWLrCz-LQQQ.cache +0 -0
  47. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/r9/r9iU1l58a6rxkZSW5RSC52_tD-_UQuHxoMVnkfJ7Mhs.cache +1 -0
  48. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xi/xitPPFfPIyDMpaznV0sBBcw8eSCV8PJcLLWin78sCgE.cache +0 -0
  49. data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
  50. data/spec/graphql/authorization_spec.rb +47 -14
  51. data/spec/graphql/execution/lookahead_spec.rb +29 -2
  52. data/spec/graphql/function_spec.rb +28 -5
  53. data/spec/graphql/introspection/input_value_type_spec.rb +40 -1
  54. data/spec/graphql/language/parser_spec.rb +8 -0
  55. data/spec/graphql/query/executor_spec.rb +30 -3
  56. data/spec/graphql/schema/object_spec.rb +71 -0
  57. data/spec/graphql/schema/relay_classic_mutation_spec.rb +18 -0
  58. data/spec/graphql/schema/rescue_middleware_spec.rb +14 -0
  59. data/spec/graphql/schema/warden_spec.rb +1 -1
  60. data/spec/graphql/types/relay/base_edge_spec.rb +33 -0
  61. data/spec/integration/rails/graphql/schema_spec.rb +13 -0
  62. data/spec/integration/tmp/app/graphql/types/bird_type.rb +7 -0
  63. data/spec/support/dummy/schema.rb +19 -0
  64. data/spec/support/jazz.rb +16 -14
  65. metadata +57 -7
@@ -0,0 +1,199 @@
1
+ -----------------------------------------------------------
2
+ ActionCableSubscriptionsTest: test_it_handles_subscriptions
3
+ -----------------------------------------------------------
4
+ Started GET "/" for 127.0.0.1 at 2018-09-29 14:31:04 -0400
5
+ Processing by PagesController#show as HTML
6
+ Rendering pages/show.html within layouts/application
7
+ Rendered pages/show.html within layouts/application (1.3ms)
8
+ Completed 200 OK in 211ms (Views: 208.8ms)
9
+ Started GET "/assets/application-03569c14ba2ebaf689cf2b8eecd6aba17af7402d872a3eca6c4ec8fac4eb31e9.js" for 127.0.0.1 at 2018-09-29 14:31:05 -0400
10
+ Started GET "/cable" for 127.0.0.1 at 2018-09-29 14:31:05 -0400
11
+ Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-09-29 14:31:05 -0400
12
+ Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
13
+ GraphqlChannel is transmitting the subscription confirmation
14
+ GraphqlChannel is transmitting the subscription confirmation
15
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-1"}})
16
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-2"}})
17
+ Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"id\":\"1662699726a\"}", "data"=>"{\"query\":\"subscription($id: ID!) { payload(id: $id) { value } }\",\"variables\":{\"id\":\"updates-1\"},\"action\":\"execute\"}"}) [ArgumentError - wrong number of arguments (given 1, expected 0)]: /Users/rmosolgo/code/graphql-ruby/spec/dummy/app/channels/graphql_channel.rb:19:in `payload' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/field.rb:524:in `public_send' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/field.rb:524:in `block in public_send_field' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/field.rb:536:in `with_extensions' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/field.rb:515:in `public_send_field'
18
+ Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"id\":\"166269a4ccc\"}", "data"=>"{\"query\":\"subscription($id: ID!) { payload(id: $id) { value } }\",\"variables\":{\"id\":\"updates-2\"},\"action\":\"execute\"}"}) [ArgumentError - wrong number of arguments (given 1, expected 0)]: /Users/rmosolgo/code/graphql-ruby/spec/dummy/app/channels/graphql_channel.rb:19:in `payload' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/field.rb:524:in `public_send' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/field.rb:524:in `block in public_send_field' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/field.rb:536:in `with_extensions' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/schema/field.rb:515:in `public_send_field'
19
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>1})
20
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
21
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>2})
22
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
23
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>3})
24
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
25
+ Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-09-29 14:31:08 -0400
26
+ -----------------------------------------------------------
27
+ ActionCableSubscriptionsTest: test_it_handles_subscriptions
28
+ -----------------------------------------------------------
29
+ Started GET "/" for 127.0.0.1 at 2018-09-29 14:31:34 -0400
30
+ Processing by PagesController#show as HTML
31
+ Rendering pages/show.html within layouts/application
32
+ Rendered pages/show.html within layouts/application (1.2ms)
33
+ Completed 200 OK in 209ms (Views: 206.7ms)
34
+ Started GET "/assets/application-03569c14ba2ebaf689cf2b8eecd6aba17af7402d872a3eca6c4ec8fac4eb31e9.js" for 127.0.0.1 at 2018-09-29 14:31:34 -0400
35
+ Started GET "/cable" for 127.0.0.1 at 2018-09-29 14:31:34 -0400
36
+ Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-09-29 14:31:34 -0400
37
+ Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
38
+ GraphqlChannel is transmitting the subscription confirmation
39
+ GraphqlChannel is transmitting the subscription confirmation
40
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-1"}})
41
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
42
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-2"}})
43
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
44
+ GraphqlChannel is streaming from graphql-subscription:d39b7767-bfcf-487f-9985-a99e0074a99c
45
+ GraphqlChannel is streaming from graphql-subscription:95a2d0a0-e2a1-47d2-b9c4-a305e9532f41
46
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-1
47
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-2
48
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>1})
49
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
50
+ [ActionCable] Broadcasting to graphql-subscription:d39b7767-bfcf-487f-9985-a99e0074a99c: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
51
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:d39b7767-bfcf-487f-9985-a99e0074a99c)
52
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>2})
53
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
54
+ [ActionCable] Broadcasting to graphql-subscription:d39b7767-bfcf-487f-9985-a99e0074a99c: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
55
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:d39b7767-bfcf-487f-9985-a99e0074a99c)
56
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>3})
57
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
58
+ [ActionCable] Broadcasting to graphql-subscription:d39b7767-bfcf-487f-9985-a99e0074a99c: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
59
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:d39b7767-bfcf-487f-9985-a99e0074a99c)
60
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>1})
61
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
62
+ [ActionCable] Broadcasting to graphql-subscription:95a2d0a0-e2a1-47d2-b9c4-a305e9532f41: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
63
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:95a2d0a0-e2a1-47d2-b9c4-a305e9532f41)
64
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>2})
65
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
66
+ [ActionCable] Broadcasting to graphql-subscription:95a2d0a0-e2a1-47d2-b9c4-a305e9532f41: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
67
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:95a2d0a0-e2a1-47d2-b9c4-a305e9532f41)
68
+ Unsubscribing from channel: {"channel":"GraphqlChannel","id":"166269a8bd0"}
69
+ GraphqlChannel stopped streaming from graphql-subscription:d39b7767-bfcf-487f-9985-a99e0074a99c
70
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-1
71
+ Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"id\":\"166269a8bd0\"}", "data"=>"{\"id\":\"updates-1\",\"value\":4,\"action\":\"make_trigger\"}"}) [RuntimeError - Unable to find subscription with identifier: {"channel":"GraphqlChannel","id":"166269a8bd0"}]: /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/subscriptions.rb:78:in `find' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/subscriptions.rb:55:in `perform_action' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/subscriptions.rb:19:in `execute_command' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/base.rb:87:in `dispatch_websocket_message' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/server/worker.rb:60:in `block in invoke'
72
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>3})
73
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
74
+ [ActionCable] Broadcasting to graphql-subscription:95a2d0a0-e2a1-47d2-b9c4-a305e9532f41: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
75
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:95a2d0a0-e2a1-47d2-b9c4-a305e9532f41)
76
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>4})
77
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "4x"
78
+ [ActionCable] Broadcasting to graphql-subscription:95a2d0a0-e2a1-47d2-b9c4-a305e9532f41: {:result=>{"data"=>{"payload"=>{"value"=>400}}}, :more=>true}
79
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>400}}}, "more"=>true} (via streamed from graphql-subscription:95a2d0a0-e2a1-47d2-b9c4-a305e9532f41)
80
+ Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-09-29 14:31:36 -0400
81
+ GraphqlChannel stopped streaming from graphql-subscription:95a2d0a0-e2a1-47d2-b9c4-a305e9532f41
82
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-2
83
+ -----------------------------------------------------------
84
+ ActionCableSubscriptionsTest: test_it_handles_subscriptions
85
+ -----------------------------------------------------------
86
+ Started GET "/" for 127.0.0.1 at 2018-09-29 14:31:58 -0400
87
+ Processing by PagesController#show as HTML
88
+ Rendering pages/show.html within layouts/application
89
+ Rendered pages/show.html within layouts/application (1.2ms)
90
+ Completed 200 OK in 244ms (Views: 241.4ms)
91
+ Started GET "/assets/application-03569c14ba2ebaf689cf2b8eecd6aba17af7402d872a3eca6c4ec8fac4eb31e9.js" for 127.0.0.1 at 2018-09-29 14:31:58 -0400
92
+ Started GET "/cable" for 127.0.0.1 at 2018-09-29 14:31:58 -0400
93
+ Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-09-29 14:31:58 -0400
94
+ Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
95
+ GraphqlChannel is transmitting the subscription confirmation
96
+ GraphqlChannel is transmitting the subscription confirmation
97
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-1"}})
98
+ GraphqlChannel transmitting {:result=>{"data"=>{}}, :more=>true}
99
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-2"}})
100
+ GraphqlChannel transmitting {:result=>{"data"=>{}}, :more=>true}
101
+ GraphqlChannel is streaming from graphql-subscription:2b19317b-9279-4b20-95fc-adee4a81161b
102
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-1
103
+ GraphqlChannel is streaming from graphql-subscription:5f944467-ccfa-4765-9b4a-3bccb29b0b6b
104
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-2
105
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>1})
106
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
107
+ [ActionCable] Broadcasting to graphql-subscription:2b19317b-9279-4b20-95fc-adee4a81161b: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
108
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:2b19317b-9279-4b20-95fc-adee4a81161b)
109
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>2})
110
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
111
+ [ActionCable] Broadcasting to graphql-subscription:2b19317b-9279-4b20-95fc-adee4a81161b: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
112
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:2b19317b-9279-4b20-95fc-adee4a81161b)
113
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>3})
114
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
115
+ [ActionCable] Broadcasting to graphql-subscription:2b19317b-9279-4b20-95fc-adee4a81161b: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
116
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:2b19317b-9279-4b20-95fc-adee4a81161b)
117
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>1})
118
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
119
+ [ActionCable] Broadcasting to graphql-subscription:5f944467-ccfa-4765-9b4a-3bccb29b0b6b: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
120
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:5f944467-ccfa-4765-9b4a-3bccb29b0b6b)
121
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>2})
122
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
123
+ [ActionCable] Broadcasting to graphql-subscription:5f944467-ccfa-4765-9b4a-3bccb29b0b6b: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
124
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:5f944467-ccfa-4765-9b4a-3bccb29b0b6b)
125
+ Unsubscribing from channel: {"channel":"GraphqlChannel","id":"166269a7cac"}
126
+ GraphqlChannel stopped streaming from graphql-subscription:2b19317b-9279-4b20-95fc-adee4a81161b
127
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-1
128
+ Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"id\":\"166269a7cac\"}", "data"=>"{\"id\":\"updates-1\",\"value\":4,\"action\":\"make_trigger\"}"}) [RuntimeError - Unable to find subscription with identifier: {"channel":"GraphqlChannel","id":"166269a7cac"}]: /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/subscriptions.rb:78:in `find' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/subscriptions.rb:55:in `perform_action' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/subscriptions.rb:19:in `execute_command' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/base.rb:87:in `dispatch_websocket_message' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/server/worker.rb:60:in `block in invoke'
129
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>3})
130
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
131
+ [ActionCable] Broadcasting to graphql-subscription:5f944467-ccfa-4765-9b4a-3bccb29b0b6b: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
132
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:5f944467-ccfa-4765-9b4a-3bccb29b0b6b)
133
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>4})
134
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "4x"
135
+ [ActionCable] Broadcasting to graphql-subscription:5f944467-ccfa-4765-9b4a-3bccb29b0b6b: {:result=>{"data"=>{"payload"=>{"value"=>400}}}, :more=>true}
136
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>400}}}, "more"=>true} (via streamed from graphql-subscription:5f944467-ccfa-4765-9b4a-3bccb29b0b6b)
137
+ Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-09-29 14:32:00 -0400
138
+ GraphqlChannel stopped streaming from graphql-subscription:5f944467-ccfa-4765-9b4a-3bccb29b0b6b
139
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-2
140
+ -----------------------------------------------------------
141
+ ActionCableSubscriptionsTest: test_it_handles_subscriptions
142
+ -----------------------------------------------------------
143
+ Started GET "/" for 127.0.0.1 at 2018-10-05 11:46:22 -0400
144
+ Processing by PagesController#show as HTML
145
+ Rendering pages/show.html within layouts/application
146
+ Rendered pages/show.html within layouts/application (1.7ms)
147
+ Completed 200 OK in 254ms (Views: 251.5ms)
148
+ Started GET "/assets/application-03569c14ba2ebaf689cf2b8eecd6aba17af7402d872a3eca6c4ec8fac4eb31e9.js" for 127.0.0.1 at 2018-10-05 11:46:22 -0400
149
+ Started GET "/cable" for 127.0.0.1 at 2018-10-05 11:46:22 -0400
150
+ Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-10-05 11:46:22 -0400
151
+ Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
152
+ GraphqlChannel is transmitting the subscription confirmation
153
+ GraphqlChannel is transmitting the subscription confirmation
154
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-2"}})
155
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-1"}})
156
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
157
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
158
+ GraphqlChannel is streaming from graphql-subscription:6da90bd0-cd94-41db-bf3e-760e37b2873f
159
+ GraphqlChannel is streaming from graphql-subscription:c781954b-7b9a-4742-9f9c-69b869d85fad
160
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-2
161
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-1
162
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>1})
163
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
164
+ [ActionCable] Broadcasting to graphql-subscription:6da90bd0-cd94-41db-bf3e-760e37b2873f: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
165
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:6da90bd0-cd94-41db-bf3e-760e37b2873f)
166
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>2})
167
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
168
+ [ActionCable] Broadcasting to graphql-subscription:6da90bd0-cd94-41db-bf3e-760e37b2873f: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
169
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:6da90bd0-cd94-41db-bf3e-760e37b2873f)
170
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>3})
171
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
172
+ [ActionCable] Broadcasting to graphql-subscription:6da90bd0-cd94-41db-bf3e-760e37b2873f: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
173
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:6da90bd0-cd94-41db-bf3e-760e37b2873f)
174
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>1})
175
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
176
+ [ActionCable] Broadcasting to graphql-subscription:c781954b-7b9a-4742-9f9c-69b869d85fad: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
177
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:c781954b-7b9a-4742-9f9c-69b869d85fad)
178
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>2})
179
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
180
+ [ActionCable] Broadcasting to graphql-subscription:c781954b-7b9a-4742-9f9c-69b869d85fad: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
181
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:c781954b-7b9a-4742-9f9c-69b869d85fad)
182
+ Unsubscribing from channel: {"channel":"GraphqlChannel","id":"16644e966c2"}
183
+ GraphqlChannel stopped streaming from graphql-subscription:6da90bd0-cd94-41db-bf3e-760e37b2873f
184
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-1
185
+ Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"id\":\"16644e966c2\"}", "data"=>"{\"id\":\"updates-1\",\"value\":4,\"action\":\"make_trigger\"}"}) [RuntimeError - Unable to find subscription with identifier: {"channel":"GraphqlChannel","id":"16644e966c2"}]: /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/subscriptions.rb:78:in `find' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/subscriptions.rb:55:in `perform_action' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/subscriptions.rb:19:in `execute_command' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/connection/base.rb:87:in `dispatch_websocket_message' | /Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/action_cable/server/worker.rb:60:in `block in invoke'
186
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>3})
187
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
188
+ [ActionCable] Broadcasting to graphql-subscription:c781954b-7b9a-4742-9f9c-69b869d85fad: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
189
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:c781954b-7b9a-4742-9f9c-69b869d85fad)
190
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>4})
191
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "4x"
192
+ [ActionCable] Broadcasting to graphql-subscription:c781954b-7b9a-4742-9f9c-69b869d85fad: {:result=>{"data"=>{"payload"=>{"value"=>400}}}, :more=>true}
193
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>400}}}, "more"=>true} (via streamed from graphql-subscription:c781954b-7b9a-4742-9f9c-69b869d85fad)
194
+ Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-10-05 11:46:25 -0400
195
+ GraphqlChannel stopped streaming from graphql-subscription:c781954b-7b9a-4742-9f9c-69b869d85fad
196
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-2
197
+ -----------------------------------------------------------
198
+ ActionCableSubscriptionsTest: test_it_handles_subscriptions
199
+ -----------------------------------------------------------
@@ -0,0 +1 @@
1
+ "%A��G �{h t�l�m�V���NE���f���
@@ -0,0 +1 @@
1
+ I"�/Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actionview-5.2.1/lib/assets/compiled/rails-ujs.js?type=application/javascript&pipeline=self&id=796d21c1f660d0727db2c56f43915a7a091f297126acf936c5ffbbeeae910c17:ET
@@ -0,0 +1,3 @@
1
+ [o:Set:
2
+ @hash}
3
+ I"environment-version:ETTI"environment-paths;TTI"rails-env;TTI"Zprocessors:type=application/javascript&file_type=application/javascript&pipeline=self;TTI"~file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actionview-5.2.1/lib/assets/compiled/rails-ujs.js;TTF
@@ -0,0 +1,2 @@
1
+ [o:Set:
2
+ @hash}I"environment-version:ETTI"environment-paths;TTI"rails-env;TTI"Zprocessors:type=application/javascript&file_type=application/javascript&pipeline=self;TTI"8file-digest://app/assets/javascripts/application.js;TTI"$file-digest://app/assets/config;TTI".file-digest://app/assets/config/rails-ujs;TTI")file-digest://app/assets/javascripts;TTI"3file-digest://app/assets/javascripts/rails-ujs;TTI"wfile-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/assets/compiled;TTI"|file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/assets/compiled/rails-ujs;TTI"vfile-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actionview-5.2.1/lib/assets/compiled;TTI"{file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actionview-5.2.1/lib/assets/compiled/rails-ujs;TTI"~file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actionview-5.2.1/lib/assets/compiled/rails-ujs.js;TTI"1file-digest://app/assets/config/action_cable;TTI"6file-digest://app/assets/javascripts/action_cable;TTI"file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/assets/compiled/action_cable;TTI"�file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/assets/compiled/action_cable.js;TTF
@@ -0,0 +1,2 @@
1
+ [o:Set:
2
+ @hash}I"environment-version:ETTI"environment-paths;TTI"rails-env;TTI"Lprocessors:type=application/javascript&file_type=application/javascript;TTI"8file-digest://app/assets/javascripts/application.js;TTI"Zprocessors:type=application/javascript&file_type=application/javascript&pipeline=self;TTI"~file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actionview-5.2.1/lib/assets/compiled/rails-ujs.js;TTI"�file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/assets/compiled/action_cable.js;TTI"$file-digest://app/assets/config;TTI".file-digest://app/assets/config/rails-ujs;TTI")file-digest://app/assets/javascripts;TTI"3file-digest://app/assets/javascripts/rails-ujs;TTI"wfile-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/assets/compiled;TTI"|file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/assets/compiled/rails-ujs;TTI"vfile-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actionview-5.2.1/lib/assets/compiled;TTI"{file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actionview-5.2.1/lib/assets/compiled/rails-ujs;TTI"1file-digest://app/assets/config/action_cable;TTI"6file-digest://app/assets/javascripts/action_cable;TTI"file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/assets/compiled/action_cable;TTF
@@ -0,0 +1 @@
1
+ I"�app/assets/javascripts/application.js?type=application/javascript&id=2ee40e48961834681557f3d62ba66cca730386fc65c8e753fcc131c5eb57f691:ET
@@ -0,0 +1 @@
1
+ I"�app/assets/javascripts/application.js?type=application/javascript&pipeline=self&id=cc953a7e5d4fae38988cd3dedb6bc5c7d501af2190fe07930d5a3ac7b8f03ad7:ET
@@ -0,0 +1,3 @@
1
+ [o:Set:
2
+ @hash}
3
+ I"environment-version:ETTI"environment-paths;TTI"rails-env;TTI"Zprocessors:type=application/javascript&file_type=application/javascript&pipeline=self;TTI"�file-digest:///Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/assets/compiled/action_cable.js;TTF
@@ -0,0 +1 @@
1
+ I"�/Users/rmosolgo/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/actioncable-5.2.1/lib/assets/compiled/action_cable.js?type=application/javascript&pipeline=self&id=511553fd80002b90bc2b116eebc32ea1592732ff16395e6f2424f75f0ffc1870:ET
@@ -0,0 +1 @@
1
+ "%�d�-�K���`���8Y��3�͹/Y����a~K
@@ -48,6 +48,9 @@ describe GraphQL::Authorization do
48
48
  end
49
49
 
50
50
  def authorized?(object, context)
51
+ if object == :raise
52
+ raise GraphQL::UnauthorizedFieldError.new("raised authorized field error", object: object)
53
+ end
51
54
  super && object != :hide && object != :replace
52
55
  end
53
56
  end
@@ -149,8 +152,13 @@ describe GraphQL::Authorization do
149
152
 
150
153
  class UnauthorizedObject < BaseObject
151
154
  def self.authorized?(value, context)
155
+ if context[:raise]
156
+ raise GraphQL::UnauthorizedError.new("raised authorized object error", object: value.object)
157
+ end
152
158
  super && !context[:hide]
153
159
  end
160
+
161
+ field :value, String, null: false, method: :itself
154
162
  end
155
163
 
156
164
  class UnauthorizedBox < BaseObject
@@ -389,6 +397,8 @@ describe GraphQL::Authorization do
389
397
  err.object.replacement
390
398
  elsif err.object == :replace
391
399
  33
400
+ elsif err.object == :raise_from_object
401
+ raise GraphQL::ExecutionError, err.message
392
402
  else
393
403
  raise GraphQL::ExecutionError, "Unauthorized #{err.type.graphql_name}: #{err.object.inspect}"
394
404
  end
@@ -398,11 +408,16 @@ describe GraphQL::Authorization do
398
408
  end
399
409
 
400
410
  class SchemaWithFieldHook < GraphQL::Schema
411
+ if TESTING_INTERPRETER
412
+ use GraphQL::Execution::Interpreter
413
+ end
401
414
  query(Query)
402
415
 
403
416
  def self.unauthorized_field(err)
404
417
  if err.object == :replace
405
418
  42
419
+ elsif err.object == :raise
420
+ raise GraphQL::ExecutionError, "#{err.message} in field #{err.field.name}"
406
421
  else
407
422
  raise GraphQL::ExecutionError, "Unauthorized field #{err.field.graphql_name} on #{err.type.graphql_name}: #{err.object}"
408
423
  end
@@ -663,6 +678,14 @@ describe GraphQL::Authorization do
663
678
  assert_equal ["Unauthorized field unauthorized on Query: hide"], response["errors"].map { |e| e["message"] }
664
679
  end
665
680
  end
681
+
682
+ describe "when the field authorization raises an UnauthorizedFieldError" do
683
+ it "receives the raised error" do
684
+ query = "{ unauthorized }"
685
+ response = AuthTest::SchemaWithFieldHook.execute(query, root_value: :raise)
686
+ assert_equal ["raised authorized field error in field unauthorized"], response["errors"].map { |e| e["message"] }
687
+ end
688
+ end
666
689
  end
667
690
 
668
691
  describe "with an unauthorized field hook not configured" do
@@ -893,23 +916,33 @@ describe GraphQL::Authorization do
893
916
  assert_equal [{"value" => "z"}, {"value" => "z2"}, nil, nil], res["data"]["unauthorizedLazyListInterface"]
894
917
  end
895
918
 
896
- it "replaces objects from the unauthorized_object hook" do
897
- query = "{ replacedObject { replaced } }"
898
- res = auth_execute(query, context: { replace_me: true })
899
- assert_equal true, res["data"]["replacedObject"]["replaced"]
919
+ describe "with an unauthorized field hook configured" do
920
+ it "replaces objects from the unauthorized_object hook" do
921
+ query = "{ replacedObject { replaced } }"
922
+ res = auth_execute(query, context: { replace_me: true })
923
+ assert_equal true, res["data"]["replacedObject"]["replaced"]
900
924
 
901
- res = auth_execute(query, context: { replace_me: false })
902
- assert_equal false, res["data"]["replacedObject"]["replaced"]
903
- end
925
+ res = auth_execute(query, context: { replace_me: false })
926
+ assert_equal false, res["data"]["replacedObject"]["replaced"]
927
+ end
904
928
 
905
- it "works when the query hook returns false and there's no root object" do
906
- query = "{ __typename }"
907
- res = auth_execute(query)
908
- assert_equal "Query", res["data"]["__typename"]
929
+ it "works when the query hook returns false and there's no root object" do
930
+ query = "{ __typename }"
931
+ res = auth_execute(query)
932
+ assert_equal "Query", res["data"]["__typename"]
909
933
 
910
- unauth_res = auth_execute(query, context: { query_unauthorized: true })
911
- assert_nil unauth_res["data"]
912
- assert_equal [{"message"=>"Unauthorized Query: nil"}], unauth_res["errors"]
934
+ unauth_res = auth_execute(query, context: { query_unauthorized: true })
935
+ assert_nil unauth_res["data"]
936
+ assert_equal [{"message"=>"Unauthorized Query: nil"}], unauth_res["errors"]
937
+ end
938
+
939
+ describe "when the object authorization raises an UnauthorizedFieldError" do
940
+ it "receives the raised error" do
941
+ query = "{ unauthorizedObject { value } }"
942
+ response = auth_execute(query, context: { raise: true }, root_value: :raise_from_object)
943
+ assert_equal ["raised authorized object error"], response["errors"].map { |e| e["message"] }
944
+ end
945
+ end
913
946
  end
914
947
  end
915
948
 
@@ -20,6 +20,7 @@ describe GraphQL::Execution::Lookahead do
20
20
  end
21
21
 
22
22
  class BirdGenus < GraphQL::Schema::Object
23
+ field :name, String, null: false
23
24
  field :latin_name, String, null: false
24
25
  field :id, ID, null: false, method: :latin_name
25
26
  end
@@ -69,7 +70,7 @@ describe GraphQL::Execution::Lookahead do
69
70
 
70
71
  class LookaheadInstrumenter
71
72
  def self.before_query(query)
72
- query.context[:root_lookahead_names] = query.lookahead.selections.map(&:name)
73
+ query.context[:root_lookahead_selections] = query.lookahead.selections
73
74
  end
74
75
 
75
76
  def self.after_query(q)
@@ -265,7 +266,11 @@ describe GraphQL::Execution::Lookahead do
265
266
  res = LookaheadTest::Schema.execute(query_str, context: context)
266
267
  refute res.key?("errors")
267
268
  assert_equal 2, context[:lookahead_latin_name]
268
- assert_equal [:find_bird_species], context[:root_lookahead_names]
269
+ assert_equal [:find_bird_species], context[:root_lookahead_selections].map(&:name).uniq
270
+ assert_equal(
271
+ [{ by_name: "Cardinal" }, { by_name: "Scarlet Tanager" }, { by_name: "Great Blue Heron" }],
272
+ context[:root_lookahead_selections].map(&:arguments)
273
+ )
269
274
  end
270
275
 
271
276
  it "works for invalid queries" do
@@ -350,6 +355,28 @@ describe GraphQL::Execution::Lookahead do
350
355
  assert_equal [:name, :similar_species], root_selections.first.selections.map(&:name), "Subselections are merged"
351
356
  end
352
357
 
358
+ it "avoids merging selections for same field name on distinct types" do
359
+ query = GraphQL::Query.new(LookaheadTest::Schema, <<-GRAPHQL)
360
+ query {
361
+ node(id: "Cardinal") {
362
+ ... on BirdSpecies {
363
+ name
364
+ }
365
+ ... on BirdGenus {
366
+ name
367
+ }
368
+ id
369
+ }
370
+ }
371
+ GRAPHQL
372
+
373
+ node_lookahead = query.lookahead.selection("node")
374
+ assert_equal(
375
+ [[LookaheadTest::Node, :id], [LookaheadTest::BirdSpecies, :name], [LookaheadTest::BirdGenus, :name]],
376
+ node_lookahead.selections.map { |s| [s.owner_type, s.name] }
377
+ )
378
+ end
379
+
353
380
  it "works for missing selections" do
354
381
  ast_node = document.definitions.first.selections.first
355
382
  field = LookaheadTest::Query.fields["findBirdSpecies"]
@@ -2,13 +2,15 @@
2
2
  require "spec_helper"
3
3
 
4
4
  describe GraphQL::Function do
5
+ TestFuncPayload = GraphQL::ObjectType.define do
6
+ name "TestFuncPayload"
7
+ field :name, types.String, hash_key: :name
8
+ end
9
+
5
10
  class TestFunc < GraphQL::Function
6
11
  argument :name, GraphQL::STRING_TYPE
7
12
  argument :age, types.Int
8
- type do
9
- name "TestFuncPayload"
10
- field :name, types.String, hash_key: :name
11
- end
13
+ type TestFuncPayload
12
14
 
13
15
  description "Returns the string you give it"
14
16
  deprecation_reason "It's useless"
@@ -18,6 +20,19 @@ describe GraphQL::Function do
18
20
  end
19
21
  end
20
22
 
23
+ class TestFuncConn < GraphQL::Function
24
+ argument :name, GraphQL::STRING_TYPE
25
+ argument :age, types.Int
26
+ type TestFuncPayload.connection_type
27
+
28
+ description "Returns the string you give it"
29
+ deprecation_reason "It's useless"
30
+ complexity 9
31
+ def call(o, a, c)
32
+ [{ name: a[:name] }]
33
+ end
34
+ end
35
+
21
36
  describe "function API" do
22
37
  it "exposes required info" do
23
38
  f = TestFunc.new
@@ -49,7 +64,7 @@ describe GraphQL::Function do
49
64
  query_type = GraphQL::ObjectType.define do
50
65
  name "Query"
51
66
  field :test, function: TestFunc.new
52
- connection :testConn, function: TestFunc.new
67
+ connection :testConn, function: TestFuncConn.new
53
68
  end
54
69
 
55
70
  relay_mutation = GraphQL::Relay::Mutation.define do
@@ -86,6 +101,14 @@ describe GraphQL::Function do
86
101
  assert_equal "graphql", res["data"]["test"]["name"]
87
102
  end
88
103
 
104
+ it "can be used as a connection" do
105
+ query_str = <<-GRAPHQL
106
+ { testConn(name: "graphql") { edges { node { name } } } }
107
+ GRAPHQL
108
+ res = schema.execute(query_str)
109
+ assert_equal "graphql", res["data"]["testConn"]["edges"][0]["node"]["name"]
110
+ end
111
+
89
112
  it "can be used as a mutation" do
90
113
  query_str = <<-GRAPHQL
91
114
  mutation { test(input: {clientMutationId: "123", name: "graphql"}) { name, clientMutationId } }