~abompard/mailman/import21

« back to all changes in this revision

Viewing changes to src/mailman/utilities/tests/test_import.py

  • Committer: Aurélien Bompard
  • Date: 2013-10-03 16:37:04 UTC
  • Revision ID: aurelien@bompard.org-20131003163704-d9p7wz110x91p25f
More unicode fixes in the import script

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
import cPickle
29
29
import unittest
30
30
from datetime import timedelta, datetime
31
 
from traceback import format_exc
32
31
 
33
32
from mailman.app.lifecycle import create_list, remove_list
34
33
from mailman.testing.layers import ConfigLayer
35
 
from mailman.utilities.importer import import_config_pck, Import21Error
 
34
from mailman.utilities.importer import import_config_pck
36
35
from mailman.interfaces.archiver import ArchivePolicy
37
36
from mailman.interfaces.action import Action, FilterAction
38
 
from mailman.interfaces.address import ExistingAddressError
39
37
from mailman.interfaces.bounce import UnrecognizedBounceDisposition
40
38
from mailman.interfaces.bans import IBanManager
41
39
from mailman.interfaces.mailinglist import IAcceptableAliasSet
43
41
from mailman.interfaces.autorespond import ResponseAction
44
42
from mailman.interfaces.templates import ITemplateLoader
45
43
from mailman.interfaces.usermanager import IUserManager
46
 
from mailman.interfaces.member import DeliveryMode, DeliveryStatus, MemberRole
 
44
from mailman.interfaces.member import DeliveryMode, DeliveryStatus
47
45
from mailman.interfaces.languages import ILanguageManager
48
 
from mailman.model.address import Address
49
46
from mailman.handlers.decorate import decorate
50
47
from mailman.utilities.string import expand
51
48
from pkg_resources import resource_filename
52
49
from enum import Enum
53
50
from zope.component import getUtility
54
 
from storm.locals import Store
55
51
 
56
52
 
57
53
 
81
77
        self._import()
82
78
        self.assertEqual(self._mlist.display_name, 'Test')
83
79
 
84
 
    def test_mail_host_invariant(self):
85
 
        # The mlist.mail_host must not be updated when importing (it will
86
 
        # change the list_id property, which is supposed to be read-only)
 
80
    def test_mail_host(self):
 
81
        # The mlist.mail_host gets set.
87
82
        self.assertEqual(self._mlist.mail_host, 'example.com')
88
83
        self._import()
89
 
        self.assertEqual(self._mlist.mail_host, 'example.com')
 
84
        self.assertEqual(self._mlist.mail_host, 'heresy.example.org')
90
85
 
91
86
    def test_rfc2369_headers(self):
92
87
        self._mlist.allow_list_posts = False
177
172
        # moderator_password must not be unicode
178
173
        self._pckdict[b"mod_password"] = b'TESTVALUE'
179
174
        self._import()
180
 
        self.assertFalse(isinstance(self._mlist.moderator_password, unicode))
181
175
        self.assertEqual(self._mlist.moderator_password, b'TESTVALUE')
182
176
 
183
177
    def test_newsgroup_moderation(self):
202
196
    def test_ban_list(self):
203
197
        banned = [
204
198
            ("anne@example.com", "anne@example.com"),
205
 
            ("^.*@example.com", "bob@example.com"),
206
 
            ("non-ascii-\xe8@example.com", "non-ascii-\ufffd@example.com"),
 
199
            ("^.*@example.com", "bob@example.com")
207
200
            ]
208
 
        self._pckdict["ban_list"] = [ b[0].encode("iso-8859-1") for b in banned ]
209
 
        try:
210
 
            self._import()
211
 
        except UnicodeDecodeError, e:
212
 
            print(format_exc())
213
 
            self.fail(e)
 
201
        self._pckdict["ban_list"] = [ str(b[0]) for b in banned ]
 
202
        self._import()
214
203
        for _pattern, addr in banned:
215
204
            self.assertTrue(IBanManager(self._mlist).is_banned(addr))
216
205
 
217
206
    def test_acceptable_aliases(self):
218
207
        # it used to be a plain-text field (values are newline-separated)
