mirror of
https://github.com/langgenius/dify.git
synced 2026-05-31 19:00:22 -04:00
Merge branch 'main' into feat/evaluation-fe
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
"""
|
||||
Integration tests for delete_account_task.
|
||||
|
||||
These tests keep billing and email dispatch mocked, but exercise the account
|
||||
lookup through the real Testcontainers PostgreSQL session factory instead of a
|
||||
patched session_factory mock.
|
||||
"""
|
||||
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from models.account import Account
|
||||
from tasks.delete_account_task import delete_account_task
|
||||
|
||||
|
||||
def _create_account(db_session: Session, *, email: str = "user@example.com") -> Account:
|
||||
account = Account(
|
||||
name=f"account-{uuid4()}",
|
||||
email=email,
|
||||
)
|
||||
db_session.add(account)
|
||||
db_session.commit()
|
||||
return account
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_external_dependencies(mocker):
|
||||
billing_service = mocker.patch("tasks.delete_account_task.BillingService")
|
||||
mail_task = mocker.patch("tasks.delete_account_task.send_deletion_success_task")
|
||||
return billing_service, mail_task
|
||||
|
||||
|
||||
def test_billing_enabled_account_exists_calls_billing_and_sends_email(
|
||||
db_session_with_containers: Session, mock_external_dependencies, mocker
|
||||
) -> None:
|
||||
billing_service, mail_task = mock_external_dependencies
|
||||
account = _create_account(db_session_with_containers, email="a@b.com")
|
||||
mocker.patch("tasks.delete_account_task.dify_config.BILLING_ENABLED", True)
|
||||
|
||||
delete_account_task(account.id)
|
||||
|
||||
billing_service.delete_account.assert_called_once_with(account.id)
|
||||
mail_task.delay.assert_called_once_with(account.email)
|
||||
|
||||
|
||||
def test_billing_disabled_account_exists_sends_email_only(
|
||||
db_session_with_containers: Session, mock_external_dependencies, mocker
|
||||
) -> None:
|
||||
billing_service, mail_task = mock_external_dependencies
|
||||
account = _create_account(db_session_with_containers, email="x@y.com")
|
||||
mocker.patch("tasks.delete_account_task.dify_config.BILLING_ENABLED", False)
|
||||
|
||||
delete_account_task(account.id)
|
||||
|
||||
billing_service.delete_account.assert_not_called()
|
||||
mail_task.delay.assert_called_once_with(account.email)
|
||||
|
||||
|
||||
def test_billing_enabled_account_not_found_calls_billing_no_email(mock_external_dependencies, mocker, caplog) -> None:
|
||||
billing_service, mail_task = mock_external_dependencies
|
||||
account_id = str(uuid4())
|
||||
mocker.patch("tasks.delete_account_task.dify_config.BILLING_ENABLED", True)
|
||||
|
||||
delete_account_task(account_id)
|
||||
|
||||
billing_service.delete_account.assert_called_once_with(account_id)
|
||||
mail_task.delay.assert_not_called()
|
||||
assert any("not found" in record.getMessage().lower() for record in caplog.records)
|
||||
|
||||
|
||||
def test_billing_delete_raises_propagates_and_no_email(
|
||||
db_session_with_containers: Session, mock_external_dependencies, mocker
|
||||
) -> None:
|
||||
billing_service, mail_task = mock_external_dependencies
|
||||
account = _create_account(db_session_with_containers, email="err@example.com")
|
||||
billing_service.delete_account.side_effect = RuntimeError("billing down")
|
||||
mocker.patch("tasks.delete_account_task.dify_config.BILLING_ENABLED", True)
|
||||
|
||||
with pytest.raises(RuntimeError, match="billing down"):
|
||||
delete_account_task(account.id)
|
||||
|
||||
mail_task.delay.assert_not_called()
|
||||
@@ -1,115 +0,0 @@
|
||||
"""
|
||||
Unit tests for delete_account_task.
|
||||
|
||||
Covers:
|
||||
- Billing enabled with existing account: calls billing and sends success email
|
||||
- Billing disabled with existing account: skips billing, sends success email
|
||||
- Account not found: still calls billing when enabled, does not send email
|
||||
- Billing deletion raises: logs and re-raises, no email
|
||||
"""
|
||||
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from tasks.delete_account_task import delete_account_task
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_db_session():
|
||||
"""Mock session via session_factory.create_session()."""
|
||||
with patch("tasks.delete_account_task.session_factory") as mock_sf:
|
||||
session = MagicMock()
|
||||
cm = MagicMock()
|
||||
cm.__enter__.return_value = session
|
||||
cm.__exit__.return_value = None
|
||||
mock_sf.create_session.return_value = cm
|
||||
|
||||
yield session
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_deps():
|
||||
"""Patch external dependencies: BillingService and send_deletion_success_task."""
|
||||
with (
|
||||
patch("tasks.delete_account_task.BillingService") as mock_billing,
|
||||
patch("tasks.delete_account_task.send_deletion_success_task") as mock_mail_task,
|
||||
):
|
||||
# ensure .delay exists on the mail task
|
||||
mock_mail_task.delay = MagicMock()
|
||||
yield {
|
||||
"billing": mock_billing,
|
||||
"mail_task": mock_mail_task,
|
||||
}
|
||||
|
||||
|
||||
def _set_account_found(mock_db_session, email: str = "user@example.com"):
|
||||
account = SimpleNamespace(email=email)
|
||||
mock_db_session.scalar.return_value = account
|
||||
return account
|
||||
|
||||
|
||||
def _set_account_missing(mock_db_session):
|
||||
mock_db_session.scalar.return_value = None
|
||||
|
||||
|
||||
class TestDeleteAccountTask:
|
||||
def test_billing_enabled_account_exists_calls_billing_and_sends_email(self, mock_db_session, mock_deps):
|
||||
# Arrange
|
||||
account_id = "acc-123"
|
||||
account = _set_account_found(mock_db_session, email="a@b.com")
|
||||
|
||||
# Enable billing
|
||||
with patch("tasks.delete_account_task.dify_config.BILLING_ENABLED", True):
|
||||
# Act
|
||||
delete_account_task(account_id)
|
||||
|
||||
# Assert
|
||||
mock_deps["billing"].delete_account.assert_called_once_with(account_id)
|
||||
mock_deps["mail_task"].delay.assert_called_once_with(account.email)
|
||||
|
||||
def test_billing_disabled_account_exists_sends_email_only(self, mock_db_session, mock_deps):
|
||||
# Arrange
|
||||
account_id = "acc-456"
|
||||
account = _set_account_found(mock_db_session, email="x@y.com")
|
||||
|
||||
# Disable billing
|
||||
with patch("tasks.delete_account_task.dify_config.BILLING_ENABLED", False):
|
||||
# Act
|
||||
delete_account_task(account_id)
|
||||
|
||||
# Assert
|
||||
mock_deps["billing"].delete_account.assert_not_called()
|
||||
mock_deps["mail_task"].delay.assert_called_once_with(account.email)
|
||||
|
||||
def test_account_not_found_billing_enabled_calls_billing_no_email(self, mock_db_session, mock_deps, caplog):
|
||||
# Arrange
|
||||
account_id = "missing-id"
|
||||
_set_account_missing(mock_db_session)
|
||||
|
||||
# Enable billing
|
||||
with patch("tasks.delete_account_task.dify_config.BILLING_ENABLED", True):
|
||||
# Act
|
||||
delete_account_task(account_id)
|
||||
|
||||
# Assert
|
||||
mock_deps["billing"].delete_account.assert_called_once_with(account_id)
|
||||
mock_deps["mail_task"].delay.assert_not_called()
|
||||
# Optional: verify log contains not found message
|
||||
assert any("not found" in rec.getMessage().lower() for rec in caplog.records)
|
||||
|
||||
def test_billing_delete_raises_propagates_and_no_email(self, mock_db_session, mock_deps):
|
||||
# Arrange
|
||||
account_id = "acc-err"
|
||||
_set_account_found(mock_db_session, email="err@ex.com")
|
||||
mock_deps["billing"].delete_account.side_effect = RuntimeError("billing down")
|
||||
|
||||
# Enable billing
|
||||
with patch("tasks.delete_account_task.dify_config.BILLING_ENABLED", True):
|
||||
# Act & Assert
|
||||
with pytest.raises(RuntimeError):
|
||||
delete_account_task(account_id)
|
||||
|
||||
# Ensure email was not sent
|
||||
mock_deps["mail_task"].delay.assert_not_called()
|
||||
Reference in New Issue
Block a user