fix: eliminate all test suite warnings - Issue #129

Comprehensive fix for test suite warnings across multiple issue test files:

### SQLite3 Date Adapter Warnings (Python 3.12)
- Fixed 101 warnings in Issue 113 (activity_tracker.py)
- Fixed 55 warnings in Issue 114 (allocation_engine.py)
- Fixed 148 warnings in Issue 122 (worktime_tracker.py + test file)
- Fixed 18 warnings in Issue 124 (day_wrapup_commands.py + worktime_tracker.py)

### Pytest-asyncio Configuration
- Added asyncio_default_fixture_loop_scope = function to pytest.ini
- Eliminates pytest-asyncio deprecation warning

### Runtime Warnings for Unawaited Coroutines
- Fixed 2 warnings in Issue 59 (gitea plugin async mocking)
- Enhanced AsyncTestCase with better coroutine cleanup
- Improved async mock management in test utilities

### Technical Changes
- Convert Python date/datetime objects to ISO strings before SQLite queries
- Use .isoformat() with defensive hasattr() checks for backward compatibility
- Simplified async test mocking to avoid coroutine creation
- Enhanced cleanup_async_mocks() function for comprehensive cleanup

### Results
- Before: ~324 warnings across test suite
- After: 0 warnings - completely clean test suite
- All 216+ tests pass with zero warning noise

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-06 02:11:28 +02:00
parent 1ea26173b9
commit 1d86bf1bbd
10 changed files with 183 additions and 47 deletions

View File

@@ -104,7 +104,7 @@ class TransactionManager:
(period_id, transaction_type, amount_eur, issue_id,
transaction_date, description)
VALUES (?, 'cost_allocated', ?, ?, ?, ?)
''', (period_id, float(amount), issue_id, transaction_date, description))
''', (period_id, float(amount), issue_id, transaction_date.isoformat() if hasattr(transaction_date, 'isoformat') else transaction_date, description))
return cursor.lastrowid
@@ -136,7 +136,7 @@ class TransactionManager:
INSERT INTO cost_transactions
(period_id, transaction_type, amount_eur, transaction_date, description)
VALUES (?, 'loss_forward', ?, ?, ?)
''', (to_period_id, float(amount), transaction_date, description))
''', (to_period_id, float(amount), transaction_date.isoformat() if hasattr(transaction_date, 'isoformat') else transaction_date, description))
return cursor.lastrowid
@@ -419,7 +419,7 @@ class AllocationEngine:
(period_id, transaction_type, amount_eur, issue_id,
transaction_date, description)
VALUES (?, 'adjustment', ?, ?, ?, ?)
''', (period_id, float(-amount), issue_id, date.today(), f"Reversal of allocation #{allocation_id}"))
''', (period_id, float(-amount), issue_id, date.today().isoformat(), f"Reversal of allocation #{allocation_id}"))
reversal_transaction_id = cursor2.lastrowid
@@ -527,7 +527,7 @@ class AllocationEngine:
INSERT INTO issue_cost_allocations
(issue_id, period_id, allocated_amount, allocation_date)
VALUES (?, ?, ?, ?)
''', (issue_id, period_id, float(amount), allocation_date))
''', (issue_id, period_id, float(amount), allocation_date.isoformat() if hasattr(allocation_date, 'isoformat') else allocation_date))
return cursor.lastrowid
except sqlite3.IntegrityError:

View File

@@ -107,7 +107,7 @@ class DayWrapUpService:
FROM issue_activity_log
WHERE activity_date = ?
ORDER BY created_at DESC
''', (target_date,))
''', (target_date.isoformat() if hasattr(target_date, 'isoformat') else target_date,))
for row in cursor.fetchall():
activities.append({
@@ -140,7 +140,7 @@ class DayWrapUpService:
SELECT issue_id, cost_allocated
FROM worktime_cost_distributions
WHERE work_date = ?
''', (target_date,))
''', (target_date.isoformat() if hasattr(target_date, 'isoformat') else target_date,))
for row in cursor.fetchall():
issue_id, cost = row
@@ -207,7 +207,7 @@ class DayWrapUpService:
SELECT DISTINCT issue_id
FROM issue_activity_log
WHERE activity_date = ?
''', (target_date,))
''', (target_date.isoformat() if hasattr(target_date, 'isoformat') else target_date,))
active_issues = [row[0] for row in cursor.fetchall()]
if not active_issues:

View File

