basic setup
This commit is contained in:
		
							parent
							
								
									86359ec850
								
							
						
					
					
						commit
						252dbbdcce
					
				@ -20,14 +20,9 @@ def main():
 | 
				
			|||||||
    app.setApplicationVersion("0.1.0")
 | 
					    app.setApplicationVersion("0.1.0")
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    # TODO: Create and show main window
 | 
					    # TODO: Create and show main window
 | 
				
			||||||
    # from .gui.main_window import MainWindow
 | 
					 | 
				
			||||||
    # window = MainWindow()
 | 
					 | 
				
			||||||
    # window.show()
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    # For now, just exit immediately since we have no GUI yet
 | 
					    logging.info("Application started")
 | 
				
			||||||
    logging.debug("No GUI yet - exiting...")
 | 
					    sys.exit(app.exec())
 | 
				
			||||||
    return 0
 | 
					 | 
				
			||||||
    # sys.exit(app.exec())
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    sys.exit(main())
 | 
					    sys.exit(main())
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
from ..utils.config import config
 | 
					from ..utils.config import config
 | 
				
			||||||
from ..db.database import get_db_connection
 | 
					from ..db.database import get_db_connection
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
from datetime import datetime
 | 
					from datetime import datetime, timezone
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CaseManager():
 | 
					class CaseManager():
 | 
				
			||||||
    def __init__(self, db_path=None):
 | 
					    def __init__(self, db_path=None):
 | 
				
			||||||
@ -57,7 +57,7 @@ class CaseManager():
 | 
				
			|||||||
            logging.warning("No valid fields provided for update.")
 | 
					            logging.warning("No valid fields provided for update.")
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        updates['modified_at'] = datetime.utcnow().isoformat()
 | 
					        updates['modified_at'] = datetime.now(timezone.utc).isoformat()
 | 
				
			||||||
        set_clause = ", ".join([f"{k} = ?" for k in updates.keys()])
 | 
					        set_clause = ", ".join([f"{k} = ?" for k in updates.keys()])
 | 
				
			||||||
        values = list(updates.values()) + [case_id]
 | 
					        values = list(updates.values()) + [case_id]
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
@ -91,4 +91,49 @@ class CaseManager():
 | 
				
			|||||||
        # TODO: Implement import functionality
 | 
					        # TODO: Implement import functionality
 | 
				
			||||||
        # should import a .sqlite file and merge its data into the main database
 | 
					        # should import a .sqlite file and merge its data into the main database
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def create_note(self, case_id, content, investigator, question_tags=None):
 | 
				
			||||||
 | 
					        """Create a new note for a case."""
 | 
				
			||||||
 | 
					        import hashlib
 | 
				
			||||||
 | 
					        import uuid
 | 
				
			||||||
 | 
					        import json
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        note_id = str(uuid.uuid4())
 | 
				
			||||||
 | 
					        timestamp = datetime.now(timezone.utc).isoformat()
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Create hash of content + timestamp for integrity
 | 
				
			||||||
 | 
					        hash_content = f"{content}{timestamp}".encode('utf-8')
 | 
				
			||||||
 | 
					        content_hash = hashlib.sha256(hash_content).hexdigest()
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Convert tags to JSON
 | 
				
			||||||
 | 
					        tags_json = json.dumps(question_tags) if question_tags else None
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        with self.conn:
 | 
				
			||||||
 | 
					            self.cursor.execute("""
 | 
				
			||||||
 | 
					                INSERT INTO notes (note_id, case_id, timestamp, content, investigator, question_tags, hash)
 | 
				
			||||||
 | 
					                VALUES (?, ?, ?, ?, ?, ?, ?)
 | 
				
			||||||
 | 
					            """, (note_id, case_id, timestamp, content, investigator, tags_json, content_hash))
 | 
				
			||||||
 | 
					            logging.info(f"Created note {note_id} for case {case_id}")
 | 
				
			||||||
 | 
					            return note_id
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def get_notes(self, case_id):
 | 
				
			||||||
 | 
					        """Get all notes for a case, ordered by timestamp."""
 | 
				
			||||||
 | 
					        with self.conn:
 | 
				
			||||||
 | 
					            self.cursor.execute("""
 | 
				
			||||||
 | 
					                SELECT * FROM notes 
 | 
				
			||||||
 | 
					                WHERE case_id = ? 
 | 
				
			||||||
 | 
					                ORDER BY timestamp DESC
 | 
				
			||||||
 | 
					            """, (case_id,))
 | 
				
			||||||
 | 
					            return [dict(row) for row in self.cursor.fetchall()]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def get_note(self, note_id):
 | 
				
			||||||
 | 
					        """Get a specific note by ID."""
 | 
				
			||||||
 | 
					        with self.conn:
 | 
				
			||||||
 | 
					            self.cursor.execute("SELECT * FROM notes WHERE note_id = ?", (note_id,))
 | 
				
			||||||
 | 
					            note = self.cursor.fetchone()
 | 
				
			||||||
 | 
					            if note:
 | 
				
			||||||
 | 
					                return dict(note)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                logging.warning(f"No note found with ID: {note_id}")
 | 
				
			||||||
 | 
					                return None
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					"""GUI package for ForensicTrails application."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from .main_window import MainWindow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__all__ = ['MainWindow']
 | 
				
			||||||
@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					"""GUI dialogs for ForensicTrails application."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/forensictrails/gui/main_window.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/forensictrails/gui/main_window.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					from PyQt6 import QtWidgets, uic
 | 
				
			||||||
 | 
					from PyQt6.QtWidgets import QMainWindow, QFileDialog, QMessageBox
 | 
				
			||||||
 | 
					from PyQt6.QtCore import Qt
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					from ..core.case_manager import CaseManager
 | 
				
			||||||
 | 
					from ..utils.config import config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MainWindow(QMainWindow):
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
							
								
								
									
										123
									
								
								tests/README.md
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								tests/README.md
									
									
									
									
									
								
							@ -1,123 +0,0 @@
 | 
				
			|||||||
