"""Tests verifying server responses match client (AuthManager.java) expectations.""" import pytest from tests.conftest import auth_headers class TestAuthResponseContract: """Verify /auth/register and /auth/login response fields match AuthSession.java.""" def test_register_has_all_session_fields(self, client): """Client expects: access_token, refresh_token, expires_in, uuid, username, role.""" resp = client.post("/auth/register", json={ "username": "contracttest", "password": "ContractPass123" }) assert resp.status_code == 200 data = resp.json() # AuthManager.AuthSession fields assert "access_token" in data, "Client needs access_token" assert "refresh_token" in data, "Client needs refresh_token" assert "expires_in" in data, "Client needs expires_in (int)" assert "uuid" in data, "Client needs uuid" assert "username" in data, "Client needs username" assert "role" in data, "Client needs role (int)" # Type checks assert isinstance(data["access_token"], str) assert isinstance(data["refresh_token"], str) assert isinstance(data["expires_in"], int) assert isinstance(data["uuid"], str) assert isinstance(data["role"], int) assert data["expires_in"] > 0 # Must be positive seconds def test_login_has_all_session_fields(self, client, registered_user): resp = client.post("/auth/login", json=registered_user) assert resp.status_code == 200 data = resp.json() assert "access_token" in data assert "refresh_token" in data assert "expires_in" in data assert "uuid" in data assert "username" in data assert "role" in data assert isinstance(data["expires_in"], int) assert isinstance(data["role"], int) class TestValidateResponseContract: """Verify /auth/validate response matches client expectations.""" def test_validate_valid_response_fields(self, client, logged_in_user): """Client checks: valid (bool), username, uuid, role.""" resp = client.post("/auth/validate", json={ "username": logged_in_user["username"], "uuid": logged_in_user["uuid"] }, headers=auth_headers(logged_in_user["access_token"])) assert resp.status_code == 200 data = resp.json() assert "valid" in data assert isinstance(data["valid"], bool) assert data["valid"] is True assert "username" in data assert "uuid" in data def test_validate_invalid_response_fields(self, client): resp = client.post("/auth/validate", json={ "username": "test", "uuid": "test" }, headers=auth_headers("bad.token")) assert resp.status_code == 401 # Invalid token returns 401 class TestAdminMeResponseContract: """Verify /admin/me response matches UserInfo.java expectations.""" def test_admin_me_has_all_userinfo_fields(self, client, logged_in_user): """ Client UserInfo.java expects: id (int), username, uuid, role (int), role_name, has_pass (bool), permissions (list) """ resp = client.get("/admin/me", headers=auth_headers(logged_in_user["access_token"])) assert resp.status_code == 200 data = resp.json() assert "id" in data, "UserInfo needs id" assert "username" in data assert "uuid" in data assert "role" in data, "UserInfo needs role" assert "role_name" in data, "UserInfo needs role_name" assert "has_pass" in data, "UserInfo needs has_pass" assert "permissions" in data, "UserInfo needs permissions" # Type checks assert isinstance(data["id"], int) assert isinstance(data["role"], int) assert isinstance(data["has_pass"], bool) assert isinstance(data["permissions"], list) assert isinstance(data["role_name"], str) class TestErrorResponseContract: """Verify error responses match client extractError() parsing.""" def test_error_has_detail_field(self, client): """Client parses json.detail (string or array with msg).""" resp = client.post("/auth/login", json={ "username": "nonexistent", "password": "wrong" }) # FastAPI returns 422 for validation errors, auth errors return 401 assert resp.status_code in (401, 422) data = resp.json() assert "detail" in data, "Client expects 'detail' field in errors" assert isinstance(data["detail"], (str, list)) def test_validation_error_has_detail_array(self, client): """FastAPI 422 returns detail as array of {loc, msg, type}.""" resp = client.post("/auth/register", json={ "username": "ab", "password": "x" }) assert resp.status_code == 422 data = resp.json() assert "detail" in data assert isinstance(data["detail"], list) assert "msg" in data["detail"][0] class TestPackResponseContract: """Verify /packs response matches client expectations.""" def test_packs_response_structure(self, client, logged_in_user): resp = client.get("/packs", headers=auth_headers(logged_in_user["access_token"])) # May return 200 or 401/403 depending on auth setup assert resp.status_code in (200, 401, 403) if resp.status_code == 200: data = resp.json() assert "packs" in data assert isinstance(data["packs"], list)