# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Initial Owner of the Original Code is European Environment
# Agency (EEA).  Portions created by Eau de Web are
# Copyright (C) European Environment Agency.  All
# Rights Reserved.
#
# Authors:
#
# Alex Morega, Eau de Web

from unittest import TestSuite, makeSuite
from Testing import ZopeTestCase

from Acquisition import Implicit
from OFS.SimpleItem import Item

from Products.NaayaBase.NyProperties import NyProperties
from Products.NaayaCore.SchemaTool.Schema import Schema
from Products.NaayaBase.NyContentType import NyContentType, NyContentData
from Products.Localizer.LocalPropertyManager import LocalProperty

def _create_test_schema():
    schema = Schema(id='my_schema', title='my_schema')
    # patch the schema instance so we can add widgets
    schema.gl_get_selected_language = lambda: 'en'
    schema.gl_add_languages = lambda a: None
    schema.addWidget('title', widget_type='String', localized=True)
    schema.addWidget('my_str', widget_type='String')
    schema.addWidget('my_local_str', widget_type='String', localized=True)
    schema.addWidget('my_int', widget_type='String', data_type='int')
    return schema

# why do we import from Implicit? don't know; adding it here to make sure we
# test in realistic conditions
class dummy_item(Implicit, NyContentData, NyProperties):
    # _default_language is needed for Localizer to work
    _default_language = 'en'
    def updatePropertiesFromGlossary(self, lang): pass # override with dummy implementation
    def recatalogNyObject(self, arg): pass # override with dummy implementation
    def gl_get_selected_language(self): return self._default_language
    _schema = _create_test_schema()
    def _get_schema(self): return self._schema

class NyDummy(dummy_item, Item, NyContentType):
    # we inherit from Item, because all Naaya content types do so, and this
    # causes problems with the "title" property (and perhaps others)
    pass

class NyContentTypeTestCase(ZopeTestCase.TestCase):
    """ TestCase for NyContentType base class """

    def test_change_schema_properties(self):
        obj = NyDummy()

        obj._change_schema_properties(my_str='asdf')
        self.failUnlessEqual(obj.my_str, 'asdf')

        obj._change_schema_properties(my_local_str='yes')
        obj._change_schema_properties(my_local_str='oui', _lang='fr')
        self.failUnlessEqual(obj.my_local_str, 'yes')
        self.failUnlessEqual(obj.getLocalProperty('my_local_str', 'fr'), 'oui')

    def test_getattr_inheritance(self):
        obj = NyDummy()
        obj._change_schema_properties(my_str='lala_str', my_local_str='lala_local_str')

        self.failUnlessEqual(obj.my_str, 'lala_str')
        self.failUnlessEqual(obj.my_local_str, 'lala_local_str')

        # Note: my_local_str_en is provided by Localizer's LocalPropertyManager
        # class (not by NyContentData), so if we get the correct value,
        # our __getattr__ inheritance works properly
        self.failUnlessEqual(obj.my_local_str_en, 'lala_local_str')
        self.failUnlessRaises(AttributeError, lambda: obj.xzzx)

    def test_special_properties(self):
        """
        we have to treat title (and also id and maybe others) as a special case
        because they are defined as empty strings on the SimpleItem class, so
        NyContentData's __getattr__ method is never called (this breaks
        localized properties)
        """
        obj = NyDummy()
        obj._change_schema_properties(title='tomorrow')
        obj._change_schema_properties(title='demain', _lang='fr')

        self.failUnlessEqual(obj.title, 'tomorrow')
        self.failUnlessEqual(obj.getLocalProperty('title', 'fr'), 'demain')

        # check that things work well even if title is not a local property
        obj._schema = _create_test_schema()
        obj._schema.getWidget('title').localized = False

        obj._change_schema_properties(title='tomorrow')
        obj._change_schema_properties(title='demain', _lang='fr')

        self.failUnlessEqual(obj.title, 'demain')

    def test_copy_schema_properties(self):
        obj = NyDummy()
        obj._change_schema_properties(title='title_val', my_str='my_str_val',
            my_local_str='my_local_str_val', my_int=13)
        obj._change_schema_properties(my_local_str='my_local_str_fr_val', _lang='fr')

        obj2 = dummy_item()
        obj2.copy_naaya_properties_from(obj)

        self.failUnlessEqual(obj2.title, 'title_val')
        self.failUnlessEqual(obj2.my_str, 'my_str_val')
        self.failUnlessEqual(obj2.my_local_str, 'my_local_str_val')
        self.failUnlessEqual(obj2.getLocalProperty('my_local_str', 'fr'), 'my_local_str_fr_val')
        self.failUnlessEqual(obj2.my_int, 13)

    def test_change_schema_properties(self):
        obj = NyDummy()
        obj._change_schema_properties(my_int="12")
        self.failUnlessEqual(obj.my_int, 12)
        self.failUnlessRaises(ValueError, lambda: obj._change_schema_properties(my_int="3.14"))

    def test_dump_data(self):
        obj = NyDummy()
        obj._change_schema_properties(title='entitle', my_str='somestr',
            my_local_str='enstr', my_int='13', _lang='en')
        obj._change_schema_properties(title='frtitle', my_local_str='frstr', _lang='fr')
        ref_data = {
            'title': {'fr': u'frtitle', 'en': u'entitle'},
            'my_str': u'somestr',
            'my_local_str': {'fr': u'frstr', 'en': u'enstr'},
            'my_int': 13,
        }
        self.assertEqual(dict(obj.dump_data()), ref_data)

def test_suite():
    suite = TestSuite()
    suite.addTest(makeSuite(NyContentTypeTestCase))
    return suite
