From 3611d9dbe2e215804e8392ecfac3c356edb1ca73 Mon Sep 17 00:00:00 2001 From: Cizz22 Date: Tue, 24 Feb 2026 13:51:31 +0700 Subject: [PATCH] feat: Add a unit testing guide, update pytest configuration to target unit tests, and refactor the overhaul activity service to use paginated equipment retrieval with location filtering. --- TESTING.md | 44 ++++++++++++++++++++++++++++++++ pytest.ini | 2 +- src/overhaul_activity/service.py | 31 +++++++++++++--------- 3 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 TESTING.md diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 0000000..e254eb6 --- /dev/null +++ b/TESTING.md @@ -0,0 +1,44 @@ +# Unit Testing Guide - be-optimumoh + +This document provides instructions on how to set up and run unit tests for the **be-optimumoh** project. + +## 1. Preparation + +### Install Dependencies +Ensure you have all dependencies installed. This project uses `poetry`. + +```bash +# Install dependencies +poetry install +``` + +## 2. Configuration + +### Pytest Configuration +Ensure the `pytest.ini` file in the root directory points to the `unit` test folder: + +```ini +[pytest] +testpaths = tests/unit +python_files = test_*.py +asyncio_mode = auto +``` + +## 3. Running Tests + +### Run Unit Tests +To run all unit tests in the project: + +```bash +poetry run pytest tests/unit +``` + +### Run Specific Unit Test File +```bash +poetry run pytest tests/unit/test_specific_feature.py +``` + +## 4. Best Practices + +- **Isolation**: Unit tests should be isolated from external services. Use mocking for APIs and databases. +- **Async Testing**: Use `@pytest.mark.asyncio` for asynchronous test functions. diff --git a/pytest.ini b/pytest.ini index 3259ad7..d3f7b54 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,6 @@ [pytest] asyncio_mode = auto -testpaths = tests +testpaths = tests/unit python_files = test_*.py filterwarnings = ignore::pydantic.PydanticDeprecatedSince20 diff --git a/src/overhaul_activity/service.py b/src/overhaul_activity/service.py index e77ef40..e19bebe 100644 --- a/src/overhaul_activity/service.py +++ b/src/overhaul_activity/service.py @@ -106,10 +106,23 @@ async def get_all( ).distinct() ) - equipments = (await common['db_session'].execute(query)).scalars().all() + if location_tag: + query = query.filter(StandardScope.location_tag == location_tag) + # Use search_filter_sort_paginate for server-side pagination + # Prioritize the 'all' parameter passed to the function + common_params = {**common, "all": all or common.get("all", False)} + + paginated_results = await search_filter_sort_paginate( + model=query, + **common_params + ) + + equipments = paginated_results["items"] + material_cost = await get_cm_cost_summary(collector_db=collector_db, last_oh_date=prev_oh_scope.end_date, upcoming_oh_date=overhaul.start_date) - service_cost = get_service_cost(scope=overhaul.maintenance_type.name, total_equipment=len(equipments)) + # total_equipment for cost calculation should be the global total, not just the page + total_count = paginated_results["total"] overhaul_cost = await get_oh_cost_summary(collector_db=collector_db, last_oh_date=prev_oh_scope.end_date, upcoming_oh_date=overhaul.start_date) results = [] @@ -133,18 +146,12 @@ async def get_all( results.append(res) - # # Pagination parameters - # page = common.get("page", 1) - # items_per_page = common.get("items_per_page", 10) - - # Build response data - data = { - "items": results, - "total": len(results), + # Return paginated structure with transformed items + return { + **paginated_results, + "items": results } - return data - async def get_standard_scope_by_session_id(*, db_session: DbSession, overhaul_session_id: UUID, collector_db: CollectorDbSession): overhaul = await get_session(db_session=db_session, overhaul_session_id=overhaul_session_id)