226 lines
8.0 KiB
Python
226 lines
8.0 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, patch
|
|
from datetime import datetime, timedelta
|
|
|
|
from kumacli.client import KumaClient
|
|
|
|
|
|
class TestKumaClient:
|
|
def test_parse_duration_minutes(self):
|
|
"""Test parsing duration in minutes"""
|
|
client = KumaClient("http://test.com")
|
|
|
|
assert client.parse_duration("90m") == 5400 # 90 * 60
|
|
assert client.parse_duration("1m") == 60
|
|
assert client.parse_duration("120m") == 7200
|
|
|
|
def test_parse_duration_hours(self):
|
|
"""Test parsing duration in hours"""
|
|
client = KumaClient("http://test.com")
|
|
|
|
assert client.parse_duration("1h") == 3600 # 1 * 3600
|
|
assert client.parse_duration("2h") == 7200
|
|
assert client.parse_duration("24h") == 86400
|
|
|
|
def test_parse_duration_seconds(self):
|
|
"""Test parsing duration in seconds"""
|
|
client = KumaClient("http://test.com")
|
|
|
|
assert client.parse_duration("3600s") == 3600
|
|
assert client.parse_duration("60s") == 60
|
|
assert client.parse_duration("1s") == 1
|
|
|
|
def test_parse_duration_default(self):
|
|
"""Test parsing duration with default value"""
|
|
client = KumaClient("http://test.com")
|
|
|
|
assert client.parse_duration(None) == 5400 # Default 90 minutes
|
|
assert client.parse_duration("") == 5400
|
|
|
|
def test_parse_duration_invalid(self):
|
|
"""Test parsing invalid duration format"""
|
|
client = KumaClient("http://test.com")
|
|
|
|
with pytest.raises(ValueError, match="Invalid duration format"):
|
|
client.parse_duration("invalid")
|
|
|
|
with pytest.raises(ValueError, match="Invalid duration format"):
|
|
client.parse_duration("90x")
|
|
|
|
with pytest.raises(ValueError, match="Invalid duration format"):
|
|
client.parse_duration("90")
|
|
|
|
def test_parse_start_time_none(self):
|
|
"""Test parsing start time with None (current time)"""
|
|
client = KumaClient("http://test.com")
|
|
|
|
before = datetime.utcnow()
|
|
result = client.parse_start_time(None)
|
|
after = datetime.utcnow()
|
|
|
|
assert before <= result <= after
|
|
|
|
def test_parse_start_time_iso_format(self):
|
|
"""Test parsing ISO format start time"""
|
|
client = KumaClient("http://test.com")
|
|
|
|
# Test ISO format with Z
|
|
result = client.parse_start_time("2023-12-25T10:30:00Z")
|
|
expected = datetime(2023, 12, 25, 10, 30, 0)
|
|
assert result == expected
|
|
|
|
# Test ISO format with timezone
|
|
result = client.parse_start_time("2023-12-25T10:30:00+00:00")
|
|
assert result == expected
|
|
|
|
def test_parse_start_time_common_formats(self):
|
|
"""Test parsing common date/time formats"""
|
|
client = KumaClient("http://test.com")
|
|
|
|
# Full datetime
|
|
result = client.parse_start_time("2023-12-25 10:30:00")
|
|
expected = datetime(2023, 12, 25, 10, 30, 0)
|
|
assert result == expected
|
|
|
|
# Date and hour:minute
|
|
result = client.parse_start_time("2023-12-25 10:30")
|
|
expected = datetime(2023, 12, 25, 10, 30, 0)
|
|
assert result == expected
|
|
|
|
# Date only
|
|
result = client.parse_start_time("2023-12-25")
|
|
expected = datetime(2023, 12, 25, 0, 0, 0)
|
|
assert result == expected
|
|
|
|
def test_parse_start_time_invalid(self):
|
|
"""Test parsing invalid start time format"""
|
|
client = KumaClient("http://test.com")
|
|
|
|
with pytest.raises(ValueError, match="Invalid start time format"):
|
|
client.parse_start_time("invalid-date")
|
|
|
|
with pytest.raises(ValueError, match="Invalid start time format"):
|
|
client.parse_start_time("2023-13-45")
|
|
|
|
def test_find_monitors_by_pattern_success(self):
|
|
"""Test finding monitors by pattern successfully"""
|
|
client = KumaClient("http://test.com")
|
|
client.api = Mock()
|
|
|
|
mock_monitors = [
|
|
{"id": 1, "name": "Web Server"},
|
|
{"id": 2, "name": "API Server"},
|
|
{"id": 3, "name": "Database"},
|
|
{"id": 4, "name": "Web Frontend"}
|
|
]
|
|
client.api.get_monitors.return_value = mock_monitors
|
|
|
|
# Test exact match
|
|
result = client.find_monitors_by_pattern(["Web Server"])
|
|
assert len(result) == 1
|
|
assert result[0]["name"] == "Web Server"
|
|
|
|
# Test wildcard pattern
|
|
result = client.find_monitors_by_pattern(["Web*"])
|
|
assert len(result) == 2
|
|
names = [m["name"] for m in result]
|
|
assert "Web Server" in names
|
|
assert "Web Frontend" in names
|
|
|
|
def test_find_monitors_by_pattern_case_insensitive(self):
|
|
"""Test finding monitors by pattern is case insensitive"""
|
|
client = KumaClient("http://test.com")
|
|
client.api = Mock()
|
|
|
|
mock_monitors = [
|
|
{"id": 1, "name": "Web Server"},
|
|
{"id": 2, "name": "API Server"}
|
|
]
|
|
client.api.get_monitors.return_value = mock_monitors
|
|
|
|
# Test case insensitive matching
|
|
result = client.find_monitors_by_pattern(["web*"])
|
|
assert len(result) == 1
|
|
assert result[0]["name"] == "Web Server"
|
|
|
|
def test_find_monitors_by_pattern_no_matches(self):
|
|
"""Test finding monitors with no matches"""
|
|
client = KumaClient("http://test.com")
|
|
client.api = Mock()
|
|
|
|
mock_monitors = [
|
|
{"id": 1, "name": "Web Server"}
|
|
]
|
|
client.api.get_monitors.return_value = mock_monitors
|
|
|
|
result = client.find_monitors_by_pattern(["Database*"])
|
|
assert len(result) == 0
|
|
|
|
def test_find_monitors_by_pattern_duplicates(self):
|
|
"""Test finding monitors removes duplicates"""
|
|
client = KumaClient("http://test.com")
|
|
client.api = Mock()
|
|
|
|
mock_monitors = [
|
|
{"id": 1, "name": "Web Server"}
|
|
]
|
|
client.api.get_monitors.return_value = mock_monitors
|
|
|
|
# Same monitor should match both patterns
|
|
result = client.find_monitors_by_pattern(["Web*", "*Server"])
|
|
assert len(result) == 1
|
|
assert result[0]["name"] == "Web Server"
|
|
|
|
def test_find_monitors_by_pattern_api_error(self, capsys):
|
|
"""Test finding monitors handles API errors"""
|
|
client = KumaClient("http://test.com")
|
|
client.api = Mock()
|
|
|
|
client.api.get_monitors.side_effect = Exception("API Error")
|
|
|
|
result = client.find_monitors_by_pattern(["Web*"])
|
|
assert len(result) == 0
|
|
|
|
captured = capsys.readouterr()
|
|
assert "Error finding monitors: API Error" in captured.out
|
|
|
|
@patch('kumacli.client.UptimeKumaApi')
|
|
def test_connect_success(self, mock_api_class, capsys):
|
|
"""Test successful connection"""
|
|
mock_api = Mock()
|
|
mock_api_class.return_value = mock_api
|
|
mock_api.login.return_value = True
|
|
|
|
client = KumaClient("http://test.com", "user", "pass")
|
|
result = client.connect()
|
|
|
|
assert result is True
|
|
assert client.api is mock_api
|
|
mock_api_class.assert_called_once_with("http://test.com")
|
|
mock_api.login.assert_called_once_with("user", "pass")
|
|
|
|
captured = capsys.readouterr()
|
|
assert "Connected to http://test.com" in captured.out
|
|
|
|
@patch('kumacli.client.UptimeKumaApi')
|
|
def test_connect_failure(self, mock_api_class, capsys):
|
|
"""Test connection failure"""
|
|
mock_api_class.side_effect = Exception("Connection failed")
|
|
|
|
client = KumaClient("http://test.com", "user", "pass")
|
|
result = client.connect()
|
|
|
|
assert result is False
|
|
captured = capsys.readouterr()
|
|
assert "Failed to connect: Connection failed" in captured.out
|
|
|
|
def test_disconnect(self):
|
|
"""Test disconnection"""
|
|
client = KumaClient("http://test.com")
|
|
client.api = Mock()
|
|
|
|
client.disconnect()
|
|
|
|
client.api.disconnect.assert_called_once() |