219
 
        aliases = ["alias1@example.com",
220
 
                   "alias2@exemple.com",
221
 
                   "non-ascii-\xe8@example.com",
222
 
                   ]
223
 
        self._pckdict[b"acceptable_aliases"] = \
224
 
                ("\n".join(aliases)).encode("utf-8")
 
208
        aliases = ["alias1@example.com", "alias2@exemple.com"]
 
209
        self._pckdict[b"acceptable_aliases"] = str("\n".join(aliases))
225
210
        self._import()
226
211
        alias_set = IAcceptableAliasSet(self._mlist)
227
212
        self.assertEqual(sorted(alias_set.aliases), aliases)
228
213
 
229
 
    def test_acceptable_aliases_invalid(self):
230
 
        # values without an '@' sign used to be matched against the local part,
231
 
        # now we need to add the '^' sign
232
 
        aliases = ["invalid-value", ]
233
 
        self._pckdict[b"acceptable_aliases"] = \
234
 
                ("\n".join(aliases)).encode("utf-8")
235
 
        try:
236
 
            self._import()
237
 
        except ValueError, e:
238
 
            print(format_exc())
239
 
            self.fail("Invalid value '%s' caused a crash" % e)
240
 
        alias_set = IAcceptableAliasSet(self._mlist)
241
 
        self.assertEqual(sorted(alias_set.aliases),
242
 
                         [ ("^" + a) for a in aliases ])
243
 
 
244
 
    def test_acceptable_aliases_as_list(self):
245
 
        # in some versions of the pickle, it can be a list, not a string
246
 
        # (seen in the wild)
247
 
        aliases = [b"alias1@example.com", b"alias2@exemple.com" ]
248
 
        self._pckdict[b"acceptable_aliases"] = aliases
249
 
        try:
250
 
            self._import()
251
 
        except AttributeError:
252
 
            print(format_exc())
253
 
            self.fail("Import does not handle acceptable_aliases as list")
254
 
        alias_set = IAcceptableAliasSet(self._mlist)
255
 
        self.assertEqual(sorted(alias_set.aliases), aliases)
256
 
 
257
214
    def test_info_non_ascii(self):
258
215
        # info can contain non-ascii chars
259
216
        info = 'O idioma aceito \xe9 somente Portugu\xeas do Brasil'
268
225
                         unicode(self._pckdict[b"info"], "ascii", "replace"),
269
226
                         "We don't fall back to replacing non-ascii chars")
270
227
 
271
 
    def test_preferred_language(self):
272
 
        self._pckdict[b"preferred_language"] = b'ja'
273
 
        english = getUtility(ILanguageManager).get('en')
274
 
        japanese = getUtility(ILanguageManager).get('ja')
275
 
        self.assertEqual(self._mlist.preferred_language, english)
276
 
        self._import()
277
 
        self.assertEqual(self._mlist.preferred_language, japanese)
278
 
 
279
 
    def test_preferred_language_unknown_previous(self):
280
 
        # when the previous language is unknown, it should not fail
281
 
        self._mlist._preferred_language = 'xx' # non-existant
282
 
        self._import()
283
 
        english = getUtility(ILanguageManager).get('en')
284
 
        self.assertEqual(self._mlist.preferred_language, english)
285
 
 
286
 
    def test_new_language(self):
287
 
        self._pckdict[b"preferred_language"] = b'xx_XX'
288
 
        try:
289
 
            self._import()
290
 
        except Import21Error, e:
291
 
            # check the message
292
 
            self.assertTrue("[language.xx_XX]" in str(e))
293
 
        else:
294
 
            self.fail("Import21Error was not raised")
295
 
 
296
228
 
297
229
 
298
230
class TestArchiveImport(unittest.TestCase):
503
435
        # We can't check if it changed from the default
504
436
        # -> don't import, we may do more harm than good and it's easy to
505
437
        # change if needed
506
 
        test_value = b"TEST-VALUE"
 
438
        test_value = "TEST-VALUE"
507
439
        for oldvar, newvar in self._conf_mapping.iteritems():
508
440
            self._mlist.mail_host = "example.com"
509
441
            self._pckdict[b"mail_host"] = b"test.example.com"