# ForensicTrails Test Suite
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Overview
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This directory contains unit and integration tests for the ForensicTrails application.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Running Tests
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Run all tests
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
python -m pytest tests/
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Run specific test file
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
python -m pytest tests/test_database.py
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Run with verbose output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
python -m pytest tests/test_database.py -v
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Run with coverage report
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
python -m pytest tests/test_database.py --cov=forensictrails.db.database --cov-report=term-missing
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Run specific test class or method
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
python -m pytest tests/test_database.py::TestGetDbConnection
 | 
					 | 
				
			||||||
python -m pytest tests/test_database.py::TestGetDbConnection::test_get_db_connection_creates_file
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Test Files
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### `test_database.py`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Comprehensive tests for the database module (`forensictrails.db.database`).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**Coverage: 94%**
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### Test Classes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestGetDbConnection**: Tests for `get_db_connection()` function
 | 
					 | 
				
			||||||
  - Connection creation and file creation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestValidateDatabaseSchema**: Tests for `validate_database_schema()` function
 | 
					 | 
				
			||||||
  - Empty database validation
 | 
					 | 
				
			||||||
  - Incomplete database validation
 | 
					 | 
				
			||||||
  - Complete database validation
 | 
					 | 
				
			||||||
  - Non-existent database validation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestCreateFreshDatabase**: Tests for `create_fresh_database()` function
 | 
					 | 
				
			||||||
  - Database file creation
 | 
					 | 
				
			||||||
  - All required tables creation
 | 
					 | 
				
			||||||
  - Return value verification
 | 
					 | 
				
			||||||
  - Clean path behavior
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestInitializeDatabase**: Tests for `initialize_database()` function
 | 
					 | 
				
			||||||
  - New database creation
 | 
					 | 
				
			||||||
  - Valid database preservation
 | 
					 | 
				
			||||||
  - Invalid database recreation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestShowDbSchema**: Tests for `show_db_schema()` function
 | 
					 | 
				
			||||||
  - Logging behavior
 | 
					 | 
				
			||||||
  - Exception handling
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestDatabaseIntegration**: Full lifecycle integration tests
 | 
					 | 
				
			||||||
  - Complete workflow: create → use → corrupt → recreate
 | 
					 | 
				
			||||||
  - Data persistence and loss scenarios
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Test Coverage Summary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| Module | Statements | Missing | Coverage |
 | 
					 | 
				
			||||||
