diff --git a/netbox/utilities/conversion.py b/netbox/utilities/conversion.py index 6ce32212a..36ac072d8 100644 --- a/netbox/utilities/conversion.py +++ b/netbox/utilities/conversion.py @@ -1,4 +1,4 @@ -from decimal import Decimal +from decimal import Decimal, InvalidOperation from django.utils.translation import gettext as _ @@ -37,28 +37,29 @@ def to_grams(weight, unit) -> int: ) -def to_meters(length, unit): +def to_meters(length, unit) -> Decimal: """ - Convert the given length to meters. + Convert the given length to meters, returning a Decimal value. """ try: - if length < 0: - raise ValueError(_("Length must be a positive number")) - except TypeError: + length = Decimal(length) + except InvalidOperation: raise TypeError(_("Invalid value '{length}' for length (must be a number)").format(length=length)) + if length < 0: + raise ValueError(_("Length must be a positive number")) if unit == CableLengthUnitChoices.UNIT_KILOMETER: - return length * 1000 + return round(Decimal(length * 1000), 4) if unit == CableLengthUnitChoices.UNIT_METER: - return length + return round(Decimal(length), 4) if unit == CableLengthUnitChoices.UNIT_CENTIMETER: - return length / 100 + return round(Decimal(length / 100), 4) if unit == CableLengthUnitChoices.UNIT_MILE: - return length * Decimal(1609.344) + return round(length * Decimal(1609.344), 4) if unit == CableLengthUnitChoices.UNIT_FOOT: - return length * Decimal(0.3048) + return round(length * Decimal(0.3048), 4) if unit == CableLengthUnitChoices.UNIT_INCH: - return length * Decimal(0.0254) + return round(length * Decimal(0.0254), 4) raise ValueError( _("Unknown unit {unit}. Must be one of the following: {valid_units}").format( unit=unit, diff --git a/netbox/utilities/tests/test_conversions.py b/netbox/utilities/tests/test_conversions.py new file mode 100644 index 000000000..2338a7ac2 --- /dev/null +++ b/netbox/utilities/tests/test_conversions.py @@ -0,0 +1,53 @@ +from decimal import Decimal + +from dcim.choices import CableLengthUnitChoices +from netbox.choices import WeightUnitChoices +from utilities.conversion import to_grams, to_meters +from utilities.testing.base import TestCase + + +class ConversionsTest(TestCase): + + def test_to_grams(self): + self.assertEqual( + to_grams(1, WeightUnitChoices.UNIT_KILOGRAM), + 1000 + ) + self.assertEqual( + to_grams(1, WeightUnitChoices.UNIT_GRAM), + 1 + ) + self.assertEqual( + to_grams(1, WeightUnitChoices.UNIT_POUND), + 453 + ) + self.assertEqual( + to_grams(1, WeightUnitChoices.UNIT_OUNCE), + 28 + ) + + def test_to_meters(self): + self.assertEqual( + to_meters(1.5, CableLengthUnitChoices.UNIT_KILOMETER), + Decimal('1500') + ) + self.assertEqual( + to_meters(1, CableLengthUnitChoices.UNIT_METER), + Decimal('1') + ) + self.assertEqual( + to_meters(1, CableLengthUnitChoices.UNIT_CENTIMETER), + Decimal('0.01') + ) + self.assertEqual( + to_meters(1, CableLengthUnitChoices.UNIT_MILE), + Decimal('1609.344') + ) + self.assertEqual( + to_meters(1, CableLengthUnitChoices.UNIT_FOOT), + Decimal('0.3048') + ) + self.assertEqual( + to_meters(1, CableLengthUnitChoices.UNIT_INCH), + Decimal('0.0254') + )