"""Test object history.
"""
import grok
import shutil
import tempfile
from persistent.list import PersistentList
from zope.interface.verify import verifyObject, verifyClass
from zope.security.management import newInteraction, endInteraction
from zope.security.testing import Principal, Participation
from waeup.sirp.app import University
from waeup.sirp.interfaces import IObjectHistory, IWAeUPObject
from waeup.sirp.testing import FunctionalTestCase, FunctionalLayer
from waeup.sirp.objecthistory import ObjectHistory

class SampleObject(grok.Model):
    grok.implements(IWAeUPObject)
    pass

class ObjectHistoryTests(FunctionalTestCase):
    # Tests for helpers like get_access_code, disable_accesscode, ...

    layer = FunctionalLayer

    def setUp(self):
        super(ObjectHistoryTests, self).setUp()

        # Prepopulate ZODB
        app = University()
        self.dc_root = tempfile.mkdtemp()
        app['datacenter'].setStoragePath(self.dc_root)

        # Prepopulate the ZODB...
        self.getRootFolder()['app'] = app
        self.app = self.getRootFolder()['app']
        self.obj = SampleObject()

    def tearDown(self):
        shutil.rmtree(self.dc_root)
        super(ObjectHistoryTests, self).tearDown()
        endInteraction() # Just in case, one is still lingering around

    def test_iface(self):
        # ObjectHistory class and instances provide the promised ifaces
        hist = IObjectHistory(self.obj)
        assert verifyObject(IObjectHistory, hist)
        assert verifyClass(IObjectHistory, ObjectHistory)

    def test_adapter(self):
        # We can get a history by adapting to IObjectHistory
        result = IObjectHistory(self.obj)
        assert isinstance(result, ObjectHistory)

    def test_add_messages(self):
        # We can add a message
        hist = IObjectHistory(self.obj)
        assert hist.messages == []
        hist.addMessage('blah')
        assert 'blah' in ''.join(hist.messages)

    def test_add_messages_timestamp_and_user(self):
        # Messages added get a timestamp and the current user
        hist = IObjectHistory(self.obj)
        hist.addMessage('blah')
        result = ''.join(hist.messages)
        self.assertMatches('<YYYY-MM-DD hh:mm:ss> - blah by system', result)

    def test_add_messages_existing_principal(self):
        principal = Principal('bob')
        principal.title = 'Bob'
        newInteraction(Participation(principal)) # set current user
        hist = IObjectHistory(self.obj)
        hist.addMessage('blah')
        result = ''.join(hist.messages)
        self.assertMatches('<YYYY-MM-DD hh:mm:ss> - blah by bob', result)

    def test_messages(self):
        # we get messages as a persistent list of strings
        hist = IObjectHistory(self.obj)
        hist.addMessage('foo')
        hist.addMessage('bar')
        assert isinstance(hist.messages, PersistentList)
        assert 'foo' in hist.messages[0]
        assert 'bar' in hist.messages[1]