|--------|-----------|---------|----------|
 | 
					 | 
				
			||||||
| `forensictrails.db.database` | 65 | 4 | **94%** |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Uncovered Lines
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Line 10: Config fallback in `get_db_connection()` (uses mocked config in tests)
 | 
					 | 
				
			||||||
- Line 48: Config fallback in `create_fresh_database()` (uses explicit paths in tests)
 | 
					 | 
				
			||||||
- Line 69: Config fallback in `initialize_database()` (uses explicit paths in tests)
 | 
					 | 
				
			||||||
- Line 91: Debug logging in `show_db_schema()` (covered but not counted due to mocking)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
These uncovered lines are primarily default parameter handling that relies on the global config object, which is mocked in tests.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Test Design Principles
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. **Isolation**: Each test uses temporary directories and cleans up after itself
 | 
					 | 
				
			||||||
2. **Independence**: Tests don't depend on each other and can run in any order
 | 
					 | 
				
			||||||
3. **Mocking**: External dependencies (config, logging) are mocked where appropriate
 | 
					 | 
				
			||||||
4. **Real Database**: Tests use actual SQLite databases to ensure realistic behavior
 | 
					 | 
				
			||||||
5. **Comprehensive**: Tests cover success paths, error paths, and edge cases
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Adding New Tests
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
When adding new database functionality:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. Add unit tests for individual functions
 | 
					 | 
				
			||||||
2. Add integration tests for complex workflows
 | 
					 | 
				
			||||||
3. Ensure cleanup in `tearDown()` methods
 | 
					 | 
				
			||||||
4. Use descriptive test names that explain what is being tested
 | 
					 | 
				
			||||||
5. Run coverage to ensure new code is tested
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Dependencies
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Tests require:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- `pytest` - Test framework
 | 
					 | 
				
			||||||
- `pytest-cov` - Coverage reporting
 | 
					 | 
				
			||||||
- Standard library: `unittest`, `tempfile`, `sqlite3`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Install test dependencies:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
pip install pytest pytest-cov
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
@ -1,92 +0,0 @@
 | 
				
			|||||||
