fix(workflow): address migration CI failures

Expose workflow lookup for Service API compatibility, tighten workflow template typing, and add focused command coverage for the migration PR.
This commit is contained in:
-LAN-
2026-05-11 13:44:13 +08:00
parent 47dc084659
commit c1e2c2e1ee
6 changed files with 104 additions and 21 deletions

View File

@ -55,6 +55,18 @@ def test_migrate_legacy_sys_files_workflows_rejects_non_positive_batch_size():
)
def test_migrate_legacy_sys_files_workflows_rejects_non_positive_limit():
with pytest.raises(click.UsageError, match="limit"):
migrate_legacy_sys_files_workflows.callback(
batch_size=100,
limit=0,
start_after_id=None,
tenant_id=None,
app_id=None,
dry_run=False,
)
def test_build_legacy_sys_files_workflow_query_uses_keyset_pagination():
stmt = workflow_migration_commands._build_legacy_sys_files_workflow_query(
start_after_id="workflow-1",
@ -96,3 +108,31 @@ def test_migrate_legacy_sys_files_workflow_batch_dry_run_rolls_back():
assert stats.last_id == "workflow-2"
session.rollback.assert_called_once()
session.commit.assert_not_called()
def test_migrate_legacy_sys_files_workflow_batch_commits_and_counts_failures(caplog):
migrated_workflow = MagicMock()
migrated_workflow.id = "workflow-1"
migrated_workflow.migrate_legacy_sys_files_graph_in_place.return_value = True
failing_workflow = MagicMock()
failing_workflow.id = "workflow-2"
failing_workflow.migrate_legacy_sys_files_graph_in_place.side_effect = RuntimeError("boom")
session = MagicMock()
session.scalars.return_value.all.return_value = [migrated_workflow, failing_workflow]
stats = workflow_migration_commands._migrate_legacy_sys_files_workflow_batch(
session=session,
start_after_id=None,
batch_size=200,
tenant_id=None,
app_id=None,
dry_run=False,
)
assert stats.scanned == 2
assert stats.migrated == 1
assert stats.failed == 1
assert stats.last_id == "workflow-2"
assert "Failed to migrate legacy" in caplog.text
session.commit.assert_called_once()
session.rollback.assert_not_called()

View File

@ -0,0 +1,33 @@
from unittest.mock import MagicMock
from commands import reset_encrypt_key_pair
from commands import workspace as workspace_commands
def test_reset_encrypt_key_pair_skips_non_self_hosted(monkeypatch, capsys):
monkeypatch.setattr(workspace_commands.dify_config, "EDITION", "CLOUD")
reset_encrypt_key_pair.callback()
captured = capsys.readouterr()
assert "only for SELF_HOSTED" in captured.out
def test_reset_encrypt_key_pair_rotates_keys_and_removes_custom_provider_data(monkeypatch, capsys):
monkeypatch.setattr(workspace_commands.dify_config, "EDITION", "SELF_HOSTED")
monkeypatch.setattr(workspace_commands, "generate_key_pair", lambda tenant_id: f"public-key-{tenant_id}")
tenant = MagicMock()
tenant.id = "tenant-1"
session = MagicMock()
session.scalars.return_value.all.return_value = [tenant]
session_manager = MagicMock()
session_manager.begin.return_value.__enter__.return_value = session
monkeypatch.setattr(workspace_commands, "sessionmaker", lambda *args, **kwargs: session_manager)
monkeypatch.setattr(workspace_commands, "db", MagicMock(engine=object()))
reset_encrypt_key_pair.callback()
assert tenant.encrypt_public_key == "public-key-tenant-1"
assert session.execute.call_count == 2
captured = capsys.readouterr()
assert "tenant-1 has been reset" in captured.out

View File

@ -22,7 +22,7 @@ def _legacy_file_graph() -> dict:
def test_hidden_service_api_file_payload_maps_to_generated_start_input(mocker):
workflow = MagicMock()
workflow.graph_dict = _legacy_file_graph()
get_workflow = mocker.patch.object(AppGenerateService, "_get_workflow", return_value=workflow)
get_workflow = mocker.patch.object(AppGenerateService, "get_workflow", return_value=workflow)
app_model = MagicMock()
files = [{"transfer_method": "remote_url", "url": "https://example.com/a.png"}]