from base import CacheFuTestCase

from Interface.Verify import verifyObject
from Products.Archetypes.public import listTypes
from Products.CMFCore.utils  import getToolByName

from Products.CacheSetup.config import PROJECT_NAME
from Products.CacheSetup.config import CACHE_TOOL_ID
from Products.CacheSetup.interfaces import ICacheTool

# the following may be moved to config.py
from Products.CacheSetup.Extensions.Install import TYPES
from Products.CacheSetup.Extensions.Install import TOOL_TITLE

# util for making content in a container
def makeContent(container, id, portal_type, title=None):
    container.invokeFactory(id=id, type_name=portal_type)
    o = getattr(container, id)
    if title is not None:
        o.setTitle(title)
    return o


# This is the test case. You will have to add test_<methods> to your
# class inorder to assert things about your Product.
class CacheManagerTest(CacheFuTestCase):
    USER1 = 'user1'
    
    def afterSetUp(self):
        CacheFuTestCase.afterSetUp(self)
        
        # Add a couple of users
        self.portal.acl_users._doAddUser('manager', 'secret', ['Manager'], [])
        self.portal.acl_users._doAddUser(self.USER1, 'secret', ['Member'], [])
        self.login('manager')

    def test_install(self):
        cpm = self.portal.caching_policy_manager
        cpm.addPolicy('foo', 'python:0', '', 1, 1, 0, 1, 'foo', '')
        original_class = cpm.__class__
        installed_types = [typeinfo['name'] for typeinfo in listTypes(PROJECT_NAME)]
        # before installation the new types are not in the types factory
        portal_factory = getToolByName(self, 'portal_factory')
        self.assertEqual(set(installed_types).issubset(set(portal_factory.getFactoryTypes())), False)
        self.portal.portal_quickinstaller.installProducts(['CacheSetup'])
        self.portal.portal_quickinstaller.installProducts(['CacheSetup'])
        # now the new types are in the types factory
        self.assertEqual(set(installed_types).issubset(set(portal_factory.getFactoryTypes())), True)
        cpm = self.portal.caching_policy_manager
        self.assertNotEqual(cpm.__class__, original_class)
        #self.failIf('caching_policy_manager' in self.portal.objectIds())
        
        self.portal.portal_quickinstaller.uninstallProducts(['CacheSetup'])
        # now the new types are gone again
        self.assertEqual(set(installed_types).issubset(set(portal_factory.getFactoryTypes())), False)
        cpm = self.portal.caching_policy_manager
        self.assertEqual(cpm.__class__, original_class)
        lp = cpm.listPolicies()
        self.assertEqual(len(lp), 1)
        (id, p) = lp[0]
        self.assertEqual(id, 'foo')
        self.assertEqual(p.getPredicate(), 'python:0')

class TestInstall(CacheFuTestCase):
    """ ensure product is properly installed """

    def afterSetUp(self):
        self.skins     = self.portal.portal_skins
        self.types     = self.portal.portal_types
        self.factory   = self.portal.portal_factory
        self.tool      = self.portal.portal_cache_settings
        self.metaTypes = TYPES

    def testSkinLayersInstalled(self):
        self.failUnless('cache_setup' in self.skins.objectIds())

    def testTypesInstalled(self):
        for t in self.metaTypes:
            self.failUnless(t in self.types.objectIds())

    def testPortalFactorySetup(self):
        for t in self.metaTypes:
            self.failUnless(t in self.factory.getFactoryTypes())

    def testToolInstalled(self):
        self.failUnless(getattr(self.portal, CACHE_TOOL_ID, None) is not None)

    def testToolInterface(self):
        t = self.tool
        self.failUnless(ICacheTool.isImplementedBy(t))
        self.failUnless(verifyObject(ICacheTool, t))

    def testToolNames(self):
        t = self.tool
        self.failUnlessEqual(t.meta_type, 'CacheTool')
        self.failUnlessEqual(t.getId(), CACHE_TOOL_ID)
        self.failUnlessEqual(t.title, TOOL_TITLE)
        self.failUnlessEqual(t.plone_tool, True)

class TestUninstall(CacheFuTestCase):
    """ ensure product is properly uninstalled """

    def afterSetUp(self):
        """ uninstall requieres 'Manager' role """
        self.setRoles(['Manager', 'Member'])
        self.qitool = self.portal.portal_quickinstaller
        self.qitool.uninstallProducts(products=[PROJECT_NAME])

    def testProductUninstalled(self):
        self.failIf(self.qitool.isProductInstalled(PROJECT_NAME))

    def testToolUninstalled(self):
        self.failIf(getattr(self.portal, CACHE_TOOL_ID, None) is not None)

def test_suite():
    from unittest import TestSuite, makeSuite
    suite = TestSuite()
    suite.addTest(makeSuite(CacheManagerTest))
    suite.addTest(makeSuite(TestInstall))
    suite.addTest(makeSuite(TestUninstall))
    return suite
