147 lines
5.4 KiB
Python
147 lines
5.4 KiB
Python
from __future__ import annotations
|
|
|
|
import time
|
|
|
|
import fitz
|
|
import pytest
|
|
|
|
from .conftest import TenantSeed
|
|
from .helpers import ReleaseApiClient
|
|
|
|
|
|
def _document_ids(items: list[dict]) -> set[int]:
|
|
return {int(item["documentId"]) for item in items if item.get("documentId") is not None}
|
|
|
|
|
|
def _sample_pdf_bytes(text: str) -> bytes:
|
|
document = fitz.open()
|
|
page = document.new_page()
|
|
page.insert_text((72, 72), text)
|
|
return document.tobytes()
|
|
|
|
|
|
@pytest.mark.release
|
|
def test_g4_document_list_and_detail_respect_tenant_boundary(
|
|
tenant_admin_api: ReleaseApiClient,
|
|
tenant_admin_api_b: ReleaseApiClient,
|
|
tenant_a: TenantSeed,
|
|
tenant_b: TenantSeed,
|
|
make_release_document,
|
|
) -> None:
|
|
own_doc = make_release_document(
|
|
client=tenant_admin_api,
|
|
tenant=tenant_a,
|
|
file_name=f"pytest-g4-a-{int(time.time())}.txt",
|
|
)
|
|
other_doc = make_release_document(
|
|
client=tenant_admin_api_b,
|
|
tenant=tenant_b,
|
|
file_name=f"pytest-g4-b-{int(time.time())}.txt",
|
|
)
|
|
|
|
own_list = ReleaseApiClient.json_data(tenant_admin_api.get("/api/documents/list?page=1&pageSize=100"))
|
|
own_ids = _document_ids(own_list["documents"])
|
|
assert own_doc.document_id in own_ids
|
|
assert other_doc.document_id not in own_ids
|
|
|
|
own_detail = ReleaseApiClient.json_data(tenant_admin_api.get(f"/api/documents/{own_doc.document_id}"))
|
|
assert int(own_detail["documentId"]) == own_doc.document_id
|
|
assert str(own_detail.get("tenantCode") or "") == tenant_a.tenant_code
|
|
|
|
cross_detail = tenant_admin_api.get(f"/api/documents/{other_doc.document_id}", expected_status=404)
|
|
assert "无权访问" in cross_detail.text or "不存在" in cross_detail.text
|
|
|
|
|
|
@pytest.mark.release
|
|
def test_g4_document_update_append_and_delete_reject_cross_tenant_access(
|
|
tenant_admin_api: ReleaseApiClient,
|
|
tenant_admin_api_b: ReleaseApiClient,
|
|
tenant_a: TenantSeed,
|
|
make_release_document,
|
|
) -> None:
|
|
own_doc = make_release_document(
|
|
client=tenant_admin_api,
|
|
tenant=tenant_a,
|
|
file_name=f"pytest-g4-own-{int(time.time())}.pdf",
|
|
content=_sample_pdf_bytes("pytest g4 own document"),
|
|
content_type="application/pdf",
|
|
)
|
|
|
|
update_response = tenant_admin_api.put(
|
|
f"/api/documents/{own_doc.document_id}",
|
|
json={"remark": "pytest g4 own update"},
|
|
expected_status=200,
|
|
)
|
|
update_data = ReleaseApiClient.json_data(update_response)
|
|
assert int(update_data["documentId"]) == own_doc.document_id
|
|
|
|
append_response = tenant_admin_api.post(
|
|
f"/api/documents/{own_doc.document_id}/attachments",
|
|
data={"mergeMode": "new", "remark": "pytest attachment"},
|
|
files=[("files", ("attachment.pdf", _sample_pdf_bytes("pytest attachment"), "application/pdf"))],
|
|
expected_status=200,
|
|
)
|
|
append_data = ReleaseApiClient.json_data(append_response)
|
|
new_document_id = int(append_data["documentId"])
|
|
assert new_document_id != own_doc.document_id
|
|
assert str(append_data.get("tenantCode") or "") == tenant_a.tenant_code
|
|
assert int(append_data.get("previousVersionId") or 0) == own_doc.document_id
|
|
|
|
cross_update = tenant_admin_api_b.put(
|
|
f"/api/documents/{new_document_id}",
|
|
json={"remark": "should fail"},
|
|
expected_status=404,
|
|
)
|
|
assert "无权访问" in cross_update.text or "不存在" in cross_update.text
|
|
|
|
cross_append = tenant_admin_api_b.post(
|
|
f"/api/documents/{new_document_id}/attachments",
|
|
data={"mergeMode": "new", "remark": "should fail"},
|
|
files=[("files", ("cross.pdf", _sample_pdf_bytes("cross tenant"), "application/pdf"))],
|
|
expected_status=404,
|
|
)
|
|
assert "无权访问" in cross_append.text or "不存在" in cross_append.text
|
|
|
|
cross_delete = tenant_admin_api_b.delete(f"/api/documents/{new_document_id}", expected_status=404)
|
|
assert "无权访问" in cross_delete.text or "不存在" in cross_delete.text
|
|
|
|
|
|
@pytest.mark.release
|
|
def test_g4_common_user_only_sees_self_created_documents(
|
|
common_api_a: ReleaseApiClient,
|
|
tenant_admin_api: ReleaseApiClient,
|
|
tenant_a: TenantSeed,
|
|
make_release_document,
|
|
) -> None:
|
|
user_doc = make_release_document(
|
|
client=common_api_a,
|
|
tenant=tenant_a,
|
|
file_name=f"pytest-g4-common-self-{int(time.time())}.txt",
|
|
)
|
|
admin_doc = make_release_document(
|
|
client=tenant_admin_api,
|
|
tenant=tenant_a,
|
|
file_name=f"pytest-g4-common-other-{int(time.time())}.txt",
|
|
)
|
|
|
|
own_list = ReleaseApiClient.json_data(common_api_a.get("/api/documents/list?page=1&pageSize=100"))
|
|
own_ids = _document_ids(own_list["documents"])
|
|
assert user_doc.document_id in own_ids
|
|
assert admin_doc.document_id not in own_ids
|
|
|
|
own_detail = ReleaseApiClient.json_data(common_api_a.get(f"/api/documents/{user_doc.document_id}"))
|
|
assert int(own_detail["documentId"]) == user_doc.document_id
|
|
|
|
hidden_detail = common_api_a.get(f"/api/documents/{admin_doc.document_id}", expected_status=404)
|
|
assert "无权访问" in hidden_detail.text or "不存在" in hidden_detail.text
|
|
|
|
|
|
@pytest.mark.release
|
|
def test_g4_govdoc_list_endpoint_does_not_fail_when_backfilling_version_groups(
|
|
tenant_admin_api: ReleaseApiClient,
|
|
) -> None:
|
|
response = tenant_admin_api.get("/api/govdoc/documents?page=1&pageSize=10", expected_status=200)
|
|
payload = response.json()
|
|
assert payload.get("code") in {0, 200}, payload
|
|
assert "data" in payload, payload
|