فهرست منبع

Handle file uploads with substates (#703)

Elijah Ahianyo 2 سال پیش
والد
کامیت
41e8afc92a
3فایلهای تغییر یافته به همراه95 افزوده شده و 4 حذف شده
  1. 2 1
      pynecone/utils/format.py
  2. 66 3
      tests/conftest.py
  3. 27 0
      tests/test_utils.py

+ 2 - 1
pynecone/utils/format.py

@@ -299,7 +299,8 @@ def format_upload_event(event_spec: EventSpec) -> str:
     from pynecone.compiler import templates
     from pynecone.compiler import templates
 
 
     state, name = get_event_handler_parts(event_spec.handler)
     state, name = get_event_handler_parts(event_spec.handler)
-    return f'uploadFiles({state}, {templates.RESULT}, {templates.SET_RESULT}, {state}.files, "{name}", UPLOAD)'
+    parent_state = state.split(".")[0]
+    return f'uploadFiles({parent_state}, {templates.RESULT}, {templates.SET_RESULT}, {parent_state}.files, "{state}.{name}", UPLOAD)'
 
 
 
 
 def format_query_params(router_data: Dict[str, Any]) -> Dict[str, str]:
 def format_query_params(router_data: Dict[str, Any]) -> Dict[str, str]:

+ 66 - 3
tests/conftest.py

@@ -4,7 +4,8 @@ from typing import Generator
 
 
 import pytest
 import pytest
 
 
-from pynecone.state import State
+import pynecone as pc
+from pynecone.event import EventSpec
 
 
 
 
 @pytest.fixture(scope="function")
 @pytest.fixture(scope="function")
@@ -25,7 +26,7 @@ def list_mutation_state():
         A state with list mutation features.
         A state with list mutation features.
     """
     """
 
 
-    class TestState(State):
+    class TestState(pc.State):
         """The test state."""
         """The test state."""
 
 
         # plain list
         # plain list
@@ -88,7 +89,7 @@ def dict_mutation_state():
         A state with dict mutation features.
         A state with dict mutation features.
     """
     """
 
 
-    class TestState(State):
+    class TestState(pc.State):
         """The test state."""
         """The test state."""
 
 
         # plain dict
         # plain dict
@@ -134,3 +135,65 @@ def dict_mutation_state():
             self.friend_in_nested_dict["friend"]["age"] = 30
             self.friend_in_nested_dict["friend"]["age"] = 30
 
 
     return TestState()
     return TestState()
+
+
+class UploadState(pc.State):
+    """The base state for uploading a file."""
+
+    img: str
+
+    async def handle_upload(self, file: pc.UploadFile):
+        """Handle the upload of a file.
+
+        Args:
+            file: The uploaded file.
+        """
+        upload_data = await file.read()
+        outfile = f".web/public/{file.filename}"
+
+        # Save the file.
+        with open(outfile, "wb") as file_object:
+            file_object.write(upload_data)
+
+        # Update the img var.
+        self.img = file.filename
+
+
+class BaseState(pc.State):
+    """The test base state."""
+
+    pass
+
+
+class SubUploadState(BaseState):
+    """The test substate."""
+
+    img: str
+
+    async def handle_upload(self, file: pc.UploadFile):
+        """Handle the upload of a file.
+
+        Args:
+            file: The uploaded file.
+        """
+        pass
+
+
+@pytest.fixture
+def upload_event_spec():
+    """Create an event Spec for a base state.
+
+    Returns:
+        Event Spec.
+    """
+    return EventSpec(handler=UploadState.handle_upload, upload=True)  # type: ignore
+
+
+@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

+ 27 - 0
tests/test_utils.py

@@ -285,3 +285,30 @@ def test_is_backend_variable(input, output):
 )
 )
 def test_issubclass(cls: type, cls_check: type, expected: bool):
 def test_issubclass(cls: type, cls_check: type, expected: bool):
     assert types._issubclass(cls, cls_check) == expected
     assert types._issubclass(cls, cls_check) == expected
+
+
+def test_format_upload_event(upload_event_spec):
+    """Test formatting an upload event spec.
+
+    Args:
+        upload_event_spec: The event spec fixture.
+    """
+    assert (
+        format.format_upload_event(upload_event_spec)
+        == "uploadFiles(upload_state, result, setResult, "
+        'upload_state.files, "upload_state.handle_upload", '
+        "UPLOAD)"
+    )
+
+
+def test_format_sub_state_event(upload_sub_state_event_spec):
+    """Test formatting an upload event spec of substate.
+
+    Args:
+        upload_sub_state_event_spec: The event spec fixture.
+    """
+    assert (
+        format.format_upload_event(upload_sub_state_event_spec)
+        == "uploadFiles(base_state, result, setResult, base_state.files, "
+        '"base_state.sub_upload_state.handle_upload", UPLOAD)'
+    )