"""
 | 
					 | 
				
			||||||
ForensicTrails Test Suite Summary
 | 
					 | 
				
			||||||
==================================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
OVERVIEW
 | 
					 | 
				
			||||||
--------
 | 
					 | 
				
			||||||
✅ 54 tests across 4 test files
 | 
					 | 
				
			||||||
✅ 87% overall code coverage
 | 
					 | 
				
			||||||
✅ All tests passing
 | 
					 | 
				
			||||||
⚡ Fast execution (~0.11 seconds)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST FILES
 | 
					 | 
				
			||||||
----------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. test_config.py (8 tests) - 100% coverage
 | 
					 | 
				
			||||||
   - Config file loading
 | 
					 | 
				
			||||||
   - Default value handling
 | 
					 | 
				
			||||||
   - Partial configuration support
 | 
					 | 
				
			||||||
   - Data type validation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2. test_logging.py (9 tests) - 100% coverage
 | 
					 | 
				
			||||||
   - Log file creation
 | 
					 | 
				
			||||||
   - Handler configuration
 | 
					 | 
				
			||||||
   - Log level management
 | 
					 | 
				
			||||||
   - Formatter verification
 | 
					 | 
				
			||||||
   - Integration tests
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
3. test_database.py (16 tests) - 94% coverage
 | 
					 | 
				
			||||||
   - Database initialization
 | 
					 | 
				
			||||||
   - Schema validation
 | 
					 | 
				
			||||||
   - Fresh database creation
 | 
					 | 
				
			||||||
   - Invalid database recovery
 | 
					 | 
				
			||||||
   - Full lifecycle integration
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
4. test_case_manager.py (21 tests) - 97% coverage
 | 
					 | 
				
			||||||
   - Case CRUD operations
 | 
					 | 
				
			||||||
   - Search and filtering
 | 
					 | 
				
			||||||
   - Status management
 | 
					 | 
				
			||||||
   - Update tracking
 | 
					 | 
				
			||||||
   - Full workflow integration
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
COVERAGE BY MODULE
 | 
					 | 
				
			||||||
------------------
 | 
					 | 
				
			||||||
forensictrails.utils.config        100% ✓
 | 
					 | 
				
			||||||
forensictrails.utils.logging       100% ✓
 | 
					 | 
				
			||||||
forensictrails.core.case_manager    97% ✓
 | 
					 | 
				
			||||||
forensictrails.db.database          94% ✓
 | 
					 | 
				
			||||||
forensictrails.__main__              0% (GUI entry point)
 | 
					 | 
				
			||||||
----------------------------------------
 | 
					 | 
				
			||||||
TOTAL                                87% ✓
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RUNNING TESTS
 | 
					 | 
				
			||||||
-------------
 | 
					 | 
				
			||||||
All tests:       python -m pytest tests/
 | 
					 | 
				
			||||||
Specific file:   python -m pytest tests/test_config.py
 | 
					 | 
				
			||||||
With coverage:   python -m pytest tests/ --cov=forensictrails
 | 
					 | 
				
			||||||
Verbose:         python -m pytest tests/ -v
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
COVERAGE REPORT
 | 
					 | 
				
			||||||
---------------
 | 
					 | 
				
			||||||
HTML report:     python -m pytest tests/ --cov=forensictrails --cov-report=html
 | 
					 | 
				
			||||||
                 (Open htmlcov/index.html in browser)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
UNCOVERED CODE
 | 
					 | 
				
			||||||
--------------
 | 
					 | 
				
			||||||
- database.py (4 lines): Default parameter fallbacks
 | 
					 | 
				
			||||||
- case_manager.py (2 lines): TODO export/import functions
 | 
					 | 
				
			||||||
- __main__.py (17 lines): GUI entry point (requires GUI testing)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
KNOWN ISSUES
 | 
					 | 
				
			||||||
------------
 | 
					 | 
				
			||||||
⚠️  DeprecationWarning in case_manager.py:60
 | 
					 | 
				
			||||||
    Using datetime.utcnow() - should migrate to datetime.now(datetime.UTC)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TEST PRINCIPLES
 | 
					 | 
				
			||||||
---------------
 | 
					 | 
				
			||||||
✓ Isolated - Each test uses temp directories
 | 
					 | 
				
			||||||
✓ Independent - Tests run in any order
 | 
					 | 
				
			||||||
✓ Mocked - External dependencies mocked appropriately
 | 
					 | 
				
			||||||
✓ Realistic - Uses real SQLite databases
 | 
					 | 
				
			||||||
✓ Comprehensive - Success, error, and edge cases
 | 
					 | 
				
			||||||
✓ Fast - All 54 tests in ~0.11 seconds
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
MAINTENANCE
 | 
					 | 
				
			||||||
-----------
 | 
					 | 
				
			||||||
- Keep coverage above 85%
 | 
					 | 
				
			||||||
- Update tests when refactoring
 | 
					 | 
				
			||||||
- Add tests for new features
 | 
					 | 
				
			||||||
- Run tests before committing
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Last Updated: 2025-10-08
 | 
					 | 
				
			||||||
"""
 | 
					 | 
				
			||||||
@ -1,243 +0,0 @@
 | 
				
			|||||||
# ForensicTrails Test Suite
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Overview
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This directory contains comprehensive unit and integration tests for the ForensicTrails application.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Test Summary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **Total Tests:** 54
 | 
					 | 
				
			||||||
- **Test Files:** 4
 | 
					 | 
				
			||||||
- **Overall Coverage:** 87%
 | 
					 | 
				
			||||||
- **Execution Time:** ~0.17s
 | 
					 | 
				
			||||||
- **Status:** ✅ All tests passing
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Running Tests
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Run all tests
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
python -m pytest tests/
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Run specific test file
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
python -m pytest tests/test_database.py
 | 
					 | 
				
			||||||
python -m pytest tests/test_config.py
 | 
					 | 
				
			||||||
python -m pytest tests/test_logging.py
 | 
					 | 
				
			||||||
python -m pytest tests/test_case_manager.py
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Run with verbose output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
python -m pytest tests/ -v
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Run with coverage report
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
python -m pytest tests/ --cov=forensictrails --cov-report=term-missing
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Generate HTML coverage report
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
python -m pytest tests/ --cov=forensictrails --cov-report=html
 | 
					 | 
				
			||||||