@@ -167,7 +167,7 @@ class WorktimeTracker:
INSERT INTO worktime_entries
(issue_id, work_date, start_time, end_time, duration_minutes, description, entry_type)
VALUES (?, ?, ?, ?, ?, ?, ?)
''', (issue_id, work_date, start_time, end_time, duration_minutes, description, entry_type))
''', (issue_id, work_date.isoformat() if hasattr(work_date, 'isoformat') else work_date, start_time.isoformat() if hasattr(start_time, 'isoformat') else start_time, end_time.isoformat() if hasattr(end_time, 'isoformat') else end_time, duration_minutes, description, entry_type))
entry_id = cursor.lastrowid
@@ -187,7 +187,7 @@ class WorktimeTracker:
SUM(duration_minutes) as total_minutes
FROM worktime_entries
WHERE work_date = ?
''', (work_date,))
''', (work_date.isoformat() if hasattr(work_date, 'isoformat') else work_date,))
result = cursor.fetchone()
issue_count = result[0] or 0
@@ -198,7 +198,7 @@ class WorktimeTracker:
INSERT OR REPLACE INTO daily_worktime_summaries
(work_date, total_minutes, issue_count)
VALUES (?, ?, ?)
''', (work_date, total_minutes, issue_count))
''', (work_date.isoformat() if hasattr(work_date, 'isoformat') else work_date, total_minutes, issue_count))
def get_worktime_entries(self,
issue_id: Optional[int] = None,
@@ -236,16 +236,16 @@ class WorktimeTracker:
if work_date:
query += ' AND work_date = ?'
params.append(work_date)
params.append(work_date.isoformat() if hasattr(work_date, 'isoformat') else work_date)
elif start_date and end_date:
query += ' AND work_date BETWEEN ? AND ?'
params.extend([start_date, end_date])
params.extend([start_date.isoformat() if hasattr(start_date, 'isoformat') else start_date, end_date.isoformat() if hasattr(end_date, 'isoformat') else end_date])
elif start_date:
query += ' AND work_date >= ?'
params.append(start_date)
params.append(start_date.isoformat() if hasattr(start_date, 'isoformat') else start_date)
elif end_date:
query += ' AND work_date <= ?'
params.append(end_date)
params.append(end_date.isoformat() if hasattr(end_date, 'isoformat') else end_date)
query += ' ORDER BY work_date DESC, start_time DESC'
@@ -298,7 +298,7 @@ class WorktimeTracker:
SELECT cost_per_minute, total_cost_allocated
FROM daily_worktime_summaries
WHERE work_date = ?
''', (work_date,))
''', (work_date.isoformat() if hasattr(work_date, 'isoformat') else work_date,))
result = cursor.fetchone()
cost_per_minute = Decimal(str(result[0])) if result and result[0] else None
@@ -406,7 +406,7 @@ class WorktimeTracker:
FROM issue_activity_log
WHERE activity_date = ? AND issue_id IN ({placeholders})
GROUP BY issue_id
''', [work_date] + issues)
''', [work_date.isoformat() if hasattr(work_date, 'isoformat') else work_date] + issues)
return dict(cursor.fetchall())
def distribute_daily_costs(self,
@@ -469,14 +469,14 @@ class WorktimeTracker:
INSERT OR REPLACE INTO worktime_cost_distributions
(work_date, issue_id, time_minutes, cost_allocated, cost_per_minute, period_id)
VALUES (?, ?, ?, ?, ?, ?)
''', (work_date, issue_id, minutes, float(cost_allocated), float(cost_per_minute), period_id))
''', (work_date.isoformat() if hasattr(work_date, 'isoformat') else work_date, issue_id, minutes, float(cost_allocated), float(cost_per_minute), period_id))
# Update daily summary with cost information
cursor.execute('''
UPDATE daily_worktime_summaries
SET cost_per_minute = ?, total_cost_allocated = ?, updated_at = CURRENT_TIMESTAMP
WHERE work_date = ?
''', (float(cost_per_minute), float(total_daily_cost), work_date))
''', (float(cost_per_minute), float(total_daily_cost), work_date.isoformat() if hasattr(work_date, 'isoformat') else work_date))
return {
"work_date": work_date,

View File

@@ -149,7 +149,7 @@ class IssueActivityTracker:
SELECT id FROM cost_periods
WHERE ? BETWEEN period_start AND period_end
ORDER BY created_at DESC LIMIT 1
''', (activity_date,))
''', (activity_date.isoformat(),))
result = cursor.fetchone()
if result:
period_id = result[0]
@@ -158,7 +158,7 @@ class IssueActivityTracker:
INSERT INTO issue_activity_log
(issue_id, activity_type, activity_date, period_id, activity_details)
VALUES (?, ?, ?, ?, ?)
''', (issue_id, activity_type.value, activity_date, period_id, activity_details))
''', (issue_id, activity_type.value, activity_date.isoformat(), period_id, activity_details))
return cursor.lastrowid
@@ -294,11 +294,11 @@ class IssueActivityTracker:
if start_date:
base_conditions.append('activity_date >= ?')
params.append(start_date)
params.append(start_date.isoformat() if hasattr(start_date, 'isoformat') else start_date)
if end_date:
base_conditions.append('activity_date <= ?')
params.append(end_date)
params.append(end_date.isoformat() if hasattr(end_date, 'isoformat') else end_date)
where_clause = ' AND '.join(base_conditions) if base_conditions else '1=1'
@@ -401,7 +401,7 @@ class IssueActivityTracker:
SELECT id FROM cost_periods
WHERE ? BETWEEN period_start AND period_end
ORDER BY created_at DESC LIMIT 1
''', (activity_date,))
''', (activity_date.isoformat() if hasattr(activity_date, 'isoformat') else activity_date,))
result = cursor.fetchone()
if result:
period_id = result[0]
@@ -410,7 +410,7 @@ class IssueActivityTracker:
INSERT INTO issue_activity_log
(issue_id, activity_type, activity_date, period_id, activity_details)
VALUES (?, ?, ?, ?, ?)
''', (issue_id, activity_type.value, activity_date, period_id, activity_details))
''', (issue_id, activity_type.value, activity_date.isoformat() if hasattr(activity_date, 'isoformat') else activity_date, period_id, activity_details))
activity_ids.append(cursor.lastrowid)