test_s1_pagination.py 3.6 KB
"""RED test for S1: /api/sessions pagination + sort"""
import urllib.request, json, sys

BASE = "http://127.0.0.1:5000"
passed = 0
failed = 0

def test(label, path, check_fn):
    global passed, failed
    try:
        with urllib.request.urlopen(f"{BASE}{path}", timeout=15) as r:
            body = r.read()
            d = json.loads(body)
            ok, msg = check_fn(d)
            if ok:
                passed += 1
                print(f"  PASS  {label}: {msg}")
            else:
                failed += 1
                print(f"  FAIL  {label}: {msg}")
    except Exception as e:
        failed += 1
        print(f"  FAIL  {label}: {e}")

# TC1: page=1&per_page=10
def check_tc1(d):
    ok = d.get("ok")
    data = d.get("data", [])
    total = d.get("total")
    page = d.get("page")
    per_page = d.get("per_page")
    if not ok:
        return False, f"ok=False"
    if not isinstance(data, list):
        return False, f"data not list"
    if total is None:
        return False, f"total missing"
    if page != 1:
        return False, f"page={page} expected 1"
    if per_page != 10:
        return False, f"per_page={per_page} expected 10"
    if len(data) > 10:
        return False, f"data len={len(data)} exceeds 10"
    return True, f"total={total} page={page} per_page={per_page} len={len(data)}"

# TC2: page 1 vs page 2 — no overlap
def check_tc2_a(d):
    global page1_ids
    data = d.get("data", [])
    page1_ids = [s.get("talker") for s in data]
    return True, f"page1 ids={len(page1_ids)}"

def check_tc2_b(d):
    data = d.get("data", [])
    page2_ids = [s.get("talker") for s in data]
    overlap = set(page1_ids) & set(page2_ids)
    if len(overlap) > 0:
        return False, f"overlap: {overlap}"
    return True, f"page2 unique={len(page2_ids)} no overlap"

# TC3: sort=time_asc
def check_tc3(d):
    data = d.get("data", [])
    if len(data) < 2:
        return True, f"only {len(data)} items, skip"
    times = [s.get("createTime", 0) for s in data]
    for i in range(len(times) - 1):
        if times[i] > times[i+1]:
            return False, f"not ascending at index {i}: {times[i]} > {times[i+1]}"
    return True, f"ascending: first={times[0]} last={times[-1]}"

# TC4: backward compat — no params
def check_tc4(d):
    ok = d.get("ok")
    data = d.get("data", [])
    total = d.get("total")
    if not ok:
        return False, f"ok=False"
    if total is None:
        return False, f"total missing"
    if not isinstance(data, list):
        return False, f"data not list"
    return True, f"total={total} len={len(data)}"

# TC5: per_page=0 boundary
def check_tc5(d):
    ok = d.get("ok")
    per_page = d.get("per_page")
    data = d.get("data", [])
    # Should default to 10, not crash
    if not ok:
        return False, f"ok=False (crash?)"
    if len(data) > 10:
        return False, f"per_page=0 returned {len(data)} items (expected ≤10)"
    return True, f"per_page=0 → got per_page={per_page} len={len(data)}"

print("=== S1 RED: /api/sessions pagination + sort ===\n")

page1_ids = []
test("TC1: page=1&per_page=10", "/api/sessions?page=1&per_page=10", check_tc1)

if failed == 0:
    test("TC2a: page=1&per_page=10", "/api/sessions?page=1&per_page=10", check_tc2_a)
    test("TC2b: page=2&per_page=10", "/api/sessions?page=2&per_page=10", check_tc2_b)
else:
    print("  SKIP  TC2: TC1 failed")

test("TC3: sort=time_asc", "/api/sessions?page=1&per_page=20&sort=time_asc", check_tc3)
test("TC4: no params (backward compat)", "/api/sessions", check_tc4)
test("TC5: per_page=0 boundary", "/api/sessions?page=1&per_page=0", check_tc5)

print(f"\n{passed}/{passed+failed} 通过")
sys.exit(0 if failed == 0 else 1)