test_device_semantics_postgres.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. from __future__ import annotations
  2. import os
  3. import uuid
  4. import pytest
  5. pytestmark = pytest.mark.integration
  6. def test_device_semantic_codes_keep_versions_reviews_and_search(
  7. monkeypatch,
  8. ):
  9. platform_url = os.environ.get("TEST_DATABASE_URL")
  10. if not platform_url:
  11. pytest.skip("TEST_DATABASE_URL is required")
  12. monkeypatch.setenv("DATABASE_URL", platform_url)
  13. from app import create_app, db
  14. from app.core.data_research.device_semantic_repository import (
  15. SqlAlchemyDeviceSemanticCodeRepository,
  16. )
  17. from app.core.data_research.device_semantics import (
  18. DeviceSemanticCodeService,
  19. )
  20. from app.models.data_research import (
  21. DeviceSemanticCode,
  22. DeviceSemanticCodeReview,
  23. DeviceSemanticCodeVersion,
  24. OntologyModel,
  25. )
  26. app = create_app()
  27. app.config.update(TESTING=True)
  28. ontology_uid = None
  29. created_ontology = False
  30. canonical_code = f"F-PG-{uuid.uuid4().hex[:8].upper()}"
  31. code_uid = None
  32. try:
  33. with app.app_context():
  34. existing = OntologyModel.query.filter_by(
  35. code="DEVICE_SEMANTIC"
  36. ).first()
  37. if existing is None:
  38. ontology_uid = str(uuid.uuid4())
  39. db.session.add(
  40. OntologyModel(
  41. uid=ontology_uid,
  42. code="DEVICE_SEMANTIC",
  43. name="设备语义集成验收本体",
  44. owner_uid="integration-test",
  45. status="draft",
  46. draft_revision=0,
  47. created_by="integration-test",
  48. )
  49. )
  50. created_ontology = True
  51. else:
  52. ontology_uid = str(existing.uid)
  53. db.session.commit()
  54. repository = SqlAlchemyDeviceSemanticCodeRepository(
  55. db.session
  56. )
  57. approvals = []
  58. service = DeviceSemanticCodeService(
  59. repository,
  60. review_authorizer=lambda ontology, actor: approvals.append(
  61. (ontology, actor)
  62. ),
  63. commit=db.session.commit,
  64. rollback=db.session.rollback,
  65. )
  66. created = service.create(
  67. {
  68. "ontology_uid": ontology_uid,
  69. "code_type": "fault",
  70. "canonical_code": canonical_code,
  71. "canonical_name": "轴承过热",
  72. "definition": "集成验收首版定义",
  73. "suggestion_source": "rule",
  74. "evidence_uids": ["integration-evidence-1"],
  75. },
  76. actor_uid="integration-editor",
  77. )
  78. code_uid = created.uid
  79. revised = service.revise(
  80. created.uid,
  81. {
  82. "canonical_name": "轴承温度过高",
  83. "definition": "集成验收修订定义",
  84. },
  85. expected_version=1,
  86. actor_uid="integration-editor",
  87. )
  88. service.submit(
  89. created.uid,
  90. expected_version=2,
  91. actor_uid="integration-editor",
  92. )
  93. published, review = service.review(
  94. created.uid,
  95. {
  96. "decision": "approve",
  97. "reason": "企业故障字典验收通过",
  98. "expected_version": 2,
  99. },
  100. actor_uid="integration-manager",
  101. )
  102. records, total = service.search(
  103. {
  104. "ontology_uid": ontology_uid,
  105. "code_type": "fault",
  106. "status": "published",
  107. "keyword": canonical_code,
  108. },
  109. page=1,
  110. page_size=20,
  111. )
  112. versions = service.versions(created.uid)
  113. reviews = service.reviews(created.uid)
  114. assert revised.current_version == 2
  115. assert published.status == "published"
  116. assert review.version == 2
  117. assert total == 1
  118. assert records[0].uid == created.uid
  119. assert [item.version for item in versions] == [2, 1]
  120. assert versions[0].snapshot["canonical_name"] == "轴承温度过高"
  121. assert versions[1].snapshot["canonical_name"] == "轴承过热"
  122. assert reviews == [review]
  123. assert approvals == [
  124. (ontology_uid, "integration-manager")
  125. ]
  126. finally:
  127. with app.app_context():
  128. if code_uid:
  129. db.session.query(DeviceSemanticCodeReview).filter_by(
  130. code_uid=code_uid
  131. ).delete(synchronize_session=False)
  132. db.session.query(DeviceSemanticCodeVersion).filter_by(
  133. code_uid=code_uid
  134. ).delete(synchronize_session=False)
  135. db.session.query(DeviceSemanticCode).filter_by(
  136. uid=code_uid
  137. ).delete(synchronize_session=False)
  138. if created_ontology:
  139. db.session.query(OntologyModel).filter_by(
  140. uid=ontology_uid
  141. ).delete(synchronize_session=False)
  142. db.session.commit()