Adding UAC Diameter Range MM to augmented parts
This commit is contained in:
1 parent
597cf68157
commit
d23f5b9e82
7 files changed
+263
-2
No files matched your search
@@ -0,0 +1,156 @@
|
||||
"""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
|
||||
Reference in new issue
Block a user