SurfSmart/test/tests_backend/test_api_list.py
2025-06-09 17:53:19 +08:00

163 lines
5.8 KiB
Python

import json
import pytest
from backend.app import create_app
@pytest.fixture
def client():
"""
Creates a Flask test client from your create_app function.
"""
app = create_app()
app.config["TESTING"] = True
with app.test_client() as client:
yield client
@pytest.fixture
def auth_headers(client):
"""
Registers and logs in a test user, returning an authorization header.
"""
import uuid
unique_suffix = str(uuid.uuid4())[:8]
username = f"apilistuser_{unique_suffix}"
email = f"{username}@example.com"
reg_payload = {
"username": username,
"email": email,
"password": "TestPassword123"
}
reg_resp = client.post("/api/register", data=json.dumps(reg_payload), content_type="application/json")
assert reg_resp.status_code == 201, f"Registration failed: {reg_resp.data.decode()}"
data = json.loads(reg_resp.data)
token = data["token"]
return {"Authorization": f"Bearer {token}"}
def test_list_api_keys_empty(client, auth_headers):
"""
Initially, the user has no API keys.
GET /api/api_list should return empty array.
"""
resp = client.get("/api/api_list", headers=auth_headers)
assert resp.status_code == 200, f"List keys failed: {resp.data.decode()}"
data = json.loads(resp.data)
assert "api_keys" in data
assert len(data["api_keys"]) == 0
def test_create_api_key(client, auth_headers):
"""
Test creating an API key for e.g. 'Gemini'.
"""
payload = {
"name": "Gemini",
"key": "gemini-secret-key",
"selected": True
}
create_resp = client.post("/api/api_list", data=json.dumps(payload),
content_type="application/json", headers=auth_headers)
assert create_resp.status_code == 201, f"Create API key failed: {create_resp.data.decode()}"
data = json.loads(create_resp.data)
assert "api_id" in data
# Now list and verify we see the new key
list_resp = client.get("/api/api_list", headers=auth_headers)
assert list_resp.status_code == 200
list_data = json.loads(list_resp.data)
keys = list_data.get("api_keys", [])
assert len(keys) == 1
api_entry = keys[0]
assert api_entry["name"] == "Gemini"
assert api_entry["key"] == "gemini-secret-key"
assert api_entry["selected"] is True
def test_create_api_key_duplicate(client, auth_headers):
"""
By default, the code returns 400 if the user already has an API key for the same 'name'.
"""
# Create first
payload1 = {
"name": "Chatgpt",
"key": "chatgpt-key1",
"selected": False
}
resp1 = client.post("/api/api_list", data=json.dumps(payload1),
content_type="application/json", headers=auth_headers)
assert resp1.status_code == 201
# Try creating second with same 'name' => should fail with 400
payload2 = {
"name": "Chatgpt",
"key": "chatgpt-key2",
"selected": True
}
resp2 = client.post("/api/api_list", data=json.dumps(payload2),
content_type="application/json", headers=auth_headers)
assert resp2.status_code == 400, f"Expected 400 on duplicate provider, got {resp2.status_code}"
def test_create_api_key_invalid_name(client, auth_headers):
"""
If 'name' is not in ['Gemini','Deepseek','Chatgpt'], the code should fail with 400.
"""
invalid_payload = {
"name": "InvalidProvider",
"key": "some-key",
"selected": False
}
resp = client.post("/api/api_list", data=json.dumps(invalid_payload),
content_type="application/json", headers=auth_headers)
assert resp.status_code == 400, f"Expected 400 on invalid 'name', got {resp.status_code}"
def test_update_api_key(client, auth_headers):
"""
Test updating an existing API key fields: 'key', 'selected', or 'name'.
"""
# Create
payload = {
"name": "Deepseek",
"key": "deepseek-initial",
"selected": False
}
create_resp = client.post("/api/api_list", data=json.dumps(payload),
content_type="application/json", headers=auth_headers)
assert create_resp.status_code == 201
api_id = json.loads(create_resp.data)["api_id"]
# Now update
update_payload = {"key": "deepseek-updated", "selected": True}
update_resp = client.put(f"/api/api_list/{api_id}",
data=json.dumps(update_payload),
content_type="application/json", headers=auth_headers)
assert update_resp.status_code == 200, f"Update failed: {update_resp.data.decode()}"
# List and confirm
list_resp = client.get("/api/api_list", headers=auth_headers)
data = json.loads(list_resp.data)
updated_entry = next((k for k in data["api_keys"] if k["_id"] == api_id), None)
assert updated_entry is not None, "Updated key not found in list"
assert updated_entry["key"] == "deepseek-updated"
assert updated_entry["selected"] is True
def test_delete_api_key(client, auth_headers):
"""
Test deleting an API key by _id.
"""
payload = {
"name": "Gemini",
"key": "gemini-key2",
"selected": False
}
create_resp = client.post("/api/api_list", data=json.dumps(payload),
content_type="application/json", headers=auth_headers)
assert create_resp.status_code == 201
api_id = json.loads(create_resp.data)["api_id"]
# Delete
delete_resp = client.delete(f"/api/api_list/{api_id}", headers=auth_headers)
assert delete_resp.status_code == 200, f"Deletion failed: {delete_resp.data.decode()}"
# Confirm it's gone
list_resp = client.get("/api/api_list", headers=auth_headers)
data = json.loads(list_resp.data)
keys_left = [k for k in data["api_keys"] if k["_id"] == api_id]
assert len(keys_left) == 0, "API key was not deleted properly"