"""M0 smoke test: auth + roles via Flask test client.""" import json import os import sys import tempfile import warnings from pathlib import Path warnings.filterwarnings("ignore", message="The HMAC key is") sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")) os_env_data = tempfile.mkdtemp(prefix="salestrainer_m0_") os.environ["DATA_DIR"] = os_env_data os.environ["JWT_SECRET"] = "test-secret" from app.factory import create_app # noqa: E402 from app.config import Config # noqa: E402 from pathlib import Path as _Path # .env with override=True would clobber DATA_DIR, so pin the store root directly. Config.DATA_DIR = _Path(os_env_data) def main() -> None: app = create_app() client = app.test_client() # 1. Health r = client.get("/health") assert r.status_code == 200 and r.get_json()["status"] == "ok", r.get_json() print("[ok] health") # 2. No self-registration: register route must NOT exist (404) r = client.post("/api/auth/register", json={"email": "a@b.c", "password": "x"}) assert r.status_code == 404, f"register should not exist, got {r.status_code}" print("[ok] no self-registration (register -> 404)") # 3. Bootstrap super-admin login (username admin / 1234) r = client.post( "/api/auth/login", json={"username": "admin", "password": "1234"}, ) assert r.status_code == 200, r.get_json() admin_token = r.get_json()["token"] print("[ok] super-admin login") # 4. /me with token r = client.get("/api/auth/me", headers={"Authorization": f"Bearer {admin_token}"}) assert r.status_code == 200 assert r.get_json()["user"]["role"] == "super_admin" print("[ok] /me super_admin") # 5. Create a regular user (admin) r = client.post( "/api/admin/users", json={"name": "Trainee One", "username": "trainee1", "password": "pass123", "role": "user"}, headers={"Authorization": f"Bearer {admin_token}"}, ) assert r.status_code == 201, r.get_json() print("[ok] admin creates user") # 6. Trainee login + cannot access admin users list (403) r = client.post("/api/auth/login", json={"username": "trainee1", "password": "pass123"}) user_token = r.get_json()["token"] r = client.get("/api/admin/users", headers={"Authorization": f"Bearer {user_token}"}) assert r.status_code == 403, f"trainee should be denied, got {r.status_code}" print("[ok] trainee denied admin route (403)") # 7. No token -> 401 r = client.get("/api/admin/users") assert r.status_code == 401 print("[ok] no token -> 401") # 8. Role restriction: admin cannot create another admin (only super_admin) # create an 'admin' actor first client.post( "/api/admin/users", json={"name": "Admin Two", "username": "admin2", "password": "pass123", "role": "admin"}, headers={"Authorization": f"Bearer {admin_token}"}, ) r = client.post( "/api/auth/login", json={"username": "admin2", "password": "pass123"} ) admin2_token = r.get_json()["token"] r = client.post( "/api/admin/users", json={"name": "Bogus Admin", "username": "bogus", "password": "pass123", "role": "super_admin"}, headers={"Authorization": f"Bearer {admin2_token}"}, ) assert r.status_code == 403, f"admin should not promote, got {r.status_code}" print("[ok] admin cannot grant super_admin (403)") # 9. Duplicate username rejected r = client.post( "/api/admin/users", json={"name": "Dup", "username": "trainee1", "password": "pass123", "role": "user"}, headers={"Authorization": f"Bearer {admin_token}"}, ) assert r.status_code == 400 print("[ok] duplicate username rejected (400)") print("\nALL M0 TESTS PASSED") if __name__ == "__main__": main()