fix(审计): 移除共享库审计与预览噪声
This commit is contained in:
@@ -674,24 +674,30 @@ def test_subject_audit_uses_structured_business_snapshot():
|
||||
assert 'detail=f"参与者 {subject_id} 已删除"' not in delete_subject_source
|
||||
|
||||
|
||||
def test_faq_audit_uses_business_descriptions():
|
||||
"""医学咨询审计详情应使用业务描述,避免 FAQ 技术文案。"""
|
||||
def test_shared_library_does_not_write_audits():
|
||||
"""共享库各模块及其附件不应写入业务审计。"""
|
||||
api_dir = Path(__file__).resolve().parents[1] / "app" / "api" / "v1"
|
||||
category_source = (api_dir / "faq_categories.py").read_text()
|
||||
item_source = (api_dir / "faqs.py").read_text()
|
||||
services_dir = Path(__file__).resolve().parents[1] / "app" / "services"
|
||||
non_audited_sources = [
|
||||
(api_dir / "faq_categories.py").read_text(),
|
||||
(api_dir / "faqs.py").read_text(),
|
||||
(api_dir / "precautions.py").read_text(),
|
||||
(services_dir / "collaboration_service.py").read_text(),
|
||||
(services_dir / "collaboration_share_service.py").read_text(),
|
||||
(services_dir / "onlyoffice_collaboration_service.py").read_text(),
|
||||
]
|
||||
|
||||
assert 'description": f"创建“{category.name}”分类"' in category_source
|
||||
assert 'description": f"更新“{updated.name}”分类"' in category_source
|
||||
assert 'description": f"删除“{category_name}”分类"' in category_source
|
||||
assert 'f"创建医学咨询问题“{question_name}”"' in item_source
|
||||
assert 'f"更新医学咨询问题“{question_name}”"' in item_source
|
||||
assert 'f"回复医学咨询问题“{question_name}”"' in item_source
|
||||
assert 'f"删除医学咨询问题“{question_name}”"' in item_source
|
||||
assert 'f"删除医学咨询问题“{question_name}”的回复"' in item_source
|
||||
assert "FAQ 分类 {category.name} 已创建" not in category_source
|
||||
assert 'detail="FAQ 已创建"' not in item_source
|
||||
assert 'detail = "FAQ updated"' not in item_source
|
||||
assert '"description": "创建医学咨询问题"' not in item_source
|
||||
for source in non_audited_sources:
|
||||
assert "audit_crud" not in source
|
||||
assert "._audit(" not in source
|
||||
|
||||
attachment_source = (api_dir / "attachments.py").read_text()
|
||||
assert 'SHARED_LIBRARY_ENTITY_TYPES = {"precaution", "faq_replies"}' in attachment_source
|
||||
assert "if entity_type not in SHARED_LIBRARY_ENTITY_TYPES:" in attachment_source
|
||||
assert "if attachment.entity_type not in SHARED_LIBRARY_ENTITY_TYPES:" in attachment_source
|
||||
|
||||
onlyoffice_source = (api_dir / "onlyoffice.py").read_text()
|
||||
assert "OFFICE_PREVIEW_OPEN" not in onlyoffice_source
|
||||
|
||||
|
||||
def test_domain_audits_use_business_object_names():
|
||||
@@ -704,7 +710,6 @@ def test_domain_audits_use_business_object_names():
|
||||
"material_equipments.py",
|
||||
"visits.py",
|
||||
"aes.py",
|
||||
"precautions.py",
|
||||
"fees_contracts.py",
|
||||
"startup.py",
|
||||
"subject_histories.py",
|
||||
@@ -715,7 +720,6 @@ def test_domain_audits_use_business_object_names():
|
||||
assert "_equipment_audit_detail" in sources["material_equipments.py"]
|
||||
assert "_visit_audit_detail" in sources["visits.py"]
|
||||
assert "_ae_audit_detail" in sources["aes.py"]
|
||||
assert "_precaution_audit_detail" in sources["precautions.py"]
|
||||
assert "_contract_audit_detail" in sources["fees_contracts.py"]
|
||||
assert "_payment_audit_detail" in sources["fees_contracts.py"]
|
||||
assert "_feasibility_audit_detail" in sources["startup.py"]
|
||||
|
||||
@@ -140,7 +140,6 @@ async def test_copy_revision_saves_to_the_selected_workspace_folder(monkeypatch,
|
||||
content=content,
|
||||
source="COPY",
|
||||
user=user,
|
||||
source_file_id=item.id,
|
||||
)
|
||||
|
||||
|
||||
@@ -159,22 +158,13 @@ async def test_delete_revision_soft_deletes_a_non_current_version(monkeypatch):
|
||||
)
|
||||
db = SimpleNamespace(get=AsyncMock(return_value=revision), commit=AsyncMock())
|
||||
require_manager = AsyncMock()
|
||||
audit = AsyncMock()
|
||||
monkeypatch.setattr(collaboration_service, "require_file_manager", require_manager)
|
||||
monkeypatch.setattr(collaboration_service, "_audit", audit)
|
||||
|
||||
await collaboration_service.delete_revision(db, item, revision_id, user)
|
||||
|
||||
require_manager.assert_awaited_once_with(db, item, user)
|
||||
assert revision.deleted_at is not None
|
||||
assert revision.deleted_by == user.id
|
||||
audit.assert_awaited_once_with(
|
||||
db,
|
||||
item,
|
||||
"COLLABORATION_REVISION_DELETED",
|
||||
user,
|
||||
{"revision_id": str(revision_id), "revision_no": 2},
|
||||
)
|
||||
db.commit.assert_awaited_once()
|
||||
|
||||
|
||||
@@ -260,7 +250,6 @@ async def test_sheet_permission_change_updates_current_file_without_creating_rev
|
||||
user = SimpleNamespace(id=uuid.uuid4())
|
||||
db = SimpleNamespace(get=AsyncMock(return_value=revision), commit=AsyncMock(), refresh=AsyncMock())
|
||||
monkeypatch.setattr(collaboration_service, "require_file_manager", AsyncMock())
|
||||
monkeypatch.setattr(collaboration_service, "_audit", AsyncMock())
|
||||
persist_revision = AsyncMock()
|
||||
monkeypatch.setattr(collaboration_service, "_persist_revision_bytes", persist_revision)
|
||||
|
||||
@@ -540,7 +529,6 @@ async def test_share_link_url_stays_immutable_when_disabled_and_reenabled(monkey
|
||||
refresh=AsyncMock(),
|
||||
)
|
||||
monkeypatch.setattr(collaboration_service, "require_file_manager", AsyncMock())
|
||||
monkeypatch.setattr(collaboration_service, "_audit", AsyncMock())
|
||||
original_token = collaboration_share_service.share_token(link)
|
||||
|
||||
await collaboration_share_service.update_share_link(
|
||||
@@ -803,12 +791,11 @@ async def test_copy_creates_an_independent_r1_from_the_current_revision(monkeypa
|
||||
content=content,
|
||||
source="COPY",
|
||||
user=user,
|
||||
source_file_id=item.id,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_download_returns_current_revision_and_records_audit(monkeypatch, tmp_path):
|
||||
async def test_download_returns_current_revision_without_writing_audit(monkeypatch, tmp_path):
|
||||
source = tmp_path / "source.docx"
|
||||
source.write_bytes(collaboration_service.blank_file_bytes("word"))
|
||||
revision = SimpleNamespace(
|
||||
@@ -821,22 +808,33 @@ async def test_download_returns_current_revision_and_records_audit(monkeypatch,
|
||||
user = SimpleNamespace(id=uuid.uuid4())
|
||||
db = SimpleNamespace(get=AsyncMock(return_value=revision), commit=AsyncMock())
|
||||
require_exporter = AsyncMock()
|
||||
audit = AsyncMock()
|
||||
monkeypatch.setattr(collaboration_service, "require_file_exporter", require_exporter)
|
||||
monkeypatch.setattr(collaboration_service, "_audit", audit)
|
||||
|
||||
result = await collaboration_service.prepare_download(db, item, user)
|
||||
|
||||
assert result is revision
|
||||
require_exporter.assert_awaited_once_with(db, item, user)
|
||||
audit.assert_awaited_once_with(
|
||||
db.commit.assert_not_awaited()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_revision_preview_does_not_write_passive_audit(monkeypatch, tmp_path):
|
||||
revision_path = tmp_path / "revision.docx"
|
||||
revision_path.write_bytes(b"office")
|
||||
revision = SimpleNamespace(id=uuid.uuid4(), file_uri=str(revision_path), revision_no=2)
|
||||
item = SimpleNamespace(id=uuid.uuid4())
|
||||
db = SimpleNamespace(commit=AsyncMock())
|
||||
monkeypatch.setattr(collaboration_service, "get_revision_or_404", AsyncMock(return_value=revision))
|
||||
|
||||
result = await collaboration_service.prepare_revision_preview(
|
||||
db,
|
||||
item,
|
||||
"COLLABORATION_FILE_DOWNLOADED",
|
||||
user,
|
||||
{"revision_id": str(revision.id), "revision_no": 3},
|
||||
revision.id,
|
||||
SimpleNamespace(id=uuid.uuid4()),
|
||||
)
|
||||
db.commit.assert_awaited_once()
|
||||
|
||||
assert result is revision
|
||||
db.commit.assert_not_awaited()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -1041,12 +1039,6 @@ async def test_force_save_updates_session_recovery_revision(monkeypatch):
|
||||
"append_revision",
|
||||
AsyncMock(return_value=(revision, True)),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
onlyoffice_collaboration_service.collaboration_service,
|
||||
"_audit",
|
||||
AsyncMock(),
|
||||
)
|
||||
|
||||
result = await onlyoffice_collaboration_service.process_callback(
|
||||
db,
|
||||
session.id,
|
||||
|
||||
@@ -128,7 +128,6 @@ async def test_edit_request_notifies_the_active_file_owner_and_managers(monkeypa
|
||||
"get_member",
|
||||
AsyncMock(return_value=SimpleNamespace(is_active=True)),
|
||||
)
|
||||
monkeypatch.setattr(collaboration_service, "_audit", AsyncMock())
|
||||
monkeypatch.setattr(collaboration_service.notification_service, "create_recipient_notifications", notify)
|
||||
|
||||
result = await collaboration_service.create_edit_request(db, item, user)
|
||||
|
||||
@@ -39,12 +39,10 @@ async def test_attachment_config_reuses_permission_and_preserves_original_name(m
|
||||
content_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
||||
)
|
||||
permission = AsyncMock()
|
||||
audit = AsyncMock()
|
||||
monkeypatch.setattr(onlyoffice_api.attachment_crud, "get_attachment", AsyncMock(return_value=attachment))
|
||||
monkeypatch.setattr(onlyoffice_api, "_ensure_study_exists", AsyncMock())
|
||||
monkeypatch.setattr(onlyoffice_api, "_ensure_attachment_permission", permission)
|
||||
monkeypatch.setattr(onlyoffice_api.onlyoffice_service, "ensure_onlyoffice_available", AsyncMock())
|
||||
monkeypatch.setattr(onlyoffice_api, "_log_preview_open", audit)
|
||||
response = Response()
|
||||
db = object()
|
||||
|
||||
@@ -54,7 +52,6 @@ async def test_attachment_config_reuses_permission_and_preserves_original_name(m
|
||||
assert result.file_name == "研究方案最终版.DOCX"
|
||||
assert result.config["document"]["title"] == "研究方案最终版.DOCX"
|
||||
assert response.headers["Cache-Control"] == "no-store"
|
||||
audit.assert_awaited_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -96,7 +93,6 @@ async def test_version_config_reuses_document_access_and_version_hash(monkeypatc
|
||||
monkeypatch.setattr(onlyoffice_api.document_crud, "get", AsyncMock(return_value=document))
|
||||
monkeypatch.setattr(onlyoffice_api.document_service, "_ensure_study_access", access)
|
||||
monkeypatch.setattr(onlyoffice_api.onlyoffice_service, "ensure_onlyoffice_available", AsyncMock())
|
||||
monkeypatch.setattr(onlyoffice_api, "_log_preview_open", AsyncMock())
|
||||
|
||||
result = await onlyoffice_api.get_version_preview_config(version.id, Response(), object(), user)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user