"""回归测试: 比赛列表游标分页方向修复。 验证: - status=scheduled 时,游标条件为「大于」(ASC 方向) - 其它 status 时,游标条件为「小于」(DESC 方向) - 无 cursor 时行为不变 """ from __future__ import annotations from datetime import datetime, timezone import pytest from sqlalchemy import select from src.db.models import Match class TestCursorPaginationDirection: """验证游标条件方向与排序方向一致。""" def _build_query(self, status=None, cursor=None): """复现 list_matches 的查询构造逻辑,返回 where 条件列表。""" q = select(Match) if cursor: last_date_str, last_id_str = cursor.split("|", 1) last_date = datetime.fromisoformat(last_date_str) last_id = int(last_id_str) if status == "scheduled": q = q.where( (Match.match_date > last_date) | ((Match.match_date == last_date) & (Match.id > last_id)) ) else: q = q.where( (Match.match_date < last_date) | ((Match.match_date == last_date) & (Match.id < last_id)) ) if status: q = q.where(Match.match_status == status) if status == "scheduled": order = (Match.match_date.asc(), Match.id.asc()) else: order = (Match.match_date.desc(), Match.id.desc()) return q.order_by(*order) def test_scheduled_uses_greater_than(self): """scheduled + cursor: 应使用 > 条件(ASC 方向)。""" q = self._build_query( status="scheduled", cursor="2026-01-15T15:00:00|100" ) sql = str(q) assert ">" in sql, f"scheduled 游标应使用 >,SQL: {sql}" assert "<" not in sql or "match_date <" not in sql, f"不应出现 < 条件" def test_other_status_uses_less_than(self): """finished + cursor: 应使用 < 条件(DESC 方向)。""" q = self._build_query( status="finished", cursor="2026-01-15T15:00:00|100" ) sql = str(q) assert "<" in sql, f"finished 游标应使用 <,SQL: {sql}" assert "match_date >" not in sql, f"不应出现 > 条件" def test_no_cursor_no_direction(self): """无 cursor 时不应有游标条件。""" q = self._build_query(status="scheduled", cursor=None) sql = str(q) # 应无 match_date 比较条件(只有 status filter) assert "match_date >" not in sql assert "match_date <" not in sql def test_scheduled_order_is_asc(self): """scheduled 排序应为 ASC。""" q = self._build_query(status="scheduled", cursor=None) sql = str(q) assert "ASC" in sql, f"scheduled 应 ASC 排序,SQL: {sql}" assert "DESC" not in sql, f"不应出现 DESC" def test_finished_order_is_desc(self): """finished 排序应为 DESC。""" q = self._build_query(status="finished", cursor=None) sql = str(q) assert "DESC" in sql, f"finished 应 DESC 排序,SQL: {sql}"