Test everything with behaviors

    >>> from Products.CMFCore.utils import getToolByName
    >>> from plone.app.testing import TEST_USER_NAME
    >>> from plone.app.testing import login
    >>> from plone.dexterity.fti import DexterityFTI
    >>> from plone.dexterity.utils import createContentInContainer

    >>> portal = layer['portal']
    >>> login(portal, TEST_USER_NAME)


Helpers:

    >>> def obj2brain(obj):
    ...     catalog = getToolByName(obj, 'portal_catalog')
    ...     query = {'path': {'query': '/'.join(obj.getPhysicalPath()),
    ...                       'depth': 0}}
    ...     brains = catalog(query)
    ...     if len(brains) == 0:
    ...         raise Exception('Not in catalog: %s' % obj)
    ...     else:
    ...         return brains[0]

    >>> def getSearchableText(obj):
    ...     brain = obj2brain(obj)
    ...     catalog = getToolByName(obj, 'portal_catalog')
    ...     data = catalog.getIndexDataForRID(brain.getRID())
    ...     return data['SearchableText']


First test it with a simple behavior:

    >>> from collective.dexteritytextindexer.tests.behaviors import ISimpleBehavior
    >>> fti = DexterityFTI('SimpleFTI')
    >>> fti.behaviors = (
    ...     'collective.dexteritytextindexer.behavior.IDexterityTextIndexer',
    ...     'collective.dexteritytextindexer.tests.behaviors.ISimpleBehavior',
    ... )
    >>> portal.portal_types._setObject('SimpleFTI', fti)
    'SimpleFTI'
    >>> schema = fti.lookupSchema()

    >>> obj1 = createContentInContainer(portal, 'SimpleFTI',
    ...                                 checkContstraints=False,
    ...                                 foo='foox',
    ...                                 bar='barx')
    >>> obj1
    <Item at /plone/simplefti>
    >>> getSearchableText(obj1)
    ['foox']


Test, if the value getter works also, when the request has stored another value for this field.
    >>> schema = fti.lookupSchema()

    >>> portal.REQUEST.form['foo'] = 'blubb'
    >>> obj1 = createContentInContainer(portal, 'SimpleFTI',
    ...                                 checkContstraints=False,
    ...                                 foo='foox',
    ...                                 bar='barx')
    >>> obj1
    <Item at /plone/simplefti-1>
    >>> getSearchableText(obj1)
    ['foox']


Does a list work?

    >>> from collective.dexteritytextindexer.tests.behaviors import IListBehavior
    >>> fti = DexterityFTI('ListFTI')
    >>> fti.behaviors = (
    ...     'collective.dexteritytextindexer.behavior.IDexterityTextIndexer',
    ...     'collective.dexteritytextindexer.tests.behaviors.IListBehavior',
    ... )
    >>> portal.portal_types._setObject('ListFTI', fti)
    'ListFTI'
    >>> schema = fti.lookupSchema()

    >>> obj2 = createContentInContainer(portal, 'ListFTI',
    ...                                 checkContstraints=False,
    ...                                 list_field=['hello', u'little', 'world'])

    >>> obj2
    <Item at /plone/listfti>
    >>> getSearchableText(obj2)
    ['hello', 'little', 'world']


Do ints work?

    >>> from collective.dexteritytextindexer.tests.behaviors import IIntBehavior
    >>> fti = DexterityFTI('IntFTI')
    >>> fti.behaviors = (
    ...     'collective.dexteritytextindexer.behavior.IDexterityTextIndexer',
    ...     'collective.dexteritytextindexer.tests.behaviors.IIntBehavior',
    ... )
    >>> portal.portal_types._setObject('IntFTI', fti)
    'IntFTI'
    >>> schema = fti.lookupSchema()

    >>> obj3 = createContentInContainer(portal, 'IntFTI',
    ...                                 checkContstraints=False,
    ...                                 int_field=57)

    >>> obj3
    <Item at /plone/intfti>

In Plone 4.3 int-values are stored as unicodes.
Since our test should work also for old Plones, we convert everything
to string here:

    >>> map(str, getSearchableText(obj3))
    ['57']


When a schema marks a field as searchable which does not exist it should:
- not break indexing other fields
- log an error

    >>> from collective.dexteritytextindexer.tests.behaviors import IMissingFieldBehavior
    >>> fti = DexterityFTI('MissingFieldFTI')
    >>> fti.behaviors = (
    ...     'collective.dexteritytextindexer.behavior.IDexterityTextIndexer',
    ...     'collective.dexteritytextindexer.tests.behaviors.IMissingFieldBehavior',
    ... )
    >>> portal.portal_types._setObject('MissingFieldFTI', fti)
    'MissingFieldFTI'
    >>> schema = fti.lookupSchema()

    >>> obj = createContentInContainer(portal, 'MissingFieldFTI',
    ...                                checkContstraints=False,
    ...                                foo='foo value')
    >>> obj
    <Item at /plone/missingfieldfti>
    >>> getSearchableText(obj)
    ['foo', 'value']

    >>> 'IMissingFieldBehavior has no field "bar"' in layer['read_log']()
    True


Test, if a subclassed schema also inherits the searchable configuration of
it's superclass:

    >>> from collective.dexteritytextindexer.tests.behaviors import IInheritedBehavior
    >>> fti = DexterityFTI('InheritedFTI')
    >>> fti.behaviors = (
    ...     'collective.dexteritytextindexer.behavior.IDexterityTextIndexer',
    ...     'collective.dexteritytextindexer.tests.behaviors.IInheritedBehavior',
    ... )
    >>> portal.portal_types._setObject('InheritedFTI', fti)
    'InheritedFTI'
    >>> schema = fti.lookupSchema()

    >>> obj1 = createContentInContainer(portal, 'InheritedFTI',
    ...                                 checkContstraints=False,
    ...                                 foo='foo value',
    ...                                 bar='bar value')
    >>> obj1
    <Item at /plone/inheritedfti>
    >>> getSearchableText(obj1)
    ['foo', 'value']
