Files
thechart/tests/test_data_manager.py
William Valentin d7d4b332d4 Add medicine management functionality with UI and data handling
- Implemented MedicineManagementWindow for adding, editing, and removing medicines.
- Created MedicineManager to handle medicine configurations, including loading and saving to JSON.
- Updated UIManager to dynamically generate medicine-related UI components based on the MedicineManager.
- Enhanced test suite with mock objects for MedicineManager to ensure proper functionality in DataManager tests.
- Added validation for medicine input fields in the UI.
- Introduced default medicine configurations for initial setup.
2025-07-30 16:01:02 -07:00

304 lines
13 KiB
Python

"""
Tests for the DataManager class.
"""
import os
import csv
from unittest.mock import patch
import sys
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
from src.data_manager import DataManager
class TestDataManager:
"""Test cases for the DataManager class."""
def test_init(self, temp_csv_file, mock_logger, mock_medicine_manager):
"""Test DataManager initialization."""
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
assert dm.filename == temp_csv_file
assert dm.logger == mock_logger
assert dm.medicine_manager == mock_medicine_manager
assert os.path.exists(temp_csv_file)
def test_initialize_csv_creates_file_with_headers(self, temp_csv_file, mock_logger, mock_medicine_manager):
"""Test that initialize_csv creates a file with proper headers."""
# Remove the file if it exists
if os.path.exists(temp_csv_file):
os.unlink(temp_csv_file)
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
# Check file exists and has correct headers
assert os.path.exists(temp_csv_file)
with open(temp_csv_file, 'r') as f:
reader = csv.reader(f)
headers = next(reader)
expected_headers = [
"date", "depression", "anxiety", "sleep", "appetite",
"bupropion", "bupropion_doses", "hydroxyzine", "hydroxyzine_doses",
"gabapentin", "gabapentin_doses", "propranolol", "propranolol_doses",
"quetiapine", "quetiapine_doses", "note"
]
assert headers == expected_headers
def test_initialize_csv_does_not_overwrite_existing_file(self, temp_csv_file, mock_logger, mock_medicine_manager):
"""Test that initialize_csv does not overwrite existing file."""
# Write some data to the file first
with open(temp_csv_file, 'w') as f:
f.write("existing,data\n1,2\n")
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
# Check that existing data is preserved
with open(temp_csv_file, 'r') as f:
content = f.read()
assert "existing,data" in content
def test_load_data_empty_file(self, temp_csv_file, mock_logger, mock_medicine_manager):
"""Test loading data from an empty file."""
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
df = dm.load_data()
assert df.empty
def test_load_data_nonexistent_file(self, mock_logger, mock_medicine_manager):
"""Test loading data from a nonexistent file."""
dm = DataManager("nonexistent.csv", mock_logger, mock_medicine_manager)
df = dm.load_data()
assert df.empty
mock_logger.warning.assert_called()
def test_load_data_with_valid_data(self, temp_csv_file, mock_logger, mock_medicine_manager, sample_data):
"""Test loading valid data from CSV file."""
# Write sample data to file
with open(temp_csv_file, 'w', newline='') as f:
writer = csv.writer(f)
# Write headers first
writer.writerow([
"date", "depression", "anxiety", "sleep", "appetite",
"bupropion", "bupropion_doses", "hydroxyzine", "hydroxyzine_doses",
"gabapentin", "gabapentin_doses", "propranolol", "propranolol_doses",
"quetiapine", "quetiapine_doses", "note"
])
# Write sample data
writer.writerows(sample_data)
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
df = dm.load_data()
assert not df.empty
assert len(df) == 3
assert list(df.columns) == [
"date", "depression", "anxiety", "sleep", "appetite",
"bupropion", "bupropion_doses", "hydroxyzine", "hydroxyzine_doses",
"gabapentin", "gabapentin_doses", "propranolol", "propranolol_doses",
"quetiapine", "quetiapine_doses", "note"
]
# Check data types
assert df["depression"].dtype == int
assert df["anxiety"].dtype == int
assert df["note"].dtype == object
def test_load_data_sorted_by_date(self, temp_csv_file, mock_logger, mock_medicine_manager):
"""Test that loaded data is sorted by date."""
# Write data in random order
unsorted_data = [
["2024-01-03", 1, 1, 1, 1, 1, "", 1, "", 1, "", 1, "", 0, "", "third"],
["2024-01-01", 2, 2, 2, 2, 2, "", 2, "", 2, "", 2, "", 1, "", "first"],
["2024-01-02", 3, 3, 3, 3, 3, "", 3, "", 3, "", 3, "", 0, "", "second"],
]
with open(temp_csv_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow([
"date", "depression", "anxiety", "sleep", "appetite",
"bupropion", "bupropion_doses", "hydroxyzine", "hydroxyzine_doses",
"gabapentin", "gabapentin_doses", "propranolol", "propranolol_doses",
"quetiapine", "quetiapine_doses", "note"
])
writer.writerows(unsorted_data)
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
df = dm.load_data()
# Check that data is sorted by date
assert df.iloc[0]["note"] == "first"
assert df.iloc[1]["note"] == "second"
assert df.iloc[2]["note"] == "third"
def test_add_entry_success(self, temp_csv_file, mock_logger, mock_medicine_manager):
"""Test successfully adding an entry."""
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
entry = ["2024-01-01", 3, 2, 4, 3, 1, 0, 2, 1, "Test note"]
result = dm.add_entry(entry)
assert result is True
# Verify entry was added
df = dm.load_data()
assert len(df) == 1
assert df.iloc[0]["date"] == "2024-01-01"
assert df.iloc[0]["note"] == "Test note"
def test_add_entry_duplicate_date(self, temp_csv_file, mock_logger, mock_medicine_manager, sample_data):
"""Test adding entry with duplicate date."""
# Add initial data
with open(temp_csv_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow([
"date", "depression", "anxiety", "sleep", "appetite",
"bupropion", "bupropion_doses", "hydroxyzine", "hydroxyzine_doses",
"gabapentin", "gabapentin_doses", "propranolol", "propranolol_doses",
"quetiapine", "quetiapine_doses", "note"
])
writer.writerows(sample_data)
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
# Try to add entry with existing date
duplicate_entry = ["2024-01-01", 5, 5, 5, 5, 1, "", 1, "", 1, "", 1, "", 0, "", "Duplicate"]
result = dm.add_entry(duplicate_entry)
assert result is False
mock_logger.warning.assert_called_with("Entry with date 2024-01-01 already exists.")
def test_update_entry_success(self, temp_csv_file, mock_logger, mock_medicine_manager, sample_data):
"""Test successfully updating an entry."""
# Add initial data
with open(temp_csv_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow([
"date", "depression", "anxiety", "sleep", "appetite",
"bupropion", "bupropion_doses", "hydroxyzine", "hydroxyzine_doses",
"gabapentin", "gabapentin_doses", "propranolol", "propranolol_doses",
"quetiapine", "quetiapine_doses", "note"
])
writer.writerows(sample_data)
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
updated_values = ["2024-01-01", 5, 5, 5, 5, 2, "", 2, "", 2, "", 2, "", 1, "", "Updated note"]
result = dm.update_entry("2024-01-01", updated_values)
assert result is True
# Verify entry was updated
df = dm.load_data()
updated_row = df[df["date"] == "2024-01-01"].iloc[0]
assert updated_row["depression"] == 5
assert updated_row["note"] == "Updated note"
def test_update_entry_change_date(self, temp_csv_file, mock_logger, mock_medicine_manager, sample_data):
"""Test updating an entry with a date change."""
# Add initial data
with open(temp_csv_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow([
"date", "depression", "anxiety", "sleep", "appetite",
"bupropion", "bupropion_doses", "hydroxyzine", "hydroxyzine_doses",
"gabapentin", "gabapentin_doses", "propranolol", "propranolol_doses",
"quetiapine", "quetiapine_doses", "note"
])
writer.writerows(sample_data)
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
updated_values = ["2024-01-05", 5, 5, 5, 5, 2, "", 2, "", 2, "", 2, "", 1, "", "Updated note"]
result = dm.update_entry("2024-01-01", updated_values)
assert result is True
# Verify old date is gone and new date exists
df = dm.load_data()
assert not any(df["date"] == "2024-01-01")
assert any(df["date"] == "2024-01-05")
def test_update_entry_duplicate_date(self, temp_csv_file, mock_logger, mock_medicine_manager, sample_data):
"""Test updating entry to a date that already exists."""
# Add initial data
with open(temp_csv_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow([
"date", "depression", "anxiety", "sleep", "appetite",
"bupropion", "bupropion_doses", "hydroxyzine", "hydroxyzine_doses",
"gabapentin", "gabapentin_doses", "propranolol", "propranolol_doses",
"quetiapine", "quetiapine_doses", "note"
])
writer.writerows(sample_data)
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
# Try to change date to one that already exists
updated_values = ["2024-01-02", 5, 5, 5, 5, 2, "", 2, "", 2, "", 2, "", 1, "", "Updated note"]
result = dm.update_entry("2024-01-01", updated_values)
assert result is False
mock_logger.warning.assert_called_with(
"Cannot update: entry with date 2024-01-02 already exists."
)
def test_delete_entry_success(self, temp_csv_file, mock_logger, mock_medicine_manager, sample_data):
"""Test successfully deleting an entry."""
# Add initial data
with open(temp_csv_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow([
"date", "depression", "anxiety", "sleep", "appetite",
"bupropion", "bupropion_doses", "hydroxyzine", "hydroxyzine_doses",
"gabapentin", "gabapentin_doses", "propranolol", "propranolol_doses",
"quetiapine", "quetiapine_doses", "note"
])
writer.writerows(sample_data)
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
result = dm.delete_entry("2024-01-02")
assert result is True
# Verify entry was deleted
df = dm.load_data()
assert len(df) == 2
assert not any(df["date"] == "2024-01-02")
def test_delete_entry_nonexistent(self, temp_csv_file, mock_logger, mock_medicine_manager, sample_data):
"""Test deleting a nonexistent entry."""
# Add initial data
with open(temp_csv_file, 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow([
"date", "depression", "anxiety", "sleep", "appetite",
"bupropion", "bupropion_doses", "hydroxyzine", "hydroxyzine_doses",
"gabapentin", "gabapentin_doses", "propranolol", "propranolol_doses",
"quetiapine", "quetiapine_doses", "note"
])
writer.writerows(sample_data)
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
result = dm.delete_entry("2024-01-10")
assert result is True # Should return True even if no matching entry
# Verify no data was lost
df = dm.load_data()
assert len(df) == 3
@patch('pandas.read_csv')
def test_load_data_exception_handling(self, mock_read_csv, temp_csv_file, mock_logger, mock_medicine_manager):
"""Test exception handling in load_data."""
mock_read_csv.side_effect = Exception("Test error")
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
df = dm.load_data()
assert df.empty
mock_logger.error.assert_called_with("Error loading data: Test error")
@patch('builtins.open')
def test_add_entry_exception_handling(self, mock_open, temp_csv_file, mock_logger, mock_medicine_manager):
"""Test exception handling in add_entry."""
mock_open.side_effect = Exception("Test error")
dm = DataManager(temp_csv_file, mock_logger, mock_medicine_manager)
entry = ["2024-01-01", 3, 2, 4, 3, 1, 0, 2, 1, "Test note"]
result = dm.add_entry(entry)
assert result is False
mock_logger.error.assert_called_with("Error adding entry: Test error")