# -*- coding: utf-8 -*- """Flask 兼容会话编解码的单元测试。 验证 core.session 与 itsdangerous(Flask 会话所用库)**双向互通**: Flask 时代签发的会话 Cookie 必须仍能被本站解析(用户不必重新登录)。 Flask 本身已从依赖中移除,这里直接用 itsdangerous 构造/校验 (Flask 会话即 itsdangerous URLSafeTimedSerializer:盐 cookie-session、HMAC-SHA1)。 """ import hashlib import time import pytest from itsdangerous import URLSafeTimedSerializer from core import session as cs SECRET = 'unit-test-secret-key' def _flask_serializer(): """等价于 Flask 的会话序列化器(同盐、同摘要算法、同 key 派生)。""" return URLSafeTimedSerializer( SECRET, salt='cookie-session', signer_kwargs={'key_derivation': 'hmac', 'digest_method': hashlib.sha1}) def test_itsdangerous_to_core(): """itsdangerous(Flask)签发的会话 Cookie 能被 core.session 解出。""" cookie = _flask_serializer().dumps({'site_uid': 26, 'site_uid_seq': 5}) data = cs.loads(SECRET, cookie) assert data == {'site_uid': 26, 'site_uid_seq': 5} assert cs.get_uid(data) == 26 def test_core_to_itsdangerous(): """core.session 签发的 Cookie 能被 itsdangerous 解出。""" cookie = cs.dumps(SECRET, {'site_uid': 74, 'site_uid_seq': 8}) assert _flask_serializer().loads(cookie) == {'site_uid': 74, 'site_uid_seq': 8} def test_core_timestamp_valid_for_timed_check(): """时间戳编码与 itsdangerous 一致:max_age 校验可用(未过期)。""" cookie = cs.dumps(SECRET, {'site_uid': 1}) assert _flask_serializer().loads(cookie, max_age=3600) == {'site_uid': 1} def test_tampered_returns_none(): cookie = _flask_serializer().dumps({'site_uid': 26}) assert cs.loads(SECRET, cookie[:-3] + 'xyz') is None def test_wrong_key_returns_none(): cookie = _flask_serializer().dumps({'site_uid': 26}) assert cs.loads('wrong-secret', cookie) is None def test_garbage_returns_none(): assert cs.loads(SECRET, 'not-a-cookie') is None assert cs.loads(SECRET, '') is None def test_roundtrip_selfconsistency(): payload = {'site_uid': 9, 'site_uid_seq': 3, 'site_uid_ts': int(time.time())} assert cs.loads(SECRET, cs.dumps(SECRET, payload)) == payload def test_get_uid_none(): assert cs.get_uid(None) is None assert cs.get_uid({}) is None @pytest.mark.parametrize('uid', [1, 26, 99999]) def test_various_uids(uid): assert cs.get_uid(cs.loads(SECRET, cs.dumps(SECRET, {'site_uid': uid}))) == uid