from __future__ import annotations from decimal import Decimal import pytest from app import create_app from app.extensions import db from app.models import Account, AuditLog, Household, OptionItem @pytest.fixture def app(): app = create_app("testing") with app.app_context(): db.create_all() yield app db.session.remove() db.drop_all() @pytest.fixture def client(app): return app.test_client() def create_account(*, username: str, password: str, role: str, status: str = "active", display_name: str | None = None) -> Account: account = Account(username=username, role=role, status=status, display_name=display_name) account.set_password(password) db.session.add(account) db.session.commit() return account def create_option(*, option_group: str, option_code: str, option_label: str, parent_id: int | None = None) -> OptionItem: option = OptionItem( option_group=option_group, option_code=option_code, option_label=option_label, parent_id=parent_id, sort_order=10, is_enabled=True, is_system=True, ) db.session.add(option) db.session.commit() return option def create_household(**overrides: object) -> Household: household = Household( household_code=str(overrides.get("household_code", "H001")), head_name=str(overrides.get("head_name", "王大爷")), phone=str(overrides.get("phone", "13800001111")), side=str(overrides.get("side", "groom_side")), attendance_status=str(overrides.get("attendance_status", "pending")), invite_status=str(overrides.get("invite_status", "invited")), expected_attendee_count=int(str(overrides.get("expected_attendee_count", 3))), actual_attendee_count=int(str(overrides.get("actual_attendee_count", 0))), child_count=int(str(overrides.get("child_count", 0))), red_packet_child_count=int(str(overrides.get("red_packet_child_count", 0))), total_gift_amount=Decimal(str(overrides.get("total_gift_amount", "0.00"))), favor_status=str(overrides.get("favor_status", "not_given")), candy_status=str(overrides.get("candy_status", "not_given")), child_red_packet_status=str(overrides.get("child_red_packet_status", "not_given")), note=overrides.get("note", None), version=int(str(overrides.get("version", 1))), ) db.session.add(household) db.session.commit() return household def login(client, *, username: str, password: str): return client.post( "/auth/login", data={"username": username, "password": password}, follow_redirects=False, ) def test_admin_accounts_page_renders_for_admin(client, app) -> None: with app.app_context(): create_account(username="admin", password="AdminPass123!", role="admin", display_name="管理员") create_account(username="editor-user", password="EditorPass123!", role="editor", display_name="录入员") login(client, username="admin", password="AdminPass123!") response = client.get("/admin/accounts") page = response.get_data(as_text=True) assert response.status_code == 200 assert "账号管理" in page assert "editor-user" in page assert "新增账号" in page def test_admin_account_form_includes_quick_editor_role_option(client, app) -> None: with app.app_context(): create_account(username="admin", password="AdminPass123!", role="admin", display_name="管理员") login(client, username="admin", password="AdminPass123!") response = client.get("/admin/accounts/new") page = response.get_data(as_text=True) assert response.status_code == 200 assert '