testsAndMisc/articles/test_server_api.py

99 lines
2.8 KiB
Python
Raw Normal View History

2025-09-07 21:26:55 +02:00
import json
import os
from pathlib import Path
import socket
import subprocess
2025-09-07 21:26:55 +02:00
import time
import urllib.error
import urllib.request
2025-09-07 21:26:55 +02:00
def _req(url, method="GET", data=None):
if data is not None and not isinstance(data, (bytes, bytearray)):
data = json.dumps(data).encode("utf-8")
req = urllib.request.Request(url, data=data, method=method)
req.add_header("Content-Type", "application/json")
with urllib.request.urlopen(req, timeout=5) as resp:
body = resp.read()
return resp.getcode(), body
def test_crud_roundtrip(tmp_path):
2025-09-07 21:46:47 +02:00
# Build C server
here = Path(__file__).resolve().parent
subprocess.run(["make", "-s", "server_c"], check=True, cwd=str(here))
2025-09-07 21:26:55 +02:00
2025-09-07 21:46:47 +02:00
# Find a free port
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(("127.0.0.1", 0))
_, port = s.getsockname()
host = "127.0.0.1"
2025-09-07 21:26:55 +02:00
base = f"http://{host}:{port}"
2025-09-07 21:46:47 +02:00
# Isolate storage and start server
env = os.environ.copy()
env["ARTICLES_DATA_DIR"] = str(tmp_path)
env["HOST"] = host
env["PORT"] = str(port)
srv = subprocess.Popen(["./server_c"], cwd=str(here), env=env)
try:
# wait briefly for server to be ready
for _ in range(30):
try:
with urllib.request.urlopen(base + "/api/articles", timeout=0.2) as resp:
2025-09-07 21:46:47 +02:00
resp.read()
break
except Exception:
time.sleep(0.05)
2025-09-07 21:26:55 +02:00
2025-09-07 21:46:47 +02:00
# Create
code, body = _req(
base + "/api/articles",
method="POST",
data={
"title": "T1",
"body": "<p>Hello</p>",
"thumb": "data:image/png;base64,xyz",
},
)
2025-09-07 21:46:47 +02:00
assert code == 201
created = json.loads(body)
art_id = created["id"]
2025-09-07 21:26:55 +02:00
2025-09-07 21:46:47 +02:00
# List
code, body = _req(base + "/api/articles")
2025-09-07 21:46:47 +02:00
assert code == 200
items = json.loads(body)
assert any(a["id"] == art_id for a in items)
2025-09-07 21:26:55 +02:00
2025-09-07 21:46:47 +02:00
# Get one
code, body = _req(base + f"/api/articles/{art_id}")
2025-09-07 21:46:47 +02:00
assert code == 200
got = json.loads(body)
assert got["title"] == "T1"
2025-09-07 21:26:55 +02:00
2025-09-07 21:46:47 +02:00
# Update
code, body = _req(base + f"/api/articles/{art_id}", method="PUT", data={"title": "T2"})
2025-09-07 21:46:47 +02:00
assert code == 200
updated = json.loads(body)
assert updated["title"] == "T2"
2025-09-07 21:26:55 +02:00
2025-09-07 21:46:47 +02:00
# Delete
code, _ = _req(base + f"/api/articles/{art_id}", method="DELETE")
2025-09-07 21:46:47 +02:00
assert code == 204
# Ensure gone
try:
_req(base + f"/api/articles/{art_id}")
msg = "Expected 404"
raise AssertionError(msg)
2025-09-07 21:46:47 +02:00
except urllib.error.HTTPError as e:
assert e.code == 404
2025-09-07 21:26:55 +02:00
2025-09-07 21:46:47 +02:00
finally:
srv.terminate()
try:
srv.wait(timeout=2)
except Exception:
srv.kill()