514
446
            self.assertEqual(old_value, new_value,
515
447
                    "Default value was not preserved for %s" % newvar)
516
448
 
517
 
    def test_unicode(self):
518
 
        for oldvar in self._conf_mapping:
519
 
            self._pckdict[str(oldvar)] = b"Ol\xe1!"
520
 
        try:
521
 
            import_config_pck(self._mlist, self._pckdict)
522
 
        except UnicodeDecodeError, e:
523
 
            print(format_exc())
524
 
            self.fail(e)
525
 
        for oldvar, newvar in self._conf_mapping.iteritems():
526
 
            newattr = getattr(self._mlist, newvar)
527
 
            text = decorate(self._mlist, newattr)
528
 
            expected = u'Ol\ufffd!'.encode("utf-8")
529
 
            # we get bytestrings because the text is stored in a file
530
 
            self.assertEqual(text, expected)
531
 
 
532
449
 
533
450
 
534
451
class TestRosterImport(unittest.TestCase):
617
534
            self.assertEqual(member.preferred_language.code,
618
535
                             self._pckdict["language"][addr])
619
536
 
620
 
    def test_new_language(self):
621
 
        self._pckdict[b"language"][b"anne@example.com"] = b'xx_XX'
622
 
        try:
623
 
            import_config_pck(self._mlist, self._pckdict)
624
 
        except Import21Error, e:
625
 
            # check the message
626
 
            self.assertTrue("[language.xx_XX]" in str(e))
627
 
        else:
628
 
            self.fail("Import21Error was not raised")
629
 
 
630
537
    def test_username(self):
631
538
        import_config_pck(self._mlist, self._pckdict)
632
539
        for name in ("anne", "bob", "cindy", "dave"):
684
591
        member = self._mlist.members.get_member('bob@example.com')
685
592
        self.assertEqual(member.user, user)
686
593
 
687
 
    def test_owner_and_moderator_not_lowercase(self):
688
 
        # In the v2.1 pickled dict, the owner and moderator lists are not
689
 
        # necessarily lowercased already
690
 
        self._pckdict[b"owner"] = [b"Anne@example.com"]
691
 
        self._pckdict[b"moderator"] = [b"Anne@example.com"]
692
 
        try:
693
 
            import_config_pck(self._mlist, self._pckdict)
694
 
        except AssertionError:
695
 
            print(format_exc())
696
 
            self.fail("The address was not lowercased")
697
 
        self.assertTrue("anne@example.com" in
698
 
                [ a.email for a in self._mlist.owners.addresses ])
699
 
        self.assertTrue("anne@example.com" in
700
 
                [ a.email for a in self._mlist.moderators.addresses])
701
 
 
702
 
    def test_address_already_exists_but_no_user(self):
703
 
        # An address already exists, but it is not linked to a user nor
704
 
        # subscribed
705
 
        anne_addr = Address("anne@example.com", "Anne")
706
 
        Store.of(self._mlist).add(anne_addr)
707
 
        try:
708
 
            import_config_pck(self._mlist, self._pckdict)
709
 
        except ExistingAddressError:
710
 
            print(format_exc())
711
 
            self.fail("existing address was not checked")
712
 
        anne = self._usermanager.get_user("anne@example.com")
713
 
        self.assertTrue(anne.controls("anne@example.com"))
714
 
        self.assertTrue(anne_addr in self._mlist.regular_members.addresses)
715
 
 
716
 
    def test_address_already_subscribed_but_no_user(self):
717
 
        # An address is already subscribed, but it is not linked to a user
718
 
        anne_addr = Address("anne@example.com", "Anne")
719
 
        self._mlist.subscribe(anne_addr)
720
 
        try:
721
 
            import_config_pck(self._mlist, self._pckdict)
722
 
        except ExistingAddressError:
723
 
            print(format_exc())
724
 
            self.fail("existing address was not checked")
725
 
        anne = self._usermanager.get_user("anne@example.com")
726
 
        self.assertTrue(anne.controls("anne@example.com"))
727
 
 
728
 
 
729
594
 
730
595
 
731
596
class TestPreferencesImport(unittest.TestCase):