Implement date uniqueness validation in DataManager and update MedTrackerApp for duplicate checks
This commit is contained in:
91
scripts/test_date_uniqueness.py
Normal file
91
scripts/test_date_uniqueness.py
Normal 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()
|
||||
@@ -66,6 +66,14 @@ class DataManager:
|
||||
def add_entry(self, entry_data: list[str | int]) -> bool:
|
||||
"""Add a new entry to the CSV file."""
|
||||
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:
|
||||
writer = csv.writer(file)
|
||||
writer.writerow(entry_data)
|
||||
@@ -74,13 +82,22 @@ class DataManager:
|
||||
self.logger.error(f"Error adding entry: {str(e)}")
|
||||
return False
|
||||
|
||||
def update_entry(self, date: str, values: list[str | int]) -> bool:
|
||||
"""Update an existing entry identified by date."""
|
||||
def update_entry(self, original_date: str, values: list[str | int]) -> bool:
|
||||
"""Update an existing entry identified by original_date."""
|
||||
try:
|
||||
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["date"] == date,
|
||||
df["date"] == original_date,
|
||||
[
|
||||
"date",
|
||||
"depression",
|
||||
|
||||
32
src/main.py
32
src/main.py
@@ -119,9 +119,11 @@ class MedTrackerApp:
|
||||
|
||||
def _create_edit_window(self, item_id: str, values: tuple[str, ...]) -> None:
|
||||
"""Create a new Toplevel window for editing an entry."""
|
||||
original_date = values[0] # Store the original date
|
||||
|
||||
# Define callbacks for edit window buttons
|
||||
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),
|
||||
}
|
||||
|
||||
@@ -131,6 +133,7 @@ class MedTrackerApp:
|
||||
def _save_edit(
|
||||
self,
|
||||
edit_win: tk.Toplevel,
|
||||
original_date: str,
|
||||
date: str,
|
||||
dep: int,
|
||||
anx: int,
|
||||
@@ -156,13 +159,23 @@ class MedTrackerApp:
|
||||
note,
|
||||
]
|
||||
|
||||
if self.data_manager.update_entry(date, values):
|
||||
if self.data_manager.update_entry(original_date, values):
|
||||
edit_win.destroy()
|
||||
messagebox.showinfo(
|
||||
"Success", "Entry updated successfully!", parent=self.root
|
||||
)
|
||||
self._clear_entries()
|
||||
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:
|
||||
messagebox.showerror("Error", "Failed to save changes", parent=edit_win)
|
||||
|
||||
@@ -189,12 +202,27 @@ class MedTrackerApp:
|
||||
]
|
||||
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):
|
||||
messagebox.showinfo(
|
||||
"Success", "Entry added successfully!", parent=self.root
|
||||
)
|
||||
self._clear_entries()
|
||||
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:
|
||||
messagebox.showerror("Error", "Failed to add entry", parent=self.root)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user