iOSBuildServer/tests/test_edge_cases.py
shen 6f4f625c56 Initial commit: iOS Build Server
- FastAPI backend with build queue, WebSocket logs, task management
- Vue 3 frontend with build/config/history views
- Xcode project build automation with IPA export
- Fix: initialize build_dir before try block to ensure cleanup on early failure
2026-06-06 17:42:27 +08:00

161 lines
5.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""边界情况测试"""
import json
import pytest
def test_invalid_json_body(client, tmp_config):
"""无效 JSON 请求体"""
resp = client.post(
"/api/tasks",
content="not json",
headers={"Content-Type": "application/json"},
)
assert resp.status_code == 422
def test_missing_required_fields(client, tmp_config):
"""缺少必填字段"""
resp = client.post("/api/tasks", json={"app_id": "1"})
assert resp.status_code == 422
def test_empty_app_id(client, tmp_config):
"""空 app_id"""
resp = client.post("/api/tasks", json={
"app_id": "",
"build_type": "Ad_Hoc",
"scheme_id": "1",
})
assert resp.status_code == 400
def test_server_name_with_special_chars(client, tmp_config):
"""服务器名称包含特殊字符"""
resp = client.post("/api/config/servers", json={
"name": "环境/测试",
"api": "https://test.com",
})
assert resp.status_code == 200
def test_branch_name_with_slash(client, tmp_config):
"""分支名包含斜杠"""
resp = client.post("/api/config/branches", json={"name": "feature/my-branch"})
assert resp.status_code == 200
assert "feature/my-branch" in client.get("/api/config/branches").json()
def test_branch_name_with_space(client, tmp_config):
"""分支名包含空格(应被 trim"""
resp = client.post("/api/config/branches", json={"name": " "})
assert resp.status_code == 400
def test_config_backup_on_save(client, tmp_config):
"""保存配置时自动备份"""
# 先写一次产生文件
client.put("/api/config", json={"apps": {}, "schemes": {}, "branches": ["main"]})
# 再写一次,应该产生 .bak 文件
client.put("/api/config", json={"apps": {"1": {"name": "test"}}, "schemes": {}, "branches": ["main"]})
backup = tmp_config.with_suffix(".json.bak")
assert backup.exists()
def test_sequential_config_writes(client, tmp_config):
"""顺序多次写入配置"""
for i in range(5):
resp = client.post("/api/config/branches", json={"name": f"branch-{i}"})
assert resp.status_code == 200
branches = client.get("/api/config/branches").json()
for i in range(5):
assert f"branch-{i}" in branches
def test_task_status_filter(client, tmp_config):
"""按状态过滤任务"""
from unittest.mock import patch, AsyncMock
with patch("backend.services.build_queue.build_queue") as mock_queue:
mock_queue.submit = AsyncMock()
client.post("/api/tasks", json={
"app_id": "1", "build_type": "Ad_Hoc", "scheme_id": "1",
})
# 过滤 pending
resp = client.get("/api/tasks?status=pending")
assert resp.status_code == 200
assert len(resp.json()) >= 1
# 过滤 running应该没有
resp = client.get("/api/tasks?status=running")
assert len(resp.json()) == 0
def test_task_pagination(client, tmp_config):
"""任务分页"""
from unittest.mock import patch, AsyncMock
with patch("backend.services.build_queue.build_queue") as mock_queue:
mock_queue.submit = AsyncMock()
for _ in range(5):
client.post("/api/tasks", json={
"app_id": "1", "build_type": "Ad_Hoc", "scheme_id": "1",
})
resp = client.get("/api/tasks?limit=2&offset=0")
assert len(resp.json()) == 2
resp = client.get("/api/tasks?limit=2&offset=2")
assert len(resp.json()) == 2
def test_delete_server_not_in_use(client, tmp_config):
"""删除未被使用的服务器"""
# 先添加一个不被使用的服务器
client.post("/api/config/servers", json={"name": "临时环境", "api": "https://tmp.com"})
resp = client.delete("/api/config/servers/临时环境")
assert resp.status_code == 200
def test_update_full_config_replaces_all(client, tmp_config):
"""整体替换配置"""
new_config = {
"apps": {"99": {"name": "新App"}},
"schemes": {},
"servers": {},
"branches": ["release"],
}
resp = client.put("/api/config", json=new_config)
assert resp.status_code == 200
config = client.get("/api/config").json()
assert "99" in config["apps"]
assert config["branches"] == ["release"]
def test_scheme_id_auto_increment(client, tmp_config):
"""Scheme ID 自动递增"""
client.post("/api/config/schemes", json={"name": "sch2", "ossFloder": "f2"})
client.post("/api/config/schemes", json={"name": "sch3", "ossFloder": "f3"})
schemes = client.get("/api/config/schemes").json()
assert "2" in schemes
assert "3" in schemes
def test_build_settings_validation(client, tmp_config):
"""打包设置更新"""
# 更新为有效值
resp = client.put("/api/config/build", json={"max_concurrent_builds": 3})
assert resp.status_code == 200
assert client.get("/api/config/build").json()["max_concurrent_builds"] == 3
# 更新部分字段
resp = client.put("/api/config/build", json={"build_dir_retention_hours": 48})
assert resp.status_code == 200
settings = client.get("/api/config/build").json()
assert settings["build_dir_retention_hours"] == 48
assert settings["max_concurrent_builds"] == 3 # 未修改的保持不变