[REF-3334] Validate Toast Props (#3793)

This commit is contained in:
Elijah Ahianyo 2024-08-15 16:30:32 +00:00 committed by GitHub
parent b01c4b6c6a
commit 4190a79835
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 34 additions and 3 deletions

View File

@ -125,8 +125,8 @@ def default_backend_exception_handler(exception: Exception) -> EventSpec:
) )
if Toaster.is_used: if Toaster.is_used:
return toast( return toast(
"An error occurred.",
level="error", level="error",
title="An error occurred.",
description="<br/>".join(error_message), description="<br/>".join(error_message),
position="top-center", position="top-center",
id="backend_error", id="backend_error",

View File

@ -4,6 +4,8 @@ from __future__ import annotations
from typing import Any, ClassVar, Literal, Optional, Union from typing import Any, ClassVar, Literal, Optional, Union
from pydantic import ValidationError
from reflex.base import Base from reflex.base import Base
from reflex.components.component import Component, ComponentNamespace from reflex.components.component import Component, ComponentNamespace
from reflex.components.lucide.icon import Icon from reflex.components.lucide.icon import Icon
@ -27,7 +29,6 @@ LiteralPosition = Literal[
"bottom-right", "bottom-right",
] ]
toast_ref = Var.create_safe("refs['__toast']", _var_is_string=False) toast_ref = Var.create_safe("refs['__toast']", _var_is_string=False)
@ -128,6 +129,24 @@ class ToastProps(PropsBase):
# Function that gets called when the toast disappears automatically after it's timeout (duration` prop). # Function that gets called when the toast disappears automatically after it's timeout (duration` prop).
on_auto_close: Optional[Any] on_auto_close: Optional[Any]
def __init__(self, **kwargs):
"""Initialize the props.
Args:
kwargs: Kwargs to initialize the props.
Raises:
ValueError: If invalid props are passed on instantiation.
"""
try:
super().__init__(**kwargs)
except ValidationError as e:
invalid_fields = ", ".join([error["loc"][0] for error in e.errors()]) # type: ignore
supported_props_str = ", ".join(f'"{field}"' for field in self.get_fields())
raise ValueError(
f"Invalid prop(s) {invalid_fields} for rx.toast. Supported props are {supported_props_str}"
) from None
def dict(self, *args, **kwargs) -> dict[str, Any]: def dict(self, *args, **kwargs) -> dict[str, Any]:
"""Convert the object to a dictionary. """Convert the object to a dictionary.
@ -159,6 +178,13 @@ class ToastProps(PropsBase):
) )
return d return d
class Config:
"""Pydantic config."""
arbitrary_types_allowed = True
use_enum_values = True
extra = "forbid"
class Toaster(Component): class Toaster(Component):
"""A Toaster Component for displaying toast notifications.""" """A Toaster Component for displaying toast notifications."""

View File

@ -51,6 +51,11 @@ class ToastProps(PropsBase):
def dict(self, *args, **kwargs) -> dict[str, Any]: ... def dict(self, *args, **kwargs) -> dict[str, Any]: ...
class Config:
arbitrary_types_allowed = True
use_enum_values = True
extra = "forbid"
class Toaster(Component): class Toaster(Component):
is_used: ClassVar[bool] = False is_used: ClassVar[bool] = False

View File

@ -1565,7 +1565,7 @@ async def test_state_with_invalid_yield(capsys, mock_app):
assert update.events == rx.event.fix_events( assert update.events == rx.event.fix_events(
[ [
rx.toast( rx.toast(
title="An error occurred.", "An error occurred.",
description="TypeError: Your handler test_state_with_invalid_yield.<locals>.StateWithInvalidYield.invalid_handler must only return/yield: None, Events or other EventHandlers referenced by their class (not using `self`).<br/>See logs for details.", description="TypeError: Your handler test_state_with_invalid_yield.<locals>.StateWithInvalidYield.invalid_handler must only return/yield: None, Events or other EventHandlers referenced by their class (not using `self`).<br/>See logs for details.",
level="error", level="error",
id="backend_error", id="backend_error",