All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / changes (pull_request) Successful in 10s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 1m37s
CI Trade-In / backend-tests (pull_request) Successful in 2m0s
/me теперь отдаёт display_name/org/email (kopylov -> "Копылов", остальные None). TopNav использует их вместо фабрикации username-as-name; org/email фолбэк остаётся прежним для юзеров без известного профиля.
99 lines
3.7 KiB
Python
99 lines
3.7 KiB
Python
"""Tests for #657 brand-by-account — UserScope.brand resolution.
|
||
|
||
Pure-function tests against app.core.auth. White-label бренд «Практика» снят
|
||
целиком (бизнес-решение 2026-06-19): маппинг аккаунт→бренд пустой, поэтому ВСЕ
|
||
юзеры (включая praktika/kopylov) резолвятся в None (generic UI/PDF).
|
||
get_user_scope прокидывает brand в scope, который /me отдаёт фронту.
|
||
|
||
Без БД и сети: читается реальный auth/roles.yaml (ancestor-walk внутри репо).
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import os
|
||
import sys
|
||
from unittest.mock import MagicMock
|
||
|
||
# DATABASE_URL required by config before any app import (см. test_dadata.py).
|
||
os.environ.setdefault("DATABASE_URL", "postgresql+psycopg://test:test@localhost:5432/test")
|
||
|
||
# WeasyPrint stub — not installed без GTK (consistent с прочими тестами).
|
||
_wp_mock = MagicMock()
|
||
sys.modules.setdefault("weasyprint", _wp_mock)
|
||
|
||
import pytest # noqa: E402
|
||
|
||
from app.core.auth import get_brand_for_user, get_profile_for_user, get_user_scope # noqa: E402
|
||
|
||
|
||
@pytest.mark.parametrize(
|
||
("username", "expected"),
|
||
[
|
||
# «Практика» снята целиком (2026-06-19): praktika/kopylov больше не
|
||
# брендируются — маппинг пустой, все аккаунты → generic UI/PDF.
|
||
("praktika", None),
|
||
("kopylov", None),
|
||
("admin", None),
|
||
("user1", None),
|
||
("unknown_user", None),
|
||
],
|
||
)
|
||
def test_get_brand_for_user(username: str, expected: str | None) -> None:
|
||
assert get_brand_for_user(username) == expected
|
||
|
||
|
||
def test_user_scope_brand_none_for_kopylov() -> None:
|
||
# Регресс-гард: бренд снят, kopylov-оценки рендерят generic PDF.
|
||
scope = get_user_scope("kopylov")
|
||
assert scope["brand"] is None
|
||
assert scope["username"] == "kopylov"
|
||
|
||
|
||
def test_user_scope_brand_none_for_praktika() -> None:
|
||
# Бренд «Практика» удалён — praktika-аккаунт теперь generic.
|
||
scope = get_user_scope("praktika")
|
||
assert scope["brand"] is None
|
||
assert scope["username"] == "praktika"
|
||
|
||
|
||
def test_user_scope_brand_none_for_generic_user() -> None:
|
||
scope = get_user_scope("user1")
|
||
assert scope["brand"] is None
|
||
|
||
|
||
# ---------------------------------------------------------------------------
|
||
# #2046 profile fields (display_name/org/email) — TopNav real identity.
|
||
# ---------------------------------------------------------------------------
|
||
|
||
|
||
@pytest.mark.parametrize(
|
||
("username", "expected"),
|
||
[
|
||
# Единственный известный display_name — фамилия Копылова (см. комментарий
|
||
# в caddy/users.caddy.snippet). org/email для него не задокументированы —
|
||
# намеренно None, не выдумываем.
|
||
("kopylov", ("Копылов", None, None)),
|
||
("praktika", (None, None, None)),
|
||
("admin", (None, None, None)),
|
||
("user1", (None, None, None)),
|
||
("unknown_user", (None, None, None)),
|
||
],
|
||
)
|
||
def test_get_profile_for_user(
|
||
username: str, expected: tuple[str | None, str | None, str | None]
|
||
) -> None:
|
||
assert get_profile_for_user(username) == expected
|
||
|
||
|
||
def test_user_scope_display_name_kopylov() -> None:
|
||
scope = get_user_scope("kopylov")
|
||
assert scope["display_name"] == "Копылов"
|
||
assert scope["org"] is None
|
||
assert scope["email"] is None
|
||
|
||
|
||
def test_user_scope_profile_none_for_generic_user() -> None:
|
||
scope = get_user_scope("user1")
|
||
assert scope["display_name"] is None
|
||
assert scope["org"] is None
|
||
assert scope["email"] is None
|