# Open htmlcov/index.html in your browser
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Run specific test class or method
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
python -m pytest tests/test_database.py::TestGetDbConnection
 | 
					 | 
				
			||||||
python -m pytest tests/test_case_manager.py::TestCaseManager::test_create_case
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Test Files
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### 1. `test_config.py` (8 tests)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Tests for the configuration module (`forensictrails.utils.config`).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**Coverage: 100%** ✓
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### Test Classes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestConfig** (7 tests)
 | 
					 | 
				
			||||||
  - Loading from valid JSON file
 | 
					 | 
				
			||||||
  - Handling non-existent files
 | 
					 | 
				
			||||||
  - Partial configuration with defaults
 | 
					 | 
				
			||||||
  - Empty configuration files
 | 
					 | 
				
			||||||
  - Extra keys in configuration
 | 
					 | 
				
			||||||
  - Default constructor behavior
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestConfigDataTypes** (1 test)
 | 
					 | 
				
			||||||
  - String and integer value handling
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### 2. `test_logging.py` (9 tests)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Tests for the logging setup module (`forensictrails.utils.logging`).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**Coverage: 100%** ✓
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### Test Classes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestSetupLogging** (8 tests)
 | 
					 | 
				
			||||||
  - Log file creation
 | 
					 | 
				
			||||||
  - Nested directory creation
 | 
					 | 
				
			||||||
  - Handler addition (FileHandler, StreamHandler)
 | 
					 | 
				
			||||||
  - Log level configuration
 | 
					 | 
				
			||||||
  - Message logging
 | 
					 | 
				
			||||||
  - Formatter verification
 | 
					 | 
				
			||||||
  - Config fallback behavior
 | 
					 | 
				
			||||||
  - Multiple log level testing
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestLoggingIntegration** (1 test)
 | 
					 | 
				
			||||||
  - Multiple message logging integration
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### 3. `test_database.py` (16 tests)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Comprehensive tests for the database module (`forensictrails.db.database`).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**Coverage: 94%** ✓
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### Test Classes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestGetDbConnection** (2 tests)
 | 
					 | 
				
			||||||
  - Connection creation and file creation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestValidateDatabaseSchema** (4 tests)
 | 
					 | 
				
			||||||
  - Empty database validation
 | 
					 | 
				
			||||||
  - Incomplete database validation
 | 
					 | 
				
			||||||
  - Complete database validation
 | 
					 | 
				
			||||||
  - Non-existent database validation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestCreateFreshDatabase** (4 tests)
 | 
					 | 
				
			||||||
  - Database file creation
 | 
					 | 
				
			||||||
  - All required tables creation
 | 
					 | 
				
			||||||
  - Return value verification
 | 
					 | 
				
			||||||
  - Clean path behavior
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestInitializeDatabase** (3 tests)
 | 
					 | 
				
			||||||
  - New database creation
 | 
					 | 
				
			||||||
  - Valid database preservation
 | 
					 | 
				
			||||||
  - Invalid database recreation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestShowDbSchema** (2 tests)
 | 
					 | 
				
			||||||
  - Logging behavior
 | 
					 | 
				
			||||||
  - Exception handling
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestDatabaseIntegration** (1 test)
 | 
					 | 
				
			||||||
  - Complete workflow: create → use → corrupt → recreate
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### 4. `test_case_manager.py` (21 tests)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Comprehensive tests for the case manager module (`forensictrails.core.case_manager`).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
**Coverage: 97%** ✓
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### Test Classes
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestCaseManager** (19 tests)
 | 
					 | 
				
			||||||
  - Initialization
 | 
					 | 
				
			||||||
  - Case creation (full and minimal)
 | 
					 | 
				
			||||||
  - Getting cases (existent and non-existent)
 | 
					 | 
				
			||||||
  - Listing cases (empty, multiple, filtered)
 | 
					 | 
				
			||||||
  - Search functionality
 | 
					 | 
				
			||||||
  - Combined filters
 | 
					 | 
				
			||||||
  - Case updates (valid, invalid, non-existent)
 | 
					 | 
				
			||||||
  - Status changes (close, archive)
 | 
					 | 
				
			||||||
  - Case deletion
 | 
					 | 
				
			||||||
  - Modified timestamp tracking
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **TestCaseManagerIntegration** (2 tests)
 | 
					 | 
				
			||||||
  - Full case lifecycle integration
 | 
					 | 
				
			||||||
  - Multiple cases workflow
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Test Coverage Summary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| Module | Statements | Missing | Coverage |
 | 
					 | 
				
			||||||
