Repository: igorbenav/fastcrud
Pull request #216 (2025-03-28 11:43:17)

code fix in get_multi_by_cursor
Added tests for desc sort in get_multi_by_cursor

# Pull Request Template for FastCRUD

## Description
Fixed logic for desc sotring, added test for this case.

## Changes
Briefly list the changes you've made. If applicable, also link any relevant issues or pull requests.

## Tests
Describe the tests you added or modified to cover your changes, if applicable.

## Checklist
- [x] I have read the [CONTRIBUTING](CONTRIBUTING.md) document.
- [x] My code follows the code style of this project.
- [x] I have added necessary documentation (if appropriate).
- [x] I have added tests that cover my changes (if applicable).
- [x] All new and existing tests passed.

## Additional Notes
Include any additional information that you think is important for reviewers to know.



Patch:
diff --git a/fastcrud/crud/fast_crud.py b/fastcrud/crud/fast_crud.py
index 08ed6fb..86eb0cd 100644
--- a/fastcrud/crud/fast_crud.py
+++ b/fastcrud/crud/fast_crud.py
@@ -2225,12 +2225,7 @@ class FastCRUD(
         result = await db.execute(stmt)
         data = [dict(row) for row in result.mappings()]
 
-        next_cursor = None
-        if len(data) == limit:
-            if sort_order == "asc":
-                next_cursor = data[-1][sort_column]
-            else:
-                data[0][sort_column]
+        next_cursor = data[-1][sort_column] if len(data) == limit else None
 
         return {"data": data, "next_cursor": next_cursor}
 


Test patch:
diff --git a/tests/sqlalchemy/crud/test_get_multi_by_cursor.py b/tests/sqlalchemy/crud/test_get_multi_by_cursor.py
index ffa1fb1..e307f21 100644
--- a/tests/sqlalchemy/crud/test_get_multi_by_cursor.py
+++ b/tests/sqlalchemy/crud/test_get_multi_by_cursor.py
@@ -169,3 +169,47 @@ async def test_get_multi_by_cursor_desc_with_cursor_filter(async_session, test_d
         assert (
             record["id"] < first_page_last_id
         ), "Each ID in the second page should be less than the last ID of the first page"
+
+
+@pytest.mark.asyncio
+async def test_get_multi_by_cursor_descending_order(async_session, test_data):
+    for item in test_data:
+        async_session.add(ModelTest(**item))
+    await async_session.commit()
+
+    crud = FastCRUD(ModelTest)
+    
+    first_page = await crud.get_multi_by_cursor(
+        db=async_session,
+        limit=2,
+        sort_column="id",
+        sort_order="desc"
+    )
+    next_cursor = first_page["next_cursor"]
+    item1, item2 = first_page["data"][0]["id"], first_page["data"][1]["id"]
+    
+    assert len(first_page["data"]) == 2
+    assert first_page["data"][0]["id"] == 11  # Should start with highest ID
+    assert first_page["data"][1]["id"] == 10
+    assert first_page["next_cursor"] == 10  # Next cursor should be the last ID in the result
+
+    while next_cursor is not None:
+        next_page = await crud.get_multi_by_cursor(
+            db=async_session,
+            cursor=next_cursor,
+            limit=2,
+            sort_column="id",
+            sort_order="desc"
+        )
+        next_cursor = next_page["next_cursor"]
+        if len(next_page["data"]) == 2:
+            assert next_page["data"][0]["id"] == item1 - 2
+            assert next_page["data"][1]["id"] == item2 - 2
+            assert next_cursor == item2 - 2
+            item1 -= 2
+            item2 -= 2
+        else:
+            assert next_page["data"][0]["id"] == item1 - 2
+            assert next_cursor is None
+
+