Skip to content

Commit

Permalink
Add some tests and code improvements (#377)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vaskivskyi authored Nov 19, 2023
1 parent 8690971 commit c7b5e8e
Show file tree
Hide file tree
Showing 12 changed files with 630 additions and 46 deletions.
5 changes: 5 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[run]
source = asusrouter
omit =
# Constants modules
asusrouter/modules/endpoint/devicemap_const.py
3 changes: 1 addition & 2 deletions asusrouter/modules/endpoint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from asusrouter.error import AsusRouter404Error
from asusrouter.modules.data import AsusData, AsusDataState
from asusrouter.modules.firmware import Firmware
from asusrouter.modules.flags import Flag
from asusrouter.modules.wlan import Wlan

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -126,7 +125,7 @@ def data_set(data: dict[str, Any], **kwargs: Any) -> dict[str, Any]:
return data


def data_get(data: dict[str, Any], key: str) -> Any:
def data_get(data: dict[str, Any], key: str) -> Optional[Any]:
"""Extract value from the data dict and update the data dict."""

# Get the value
Expand Down
2 changes: 1 addition & 1 deletion asusrouter/modules/endpoint/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from asusrouter.tools.readers import read_json_content


def read(content: str) -> dict[str, Any]: # pylint: disable=unused-argument
def read(content: str) -> dict[str, Any]:
"""Read state data"""

# Read the json content
Expand Down
97 changes: 58 additions & 39 deletions asusrouter/modules/endpoint/devicemap.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ def read(content: str) -> dict[str, Any]:
devicemap: dict[str, Any] = {}

# Parse the XML data
xml_content: dict[str, Any] = xmltodict.parse(content).get("devicemap", {})
if not xml_content:
try:
xml_content: dict[str, Any] = xmltodict.parse(content).get("devicemap", {})
if not xml_content:
return devicemap
except xmltodict.expat.ExpatError: # type: ignore
return devicemap

# Go through the data and fill the dict
Expand All @@ -42,6 +45,8 @@ def read(content: str) -> dict[str, Any]:

# Clear values from useless symbols
for output_group, clear_map in DEVICEMAP_CLEAR.items():
if output_group not in devicemap:
continue
for key, clear_value in clear_map.items():
# If the key is not in the devicemap, continue
if key not in devicemap[output_group]:
Expand All @@ -61,22 +66,30 @@ def read(content: str) -> dict[str, Any]:
return devicemap


# This method performs reading of the devicemap by index
# to simplify the original read_devicemap method
def read_index(xml_content: dict[str, Any]) -> dict[str, Any]:
"""Read devicemap by index."""
"""Read devicemap by index.
This method performs reading of the devicemap by index
to simplify the original read_devicemap method."""

# Create a dict to store the data
devicemap: dict[str, Any] = {}

# Get values for which we only know their order (index)
for output_group, input_group, input_values in DEVICEMAP_BY_INDEX:
# Create a dict to store the data
output_group_data: dict[str, Any] = {}
# Create an empty dictionary for the output group
devicemap[output_group] = {}

# Go through the input values and fill the dict
for index, input_value in enumerate(input_values):
output_group_data[input_value] = xml_content[input_group][index]
# Check that the input group is in the xml content
if input_group not in xml_content:
continue

# Use dict comprehension to build output_group_data
output_group_data = {
input_value: xml_content[input_group][index]
for index, input_value in enumerate(input_values)
if index < len(xml_content[input_group])
}

# Add the output group data to the devicemap
devicemap[output_group] = output_group_data
Expand All @@ -85,10 +98,11 @@ def read_index(xml_content: dict[str, Any]) -> dict[str, Any]:
return devicemap


# This method performs reading of the devicemap by key
# to simplify the original read_devicemap method
def read_key(xml_content: dict[str, Any]) -> dict[str, Any]:
"""Read devicemap by key."""
"""Read devicemap by key.
This method performs reading of the devicemap by key
to simplify the original read_devicemap method."""

# Create a dict to store the data
devicemap: dict[str, Any] = {}
Expand All @@ -100,27 +114,25 @@ def read_key(xml_content: dict[str, Any]) -> dict[str, Any]:

# Go through the input values and fill the dict
for input_value in input_values:
# Check if the input group is a string
if isinstance(xml_content.get(input_group), str):
# Check if the input value is in the input group
if input_value in xml_content[input_group]:
# Add the input value to the output group data and remove the key
output_group_data[input_value] = xml_content[input_group].replace(
# Get the input group data
xml_input_group = xml_content.get(input_group)

# If the input group data is None, skip this iteration
if xml_input_group is None:
continue

# If the input group data is a string, convert it to a list
if isinstance(xml_input_group, str):
xml_input_group = [xml_input_group]

# Go through the input group data and check if the input value is in it
for value in xml_input_group:
if input_value in value:
# Add the input value to the output group data
output_group_data[input_value] = value.replace(
f"{input_value}=", ""
)
# Check if the input group is a list
else:
# Go through the input group and check if the input value is in it
xml_input_group = xml_content.get(input_group)
if not xml_input_group:
continue
for value in xml_input_group:
if input_value in value:
# Add the input value to the output group data
output_group_data[input_value] = value.replace(
f"{input_value}=", ""
)
break
break

# Add the output group data to the devicemap
devicemap[output_group] = output_group_data
Expand All @@ -142,17 +154,24 @@ def read_special(xml_content: dict[str, Any]) -> dict[str, Any]:
def read_uptime_string(content: str) -> datetime | None:
"""Read uptime string and return proper datetime object."""

# Split the content into the date/time part and the seconds part
uptime_parts = content.split("(")
if len(uptime_parts) < 2:
return None

# Extract the number of seconds from the seconds part
seconds_match = re.search("([0-9]+)", uptime_parts[1])
if not seconds_match:
return None

try:
part = content.split("(")
match = re.search("([0-9]+)", part[1])
if not match:
return None
seconds = int(match.group())
when = dtparse(part[0])
uptime = when - timedelta(seconds=seconds)
seconds = int(seconds_match.group())
when = dtparse(uptime_parts[0])
except ValueError:
return None

uptime = when - timedelta(seconds=seconds)

return uptime


Expand Down
1 change: 1 addition & 0 deletions requirements_test.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Pytest for running tests
pytest>=7.4.3
pytest-asyncio>=0.21.1
pytest-cov>=4.1.0
2 changes: 1 addition & 1 deletion tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"""Tests for AsusRouter"""
"""Tests for AsusRouter."""
1 change: 1 addition & 0 deletions tests/modules/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for the AsusRouter modules."""
1 change: 1 addition & 0 deletions tests/modules/endpoint/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for AsusRouter endpoint module."""
27 changes: 27 additions & 0 deletions tests/modules/endpoint/test_command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Test AsusRouter command endpoint module."""

from unittest.mock import patch

from asusrouter.modules.endpoint import command


def test_read():
"""Test read function."""

# Test data
content = '{"key1": "value1", "key2": "value2"}'
expected_command = {"key1": "value1", "key2": "value2"}

# Mock the read_json_content function
with patch(
"asusrouter.modules.endpoint.command.read_json_content",
return_value=expected_command,
) as mock_read_json_content:
# Call the function
result = command.read(content)

# Check the result
assert result == expected_command

# Check that read_json_content was called with the correct argument
mock_read_json_content.assert_called_once_with(content)
Loading

0 comments on commit c7b5e8e

Please sign in to comment.