|--------|-----------|---------|----------|
 | 
					 | 
				
			||||||
| `forensictrails.utils.config` | 16 | 0 | **100%** ✓ |
 | 
					 | 
				
			||||||
| `forensictrails.utils.logging` | 20 | 0 | **100%** ✓ |
 | 
					 | 
				
			||||||
| `forensictrails.core.case_manager` | 65 | 2 | **97%** ✓ |
 | 
					 | 
				
			||||||
| `forensictrails.db.database` | 65 | 4 | **94%** ✓ |
 | 
					 | 
				
			||||||
| `forensictrails.__main__` | 17 | 17 | **0%** (GUI entry) |
 | 
					 | 
				
			||||||
| **TOTAL** | **183** | **23** | **87%** |
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Uncovered Lines
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### database.py (4 lines)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Line 10: Config fallback in `get_db_connection()` (uses mocked config)
 | 
					 | 
				
			||||||
- Line 48: Config fallback in `create_fresh_database()` (uses explicit paths)
 | 
					 | 
				
			||||||
- Line 69: Config fallback in `initialize_database()` (uses explicit paths)
 | 
					 | 
				
			||||||
- Line 91: Debug logging (covered but mocked)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### case_manager.py (2 lines)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Lines 88, 93: Export/import functions (TODO - not implemented yet)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#### **main**.py (17 lines)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Entry point for GUI application (requires PyQt6 GUI testing)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Test Design Principles
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. **Isolation**: Each test uses temporary directories and cleans up after itself
 | 
					 | 
				
			||||||
2. **Independence**: Tests don't depend on each other and can run in any order
 | 
					 | 
				
			||||||
3. **Mocking**: External dependencies (config, logging) are mocked where appropriate
 | 
					 | 
				
			||||||
4. **Real Database**: Tests use actual SQLite databases to ensure realistic behavior
 | 
					 | 
				
			||||||
5. **Comprehensive**: Tests cover success paths, error paths, and edge cases
 | 
					 | 
				
			||||||
6. **Fast**: All 54 tests run in ~0.17 seconds
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Adding New Tests
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
When adding new functionality:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. Add unit tests for individual functions
 | 
					 | 
				
			||||||
2. Add integration tests for complex workflows
 | 
					 | 
				
			||||||
3. Ensure cleanup in `tearDown()` methods
 | 
					 | 
				
			||||||
4. Use descriptive test names that explain what is being tested
 | 
					 | 
				
			||||||
5. Mock external dependencies appropriately
 | 
					 | 
				
			||||||
6. Run coverage to ensure new code is tested
 | 
					 | 
				
			||||||
7. Aim for >90% coverage on new modules
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Dependencies
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Tests require:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- `pytest` - Test framework
 | 
					 | 
				
			||||||
- `pytest-cov` - Coverage reporting
 | 
					 | 
				
			||||||
- Standard library: `unittest`, `tempfile`, `sqlite3`, `json`, `logging`
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Install test dependencies:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
pip install pytest pytest-cov
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Continuous Integration
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
These tests are designed to run in CI/CD pipelines. Example usage:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```bash
 | 
					 | 
				
			||||||
# Run tests with JUnit XML output for CI
 | 
					 | 
				
			||||||
python -m pytest tests/ --junitxml=test-results.xml
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Run with coverage and fail if below threshold
 | 
					 | 
				
			||||||
python -m pytest tests/ --cov=forensictrails --cov-fail-under=85
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Known Issues
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- **DeprecationWarning** in `case_manager.py:60`: Uses `datetime.utcnow()` which is deprecated. Should be updated to use `datetime.now(datetime.UTC)` in the future.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Test Maintenance
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- Tests are automatically run on code changes
 | 
					 | 
				
			||||||
- Coverage reports are generated in `htmlcov/` directory
 | 
					 | 
				
			||||||
- Keep test coverage above 85% for the project
 | 
					 | 
				
			||||||
- Review and update tests when refactoring code
 | 
					 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user