feat(avatar): complete authorization management
This commit is contained in:
@@ -1,105 +1,125 @@
|
||||
"""Tests for PUT /api/avatar/{avatar_id}/authorizations/takeover endpoint."""
|
||||
"""Tests for the authorization takeover configuration endpoint."""
|
||||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from database import SessionLocal
|
||||
from main import app
|
||||
from database import SessionLocal, Base, engine
|
||||
from models import Authorization, Avatar
|
||||
from models import Authorization
|
||||
|
||||
|
||||
def setup_test_db():
|
||||
Base.metadata.create_all(bind=engine)
|
||||
client = TestClient(app)
|
||||
|
||||
|
||||
def test_update_takeover_accepts_camel_case_and_persists(authorization_context):
|
||||
context = authorization_context
|
||||
response = client.put(
|
||||
f"/api/avatar/{context['avatar'].id}/authorizations/takeover",
|
||||
headers=context["owner_headers"],
|
||||
json={
|
||||
"authorizationId": context["authorization"].id,
|
||||
"takeoverEnabled": True,
|
||||
"takeoverMode": "delayed",
|
||||
"takeoverDelaySeconds": 60,
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert payload["code"] == 200
|
||||
assert payload["data"]["takeoverEnabled"] is True
|
||||
assert payload["data"]["takeoverMode"] == "delayed"
|
||||
assert payload["data"]["takeoverDelaySeconds"] == 60
|
||||
assert "takeover" in payload["data"]["permissions"]
|
||||
|
||||
db = SessionLocal()
|
||||
avatar = Avatar(name="test", status="active", config={})
|
||||
db.add(avatar)
|
||||
db.commit()
|
||||
db.refresh(avatar)
|
||||
auth = Authorization(avatar_id=avatar.id, target_id="user1", target_name="测试用户")
|
||||
db.add(auth)
|
||||
db.commit()
|
||||
db.refresh(auth)
|
||||
return db, auth.id
|
||||
|
||||
|
||||
def test_update_takeover_config():
|
||||
db, auth_id = setup_test_db()
|
||||
try:
|
||||
client = TestClient(app)
|
||||
response = client.put(
|
||||
f"/api/avatar/test_avatar_id/authorizations/takeover",
|
||||
json={
|
||||
"authorization_id": auth_id,
|
||||
"takeover_enabled": True,
|
||||
"takeover_mode": "delayed",
|
||||
"takeover_delay_seconds": 60,
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["code"] == 200
|
||||
assert data["data"]["takeoverEnabled"] is True
|
||||
assert data["data"]["takeoverMode"] == "delayed"
|
||||
assert data["data"]["takeoverDelaySeconds"] == 60
|
||||
# 验证数据库已更新
|
||||
auth = db.query(Authorization).filter(Authorization.id == auth_id).first()
|
||||
assert auth.takeover_enabled is True
|
||||
assert auth.takeover_mode == "delayed"
|
||||
assert auth.takeover_delay_seconds == 60
|
||||
stored = db.query(Authorization).filter(
|
||||
Authorization.id == context["authorization"].id
|
||||
).first()
|
||||
assert stored.takeover_enabled is True
|
||||
assert stored.takeover_mode == "delayed"
|
||||
assert stored.takeover_delay_seconds == 60
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def test_update_takeover_invalid_mode():
|
||||
db, auth_id = setup_test_db()
|
||||
try:
|
||||
client = TestClient(app)
|
||||
response = client.put(
|
||||
f"/api/avatar/test/authorizations/takeover",
|
||||
json={
|
||||
"authorization_id": auth_id,
|
||||
"takeover_mode": "invalid_mode",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["code"] == 400
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def test_update_takeover_invalid_delay():
|
||||
db, auth_id = setup_test_db()
|
||||
try:
|
||||
client = TestClient(app)
|
||||
response = client.put(
|
||||
f"/api/avatar/test/authorizations/takeover",
|
||||
json={
|
||||
"authorization_id": auth_id,
|
||||
"takeover_delay_seconds": 2,
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["code"] == 400
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def test_update_takeover_missing_auth_id():
|
||||
client = TestClient(app)
|
||||
response = client.put(
|
||||
f"/api/avatar/test/authorizations/takeover",
|
||||
json={"takeover_enabled": True},
|
||||
def test_disabling_authorization_also_disables_takeover(authorization_context):
|
||||
context = authorization_context
|
||||
endpoint = f"/api/avatar/{context['avatar'].id}/authorizations/takeover"
|
||||
client.put(
|
||||
endpoint,
|
||||
headers=context["owner_headers"],
|
||||
json={
|
||||
"authorizationId": context["authorization"].id,
|
||||
"takeoverEnabled": True,
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["code"] == 400
|
||||
|
||||
updated = client.put(
|
||||
f"/api/avatar/{context['avatar'].id}/authorizations",
|
||||
headers=context["owner_headers"],
|
||||
json={"id": context["authorization"].id, "status": "inactive"},
|
||||
).json()
|
||||
assert updated["code"] == 200
|
||||
assert updated["data"]["status"] == "inactive"
|
||||
assert updated["data"]["takeoverEnabled"] is False
|
||||
assert "takeover" not in updated["data"]["permissions"]
|
||||
|
||||
|
||||
def test_update_takeover_not_found():
|
||||
client = TestClient(app)
|
||||
response = client.put(
|
||||
f"/api/avatar/test/authorizations/takeover",
|
||||
json={"authorization_id": "nonexistent"},
|
||||
def test_takeover_rejects_invalid_values_and_cross_avatar_access(authorization_context):
|
||||
context = authorization_context
|
||||
endpoint = f"/api/avatar/{context['avatar'].id}/authorizations/takeover"
|
||||
|
||||
invalid_mode = client.put(
|
||||
endpoint,
|
||||
headers=context["owner_headers"],
|
||||
json={
|
||||
"authorization_id": context["authorization"].id,
|
||||
"takeover_mode": "invalid",
|
||||
},
|
||||
).json()
|
||||
assert invalid_mode["code"] == 400
|
||||
|
||||
invalid_delay = client.put(
|
||||
endpoint,
|
||||
headers=context["owner_headers"],
|
||||
json={
|
||||
"authorization_id": context["authorization"].id,
|
||||
"takeover_delay_seconds": 2,
|
||||
},
|
||||
).json()
|
||||
assert invalid_delay["code"] == 400
|
||||
|
||||
forbidden = client.put(
|
||||
endpoint,
|
||||
headers=context["other_headers"],
|
||||
json={
|
||||
"authorizationId": context["authorization"].id,
|
||||
"takeoverEnabled": True,
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["code"] == 404
|
||||
assert forbidden.status_code == 403
|
||||
|
||||
|
||||
def test_takeover_is_limited_to_active_user_authorizations(authorization_context):
|
||||
context = authorization_context
|
||||
avatar_id = context["avatar"].id
|
||||
created = client.post(
|
||||
f"/api/avatar/{avatar_id}/authorizations",
|
||||
headers=context["owner_headers"],
|
||||
json={
|
||||
"targetType": "organization",
|
||||
"targetId": f"org-{context['suffix']}",
|
||||
"targetName": "测试组织",
|
||||
"permissions": ["chat"],
|
||||
},
|
||||
).json()
|
||||
response = client.put(
|
||||
f"/api/avatar/{avatar_id}/authorizations/takeover",
|
||||
headers=context["owner_headers"],
|
||||
json={
|
||||
"authorizationId": created["data"]["id"],
|
||||
"takeoverEnabled": True,
|
||||
},
|
||||
).json()
|
||||
assert response["code"] == 400
|
||||
assert "单聊接管" in response["message"]
|
||||
|
||||
Reference in New Issue
Block a user