plone / plone.app.multilingual

Plone Multilingual Content Add-on
https://pypi.org/project/plone.app.multilingual
19 stars 47 forks source link

using multilingual content in my tests #312

Open iham opened 6 years ago

iham commented 6 years ago

as i develop a tool which uses pam-features, i came across testing them and had to create sample content. which had some strange side-effects.

in testing.py

from plone import api
from plone.app.contenttypes.testing import PLONE_APP_CONTENTTYPES_FIXTURE
from plone.app.multilingual.interfaces import ITranslationManager
from plone.app.testing import TEST_USER_ID
from plone.app.testing import TEST_USER_NAME
from plone.app.testing import FunctionalTesting
from plone.app.testing import IntegrationTesting
from plone.app.testing import PloneSandboxLayer
from plone.app.testing import applyProfile
from plone.app.testing import login
from plone.app.testing import setRoles
from Products.CMFPlone.interfaces import ILanguage

import my.package

class MyPackageLayer(PloneSandboxLayer):
    """Testing Layer for my package"""

    defaultBases = (PLONE_APP_CONTENTTYPES_FIXTURE,)

    def setUpZope(self, app, configurationContext):  # noqa
        """Setting up the Zope Server."""
        # my.package has plone.app.multilingual as a dependency, so i only load my package
        self.loadZCML(package=my.package)

   def setUpPloneSite(self, portal):
        """Setting up Plone Site."""
        applyProfile(portal, 'my.package:default')

        # setup de/en plone site
        ltool = api.portal.get_tool(name='portal_languages')
        ltool.addSupportedLanguage('de')
        ltool.addSupportedLanguage('en')
        ltool.setDefaultLanguage('de')

        # now i have to re-apply the pam to get the lang root and lang independent folders
        # which is a little annoying, but not too bad.
        applyProfile(portal, 'plone.app.multilingual:default')

        setRoles(portal, TEST_USER_ID, ['Manager'])
        login(portal, TEST_USER_NAME)

        for lang, lang_name in ltool.listSupportedLanguages():
            folder = api.content.create(
                container=portal.get(lang),
                type='Folder',
                title=u'A Folder ({0})'.format(lang),
                id=u'a-folder-{0}'.format(lang),
            )
            # as ILanguage(folder).get_language() returns an empty string i have to set that manually.
            # which is annoying too, as i add the object to a language-folder,
            # it should get the language of its parent. like it does, when using the plone ui
            ILanguage(folder).set_language(lang)
            api.content.transition(obj=folder, transition='publish')

        # now i set the translation between those two folders
        tm = ITranslationManager(portal.de.a-folder)
        tm.register_translation('en', portal.en.a-folder)

        # tm.get_translations() returns a dict with 'de' and 'en' as expected
        # {'de': <Folder at /plone/de/a-folder>, 'en': <Folder at /plone/en/a-folder>}

MY_PACKAGE_FIXTURE = MyPackageLayer()

MY_PACKAGE_INTEGRATION_TESTING = IntegrationTesting(
    bases=(MY_PACKAGE_FIXTURE,),
    name='MyPackageLayer:IntegrationTesting',
)

MY_PACKAGE_FUNCTIONAL_TESTING = FunctionalTesting(
    bases=(MY_PACKAGE_FIXTURE,),
    name='MyPackageLayer:FunctionalTesting',
)

in my test_content.py

import unittest

class TestContent(unittest.TestCase):
    """Testing my.package."""

    layer = MY_PACKAGE_FUNCTIONAL_TESTING

    def setUp(self):
        self.portal = self.layer['portal']

    def test_translations(self):
        """lets look for the translations of folder."""
        tm = ITranslationManager(self.portal.de.a-folder)
        # this test fails ...
        self.assertTrue(len(tm.get_translations()) == 2)
        # ... because tm.get_translations() only returns a dict with the translation, but not the context
        #  {'en':  <Folder at /plone/en/a-folder>}

the only thing fixing that was to add this in testing.py after registering the translation. (big thanks to @jensens for helping me on that!)

.
.
.
   def setUpPloneSite(self, portal):
.
.
.
        # now i set the translation between those two folders
        tm = ITranslationManager(portal.de.a-folder)
        tm.register_translation('en', portal.en.a-folder)

        from Products.CMFCore.indexing import processQueue
        processQueue()
        # or by using
        # import transaction
        # transaction.commit()

        # or by simply calling
        # tm.get_translations()
        # without any further usage

seams something is not as the documentation tells me. and why is the language not set, after creating it? (i tried using notify(), which didn't help by any means)

iham commented 6 years ago

about the ILanguage(obj).set_language()

after creating an object inside a lang root folder i tried

all of them don't effect the obj.language or the ILanguage(obj).get_language()

i don't get, why i have to set that manually only because i am in a test. on the plone ui this works just i expect it to.

jensens commented 6 years ago

seems that tm.register_translation('en', portal.en.a-folder) does not query the catalog, so it has to call itself processQueue before.