61 lines
2.4 KiB
Python
61 lines
2.4 KiB
Python
"""AuditLog model — append-only admin action tracking.
|
|
|
|
ADMIN-002. Every sensitive admin action (backup, restore, toggle, season,
|
|
wipe) writes an AuditLog entry. These tests verify the model itself.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from app.extensions import db
|
|
from app.models import AuditLog, User
|
|
|
|
|
|
class TestAuditLogRecord:
|
|
def test_record_stores_all_fields(self, app, make_user):
|
|
admin_id = make_user('admin')
|
|
with app.app_context():
|
|
AuditLog.record(
|
|
user_id=admin_id,
|
|
action='test_action',
|
|
details='some details here',
|
|
ip_address='192.168.1.1',
|
|
)
|
|
entry = AuditLog.query.order_by(AuditLog.id.desc()).first()
|
|
assert entry is not None
|
|
assert entry.user_id == admin_id
|
|
assert entry.action == 'test_action'
|
|
assert entry.details == 'some details here'
|
|
assert entry.ip_address == '192.168.1.1'
|
|
assert entry.created_at is not None
|
|
|
|
def test_record_without_details_or_ip(self, app, make_user):
|
|
admin_id = make_user('admin')
|
|
with app.app_context():
|
|
AuditLog.record(user_id=admin_id, action='minimal')
|
|
entry = AuditLog.query.order_by(AuditLog.id.desc()).first()
|
|
assert entry.action == 'minimal'
|
|
assert entry.details is None
|
|
assert entry.ip_address is None
|
|
|
|
def test_entries_are_ordered_by_date_descending(self, app, make_user):
|
|
admin_id = make_user('admin')
|
|
with app.app_context():
|
|
AuditLog.record(user_id=admin_id, action='first')
|
|
AuditLog.record(user_id=admin_id, action='second')
|
|
AuditLog.record(user_id=admin_id, action='third')
|
|
|
|
entries = AuditLog.query.order_by(AuditLog.created_at.desc()).all()
|
|
actions = [e.action for e in entries]
|
|
assert actions == ['third', 'second', 'first']
|
|
|
|
def test_audit_log_survives_user_deletion(self, app, make_user):
|
|
admin_id = make_user('admin')
|
|
with app.app_context():
|
|
AuditLog.record(user_id=admin_id, action='before_delete')
|
|
user = db.session.get(User, admin_id)
|
|
db.session.delete(user)
|
|
db.session.commit()
|
|
|
|
entry = AuditLog.query.filter_by(action='before_delete').first()
|
|
assert entry is not None
|
|
assert entry.user_id is None # FK set to NULL on delete |