Files
fitguide/tests/test_augmented_part_sync_uac.py
T

157 lines
5.2 KiB
Python

"""UACDiameterRangemm handling in the AugmentedPart sync service: the
reformatted range field on AugmentedPart, and the "Objective" clamp
attachment point it should produce."""
import pytest
from sqlalchemy import select
from app.crud import attachment_point as attachment_point_crud
from app.crud import clamp_connection as clamp_connection_crud
from app.models.augmented_part import AugmentedPart
from app.models.imported_part import ImportedPart
from app.models.manufacturer import Manufacturer
from app.models.part_colour import PartColour
from app.models.part_type import PartType
from app.services import augmented_part_sync
from app.services.augmented_part_sync import _parse_uac_diameter_range
def test_parse_uac_diameter_range_valid_8_digits():
assert _parse_uac_diameter_range("03505500") == ("03.50-55.00", 3.5, 55.0)
@pytest.mark.parametrize("value", [None, "", "1234567", "123456789", "abcdefgh"])
def test_parse_uac_diameter_range_rejects_non_8_digit(value):
assert _parse_uac_diameter_range(value) is None
def test_parse_uac_diameter_range_strips_non_digit_separators():
# Defensive: pull digits out even if the feed adds punctuation.
assert _parse_uac_diameter_range("0350-5500") == ("03.50-55.00", 3.5, 55.0)
async def _seed_reference_data(db):
manufacturer = Manufacturer(name="Acme", url="https://acme.test")
colour = PartColour(name="Black")
part_type = PartType(name="Scope")
db.add_all([manufacturer, colour, part_type])
await db.flush()
return manufacturer, colour, part_type
@pytest.mark.asyncio
async def test_sync_populates_range_and_creates_objective_clamp_point(
db_sessionmaker,
):
async with db_sessionmaker() as db:
await _seed_reference_data(db)
db.add(
ImportedPart(
InventoryID="INV-UAC-1",
Description="Scope widget",
UACDiameterRangemm="03505500",
)
)
await db.commit()
result = await augmented_part_sync.sync(db)
assert result.created == 1
ap = (
await db.execute(
select(AugmentedPart).where(AugmentedPart.sku == "INV-UAC-1")
)
).scalar_one()
assert ap.uac_diameter_range_mm == "03.50-55.00"
points = await attachment_point_crud.list_for_augmented_part(db, ap.id)
objective_points = [
p for p in points if p.attachment_point_name.name == "Objective"
]
assert len(objective_points) == 1
clamp = await clamp_connection_crud.get(
db, objective_points[0].clamp_connection_id
)
assert clamp.min_mm == 3.5
assert clamp.max_mm == 55.0
assert clamp.min_in == pytest.approx(3.5 / 25.4)
assert clamp.max_in == pytest.approx(55.0 / 25.4)
@pytest.mark.asyncio
async def test_sync_leaves_range_and_objective_point_unset_when_field_blank(
db_sessionmaker,
):
async with db_sessionmaker() as db:
await _seed_reference_data(db)
db.add(ImportedPart(InventoryID="INV-NO-UAC", Description="Scope widget"))
await db.commit()
result = await augmented_part_sync.sync(db)
assert result.created == 1
ap = (
await db.execute(
select(AugmentedPart).where(AugmentedPart.sku == "INV-NO-UAC")
)
).scalar_one()
assert ap.uac_diameter_range_mm is None
points = await attachment_point_crud.list_for_augmented_part(db, ap.id)
assert all(p.attachment_point_name.name != "Objective" for p in points)
@pytest.mark.asyncio
async def test_sync_reuses_existing_clamp_connection_for_same_range(db_sessionmaker):
async with db_sessionmaker() as db:
await _seed_reference_data(db)
db.add_all(
[
ImportedPart(
InventoryID="INV-UAC-A",
Description="Scope widget A",
UACDiameterRangemm="03505500",
),
ImportedPart(
InventoryID="INV-UAC-B",
Description="Scope widget B",
UACDiameterRangemm="03505500",
),
]
)
await db.commit()
result = await augmented_part_sync.sync(db)
assert result.created == 2
clamps = await clamp_connection_crud.list_all(db)
assert len(clamps) == 1
@pytest.mark.asyncio
async def test_sync_one_populates_range_and_objective_point(db_sessionmaker):
async with db_sessionmaker() as db:
manufacturer, colour, part_type = await _seed_reference_data(db)
db.add(
ImportedPart(
InventoryID="INV-UAC-MANUAL",
Description="Odd widget",
UACDiameterRangemm="10002000",
)
)
await db.commit()
ap = await augmented_part_sync.sync_one(
db,
inventory_id="INV-UAC-MANUAL",
part_type_id=part_type.id,
sub_part_type_id=None,
)
assert ap.uac_diameter_range_mm == "10.00-20.00"
points = await attachment_point_crud.list_for_augmented_part(db, ap.id)
objective_points = [
p for p in points if p.attachment_point_name.name == "Objective"
]
assert len(objective_points) == 1