Implement date uniqueness validation in DataManager and update MedTrackerApp for duplicate checks

This commit is contained in:
William Valentin
2025-07-28 17:28:00 -07:00
parent f0dd47d433
commit 9aa1188c98
3 changed files with 144 additions and 8 deletions

View File

@@ -0,0 +1,91 @@
#!/usr/bin/env python3
"""
Test script to verify date uniqueness functionality in TheChart app.
"""
import logging
import os
import sys
# Add the src directory to the Python path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src"))
from data_manager import DataManager
# Set up simple logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("test")
def test_date_uniqueness():
"""Test the date uniqueness validation."""
print("Testing date uniqueness functionality...")
# Create a test data manager with a test file
test_filename = "test_data.csv"
dm = DataManager(test_filename, logger)
# Test 1: Add first entry (should succeed)
print("\n1. Adding first entry...")
entry1 = ["2025-07-28", 5, 5, 5, 5, 0, 0, 0, 0, "First entry"]
result1 = dm.add_entry(entry1)
print(f"Result: {result1} (Expected: True)")
# Test 2: Try to add duplicate date (should fail)
print("\n2. Trying to add duplicate date...")
entry2 = ["2025-07-28", 3, 3, 3, 3, 1, 1, 1, 1, "Duplicate entry"]
result2 = dm.add_entry(entry2)
print(f"Result: {result2} (Expected: False)")
# Test 3: Add different date (should succeed)
print("\n3. Adding different date...")
entry3 = ["2025-07-29", 4, 4, 4, 4, 0, 0, 0, 0, "Second entry"]
result3 = dm.add_entry(entry3)
print(f"Result: {result3} (Expected: True)")
# Test 4: Update entry with same date (should succeed)
print("\n4. Updating entry with same date...")
updated_entry = ["2025-07-28", 6, 6, 6, 6, 1, 1, 1, 1, "Updated entry"]
result4 = dm.update_entry("2025-07-28", updated_entry)
print(f"Result: {result4} (Expected: True)")
# Test 5: Try to update entry to existing date (should fail)
print("\n5. Trying to update entry to existing date...")
conflicting_entry = ["2025-07-29", 7, 7, 7, 7, 1, 1, 1, 1, "Conflicting entry"]
result5 = dm.update_entry("2025-07-28", conflicting_entry)
print(f"Result: {result5} (Expected: False)")
# Test 6: Update entry to new date (should succeed)
print("\n6. Updating entry to new date...")
new_date_entry = ["2025-07-30", 8, 8, 8, 8, 1, 1, 1, 1, "New date entry"]
result6 = dm.update_entry("2025-07-28", new_date_entry)
print(f"Result: {result6} (Expected: True)")
# Cleanup
if os.path.exists(test_filename):
os.remove(test_filename)
# Summary
expected_results = [True, False, True, True, False, True]
actual_results = [result1, result2, result3, result4, result5, result6]
print("\n" + "=" * 50)
print("TEST SUMMARY:")
print("=" * 50)
all_passed = True
for i, (expected, actual) in enumerate(
zip(expected_results, actual_results, strict=True), 1
):
status = "PASS" if expected == actual else "FAIL"
if expected != actual:
all_passed = False
print(f"Test {i}: {status} (Expected: {expected}, Got: {actual})")
overall_result = "ALL TESTS PASSED" if all_passed else "SOME TESTS FAILED"
print(f"\nOverall result: {overall_result}")
return all_passed
if __name__ == "__main__":
test_date_uniqueness()

View File

