From 229bef99f6bd0163e29620445b87f977a6d29886 Mon Sep 17 00:00:00 2001 From: IluaAir Date: Sat, 6 Jun 2026 13:55:01 +0300 Subject: [PATCH] Add UTF-8 decoding utility and corresponding unit tests - Introduced a new utility function `decode_utf` in `utils.py` to decode escaped UTF-8 descriptions. - Updated unit tests in `test_units.py` to include tests for the `decode_utf` function, covering plain text and escaped UTF-8 scenarios. - Refactored existing tests to streamline the usage of the `expand_vlan_range` function. --- oxi/interfaces/utils.py | 14 ++++++++++++++ tests/test_units.py | 27 +++++++++++---------------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/oxi/interfaces/utils.py b/oxi/interfaces/utils.py index f91466d..7348000 100644 --- a/oxi/interfaces/utils.py +++ b/oxi/interfaces/utils.py @@ -23,3 +23,17 @@ def expand_vlan_range(value: str | list[str]) -> list[str]: else: result.append(part) return result + + +def decode_utf(text: str): + """Decode escaped UTF-8 descriptions.""" + if "\\x" in text: + desc = text.strip('"') + decoded = ( + desc.encode("utf-8") + .decode("unicode_escape") + .encode("latin1") + .decode("utf-8") + ) + return decoded + return text diff --git a/tests/test_units.py b/tests/test_units.py index ad7cf32..0df7e8e 100644 --- a/tests/test_units.py +++ b/tests/test_units.py @@ -5,42 +5,37 @@ from oxi.exception import OxiAPIError from oxi.interfaces import device_registry from oxi.interfaces.base import BaseDevice from oxi.interfaces.contract import Interfaces, System -from oxi.interfaces.utils import expand_vlan_range as eltex_expand -from oxi.interfaces.utils import expand_vlan_range as qtech_expand +from oxi.interfaces.utils import decode_utf, expand_vlan_range class TestExpandVlanRange: - @pytest.mark.parametrize("expand", [qtech_expand, eltex_expand]) + @pytest.mark.parametrize("expand", [expand_vlan_range]) def test_simple_and_range(self, expand): assert expand("1,7,14-15") == ["1", "7", "14", "15"] - @pytest.mark.parametrize("expand", [qtech_expand, eltex_expand]) + @pytest.mark.parametrize("expand", [expand_vlan_range]) def test_reversed_range_is_normalized(self, expand): assert expand("15-13") == ["13", "14", "15"] - @pytest.mark.parametrize("expand", [qtech_expand, eltex_expand]) + @pytest.mark.parametrize("expand", [expand_vlan_range]) def test_non_numeric_range_kept_verbatim(self, expand): assert expand("a-b") == ["a-b"] - @pytest.mark.parametrize("expand", [qtech_expand, eltex_expand]) + @pytest.mark.parametrize("expand", [expand_vlan_range]) def test_empty(self, expand): assert expand("") == [] - @pytest.mark.parametrize("expand", [qtech_expand, eltex_expand]) + @pytest.mark.parametrize("expand", [expand_vlan_range]) def test_list_input(self, expand): assert expand(["1", "3-4"]) == ["1", "3", "4"] -class TestKeeneticDecodeUtf: - @pytest.fixture(scope="class") - def keenetic(self): - return device_registry["keenetic"](load("keenetic")) +class TestDecodeUtf: + def test_plain_text_passthrough(self): + assert decode_utf("Plain ASCII") == "Plain ASCII" - def test_plain_text_passthrough(self, keenetic): - assert keenetic._decode_utf("Plain ASCII") == "Plain ASCII" - - def test_escaped_utf8_is_decoded(self, keenetic): - assert keenetic._decode_utf(r'"\xd0\x94\xd0\xbe\xd0\xbc"') == "Дом" + def test_escaped_utf8_is_decoded(self): + assert decode_utf(r'"\xd0\x94\xd0\xbe\xd0\xbc"') == "Дом" class TestTemplateValidation: