TasmotaManager/test_get_tasmota_devices.py
Mike Geppert 126cd39555 Major code improvements and bug fixes:
1. Restructured configuration: Moved config_other and console to top level
2. Added common _match_pattern function for regex pattern matching
3. Implemented Unifi Hostname bug fix in is_hostname_unknown
4. Created common get_device_hostname function to eliminate code duplication
5. Added comprehensive test scripts for all new functionality
6. Added detailed documentation for all changes
2025-08-08 19:04:33 -05:00

146 lines
4.9 KiB
Python

#!/usr/bin/env python3
"""
Test script to verify that the get_tasmota_devices method works correctly
after modifying it to use is_hostname_unknown instead of duplicating pattern matching logic.
"""
import logging
import unittest
from unittest.mock import patch, MagicMock
# Configure logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger(__name__)
# Import TasmotaManager class
import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from TasmotaManager import TasmotaDiscovery
class TestGetTasmotaDevices(unittest.TestCase):
"""Test cases for the get_tasmota_devices method."""
def setUp(self):
"""Set up test environment."""
self.discovery = TasmotaDiscovery(debug=True)
# Create a mock config
self.discovery.config = {
'unifi': {
'network_filter': {
'test_network': {
'subnet': '192.168.1',
'exclude_patterns': [
"^homeassistant*",
"^.*sonos.*"
],
'unknown_device_patterns': [
"^tasmota_*",
"^tasmota-*",
"^esp-*",
"^ESP-*"
]
}
}
}
}
@patch('requests.get')
def test_get_tasmota_devices_with_unknown_device(self, mock_get):
"""Test get_tasmota_devices with a device that matches unknown patterns."""
# Mock the UniFi client
mock_unifi_client = MagicMock()
mock_unifi_client.get_clients.return_value = [
{
'name': 'tasmota_123',
'hostname': 'tasmota_123',
'ip': '192.168.1.100',
'mac': '00:11:22:33:44:55'
}
]
self.discovery.unifi_client = mock_unifi_client
# Call the method
devices = self.discovery.get_tasmota_devices()
# Verify results
self.assertEqual(len(devices), 1)
self.assertEqual(devices[0]['name'], 'tasmota_123')
self.assertEqual(devices[0]['ip'], '192.168.1.100')
self.assertFalse(devices[0]['unifi_hostname_bug_detected'])
logger.info("Test with unknown device passed")
@patch('requests.get')
def test_get_tasmota_devices_with_unifi_bug(self, mock_get):
"""Test get_tasmota_devices with a device affected by the Unifi hostname bug."""
# Mock the UniFi client
mock_unifi_client = MagicMock()
mock_unifi_client.get_clients.return_value = [
{
'name': 'tasmota_123',
'hostname': 'tasmota_123',
'ip': '192.168.1.100',
'mac': '00:11:22:33:44:55'
}
]
self.discovery.unifi_client = mock_unifi_client
# Mock the response for Status 5 command
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.json.return_value = {
'StatusNET': {
'Hostname': 'my_proper_device' # Self-reported hostname doesn't match unknown patterns
}
}
mock_get.return_value = mock_response
# Call the method
devices = self.discovery.get_tasmota_devices()
# Verify results
self.assertEqual(len(devices), 1)
self.assertEqual(devices[0]['name'], 'tasmota_123')
self.assertEqual(devices[0]['ip'], '192.168.1.100')
self.assertTrue(devices[0]['unifi_hostname_bug_detected'])
# Verify that requests.get was called with the correct URL
mock_get.assert_called_once_with("http://192.168.1.100/cm?cmnd=Status%205", timeout=5)
logger.info("Test with Unifi hostname bug passed")
@patch('requests.get')
def test_get_tasmota_devices_with_excluded_device(self, mock_get):
"""Test get_tasmota_devices with a device that matches exclude patterns."""
# Mock the UniFi client
mock_unifi_client = MagicMock()
mock_unifi_client.get_clients.return_value = [
{
'name': 'homeassistant',
'hostname': 'homeassistant.local',
'ip': '192.168.1.100',
'mac': '00:11:22:33:44:55'
}
]
self.discovery.unifi_client = mock_unifi_client
# Call the method
devices = self.discovery.get_tasmota_devices()
# Verify results
self.assertEqual(len(devices), 0) # Device should be excluded
logger.info("Test with excluded device passed")
def main():
"""Run the tests."""
unittest.main()
if __name__ == "__main__":
main()