test_workflow_zip.py 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. from __future__ import annotations
  2. import io
  3. import json
  4. import unittest
  5. import zipfile
  6. from unittest.mock import patch
  7. from app.automation_service import import_workflows_zip, safe_zip_name, workflow_export_payload
  8. def workflow_payload(workflow_key: str, name: str = "测试工作流") -> dict:
  9. return {
  10. "schema_version": "workflow/v1",
  11. "workflow_key": workflow_key,
  12. "name": name,
  13. "description": "用于 ZIP 导入测试",
  14. "variables": {},
  15. "settings": {},
  16. "nodes": [],
  17. "edges": [],
  18. }
  19. def zip_bytes(items: dict[str, object]) -> bytes:
  20. buffer = io.BytesIO()
  21. with zipfile.ZipFile(buffer, "w", compression=zipfile.ZIP_DEFLATED) as archive:
  22. for name, payload in items.items():
  23. content = payload if isinstance(payload, str) else json.dumps(payload, ensure_ascii=False)
  24. archive.writestr(name, content)
  25. return buffer.getvalue()
  26. class WorkflowZipTest(unittest.TestCase):
  27. def test_import_zip_skips_duplicate_key_and_keeps_processing(self) -> None:
  28. content = zip_bytes(
  29. {
  30. "workflows/new.workflow.json": workflow_payload("zip-new"),
  31. "workflows/existing.workflow.json": workflow_payload("zip-existing"),
  32. "workflows/broken.workflow.json": "{bad json",
  33. "manifest.json": {"schema_version": "workflow-zip/v1"},
  34. }
  35. )
  36. with (
  37. patch("app.automation_service.workflow_key_exists", side_effect=lambda key: key == "zip-existing"),
  38. patch("app.automation_service.save_workflow", return_value={"id": 99, "workflow_key": "zip-new", "name": "测试工作流"}),
  39. ):
  40. result = import_workflows_zip(content)
  41. self.assertEqual(result["created_count"], 1)
  42. self.assertEqual(result["skipped_count"], 1)
  43. self.assertEqual(result["failed_count"], 1)
  44. self.assertEqual(result["skipped"][0]["workflow_key"], "zip-existing")
  45. def test_export_payload_removes_database_fields(self) -> None:
  46. payload = workflow_payload("zip-export")
  47. exported = workflow_export_payload({**payload, "id": 1, "created_at": "x", "updated_at": "y"})
  48. self.assertEqual(exported, payload)
  49. self.assertEqual(safe_zip_name("a/b:c*中文"), "a-b-c")
  50. if __name__ == "__main__":
  51. unittest.main()