306 lines
12 KiB
Python
306 lines
12 KiB
Python
"""
|
|
Tests for the DataManager class.
|
|
"""
|
|
import os
|
|
import csv
|
|
import pytest
|
|
import pandas as pd
|
|
from unittest.mock import Mock, patch
|
|
import tempfile
|
|
|
|
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):
|
|
"""Test DataManager initialization."""
|
|
dm = DataManager(temp_csv_file, mock_logger)
|
|
assert dm.filename == temp_csv_file
|
|
assert dm.logger == mock_logger
|
|
assert os.path.exists(temp_csv_file)
|
|
|
|
def test_initialize_csv_creates_file_with_headers(self, temp_csv_file, mock_logger):
|
|
"""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)
|
|
|
|
# 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):
|
|
"""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)
|
|
|
|
# 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):
|
|
"""Test loading data from an empty file."""
|
|
dm = DataManager(temp_csv_file, mock_logger)
|
|
df = dm.load_data()
|
|
assert df.empty
|
|
|
|
def test_load_data_nonexistent_file(self, mock_logger):
|
|
"""Test loading data from a nonexistent file."""
|
|
dm = DataManager("nonexistent.csv", mock_logger)
|
|
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, 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)
|
|
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):
|
|
"""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)
|
|
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):
|
|
"""Test successfully adding an entry."""
|
|
dm = DataManager(temp_csv_file, mock_logger)
|
|
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, 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)
|
|
# 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, 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)
|
|
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, 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)
|
|
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, 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)
|
|
# 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, 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)
|
|
|
|
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, 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)
|
|
|
|
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):
|
|
"""Test exception handling in load_data."""
|
|
mock_read_csv.side_effect = Exception("Test error")
|
|
|
|
dm = DataManager(temp_csv_file, mock_logger)
|
|
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):
|
|
"""Test exception handling in add_entry."""
|
|
mock_open.side_effect = Exception("Test error")
|
|
|
|
dm = DataManager(temp_csv_file, mock_logger)
|
|
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")
|