test_download.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. # Copyright 2021-2025 Avaiga Private Limited
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
  4. # the License. You may obtain a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  9. # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  10. # specific language governing permissions and limitations under the License.
  11. import inspect
  12. import warnings
  13. import pytest
  14. from taipy.gui import Gui, Markdown, State, download
  15. from taipy.gui.servers import get_request_meta
  16. from taipy.gui.servers.request import RequestAccessor
  17. @pytest.mark.skip_if_not_server("flask")
  18. def test_download(gui: Gui, helpers):
  19. def on_download_action(state: State):
  20. pass
  21. # set gui frame
  22. gui._set_frame(inspect.currentframe())
  23. gui.add_page("test", Markdown("<|Hello|button|>"))
  24. gui.run(run_server=False)
  25. server_client = gui._server.test_client()
  26. # WS client and emit
  27. ws_client = gui._server._ws.test_client(gui._server.get_server_instance())
  28. cid = helpers.create_scope_and_get_sid(gui)
  29. server_client.get(f"/taipy-jsx/test?client_id={cid}")
  30. with gui._server.test_request_context(f"/taipy-jsx/test/?client_id={cid}", data={"client_id": cid}):
  31. get_request_meta().client_id = cid
  32. download(gui._Gui__state, "some text", "filename.txt", "on_download_action") # type: ignore[attr-defined]
  33. received_messages = ws_client.get_received()
  34. helpers.assert_outward_ws_simple_message(
  35. received_messages[0], "DF", {"name": "filename.txt", "onAction": "on_download_action"}
  36. )
  37. @pytest.mark.skip_if_not_server("flask")
  38. def test_download_fn(gui: Gui, helpers):
  39. def on_download_action(state: State):
  40. pass
  41. # set gui frame
  42. gui._set_frame(inspect.currentframe())
  43. gui.add_page("test", Markdown("<|Hello|button|>"))
  44. gui.run(run_server=False)
  45. server_client = gui._server.test_client()
  46. # WS client and emit
  47. ws_client = gui._server._ws.test_client(gui._server.get_server_instance())
  48. cid = helpers.create_scope_and_get_sid(gui)
  49. server_client.get(f"/taipy-jsx/test?client_id={cid}")
  50. with gui._server.test_request_context(f"/taipy-jsx/test/?client_id={cid}", data={"client_id": cid}):
  51. get_request_meta().client_id = cid
  52. download(gui._Gui__state, "some text", "filename.txt", on_download_action) # type: ignore[attr-defined]
  53. received_messages = ws_client.get_received()
  54. helpers.assert_outward_ws_simple_message(
  55. received_messages[0],
  56. "DF",
  57. {"name": "filename.txt", "context": "test_download"},
  58. )
  59. assert "onAction" in received_messages[0]["args"] # inner function is treated as lambda
  60. @pytest.mark.skip_if_not_server("fastapi")
  61. @pytest.mark.teste2e
  62. def test_download_fastapi(gui: Gui, helpers):
  63. def on_download_action(state: State):
  64. pass
  65. # set gui frame
  66. gui._set_frame(inspect.currentframe())
  67. gui.add_page("test", Markdown("<|Hello|button|>"))
  68. helpers.run_e2e_multi_client(gui)
  69. ws_client = helpers.get_socketio_test_client()
  70. cid = helpers.create_scope_and_get_sid(gui)
  71. sid = ws_client.get_sid()
  72. ws_client.get(f"/taipy-jsx/test?client_id={cid}")
  73. with gui.get_app_context():
  74. RequestAccessor.set_sid(sid)
  75. get_request_meta().client_id = cid
  76. download(gui._Gui__state, "some text", "filename.txt", "on_download_action") # type: ignore[attr-defined]
  77. received_messages = ws_client.get_received()
  78. try:
  79. helpers.assert_outward_ws_simple_message(
  80. received_messages[0], "DF", {"name": "filename.txt", "onAction": "on_download_action"}
  81. )
  82. finally:
  83. ws_client.disconnect()
  84. @pytest.mark.skip_if_not_server("fastapi")
  85. @pytest.mark.teste2e
  86. def test_download_fn_fastapi(gui: Gui, helpers):
  87. def on_download_action(state: State):
  88. pass
  89. # set gui frame
  90. gui._set_frame(inspect.currentframe())
  91. gui.add_page("test", Markdown("<|Hello|button|>"))
  92. helpers.run_e2e_multi_client(gui)
  93. ws_client = helpers.get_socketio_test_client()
  94. cid = helpers.create_scope_and_get_sid(gui)
  95. sid = ws_client.get_sid()
  96. ws_client.get(f"/taipy-jsx/test?client_id={cid}")
  97. with gui.get_app_context():
  98. RequestAccessor.set_sid(sid)
  99. get_request_meta().client_id = cid
  100. download(gui._Gui__state, "some text", "filename.txt", on_download_action) # type: ignore[attr-defined]
  101. received_messages = ws_client.get_received()
  102. try:
  103. helpers.assert_outward_ws_simple_message(
  104. received_messages[0],
  105. "DF",
  106. {"name": "filename.txt", "context": "test_download"},
  107. )
  108. assert "onAction" in received_messages[0]["args"] # inner function is treated as lambda
  109. finally:
  110. ws_client.disconnect()
  111. def test_bad_download(gui: Gui, helpers):
  112. with warnings.catch_warnings(record=True) as records:
  113. download(None, "some text", "filename.txt", "on_download_action") # type: ignore[arg-type]
  114. assert len(records) == 1