mirror of
https://github.com/DRYTRIX/TimeTracker.git
synced 2026-05-01 17:59:28 -05:00
90dde470da
- 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.
216 lines
8.3 KiB
Python
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"
|