Files

176 lines
6.0 KiB
Python

from __future__ import annotations
import time
import pytest
from .conftest import ReleaseDatasetSeed, TenantSeed
from .helpers import ReleaseApiClient
def _dataset_ids(items: list[dict]) -> set[int]:
return {int(item["id"]) for item in items if item.get("id") is not None}
def _app_ids(items: list[dict]) -> set[str]:
return {str(item["appId"]) for item in items if item.get("appId") is not None}
@pytest.mark.release
def test_g5_rag_dataset_admin_scope_is_limited_to_own_tenant(
admin_client: ReleaseApiClient,
tenant_admin_api: ReleaseApiClient,
tenant_admin_api_b: ReleaseApiClient,
tenant_a: TenantSeed,
tenant_b: TenantSeed,
make_release_dataset,
) -> None:
dataset_a = make_release_dataset(
tenant=tenant_a,
dataset_name=f"Pytest G5 A {int(time.time())}",
)
dataset_b = make_release_dataset(
tenant=tenant_b,
dataset_name=f"Pytest G5 B {int(time.time())}",
)
global_admin_list = ReleaseApiClient.json_data(admin_client.get("/api/v3/rag/datasets/admin?page=1&pageSize=100"))
ids_a = _dataset_ids(global_admin_list["data"])
assert dataset_a.dataset_id in ids_a
assert dataset_b.dataset_id in ids_a
tenant_admin_list = ReleaseApiClient.json_data(
tenant_admin_api.get("/api/v3/rag/datasets/admin?page=1&pageSize=100")
)
tenant_admin_ids = _dataset_ids(tenant_admin_list["data"])
assert dataset_a.dataset_id in tenant_admin_ids
assert dataset_b.dataset_id not in tenant_admin_ids
forbidden_query = tenant_admin_api.get(
f"/api/v3/rag/datasets/admin?page=1&pageSize=100&tenant_code={tenant_b.tenant_code}",
expected_status=403,
)
assert "本地区知识库配置" in forbidden_query.text or "本租户知识库" in forbidden_query.text
@pytest.mark.release
def test_g5_rag_dataset_detail_and_update_respect_tenant_boundary(
admin_client: ReleaseApiClient,
tenant_admin_api: ReleaseApiClient,
tenant_a: TenantSeed,
tenant_b: TenantSeed,
make_release_dataset,
) -> None:
dataset_a = make_release_dataset(
tenant=tenant_a,
dataset_name=f"Pytest G5 Detail A {int(time.time())}",
)
dataset_b = make_release_dataset(
tenant=tenant_b,
dataset_name=f"Pytest G5 Detail B {int(time.time())}",
)
own_detail = ReleaseApiClient.json_data(tenant_admin_api.get(f"/api/v3/rag/datasets/{dataset_a.dataset_id}"))
assert int(own_detail["id"]) == dataset_a.dataset_id
assert str(own_detail.get("tenantCode") or "") == tenant_a.tenant_code
hidden_detail = ReleaseApiClient.json_data(tenant_admin_api.get(f"/api/v3/rag/datasets/{dataset_b.dataset_id}"))
assert hidden_detail is None
own_update = ReleaseApiClient.json_data(
tenant_admin_api.patch(
f"/api/v3/rag/datasets/{dataset_a.dataset_id}",
json={"name": f"{dataset_a.dataset_name}-tenant-updated"},
expected_status=200,
)
)
assert str(own_update["name"]).endswith("-tenant-updated")
hidden_update = ReleaseApiClient.json_data(
tenant_admin_api.patch(
f"/api/v3/rag/datasets/{dataset_b.dataset_id}",
json={"name": "should-not-work"},
expected_status=200,
)
)
assert hidden_update is None
admin_update = ReleaseApiClient.json_data(
admin_client.patch(
f"/api/v3/rag/datasets/{dataset_a.dataset_id}",
json={"name": f"{dataset_a.dataset_name}-updated"},
expected_status=200,
)
)
assert str(admin_update["name"]).endswith("-updated")
@pytest.mark.release
def test_g5_rag_apps_and_public_dataset_visibility(
tenant_admin_api: ReleaseApiClient,
tenant_admin_api_b: ReleaseApiClient,
common_api_a: ReleaseApiClient,
common_api_b: ReleaseApiClient,
tenant_a: TenantSeed,
tenant_b: TenantSeed,
make_release_dataset,
) -> None:
dataset_a = make_release_dataset(
tenant=tenant_a,
dataset_name=f"Pytest G5 App A {int(time.time())}",
is_default=True,
)
dataset_b = make_release_dataset(
tenant=tenant_b,
dataset_name=f"Pytest G5 App B {int(time.time())}",
is_default=True,
)
public_dataset = make_release_dataset(
tenant=tenant_a,
dataset_name=f"Pytest G5 Public {int(time.time())}",
is_public=True,
is_default=False,
)
apps_a = ReleaseApiClient.json_data(common_api_a.get("/api/v3/rag/apps"))
app_ids_a = _app_ids(apps_a["data"])
assert dataset_a.app_id is not None
assert str(dataset_a.app_id) in app_ids_a
assert dataset_b.app_id is not None
assert str(dataset_b.app_id) not in app_ids_a
assert public_dataset.app_id is not None
assert str(public_dataset.app_id) in app_ids_a
apps_b = ReleaseApiClient.json_data(common_api_b.get("/api/v3/rag/apps"))
app_ids_b = _app_ids(apps_b["data"])
assert str(dataset_b.app_id) in app_ids_b
assert str(dataset_a.app_id) not in app_ids_b
assert str(public_dataset.app_id) in app_ids_b
default_app_a = ReleaseApiClient.json_data(common_api_a.get("/api/v3/rag/apps/default"))
assert default_app_a is not None
assert str(default_app_a.get("tenantCode") or "") in {tenant_a.tenant_code, public_dataset.tenant_code}
@pytest.mark.release
def test_g5_common_user_cannot_access_rag_admin_endpoints(
common_api_a: ReleaseApiClient,
tenant_a: TenantSeed,
) -> None:
forbidden_admin_list = common_api_a.get("/api/v3/rag/datasets/admin?page=1&pageSize=20", expected_status=403)
assert "管理知识库权限" in forbidden_admin_list.text
forbidden_create = common_api_a.post(
"/api/v3/rag/datasets/admin",
json={
"tenant_code": tenant_a.tenant_code,
"tenant_name": tenant_a.tenant_name,
"area": tenant_a.tenant_name,
"name": f"should-forbid-{int(time.time())}",
"description": "forbidden",
"status": 1,
},
expected_status=403,
)
assert "创建知识库权限" in forbidden_create.text