test_context_update_data.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. from datetime import datetime
  12. from unittest.mock import Mock, patch
  13. import pytest
  14. from taipy import DataNode, Gui, Scope
  15. from taipy.core.data._data_manager_factory import _DataManagerFactory
  16. from taipy.core.data.pickle import PickleDataNode
  17. from taipy.core.reason import Reason, ReasonCollection
  18. from taipy.gui_core._context import _GuiCoreContext
  19. dn = PickleDataNode("data_node_config_id", Scope.SCENARIO)
  20. def core_get(entity_id):
  21. if entity_id == dn.id:
  22. return dn
  23. return None
  24. def is_false(entity_id):
  25. return ReasonCollection()._add_reason(entity_id, Reason("foo"))
  26. def is_true(entity_id):
  27. return True
  28. def fails(**kwargs):
  29. raise Exception("Failed")
  30. class MockState:
  31. def __init__(self, **kwargs) -> None:
  32. self.assign = kwargs.get("assign")
  33. class TestGuiCoreContext_update_data:
  34. @pytest.fixture(scope="class", autouse=True)
  35. def set_entities(self):
  36. _DataManagerFactory._build_manager()._repository._save(dn)
  37. def test_does_not_fail_if_wrong_args(self):
  38. gui_core_context = _GuiCoreContext(Mock(Gui))
  39. gui_core_context.update_data(state=Mock(), id="", payload={})
  40. gui_core_context.update_data(state=Mock(), id="", payload={"args": "wrong_args"})
  41. gui_core_context.update_data(state=Mock(), id="", payload={"args": ["wrong_args"]})
  42. def test_do_not_update_data_if_not_readable(self):
  43. with patch("taipy.gui_core._context.is_readable", side_effect=is_false):
  44. with patch("taipy.gui_core._context.core_get", side_effect=core_get) as mock_core_get:
  45. with patch.object(DataNode, "write") as mock_write:
  46. mockGui = Mock(Gui)
  47. mockGui._get_client_id = lambda: "a_client_id"
  48. gui_core_context = _GuiCoreContext(mockGui)
  49. assign = Mock()
  50. gui_core_context.update_data(
  51. state=MockState(assign=assign),
  52. id="",
  53. payload={"args": [{"id": dn.id, "error_id": "error_var"}]},
  54. )
  55. mock_core_get.assert_not_called()
  56. mock_write.assert_not_called()
  57. assign.assert_called_once_with("error_var", f"Data node {dn.id} is not readable: foo.")
  58. def test_do_not_update_data_if_not_editable(self):
  59. with patch("taipy.gui_core._context.is_readable", side_effect=is_true):
  60. with patch("taipy.gui_core._context.is_editable", side_effect=is_false):
  61. with patch("taipy.gui_core._context.core_get", side_effect=core_get) as mock_core_get:
  62. with patch.object(DataNode, "write") as mock_write:
  63. mockGui = Mock(Gui)
  64. mockGui._get_client_id = lambda: "a_client_id"
  65. gui_core_context = _GuiCoreContext(mockGui)
  66. assign = Mock()
  67. gui_core_context.update_data(
  68. state=MockState(assign=assign),
  69. id="",
  70. payload={"args": [{"id": dn.id, "error_id": "error_var"}]},
  71. )
  72. mock_core_get.assert_not_called()
  73. mock_write.assert_not_called()
  74. assign.assert_called_once_with("error_var", f"Data node {dn.id} is not editable: foo.")
  75. def test_write_str_data_with_editor_and_comment(self):
  76. with patch("taipy.gui_core._context.is_readable", side_effect=is_true):
  77. with patch("taipy.gui_core._context.is_editable", side_effect=is_true):
  78. with patch("taipy.gui_core._context.core_get", side_effect=core_get) as mock_core_get:
  79. with patch.object(DataNode, "write") as mock_write:
  80. mockGui = Mock(Gui)
  81. mockGui._get_client_id = lambda: "a_client_id"
  82. gui_core_context = _GuiCoreContext(mockGui)
  83. assign = Mock()
  84. gui_core_context.update_data(
  85. state=MockState(assign=assign),
  86. id="",
  87. payload={
  88. "args": [
  89. {
  90. "id": dn.id,
  91. "value": "data to write",
  92. "comment": "The comment",
  93. "error_id": "error_var",
  94. }
  95. ],
  96. },
  97. )
  98. mock_core_get.assert_called_once_with(dn.id)
  99. mock_write.assert_called_once_with(
  100. "data to write", editor_id="a_client_id", comment="The comment"
  101. )
  102. assign.assert_called_once_with("error_var", "")
  103. def test_write_date_data_with_editor_and_comment(self):
  104. with patch("taipy.gui_core._context.is_readable", side_effect=is_true):
  105. with patch("taipy.gui_core._context.is_editable", side_effect=is_true):
  106. with patch("taipy.gui_core._context.core_get", side_effect=core_get) as mock_core_get:
  107. with patch.object(DataNode, "write") as mock_write:
  108. mockGui = Mock(Gui)
  109. mockGui._get_client_id = lambda: "a_client_id"
  110. gui_core_context = _GuiCoreContext(mockGui)
  111. assign = Mock()
  112. date = datetime(2000, 1, 1, 0, 0, 0)
  113. gui_core_context.update_data(
  114. state=MockState(assign=assign),
  115. id="",
  116. payload={
  117. "args": [
  118. {
  119. "id": dn.id,
  120. "value": "2000-01-01 00:00:00",
  121. "type": "date",
  122. "comment": "The comment",
  123. "error_id": "error_var",
  124. }
  125. ],
  126. },
  127. )
  128. mock_core_get.assert_called_once_with(dn.id)
  129. mock_write.assert_called_once_with(date, editor_id="a_client_id", comment="The comment")
  130. assign.assert_called_once_with("error_var", "")
  131. def test_write_int_data_with_editor_and_comment(self):
  132. with patch("taipy.gui_core._context.is_readable", side_effect=is_true):
  133. with patch("taipy.gui_core._context.is_editable", side_effect=is_true):
  134. with patch("taipy.gui_core._context.core_get", side_effect=core_get) as mock_core_get:
  135. with patch.object(DataNode, "write") as mock_write:
  136. mockGui = Mock(Gui)
  137. mockGui._get_client_id = lambda: "a_client_id"
  138. gui_core_context = _GuiCoreContext(mockGui)
  139. assign = Mock()
  140. gui_core_context.update_data(
  141. state=MockState(assign=assign),
  142. id="",
  143. payload={
  144. "args": [{"id": dn.id, "value": "1", "type": "int", "error_id": "error_var"}],
  145. },
  146. )
  147. mock_core_get.assert_called_once_with(dn.id)
  148. mock_write.assert_called_once_with(1, editor_id="a_client_id", comment=None)
  149. assign.assert_called_once_with("error_var", "")
  150. def test_write_float_data_with_editor_and_comment(self):
  151. with patch("taipy.gui_core._context.is_readable", side_effect=is_true):
  152. with patch("taipy.gui_core._context.is_editable", side_effect=is_true):
  153. with patch("taipy.gui_core._context.core_get", side_effect=core_get) as mock_core_get:
  154. with patch.object(DataNode, "write") as mock_write:
  155. mockGui = Mock(Gui)
  156. mockGui._get_client_id = lambda: "a_client_id"
  157. gui_core_context = _GuiCoreContext(mockGui)
  158. assign = Mock()
  159. gui_core_context.update_data(
  160. state=MockState(assign=assign),
  161. id="",
  162. payload={
  163. "args": [{"id": dn.id, "value": "1.9", "type": "float", "error_id": "error_var"}],
  164. },
  165. )
  166. mock_core_get.assert_called_once_with(dn.id)
  167. mock_write.assert_called_once_with(1.9, editor_id="a_client_id", comment=None)
  168. assign.assert_called_once_with("error_var", "")
  169. def test_fails_and_catch_the_error(self):
  170. with patch("taipy.gui_core._context.is_readable", side_effect=is_true):
  171. with patch("taipy.gui_core._context.is_editable", side_effect=is_true):
  172. with patch("taipy.gui_core._context.core_get", side_effect=core_get) as mock_core_get:
  173. with patch.object(DataNode, "write", side_effect=fails) as mock_write:
  174. mockGui = Mock(Gui)
  175. mockGui._get_client_id = lambda: "a_client_id"
  176. gui_core_context = _GuiCoreContext(mockGui)
  177. assign = Mock()
  178. gui_core_context.update_data(
  179. state=MockState(assign=assign),
  180. id="",
  181. payload={
  182. "args": [{"id": dn.id, "value": "1.9", "type": "float", "error_id": "error_var"}],
  183. },
  184. )
  185. mock_core_get.assert_called_once_with(dn.id)
  186. mock_write.assert_called_once_with(1.9, editor_id="a_client_id", comment=None)
  187. assign.assert_called_once()
  188. assert assign.call_args_list[0].args[0] == "error_var"
  189. assert "Error updating Data node value." in assign.call_args_list[0].args[1]