def test_money_formatter_digit_grouping(): with translation.override("en-US"): assert money(usd(12345678)) == "$12,345,678.00" with translation.override("fi-FI"): assert money(usd(12345678)) == nbsp("12 345 678,00 $") with translation.override("ar-QA"): assert money(usd(12345678)) == nbsp("US$ 12,345,678.00")
def test_raw_sql(self): foo = LocalizedFoo.objects.create(name_de='Antwort', name_en='answer') foo2 = LocalizedFoo.objects.raw('SELECT * FROM composite_field_test_localizedfoo')[0] with translation.override('de'): self.assertEqual(force_text(foo2.name), 'Antwort') with translation.override('en'): self.assertEqual(force_text(foo2.name), 'answer')
def test_question_urls(self): question_1_pk = self.question1.pk question_1_category_pk = self.question1.category_id question_2_pk = self.question2.pk question_2_category_pk = self.question2.category_id with override('en'): question_1 = self.reload(self.question1) question_1_url = question_1.get_absolute_url() question_2 = self.reload(self.question2) question_2_url = question_2.get_absolute_url() self.assertEquals('/en/faq/{cat_pk}-example/{pk}/'.format( cat_pk=question_1_category_pk, pk=question_1_pk), question_1_url) self.assertEquals('/en/faq/{cat_pk}-beispiel2/{pk}/'.format( cat_pk=question_2_category_pk, pk=question_2_pk), question_2_url) with override('de'): question_1 = self.reload(self.question1) question_1_url = question_1.get_absolute_url() question_2 = self.reload(self.question2) question_2_url = question_2.get_absolute_url() self.assertEquals('/de/faq/{cat_pk}-beispiel/{pk}/'.format( cat_pk=question_1_category_pk, pk=question_1_pk), question_1_url) self.assertEquals('/de/faq/{cat_pk}-beispiel2/{pk}/'.format( cat_pk=question_2_category_pk, pk=question_2_pk), question_2_url)
def test_admin_dual(self): SHARED = 'shared_new' TRANS_EN = 'English' TRANS_JA = u'日本語' with self.login_user_context('admin'): url = reverse('admin:app_normal_add') data_en = { 'shared_field': SHARED, 'translated_field': TRANS_EN, 'simplerel-TOTAL_FORMS': '0', 'simplerel-INITIAL_FORMS': '0', 'simplerel-MAX_NUM_FORMS': '0', } data_ja = { 'shared_field': SHARED, 'translated_field': TRANS_JA, 'simplerel-TOTAL_FORMS': '0', 'simplerel-INITIAL_FORMS': '0', 'simplerel-MAX_NUM_FORMS': '0', } with translation.override('en'): response = self.client.post(url, data_en) self.assertEqual(response.status_code, 302) self.assertEqual(Normal.objects.untranslated().count(), self.normal_count + 1) with translation.override('ja'): response = self.client.post(url, data_ja) self.assertEqual(response.status_code, 302) self.assertEqual(Normal.objects.untranslated().count(), self.normal_count + 2) en = Normal.objects.language('en').get(shared_field=SHARED) self.assertEqual(en.shared_field, SHARED) self.assertEqual(en.translated_field, TRANS_EN) ja = Normal.objects.language('ja').get(shared_field=SHARED) self.assertEqual(ja.shared_field, SHARED) self.assertEqual(ja.translated_field, TRANS_JA)
def test_all_translations(self): # Create an unstranslated model and get the translations myadmin = self._get_admin(Normal) obj = Normal.objects.untranslated().create(shared_field="shared") self.assertEqual(myadmin.all_translations(obj), "") # Create a english translated model and make sure the active language # is highlighted in admin with <strong></strong> obj = Normal.objects.language("en").get(pk=self.normal_id[1]) with translation.override('en'): # make sure no the call will not generate a spurious query in assertNumQueries ContentType.objects.get_for_model(Normal) with self.assertNumQueries(1): self.assertTrue(myadmin.all_translations(obj).find("<strong>") != -1) with self.assertNumQueries(1): # Entries should be linked to the corresponding translation page self.assertTrue(myadmin.all_translations(obj).find("?language=en") != -1) with translation.override('th'): with self.assertNumQueries(1): self.assertTrue(myadmin.all_translations(obj).find("<strong>") == -1) # An unsaved object, shouldn't have any translations obj = Normal() self.assertEqual(myadmin.all_translations(obj), "")
def test_edit_collection_name_and_description_multiple_translations(self): self.make_publisher() updates = { 'name': { 'en-US': u'Basta the potato', 'fr': u'Basta la pomme de terre', 'es': u'Basta la pâtätà', 'it': u'Basta la patata' }, 'description': { 'en-US': 'Basta likes potatoes and Le Boulanger', 'fr': 'Basta aime les patates et Le Boulanger', 'es': 'Basta gusta las patatas y Le Boulanger', 'it': 'Basta ama patate e Le Boulanger' } } res, data = self.edit_collection(self.client, **updates) eq_(res.status_code, 200) self.collection = Collection.objects.get(pk=self.collection.pk) for key, value in updates.iteritems(): eq_(getattr(self.collection, key), updates[key]['en-US']) with translation.override('es'): collection_in_es = Collection.objects.get(pk=self.collection.pk) eq_(getattr(collection_in_es, key), updates[key]['es']) with translation.override('fr'): collection_in_fr = Collection.objects.get(pk=self.collection.pk) eq_(getattr(collection_in_fr, key), updates[key]['fr'])
def test_get_object(self): # Check if it returns a model, if there is at least one translation myadmin = self._get_admin(Normal) get_request = self.request_factory.get('/admin/app/normal/') obj = Normal.objects.language("en").get(pk=self.normal_id[1]) with translation.override('en'): self.assertEqual(myadmin.get_object(get_request, obj.pk).pk, self.normal_id[1]) self.assertEqual(myadmin.get_object(get_request, obj.pk).shared_field, NORMAL[1].shared_field) self.assertEqual(myadmin.get_object(get_request, obj.pk).language_code, 'en') self.assertEqual(myadmin.get_object(get_request, obj.pk).translated_field, NORMAL[1].translated_field['en']) with translation.override('th'): self.assertEqual(myadmin.get_object(get_request, obj.pk).pk, self.normal_id[1]) self.assertEqual(myadmin.get_object(get_request, obj.pk).shared_field, NORMAL[1].shared_field) self.assertEqual(myadmin.get_object(get_request, obj.pk).language_code, 'th') self.assertEqual(myadmin.get_object(get_request, obj.pk).translated_field, '') # Check what happens if there is no translations at all obj = Normal.objects.untranslated().create(shared_field="shared") with translation.override('en'): self.assertEqual(myadmin.get_object(get_request, obj.pk).pk, obj.pk) self.assertEqual(myadmin.get_object(get_request, obj.pk).shared_field, obj.shared_field) self.assertEqual(myadmin.get_object(get_request, obj.pk).language_code, 'en') self.assertEqual(myadmin.get_object(get_request, obj.pk).translated_field, '')
def test_prefixed(self): with translation.override('en'): self.assertEqual(reverse('prefixed'), '/en/prefixed/') with translation.override('nl'): self.assertEqual(reverse('prefixed'), '/nl/prefixed/') with translation.override(None): self.assertEqual(reverse('prefixed'), '/%s/prefixed/' % settings.LANGUAGE_CODE)
def test_not_prefixed(self): with translation.override('en'): self.assertEqual(reverse('not-prefixed'), '/not-prefixed/') self.assertEqual(reverse('not-prefixed-included-url'), '/not-prefixed-include/foo/') with translation.override('nl'): self.assertEqual(reverse('not-prefixed'), '/not-prefixed/') self.assertEqual(reverse('not-prefixed-included-url'), '/not-prefixed-include/foo/')
def test_triple(self): normal = Normal.objects.language('en').get(pk=self.normal_id[1]) standard = Standard.objects.get(pk=self.standard_id[1]) simple = SimpleRelated.objects.language('en').create(normal=normal) obj = Normal.objects.language('en').get(standards__pk=standard.pk) self.assertEqual(obj.pk, normal.pk) obj = Normal.objects.language('en').get(simplerel__pk=simple.pk) self.assertEqual(obj.pk, normal.pk) # We created an english Normal object, so we want to make sure that we use 'en' with translation.override('en'): obj = get_translation_aware_manager(Standard).get(normal__simplerel__pk=simple.pk) self.assertEqual(obj.pk, standard.pk) # If we don't use language 'en', it should give DoesNotExist, when using the # translation aware manager with translation.override('ja'): manager = get_translation_aware_manager(Standard) self.assertRaises(Standard.DoesNotExist, manager.get, normal__simplerel__pk=simple.pk) # However, if we don't use the translation aware manager, we can query any # the shared fields in any language, and it should return the object, # even though there is no translated Normal objects with translation.override('ja'): obj = Standard.objects.get(normal__simplerel__pk=simple.pk) self.assertEqual(obj.pk, standard.pk)
def test_iter_deferred_language(self): with translation.override('en'): qs = Normal.objects.language() with translation.override('ja'): for index, obj in enumerate(qs, 1): self.assertEqual(obj.shared_field, NORMAL[index].shared_field) self.assertEqual(obj.translated_field, NORMAL[index].translated_field['ja'])
def test_logentry_change_message(self): """ LogEntry.change_message is stored as a dumped JSON structure to be able to get the message dynamically translated at display time. """ post_data = { 'site': self.site.pk, 'title': 'Changed', 'hist': 'Some content', 'created_0': '2008-03-18', 'created_1': '11:54', } change_url = reverse('admin:admin_utils_article_change', args=[quote(self.a1.pk)]) response = self.client.post(change_url, post_data) self.assertRedirects(response, reverse('admin:admin_utils_article_changelist')) logentry = LogEntry.objects.filter(content_type__model__iexact='article').latest('id') self.assertEqual(logentry.get_change_message(), 'Changed title and hist.') with translation.override('fr'): self.assertEqual(logentry.get_change_message(), 'Title et hist modifié(s).') add_url = reverse('admin:admin_utils_article_add') post_data['title'] = 'New' response = self.client.post(add_url, post_data) self.assertRedirects(response, reverse('admin:admin_utils_article_changelist')) logentry = LogEntry.objects.filter(content_type__model__iexact='article').latest('id') self.assertEqual(logentry.get_change_message(), 'Added.') with translation.override('fr'): self.assertEqual(logentry.get_change_message(), 'Ajout.')
def test_i18n_fallback_language_plural(self): """ The fallback to a language with less plural forms maintains the real language's number of plural forms and correct translations. """ with self.settings(LANGUAGE_CODE='pt'), override('ru'): response = self.client.get('/jsi18n/') self.assertEqual( response.context['catalog']['{count} plural3'], ['{count} plural3 p3', '{count} plural3 p3s', '{count} plural3 p3t'] ) self.assertEqual( response.context['catalog']['{count} plural2'], ['{count} plural2', '{count} plural2s', ''] ) with self.settings(LANGUAGE_CODE='ru'), override('pt'): response = self.client.get('/jsi18n/') self.assertEqual( response.context['catalog']['{count} plural3'], ['{count} plural3', '{count} plural3s'] ) self.assertEqual( response.context['catalog']['{count} plural2'], ['{count} plural2', '{count} plural2s'] )
def test_create_not_enforcing(self): 'Calling save on a new instance with no language_code in cleaned_data' data = { 'shared_field': 'shared', 'translated_field': u'српски', } # no instance, should use current language with translation.override('sr'): form = NormalForm(data) with self.assertNumQueries(2): obj = form.save() with self.assertNumQueries(0): self.assertNotEqual(obj.pk, None) self.assertEqual(obj.language_code, 'sr') self.assertEqual(obj.shared_field, 'shared') self.assertEqual(obj.translated_field, u'српски') # an instance with a translation loaded, should use that with translation.override('en'): form = NormalForm(data, instance=Normal(language_code='sr')) with self.assertNumQueries(2): obj = form.save() with self.assertNumQueries(0): self.assertNotEqual(obj.pk, None) self.assertEqual(obj.language_code, 'sr') self.assertEqual(obj.shared_field, 'shared') self.assertEqual(obj.translated_field, u'српски')
def test_create_municipality(self): self.assertEqual(Organization.unmoderated_objects.real().count(), 0) resp = self.client.post('/fi/organisaatiot/uusi/', { 'name-sv': 'Test Org', 'type': Organization.TYPE_MUNICIPALITY, 'municipalities': [MunicipalityFactory().pk], 'admins': [self.user.pk, ], 'description-fi': 'tadaa', 'description-sv': 'wohoo', 'terms_accepted': True, 'upload_ticket': get_upload_signature() }) self.assertEqual(resp.status_code, 302) self.assertEqual(Organization.unmoderated_objects.real().count(), 1) org = Organization.unmoderated_objects.real().first() self.assertEqual('%s' % org.name, 'Test Org') self.assertEqual('%s' % org.description, 'tadaa') with override(language='fi'): self.assertEqual('%s' % org.name, 'Test Org') self.assertEqual('%s' % org.description, 'tadaa') with override(language='sv'): self.assertEqual('%s' % org.name, 'Test Org') self.assertEqual('%s' % org.description, 'wohoo') with override(language='en'): self.assertEqual('%s' % org.name, 'Test Org') self.assertEqual('%s' % org.description, 'tadaa') self.assertEqual(org.municipalities.count(), 1)
def test_language_display_name(english): english.fullname = "" english.save() # as fullname is not set - this should default to the pycountry name assert ( english.name == get_language_iso_fullname(english.code)) # lets give english a custom name in db english.fullname = "English (bristol twang)" english.save() # as we are translating to server lang, we use lang.fullname # and not the one from pycountry/iso translation assert ( english.name == english.fullname) with translation.override("fr"): # now request lang has changed (and != server lang) # so we get the translated name assert ( english.name == site_languages.get().capitalize( tr_lang(get_language_iso_fullname(english.code)))) with translation.override("en-GB"): # as request lang is also a dialect of english # it uses the lang.fullname assert ( english.name == english.fullname)
def create_default_job_opening(self, translated=False, category=None): # ensure that we always start with english, since it looks # like there is some issues with handling active language # between tests cases run if category is None: category = self.default_category with override('en'): job_opening = JobOpening.objects.create( category=category, **self.default_job_values['en']) api.add_plugin( job_opening.content, 'TextPlugin', 'en', body=self.default_plugin_content['en']) # check if we need a translated job opening if translated: job_opening.create_translation( 'de', **self.default_job_values['de']) with override('de'): api.add_plugin(job_opening.content, 'TextPlugin', 'de', body=self.default_plugin_content['de']) return JobOpening.objects.language('en').get(pk=job_opening.pk)
def test_gateway(self, client): twilio = Twilio() client.assert_called_with('SID', 'TOKEN') for code in ['654321', '054321', '87654321', '07654321']: twilio.make_call(device=Mock(number=PhoneNumber.from_string('+123')), token=code) client.return_value.calls.create.assert_called_with( from_='+456', to='+123', method='GET', timeout=15, url='http://testserver/twilio/inbound/two_factor/%s/?locale=en-us' % code) twilio.send_sms(device=Mock(number=PhoneNumber.from_string('+123')), token=code) client.return_value.messages.create.assert_called_with( to='+123', body='Your authentication token is %s' % code, from_='+456') client.return_value.calls.create.reset_mock() with translation.override('en-gb'): twilio.make_call(device=Mock(number=PhoneNumber.from_string('+123')), token=code) client.return_value.calls.create.assert_called_with( from_='+456', to='+123', method='GET', timeout=15, url='http://testserver/twilio/inbound/two_factor/%s/?locale=en-gb' % code) client.return_value.calls.create.reset_mock() with translation.override('en-gb'): twilio.make_call(device=Mock(number=PhoneNumber.from_string('+123')), token=code) client.return_value.calls.create.assert_called_with( from_='+456', to='+123', method='GET', timeout=15, url='http://testserver/twilio/inbound/two_factor/%s/?locale=en-gb' % code)
def test_translated_attribute_delete(self): """ Translated attribute delete behaviors """ # Delete a translated field with a translation loaded obj = Normal.objects.language("en").get(pk=self.normal_id[1]) with self.assertNumQueries(0): del obj.translated_field if django.VERSION >= (1, 10): # on version 1.10 and newer, this refreshes from db with self.assertNumQueries(1): self.assertEqual(obj.translated_field, NORMAL[1].translated_field['en']) else: with self.assertNumQueries(0): self.assertRaises(AttributeError, getattr, obj, 'translated_field') # Delete a translated field without a translation loaded, AUTOLOAD is false obj = Normal.objects.untranslated().get(pk=self.normal_id[1]) with self.assertNumQueries(0): with self.settings(HVAD={'AUTOLOAD_TRANSLATIONS': False}): self.assertRaises(AttributeError, delattr, obj, 'translated_field') # Delete translated attribute without a translation loaded, AUTOLOAD is true and one exists obj = Normal.objects.untranslated().get(pk=self.normal_id[1]) with self.assertNumQueries(1): with translation.override('en'): del obj.translated_field # Delete translated attribute without a translation loaded, AUTOLOAD is true but none exists obj = Normal.objects.untranslated().get(pk=self.normal_id[1]) with self.assertNumQueries(1): with self.settings(HVAD={'AUTOLOAD_TRANSLATIONS': True}), translation.override('fr'): self.assertRaises(AttributeError, delattr, obj, 'translated_field')
def get_region(region_code="GL", language_code="en"): """ Get a corresponding Region and language, if active. - if the specified language is not active for that region, try the default_language - if the default_language is not active for that region fall back to Global - English :param region_code: two letter region code, usually from URL :param language_code: two letter language code, usually from URL :return: Region and the fallback language code """ available_languages = [lang[0] for lang in settings.LANGUAGES] try: region = Region.objects.get(code=region_code.upper()) # For bogus language_code set to default_language for that region. if language_code not in available_languages: language_code = region.default_language with override(language_code.lower()): if region.active: return region, language_code # Language not active for the specified language_code, try to fall back to default_language. with override(region.default_language): if region.active: return region, region.default_language except Region.DoesNotExist: pass # Region does not exist or not active for the selected language, or the default language. region = Region.objects.get(code='GL') return region, 'en'
def test_translated_attribute_get(self): """ Translated attribute get behaviors """ # Get translated attribute on class itself DEFAULT = 'world' class MyDescriptorTestModel(TranslatableModel): translations = TranslatedFields( hello = models.CharField(default=DEFAULT, max_length=128) ) self.assertEqual(MyDescriptorTestModel.hello, DEFAULT) # Get translated attribute with a translation loaded obj = Normal.objects.language("en").get(pk=self.normal_id[1]) with self.assertNumQueries(0): self.assertEqual(obj.translated_field, NORMAL[1].translated_field['en']) # Get translated attribute without a translation loaded, AUTOLOAD is false obj = Normal.objects.untranslated().get(pk=self.normal_id[1]) with self.assertNumQueries(0): with self.settings(HVAD={'AUTOLOAD_TRANSLATIONS': False}): self.assertRaises(AttributeError, getattr, obj, 'translated_field') # Get translated attribute without a translation loaded, AUTOLOAD is true and one exists obj = Normal.objects.untranslated().get(pk=self.normal_id[1]) with self.assertNumQueries(1): with self.settings(HVAD={'AUTOLOAD_TRANSLATIONS': True}), translation.override('ja'): self.assertEqual(obj.translated_field, NORMAL[1].translated_field['ja']) # Get translated attribute without a translation loaded, AUTOLOAD is true but none exists obj = Normal.objects.untranslated().get(pk=self.normal_id[1]) with self.assertNumQueries(1): with self.settings(HVAD={'AUTOLOAD_TRANSLATIONS': True}), translation.override('fr'): self.assertRaises(AttributeError, getattr, obj, 'translated_field')
def test_translated_attribute_set(self): """ Translated attribute set behaviors """ # Set translated attribute with a translation loaded obj = Normal.objects.language("en").get(pk=self.normal_id[1]) trans = get_cached_translation(obj) with self.assertNumQueries(0): obj.translated_field = 'foo' self.assertNotIn('translated_field', obj.__dict__) self.assertEqual(trans.__dict__['translated_field'], 'foo') # Set translated attribute without a translation loaded, AUTOLOAD is false obj = Normal.objects.untranslated().get(pk=self.normal_id[1]) with self.assertNumQueries(0): with self.settings(HVAD={'AUTOLOAD_TRANSLATIONS': False}): self.assertRaises(AttributeError, setattr, obj, 'translated_field', 'foo') # Set translated attribute without a translation loaded, AUTOLOAD is true and one exists obj = Normal.objects.untranslated().get(pk=self.normal_id[1]) with self.assertNumQueries(1): with self.settings(HVAD={'AUTOLOAD_TRANSLATIONS': True}), translation.override('ja'): obj.translated_field = 'foo' trans = get_cached_translation(obj) self.assertNotIn('translated_field', obj.__dict__) self.assertEqual(trans.__dict__['translated_field'], 'foo') # Set translated attribute without a translation loaded, AUTOLOAD is true but none exists obj = Normal.objects.untranslated().get(pk=self.normal_id[1]) with self.assertNumQueries(1): with self.settings(HVAD={'AUTOLOAD_TRANSLATIONS': True}), translation.override('fr'): self.assertRaises(AttributeError, setattr, obj, 'translated_field', 'foo')
def test_view_excel_file_sorted(self): semester = mommy.make(Semester) course_type = mommy.make(CourseType) course1 = mommy.make(Course, state='published', type=course_type, name_de='A - Course1', name_en='B - Course1', semester=semester) course2 = mommy.make(Course, state='published', type=course_type, name_de='B - Course2', name_en='A - Course2', semester=semester) mommy.make(Contribution, course=course1, responsible=True, can_edit=True, comment_visibility=Contribution.ALL_COMMENTS) mommy.make(Contribution, course=course2, responsible=True, can_edit=True, comment_visibility=Contribution.ALL_COMMENTS) content_de = BytesIO() with translation.override("de"): ExcelExporter(semester).export(content_de, [[course_type.id]], True, True) content_en = BytesIO() with translation.override("en"): ExcelExporter(semester).export(content_en, [[course_type.id]], True, True) content_de.seek(0) content_en.seek(0) # Load responses as Excel files and check for correct sorting workbook = xlrd.open_workbook(file_contents=content_de.read()) self.assertEqual(workbook.sheets()[0].row_values(0)[1], "A - Course1") self.assertEqual(workbook.sheets()[0].row_values(0)[2], "B - Course2") workbook = xlrd.open_workbook(file_contents=content_en.read()) self.assertEqual(workbook.sheets()[0].row_values(0)[1], "A - Course2") self.assertEqual(workbook.sheets()[0].row_values(0)[2], "B - Course1")
def test_language(self): """ if the wrong language is set in the url we should get a redirect to the main homepage """ title = 'French Blog Post' post = Post.objects.create( title=title, slug='french-post', author=self.user, language='fr', ) with override('fr'): # List View url = reverse('aldryn_blog:latest-posts') response = self.client.get(url) self.assertContains(response, title) # Detail View url = post.get_absolute_url() response = self.client.get(url) self.assertContains(response, title) with override('en'): # List View url = reverse('aldryn_blog:latest-posts') response = self.client.get(url) self.assertNotContains(response, title) with self.settings(ALDRYN_BLOG_SHOW_ALL_LANGUAGES=True): response = self.client.get(url) self.assertContains(response, title)
def test_momentjs_locale(self): """momentjs_locale adds MOMENTJS_LOCALE_URL to context""" with translation.override('no-no'): self.assertEqual( context_processors.momentjs_locale(True), { 'MOMENTJS_LOCALE_URL': None, } ) with translation.override('en-us'): self.assertEqual( context_processors.momentjs_locale(True), { 'MOMENTJS_LOCALE_URL': None, } ) with translation.override('de'): self.assertEqual( context_processors.momentjs_locale(True), { 'MOMENTJS_LOCALE_URL': 'misago/momentjs/de.js', } ) with translation.override('pl-de'): self.assertEqual( context_processors.momentjs_locale(True), { 'MOMENTJS_LOCALE_URL': 'misago/momentjs/pl.js', } )
def test_not_prefixed(self): with translation.override("en"): self.assertEqual(reverse("not-prefixed"), "/not-prefixed/") self.assertEqual(reverse("not-prefixed-included-url"), "/not-prefixed-include/foo/") with translation.override("nl"): self.assertEqual(reverse("not-prefixed"), "/not-prefixed/") self.assertEqual(reverse("not-prefixed-included-url"), "/not-prefixed-include/foo/")
def test_prefixed(self): with translation.override("en"): self.assertEqual(reverse("prefixed"), "/en/prefixed/") with translation.override("nl"): self.assertEqual(reverse("prefixed"), "/nl/prefixed/") with translation.override(None): self.assertEqual(reverse("prefixed"), "/%s/prefixed/" % settings.LANGUAGE_CODE)
def test_regression_3600(self): # Tests for form i18n # # There were some problems with form translations in #3600 class SomeForm(Form): username = CharField(max_length=10, label=ugettext_lazy('username')) f = SomeForm() self.assertHTMLEqual( f.as_p(), '<p><label for="id_username">username:</label>' '<input id="id_username" type="text" name="username" maxlength="10" required /></p>' ) # Translations are done at rendering time, so multi-lingual apps can define forms) with translation.override('de'): self.assertHTMLEqual( f.as_p(), '<p><label for="id_username">Benutzername:</label>' '<input id="id_username" type="text" name="username" maxlength="10" required /></p>' ) with translation.override('pl'): self.assertHTMLEqual( f.as_p(), '<p><label for="id_username">u\u017cytkownik:</label>' '<input id="id_username" type="text" name="username" maxlength="10" required /></p>' )
def setUp(self): self.template = get_cms_setting('TEMPLATES')[0][0] self.language = settings.LANGUAGES[0][0] self.page = api.create_page( 'page', self.template, self.language, published=True) self.placeholder = self.page.placeholders.all()[0] self.superuser = self.create_superuser() with override('en'): self.person1 = Person(**self.data['person1']['en']) self.group1 = Group(**self.data['group1']['en']) self.person1.name = 'person1' self.person1.slug = 'person1-slug' self.person1.save() self.group1.save() # Add a DE translation for person1, group1 self.mktranslation(self.person1, 'de', **self.data['person1']['de']) self.mktranslation(self.group1, 'de', **self.data['group1']['de']) # Make person2, group2 with override('de'): self.person2 = Person(**self.data['person2']['de']) self.group2 = Group(**self.data['group2']['de']) self.person2.name = 'person2' self.person2.slug = 'person2-slug' self.person2.save() self.group2.save()
def test_view_excel_file_sorted(self): semester = mommy.make(Semester) course_type = mommy.make(CourseType) mommy.make(Evaluation, state='published', course=mommy.make(Course, type=course_type, semester=semester, name_de="A", name_en="B"), name_de='Evaluation1', name_en='Evaluation1') mommy.make(Evaluation, state='published', course=mommy.make(Course, type=course_type, semester=semester, name_de="B", name_en="A"), name_de='Evaluation2', name_en='Evaluation2') content_de = BytesIO() with translation.override("de"): ExcelExporter(semester).export(content_de, [[course_type.id]], True, True) content_en = BytesIO() with translation.override("en"): ExcelExporter(semester).export(content_en, [[course_type.id]], True, True) content_de.seek(0) content_en.seek(0) # Load responses as Excel files and check for correct sorting workbook = xlrd.open_workbook(file_contents=content_de.read()) self.assertEqual(workbook.sheets()[0].row_values(0)[1], "A – Evaluation1") self.assertEqual(workbook.sheets()[0].row_values(0)[2], "B – Evaluation2") workbook = xlrd.open_workbook(file_contents=content_en.read()) self.assertEqual(workbook.sheets()[0].row_values(0)[1], "A – Evaluation2") self.assertEqual(workbook.sheets()[0].row_values(0)[2], "B – Evaluation1")
def test_i18n23(self): """Using filters with the {% trans %} tag (#5972).""" with translation.override('de'): output = self.engine.render_to_string('i18n23') self.assertEqual(output, 'nicht gefunden')
def test_i18n09(self): """simple non-translation (only marking) of a string to German""" with translation.override('de'): output = self.engine.render_to_string('i18n09') self.assertEqual(output, 'Page not found')
def test_number_formatters_en(): with translation.override("en-US"): assert percent(Decimal("0.38")) == "38%" assert number(Decimal("38.00000")) == "38" assert number(Decimal("38.05000")) == "38.05"
if size > settings.LANGPACK_MAX_SIZE: raise Exception('Response to big') chunks.append(chunk) except Exception, e: log.error('[@None] Error fetching "{0}" language pack: {1}'.format( xpi, e)) return upload = FileUpload() upload.add_file(chunks, xpi, size) lang = os.path.splitext(xpi)[0] # Activate the correct locale for the language pack so it # will be used as the add-on's default locale if available. with translation.override(lang): try: data = parse_addon(upload, minimal=True) allowed_guid = re.compile(r'^langpack-{0}@' r'[a-z]+\.mozilla\.org$'.format(lang)) assert allowed_guid.match(data['guid']), 'Unexpected GUID' except Exception, e: log.error('[@None] Error parsing "{0}" language pack: {1}'.format( xpi, e), exc_info=sys.exc_info()) return try: addon = Addon.objects.get(guid=data['guid']) except Addon.DoesNotExist:
def addon_factory(status=amo.STATUS_APPROVED, version_kw=None, file_kw=None, **kw): version_kw = version_kw or {} # Disconnect signals until the last save. post_save.disconnect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') post_save.disconnect(update_es_for_promoted, sender=PromotedAddon, dispatch_uid='addons.search.index') post_save.disconnect( update_es_for_promoted_approval, sender=PromotedApproval, dispatch_uid='addons.search.index', ) type_ = kw.pop('type', amo.ADDON_EXTENSION) popularity = kw.pop('popularity', None) tags = kw.pop('tags', []) users = kw.pop('users', []) when = _get_created(kw.pop('created', None)) category = kw.pop('category', None) default_locale = kw.get('default_locale', settings.LANGUAGE_CODE) # Keep as much unique data as possible in the uuid: '-' aren't important. name = kw.pop('name', 'Addôn %s' % str(uuid.uuid4()).replace('-', '')) slug = kw.pop('slug', None) if slug is None: slug = name.replace(' ', '-').lower()[:30] promoted_group = kw.pop('promoted', None) kwargs = { # Set artificially the status to STATUS_APPROVED for now, the real # status will be set a few lines below, after the update_version() # call. This prevents issues when calling addon_factory with # STATUS_DELETED. 'status': amo.STATUS_APPROVED, 'default_locale': default_locale, 'name': name, 'slug': slug, 'average_daily_users': popularity or random.randint(200, 2000), 'weekly_downloads': popularity or random.randint(200, 2000), 'created': when, 'last_updated': when, } if 'summary' not in kw: # Assign a dummy summary if none was specified in keyword args. kwargs['summary'] = 'Summary for %s' % name kwargs['guid'] = kw.pop('guid', '{%s}' % str(uuid.uuid4())) kwargs.update(kw) # Save 1. with translation.override(default_locale): addon = Addon.objects.create(type=type_, **kwargs) # Save 2. if promoted_group: PromotedAddon.objects.create(addon=addon, group_id=promoted_group.id) if 'promotion_approved' not in version_kw: version_kw['promotion_approved'] = True version = version_factory(file_kw, addon=addon, **version_kw) addon.update_version() # version_changed task will be triggered and will update last_updated in # database for this add-on depending on the state of the version / files. # We're calling the function it uses to compute the value ourselves and= # sticking that into the attribute ourselves so that we already have the # correct value in the instance we are going to return. # Note: the aim is to have the instance consistent with what will be in the # database because of the task, *not* to be consistent with the status of # the add-on. Because we force the add-on status without forcing the status # of the latest file, the value we end up with might not make sense in some # cases. addon.last_updated = compute_last_updated(addon) addon.status = status for tag in tags: Tag.objects.get_or_create(tag_text=tag)[0].add_tag(addon) for user in users: addon.addonuser_set.create(user=user) application = version_kw.get('application', amo.FIREFOX.id) if not category and addon.type in CATEGORIES[application]: category = random.choice( list(CATEGORIES[application][addon.type].values())) if category: AddonCategory.objects.create(addon=addon, category=category) # Put signals back. post_save.connect(addon_update_search_index, sender=Addon, dispatch_uid='addons.search.index') post_save.connect(update_es_for_promoted, sender=PromotedAddon, dispatch_uid='addons.search.index') post_save.connect( update_es_for_promoted_approval, sender=PromotedApproval, dispatch_uid='addons.search.index', ) # Save 4. addon.save() if addon.guid: AddonGUID.objects.create(addon=addon, guid=addon.guid) # Potentially update is_public on authors [user.update_is_public() for user in users] if 'nomination' in version_kw: # If a nomination date was set on the version, then it might have been # erased at post_save by addons.models.watch_status() version.save() return addon
def _setup_pages(cls, config): """ Create the page structure. It created a home page (if not exists) and a sub-page, and attach the Apphook to the sub-page. Pages titles are provided by ``AutoCMSAppMixin.auto_setup`` :param setup_config: boolean to control whether creating the ApphookConfig instance """ from cms.exceptions import NoHomeFound from cms.models import Page from cms.utils import get_language_list from django.conf import settings from django.utils.translation import override app_page = None get_url = False if getattr(settings, 'ALDRYN_SEARCH_CMS_PAGE', False): from aldryn_search.search_indexes import TitleIndex def fake_url(self, obj): return '' get_url = TitleIndex.get_url TitleIndex.get_url = fake_url site = Site.objects.get_current() auto_sites = cls.auto_setup.get('sites', True) if auto_sites is True or site.pk in auto_sites: if getattr(cls, 'app_config', False): configs = cls.app_config.objects.all() if not configs.exists(): config = cls._create_config() else: config = configs.first() langs = get_language_list(site.pk) if not Page.objects.on_site( site.pk).filter(application_urls=cls.__name__).exists(): for lang in langs: with override(lang): if config: if cls.auto_setup['config_translated_fields']: cls._create_config_translation(config, lang) namespace = config.namespace elif cls.app_name: namespace = cls.app_name else: namespace = None try: home = Page.objects.get_home( site.pk).get_draft_object() except NoHomeFound: home = None set_home = hasattr(Page, 'set_as_homepage') home = cls._create_page(home, lang, cls.auto_setup['home title'], site=site, set_home=set_home) app_page = cls._create_page( app_page, lang, cls.auto_setup['page title'], cls.__name__, home, namespace, site=site) if get_url: TitleIndex.get_url = get_url
def update_grade_data_from_grading_form_v2(self, request, page_context, page_data, grade_data, grading_form, files_data): if grade_data is None: grade_data = {} for k in self.grade_data_attrs: if k == "grade_percent": grade_data[k] = grading_form.cleaned_percent() else: grade_data[k] = grading_form.cleaned_data[k] if grading_form.cleaned_data["notify"] and page_context.flow_session: with translation.override(settings.RELATE_ADMIN_EMAIL_LOCALE): from django.template.loader import render_to_string from course.utils import will_use_masked_profile_for_email staff_email = [ page_context.course.notify_email, request.user.email ] message = render_to_string( "course/grade-notify.txt", { "page_title": self.title(page_context, page_data), "course": page_context.course, "participation": page_context.flow_session.participation, "feedback_text": grade_data["feedback_text"], "flow_session": page_context.flow_session, "review_uri": page_context.page_uri, "use_masked_profile": will_use_masked_profile_for_email(staff_email) }) from django.core.mail import EmailMessage msg = EmailMessage( string_concat("[%(identifier)s:%(flow_id)s] ", _("New notification")) % { 'identifier': page_context.course.identifier, 'flow_id': page_context.flow_session.flow_id }, message, getattr(settings, "GRADER_FEEDBACK_EMAIL_FROM", page_context.course.get_from_email()), [page_context.flow_session.participation.user.email]) msg.bcc = [page_context.course.notify_email] if grading_form.cleaned_data["may_reply"]: msg.reply_to = [request.user.email] if hasattr(settings, "GRADER_FEEDBACK_EMAIL_FROM"): from relate.utils import get_outbound_mail_connection msg.connection = get_outbound_mail_connection( "grader_feedback") msg.send() if (grading_form.cleaned_data["notes"] and grading_form.cleaned_data["notify_instructor"] and page_context.flow_session): with translation.override(settings.RELATE_ADMIN_EMAIL_LOCALE): from django.template.loader import render_to_string from course.utils import will_use_masked_profile_for_email staff_email = [ page_context.course.notify_email, request.user.email ] message = render_to_string( "course/grade-internal-notes-notify.txt", { "page_title": self.title(page_context, page_data), "course": page_context.course, "participation": page_context.flow_session.participation, "notes_text": grade_data["notes"], "flow_session": page_context.flow_session, "review_uri": page_context.page_uri, "sender": request.user, "use_masked_profile": will_use_masked_profile_for_email(staff_email) }) from django.core.mail import EmailMessage msg = EmailMessage( string_concat("[%(identifier)s:%(flow_id)s] ", _("Grading notes from %(ta)s")) % { 'identifier': page_context.course.identifier, 'flow_id': page_context.flow_session.flow_id, 'ta': request.user.get_full_name() }, message, getattr(settings, "GRADER_FEEDBACK_EMAIL_FROM", page_context.course.get_from_email()), [page_context.course.notify_email]) msg.bcc = [request.user.email] msg.reply_to = [request.user.email] if hasattr(settings, "GRADER_FEEDBACK_EMAIL_FROM"): from relate.utils import get_outbound_mail_connection msg.connection = get_outbound_mail_connection( "grader_feedback") msg.send() return grade_data
def test_number_formatters_fi(): with translation.override("fi-FI"): assert percent(Decimal("0.38")) == nbsp("38 %") assert number(Decimal("38.00000")) == "38" assert number(Decimal("38.05000")) == "38,05"
def test_language_preserved(self): with translation.override('fr'): management.call_command('dance', verbosity=0) self.assertEqual(translation.get_language(), 'fr')
def test_money_formatter_default_digit_expanding(): with translation.override("en-US"): assert money(usd(0)) == "$0.00" assert money(usd(1)) == "$1.00"
def get_wanted_auto_events(self, ar=None): wanted = dict() unwanted = dict() rset = self.has_auto_events() if rset is None: return wanted, unwanted qs = self.get_existing_auto_events() qs = qs.order_by('start_date', 'start_time', 'auto_type') # Find the existing event before the first unmodified # event. This is where the algorithm will start. event_no = 0 date = None # if qs.count(): # raise Exception("20180321 {}".format(qs.count())) for ee in qs: if ee.is_user_modified(): event_no = ee.auto_type # date = ee.start_date date = rset.get_next_suggested_date(ar, ee.start_date) else: break if event_no is not None: qs = qs.filter(auto_type__gt=event_no) if date is None: date = self.update_cal_from(ar) if not date: ar.info("No start date") return wanted, unwanted # Loop over existing events to fill the unwanted dict. In the # beginning all existing events are unwanted. Afterwards we # will pop wanted events from this dict. for ee in qs: unwanted[ee.auto_type] = ee event_type = self.update_cal_event_type() if event_type is None: # raise Exception("20170731") ar.warning( _("No automatic calendar entries because no entry type is configured" )) return wanted, unwanted # ar.debug("20140310a %s", date) date = rset.find_start_date(date) # ar.debug("20140310b %s", date) if date is None: ar.info("No available start date.") return wanted, unwanted until = self.update_cal_until() \ or dd.plugins.cal.ignore_dates_after if until is None: raise Exception("ignore_dates_after may not be None") # don't take rset.max_events == 0 as False if rset.max_events is None: max_events = settings.SITE.site_config.max_auto_events else: max_events = rset.max_events Event = settings.SITE.models.cal.Event ar.info("Generating events between %s and %s (max. %s).", date, until, max_events) ignore_before = dd.plugins.cal.ignore_dates_before user = self.get_events_user() # if max_events is not None and event_no >= max_events: # raise Exception("20180321") with translation.override(self.get_events_language()): while max_events is None or event_no < max_events: if date > until: ar.info("Reached upper date limit %s for %s", until, event_no) break event_no += 1 if ignore_before and date < ignore_before: ar.info("Ignore %d because it is before %s", event_no, ignore_before) else: we = Event(auto_type=event_no, user=user, start_date=date, summary=self.update_cal_summary( event_type, event_no), room=self.update_cal_room(event_no), owner=self, event_type=event_type, start_time=rset.start_time, end_time=rset.end_time) self.setup_auto_event(we) date = self.resolve_conflicts(we, ar, rset, until) if date is None: ar.info("Could not resolve conflicts for %s", event_no) return wanted, unwanted ee = unwanted.pop(event_no, None) if ee is None: wanted[event_no] = we elif ee.is_user_modified(): ar.debug("%s has been moved from %s to %s." % (ee.summary, date, ee.start_date)) date = ee.start_date else: rset.compare_auto_event(ee, we) # we don't need to add it to wanted because # compare_auto_event() saves any changes # immediately. # wanted[event_no] = we date = rset.get_next_suggested_date(ar, date) date = rset.find_start_date(date) if date is None: ar.info("Could not find next date after %s.", event_no) break return wanted, unwanted
def validate_voice_locale(locale): with translation.override(locale): voice_locale = pgettext('twilio_locale', 'en') if voice_locale not in VOICE_LANGUAGES: raise NotImplementedError('The language "%s" is not ' 'supported by Twilio' % voice_locale)
def render(self, context): with translation.override(self.language.resolve(context)): output = self.nodelist.render(context) return output
def compare_valuedict_to_gloss(valuedict, gloss): """Takes a dict of arbitrary key-value pairs, and compares them to a gloss""" #Create an overview of all fields, sorted by their human name with override(LANGUAGE_CODE): fields = {field.verbose_name: field for field in gloss._meta.fields} differences = [] #Go through all values in the value dict, looking for differences with the gloss for human_key, new_human_value in valuedict.items(): new_human_value = new_human_value.strip() #This fixes a casing problem that sometimes shows up if human_key.lower() == 'id gloss': human_key = 'ID Gloss' #If these are not fields, but relations to other parts of the database, go look for differenes elsewhere if human_key == 'Keywords': current_keyword_string = str(', '.join([ translation.translation.text.encode('utf-8') for translation in gloss.translation_set.all() ])) if current_keyword_string != new_human_value: differences.append({ 'pk': gloss.pk, 'idgloss': gloss.idgloss, 'machine_key': human_key, 'human_key': human_key, 'original_machine_value': current_keyword_string, 'original_human_value': current_keyword_string, 'new_machine_value': new_human_value, 'new_human_value': new_human_value }) #If not, find the matching field in the gloss, and remember its 'real' name try: field = fields[human_key] machine_key = field.name except KeyError: continue #Try to translate the value to machine values if needed if len(field.choices) > 0: human_to_machine_values = { human_value: machine_value for machine_value, human_value in field.choices } try: new_machine_value = human_to_machine_values[ new_human_value] except KeyError: #If you can't find a corresponding human value, maybe it's empty if new_human_value in ['', ' ']: new_human_value = 'None' new_machine_value = None #If not, stop trying else: raise MachineValueNotFoundError( 'At ' + gloss.idgloss + ' (' + str(gloss.pk) + '), could not find option ' + str(new_human_value) + ' for ' + human_key) #Do something special for integers and booleans elif field.__class__.__name__ == 'IntegerField': try: new_machine_value = int(new_human_value) except ValueError: new_human_value = 'None' new_machine_value = None elif field.__class__.__name__ == 'NullBooleanField': if new_human_value in ['True', 'true']: new_machine_value = True else: new_machine_value = False #If all the above does not apply, this is a None value or plain text else: if new_human_value == 'None': new_machine_value = None else: new_machine_value = new_human_value #Try to translate the key to machine keys if possible try: original_machine_value = getattr(gloss, machine_key) except KeyError: continue #Translate back the machine value from the gloss try: original_human_value = dict( field.choices)[original_machine_value] except KeyError: original_human_value = original_machine_value #Remove any weird char try: new_machine_value = unescape(new_machine_value) new_human_value = unescape(new_human_value) except TypeError: pass #Check for change, and save your findings if there is one if original_machine_value != new_machine_value: differences.append({ 'pk': gloss.pk, 'idgloss': gloss.idgloss, 'machine_key': machine_key, 'human_key': human_key, 'original_machine_value': original_machine_value, 'original_human_value': original_human_value, 'new_machine_value': new_machine_value, 'new_human_value': new_human_value }) return differences
def test_prefixed_i18n_disabled(self): with translation.override('en'): self.assertEqual(reverse('prefixed'), '/prefixed/') with translation.override('nl'): self.assertEqual(reverse('prefixed'), '/prefixed/')
def send_mail( subject, message, from_email=None, recipient_list=None, use_deny_list=True, perm_setting=None, manage_url=None, headers=None, cc=None, real_email=False, html_message=None, attachments=None, max_retries=3, reply_to=None, countdown=None, ): """ A wrapper around django.core.mail.EmailMessage. Adds deny checking and error logging. """ from olympia.amo.templatetags.jinja_helpers import absolutify from olympia.amo.tasks import send_email from olympia.users import notifications if not recipient_list: return True if isinstance(recipient_list, str): raise ValueError('recipient_list should be a list, not a string.') # Check against user notification settings if perm_setting: if isinstance(perm_setting, str): perm_setting = notifications.NOTIFICATIONS_BY_SHORT[perm_setting] perms = dict( UserNotification.objects.filter( user__email__in=recipient_list, notification_id=perm_setting.id).values_list( 'user__email', 'enabled')) d = perm_setting.default_checked recipient_list = [ e for e in recipient_list if e and perms.setdefault(e, d) ] # Prune denied emails. if use_deny_list: white_list = [] for email in recipient_list: if email and email.lower() in settings.EMAIL_DENY_LIST: log.info('Blacklisted email removed from list: %s' % email) else: white_list.append(email) else: white_list = recipient_list if not from_email: from_email = settings.DEFAULT_FROM_EMAIL if cc: # If not str, assume it is already a list. if isinstance(cc, str): cc = [cc] if not headers: headers = {} # Avoid auto-replies per rfc 3834 and the Microsoft variant headers['X-Auto-Response-Suppress'] = 'RN, NRN, OOF, AutoReply' headers['Auto-Submitted'] = 'auto-generated' def send(recipients, message, **options): kwargs = { 'attachments': attachments, 'cc': cc, 'from_email': from_email, 'headers': headers, 'html_message': html_message, 'max_retries': max_retries, 'real_email': real_email, 'reply_to': reply_to, 'countdown': countdown, } kwargs.update(options) # Email subject *must not* contain newlines args = (list(recipients), ' '.join(subject.splitlines()), message) return send_email.delay(*args, **kwargs) if white_list: if perm_setting: html_template = loader.get_template('amo/emails/unsubscribe.html') text_template = loader.get_template('amo/emails/unsubscribe.ltxt') if not manage_url: manage_url = urlparams( absolutify(reverse('users.edit', add_prefix=False)), 'acct-notify') for recipient in white_list: # Add unsubscribe link to footer. token, hash = UnsubscribeCode.create(recipient) unsubscribe_url = absolutify( reverse( 'users.unsubscribe', args=[force_text(token), hash, perm_setting.short], add_prefix=False, )) context = { 'message': message, 'manage_url': manage_url, 'unsubscribe_url': unsubscribe_url, 'perm_setting': perm_setting.label, 'SITE_URL': settings.SITE_URL, 'mandatory': perm_setting.mandatory, } # Render this template in the default locale until # bug 635840 is fixed. with translation.override(settings.LANGUAGE_CODE): message_with_unsubscribe = text_template.render(context) if html_message: context['message'] = html_message with translation.override(settings.LANGUAGE_CODE): html_with_unsubscribe = html_template.render(context) result = send( [recipient], message_with_unsubscribe, html_message=html_with_unsubscribe, attachments=attachments, ) else: result = send([recipient], message_with_unsubscribe, attachments=attachments) else: result = send( recipient_list, message=message, html_message=html_message, attachments=attachments, ) else: result = True return result
def test_account_register(self): with translation.override('en'): self.assertEqual(reverse('account:register'), '/en/account/register/') with translation.override('nl'): self.assertEqual(reverse('account:register'), '/nl/profiel/registeren/')
def test_override_decorator(): """ When current locale is changed, Money instances should be represented correctly. """ with override("cs"): assert str(Money(10, "CZK")) == "10.00 Kč"
def test_deactivate_locale_set(self): # Deactivate translation when set to true with translation.override('pl'): result = management.call_command('leave_locale_alone_false', stdout=StringIO()) self.assertIsNone(result)
def test_prefixed(self): with translation.override('en'): self.assertEqual(reverse('prefixed'), '/en/prefixed/') with translation.override('nl'): self.assertEqual(reverse('prefixed'), '/nl/prefixed/')
def footer(request): """Retrieve the branded footer. This end-point provides information about the site footer, allowing for consistent display of the footer across other sites (for example, on the marketing site and blog). It can be used in one of two ways: 1) A client renders the footer from a JSON description. 2) A browser loads an HTML representation of the footer and injects it into the DOM. The HTML includes CSS and JavaScript links. In case (2), we assume that the following dependencies are included on the page: a) JQuery (same version as used in edx-platform) b) font-awesome (same version as used in edx-platform) c) Open Sans web fonts Example: Retrieving the footer as JSON GET /api/branding/v1/footer Accepts: application/json { "navigation_links": [ { "url": "http://example.com/about", "name": "about", "title": "About" }, # ... ], "social_links": [ { "url": "http://example.com/social", "name": "facebook", "icon-class": "fa-facebook-square", "title": "Facebook", "action": "Sign up on Facebook!" }, # ... ], "mobile_links": [ { "url": "http://example.com/android", "name": "google", "image": "http://example.com/google.png", "title": "Google" }, # ... ], "legal_links": [ { "url": "http://example.com/terms-of-service.html", "name": "terms_of_service", "title': "Terms of Service" }, # ... ], "openedx_link": { "url": "http://open.edx.org", "title": "Powered by Open edX", "image": "http://example.com/openedx.png" }, "logo_image": "http://example.com/static/images/logo.png", "copyright": "edX, Open edX and their respective logos are registered trademarks of edX Inc." } Example: Retrieving the footer as HTML GET /api/branding/v1/footer Accepts: text/html Example: Including the footer with the "Powered by Open edX" logo GET /api/branding/v1/footer?show-openedx-logo=1 Accepts: text/html Example: Retrieving the footer in a particular language GET /api/branding/v1/footer?language=en Accepts: text/html Example: Retrieving the footer with a language selector GET /api/branding/v1/footer?include-language-selector=1 Accepts: text/html Example: Retrieving the footer with all JS and CSS dependencies (for testing) GET /api/branding/v1/footer?include-dependencies=1 Accepts: text/html """ if not branding_api.is_enabled(): raise Http404 # Use the content type to decide what representation to serve accepts = request.META.get('HTTP_ACCEPT', '*/*') # Show the OpenEdX logo in the footer show_openedx_logo = bool(request.GET.get('show-openedx-logo', False)) # Include JS and CSS dependencies # This is useful for testing the end-point directly. include_dependencies = bool(request.GET.get('include-dependencies', False)) # Override the language if necessary language = request.GET.get('language', translation.get_language()) try: language = get_supported_language_variant(language) except LookupError: language = settings.LANGUAGE_CODE # Include a language selector include_language_selector = request.GET.get('include-language-selector', '') == '1' # Render the footer information based on the extension if 'text/html' in accepts or '*/*' in accepts: cache_params = { 'language': language, 'show_openedx_logo': show_openedx_logo, 'include_dependencies': include_dependencies } if include_language_selector: cache_params['language_selector_options'] = ','.join(sorted([lang.code for lang in released_languages()])) cache_key = u"branding.footer.{params}.html".format(params=six.moves.urllib.parse.urlencode(cache_params)) content = cache.get(cache_key) if content is None: with translation.override(language): content = _render_footer_html( request, show_openedx_logo, include_dependencies, include_language_selector, language ) cache.set(cache_key, content, settings.FOOTER_CACHE_TIMEOUT) return HttpResponse(content, status=200, content_type="text/html; charset=utf-8") elif 'application/json' in accepts: cache_key = u"branding.footer.{params}.json".format( params=six.moves.urllib.parse.urlencode({ 'language': language, 'is_secure': request.is_secure(), }) ) footer_dict = cache.get(cache_key) if footer_dict is None: with translation.override(language): footer_dict = branding_api.get_footer(is_secure=request.is_secure()) cache.set(cache_key, footer_dict, settings.FOOTER_CACHE_TIMEOUT) return JsonResponse(footer_dict, 200, content_type="application/json; charset=utf-8") else: return HttpResponse(status=406)
def test_configured_locale_preserved(self): # Leaves locale from settings when set to false with translation.override('pl'): result = management.call_command('leave_locale_alone_true', stdout=StringIO()) self.assertEqual(result, "pl")
def type(self): with translation.override(settings.LANGUAGE_CODE): type_ = (translation.ugettext(amo.ADDON_TYPE[self.addon.type]) if self.addon else 'User' if self.user else 'Addon') return type_
def test_language_preserved(self): out = StringIO() with translation.override('fr'): management.call_command('dance', stdout=out) self.assertEqual(translation.get_language(), 'fr')
def test_intcomma_without_number_grouping(self): # Regression for #17414 with translation.override('ja'), self.settings(USE_L10N=True): self.humanize_tester([100], ['100'], 'intcomma')
def test_i18n_english_variant(self): with override('en-gb'): response = self.client.get('/jsi18n/') self.assertIn( '"this color is to be translated": "this colour is to be translated"', response.context['catalog_str'])
def test_i18n06(self): """simple translation of a string to German""" with translation.override('de'): output = self.engine.render_to_string('i18n06') self.assertEqual(output, 'Seite nicht gefunden')
def test_naturaltime(self): class naive(datetime.tzinfo): def utcoffset(self, dt): return None test_list = [ 'test', now, now - datetime.timedelta(microseconds=1), now - datetime.timedelta(seconds=1), now - datetime.timedelta(seconds=30), now - datetime.timedelta(minutes=1, seconds=30), now - datetime.timedelta(minutes=2), now - datetime.timedelta(hours=1, minutes=30, seconds=30), now - datetime.timedelta(hours=23, minutes=50, seconds=50), now - datetime.timedelta(days=1), now - datetime.timedelta(days=500), now + datetime.timedelta(seconds=1), now + datetime.timedelta(seconds=30), now + datetime.timedelta(minutes=1, seconds=30), now + datetime.timedelta(minutes=2), now + datetime.timedelta(hours=1, minutes=30, seconds=30), now + datetime.timedelta(hours=23, minutes=50, seconds=50), now + datetime.timedelta(days=1), now + datetime.timedelta(days=2, hours=6), now + datetime.timedelta(days=500), now.replace(tzinfo=naive()), now.replace(tzinfo=utc), ] result_list = [ 'test', 'now', 'now', 'a second ago', '30\xa0seconds ago', 'a minute ago', '2\xa0minutes ago', 'an hour ago', '23\xa0hours ago', '1\xa0day ago', '1\xa0year, 4\xa0months ago', 'a second from now', '30\xa0seconds from now', 'a minute from now', '2\xa0minutes from now', 'an hour from now', '23\xa0hours from now', '1\xa0day from now', '2\xa0days, 6\xa0hours from now', '1\xa0year, 4\xa0months from now', 'now', 'now', ] # Because of the DST change, 2 days and 6 hours after the chosen # date in naive arithmetic is only 2 days and 5 hours after in # aware arithmetic. result_list_with_tz_support = result_list[:] assert result_list_with_tz_support[ -4] == '2\xa0days, 6\xa0hours from now' result_list_with_tz_support[-4] == '2\xa0days, 5\xa0hours from now' orig_humanize_datetime, humanize.datetime = humanize.datetime, MockDateTime try: with translation.override('en'): self.humanize_tester(test_list, result_list, 'naturaltime') with override_settings(USE_TZ=True): self.humanize_tester(test_list, result_list_with_tz_support, 'naturaltime') finally: humanize.datetime = orig_humanize_datetime
def test_multiple_locale_direct_switch_trans(self): with translation.override('de'): t = Template("{% load i18n %}{% trans 'No' %}") with translation.override('nl'): self.assertEqual(t.render(Context({})), 'Nee')
def test_fuzzy_compiling(self): with override_settings(LOCALE_PATHS=[os.path.join(self.test_dir, 'locale')]): call_command('compilemessages', locale=[self.LOCALE], fuzzy=True, stdout=StringIO()) with translation.override(self.LOCALE): self.assertEqual(ugettext('Lenin'), force_text('Ленин')) self.assertEqual(ugettext('Vodka'), force_text('Водка'))