# -*- coding: utf-8 -*-
"""
test_routes_auth.py — 认证与页面路由测试

覆盖 routes/auth.py：login / logout / get_user_info / index
场景：登录成功/失败/空参、注销、user_info 权限、index 重定向
"""

from auth import user_manager


class TestLogin:
    """登录接口"""

    def test_get_login_page(self, client):
        """GET /login 未登录返回登录页"""
        r = client.get("/login")
        assert r.status_code == 200
        assert b"\xe7\x99\xbb\xe5\xbd\x95" in r.data  # "登录" UTF-8

    def test_get_login_redirect_if_logged_in(self, auth_client):
        """GET /login 已登录重定向到主页"""
        r = auth_client.get("/login")
        assert r.status_code == 302
        assert r.headers["Location"].endswith("/")

    def test_post_login_empty_params(self, client):
        """POST /login 空用户名或密码返回 400 + INVALID_PARAM"""
        r = client.post("/login", json={"username": "", "password": ""})
        assert r.status_code == 400
        data = r.get_json()
        assert data["success"] is False
        assert data["error"]["code"] == 1001

    def test_post_login_wrong_password(self, client, monkeypatch):
        """POST /login 错误密码返回 401"""
        monkeypatch.setattr(user_manager, "authenticate", lambda u, p: None)
        r = client.post("/login", json={"username": "x", "password": "y"})
        assert r.status_code == 401
        data = r.get_json()
        assert data["success"] is False
        assert data["error"]["code"] == 1004

    def test_post_login_success(self, client, monkeypatch):
        """POST /login 正确凭据返回 200 + session 写入"""
        monkeypatch.setattr(user_manager, "authenticate", lambda u, p: {
            "id": 1, "username": u, "role": "user"
        })
        r = client.post("/login", json={"username": "test", "password": "pass"})
        assert r.status_code == 200
        data = r.get_json()
        assert data["success"] is True
        assert data["user"]["username"] == "test"
        # session 已写入
        with client.session_transaction() as sess:
            assert sess["user"]["username"] == "test"


class TestLogout:
    """注销接口"""

    def test_logout_logged_in(self, auth_client):
        """已登录注销返回 200 + session 清空"""
        r = auth_client.post("/logout")
        assert r.status_code == 200
        assert r.get_json()["success"] is True
        with auth_client.session_transaction() as sess:
            assert "user" not in sess

    def test_logout_not_logged_in(self, client):
        """未登录注销也返回 200（不报错）"""
        r = client.post("/logout")
        assert r.status_code == 200


class TestUserInfo:
    """用户信息接口"""

    def test_user_info_requires_login(self, client):
        """未登录访问 /api/user/info 返回 401"""
        r = client.get("/api/user/info")
        assert r.status_code == 401
        assert r.get_json()["error"]["code"] == 1004

    def test_user_info_logged_in(self, auth_client):
        """已登录返回用户信息"""
        r = auth_client.get("/api/user/info")
        assert r.status_code == 200
        data = r.get_json()
        assert data["success"] is True
        assert data["user"]["role"] == "user"


class TestIndex:
    """平台首页（/ 由 platform Blueprint 接管）"""

    def test_index_not_logged_in_redirect(self, client):
        """未登录访问 / 重定向到 /login（带 next 参数）"""
        r = client.get("/")
        assert r.status_code == 302
        # SPA 回退路由在未登录时重定向到 /login?next=/
        assert "/login" in r.headers["Location"]

    def test_index_logged_in(self, auth_client):
        """已登录访问 / 返回平台首页（模块卡片）"""
        r = auth_client.get("/")
        assert r.status_code == 200
        # 平台首页应包含模块名
        assert b"\xe9\x97\xae\xe9\xa2\x98" in r.data  # "问题" UTF-8
