ModelAttributeTests.test_untranslated_get()   A
last analyzed

Complexity

Conditions 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 15
c 1
b 0
f 0
rs 9.4285
cc 3
1
from __future__ import unicode_literals
2
from django.utils import translation
3
from parler.models import TranslationDoesNotExist
4
from .utils import AppTestCase
5
from .testapp.models import SimpleModel, AnyLanguageModel, EmptyModel
6
7
8
class ModelAttributeTests(AppTestCase):
9
    """
10
    Test model construction
11
    """
12
13
    def test_untranslated_get(self):
14
        """
15
        Test the metaclass of the model.
16
        """
17
        try:
18
            value = SimpleModel().tr_title
19
        except Exception as e:
20
            self.assertIsInstance(e, TranslationDoesNotExist)
21
            self.assertIsInstance(e, AttributeError)
22
        else:
23
            self.fail("Expected exception from reading untranslated title, got {0}.".format(repr(value)))
24
25
        # Raising attribute error gives some additional benefits:
26
        self.assertEqual(getattr(SimpleModel(), 'tr_title', 'FOO'), 'FOO')
27
        self.assertFalse(hasattr(SimpleModel(), 'tr_title'))
28
29
    def test_default_language(self):
30
        """
31
        Test whether simple language assignments work.
32
        """
33
        with translation.override('ca-fr'):
34
            x = SimpleModel(id=99)   # uses get_language(), ID is to avoid reading cached items for 'en'
35
            self.assertEqual(x.get_current_language(), translation.get_language())
36
            self.assertEqual(translation.get_language(), 'ca-fr')
37
38
        x.shared = 'SHARED'
39
        x.tr_title = 'TRANS_CA'
40
        x.save()
41
42
        # Refetch
43
        with translation.override('en'):
44
            x = SimpleModel.objects.get(pk=x.pk)
45
            self.assertRaises(TranslationDoesNotExist, lambda: x.tr_title)
46
47
            # Switch context
48
            x.set_current_language('ca-fr')
49
            self.assertEqual(x.tr_title, 'TRANS_CA')
50
51
    def test_init_args(self):
52
        """
53
        Test whether passing translated attributes to __init__() works.
54
        """
55
        x = SimpleModel(tr_title='TRANS_TITLE')
56
        self.assertEqual(x.tr_title, "TRANS_TITLE")
57
58
        y = SimpleModel(tr_title='TRANS_TITLE', _current_language='nl')
59
        self.assertEqual(y.get_current_language(), 'nl')
60
        self.assertEqual(y.tr_title, "TRANS_TITLE")
61
62
    def test_create_args(self):
63
        y = SimpleModel.objects.language('nl').create(tr_title='TRANS_TITLE')
64
        self.assertEqual(y.get_current_language(), 'nl')
65
        self.assertEqual(y.tr_title, "TRANS_TITLE")
66
67
    def test_save_multiple(self):
68
        """
69
        Test the save_translations() function to store multiple languages.
70
        """
71
        x = SimpleModel()
72
        x.set_current_language('en')
73
        x.tr_title = "TITLE_EN"
74
        x.set_current_language('fr')
75
        x.tr_title = "TITLE_FR"
76
        x.set_current_language('es')
77
        x.tr_title = "TITLE_ES"
78
        x.set_current_language('nl')
79
        x.tr_title = "TITLE_NL"
80
81
        x.save()
82
83
        # Check if all translations are saved.
84
        self.assertEqual(sorted(x.translations.values_list('tr_title', flat=True)), ['TITLE_EN', 'TITLE_ES', 'TITLE_FR', 'TITLE_NL'])
85
        self.assertEqual(sorted(x.get_available_languages()), ['en', 'es', 'fr', 'nl'])
86
        self.assertTrue(x.has_translation('en'))
87
        self.assertTrue(x.has_translation('es'))
88
        self.assertFalse(x.has_translation('fi'))
89
90
        # Update 2 translations.
91
        # Only those should be updated in the database.
92
        x.set_current_language('es')
93
        x.tr_title = "TITLE_ES2"
94
        x.set_current_language('nl')
95
        x.tr_title = "TITLE_NL2"
96
97
        self.assertNumQueries(2, x.save_translations())
98
99
        # Any unmodified language is not saved.
100
        x.set_current_language('it', initialize=True)
101
        self.assertTrue(x.has_translation('it'))  # does return true for this object.
102
        self.assertNumQueries(0, x.save_translations())
103
        self.assertEqual(sorted(x.get_available_languages()), ['en', 'es', 'fr', 'nl'])
104
105
    def test_empty_model(self):
106
        """
107
        Test whether a translated model without any fields still works.
108
        """
109
        x = EmptyModel()
110
        x.set_current_language('en', initialize=True)
111
        x.set_current_language('fr', initialize=True)
112
        x.set_current_language('es')
113
        x.set_current_language('nl', initialize=True)
114
        x.save()
115
116
        self.assertEqual(sorted(x.get_available_languages()), ['en', 'fr', 'nl'])
117
118
    def test_create_translation(self):
119
        x = SimpleModel.objects.create()
120
        x.create_translation('en', tr_title='TITLE_EN')
121
        x.create_translation('fr', tr_title='TITLE_FR')
122
123
        self.assertEqual(sorted(x.get_available_languages()), ['en', 'fr'])
