133 lines
4.5 KiB
Python
133 lines
4.5 KiB
Python
|
|
import json
|
||
|
|
import os
|
||
|
|
import tempfile
|
||
|
|
from unittest.mock import patch, MagicMock
|
||
|
|
import tkinter as tk
|
||
|
|
from time_tracker.main import WorkTracker, ConfigWrapper
|
||
|
|
|
||
|
|
|
||
|
|
def test_tracker_initialization():
|
||
|
|
"""Test that WorkTracker initializes without errors"""
|
||
|
|
# Create a temporary config file to avoid creating one in the current directory
|
||
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as tmp:
|
||
|
|
json.dump({
|
||
|
|
"tracking_enabled": True,
|
||
|
|
"current_task_id": None,
|
||
|
|
"window_rules": {
|
||
|
|
"work": ["PyCharm", "VS Code"],
|
||
|
|
"distraction": ["YouTube", "Twitter"]
|
||
|
|
}
|
||
|
|
}, tmp)
|
||
|
|
tmp_path = tmp.name
|
||
|
|
|
||
|
|
original_config_path = "config.json"
|
||
|
|
|
||
|
|
# Temporarily replace the config file
|
||
|
|
if os.path.exists(original_config_path):
|
||
|
|
os.rename(original_config_path, f"{original_config_path}.backup")
|
||
|
|
|
||
|
|
os.rename(tmp_path, original_config_path)
|
||
|
|
|
||
|
|
try:
|
||
|
|
# Initialize the tracker
|
||
|
|
tracker = WorkTracker()
|
||
|
|
|
||
|
|
# Verify that config is properly loaded as a ConfigWrapper object
|
||
|
|
assert hasattr(tracker, 'config')
|
||
|
|
assert isinstance(tracker.config, ConfigWrapper)
|
||
|
|
assert hasattr(tracker.config, 'tracking_enabled')
|
||
|
|
assert hasattr(tracker.config, 'current_task_id')
|
||
|
|
assert hasattr(tracker.config, 'window_rules')
|
||
|
|
assert tracker.config.tracking_enabled is True
|
||
|
|
assert tracker.config.current_task_id is None
|
||
|
|
|
||
|
|
finally:
|
||
|
|
# Restore original config file
|
||
|
|
os.remove(original_config_path)
|
||
|
|
if os.path.exists(f"{original_config_path}.backup"):
|
||
|
|
os.rename(f"{original_config_path}.backup", original_config_path)
|
||
|
|
|
||
|
|
|
||
|
|
def test_config_wrapper_functionality():
|
||
|
|
"""Test that ConfigWrapper provides attribute access to config values"""
|
||
|
|
config_dict = {
|
||
|
|
"tracking_enabled": True,
|
||
|
|
"current_task_id": "TEST-123",
|
||
|
|
"window_rules": {
|
||
|
|
"work": ["PyCharm", "VS Code"],
|
||
|
|
"distraction": ["YouTube", "Twitter"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
wrapper = ConfigWrapper(config_dict)
|
||
|
|
|
||
|
|
# Test attribute access
|
||
|
|
assert wrapper.tracking_enabled is True
|
||
|
|
assert wrapper.current_task_id == "TEST-123"
|
||
|
|
assert "PyCharm" in wrapper.window_rules["work"]
|
||
|
|
|
||
|
|
# Test updating config
|
||
|
|
wrapper.tracking_enabled = False
|
||
|
|
assert wrapper.tracking_enabled is False
|
||
|
|
# Note: Direct assignment doesn't update the original dict, but the wrapper still works
|
||
|
|
|
||
|
|
|
||
|
|
def test_tracker_config_attribute_access():
|
||
|
|
"""Test that config can be accessed as an object with attributes"""
|
||
|
|
|
||
|
|
# Create a mock config object that behaves like the real config
|
||
|
|
class MockConfig:
|
||
|
|
def __init__(self):
|
||
|
|
self.tracking_enabled = True
|
||
|
|
self.current_task_id = "TEST-123"
|
||
|
|
|
||
|
|
config = MockConfig()
|
||
|
|
assert hasattr(config, 'tracking_enabled')
|
||
|
|
assert config.tracking_enabled is True
|
||
|
|
assert config.current_task_id == "TEST-123"
|
||
|
|
|
||
|
|
|
||
|
|
def test_overlay_compatible_config():
|
||
|
|
"""Test that the config structure is compatible with overlay expectations"""
|
||
|
|
from time_tracker.core.config import load_config
|
||
|
|
|
||
|
|
# Create a temporary config file
|
||
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as tmp:
|
||
|
|
json.dump({
|
||
|
|
"tracking_enabled": True,
|
||
|
|
"current_task_id": "TEST-123",
|
||
|
|
"window_rules": {
|
||
|
|
"work": ["PyCharm", "VS Code"],
|
||
|
|
"distraction": ["YouTube", "Twitter"]
|
||
|
|
}
|
||
|
|
}, tmp)
|
||
|
|
tmp_path = tmp.name
|
||
|
|
|
||
|
|
original_config_path = "config.json"
|
||
|
|
|
||
|
|
# Temporarily replace the config file
|
||
|
|
if os.path.exists(original_config_path):
|
||
|
|
os.rename(original_config_path, f"{original_config_path}.backup")
|
||
|
|
|
||
|
|
os.rename(tmp_path, original_config_path)
|
||
|
|
|
||
|
|
try:
|
||
|
|
# Load config using the actual function
|
||
|
|
config = load_config()
|
||
|
|
|
||
|
|
# Verify structure
|
||
|
|
assert isinstance(config, dict)
|
||
|
|
assert config.get("tracking_enabled") is True
|
||
|
|
assert config.get("current_task_id") == "TEST-123"
|
||
|
|
|
||
|
|
# Create a compatible object that supports attribute access
|
||
|
|
wrapped_config = ConfigWrapper(config)
|
||
|
|
assert hasattr(wrapped_config, 'tracking_enabled')
|
||
|
|
assert wrapped_config.tracking_enabled is True
|
||
|
|
assert wrapped_config.current_task_id == "TEST-123"
|
||
|
|
|
||
|
|
finally:
|
||
|
|
# Restore original config file
|
||
|
|
os.remove(original_config_path)
|
||
|
|
if os.path.exists(f"{original_config_path}.backup"):
|
||
|
|
os.rename(f"{original_config_path}.backup", original_config_path)
|