# -*- coding: iso-8859-15 -*-

import sys
import time
import unittest

glasnostPythonDir = '/usr/local/lib/glasnost-tests'
sys.path.insert(0, glasnostPythonDir)

from GlasnostTestCase import MinimalTestCase

import glasnost

import glasnost.common.faults as faults
import glasnost.common.slots as slots
import glasnost.common.tools_new as commonTools

import glasnost.proxy.CardsProxy as CardsProxy
import glasnost.proxy.kinds as kinds
import glasnost.proxy.properties as properties
from glasnost.proxy.tools import getProxyForServerRole


cardsProxy = getProxyForServerRole('cards')

class KindsTestCase(MinimalTestCase):
    cardId = None
    card = None
    propertiesCount = None
    kindsList = []
    kindsToTest = {}
    goodValues = {}
    badValues = {}

    def setUp(self):
        MinimalTestCase.setUp(self)
        card = CardsProxy.Card()
        card.properties = []
        cardId = cardsProxy.addObject(card)
        self.card = cardsProxy.getObject(cardId)
        self.cardId = cardId
        self.propertiesCount = card.getPropertiesCount()
        self.kindNames = [
                thingClass.getThingName.im_func(thingClass)
                for thingClass in commonTools.getAllThingClasses().values()
                if thingClass.thingCategory == 'kind' \
                and not thingClass.getThingName.im_func(thingClass) in ['Any']]
        
        for kindName in self.kindNames:
            kindObject = commonTools.newThing('kind', kindName)
            self.kindsToTest[kindName] = kindObject
            
            if kindName == 'Sequence':
                kindObject.maxCount = 2
                self.goodValues[kindName] = ['first', 'second']
                self.badValues[kindName] = ['first', 'second', 'third']
            elif kindName == 'IntegerChoice':
                kindObject.values = [1,2]
                self.goodValues[kindName] = 2
                self.badValues[kindName] = 3
            elif kindName == 'Choice':
                kindObject.values = ['first', 'second']
                self.goodValues[kindName] = 'second'
                self.badValues[kindName] = 'third'
            elif kindName == 'Id':
                self.goodValues[kindName] = 'glasnost://articles/2'
                self.badValues[kindName] = 'bad value'
            elif kindName == 'String':
                self.goodValues[kindName] = 'sometext'
                self.badValues[kindName] = 15
            elif kindName == 'Boolean':
                self.goodValues[kindName] = 1
                self.badValues[kindName] = 'sometext'
            elif kindName == 'Time':
                self.goodValues[kindName] = time.time()
                self.badValues[kindName] = 'sometext'

    def tearDown(self):
        try:
            if self.propertiesCount is not None:
                self.failUnlessEqual(self.card.getPropertiesCount(),
                                     self.propertiesCount)
        finally:
            MinimalTestCase.tearDown(self)


class BasicKindsTestCase(KindsTestCase):
    def test01_kindAccepts(self):
        for firstName in self.kindsList:
            firstKind = self.kindsToTest[firstName]
            for secondName in self.kindsList:
                secondKind = self.kindsToTest[secondName]
                if firstName == secondName:
                    self.failUnless(firstKind.accepts(secondKind))
                else:
                    self.failIf(firstKind.accepts(secondKind))


class KindsInCardsTestCase(KindsTestCase):
    def test01_propertyCreationAndDeletion(self):
        """Test property creation and deletion"""

        property = properties.Property()
        property.name = 'stringProperty'
        kind = kinds.String()
        kind.isTranslatable = 0
        property.kind = kind
        self.card.properties.append(property)

        self.failUnlessEqual(
            self.card.getSlot('stringProperty').getKind().getThingName(),
            'String')
        self.failIf(
            self.card.getSlot('stringProperty').getKind().isTranslatable)

        self.card.getSlot('stringProperty').setValue('Hello World')
        self.failUnlessEqual(self.card.getSlot('stringProperty').getValue(),
                             'Hello World')

        self.card.properties.remove(property)

    def test02_kindCheckModelValue(self):
        """Test kind check model value"""

        property = properties.Property()
        for kindName in self.kindNames:
            property.name = 'Testing %s' % kindName
            kind = self.kindsToTest[kindName]
            kind.isRequired = 1
            property.kind = kind
            self.card.properties.append(property)
            slot = self.card.getSlot('Testing %s' % kindName)
            if self.goodValues.has_key(kindName):
                kind.checkModelValue(slot, self.goodValues[kindName])
            try:
                if self.badValues.has_key(kindName):
                    kind.checkModelValue(slot, self.badValues[kindName])
                kind.checkModelValue(slot, None)
            except:
                pass
            else:
                self.fail(kindName)
            self.card.properties.remove(property)


class KindEmailTestCase(MinimalTestCase):
    def test01_none(self):
        '''None as email address'''
        kind = kinds.Email()
        kind.checkModelValue(None, None)

    def test01b_noneWhileRequired(self):
        '''None as email address while it was required'''
        kind = kinds.Email()
        kind.isRequired = 1
        try:
            kind.checkModelValue(None, None)
        except faults.MissingSlotValue:
            pass
        else:
            self.fail('Accepted None while a value was required')

    def test02_emptyString(self):
        '''Empty string as email address'''
        kind = kinds.Email()
        kind.checkModelValue(None, '')

    def test02b_emptyStringWhileRequired(self):
        '''Empty string as email address while it was required'''
        kind = kinds.Email()
        kind.isRequired = 1
        try:
            kind.checkModelValue(None, None)
        except faults.MissingSlotValue:
            pass
        else:
            self.fail('Accepted None while a value was required')

    def test03_erroneousEmails(self):
        '''Several erroneous email addresses'''
        kind = kinds.Email()
        for value in ('fred', 'fred@', '@fred', 'fred @fred', 'fred@ fred',
                      'fred @ fred'):
            try:
                kind.checkModelValue(None, value)
            except faults.BadSlotValue:
                pass
            else:
                self.fail('Accepted erroneous email address')

    def test04_goodEmails(self):
        '''Several good email addresses'''
        kind = kinds.Email()
        for value in ('fred@fred', 'fred@fred.fred', 'fred.fred@fred'):
            kind.checkModelValue(None, value)




suite1 = unittest.makeSuite(BasicKindsTestCase, 'test')
suite2 = unittest.makeSuite(KindsInCardsTestCase, 'test')
suite3 = unittest.makeSuite(KindEmailTestCase, 'test')

allTests = unittest.TestSuite((suite1, suite2, suite3))

if __name__ == '__main__':
    unittest.TextTestRunner(verbosity=2).run(allTests)


