def _add_announcement_and_translation(self, locale, is_draft=False):
        announcement = announcements.AnnouncementEntity()
        announcement.title = 'Test Announcement'
        announcement.html = 'Announcement Content'
        announcement.is_draft = is_draft
        announcement.put()

        key = i18n_dashboard.ResourceBundleKey(
            announcements.ResourceHandlerAnnouncement.TYPE,
            announcement.key().id(), locale)
        dto = i18n_dashboard.ResourceBundleDTO(
            str(key), {
                'title': {
                    'type':
                    'string',
                    'source_value':
                    '',
                    'data': [{
                        'source_value': 'Test Announcement',
                        'target_value': 'TEST ANNOUNCEMENT'
                    }]
                },
                'html': {
                    'type':
                    'string',
                    'source_value':
                    '',
                    'data': [{
                        'source_value': 'Announcement Content',
                        'target_value': 'ANNOUNCEMENT CONTENT'
                    }]
                },
            })
        i18n_dashboard.ResourceBundleDAO.save(dto)
        return announcement
    def test_hook_i18n(self):
        actions.update_course_config(
            COURSE_NAME,
            {
                'html_hooks': {'base': {'after_body_tag_begins': 'foozle'}},
                'extra_locales': [
                    {'locale': 'de', 'availability': 'available'},
                ]
            })

        hook_bundle = {
            'content': {
                'type': 'html',
                'source_value': '',
                'data': [{
                    'source_value': 'foozle',
                    'target_value': 'FUZEL',
                }],
            }
        }
        hook_key = i18n_dashboard.ResourceBundleKey(
            utils.ResourceHtmlHook.TYPE, 'base.after_body_tag_begins', 'de')
        with common_utils.Namespace(NAMESPACE):
            i18n_dashboard.ResourceBundleDAO.save(
                i18n_dashboard.ResourceBundleDTO(str(hook_key), hook_bundle))

        # Verify non-translated version.
        response = self.get(BASE_URL)
        dom = self.parse_html_string(response.body)
        html_hook = dom.find('.//div[@id="base-after-body-tag-begins"]')
        self.assertEquals('foozle', html_hook.text)

        # Set preference to translated language, and check that that's there.
        with common_utils.Namespace(NAMESPACE):
            prefs = models.StudentPreferencesDAO.load_or_default()
            prefs.locale = 'de'
            models.StudentPreferencesDAO.save(prefs)

        response = self.get(BASE_URL)
        dom = self.parse_html_string(response.body)
        html_hook = dom.find('.//div[@id="base-after-body-tag-begins"]')
        self.assertEquals('FUZEL', html_hook.text)

        # With no translation present, but preference set to foreign language,
        # verify that we fall back to the original language.

        # Remove translation bundle, and clear cache.
        with common_utils.Namespace(NAMESPACE):
            i18n_dashboard.ResourceBundleDAO.delete(
                i18n_dashboard.ResourceBundleDTO(str(hook_key), hook_bundle))
        model_caching.CacheFactory.get_cache_instance(
            i18n_dashboard.RESOURCE_BUNDLE_CACHE_NAME).clear()

        response = self.get(BASE_URL)
        dom = self.parse_html_string(response.body)
        html_hook = dom.find('.//div[@id="base-after-body-tag-begins"]')
        self.assertEquals('foozle', html_hook.text)
Exemplo n.º 3
0
 def add_location(self, resource_bundle_key, loc_name, loc_type):
     resource_key = resource_bundle_key.resource_key
     fixed_location_bundle_key = i18n_dashboard.ResourceBundleKey(
         resource_key.type, resource_key.key, self._locale_to_use)
     super(OverriddenLocaleTranslationMessage,
           self).add_location(fixed_location_bundle_key, loc_name, loc_type)
