#!/usr/bin/env python3 """Public auth/workspace smoke test for deployed Xiaoxia SaaS. Creates a throwaway user through the public Web-domain API path and verifies login, /auth/me, and /workspaces. Uses only the Python standard library. """ from __future__ import annotations import argparse import json import os import time import urllib.error import urllib.request def request_json(method: str, url: str, payload: dict | None = None, token: str | None = None) -> tuple[int, dict]: body = json.dumps(payload).encode("utf-8") if payload is not None else None headers = {"Content-Type": "application/json"} if token: headers["Authorization"] = f"Bearer {token}" request = urllib.request.Request(url, data=body, headers=headers, method=method) try: with urllib.request.urlopen(request, timeout=15) as response: data = response.read().decode("utf-8") return response.status, json.loads(data) if data else {} except urllib.error.HTTPError as error: data = error.read().decode("utf-8") try: parsed = json.loads(data) if data else {} except json.JSONDecodeError: parsed = {"raw": data} return error.code, parsed def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--base-url", default="https://saas.xiaoxiajianji.com/api/v1") args = parser.parse_args() timestamp = int(time.time()) email = f"smoke-{timestamp}@example.com" username = f"smoke{timestamp}" password = os.environ.get("SMOKE_TEST_PASSWORD", "changeme") register_status, register_body = request_json( "POST", f"{args.base_url}/auth/register", { "email": email, "username": username, "password": password, "display_name": username, }, ) print(f"register={register_status}") if register_status != 201: print(json.dumps(register_body, ensure_ascii=False)) return 1 login_status, login_body = request_json( "POST", f"{args.base_url}/auth/login", {"email": email, "password": password}, ) print(f"login={login_status}") token = login_body.get("access_token") if login_status != 200 or not token: print(json.dumps(login_body, ensure_ascii=False)) return 1 me_status, me_body = request_json("GET", f"{args.base_url}/auth/me", token=token) print(f"me={me_status}") if me_status != 200 or me_body.get("email") != email: print(json.dumps(me_body, ensure_ascii=False)) return 1 workspaces_status, workspaces_body = request_json("GET", f"{args.base_url}/workspaces", token=token) print(f"workspaces={workspaces_status}") if workspaces_status != 200 or "workspaces" not in workspaces_body: print(json.dumps(workspaces_body, ensure_ascii=False)) return 1 print("public_auth_flow=ok") return 0 if __name__ == "__main__": raise SystemExit(main())