diff --git a/goosebit/ui/bff/software/responses.py b/goosebit/ui/bff/software/responses.py index 62fd771f..e423acf9 100644 --- a/goosebit/ui/bff/software/responses.py +++ b/goosebit/ui/bff/software/responses.py @@ -5,7 +5,8 @@ from tortoise.queryset import QuerySet from goosebit.schema.software import SoftwareSchema -from goosebit.ui.bff.common.requests import DataTableRequest + +from ..common.requests import DataTableOrderDirection, DataTableRequest class BFFSoftwareResponse(BaseModel): @@ -23,15 +24,24 @@ async def convert(cls, dt_query: DataTableRequest, query: QuerySet, search_filte filtered_records = await query.count() - if dt_query.order_query: - query = query.order_by(dt_query.order_query) + if len(dt_query.order) > 0 and dt_query.order[0].name == "version": + # ordering cannot be delegated to database as semantic versioning sorting is not supported + software = await query.all() + reverse = dt_query.order[0].dir == DataTableOrderDirection.DESCENDING + software.sort(key=lambda s: s.parsed_version, reverse=reverse) - # if no ordering is specified, database-side paging can be used - if dt_query.length is not None: - query = query.limit(dt_query.length) + # in-memory paging + if dt_query.length is None: + software = software[dt_query.start :] + else: + software = software[dt_query.start : dt_query.start + dt_query.length] - software = await query.offset(dt_query.start).all() + else: + # if no ordering is specified, database-side paging can be used + if dt_query.length is not None: + query = query.limit(dt_query.length) + software = await query.offset(dt_query.start).all() data = [SoftwareSchema.model_validate(s) for s in software] return cls(data=data, draw=dt_query.draw, records_total=total_records, records_filtered=filtered_records) diff --git a/tests/unit/ui/bff/software/test_routes.py b/tests/unit/ui/bff/software/test_routes.py index f3053379..a0813765 100644 --- a/tests/unit/ui/bff/software/test_routes.py +++ b/tests/unit/ui/bff/software/test_routes.py @@ -8,9 +8,9 @@ async def test_list_software_version_asc(async_client, test_data): assert response.status_code == 200 software = response.json()["data"] assert len(software) == 3 - assert software[0]["version"] == test_data["software_release"].version - assert software[1]["version"] == test_data["software_beta"].version - assert software[2]["version"] == test_data["software_rc"].version + assert software[0]["version"] == test_data["software_beta"].version + assert software[1]["version"] == test_data["software_rc"].version + assert software[2]["version"] == test_data["software_release"].version @pytest.mark.asyncio @@ -20,6 +20,6 @@ async def test_list_software_version_desc(async_client, test_data): assert response.status_code == 200 software = response.json()["data"] assert len(software) == 3 - assert software[0]["version"] == test_data["software_rc"].version - assert software[1]["version"] == test_data["software_beta"].version - assert software[2]["version"] == test_data["software_release"].version + assert software[0]["version"] == test_data["software_release"].version + assert software[1]["version"] == test_data["software_rc"].version + assert software[2]["version"] == test_data["software_beta"].version