mirror of
https://github.com/Cccc-owo/CheckInApp.git
synced 2026-06-17 05:56:29 +00:00
198 lines
6.8 KiB
Python
198 lines
6.8 KiB
Python
from __future__ import annotations
|
|
|
|
from fastapi import FastAPI, HTTPException
|
|
from fastapi.testclient import TestClient
|
|
from pydantic import ValidationError
|
|
import pytest
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
from backend.api import admin as admin_api
|
|
from backend.dependencies import get_current_user, get_db
|
|
from backend.models import Base, User
|
|
from backend.schemas.email_settings import EmailNotificationSettingsUpdate
|
|
from backend.services import email_settings_service
|
|
from backend.services.email_service import EmailService
|
|
from backend.services.email_settings_service import EmailSettingsService
|
|
|
|
|
|
def make_session():
|
|
engine = create_engine("sqlite:///:memory:", connect_args={"check_same_thread": False})
|
|
Base.metadata.create_all(bind=engine)
|
|
session_factory = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
session = session_factory()
|
|
return engine, session_factory, session
|
|
|
|
|
|
def test_email_settings_default_row_uses_environment_defaults_and_masks_password(
|
|
monkeypatch,
|
|
) -> None:
|
|
engine, _, session = make_session()
|
|
monkeypatch.setattr(email_settings_service.settings, "SMTP_SERVER", "smtp.example.test")
|
|
monkeypatch.setattr(email_settings_service.settings, "SMTP_PORT", 2525)
|
|
monkeypatch.setattr(email_settings_service.settings, "SMTP_SENDER_EMAIL", "mailer@example.com")
|
|
monkeypatch.setattr(email_settings_service.settings, "SMTP_SENDER_PASSWORD", "secret")
|
|
monkeypatch.setattr(email_settings_service.settings, "SMTP_USE_SSL", False)
|
|
|
|
snapshot = EmailSettingsService.get_snapshot(session)
|
|
|
|
assert snapshot.smtp_server == "smtp.example.test"
|
|
assert snapshot.smtp_port == 2525
|
|
assert snapshot.smtp_sender_email == "mailer@example.com"
|
|
assert snapshot.smtp_sender_password == "secret"
|
|
assert snapshot.has_smtp_sender_password is True
|
|
session.close()
|
|
engine.dispose()
|
|
|
|
|
|
def test_email_settings_update_preserves_and_clears_password(monkeypatch) -> None:
|
|
engine, _, session = make_session()
|
|
monkeypatch.setattr(email_settings_service.settings, "SMTP_SERVER", "smtp.example.test")
|
|
monkeypatch.setattr(email_settings_service.settings, "SMTP_PORT", 2525)
|
|
monkeypatch.setattr(email_settings_service.settings, "SMTP_SENDER_EMAIL", "mailer@example.com")
|
|
monkeypatch.setattr(email_settings_service.settings, "SMTP_SENDER_PASSWORD", "")
|
|
monkeypatch.setattr(email_settings_service.settings, "SMTP_USE_SSL", False)
|
|
|
|
EmailSettingsService.get_snapshot(session)
|
|
EmailSettingsService.update_settings(
|
|
session,
|
|
EmailNotificationSettingsUpdate(
|
|
smtp_server="smtp.changed.test",
|
|
smtp_port=587,
|
|
smtp_sender_email="ops@example.com",
|
|
smtp_use_ssl=True,
|
|
notify_token_expiring=False,
|
|
notify_check_in_success=False,
|
|
smtp_sender_password="new-secret",
|
|
),
|
|
)
|
|
|
|
updated = EmailSettingsService.get_snapshot(session)
|
|
assert updated.smtp_server == "smtp.changed.test"
|
|
assert updated.smtp_port == 587
|
|
assert updated.smtp_sender_email == "ops@example.com"
|
|
assert updated.smtp_sender_password == "new-secret"
|
|
assert updated.notify_token_expiring is False
|
|
assert updated.notify_check_in_success is False
|
|
|
|
EmailSettingsService.update_settings(
|
|
session,
|
|
EmailNotificationSettingsUpdate(
|
|
smtp_server="smtp.changed.test",
|
|
smtp_port=587,
|
|
smtp_sender_email="ops@example.com",
|
|
smtp_use_ssl=True,
|
|
notify_token_expiring=False,
|
|
notify_check_in_success=False,
|
|
clear_smtp_sender_password=True,
|
|
),
|
|
)
|
|
|
|
cleared = EmailSettingsService.get_snapshot(session)
|
|
assert cleared.smtp_sender_password in ("", None)
|
|
assert cleared.has_smtp_sender_password is False
|
|
session.close()
|
|
engine.dispose()
|
|
|
|
|
|
def test_admin_email_settings_route_rejects_non_admin() -> None:
|
|
engine, session_factory, session = make_session()
|
|
app = FastAPI()
|
|
app.include_router(admin_api.router, prefix="/api/admin")
|
|
|
|
def override_get_db():
|
|
yield session
|
|
|
|
async def override_get_current_user() -> User:
|
|
return User(id=1, alias="user", role="user", is_approved=True)
|
|
|
|
app.dependency_overrides[get_db] = override_get_db
|
|
app.dependency_overrides[get_current_user] = override_get_current_user
|
|
|
|
client = TestClient(app)
|
|
response = client.get("/api/admin/email_settings")
|
|
|
|
assert response.status_code == 403
|
|
session.close()
|
|
engine.dispose()
|
|
|
|
|
|
def test_token_expiring_notification_can_be_disabled(monkeypatch) -> None:
|
|
engine, session_factory, session = make_session()
|
|
monkeypatch.setattr(email_settings_service, "SessionLocal", session_factory)
|
|
EmailSettingsService.update_settings(
|
|
session,
|
|
EmailNotificationSettingsUpdate(
|
|
smtp_server="smtp.example.test",
|
|
smtp_port=465,
|
|
smtp_sender_email="mailer@example.com",
|
|
smtp_use_ssl=True,
|
|
notify_token_expiring=False,
|
|
notify_check_in_success=True,
|
|
),
|
|
)
|
|
|
|
sent: dict[str, object] = {}
|
|
|
|
def fake_send(*args, **kwargs) -> bool:
|
|
sent["called"] = True
|
|
return True
|
|
|
|
monkeypatch.setattr(EmailService, "send_email", fake_send)
|
|
|
|
user = User(alias="Alice", email="alice@example.com")
|
|
assert EmailService.notify_token_expiring(user, "1000") is False
|
|
assert sent == {}
|
|
session.close()
|
|
engine.dispose()
|
|
|
|
|
|
def test_success_check_in_notification_can_be_disabled(monkeypatch) -> None:
|
|
engine, session_factory, session = make_session()
|
|
monkeypatch.setattr(email_settings_service, "SessionLocal", session_factory)
|
|
EmailSettingsService.update_settings(
|
|
session,
|
|
EmailNotificationSettingsUpdate(
|
|
smtp_server="smtp.example.test",
|
|
smtp_port=465,
|
|
smtp_sender_email="mailer@example.com",
|
|
smtp_use_ssl=True,
|
|
notify_token_expiring=True,
|
|
notify_check_in_success=False,
|
|
),
|
|
)
|
|
|
|
sent: dict[str, object] = {}
|
|
|
|
def fake_send(*args, **kwargs) -> bool:
|
|
sent["called"] = True
|
|
return True
|
|
|
|
monkeypatch.setattr(EmailService, "send_email", fake_send)
|
|
|
|
user = User(alias="Alice", email="alice@example.com")
|
|
assert (
|
|
EmailService.notify_check_in_result(
|
|
user,
|
|
{"thread_id": "thread-1"},
|
|
True,
|
|
"打卡成功",
|
|
)
|
|
is False
|
|
)
|
|
assert sent == {}
|
|
session.close()
|
|
engine.dispose()
|
|
|
|
|
|
def test_email_settings_update_validates_sender_email() -> None:
|
|
with pytest.raises(ValidationError):
|
|
EmailNotificationSettingsUpdate(
|
|
smtp_server="smtp.example.test",
|
|
smtp_port=465,
|
|
smtp_sender_email="not-an-email",
|
|
smtp_use_ssl=True,
|
|
notify_token_expiring=True,
|
|
notify_check_in_success=True,
|
|
)
|