test_api.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import pytest
  2. def get_auth_headers(client, username="testuser", password="password123"):
  3. client.post("/api/v1/auth/register", json={"username": username, "password": password})
  4. response = client.post(
  5. "/api/v1/auth/login",
  6. data={"username": username, "password": password}
  7. )
  8. token = response.json()["access_token"]
  9. return {"Authorization": f"Bearer {token}"}
  10. def test_create_user(client):
  11. response = client.post(
  12. "/api/v1/users/",
  13. json={"username": "testuser", "password": "password123", "role": "user"}
  14. )
  15. assert response.status_code == 200
  16. data = response.json()
  17. assert data["username"] == "testuser"
  18. assert "id" in data
  19. def test_login(client):
  20. client.post("/api/v1/users/", json={"username": "testuser", "password": "password123", "role": "user"})
  21. response = client.post(
  22. "/api/v1/auth/login",
  23. data={"username": "testuser", "password": "password123"}
  24. )
  25. assert response.status_code == 200
  26. assert "access_token" in response.json()
  27. def test_create_persona(client):
  28. # Register and login
  29. headers = get_auth_headers(client)
  30. # We still need owner_id in API, but current_user is inferred from token.
  31. # Actually, API ignores owner_id in body if we use current_user.id,
  32. # but the schema might require it?
  33. # Checking endpoints/personas.py: create_new_persona takes owner_id param?
  34. # No, we updated it to use current_user.id.
  35. # BUT, the function signature `create_new_persona(persona, current_user, db)`
  36. # means `owner_id` is NOT a query param anymore in our update?
  37. # Wait, in endpoints/personas.py I wrote:
  38. # def create_new_persona(persona: PersonaCreate, current_user: ..., db: ...):
  39. # return create_persona(db=db, persona=persona, owner_id=current_user.id)
  40. # So `owner_id` query param is GONE.
  41. response = client.post(
  42. "/api/v1/personas/",
  43. headers=headers,
  44. json={
  45. "name": "Socrates",
  46. "bio": "Greek philosopher",
  47. "theories": ["Method", "Ethics"],
  48. "is_public": False
  49. }
  50. )
  51. assert response.status_code == 200
  52. data = response.json()
  53. assert data["name"] == "Socrates"
  54. # Ensure owner_id matches the user from token (which is created first, likely id=1)
  55. assert data["owner_id"] == 1
  56. def test_persona_name_is_trimmed_and_blank_name_is_rejected(client):
  57. headers = get_auth_headers(client, username="persona-validation")
  58. created = client.post(
  59. "/api/v1/personas/",
  60. headers=headers,
  61. json={"name": " Trimmed Persona "},
  62. )
  63. assert created.status_code == 200
  64. assert created.json()["name"] == "Trimmed Persona"
  65. blank = client.post(
  66. "/api/v1/personas/",
  67. headers=headers,
  68. json={"name": " "},
  69. )
  70. assert blank.status_code == 400
  71. assert blank.json()["message"] == "请求参数验证失败"
  72. update = client.put(
  73. f"/api/v1/personas/{created.json()['id']}",
  74. headers=headers,
  75. json={"name": "\t"},
  76. )
  77. assert update.status_code == 400
  78. def test_database_startup_repairs_legacy_blank_persona_name(db):
  79. from app.db.client import db_manager, fetch_one
  80. db.execute(
  81. "INSERT INTO personas (owner_id, name, theories, is_public) VALUES (?, ?, ?, ?)",
  82. [1, " ", "[]", 0],
  83. )
  84. row = fetch_one(db.execute("SELECT MAX(id) AS id FROM personas"))
  85. persona_id = row.id
  86. db.close()
  87. db_manager.init_db()
  88. repaired_db = db_manager.get_connection()
  89. try:
  90. repaired = fetch_one(
  91. repaired_db.execute("SELECT name FROM personas WHERE id = ?", [persona_id])
  92. )
  93. assert repaired.name == f"未命名智能体 #{persona_id}"
  94. db_manager.init_db()
  95. unchanged = fetch_one(
  96. repaired_db.execute("SELECT name FROM personas WHERE id = ?", [persona_id])
  97. )
  98. assert unchanged.name == repaired.name
  99. finally:
  100. repaired_db.close()
  101. def test_create_forum(client):
  102. headers = get_auth_headers(client)
  103. # Create personas first
  104. p1 = client.post("/api/v1/personas/", headers=headers, json={"name": "P1"}).json()
  105. p2 = client.post("/api/v1/personas/", headers=headers, json={"name": "P2"}).json()
  106. # Create forum (creator_id inferred from token)
  107. response = client.post(
  108. "/api/v1/forums/",
  109. headers=headers,
  110. json={
  111. "topic": "Philosophy",
  112. "participant_ids": [p1["id"], p2["id"]]
  113. }
  114. )
  115. assert response.status_code == 200
  116. data = response.json()
  117. assert data["topic"] == "Philosophy"
  118. assert data["creator_id"] == 1
  119. def test_post_message(client):
  120. headers = get_auth_headers(client)
  121. # Setup
  122. p1 = client.post("/api/v1/personas/", headers=headers, json={"name": "P1"}).json()
  123. f = client.post("/api/v1/forums/", headers=headers, json={"topic": "T", "participant_ids": [p1["id"]]}).json()
  124. response = client.post(
  125. f"/api/v1/forums/{f['id']}/messages",
  126. headers=headers,
  127. json={
  128. "forum_id": f['id'],
  129. "persona_id": p1['id'],
  130. "speaker_name": "P1",
  131. "content": "Know thyself",
  132. "turn_count": 1
  133. }
  134. )
  135. assert response.status_code == 200
  136. data = response.json()
  137. assert data["content"] == "Know thyself"
  138. def test_get_messages(client):
  139. headers = get_auth_headers(client)
  140. p1 = client.post("/api/v1/personas/", headers=headers, json={"name": "P1"}).json()
  141. f = client.post("/api/v1/forums/", headers=headers, json={"topic": "T", "participant_ids": [p1["id"]]}).json()
  142. client.post(f"/api/v1/forums/{f['id']}/messages", headers=headers, json={
  143. "forum_id": f['id'], "persona_id": p1['id'], "speaker_name": "P1", "content": "Msg1", "turn_count": 1
  144. })
  145. response = client.get(f"/api/v1/forums/{f['id']}/messages", headers=headers)
  146. assert response.status_code == 200
  147. data = response.json()
  148. assert len(data) > 0
  149. assert data[0]["content"] == "Msg1"
  150. def test_chat_with_agent(client):
  151. response = client.post(
  152. "/api/v1/agents/chat",
  153. json={
  154. "agent_name": "TestAgent",
  155. "persona_json": {
  156. "name": "TestAgent",
  157. "title": "Tester",
  158. "bio": "A test agent",
  159. "theories": ["Testing"],
  160. "system_prompt": "You are a test agent."
  161. },
  162. "context_messages": [
  163. {"speaker": "User", "content": "Hello"}
  164. ]
  165. }
  166. )
  167. assert response.status_code != 404
  168. assert response.status_code != 422