2013-10-23 15:10:59 +00:00
import datetime
2014-03-14 16:15:31 +00:00
from django . contrib . auth . models import User , AnonymousUser
from django . core . exceptions import ValidationError
from django . db . models . signals import pre_save
from django . http import HttpResponse
from django . test import TestCase , RequestFactory
from auditlog . middleware import AuditlogMiddleware
2013-10-21 20:41:21 +00:00
from auditlog . models import LogEntry
2015-06-01 18:01:40 +00:00
from testapp . models import ( SimpleModel , AltPrimaryKeyModel , ProxyModel ,
SimpleIncludeModel , SimpleExcludeModel , AdditionDataIncludedModel , )
2013-10-21 19:46:31 +00:00
2013-10-23 15:10:59 +00:00
class SimpleModelTest ( TestCase ) :
2013-10-21 19:46:31 +00:00
def setUp ( self ) :
2013-10-23 15:10:59 +00:00
self . obj = SimpleModel . objects . create ( text = ' I am not difficult. ' )
2013-10-21 19:46:31 +00:00
2013-10-21 20:41:21 +00:00
def test_create ( self ) :
""" Creation is logged correctly. """
# Get the object to work with
2013-10-23 15:10:59 +00:00
obj = self . obj
2013-10-21 20:41:21 +00:00
# Check for log entries
self . assertTrue ( obj . history . count ( ) == 1 , msg = " There is one log entry " )
try :
history = obj . history . get ( )
2013-10-23 15:10:59 +00:00
except obj . history . DoesNotExist :
2013-10-21 20:41:21 +00:00
self . assertTrue ( False , " Log entry exists " )
else :
self . assertEqual ( history . action , LogEntry . Action . CREATE , msg = " Action is ' CREATE ' " )
self . assertEqual ( history . object_repr , str ( obj ) , msg = " Representation is equal " )
def test_update ( self ) :
""" Updates are logged correctly. """
# Get the object to work with
2013-10-23 15:10:59 +00:00
obj = self . obj
2013-10-21 20:41:21 +00:00
# Change something
obj . boolean = True
2013-10-21 19:46:31 +00:00
obj . save ( )
# Check for log entries
2013-10-21 20:41:21 +00:00
self . assertTrue ( obj . history . filter ( action = LogEntry . Action . UPDATE ) . count ( ) == 1 , msg = " There is one log entry for ' UPDATE ' " )
history = obj . history . get ( action = LogEntry . Action . UPDATE )
self . assertJSONEqual ( history . changes , ' { " boolean " : [ " False " , " True " ]} ' , msg = " The change is correctly logged " )
2013-10-23 15:10:59 +00:00
def test_delete ( self ) :
""" Deletion is logged correctly. """
# Get the object to work with
obj = self . obj
history = obj . history . latest ( )
# Delete the object
obj . delete ( )
# Check for log entries
self . assertTrue ( LogEntry . objects . filter ( content_type = history . content_type , object_pk = history . object_pk , action = LogEntry . Action . DELETE ) . count ( ) == 1 , msg = " There is one log entry for ' DELETE ' " )
def test_recreate ( self ) :
SimpleModel . objects . all ( ) . delete ( )
self . setUp ( )
self . test_create ( )
class AltPrimaryKeyModelTest ( SimpleModelTest ) :
def setUp ( self ) :
self . obj = AltPrimaryKeyModel . objects . create ( key = str ( datetime . datetime . now ( ) ) , text = ' I am strange. ' )
class ProxyModelTest ( SimpleModelTest ) :
def setUp ( self ) :
self . obj = ProxyModel . objects . create ( text = ' I am not what you think. ' )
2014-03-14 16:15:31 +00:00
class MiddlewareTest ( TestCase ) :
"""
Test the middleware responsible for connecting and disconnecting the signals used in automatic logging .
"""
def setUp ( self ) :
self . middleware = AuditlogMiddleware ( )
self . factory = RequestFactory ( )
self . user = User . objects . create_user ( username = ' test ' , email = ' test@example.com ' , password = ' top_secret ' )
2014-03-14 19:53:46 +00:00
def test_request_anonymous ( self ) :
2014-03-14 16:15:31 +00:00
""" No actor will be logged when a user is not logged in. """
# Create a request
request = self . factory . get ( ' / ' )
request . user = AnonymousUser ( )
# Run middleware
self . middleware . process_request ( request )
# Validate result
self . assertFalse ( pre_save . has_listeners ( LogEntry ) )
2014-03-14 19:53:46 +00:00
# Finalize transaction
self . middleware . process_exception ( request , None )
2014-03-14 16:15:31 +00:00
def test_request ( self ) :
""" The actor will be logged when a user is logged in. """
# Create a request
request = self . factory . get ( ' / ' )
request . user = self . user
# Run middleware
self . middleware . process_request ( request )
# Validate result
self . assertTrue ( pre_save . has_listeners ( LogEntry ) )
2014-03-14 19:53:46 +00:00
# Finalize transaction
self . middleware . process_exception ( request , None )
def test_response ( self ) :
2014-03-14 16:15:31 +00:00
""" The signal will be disconnected when the request is processed. """
# Create a request
request = self . factory . get ( ' / ' )
request . user = self . user
# Run middleware
self . middleware . process_request ( request )
self . assertTrue ( pre_save . has_listeners ( LogEntry ) ) # The signal should be present before trying to disconnect it.
self . middleware . process_response ( request , HttpResponse ( ) )
# Validate result
self . assertFalse ( pre_save . has_listeners ( LogEntry ) )
def test_exception ( self ) :
""" The signal will be disconnected when an exception is raised. """
# Create a request
request = self . factory . get ( ' / ' )
request . user = self . user
# Run middleware
self . middleware . process_request ( request )
self . assertTrue ( pre_save . has_listeners ( LogEntry ) ) # The signal should be present before trying to disconnect it.
self . middleware . process_exception ( request , ValidationError ( " Test " ) )
# Validate result
self . assertFalse ( pre_save . has_listeners ( LogEntry ) )
2014-10-06 09:16:23 +00:00
class SimpeIncludeModelTest ( TestCase ) :
""" Log only changes in include_fields """
def test_register_include_fields ( self ) :
sim = SimpleIncludeModel ( label = ' Include model ' , text = ' Looong text ' )
sim . save ( )
self . assertTrue ( sim . history . count ( ) == 1 , msg = " There is one log entry " )
# Change label, record
sim . label = ' Changed label '
sim . save ( )
self . assertTrue ( sim . history . count ( ) == 2 , msg = " There are two log entries " )
# Change text, ignore
sim . text = ' Short text '
sim . save ( )
self . assertTrue ( sim . history . count ( ) == 2 , msg = " There are two log entries " )
class SimpeExcludeModelTest ( TestCase ) :
""" Log only changes that are not in exclude_fields """
def test_register_exclude_fields ( self ) :
sem = SimpleIncludeModel ( label = ' Exclude model ' , text = ' Looong text ' )
sem . save ( )
self . assertTrue ( sem . history . count ( ) == 1 , msg = " There is one log entry " )
# Change label, ignore
sem . label = ' Changed label '
sem . save ( )
self . assertTrue ( sem . history . count ( ) == 2 , msg = " There are two log entries " )
# Change text, record
sem . text = ' Short text '
sem . save ( )
self . assertTrue ( sem . history . count ( ) == 2 , msg = " There are two log entries " )
2015-06-01 18:01:40 +00:00
class AdditionalDataModelTest ( TestCase ) :
""" Log additional data if get_additional_data is defined in the model """
def test_model_without_additional_data ( self ) :
obj_wo_additional_data = SimpleModel . objects . create ( text = ' No additional '
' data ' )
obj_log_entry = obj_wo_additional_data . history . get ( )
self . assertIsNone ( obj_log_entry . additional_data )
def test_model_with_additional_data ( self ) :
related_model = SimpleModel . objects . create ( text = ' Log my reference ' )
obj_with_additional_data = AdditionDataIncludedModel (
label = ' Additional data to log entries ' , related = related_model )
obj_with_additional_data . save ( )
self . assertTrue ( obj_with_additional_data . history . count ( ) == 1 ,
msg = " There is 1 log entry " )
log_entry = obj_with_additional_data . history . get ( )
self . assertIsNotNone ( log_entry . additional_data )
extra_data = log_entry . additional_data
self . assertTrue ( extra_data [ ' related_model_text ' ] == related_model . text ,
msg = " Related model ' s text is logged " )
self . assertTrue ( extra_data [ ' related_model_id ' ] == related_model . id ,
msg = " Related model ' s id is logged " )