from __future__ import annotations from sqlalchemy import create_engine from sqlalchemy.orm import Session, sessionmaker from sqlalchemy.pool import StaticPool from app.db.base import Base from app.schemas.auth import LoginRequest from app.services.auth import AuthService from app.services.employee import EmployeeService def build_session() -> Session: engine = create_engine( "sqlite+pysqlite:///:memory:", connect_args={"check_same_thread": False}, poolclass=StaticPool, ) Base.metadata.create_all(bind=engine) session_factory = sessionmaker(bind=engine, autoflush=False, autocommit=False) return session_factory() def test_employee_can_login_with_seed_default_password() -> None: with build_session() as db: employee = EmployeeService(db).list_employees()[0] result = AuthService(db).login( LoginRequest(username=employee.email, password="123456") ) assert result.ok is True assert result.user.username == employee.email assert result.user.name == employee.name assert result.user.roleCodes assert result.user.isAdmin is False def test_admin_can_login_with_secret(monkeypatch) -> None: with build_session() as db: monkeypatch.setattr( "app.services.auth.read_admin_secret", lambda: { "username": "superadmin", "algorithm": "scrypt", "salt": "00", "derived_key": "00", }, ) monkeypatch.setattr("app.services.auth.verify_admin_secret", lambda password, record: password == "admin123") result = AuthService(db).login( LoginRequest(username="superadmin", password="admin123") ) assert result.ok is True assert result.user.username == "superadmin" assert result.user.isAdmin is True assert result.user.roleCodes == ["manager"] def test_disabled_employee_cannot_login() -> None: with build_session() as db: service = EmployeeService(db) employee = service.list_employees()[0] service.disable_employee(employee.id) try: AuthService(db).login(LoginRequest(username=employee.email, password="123456")) except ValueError as exc: assert "账号或密码错误" in str(exc) else: raise AssertionError("disabled employee login should be rejected")