# Path: narrative/models.py
# class Datum(models.Model):
#     # When was the datum created
#     timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
#     expiration_time = models.DateTimeField(null=True, blank=True, default=None)
#     # Origin of this datum; ie, what piece of software created it
#     origin = models.CharField(max_length=64)
#     datum_name = models.CharField(max_length=64)
# 
#     # Additional information about the datum; this is very datum specific
#     # This approach, storing json in a textfield and having an
#     # explicit accessor and mutator, is very ugly.  Really this is because
#     # we are storing non-structured/sparse data in a relational format.
#     datum_note_json = models.TextField(null=True, blank=True, default=None)
# 
#     # An ID to tie particular datums together
#     thread_id = models.CharField(max_length=36, null=True, blank=True)
# 
#     log_level = models.IntegerField(choices=DatumLogLevel.types, default=DatumLogLevel.INFO)
# 
#     objects = DatumManager()
# 
#     def __init__(self, *args, **kwargs):
#         if 'ttl' in kwargs:
#             kwargs['expiration_time'] = self.get_utc_now() + kwargs.pop('ttl')
# 
#         super(Datum, self).__init__(*args, **kwargs)
# 
#     def __str__(self):
#         note_snippet = self.datum_note_json[:50] if self.datum_note_json else ''
#         return 'origin:{0} datum_name:{1} note:{2}'.format(
#             self.origin, self.datum_name, note_snippet
#         )
# 
#     def get_note(self):
#         if self.datum_note_json:
#             return json.loads(self.datum_note_json)
#         else:
#             return []
# 
#     def set_note(self, note):
#         self.datum_note_json = json.dumps(note)
# 
#     def get_utc_now(self):
#         return utc_tz.localize(datetime.datetime.utcnow())
# 
#     @property
#     def timestamp_with_tz(self):
#         return utc_tz.localize(self.timestamp)
# 
#     def save(self, *args, **kwargs):
#         if None == self.thread_id:
#             self.thread_id = str(uuid.uuid4())
# 
#         super(Datum, self).save(*args, **kwargs)
# 
# class EventMeta(PeriodicalMeta):
#     pass
# 
# Path: narrative/events.py
# class Event(six.with_metaclass(abc.ABCMeta, object)):
# 
#     def __init__(self, event_meta):
#         self.event_meta = event_meta
# 
#     @property
#     def args(self):
#         return self.event_meta.get_args()
# 
#     @abc.abstractmethod
#     def detect(self, *args, **kwargs):
#         pass
# 
#     @abc.abstractmethod
#     def instance_summary(self, *args, **kwargs):
#         """
#         Return any additional information we want to associate with this
#         occurrence of this event; this is needed to separate this occurrence
#         from other occurrences of the same event.
#         """
#         return {}
# 
#     @property
#     def summary_datum_ttl(self):
#         return None
# 
#     @property
#     def executor(self):
#         return Executor()
# 
#     @property
#     def origin_name(self):
#         return self.__class__.__name__
# 
#     def get_utc_now(self):
#         return datetime.datetime.utcnow()
# 
#     def event_instance_detected(self):
#         """
#         This method is called when the event instance is first detected.
#         """
#         pass
# 
#     def get_or_create_summary_datum(self, *args, **kwargs):
#         """
#         Create the summary datum to represent this occurrence of this event.
#         """
#         datum_kwargs = {
#             'origin': self.origin_name,
#             'datum_name': self.event_meta.display_name,
#             'datum_note_json': json.dumps(self.instance_summary(*args, **kwargs)),
#         }
# 
#         defaults = copy.copy(datum_kwargs)
# 
#         datum_kwargs['defaults'] = defaults
# 
#         # If this event has defined a TTL for it's summary datum, then
#         # respect it.
#         if self.summary_datum_ttl:
#             defaults['ttl'] = self.summary_datum_ttl
# 
#         datum, created = Datum.objects.get_or_create(**datum_kwargs)
# 
#         return created
# 
#     def detect_and_handle(self, *args, **kwargs):
#         """
#         Check if the event has occured.  If so,
#         check if a datum already exists noting this event.  If not,
#         create a datum, and perform any needed handling of the event.
#         """
#         if self.detect(*args, **kwargs):
#             created = self.get_or_create_summary_datum(*args, **kwargs)
# 
#             if created:
#                 self.event_instance_detected(*args, **kwargs)
# 
#             return True
#         return False


import datetime
from unittest import TestCase
from ..models import Datum, EventMeta
from ..events import Event



class Test_get_or_create_summary_datum(TestCase):
    def setUp(self):
        Datum.objects.all().delete()

        self.detect_return_value = False

        self.mock_ttl = None


