conftest.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. """Test fixtures."""
  2. import asyncio
  3. import platform
  4. import uuid
  5. from collections.abc import Generator
  6. from unittest import mock
  7. import pytest
  8. from reflex.app import App
  9. from reflex.event import EventSpec
  10. from reflex.model import ModelRegistry
  11. from reflex.testing import chdir
  12. from reflex.utils import prerequisites
  13. from .states import (
  14. DictMutationTestState,
  15. ListMutationTestState,
  16. MutableTestState,
  17. SubUploadState,
  18. UploadState,
  19. )
  20. def pytest_configure(config):
  21. if config.getoption("asyncio_mode") == "auto":
  22. asyncio.set_event_loop_policy(asyncio.DefaultEventLoopPolicy())
  23. @pytest.fixture
  24. def app() -> App:
  25. """A base app.
  26. Returns:
  27. The app.
  28. """
  29. return App()
  30. @pytest.fixture
  31. def app_module_mock(monkeypatch) -> mock.Mock:
  32. """Mock the app module.
  33. This overwrites prerequisites.get_app to return the mock for the app module.
  34. To use this in your test, assign `app_module_mock.app = rx.App(...)`.
  35. Args:
  36. monkeypatch: pytest monkeypatch fixture.
  37. Returns:
  38. The mock for the main app module.
  39. """
  40. app_module_mock = mock.Mock()
  41. get_app_mock = mock.Mock(return_value=app_module_mock)
  42. monkeypatch.setattr(prerequisites, "get_app", get_app_mock)
  43. return app_module_mock
  44. @pytest.fixture(scope="session")
  45. def windows_platform() -> Generator:
  46. """Check if system is windows.
  47. Yields:
  48. whether system is windows.
  49. """
  50. yield platform.system() == "Windows"
  51. @pytest.fixture
  52. def list_mutation_state():
  53. """Create a state with list mutation features.
  54. Returns:
  55. A state with list mutation features.
  56. """
  57. return ListMutationTestState()
  58. @pytest.fixture
  59. def dict_mutation_state():
  60. """Create a state with dict mutation features.
  61. Returns:
  62. A state with dict mutation features.
  63. """
  64. return DictMutationTestState()
  65. @pytest.fixture
  66. def upload_sub_state_event_spec():
  67. """Create an event Spec for a substate.
  68. Returns:
  69. Event Spec.
  70. """
  71. return EventSpec(handler=SubUploadState.handle_upload, upload=True) # pyright: ignore [reportCallIssue]
  72. @pytest.fixture
  73. def upload_event_spec():
  74. """Create an event Spec for a multi-upload base state.
  75. Returns:
  76. Event Spec.
  77. """
  78. return EventSpec(handler=UploadState.handle_upload1, upload=True) # pyright: ignore [reportCallIssue]
  79. @pytest.fixture
  80. def base_config_values() -> dict:
  81. """Get base config values.
  82. Returns:
  83. Dictionary of base config values
  84. """
  85. return {"app_name": "app"}
  86. @pytest.fixture
  87. def base_db_config_values() -> dict:
  88. """Get base DBConfig values.
  89. Returns:
  90. Dictionary of base db config values
  91. """
  92. return {"database": "db"}
  93. @pytest.fixture
  94. def sqlite_db_config_values(base_db_config_values) -> dict:
  95. """Get sqlite DBConfig values.
  96. Args:
  97. base_db_config_values: Base DBConfig fixture.
  98. Returns:
  99. Dictionary of sqlite DBConfig values
  100. """
  101. base_db_config_values["engine"] = "sqlite"
  102. return base_db_config_values
  103. @pytest.fixture
  104. def router_data_headers() -> dict[str, str]:
  105. """Router data headers.
  106. Returns:
  107. client headers
  108. """
  109. return {
  110. "host": "localhost:8000",
  111. "connection": "Upgrade",
  112. "pragma": "no-cache",
  113. "cache-control": "no-cache",
  114. "user-agent": "Mock Agent",
  115. "upgrade": "websocket",
  116. "origin": "http://localhost:3000",
  117. "sec-websocket-version": "13",
  118. "accept-encoding": "gzip, deflate, br",
  119. "accept-language": "en-US,en;q=0.9",
  120. "cookie": "csrftoken=mocktoken; "
  121. "name=reflex;"
  122. " list_cookies=%5B%22some%22%2C%20%22random%22%2C%20%22cookies%22%5D;"
  123. " dict_cookies=%7B%22name%22%3A%20%22reflex%22%7D; val=true",
  124. "sec-websocket-key": "mock-websocket-key",
  125. "sec-websocket-extensions": "permessage-deflate; client_max_window_bits",
  126. }
  127. @pytest.fixture
  128. def router_data(router_data_headers: dict[str, str]) -> dict[str, str | dict]:
  129. """Router data.
  130. Args:
  131. router_data_headers: Headers fixture.
  132. Returns:
  133. Dict of router data.
  134. """
  135. return {
  136. "pathname": "/",
  137. "query": {},
  138. "token": "b181904c-3953-4a79-dc18-ae9518c22f05",
  139. "sid": "9fpxSzPb9aFMb4wFAAAH",
  140. "headers": router_data_headers,
  141. "ip": "127.0.0.1",
  142. }
  143. @pytest.fixture
  144. def tmp_working_dir(tmp_path):
  145. """Create a temporary directory and chdir to it.
  146. After the test executes, chdir back to the original working directory.
  147. Args:
  148. tmp_path: pytest tmp_path fixture creates per-test temp dir
  149. Yields:
  150. subdirectory of tmp_path which is now the current working directory.
  151. """
  152. working_dir = tmp_path / "working_dir"
  153. working_dir.mkdir()
  154. with chdir(working_dir):
  155. yield working_dir
  156. @pytest.fixture
  157. def mutable_state() -> MutableTestState:
  158. """Create a Test state containing mutable types.
  159. Returns:
  160. A state object.
  161. """
  162. return MutableTestState()
  163. @pytest.fixture(scope="function")
  164. def token() -> str:
  165. """Create a token.
  166. Returns:
  167. A fresh/unique token string.
  168. """
  169. return str(uuid.uuid4())
  170. @pytest.fixture
  171. def model_registry() -> Generator[type[ModelRegistry], None, None]:
  172. """Create a model registry.
  173. Yields:
  174. A fresh model registry.
  175. """
  176. yield ModelRegistry
  177. ModelRegistry._metadata = None