From 252dbbdcce536183c0e0a4dbc4cd7e134bb43204 Mon Sep 17 00:00:00 2001 From: overcuriousity Date: Wed, 8 Oct 2025 22:26:01 +0200 Subject: [PATCH] basic setup --- src/forensictrails/__main__.py | 9 +- src/forensictrails/core/case_manager.py | 49 ++++- src/forensictrails/gui/__init__.py | 5 + src/forensictrails/gui/dialogs/__init__.py | 2 + src/forensictrails/gui/main_window.py | 12 + tests/README.md | 123 ----------- tests/SUMMARY.txt | 92 -------- tests/TEST_SUMMARY.md | 243 --------------------- 8 files changed, 68 insertions(+), 467 deletions(-) create mode 100644 src/forensictrails/gui/main_window.py delete mode 100644 tests/README.md delete mode 100644 tests/SUMMARY.txt delete mode 100644 tests/TEST_SUMMARY.md diff --git a/src/forensictrails/__main__.py b/src/forensictrails/__main__.py index a4fcdec..8b64cc6 100644 --- a/src/forensictrails/__main__.py +++ b/src/forensictrails/__main__.py @@ -20,14 +20,9 @@ def main(): app.setApplicationVersion("0.1.0") # 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.debug("No GUI yet - exiting...") - return 0 - # sys.exit(app.exec()) + logging.info("Application started") + sys.exit(app.exec()) if __name__ == "__main__": sys.exit(main()) \ No newline at end of file diff --git a/src/forensictrails/core/case_manager.py b/src/forensictrails/core/case_manager.py index 5e7bb57..c74bd01 100644 --- a/src/forensictrails/core/case_manager.py +++ b/src/forensictrails/core/case_manager.py @@ -1,7 +1,7 @@ from ..utils.config import config from ..db.database import get_db_connection import logging -from datetime import datetime +from datetime import datetime, timezone class CaseManager(): def __init__(self, db_path=None): @@ -57,7 +57,7 @@ class CaseManager(): logging.warning("No valid fields provided for update.") 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()]) values = list(updates.values()) + [case_id] @@ -91,4 +91,49 @@ class CaseManager(): # TODO: Implement import functionality # should import a .sqlite file and merge its data into the main database 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 \ No newline at end of file diff --git a/src/forensictrails/gui/__init__.py b/src/forensictrails/gui/__init__.py index e69de29..2dea48f 100644 --- a/src/forensictrails/gui/__init__.py +++ b/src/forensictrails/gui/__init__.py @@ -0,0 +1,5 @@ +"""GUI package for ForensicTrails application.""" + +from .main_window import MainWindow + +__all__ = ['MainWindow'] diff --git a/src/forensictrails/gui/dialogs/__init__.py b/src/forensictrails/gui/dialogs/__init__.py index e69de29..affe306 100644 --- a/src/forensictrails/gui/dialogs/__init__.py +++ b/src/forensictrails/gui/dialogs/__init__.py @@ -0,0 +1,2 @@ +"""GUI dialogs for ForensicTrails application.""" + diff --git a/src/forensictrails/gui/main_window.py b/src/forensictrails/gui/main_window.py new file mode 100644 index 0000000..a0b5391 --- /dev/null +++ b/src/forensictrails/gui/main_window.py @@ -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 diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 2ce20a7..0000000 --- a/tests/README.md +++ /dev/null @@ -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 -``` diff --git a/tests/SUMMARY.txt b/tests/SUMMARY.txt deleted file mode 100644 index f9feb77..0000000 --- a/tests/SUMMARY.txt +++ /dev/null @@ -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 -""" diff --git a/tests/TEST_SUMMARY.md b/tests/TEST_SUMMARY.md deleted file mode 100644 index 6c71208..0000000 --- a/tests/TEST_SUMMARY.md +++ /dev/null @@ -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