# Path: narrative/models.py
# class Datum(models.Model):
#     # When was the datum created
#     timestamp = models.DateTimeField(auto_now_add=True, db_index=True)
#     expiration_time = models.DateTimeField(null=True, blank=True, default=None)
#     # Origin of this datum; ie, what piece of software created it
#     origin = models.CharField(max_length=64)
#     datum_name = models.CharField(max_length=64)
# 
#     # Additional information about the datum; this is very datum specific
#     # This approach, storing json in a textfield and having an
#     # explicit accessor and mutator, is very ugly.  Really this is because
#     # we are storing non-structured/sparse data in a relational format.
#     datum_note_json = models.TextField(null=True, blank=True, default=None)
# 
#     # An ID to tie particular datums together
#     thread_id = models.CharField(max_length=36, null=True, blank=True)
# 
#     log_level = models.IntegerField(choices=DatumLogLevel.types, default=DatumLogLevel.INFO)
# 
#     objects = DatumManager()
# 
#     def __init__(self, *args, **kwargs):
#         if 'ttl' in kwargs:
#             kwargs['expiration_time'] = self.get_utc_now() + kwargs.pop('ttl')
# 
#         super(Datum, self).__init__(*args, **kwargs)
# 
#     def __str__(self):
#         note_snippet = self.datum_note_json[:50] if self.datum_note_json else ''
#         return 'origin:{0} datum_name:{1} note:{2}'.format(
#             self.origin, self.datum_name, note_snippet
#         )
# 
#     def get_note(self):
#         if self.datum_note_json:
#             return json.loads(self.datum_note_json)
#         else:
#             return []
# 
#     def set_note(self, note):
#         self.datum_note_json = json.dumps(note)
# 
#     def get_utc_now(self):
#         return utc_tz.localize(datetime.datetime.utcnow())
# 
#     @property
#     def timestamp_with_tz(self):
#         return utc_tz.localize(self.timestamp)
# 
#     def save(self, *args, **kwargs):
#         if None == self.thread_id:
#             self.thread_id = str(uuid.uuid4())
# 
#         super(Datum, self).save(*args, **kwargs)
# 
# class EventMeta(PeriodicalMeta):
#     pass
# 
# Path: narrative/events.py
# class Event(six.with_metaclass(abc.ABCMeta, object)):
# 
#     def __init__(self, event_meta):
#         self.event_meta = event_meta
# 
#     @property
#     def args(self):
#         return self.event_meta.get_args()
# 
#     @abc.abstractmethod
#     def detect(self, *args, **kwargs):
#         pass
# 
#     @abc.abstractmethod
#     def instance_summary(self, *args, **kwargs):
#         """
#         Return any additional information we want to associate with this
#         occurrence of this event; this is needed to separate this occurrence
#         from other occurrences of the same event.
#         """
#         return {}
# 
#     @property
#     def summary_datum_ttl(self):
#         return None
# 
#     @property
#     def executor(self):
#         return Executor()
# 
#     @property
#     def origin_name(self):
#         return self.__class__.__name__
# 
#     def get_utc_now(self):
#         return datetime.datetime.utcnow()
# 
#     def event_instance_detected(self):
#         """
#         This method is called when the event instance is first detected.
#         """
#         pass
# 
#     def get_or_create_summary_datum(self, *args, **kwargs):
#         """
#         Create the summary datum to represent this occurrence of this event.
#         """
#         datum_kwargs = {
#             'origin': self.origin_name,
#             'datum_name': self.event_meta.display_name,
#             'datum_note_json': json.dumps(self.instance_summary(*args, **kwargs)),
#         }
# 
#         defaults = copy.copy(datum_kwargs)
# 
#         datum_kwargs['defaults'] = defaults
# 
#         # If this event has defined a TTL for it's summary datum, then
#         # respect it.
#         if self.summary_datum_ttl:
#             defaults['ttl'] = self.summary_datum_ttl
# 
#         datum, created = Datum.objects.get_or_create(**datum_kwargs)
# 
#         return created
# 
#     def detect_and_handle(self, *args, **kwargs):
#         """
#         Check if the event has occured.  If so,
#         check if a datum already exists noting this event.  If not,
#         create a datum, and perform any needed handling of the event.
#         """
#         if self.detect(*args, **kwargs):
#             created = self.get_or_create_summary_datum(*args, **kwargs)
# 
#             if created:
#                 self.event_instance_detected(*args, **kwargs)
# 
#             return True
#         return False


# Path: narrative/tests/event_tests.py
import datetime
from unittest import TestCase
from ..models import Datum, EventMeta
from ..events import Event




class Test_get_or_create_summary_datum(TestCase):
    def setUp(self):
        Datum.objects.all().delete()

        self.detect_return_value = False

        self.mock_ttl = None


        class TestEvent(Event):