Files
TimeTracker/tests/test_audit_log_model.py
T
Dries Peeters 90dde470da style: standardize code formatting and normalize line endings
- Normalize line endings from CRLF to LF across all files to match .editorconfig
- Standardize quote style from single quotes to double quotes
- Normalize whitespace and formatting throughout codebase
- Apply consistent code style across 372 files including:
  * Application code (models, routes, services, utils)
  * Test files
  * Configuration files
  * CI/CD workflows

This ensures consistency with the project's .editorconfig settings and
improves code maintainability.
2025-11-28 20:05:37 +01:00

216 lines
8.3 KiB
Python

"""Tests for AuditLog model"""
import pytest
from datetime import datetime
from app.models import AuditLog, User, Project
from app import db
class TestAuditLogModel:
"""Tests for the AuditLog model"""
def test_audit_log_creation(self, app, test_user, test_project):
"""Test creating an audit log entry"""
with app.app_context():
audit_log = AuditLog(
user_id=test_user.id,
action="created",
entity_type="Project",
entity_id=test_project.id,
entity_name=test_project.name,
change_description=f'Created project "{test_project.name}"',
)
db.session.add(audit_log)
db.session.commit()
assert audit_log.id is not None
assert audit_log.user_id == test_user.id
assert audit_log.action == "created"
assert audit_log.entity_type == "Project"
assert audit_log.entity_id == test_project.id
assert audit_log.created_at is not None
def test_audit_log_log_change_method(self, app, test_user, test_project):
"""Test the AuditLog.log_change() class method"""
with app.app_context():
AuditLog.log_change(
user_id=test_user.id,
action="updated",
entity_type="Project",
entity_id=test_project.id,
field_name="name",
old_value="Old Name",
new_value="New Name",
entity_name=test_project.name,
change_description="Updated project name",
)
audit_log = AuditLog.query.filter_by(
user_id=test_user.id, entity_type="Project", entity_id=test_project.id, field_name="name"
).first()
assert audit_log is not None
assert audit_log.action == "updated"
assert audit_log.field_name == "name"
assert audit_log.get_old_value() == "Old Name"
assert audit_log.get_new_value() == "New Name"
def test_audit_log_value_encoding(self, app, test_user, test_project):
"""Test that values are properly encoded/decoded"""
with app.app_context():
# Test with datetime
old_dt = datetime(2024, 1, 1, 12, 0, 0)
new_dt = datetime(2024, 1, 2, 12, 0, 0)
AuditLog.log_change(
user_id=test_user.id,
action="updated",
entity_type="Project",
entity_id=test_project.id,
field_name="updated_at",
old_value=old_dt,
new_value=new_dt,
entity_name=test_project.name,
)
audit_log = AuditLog.query.filter_by(
entity_type="Project", entity_id=test_project.id, field_name="updated_at"
).first()
assert audit_log is not None
# Values should be JSON-encoded strings
assert isinstance(audit_log.old_value, str)
assert isinstance(audit_log.new_value, str)
# Decoded values should match
assert audit_log.get_old_value() == old_dt.isoformat()
assert audit_log.get_new_value() == new_dt.isoformat()
def test_audit_log_get_for_entity(self, app, test_user, test_project):
"""Test getting audit logs for a specific entity"""
with app.app_context():
# Create multiple audit logs for the same entity
for i in range(5):
AuditLog.log_change(
user_id=test_user.id,
action="updated",
entity_type="Project",
entity_id=test_project.id,
field_name=f"field_{i}",
old_value=f"old_{i}",
new_value=f"new_{i}",
entity_name=test_project.name,
)
# Get audit logs for this entity
logs = AuditLog.get_for_entity("Project", test_project.id, limit=3)
assert len(logs) == 3
assert all(log.entity_type == "Project" for log in logs)
assert all(log.entity_id == test_project.id for log in logs)
def test_audit_log_get_for_user(self, app, test_user, test_project):
"""Test getting audit logs for a specific user"""
with app.app_context():
# Create multiple audit logs by the same user
for i in range(5):
AuditLog.log_change(
user_id=test_user.id,
action="updated",
entity_type="Project",
entity_id=test_project.id,
field_name=f"field_{i}",
old_value=f"old_{i}",
new_value=f"new_{i}",
entity_name=test_project.name,
)
# Get audit logs for this user
logs = AuditLog.get_for_user(test_user.id, limit=3)
assert len(logs) == 3
assert all(log.user_id == test_user.id for log in logs)
def test_audit_log_get_recent(self, app, test_user, test_project):
"""Test getting recent audit logs with filters"""
with app.app_context():
# Create audit logs with different actions
AuditLog.log_change(
user_id=test_user.id,
action="created",
entity_type="Project",
entity_id=test_project.id,
entity_name=test_project.name,
)
AuditLog.log_change(
user_id=test_user.id,
action="updated",
entity_type="Project",
entity_id=test_project.id,
field_name="name",
old_value="Old",
new_value="New",
entity_name=test_project.name,
)
AuditLog.log_change(
user_id=test_user.id,
action="deleted",
entity_type="Project",
entity_id=test_project.id,
entity_name=test_project.name,
)
# Filter by action
created_logs = AuditLog.get_recent(action="created", limit=10)
assert len(created_logs) == 1
assert created_logs[0].action == "created"
# Filter by entity type
project_logs = AuditLog.get_recent(entity_type="Project", limit=10)
assert len(project_logs) == 3
def test_audit_log_to_dict(self, app, test_user, test_project):
"""Test converting audit log to dictionary"""
with app.app_context():
audit_log = AuditLog(
user_id=test_user.id,
action="created",
entity_type="Project",
entity_id=test_project.id,
entity_name=test_project.name,
change_description="Test description",
)
db.session.add(audit_log)
db.session.commit()
log_dict = audit_log.to_dict()
assert isinstance(log_dict, dict)
assert log_dict["id"] == audit_log.id
assert log_dict["user_id"] == test_user.id
assert log_dict["action"] == "created"
assert log_dict["entity_type"] == "Project"
assert log_dict["entity_id"] == test_project.id
assert log_dict["username"] == test_user.username
assert log_dict["display_name"] == test_user.display_name
def test_audit_log_icons_and_colors(self, app, test_user, test_project):
"""Test icon and color methods"""
with app.app_context():
created_log = AuditLog(
user_id=test_user.id, action="created", entity_type="Project", entity_id=test_project.id
)
assert "green" in created_log.get_icon()
assert created_log.get_color() == "green"
updated_log = AuditLog(
user_id=test_user.id, action="updated", entity_type="Project", entity_id=test_project.id
)
assert "blue" in updated_log.get_icon()
assert updated_log.get_color() == "blue"
deleted_log = AuditLog(
user_id=test_user.id, action="deleted", entity_type="Project", entity_id=test_project.id
)
assert "red" in deleted_log.get_icon()
assert deleted_log.get_color() == "red"