Exemplo n.º 4
0
 def get_message(self, resource_bundle_key, message_key):
     resource_key = resource_bundle_key.resource_key
     resource_bundle_key = i18n_dashboard.ResourceBundleKey(
         resource_key.type, resource_key.key, self._locale_to_use)
     return super(OverriddenLocaleTranslationContents,
                  self).get_message(resource_bundle_key, message_key)
    def test_locale_agnostic_lifecycle(self):
        app_context = self._import_course()
        course = courses.Course(None, app_context=app_context)
        unit = course.add_unit()
        unit.title = 'Title in base language'
        course.save()
        extra_env = {
            'extra_locales': [
                {
                    'locale': 'de',
                    'availability': 'available'
                },
                {
                    'locale': 'fr',
                    'availability': 'available'
                },
            ]
        }
        bundle_key_de = str(
            i18n_dashboard.ResourceBundleKey('unit', str(unit.unit_id), 'de'))
        bundle_key_fr = str(
            i18n_dashboard.ResourceBundleKey('unit', str(unit.unit_id), 'fr'))

        # Do language-agnostic export; should get locale 'gv'.
        with actions.OverriddenEnvironment(extra_env):
            self.run_download_job('--job_args=%s '
                                  '--locale_agnostic '
                                  '--export=all' % self.zipfile_name)

        with zipfile.ZipFile(self.zipfile_name) as zf:
            data = zf.read('locale/%s/LC_MESSAGES/messages.po' %
                           jobs.AGNOSTIC_EXPORT_LOCALE)
        lines = data.split('\n')
        index = lines.index('msgid "Title in base language"')
        self.assertGreater(index, -1)

        # Provide 'translation' for unit title to 'German'.
        lines[index + 1] = 'msgstr "Title in German"'
        data = '\n'.join(lines)
        with zipfile.ZipFile(self.zipfile_name, 'w') as zf:
            zf.writestr(
                'locale/%s/LC_MESSAGES/messages.po' %
                jobs.AGNOSTIC_EXPORT_LOCALE, data)
            zf.close()

        # Run upload, forcing locale to German.
        self.run_upload_job('--job_args=%s --force_locale=de' %
                            self.zipfile_name)

        # Verify that we now have DE translation bundle.
        with common_utils.Namespace(self.NAMESPACE):
            bundle = i18n_dashboard.ResourceBundleDAO.load(bundle_key_de)
            self.assertEquals('Title in German',
                              bundle.dict['title']['data'][0]['target_value'])

        # Also upload to 'fr', which will give us the wrong content, but
        # the user said "--force", so we force it.
        self.run_upload_job('--job_args=%s --force_locale=fr' %
                            self.zipfile_name)

        # Verify that we now have FR translation bundle.
        with common_utils.Namespace(self.NAMESPACE):
            bundle = i18n_dashboard.ResourceBundleDAO.load(bundle_key_fr)
            self.assertEquals('Title in German',
                              bundle.dict['title']['data'][0]['target_value'])

        # Do a locale-agnostic download, specifying all content.
        # Since it's --export=all, we should get the unit title, but
        # since it's locale agnostic, we should get no translated text.
        os.unlink(self.zipfile_name)
        with actions.OverriddenEnvironment(extra_env):
            self.run_download_job('--job_args=%s '
                                  '--locale_agnostic '
                                  '--export=all' % self.zipfile_name)

        with zipfile.ZipFile(self.zipfile_name) as zf:
            data = zf.read('locale/%s/LC_MESSAGES/messages.po' %
                           jobs.AGNOSTIC_EXPORT_LOCALE)
        lines = data.split('\n')
        index = lines.index('msgid "Title in base language"')
        self.assertGreater(index, -1)
        self.assertEquals('msgstr ""', lines[index + 1])

        # Do locale-agnostic download, specifying only new content.
        # We don't specificy locale, which means we should consider
        # 'de' and 'fr'.  But since both of those are up-to-date,
        # we shouldn't see the translation for the unit title even
        # appear in the output file.
        os.unlink(self.zipfile_name)
        with actions.OverriddenEnvironment(extra_env):
            self.run_download_job('--job_args=%s '
                                  '--locale_agnostic '
                                  '--export=new' % self.zipfile_name)

        with zipfile.ZipFile(self.zipfile_name) as zf:
            data = zf.read('locale/%s/LC_MESSAGES/messages.po' %
                           jobs.AGNOSTIC_EXPORT_LOCALE)
        lines = data.split('\n')
        self.assertEquals(0, lines.count('msgid "Title in base language"'))

        # Modify unit title.
        unit = course.find_unit_by_id(unit.unit_id)
        unit.title = 'New and improved title in the base language'
        course.save()

        # Submit a new translation of the changed title, but only for DE.
        os.unlink(self.zipfile_name)
        with actions.OverriddenEnvironment(extra_env):
            self.run_download_job('--job_args=%s '
                                  '--locale_agnostic '
                                  '--locales=de '
                                  '--export=new' % self.zipfile_name)

        with zipfile.ZipFile(self.zipfile_name) as zf:
            data = zf.read('locale/%s/LC_MESSAGES/messages.po' %
                           jobs.AGNOSTIC_EXPORT_LOCALE)
        lines = data.split('\n')
        index = lines.index(
            'msgid "New and improved title in the base language"')
        self.assertGreater(index, -1)
        lines[index + 1] = 'msgstr = "New and improved German title"'
        data = '\n'.join(lines)
        with zipfile.ZipFile(self.zipfile_name, 'w') as zf:
            zf.writestr(
                'locale/%s/LC_MESSAGES/messages.po' %
                jobs.AGNOSTIC_EXPORT_LOCALE, data)
            zf.close()

        # Run upload, forcing locale to German.
        self.run_upload_job('--job_args=%s --force_locale=de' %
                            self.zipfile_name)

        # Locale-agnostic download, for DE only, and only for 'new'
        # items.  Since we've updated the translation bundle since
        # the time we updated the course, we don't expect to see the
        # unit title exported to the .po file.
        os.unlink(self.zipfile_name)
        with actions.OverriddenEnvironment(extra_env):
            self.run_download_job('--job_args=%s '
                                  '--locales=de '
                                  '--locale_agnostic '
                                  '--export=new' % self.zipfile_name)

        with zipfile.ZipFile(self.zipfile_name) as zf:
            data = zf.read('locale/%s/LC_MESSAGES/messages.po' %
                           jobs.AGNOSTIC_EXPORT_LOCALE)
        lines = data.split('\n')
        self.assertEquals(
            0,
            lines.count('msgid "New and improved title in the base language"'))

        # Exact same download, but change 'de' to 'fr'.  Since the FR
        # translation was not updated, we should see that item in the
        # export.
        os.unlink(self.zipfile_name)
        with actions.OverriddenEnvironment(extra_env):
            self.run_download_job('--job_args=%s '
                                  '--locales=fr '
                                  '--locale_agnostic '
                                  '--export=new' % self.zipfile_name)

        with zipfile.ZipFile(self.zipfile_name) as zf:
            data = zf.read('locale/%s/LC_MESSAGES/messages.po' %
                           jobs.AGNOSTIC_EXPORT_LOCALE)
        lines = data.split('\n')
        self.assertEquals(
            1,
            lines.count('msgid "New and improved title in the base language"'))

        # Download again, leaving off the locales argument.  This should
        # find both locales, and in this case, since at least one of the
        # locales has not been updated, we should, again, see that item.
        os.unlink(self.zipfile_name)
        with actions.OverriddenEnvironment(extra_env):
            self.run_download_job('--job_args=%s '
                                  '--locale_agnostic '
                                  '--export=new' % self.zipfile_name)

        with zipfile.ZipFile(self.zipfile_name) as zf:
            data = zf.read('locale/%s/LC_MESSAGES/messages.po' %
                           jobs.AGNOSTIC_EXPORT_LOCALE)
        lines = data.split('\n')
        self.assertEquals(
            1,
            lines.count('msgid "New and improved title in the base language"'))
    def test_localized_search(self):
        def _text(elt):
            return ''.join(elt.itertext())

        dogs_page = """
          <html>
            <body>
              A page about dogs.
            </body>
          </html>"""
        dogs_link = 'http://dogs.null/'
        self.pages[dogs_link + '$'] = (dogs_page, 'text/html')

        dogs_page_fr = """
          <html>
            <body>
              A page about French dogs.
            </body>
          </html>"""
        dogs_link_fr = 'http://dogs_fr.null/'
        self.pages[dogs_link_fr + '$'] = (dogs_page_fr, 'text/html')

        self.base = '/test'
        context = actions.simple_add_course('test', '*****@*****.**',
                                            'Test Course')
        course = courses.Course(None, context)
        actions.login('*****@*****.**')
        actions.register(self, 'Some Admin')

        unit = course.add_unit()
        unit.availability = courses.AVAILABILITY_AVAILABLE
        lesson = course.add_lesson(unit)
        lesson.objectives = 'A lesson about <a href="%s">dogs</a>' % dogs_link
        lesson.availability = courses.AVAILABILITY_AVAILABLE
        course.save()

        lesson_bundle = {
            'objectives': {
                'type':
                'html',
                'source_value':
                ('A lesson about <a href="%s">dogs</a>' % dogs_link),
                'data': [{
                    'source_value':
                    ('A lesson about <a#1 href="%s">dogs</a#1>' % dogs_link),
                    'target_value': ('A lesson about French <a#1 href="%s">'
                                     'dogs</a#1>' % dogs_link_fr)
                }]
            }
        }
        lesson_key_fr = i18n_dashboard.ResourceBundleKey(
            resources_display.ResourceLesson.TYPE, lesson.lesson_id, 'fr')
        with common_utils.Namespace('ns_test'):
            i18n_dashboard.ResourceBundleDAO.save(
                i18n_dashboard.ResourceBundleDTO(str(lesson_key_fr),
                                                 lesson_bundle))

        extra_locales = [{'locale': 'fr', 'availability': 'available'}]
        with actions.OverriddenEnvironment({'extra_locales': extra_locales}):

            self.index_test_course()

            dom = self.parse_html_string(self.get('search?query=dogs').body)
            snippets = dom.findall(
                './/div[@class="gcb-search-result-snippet"]')
            self.assertEquals(2, len(snippets))  # Expect no French hits
            self.assertIn('page about dogs', _text(snippets[0]))
            self.assertIn('lesson about dogs', _text(snippets[1]))

            # Switch locale to 'fr'
            with common_utils.Namespace('ns_test'):
                prefs = models.StudentPreferencesDAO.load_or_default()
                prefs.locale = 'fr'
                models.StudentPreferencesDAO.save(prefs)

            dom = self.parse_html_string(self.get('search?query=dogs').body)
            snippets = dom.findall(
                './/div[@class="gcb-search-result-snippet"]')
            self.assertEquals(2, len(snippets))  # Expect no Engish hits
            self.assertIn('page about French dogs', _text(snippets[0]))
            self.assertIn('lesson about French dogs', _text(snippets[1]))
 def _put_translation(self, data, locale, title, html):
     resource_key = str(
         i18n_dashboard.ResourceBundleKey(
             announcements.ResourceHandlerAnnouncement.TYPE,
             db.Key(encoded=data['key']).id(), locale))
     xsrf_token = crypto.XsrfTokenManager.create_xsrf_token(
         i18n_dashboard.TranslationConsoleRestHandler.XSRF_TOKEN_NAME)
     request = {
         'key':
         resource_key,
         'xsrf_token':
         xsrf_token,
         'validate':
         False,
         'payload':
         transforms.dumps({
             'title':
             'Announcements',
             'key':
             resource_key,
             'source_locale':
             'en_US',
             'target_locale':
             locale,
             'sections': [
                 {
                     'name':
                     'title',
                     'label':
                     'Title',
                     'type':
                     'string',
                     'source_value':
                     '',
                     'data': [{
                         'source_value': data['title'],
                         'target_value': title,
                         'verb': 1,  # verb NEW
                         'old_source_value': '',
                         'changed': True
                     }]
                 },
                 {
                     'name':
                     'html',
                     'label':
                     'Body',
                     'type':
                     'html',
                     'source_value':
                     '',
                     'data': [{
                         'source_value': data['html'],
                         'target_value': html,
                         'verb': 1,  # verb NEW
                         'old_source_value': '',
                         'changed': True
                     }]
                 }
             ]
         })
     }
     response = self.put(
         self.base +
         i18n_dashboard.TranslationConsoleRestHandler.URL.lstrip(),
         {'request': transforms.dumps(request)})
     self.assertEquals(200, response.status_int)
     response = transforms.loads(response.body)
     self.assertEquals(200, response['status'])