reflex/tests/conftest.py
2023-06-27 18:04:29 -07:00

482 lines
12 KiB
Python

"""Test fixtures."""
import platform
from typing import Dict, Generator, List
import pytest
import reflex as rx
from reflex import constants
from reflex.event import EventSpec
@pytest.fixture(scope="function")
def windows_platform() -> Generator:
"""Check if system is windows.
Yields:
whether system is windows.
"""
yield platform.system() == "Windows"
@pytest.fixture
def list_mutation_state():
"""Create a state with list mutation features.
Returns:
A state with list mutation features.
"""
class TestState(rx.State):
"""The test state."""
# plain list
plain_friends = ["Tommy"]
def make_friend(self):
self.plain_friends.append("another-fd")
def change_first_friend(self):
self.plain_friends[0] = "Jenny"
def unfriend_all_friends(self):
self.plain_friends.clear()
def unfriend_first_friend(self):
del self.plain_friends[0]
def remove_last_friend(self):
self.plain_friends.pop()
def make_friends_with_colleagues(self):
colleagues = ["Peter", "Jimmy"]
self.plain_friends.extend(colleagues)
def remove_tommy(self):
self.plain_friends.remove("Tommy")
# list in dict
friends_in_dict = {"Tommy": ["Jenny"]}
def remove_jenny_from_tommy(self):
self.friends_in_dict["Tommy"].remove("Jenny")
def add_jimmy_to_tommy_friends(self):
self.friends_in_dict["Tommy"].append("Jimmy")
def tommy_has_no_fds(self):
self.friends_in_dict["Tommy"].clear()
# nested list
friends_in_nested_list = [["Tommy"], ["Jenny"]]
def remove_first_group(self):
self.friends_in_nested_list.pop(0)
def remove_first_person_from_first_group(self):
self.friends_in_nested_list[0].pop(0)
def add_jimmy_to_second_group(self):
self.friends_in_nested_list[1].append("Jimmy")
return TestState()
@pytest.fixture
def dict_mutation_state():
"""Create a state with dict mutation features.
Returns:
A state with dict mutation features.
"""
class TestState(rx.State):
"""The test state."""
# plain dict
details = {"name": "Tommy"}
def add_age(self):
self.details.update({"age": 20}) # type: ignore
def change_name(self):
self.details["name"] = "Jenny"
def remove_last_detail(self):
self.details.popitem()
def clear_details(self):
self.details.clear()
def remove_name(self):
del self.details["name"]
def pop_out_age(self):
self.details.pop("age")
# dict in list
address = [{"home": "home address"}, {"work": "work address"}]
def remove_home_address(self):
self.address[0].pop("home")
def add_street_to_home_address(self):
self.address[0]["street"] = "street address"
# nested dict
friend_in_nested_dict = {"name": "Nikhil", "friend": {"name": "Alek"}}
def change_friend_name(self):
self.friend_in_nested_dict["friend"]["name"] = "Tommy"
def remove_friend(self):
self.friend_in_nested_dict.pop("friend")
def add_friend_age(self):
self.friend_in_nested_dict["friend"]["age"] = 30
return TestState()
class UploadState(rx.State):
"""The base state for uploading a file."""
async def handle_upload1(self, files: List[rx.UploadFile]):
"""Handle the upload of a file.
Args:
files: The uploaded files.
"""
pass
class BaseState(rx.State):
"""The test base state."""
pass
class SubUploadState(BaseState):
"""The test substate."""
img: str
async def handle_upload(self, files: List[rx.UploadFile]):
"""Handle the upload of a file.
Args:
files: The uploaded files.
"""
pass
@pytest.fixture
def upload_sub_state_event_spec():
"""Create an event Spec for a substate.
Returns:
Event Spec.
"""
return EventSpec(handler=SubUploadState.handle_upload, upload=True) # type: ignore
@pytest.fixture
def upload_event_spec():
"""Create an event Spec for a multi-upload base state.
Returns:
Event Spec.
"""
return EventSpec(handler=UploadState.handle_upload1, upload=True) # type: ignore
@pytest.fixture
def upload_state(tmp_path):
"""Create upload state.
Args:
tmp_path: pytest tmp_path
Returns:
The state
"""
class FileUploadState(rx.State):
"""The base state for uploading a file."""
img_list: List[str]
async def handle_upload2(self, files):
"""Handle the upload of a file.
Args:
files: The uploaded files.
"""
for file in files:
upload_data = await file.read()
outfile = f"{tmp_path}/{file.filename}"
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
self.img_list.append(file.filename)
async def multi_handle_upload(self, files: List[rx.UploadFile]):
"""Handle the upload of a file.
Args:
files: The uploaded files.
"""
for file in files:
upload_data = await file.read()
outfile = f"{tmp_path}/{file.filename}"
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
assert file.filename is not None
self.img_list.append(file.filename)
return FileUploadState
@pytest.fixture
def upload_sub_state(tmp_path):
"""Create upload substate.
Args:
tmp_path: pytest tmp_path
Returns:
The state
"""
class FileState(rx.State):
"""The base state."""
pass
class FileUploadState(FileState):
"""The substate for uploading a file."""
img_list: List[str]
async def handle_upload2(self, files):
"""Handle the upload of a file.
Args:
files: The uploaded files.
"""
for file in files:
upload_data = await file.read()
outfile = f"{tmp_path}/{file.filename}"
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
self.img_list.append(file.filename)
async def multi_handle_upload(self, files: List[rx.UploadFile]):
"""Handle the upload of a file.
Args:
files: The uploaded files.
"""
for file in files:
upload_data = await file.read()
outfile = f"{tmp_path}/{file.filename}"
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
assert file.filename is not None
self.img_list.append(file.filename)
return FileUploadState
@pytest.fixture
def upload_grand_sub_state(tmp_path):
"""Create upload grand-state.
Args:
tmp_path: pytest tmp_path
Returns:
The state
"""
class BaseFileState(rx.State):
"""The base state."""
pass
class FileSubState(BaseFileState):
"""The substate."""
pass
class FileUploadState(FileSubState):
"""The grand-substate for uploading a file."""
img_list: List[str]
async def handle_upload2(self, files):
"""Handle the upload of a file.
Args:
files: The uploaded files.
"""
for file in files:
upload_data = await file.read()
outfile = f"{tmp_path}/{file.filename}"
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
assert file.filename is not None
self.img_list.append(file.filename)
async def multi_handle_upload(self, files: List[rx.UploadFile]):
"""Handle the upload of a file.
Args:
files: The uploaded files.
"""
for file in files:
upload_data = await file.read()
outfile = f"{tmp_path}/{file.filename}"
# Save the file.
with open(outfile, "wb") as file_object:
file_object.write(upload_data)
# Update the img var.
assert file.filename is not None
self.img_list.append(file.filename)
return FileUploadState
@pytest.fixture
def base_config_values() -> Dict:
"""Get base config values.
Returns:
Dictionary of base config values
"""
return {"app_name": "app", "db_url": constants.DB_URL, "env": rx.Env.DEV}
@pytest.fixture
def base_db_config_values() -> Dict:
"""Get base DBConfig values.
Returns:
Dictionary of base db config values
"""
return {"database": "db"}
@pytest.fixture
def sqlite_db_config_values(base_db_config_values) -> Dict:
"""Get sqlite DBConfig values.
Args:
base_db_config_values: Base DBConfig fixture.
Returns:
Dictionary of sqlite DBConfig values
"""
base_db_config_values["engine"] = "sqlite"
return base_db_config_values
class GenState(rx.State):
"""A state with event handlers that generate multiple updates."""
value: int
def go(self, c: int):
"""Increment the value c times and update each time.
Args:
c: The number of times to increment.
Yields:
After each increment.
"""
for _ in range(c):
self.value += 1
yield
@pytest.fixture
def gen_state() -> GenState:
"""A state.
Returns:
A test state.
"""
return GenState # type: ignore
@pytest.fixture
def router_data_headers() -> Dict[str, str]:
"""Router data headers.
Returns:
client headers
"""
return {
"host": "localhost:8000",
"connection": "Upgrade",
"pragma": "no-cache",
"cache-control": "no-cache",
"user-agent": "Mock Agent",
"upgrade": "websocket",
"origin": "http://localhost:3000",
"sec-websocket-version": "13",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.9",
"cookie": "csrftoken=mocktoken; "
"name=reflex;"
" list_cookies=%5B%22some%22%2C%20%22random%22%2C%20%22cookies%22%5D;"
" dict_cookies=%7B%22name%22%3A%20%22reflex%22%7D; val=true",
"sec-websocket-key": "mock-websocket-key",
"sec-websocket-extensions": "permessage-deflate; client_max_window_bits",
}
@pytest.fixture
def router_data(router_data_headers) -> Dict[str, str]:
"""Router data.
Args:
router_data_headers: Headers fixture.
Returns:
Dict of router data.
"""
return { # type: ignore
"pathname": "/",
"query": {},
"token": "b181904c-3953-4a79-dc18-ae9518c22f05",
"sid": "9fpxSzPb9aFMb4wFAAAH",
"headers": router_data_headers,
"ip": "127.0.0.1",
}