124
125
    def test_fallback_language(self):
126
        """
127
        Test whether the fallback language will be returned.
128
        """
129
        x = SimpleModel()
130
        x.set_current_language(self.conf_fallback)
131
        x.tr_title = "TITLE_FALLBACK"
132
133
        x.set_current_language(self.other_lang1)
134
        x.tr_title = 'TITLE_XX'
135
        x.save()
136
137
        with translation.override(self.other_lang2):
138
            x = SimpleModel.objects.get(pk=x.pk)
139
            self.assertEqual(x.tr_title, 'TITLE_FALLBACK')
140
141
    def test_fallback_variant(self):
142
        """Test de-us falls back to de"""
143
        x = SimpleModel()
144
145
        x.set_current_language('de')
146
        x.tr_title = "Hallo-de"
147
148
        x.set_current_language('en')
149
        x.tr_title = "Hello-en"
150
151
        x.save()
152
153
        with translation.override('de-ch'):
154
            x = SimpleModel.objects.get(pk=x.pk)
155
            self.assertEqual(x.tr_title, 'Hallo-de')
156
157
    def test_fallback_language_no_current(self):
158
        """
159
        Test whether the fallback language will be returned,
160
        even when the current language does not have a translation.
161
        """
162
        x = SimpleModel()
163
        x.set_current_language(self.conf_fallback)
164
        x.tr_title = "TITLE_FALLBACK"
165
166
        self.assertEqual(
167
            x.safe_translation_getter('tr_title', language_code=self.other_lang1),
168
            'TITLE_FALLBACK')
169
170 View Code Duplication
    def test_any_fallback_model(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
171
        """
172
        Test whether a failure in the fallback language can return any saved language (if configured for it).
173
        """
174
        x = AnyLanguageModel()
175
        x.set_current_language(self.other_lang1)
176
        x.tr_title = "TITLE_XX"
177
178
        x.save()
179
180
        with translation.override(self.other_lang2):
181
            x = AnyLanguageModel.objects.get(pk=x.pk)
182
            self.assertRaises(TranslationDoesNotExist, lambda: x._get_translated_model(use_fallback=True))
183
            self.assertEqual(x.tr_title, 'TITLE_XX')  # Even though there is no current language, there is a value.
184
185
            self.assertNumQueries(0, lambda: x._get_any_translated_model())   # Can fetch from cache next time.
186
            self.assertEqual(x._get_any_translated_model().language_code, self.other_lang1)
187
188 View Code Duplication
    def test_any_fallback_function(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
189
        x = SimpleModel()
190
        x.set_current_language(self.other_lang1)
191
        x.tr_title = "TITLE_XX"
192
193
        x.save()
194
195
        with translation.override(self.other_lang2):
196
            x = SimpleModel.objects.get(pk=x.pk)
197
            self.assertRaises(TranslationDoesNotExist, lambda: x._get_translated_model(use_fallback=True))
198
            self.assertIs(x.safe_translation_getter('tr_title', 'DEFAULT'), 'DEFAULT')  # No lanuage, gives default
199
            self.assertEqual(x.safe_translation_getter('tr_title', any_language=True), 'TITLE_XX')  # Even though there is no current language, there is a value.
200
201
            self.assertNumQueries(0, lambda: x._get_any_translated_model())   # Can fetch from cache next time.
202
            self.assertEqual(x._get_any_translated_model().language_code, self.other_lang1)
203
204
    def test_save_ignore_fallback_marker(self):
205
        """
206
        Test whether the ``save_translations()`` method skips fallback languages
207
        """
208
        x = SimpleModel()
209
        x.set_current_language(self.other_lang1)
210
        x.tr_title = "TITLE_XX"
211
        x.set_current_language(self.other_lang2)
212
        # try fetching, causing an fallback marker
213
        x.safe_translation_getter('tr_title', any_language=True)
214
        # Now save. This should not raise errors
215
        x.save()
216
217
    def test_model_with_zero_pk(self):
218
        """
219
        tests that the translated model is returned also when the pk is 0
220
        """
221
        x = SimpleModel()
222
        x.set_current_language(self.other_lang1)
223
        x.pk = 0
224
        x.tr_title = "EMPTY_PK"
225
226
        x.save()
227
228
        # now fetch it from db
229
        try:
230
            SimpleModel.objects.get(pk=x.pk)
231
        except TranslationDoesNotExist:
232
            self.fail("zero pk is not supported!")
233
234
    def test_translatedfieldsmodel_str(self):
235
        """Test converting TranslatedFieldsModel to string"""
236
        missing_language_code = 'xx'
237
        obj = SimpleModel.objects.create(tr_title='Something')
238
239
        # Adjust translation object to use language_code that is not
240
        # configured. It is easier because various Django version behave
241
        # differently if we try to use not configured language.
242
        translation = obj.translations.get()
243
        translation.language_code = missing_language_code
244
        translation.save()
245
        # Try to get str() of the TranslatedFieldsModel instance.
246
        try:
247
            translation_as_str = str(obj.translations.get())
248
        except KeyError:
249
            self.fail("Converting translation to string raises KeyError")
250
251
        # Check that we get language code as a fallback, when language is
252
        # not configured.
253
        self.assertEqual(translation_as_str, missing_language_code)
254