diff --git a/src/pymax/types/domain/user.py b/src/pymax/types/domain/user.py index 5059428..2c04b60 100644 --- a/src/pymax/types/domain/user.py +++ b/src/pymax/types/domain/user.py @@ -49,11 +49,11 @@ class User(CamelModel): :ivar description: Описание профиля. :vartype description: str | None :ivar gender: Пол пользователя. - :vartype gender: str | None + :vartype gender: str | int | None :ivar link: Ссылка на профиль. :vartype link: str | None :ivar web_app: Данные связанного web-приложения, если есть. - :vartype web_app: dict[str, Any] | None + :vartype web_app: dict[str, Any] | str | None :ivar menu_button: Данные кнопки меню профиля, если есть. :vartype menu_button: dict[str, Any] | None """ @@ -71,9 +71,11 @@ class User(CamelModel): phone: int | None = None status: str | None = None description: str | None = None - gender: str | None = None + # Bots may send ``gender`` as a numeric code and ``web_app`` as a URL + # string instead of an object; accept these so profile parsing won't fail. + gender: str | int | None = None link: str | None = None - web_app: dict[str, Any] | None = None + web_app: dict[str, Any] | str | None = None menu_button: dict[str, Any] | None = None _actions: UserService | None = PrivateAttr(default=None) diff --git a/tests/domain/test_user_models.py b/tests/domain/test_user_models.py new file mode 100644 index 0000000..27a1b58 --- /dev/null +++ b/tests/domain/test_user_models.py @@ -0,0 +1,35 @@ +from pymax.types.domain import User + + +def test_user_parses_bot_gender_int_and_web_app_url() -> None: + """Bot accounts send ``gender`` as a numeric code and ``web_app`` as a URL + string (observed for the "Алиса AI" bot); the profile must still parse.""" + payload = { + "id": 6738397, + "names": [{"name": "Алиса AI", "type": "NICK"}], + "gender": 1, + "webApp": "https://alice.yandex.ru/max_onboarding", + } + + user = User.model_validate(payload) + + assert user.gender == 1 + assert user.web_app == "https://alice.yandex.ru/max_onboarding" + + +def test_user_parses_human_without_optional_fields() -> None: + """Regular users come without ``gender`` and ``web_app``.""" + payload = {"id": 1, "names": [{"name": "Test User", "type": "NICK"}]} + + user = User.model_validate(payload) + + assert user.gender is None + assert user.web_app is None + + +def test_user_still_accepts_dict_web_app() -> None: + """The dict type for ``web_app`` is kept from the original PyMax schema + (no real example of this format was seen, but we keep compatibility).""" + user = User.model_validate({"id": 2, "webApp": {}}) + + assert user.web_app == {}