mirror of
https://github.com/langgenius/dify.git
synced 2026-07-23 20:18:40 +08:00
test: use sqlite3 session in test_app_import_api (#38674)
Co-authored-by: Byron Wang <byron@dify.ai>
This commit is contained in:
parent
62db37c403
commit
f91ea49414
@ -9,13 +9,14 @@ from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from flask import Flask
|
||||
from sqlalchemy import event
|
||||
from sqlalchemy import Engine, event
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from controllers.console.app import app_import as app_import_module
|
||||
from models.account import Account
|
||||
from models.base import TypeBase
|
||||
from models.engine import db
|
||||
from models.model import App
|
||||
from models.model import App, AppMode
|
||||
from services.app_dsl_service import ImportStatus
|
||||
from services.entities.dsl_entities import CheckDependenciesResult
|
||||
from services.feature_service import SystemFeatureModel, WebAppAuthModel
|
||||
@ -66,6 +67,13 @@ def app() -> Iterator[Flask]:
|
||||
yield app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sqlite_app_engine(app: Flask) -> Engine:
|
||||
engine = db.engine
|
||||
TypeBase.metadata.create_all(engine, tables=[TypeBase.metadata.tables[App.__tablename__]])
|
||||
return engine
|
||||
|
||||
|
||||
@dataclass
|
||||
class TransactionEvents:
|
||||
commits: int = 0
|
||||
@ -93,11 +101,34 @@ def transaction_events() -> TransactionEvents:
|
||||
event.remove(Session, "after_rollback", record_rollback)
|
||||
|
||||
|
||||
def _failed_result_after_starting_transaction(
|
||||
service: app_import_module.AppDslService, *, app_id: str | None = None
|
||||
) -> _Result:
|
||||
service._session.begin()
|
||||
return _Result(ImportStatus.FAILED, app_id=app_id)
|
||||
def _install_persisting_service_result(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
*,
|
||||
method_name: str,
|
||||
result: _Result,
|
||||
) -> str:
|
||||
app_id = result.app_id or "rolled-back-app"
|
||||
|
||||
def _return_result(import_service: app_import_module.AppDslService, *_args, **_kwargs):
|
||||
import_service._session.add(
|
||||
App(
|
||||
id=app_id,
|
||||
tenant_id="tenant-1",
|
||||
name="Imported App",
|
||||
mode=AppMode.WORKFLOW,
|
||||
enable_site=True,
|
||||
enable_api=True,
|
||||
)
|
||||
)
|
||||
return result
|
||||
|
||||
monkeypatch.setattr(app_import_module.AppDslService, method_name, _return_result)
|
||||
return app_id
|
||||
|
||||
|
||||
def _assert_app_persistence(sqlite_app_engine: Engine, app_id: str, *, persisted: bool) -> None:
|
||||
with Session(sqlite_app_engine) as session:
|
||||
assert (session.get(App, app_id) is not None) is persisted
|
||||
|
||||
|
||||
class TestAppImportApi:
|
||||
@ -110,15 +141,16 @@ class TestAppImportApi:
|
||||
api,
|
||||
app: Flask,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
sqlite_app_engine: Engine,
|
||||
transaction_events: TransactionEvents,
|
||||
) -> None:
|
||||
method = unwrap(api.post)
|
||||
|
||||
_install_features(monkeypatch, enabled=False)
|
||||
monkeypatch.setattr(
|
||||
app_import_module.AppDslService,
|
||||
"import_app",
|
||||
lambda service, *_args, **_kwargs: _failed_result_after_starting_transaction(service, app_id=None),
|
||||
app_id = _install_persisting_service_result(
|
||||
monkeypatch,
|
||||
method_name="import_app",
|
||||
result=_Result(ImportStatus.FAILED, app_id=None),
|
||||
)
|
||||
|
||||
with app.test_request_context("/console/api/apps/imports", method="POST", json={"mode": "yaml-content"}):
|
||||
@ -126,6 +158,7 @@ class TestAppImportApi:
|
||||
|
||||
assert transaction_events.rollbacks == 1
|
||||
assert transaction_events.commits == 0
|
||||
_assert_app_persistence(sqlite_app_engine, app_id, persisted=False)
|
||||
assert status == 400
|
||||
assert response["status"] == ImportStatus.FAILED
|
||||
|
||||
@ -134,15 +167,16 @@ class TestAppImportApi:
|
||||
api,
|
||||
app: Flask,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
sqlite_app_engine: Engine,
|
||||
transaction_events: TransactionEvents,
|
||||
) -> None:
|
||||
method = unwrap(api.post)
|
||||
|
||||
_install_features(monkeypatch, enabled=False)
|
||||
monkeypatch.setattr(
|
||||
app_import_module.AppDslService,
|
||||
"import_app",
|
||||
lambda *_args, **_kwargs: _Result(ImportStatus.PENDING),
|
||||
app_id = _install_persisting_service_result(
|
||||
monkeypatch,
|
||||
method_name="import_app",
|
||||
result=_Result(ImportStatus.PENDING),
|
||||
)
|
||||
|
||||
with app.test_request_context("/console/api/apps/imports", method="POST", json={"mode": "yaml-content"}):
|
||||
@ -150,6 +184,7 @@ class TestAppImportApi:
|
||||
|
||||
assert transaction_events.commits == 1
|
||||
assert transaction_events.rollbacks == 0
|
||||
_assert_app_persistence(sqlite_app_engine, app_id, persisted=True)
|
||||
assert status == 202
|
||||
assert response["status"] == ImportStatus.PENDING
|
||||
|
||||
@ -158,15 +193,16 @@ class TestAppImportApi:
|
||||
api,
|
||||
app: Flask,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
sqlite_app_engine: Engine,
|
||||
transaction_events: TransactionEvents,
|
||||
) -> None:
|
||||
method = unwrap(api.post)
|
||||
|
||||
_install_features(monkeypatch, enabled=True)
|
||||
monkeypatch.setattr(
|
||||
app_import_module.AppDslService,
|
||||
"import_app",
|
||||
lambda *_args, **_kwargs: _Result(ImportStatus.COMPLETED, app_id="app-123"),
|
||||
app_id = _install_persisting_service_result(
|
||||
monkeypatch,
|
||||
method_name="import_app",
|
||||
result=_Result(ImportStatus.COMPLETED, app_id="app-123"),
|
||||
)
|
||||
update_access = MagicMock()
|
||||
monkeypatch.setattr(app_import_module.EnterpriseService.WebAppAuth, "update_app_access_mode", update_access)
|
||||
@ -176,6 +212,7 @@ class TestAppImportApi:
|
||||
|
||||
assert transaction_events.commits == 1
|
||||
assert transaction_events.rollbacks == 0
|
||||
_assert_app_persistence(sqlite_app_engine, app_id, persisted=True)
|
||||
update_access.assert_called_once_with("app-123", "private")
|
||||
assert status == 200
|
||||
assert response["status"] == ImportStatus.COMPLETED
|
||||
@ -185,6 +222,7 @@ class TestAppImportApi:
|
||||
api,
|
||||
app: Flask,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
sqlite_app_engine: Engine,
|
||||
transaction_events: TransactionEvents,
|
||||
) -> None:
|
||||
method = _unwrap(api.post)
|
||||
@ -196,10 +234,10 @@ class TestAppImportApi:
|
||||
lambda: (_make_account(), "tenant-1"),
|
||||
)
|
||||
monkeypatch.setattr(app_import_module.dify_config, "RBAC_ENABLED", True)
|
||||
monkeypatch.setattr(
|
||||
app_import_module.AppDslService,
|
||||
"import_app",
|
||||
lambda *_args, **_kwargs: _Result(ImportStatus.COMPLETED, app_id="app-123"),
|
||||
app_id = _install_persisting_service_result(
|
||||
monkeypatch,
|
||||
method_name="import_app",
|
||||
result=_Result(ImportStatus.COMPLETED, app_id="app-123"),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
app_import_module,
|
||||
@ -211,6 +249,7 @@ class TestAppImportApi:
|
||||
response, status = method()
|
||||
|
||||
assert transaction_events.commits == 1
|
||||
_assert_app_persistence(sqlite_app_engine, app_id, persisted=True)
|
||||
assert status == 200
|
||||
assert response["permission_keys"] == ["app.acl.view_layout", "app.acl.edit"]
|
||||
|
||||
@ -219,6 +258,7 @@ class TestAppImportApi:
|
||||
api,
|
||||
app: Flask,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
sqlite_app_engine: Engine,
|
||||
transaction_events: TransactionEvents,
|
||||
) -> None:
|
||||
method = _unwrap(api.post)
|
||||
@ -230,10 +270,10 @@ class TestAppImportApi:
|
||||
lambda: (_make_account(), "tenant-1"),
|
||||
)
|
||||
monkeypatch.setattr(app_import_module.dify_config, "RBAC_ENABLED", True)
|
||||
monkeypatch.setattr(
|
||||
app_import_module.AppDslService,
|
||||
"import_app",
|
||||
lambda *_args, **_kwargs: _Result(ImportStatus.COMPLETED, app_id="app-123"),
|
||||
app_id = _install_persisting_service_result(
|
||||
monkeypatch,
|
||||
method_name="import_app",
|
||||
result=_Result(ImportStatus.COMPLETED, app_id="app-123"),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
app_import_module,
|
||||
@ -249,6 +289,7 @@ class TestAppImportApi:
|
||||
response, status = method()
|
||||
|
||||
assert transaction_events.commits == 1
|
||||
_assert_app_persistence(sqlite_app_engine, app_id, persisted=True)
|
||||
assert status == 200
|
||||
assert response["permission_keys"] == []
|
||||
|
||||
@ -263,14 +304,15 @@ class TestAppImportConfirmApi:
|
||||
api,
|
||||
app: Flask,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
sqlite_app_engine: Engine,
|
||||
transaction_events: TransactionEvents,
|
||||
) -> None:
|
||||
method = unwrap(api.post)
|
||||
|
||||
monkeypatch.setattr(
|
||||
app_import_module.AppDslService,
|
||||
"confirm_import",
|
||||
lambda service, *_args, **_kwargs: _failed_result_after_starting_transaction(service),
|
||||
app_id = _install_persisting_service_result(
|
||||
monkeypatch,
|
||||
method_name="confirm_import",
|
||||
result=_Result(ImportStatus.FAILED),
|
||||
)
|
||||
|
||||
with app.test_request_context("/console/api/apps/imports/import-1/confirm", method="POST"):
|
||||
@ -278,6 +320,7 @@ class TestAppImportConfirmApi:
|
||||
|
||||
assert transaction_events.rollbacks == 1
|
||||
assert transaction_events.commits == 0
|
||||
_assert_app_persistence(sqlite_app_engine, app_id, persisted=False)
|
||||
assert status == 400
|
||||
assert response["status"] == ImportStatus.FAILED
|
||||
|
||||
@ -286,6 +329,7 @@ class TestAppImportConfirmApi:
|
||||
api,
|
||||
app: Flask,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
sqlite_app_engine: Engine,
|
||||
transaction_events: TransactionEvents,
|
||||
) -> None:
|
||||
method = _unwrap(api.post)
|
||||
@ -304,10 +348,10 @@ class TestAppImportConfirmApi:
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(app_import_module.dify_config, "RBAC_ENABLED", True)
|
||||
monkeypatch.setattr(
|
||||
app_import_module.AppDslService,
|
||||
"confirm_import",
|
||||
lambda *_args, **_kwargs: _Result(ImportStatus.COMPLETED, app_id="app-456"),
|
||||
app_id = _install_persisting_service_result(
|
||||
monkeypatch,
|
||||
method_name="confirm_import",
|
||||
result=_Result(ImportStatus.COMPLETED, app_id="app-456"),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
app_import_module,
|
||||
@ -319,6 +363,7 @@ class TestAppImportConfirmApi:
|
||||
response, status = method(import_id="import-1")
|
||||
|
||||
assert transaction_events.commits == 1
|
||||
_assert_app_persistence(sqlite_app_engine, app_id, persisted=True)
|
||||
assert status == 200
|
||||
assert response["permission_keys"] == ["app.acl.view_layout", "app.acl.edit"]
|
||||
|
||||
@ -327,6 +372,7 @@ class TestAppImportConfirmApi:
|
||||
api,
|
||||
app: Flask,
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
sqlite_app_engine: Engine,
|
||||
transaction_events: TransactionEvents,
|
||||
) -> None:
|
||||
method = _unwrap(api.post)
|
||||
@ -345,10 +391,10 @@ class TestAppImportConfirmApi:
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(app_import_module.dify_config, "RBAC_ENABLED", True)
|
||||
monkeypatch.setattr(
|
||||
app_import_module.AppDslService,
|
||||
"confirm_import",
|
||||
lambda *_args, **_kwargs: _Result(ImportStatus.COMPLETED, app_id="app-456"),
|
||||
app_id = _install_persisting_service_result(
|
||||
monkeypatch,
|
||||
method_name="confirm_import",
|
||||
result=_Result(ImportStatus.COMPLETED, app_id="app-456"),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
app_import_module,
|
||||
@ -360,6 +406,7 @@ class TestAppImportConfirmApi:
|
||||
response, status = method(import_id="import-1")
|
||||
|
||||
assert transaction_events.commits == 1
|
||||
_assert_app_persistence(sqlite_app_engine, app_id, persisted=True)
|
||||
assert status == 200
|
||||
assert response["permission_keys"] == []
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user