Merge origin/develop into feature/a-card-operations
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
"""Unit tests for auth profile / password request schemas."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from backend.api.auth import PasswordChange, ProfileUpdate
|
||||
from backend.api.platform.employees import PlatformEmployeePasswordReset
|
||||
|
||||
|
||||
def test_profile_update_allows_partial_fields() -> None:
|
||||
only_name = ProfileUpdate(display_name="张三")
|
||||
assert only_name.display_name == "张三"
|
||||
assert only_name.email is None
|
||||
|
||||
only_email = ProfileUpdate(email="a@example.com")
|
||||
assert only_email.email == "a@example.com"
|
||||
|
||||
|
||||
def test_profile_update_forbids_unknown_fields() -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
ProfileUpdate(display_name="张三", username="hacked") # type: ignore[call-arg]
|
||||
|
||||
|
||||
def test_password_change_enforces_new_password_length() -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
PasswordChange(current_password="old-pass", new_password="short")
|
||||
|
||||
ok = PasswordChange(current_password="old-pass-1", new_password="new-pass-12")
|
||||
assert ok.new_password == "new-pass-12"
|
||||
|
||||
|
||||
def test_admin_password_reset_schema() -> None:
|
||||
with pytest.raises(ValidationError):
|
||||
PlatformEmployeePasswordReset(new_password="1234567")
|
||||
|
||||
payload = PlatformEmployeePasswordReset(new_password="reset-pass-9")
|
||||
assert payload.new_password == "reset-pass-9"
|
||||
@@ -0,0 +1,57 @@
|
||||
"""Unit tests for platform cursor pagination helpers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
|
||||
import pytest
|
||||
from fastapi import HTTPException
|
||||
|
||||
from backend.api.platform._pagination import (
|
||||
decode_cursor,
|
||||
encode_cursor,
|
||||
page_meta,
|
||||
)
|
||||
|
||||
|
||||
def test_encode_decode_roundtrip() -> None:
|
||||
created_at = datetime.datetime(2026, 3, 15, 12, 30, 45, 123000)
|
||||
row_id = "01HXY9C5B8N3K4P7Q6RT2V0J8D"
|
||||
cursor = encode_cursor(created_at, row_id)
|
||||
decoded_ts, decoded_id = decode_cursor(cursor)
|
||||
assert decoded_ts == created_at
|
||||
assert decoded_id == row_id
|
||||
|
||||
|
||||
def test_decode_strips_timezone() -> None:
|
||||
created_at = datetime.datetime(2026, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc)
|
||||
cursor = encode_cursor(created_at, "abc")
|
||||
decoded_ts, decoded_id = decode_cursor(cursor)
|
||||
assert decoded_ts.tzinfo is None
|
||||
assert decoded_id == "abc"
|
||||
|
||||
|
||||
def test_decode_invalid_cursor_raises_400() -> None:
|
||||
with pytest.raises(HTTPException) as exc_info:
|
||||
decode_cursor("not-a-valid-cursor!!!")
|
||||
assert exc_info.value.status_code == 400
|
||||
|
||||
|
||||
def test_page_meta_has_more() -> None:
|
||||
meta = page_meta(
|
||||
limit=10,
|
||||
page_count=10,
|
||||
total_count=25,
|
||||
next_cursor="abc",
|
||||
)
|
||||
assert meta["has_more"] is True
|
||||
assert meta["next_cursor"] == "abc"
|
||||
assert meta["total_count"] == 25
|
||||
|
||||
meta_end = page_meta(
|
||||
limit=10,
|
||||
page_count=5,
|
||||
total_count=25,
|
||||
next_cursor=None,
|
||||
)
|
||||
assert meta_end["has_more"] is False
|
||||
Reference in New Issue
Block a user