test_event.py 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. import json
  2. import pytest
  3. from reflex import event
  4. from reflex.event import Event, EventHandler, EventSpec, fix_events
  5. from reflex.utils import format
  6. from reflex.vars import Var
  7. def make_var(value) -> Var:
  8. """Make a variable.
  9. Args:
  10. value: The value of the var.
  11. Returns:
  12. The var.
  13. """
  14. var = Var.create(value)
  15. assert var is not None
  16. return var
  17. def test_create_event():
  18. """Test creating an event."""
  19. event = Event(token="token", name="state.do_thing", payload={"arg": "value"})
  20. assert event.token == "token"
  21. assert event.name == "state.do_thing"
  22. assert event.payload == {"arg": "value"}
  23. def test_call_event_handler():
  24. """Test that calling an event handler creates an event spec."""
  25. def test_fn():
  26. pass
  27. test_fn.__qualname__ = "test_fn"
  28. def test_fn_with_args(_, arg1, arg2):
  29. pass
  30. test_fn_with_args.__qualname__ = "test_fn_with_args"
  31. handler = EventHandler(fn=test_fn)
  32. event_spec = handler()
  33. assert event_spec.handler == handler
  34. assert event_spec.args == ()
  35. assert format.format_event(event_spec) == 'Event("test_fn", {})'
  36. handler = EventHandler(fn=test_fn_with_args)
  37. event_spec = handler(make_var("first"), make_var("second"))
  38. # Test passing vars as args.
  39. assert event_spec.handler == handler
  40. assert event_spec.args[0][0].equals(Var.create_safe("arg1"))
  41. assert event_spec.args[0][1].equals(Var.create_safe("first"))
  42. assert event_spec.args[1][0].equals(Var.create_safe("arg2"))
  43. assert event_spec.args[1][1].equals(Var.create_safe("second"))
  44. assert (
  45. format.format_event(event_spec)
  46. == 'Event("test_fn_with_args", {arg1:first,arg2:second})'
  47. )
  48. # Passing args as strings should format differently.
  49. event_spec = handler("first", "second") # type: ignore
  50. assert (
  51. format.format_event(event_spec)
  52. == 'Event("test_fn_with_args", {arg1:"first",arg2:"second"})'
  53. )
  54. first, second = 123, "456"
  55. handler = EventHandler(fn=test_fn_with_args)
  56. event_spec = handler(first, second) # type: ignore
  57. assert (
  58. format.format_event(event_spec)
  59. == 'Event("test_fn_with_args", {arg1:123,arg2:"456"})'
  60. )
  61. assert event_spec.handler == handler
  62. assert event_spec.args[0][0].equals(Var.create_safe("arg1"))
  63. assert event_spec.args[0][1].equals(Var.create_safe(first))
  64. assert event_spec.args[1][0].equals(Var.create_safe("arg2"))
  65. assert event_spec.args[1][1].equals(Var.create_safe(second))
  66. handler = EventHandler(fn=test_fn_with_args)
  67. with pytest.raises(TypeError):
  68. handler(test_fn) # type: ignore
  69. @pytest.mark.parametrize(
  70. ("arg1", "arg2"),
  71. (
  72. (1, 2),
  73. (1, "2"),
  74. ({"a": 1}, {"b": 2}),
  75. ),
  76. )
  77. def test_fix_events(arg1, arg2):
  78. """Test that chaining an event handler with args formats the payload correctly.
  79. Args:
  80. arg1: The first arg passed to the handler.
  81. arg2: The second arg passed to the handler.
  82. """
  83. def test_fn_with_args(_, arg1, arg2):
  84. pass
  85. test_fn_with_args.__qualname__ = "test_fn_with_args"
  86. handler = EventHandler(fn=test_fn_with_args)
  87. event_spec = handler(arg1, arg2)
  88. event = fix_events([event_spec], token="foo")[0]
  89. assert event.name == test_fn_with_args.__qualname__
  90. assert event.token == "foo"
  91. assert event.payload == {"arg1": arg1, "arg2": arg2}
  92. @pytest.mark.parametrize(
  93. "input,output",
  94. [
  95. (("/path", None), 'Event("_redirect", {path:"/path",external:false})'),
  96. (("/path", True), 'Event("_redirect", {path:"/path",external:true})'),
  97. (("/path", False), 'Event("_redirect", {path:"/path",external:false})'),
  98. (
  99. (Var.create_safe("path"), None),
  100. 'Event("_redirect", {path:path,external:false})',
  101. ),
  102. ],
  103. )
  104. def test_event_redirect(input, output):
  105. """Test the event redirect function.
  106. Args:
  107. input: The input for running the test.
  108. output: The expected output to validate the test.
  109. """
  110. path, external = input
  111. if external is None:
  112. spec = event.redirect(path)
  113. else:
  114. spec = event.redirect(path, external=external)
  115. assert isinstance(spec, EventSpec)
  116. assert spec.handler.fn.__qualname__ == "_redirect"
  117. # this asserts need comment about what it's testing (they fail with Var as input)
  118. # assert spec.args[0][0].equals(Var.create_safe("path"))
  119. # assert spec.args[0][1].equals(Var.create_safe("/path"))
  120. assert format.format_event(spec) == output
  121. def test_event_console_log():
  122. """Test the event console log function."""
  123. spec = event.console_log("message")
  124. assert isinstance(spec, EventSpec)
  125. assert spec.handler.fn.__qualname__ == "_console"
  126. assert spec.args[0][0].equals(Var.create_safe("message"))
  127. assert spec.args[0][1].equals(Var.create_safe("message"))
  128. assert format.format_event(spec) == 'Event("_console", {message:"message"})'
  129. spec = event.console_log(Var.create_safe("message"))
  130. assert format.format_event(spec) == 'Event("_console", {message:message})'
  131. def test_event_window_alert():
  132. """Test the event window alert function."""
  133. spec = event.window_alert("message")
  134. assert isinstance(spec, EventSpec)
  135. assert spec.handler.fn.__qualname__ == "_alert"
  136. assert spec.args[0][0].equals(Var.create_safe("message"))
  137. assert spec.args[0][1].equals(Var.create_safe("message"))
  138. assert format.format_event(spec) == 'Event("_alert", {message:"message"})'
  139. spec = event.window_alert(Var.create_safe("message"))
  140. assert format.format_event(spec) == 'Event("_alert", {message:message})'
  141. def test_set_focus():
  142. """Test the event set focus function."""
  143. spec = event.set_focus("input1")
  144. assert isinstance(spec, EventSpec)
  145. assert spec.handler.fn.__qualname__ == "_set_focus"
  146. assert spec.args[0][0].equals(Var.create_safe("ref"))
  147. assert spec.args[0][1].equals(Var.create_safe("ref_input1"))
  148. assert format.format_event(spec) == 'Event("_set_focus", {ref:ref_input1})'
  149. spec = event.set_focus("input1")
  150. assert format.format_event(spec) == 'Event("_set_focus", {ref:ref_input1})'
  151. def test_set_value():
  152. """Test the event window alert function."""
  153. spec = event.set_value("input1", "")
  154. assert isinstance(spec, EventSpec)
  155. assert spec.handler.fn.__qualname__ == "_set_value"
  156. assert spec.args[0][0].equals(Var.create_safe("ref"))
  157. assert spec.args[0][1].equals(Var.create_safe("ref_input1"))
  158. assert spec.args[1][0].equals(Var.create_safe("value"))
  159. assert spec.args[1][1].equals(Var.create_safe(""))
  160. assert format.format_event(spec) == 'Event("_set_value", {ref:ref_input1,value:""})'
  161. spec = event.set_value("input1", Var.create_safe("message"))
  162. assert (
  163. format.format_event(spec)
  164. == 'Event("_set_value", {ref:ref_input1,value:message})'
  165. )
  166. def test_set_cookie():
  167. """Test the event set_cookie."""
  168. spec = event.set_cookie("testkey", "testvalue")
  169. assert isinstance(spec, EventSpec)
  170. assert spec.handler.fn.__qualname__ == "_set_cookie"
  171. assert spec.args[0][0].equals(Var.create_safe("key"))
  172. assert spec.args[0][1].equals(Var.create_safe("testkey"))
  173. assert spec.args[1][0].equals(Var.create_safe("value"))
  174. assert spec.args[1][1].equals(Var.create_safe("testvalue"))
  175. assert (
  176. format.format_event(spec)
  177. == 'Event("_set_cookie", {key:"testkey",value:"testvalue"})'
  178. )
  179. def test_remove_cookie():
  180. """Test the event remove_cookie."""
  181. spec = event.remove_cookie("testkey")
  182. assert isinstance(spec, EventSpec)
  183. assert spec.handler.fn.__qualname__ == "_remove_cookie"
  184. assert spec.args[0][0].equals(Var.create_safe("key"))
  185. assert spec.args[0][1].equals(Var.create_safe("testkey"))
  186. assert spec.args[1][0].equals(Var.create_safe("options"))
  187. assert spec.args[1][1].equals(Var.create_safe({}))
  188. assert (
  189. format.format_event(spec)
  190. == 'Event("_remove_cookie", {key:"testkey",options:{}})'
  191. )
  192. def test_remove_cookie_with_options():
  193. """Test the event remove_cookie with options."""
  194. options = {
  195. "path": "/",
  196. "domain": "example.com",
  197. "secure": True,
  198. "sameSite": "strict",
  199. }
  200. spec = event.remove_cookie("testkey", options)
  201. assert isinstance(spec, EventSpec)
  202. assert spec.handler.fn.__qualname__ == "_remove_cookie"
  203. assert spec.args[0][0].equals(Var.create_safe("key"))
  204. assert spec.args[0][1].equals(Var.create_safe("testkey"))
  205. assert spec.args[1][0].equals(Var.create_safe("options"))
  206. assert spec.args[1][1].equals(Var.create_safe(options))
  207. assert (
  208. format.format_event(spec)
  209. == f'Event("_remove_cookie", {{key:"testkey",options:{json.dumps(options)}}})'
  210. )
  211. def test_set_local_storage():
  212. """Test the event set_local_storage."""
  213. spec = event.set_local_storage("testkey", "testvalue")
  214. assert isinstance(spec, EventSpec)
  215. assert spec.handler.fn.__qualname__ == "_set_local_storage"
  216. assert spec.args[0][0].equals(Var.create_safe("key"))
  217. assert spec.args[0][1].equals(Var.create_safe("testkey"))
  218. assert spec.args[1][0].equals(Var.create_safe("value"))
  219. assert spec.args[1][1].equals(Var.create_safe("testvalue"))
  220. assert (
  221. format.format_event(spec)
  222. == 'Event("_set_local_storage", {key:"testkey",value:"testvalue"})'
  223. )
  224. def test_clear_local_storage():
  225. """Test the event clear_local_storage."""
  226. spec = event.clear_local_storage()
  227. assert isinstance(spec, EventSpec)
  228. assert spec.handler.fn.__qualname__ == "_clear_local_storage"
  229. assert not spec.args
  230. assert format.format_event(spec) == 'Event("_clear_local_storage", {})'
  231. def test_remove_local_storage():
  232. """Test the event remove_local_storage."""
  233. spec = event.remove_local_storage("testkey")
  234. assert isinstance(spec, EventSpec)
  235. assert spec.handler.fn.__qualname__ == "_remove_local_storage"
  236. assert spec.args[0][0].equals(Var.create_safe("key"))
  237. assert spec.args[0][1].equals(Var.create_safe("testkey"))
  238. assert (
  239. format.format_event(spec) == 'Event("_remove_local_storage", {key:"testkey"})'
  240. )