@@ -66,6 +66,14 @@ class DataManager:
def add_entry(self, entry_data: list[str | int]) -> bool: def add_entry(self, entry_data: list[str | int]) -> bool:
"""Add a new entry to the CSV file.""" """Add a new entry to the CSV file."""
try: try:
# Check if date already exists
df: pd.DataFrame = self.load_data()
date_to_add: str = str(entry_data[0])
if not df.empty and date_to_add in df["date"].values:
self.logger.warning(f"Entry with date {date_to_add} already exists.")
return False
with open(self.filename, mode="a", newline="") as file: with open(self.filename, mode="a", newline="") as file:
writer = csv.writer(file) writer = csv.writer(file)
writer.writerow(entry_data) writer.writerow(entry_data)
@@ -74,13 +82,22 @@ class DataManager:
self.logger.error(f"Error adding entry: {str(e)}") self.logger.error(f"Error adding entry: {str(e)}")
return False return False
def update_entry(self, date: str, values: list[str | int]) -> bool: def update_entry(self, original_date: str, values: list[str | int]) -> bool:
"""Update an existing entry identified by date.""" """Update an existing entry identified by original_date."""
try: try:
df: pd.DataFrame = self.load_data() df: pd.DataFrame = self.load_data()
# Find the row to update using date as a unique identifier new_date: str = str(values[0])
# If the date is being changed, check if the new date already exists
if original_date != new_date and new_date in df["date"].values:
self.logger.warning(
f"Cannot update: entry with date {new_date} already exists."
)
return False
# Find the row to update using original_date as a unique identifier
df.loc[ df.loc[
df["date"] == date, df["date"] == original_date,
[ [
"date", "date",
"depression", "depression",

View File

@@ -119,9 +119,11 @@ class MedTrackerApp:
def _create_edit_window(self, item_id: str, values: tuple[str, ...]) -> None: def _create_edit_window(self, item_id: str, values: tuple[str, ...]) -> None:
"""Create a new Toplevel window for editing an entry.""" """Create a new Toplevel window for editing an entry."""
original_date = values[0] # Store the original date
# Define callbacks for edit window buttons # Define callbacks for edit window buttons
callbacks: dict[str, Callable] = { callbacks: dict[str, Callable] = {
"save": self._save_edit, "save": lambda win, *args: self._save_edit(win, original_date, *args),
"delete": lambda win: self._delete_entry(win, item_id), "delete": lambda win: self._delete_entry(win, item_id),
} }
@@ -131,6 +133,7 @@ class MedTrackerApp:
def _save_edit( def _save_edit(
self, self,
edit_win: tk.Toplevel, edit_win: tk.Toplevel,
original_date: str,
date: str, date: str,
dep: int, dep: int,
anx: int, anx: int,
@@ -156,13 +159,23 @@ class MedTrackerApp:
note, note,
] ]
if self.data_manager.update_entry(date, values): if self.data_manager.update_entry(original_date, values):
edit_win.destroy() edit_win.destroy()
messagebox.showinfo( messagebox.showinfo(
"Success", "Entry updated successfully!", parent=self.root "Success", "Entry updated successfully!", parent=self.root
) )
self._clear_entries() self._clear_entries()
self.load_data() self.load_data()
else:
# Check if it's a duplicate date issue
df = self.data_manager.load_data()
if original_date != date and not df.empty and date in df["date"].values:
messagebox.showerror(
"Error",
f"An entry for date '{date}' already exists. "
"Please use a different date.",
parent=edit_win,
)
else: else:
messagebox.showerror("Error", "Failed to save changes", parent=edit_win) messagebox.showerror("Error", "Failed to save changes", parent=edit_win)
@@ -189,12 +202,27 @@ class MedTrackerApp:
] ]
logger.debug(f"Adding entry: {entry}") logger.debug(f"Adding entry: {entry}")
# Check if date is empty
if not self.date_var.get().strip():
messagebox.showerror("Error", "Please enter a date.", parent=self.root)
return
if self.data_manager.add_entry(entry): if self.data_manager.add_entry(entry):
messagebox.showinfo( messagebox.showinfo(
"Success", "Entry added successfully!", parent=self.root "Success", "Entry added successfully!", parent=self.root
) )
self._clear_entries() self._clear_entries()
self.load_data() self.load_data()
else:
# Check if it's a duplicate date by trying to load existing data
df = self.data_manager.load_data()
if not df.empty and self.date_var.get() in df["date"].values:
messagebox.showerror(
"Error",
f"An entry for date '{self.date_var.get()}' already exists. "
"Please use a different date or edit the existing entry.",
parent=self.root,
)
else: else:
messagebox.showerror("Error", "Failed to add entry", parent=self.root) messagebox.showerror("Error", "Failed to add entry", parent=self.root)