|
7 | 7 |
|
8 | 8 | from models.model import App, AppModelConfig |
9 | 9 | from services.account_service import AccountService, TenantService |
10 | | -from services.app_dsl_service import AppDslService, ImportMode, ImportStatus |
| 10 | +from services.app_dsl_service import CURRENT_DSL_VERSION, AppDslService, ImportMode, ImportStatus |
11 | 11 | from services.app_service import AppService |
12 | 12 | from tests.test_containers_integration_tests.helpers import generate_valid_password |
13 | 13 |
|
@@ -118,7 +118,7 @@ def _create_simple_yaml_content(self, app_name="Test App", app_mode="chat"): |
118 | 118 | Helper method to create simple YAML content for testing. |
119 | 119 | """ |
120 | 120 | yaml_data = { |
121 | | - "version": "0.3.0", |
| 121 | + "version": CURRENT_DSL_VERSION, |
122 | 122 | "kind": "app", |
123 | 123 | "app": { |
124 | 124 | "name": app_name, |
@@ -407,6 +407,64 @@ def test_export_dsl_with_invalid_workflow_id_raises_error( |
407 | 407 | app, "invalid-workflow-id" |
408 | 408 | ) |
409 | 409 |
|
| 410 | + def test_import_chat_app_with_engine_session( |
| 411 | + self, flask_app_with_containers, mock_external_service_dependencies |
| 412 | + ): |
| 413 | + """ |
| 414 | + Test that importing a chat app via Session(db.engine) succeeds. |
| 415 | +
|
| 416 | + This verifies the fix that replaced ``sessionmaker(db.engine).begin()`` |
| 417 | + with ``Session(db.engine)`` in AppImportApi.post(). The previous |
| 418 | + approach returned a ``SessionTransaction`` instead of a ``Session``, |
| 419 | + which broke AppDslService operations such as ``session.scalar()`` and |
| 420 | + ``session.add()``. |
| 421 | + """ |
| 422 | + from sqlalchemy.orm import Session as SASession |
| 423 | + |
| 424 | + from extensions.ext_database import db |
| 425 | + |
| 426 | + fake = Faker() |
| 427 | + yaml_content = self._create_simple_yaml_content(fake.company(), "chat") |
| 428 | + |
| 429 | + with flask_app_with_containers.app_context(): |
| 430 | + # Create account / tenant via the global scoped session so that the |
| 431 | + # data is visible to the new engine-bound session below. |
| 432 | + with patch("services.account_service.FeatureService") as mock_fs: |
| 433 | + mock_fs.get_system_features.return_value.is_allow_register = True |
| 434 | + account = AccountService.create_account( |
| 435 | + email=fake.email(), |
| 436 | + name=fake.name(), |
| 437 | + interface_language="en-US", |
| 438 | + password=generate_valid_password(fake), |
| 439 | + ) |
| 440 | + TenantService.create_owner_tenant_if_not_exist(account, name=fake.company()) |
| 441 | + |
| 442 | + # Open a standalone Session(db.engine) – the same way the |
| 443 | + # controller does after the fix. |
| 444 | + with SASession(db.engine) as session: |
| 445 | + dsl_service = AppDslService(session) |
| 446 | + result = dsl_service.import_app( |
| 447 | + account=account, |
| 448 | + import_mode=ImportMode.YAML_CONTENT, |
| 449 | + yaml_content=yaml_content, |
| 450 | + name="Engine-session import", |
| 451 | + ) |
| 452 | + session.commit() |
| 453 | + |
| 454 | + assert result.status == ImportStatus.COMPLETED |
| 455 | + assert result.app_id is not None |
| 456 | + |
| 457 | + # Verify the app was persisted. |
| 458 | + with SASession(db.engine) as verify_session: |
| 459 | + app = verify_session.get(App, result.app_id) |
| 460 | + assert app is not None |
| 461 | + assert app.name == "Engine-session import" |
| 462 | + assert app.mode == "chat" |
| 463 | + |
| 464 | + # Verify the model config was persisted. |
| 465 | + model_cfg = verify_session.get(AppModelConfig, app.app_model_config_id) |
| 466 | + assert model_cfg is not None |
| 467 | + |
410 | 468 | def test_check_dependencies_success(self, db_session_with_containers, mock_external_service_dependencies): |
411 | 469 | """ |
412 | 470 | Test successful dependency checking. |
|
0 commit comments