diff --git a/spoolman/api/v1/filament.py b/spoolman/api/v1/filament.py index 50a70c9..be22675 100644 --- a/spoolman/api/v1/filament.py +++ b/spoolman/api/v1/filament.py @@ -115,12 +115,28 @@ class FilamentUpdateParameters(FilamentParameters): async def find( *, db: Annotated[AsyncSession, Depends(get_db_session)], + vendor_name_old: Optional[str] = Query( + alias="vendor_name", + default=None, + title="Vendor Name", + description="Partial case-insensitive search term for the filament vendor name.", + deprecated=True, + ), + vendor_id_old: Optional[int] = Query( + alias="vendor_id", + default=None, + title="Vendor ID", + description="Match an exact vendor ID.", + deprecated=True, + ), vendor_name: Optional[str] = Query( + alias="vendor.name", default=None, title="Vendor Name", description="Partial case-insensitive search term for the filament vendor name.", ), vendor_id: Optional[int] = Query( + alias="vendor.id", default=None, title="Vendor ID", description="Match an exact vendor ID.", @@ -167,8 +183,8 @@ async def find( db_items, total_count = await filament.find( db=db, - vendor_name=vendor_name, - vendor_id=vendor_id, + vendor_name=vendor_name if vendor_name is not None else vendor_name_old, + vendor_id=vendor_id if vendor_id is not None else vendor_id_old, name=name, material=material, article_number=article_number, diff --git a/spoolman/api/v1/spool.py b/spoolman/api/v1/spool.py index 3eefc25..dc7762a 100644 --- a/spoolman/api/v1/spool.py +++ b/spoolman/api/v1/spool.py @@ -73,27 +73,67 @@ class SpoolUseParameters(BaseModel): async def find( *, db: Annotated[AsyncSession, Depends(get_db_session)], + filament_name_old: Optional[str] = Query( + alias="filament_name", + default=None, + title="Filament Name", + description="Partial case-insensitive search term for the filament name.", + deprecated=True, + ), + filament_id_old: Optional[int] = Query( + alias="filament_id", + default=None, + title="Filament ID", + description="Match an exact filament ID.", + deprecated=True, + ), + filament_material_old: Optional[str] = Query( + alias="filament_material", + default=None, + title="Filament Material", + description="Partial case-insensitive search term for the filament material.", + deprecated=True, + ), + vendor_name_old: Optional[str] = Query( + alias="vendor_name", + default=None, + title="Vendor Name", + description="Partial case-insensitive search term for the filament vendor name.", + deprecated=True, + ), + vendor_id_old: Optional[int] = Query( + alias="vendor_id", + default=None, + title="Vendor ID", + description="Match an exact vendor ID.", + deprecated=True, + ), filament_name: Optional[str] = Query( + alias="filament.name", default=None, title="Filament Name", description="Partial case-insensitive search term for the filament name.", ), filament_id: Optional[int] = Query( + alias="filament.id", default=None, title="Filament ID", description="Match an exact filament ID.", ), filament_material: Optional[str] = Query( + alias="filament.material", default=None, title="Filament Material", description="Partial case-insensitive search term for the filament material.", ), vendor_name: Optional[str] = Query( + alias="vendor.name", default=None, title="Vendor Name", description="Partial case-insensitive search term for the filament vendor name.", ), vendor_id: Optional[int] = Query( + alias="vendor.id", default=None, title="Vendor ID", description="Match an exact vendor ID.", @@ -119,7 +159,7 @@ async def find( description=( 'Sort the results by the given field. Should be a comma-separate string with "field:direction" items.' ), - example="filament.name:asc,location:desc", + example="filament.name:asc,vendor.id:asc,location:desc", ), limit: Optional[int] = Query( default=None, @@ -140,11 +180,11 @@ async def find( db_items, total_count = await spool.find( db=db, - filament_name=filament_name, - filament_id=filament_id, - filament_material=filament_material, - vendor_name=vendor_name, - vendor_id=vendor_id, + filament_name=filament_name if filament_name is not None else filament_name_old, + filament_id=filament_id if filament_id is not None else filament_id_old, + filament_material=filament_material if filament_material is not None else filament_material_old, + vendor_name=vendor_name if vendor_name is not None else vendor_name_old, + vendor_id=vendor_id if vendor_id is not None else vendor_id_old, location=location, lot_nr=lot_nr, allow_archived=allow_archived, diff --git a/tests_integration/tests/filament/test_find.py b/tests_integration/tests/filament/test_find.py index a833add..91ad44d 100644 --- a/tests_integration/tests/filament/test_find.py +++ b/tests_integration/tests/filament/test_find.py @@ -1,15 +1,24 @@ """Integration tests for the Filament API endpoint.""" +from collections.abc import Iterable +from dataclasses import dataclass from typing import Any import httpx +import pytest URL = "http://spoolman:8000" -def test_find_filaments(random_vendor: dict[str, Any]): - """Test finding filaments from the database.""" - # Setup +@dataclass +class Fixture: + filaments: list[dict[str, Any]] + filaments_by_id: dict[str, dict[str, Any]] + + +@pytest.fixture() +def filaments(random_vendor: dict[str, Any]) -> Iterable[Fixture]: + """Add some filaments to the database.""" result = httpx.post( f"{URL}/api/v1/filament", json={ @@ -46,24 +55,57 @@ def test_find_filaments(random_vendor: dict[str, Any]): result.raise_for_status() filament_2 = result.json() + result = httpx.post( + f"{URL}/api/v1/filament", + json={ + "name": "Filament Y", + "material": "PETG", + "price": 200, + "density": 1.25, + "diameter": 1.75, + "weight": 1000, + "spool_weight": 250, + "article_number": "abc", + "comment": "abcdefghåäö", + }, + ) + result.raise_for_status() + filament_3 = result.json() + added_filaments_by_id = { filament_1["id"]: filament_1, filament_2["id"]: filament_2, + filament_3["id"]: filament_3, } - # Execute - find all filaments + yield Fixture( + filaments=[filament_1, filament_2, filament_3], + filaments_by_id=added_filaments_by_id, + ) + + httpx.delete(f"{URL}/api/v1/filament/{filament_1['id']}").raise_for_status() + httpx.delete(f"{URL}/api/v1/filament/{filament_2['id']}").raise_for_status() + httpx.delete(f"{URL}/api/v1/filament/{filament_3['id']}").raise_for_status() + + +def test_find_all_filaments(filaments: Fixture): + """Test finding filaments from the database.""" + # Execute result = httpx.get( f"{URL}/api/v1/filament", ) result.raise_for_status() # Verify - filaments = result.json() - assert len(filaments) == 2 - for filament in filaments: - assert filament == added_filaments_by_id[filament["id"]] + filaments_result = result.json() + assert len(filaments_result) == 3 + for filament in filaments_result: + assert filament == filaments.filaments_by_id[filament["id"]] - # Execute - find filaments by name + +def test_find_filaments_by_name(filaments: Fixture): + """Test finding filaments from the database.""" + # Execute result = httpx.get( f"{URL}/api/v1/filament", params={"name": "Filament X"}, @@ -71,11 +113,14 @@ def test_find_filaments(random_vendor: dict[str, Any]): result.raise_for_status() # Verify - filaments = result.json() - assert len(filaments) == 1 - assert filaments[0] == added_filaments_by_id[filament_1["id"]] + filaments_result = result.json() + assert len(filaments_result) == 1 + assert filaments_result[0] == filaments.filaments[0] - # Execute - find filaments by material + +def test_find_filaments_by_material(filaments: Fixture): + """Test finding filaments from the database.""" + # Execute result = httpx.get( f"{URL}/api/v1/filament", params={"material": "abs"}, @@ -83,37 +128,48 @@ def test_find_filaments(random_vendor: dict[str, Any]): result.raise_for_status() # Verify - filaments = result.json() - assert len(filaments) == 1 - assert filaments[0] == added_filaments_by_id[filament_2["id"]] + filaments_result = result.json() + assert len(filaments_result) == 1 + assert filaments_result[0] == filaments.filaments[1] - # Execute - find filaments by vendor id + +@pytest.mark.parametrize("field_name", ["vendor_id", "vendor.id"]) +def test_find_filaments_by_vendor_id(filaments: Fixture, field_name: str): + """Test finding filaments from the database.""" + # Execute result = httpx.get( f"{URL}/api/v1/filament", - params={"vendor_id": random_vendor["id"]}, + params={field_name: filaments.filaments[0]["vendor"]["id"]}, ) result.raise_for_status() # Verify - filaments = result.json() - assert len(filaments) == 2 - for filament in filaments: - assert filament == added_filaments_by_id[filament["id"]] + filaments_result = result.json() + assert len(filaments_result) == 2 + for filament in filaments_result: + assert filament == filaments.filaments_by_id[filament["id"]] - # Execute - find filaments by vendor name + +@pytest.mark.parametrize("field_name", ["vendor_name", "vendor.name"]) +def test_find_filaments_by_vendor_name(filaments: Fixture, field_name: str): + """Test finding filaments from the database.""" + # Execute result = httpx.get( f"{URL}/api/v1/filament", - params={"vendor_name": random_vendor["name"]}, + params={field_name: filaments.filaments[0]["vendor"]["name"]}, ) result.raise_for_status() # Verify - filaments = result.json() - assert len(filaments) == 2 - for filament in filaments: - assert filament == added_filaments_by_id[filament["id"]] + filaments_result = result.json() + assert len(filaments_result) == 2 + for filament in filaments_result: + assert filament == filaments.filaments_by_id[filament["id"]] - # Execute - find filaments by article number + +def test_find_filaments_by_article_number(filaments: Fixture): + """Test finding filaments from the database.""" + # Execute result = httpx.get( f"{URL}/api/v1/filament", params={"article_number": "321"}, @@ -121,10 +177,6 @@ def test_find_filaments(random_vendor: dict[str, Any]): result.raise_for_status() # Verify - filaments = result.json() - assert len(filaments) == 1 - assert filaments[0] == added_filaments_by_id[filament_2["id"]] - - # Clean up - httpx.delete(f"{URL}/api/v1/filament/{filament_1['id']}").raise_for_status() - httpx.delete(f"{URL}/api/v1/filament/{filament_2['id']}").raise_for_status() + filaments_result = result.json() + assert len(filaments_result) == 1 + assert filaments_result[0] == filaments.filaments[1] diff --git a/tests_integration/tests/spool/test_find.py b/tests_integration/tests/spool/test_find.py index 2126dcd..4559769 100644 --- a/tests_integration/tests/spool/test_find.py +++ b/tests_integration/tests/spool/test_find.py @@ -1,6 +1,6 @@ """Integration tests for the Spool API endpoint.""" -from collections.abc import Iterator +from collections.abc import Iterable from dataclasses import dataclass from typing import Any @@ -18,7 +18,7 @@ class Fixture: @pytest.fixture() -def spools(random_filament: dict[str, Any]) -> Iterator[Fixture]: +def spools(random_filament: dict[str, Any]) -> Iterable[Fixture]: """Add some spools to the database.""" result = httpx.post( f"{URL}/api/v1/spool", @@ -99,12 +99,13 @@ def test_find_all_spools_including_archived(spools: Fixture): assert spool == spools.spools_by_id[spool["id"]] -def test_find_spools_by_filament_name(spools: Fixture): +@pytest.mark.parametrize("field_name", ["filament_name", "filament.name"]) +def test_find_spools_by_filament_name(spools: Fixture, field_name: str): """Test finding spools by filament name.""" # Execute result = httpx.get( f"{URL}/api/v1/spool", - params={"filament_name": spools.filament["name"]}, + params={field_name: spools.filament["name"]}, ) result.raise_for_status() @@ -115,12 +116,13 @@ def test_find_spools_by_filament_name(spools: Fixture): assert spool == spools.spools_by_id[spool["id"]] -def test_find_spools_by_filament_id(spools: Fixture): +@pytest.mark.parametrize("field_name", ["filament_id", "filament.id"]) +def test_find_spools_by_filament_id(spools: Fixture, field_name: str): """Test finding spools by filament id.""" # Execute result = httpx.get( f"{URL}/api/v1/spool", - params={"filament_id": spools.filament["id"]}, + params={field_name: spools.filament["id"]}, ) result.raise_for_status() @@ -131,12 +133,13 @@ def test_find_spools_by_filament_id(spools: Fixture): assert spool == spools.spools_by_id[spool["id"]] -def test_find_spools_by_filament_material(spools: Fixture): +@pytest.mark.parametrize("field_name", ["filament_material", "filament.material"]) +def test_find_spools_by_filament_material(spools: Fixture, field_name: str): """Test finding spools by filament material.""" # Execute result = httpx.get( f"{URL}/api/v1/spool", - params={"filament_material": spools.filament["material"]}, + params={field_name: spools.filament["material"]}, ) result.raise_for_status() @@ -147,12 +150,13 @@ def test_find_spools_by_filament_material(spools: Fixture): assert spool == spools.spools_by_id[spool["id"]] -def test_find_spools_by_filament_vendor_name(spools: Fixture): +@pytest.mark.parametrize("field_name", ["vendor_name", "vendor.name"]) +def test_find_spools_by_filament_vendor_name(spools: Fixture, field_name: str): """Test finding spools by filament vendor name.""" # Execute result = httpx.get( f"{URL}/api/v1/spool", - params={"vendor_name": spools.filament["vendor"]["name"]}, + params={field_name: spools.filament["vendor"]["name"]}, ) result.raise_for_status() @@ -163,12 +167,13 @@ def test_find_spools_by_filament_vendor_name(spools: Fixture): assert spool == spools.spools_by_id[spool["id"]] -def test_find_spools_by_filament_vendor_id(spools: Fixture): +@pytest.mark.parametrize("field_name", ["vendor_id", "vendor.id"]) +def test_find_spools_by_filament_vendor_id(spools: Fixture, field_name: str): """Test finding spools by filament vendor id.""" # Execute result = httpx.get( f"{URL}/api/v1/spool", - params={"vendor_id": spools.filament["vendor"]["id"]}, + params={field_name: spools.filament["vendor"]["id"]}, ) result.raise_for_status()