Merge branch 'weblate-gnu-mailman-postorius' into 'master'
[mailman-postorious.git] / src / postorius / tests / test_list_forms.py
blob781ba58e4b979f06a143eb307ce83cf5d51b932f
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2017-2023 by the Free Software Foundation, Inc.
4 # This file is part of Postorius.
6 # Postorius is free software: you can redistribute it and/or modify it under
7 # the terms of the GNU General Public License as published by the Free
8 # Software Foundation, either version 3 of the License, or (at your option)
9 # any later version.
11 # Postorius is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 # more details.
16 # You should have received a copy of the GNU General Public License along with
17 # Postorius. If not, see <http://www.gnu.org/licenses/>.
19 import unittest
21 from django.test import TestCase, override_settings
23 from postorius.forms.list_forms import (
24 ArchiveSettingsForm,
25 ChangeSubscriptionForm,
26 DigestSettingsForm,
27 DMARCMitigationsForm,
28 ListAnonymousSubscribe,
29 ListAutomaticResponsesForm,
30 ListHeaderMatchForm,
31 ListIdentityForm,
32 ListMassRemoval,
33 ListMassSubscription,
34 ListNew,
35 ListSubscribe,
36 MemberModeration,
37 MemberPolicyForm,
38 MessageAcceptanceForm,
40 from postorius.forms.system import AddBanForm
41 from postorius.tests.utils import create_mock_list
44 class TestListSubscribe(TestCase):
45 def test_required_fields_only(self):
46 user_emails = ['bob@example.com', 'anne@example.com']
47 form = ListSubscribe(
48 user_emails, None, None, dict(subscriber='bob@example.com')
50 self.assertTrue(form.is_valid())
52 def test_email_is_only_from_choices(self):
53 user_emails = ['bob@example.com', 'anne@example.com']
54 form = ListSubscribe(
55 user_emails,
56 None,
57 None,
58 dict(subscriber='alice@example.com', display_name='Alice'),
60 self.assertFalse(form.is_valid())
61 self.assertTrue('subscriber' in form.errors)
62 self.assertTrue(
63 'Select a valid choice.' in form.errors['subscriber'][0]
66 def test_subscribe_works(self):
67 user_emails = ['someone@example.com']
68 form = ListSubscribe(
69 user_emails,
70 None,
71 None,
72 {'subscriber': 'someone@example.com', 'display_name': 'Someone'},
74 self.assertTrue(form.is_valid())
76 def test_subscribe_fails(self):
77 user_emails = ['someone@example.com']
78 form = ListSubscribe(
79 user_emails,
80 None,
81 None,
82 {'subscriber': 'notaemail', 'display_name': 'Someone'},
84 self.assertFalse(form.is_valid())
85 self.assertTrue('subscriber' in form.errors.keys())
86 self.assertEqual(
87 form.errors['subscriber'][0],
88 'Select a valid choice.'
89 ' notaemail is not one of the available choices.',
92 def test_subscribe_validates_email(self):
93 user_emails = ['something']
94 form = ListSubscribe(
95 user_emails,
96 None,
97 None,
98 {'subscriber': 'something', 'display_name': 'Someone'},
100 self.assertFalse(form.is_valid())
101 self.assertTrue('subscriber' in form.errors.keys())
102 self.assertEqual(
103 form.errors['subscriber'][0], 'Please enter a valid email address.'
106 def test_subscribe_with_user_uuid(self):
107 user_emails = ['aperson@example.com']
108 form = ListSubscribe(
109 user_emails,
110 '00000000000000000000000000000004',
111 'aperson@example.com',
112 {'subscriber': '00000000000000000000000000000004'},
114 self.assertEqual(form.is_valid(), True)
116 def test_subscribe_with_invalid_uuid(self):
117 # Test that invalid UUID returns errors.
118 user_emails = ['aperson@example.com']
119 form = ListSubscribe(
120 user_emails, '4', 'aperson@example.com', {'subscriber': '4'}
122 self.assertEqual(form.is_valid(), False)
123 self.assertEqual(
124 form.errors['subscriber'][0], 'Please enter a valid email address.'
127 def test_list_subscribe_with_delivery_mode(self):
128 user_emails = ['aperson@example.com']
129 form = ListSubscribe(
130 user_emails,
131 '00000000000000000000000000000004',
132 'aperson@example.com',
134 'subscriber': '00000000000000000000000000000004',
135 'delivery_mode': 'plaintext_digests',
136 'delivery_status': 'by_user',
139 self.assertTrue(form.is_valid())
141 def test_list_subscribe_with_invalid_delivery_status(self):
142 user_emails = ['aperson@example.com']
143 form = ListSubscribe(
144 user_emails,
145 '00000000000000000000000000000004',
146 'aperson@example.com',
148 'subscriber': '00000000000000000000000000000004',
149 'delivery_mode': 'plaintext_digest',
150 'delivery_status': 'by_bounces',
153 self.assertFalse(form.is_valid())
154 self.assertTrue('delivery_status' in form.errors)
157 class TestChangeSubscription(TestCase):
158 def test_subscription_changes_only_to_user_addresses(self):
159 user_emails = ['one@example.com', 'two@example.com']
160 form = ChangeSubscriptionForm(
161 user_emails,
162 None,
163 None,
164 {'subscriber': 'abcd@d.com', 'member_id': '1235sdfsd314'},
166 self.assertFalse(form.is_valid())
167 self.assertTrue('subscriber' in form.errors.keys())
168 self.assertEqual(
169 form.errors['subscriber'][0],
170 'Select a valid choice. '
171 'abcd@d.com is not one of the available choices.',
174 def test_subscription_works(self):
175 user_emails = ['one@example.com', 'two@example.com']
176 form = ChangeSubscriptionForm(
177 user_emails,
178 None,
179 None,
180 {'subscriber': 'two@example.com', 'member_id': '1235sdfsd314'},
182 self.assertTrue(form.is_valid())
184 def test_subscription_form_labels(self):
185 user_emails = ['one@example.com', 'two@example.com']
186 form = ChangeSubscriptionForm(
187 user_emails, None, None, {'member_id': '1235sdfsd314'}
189 self.assertTrue(form.is_valid())
190 self.assertEqual(form.fields['subscriber'].label, 'Select Email')
192 def test_form_validity(self):
193 form = ChangeSubscriptionForm(
194 ['email@example.com', 'john@example.com', 'doe@example.com'],
195 None,
196 None,
197 {'subscriber': 'email@example.com', 'member_id': '1235sdfsd314'},
199 self.assertTrue(form.is_valid())
201 def test_required_fields(self):
202 # There is only one required fields.
203 form = ChangeSubscriptionForm(
204 ['email@example.com', 'john@example.com', 'doe@example.com'],
205 None,
206 None,
207 {'member_id': '1235sdfsd314'},
209 self.assertTrue(form.is_valid())
211 def test_change_subscription_with_user_uuid(self):
212 user_emails = ['aperson@example.com']
213 form = ChangeSubscriptionForm(
214 user_emails,
215 '00000000000000000000000000000004',
216 'aperson@example.com',
218 'subscriber': '00000000000000000000000000000004',
219 'member_id': '1235sdfsd314',
222 self.assertEqual(form.is_valid(), True)
224 def test_subscribe_with_invalid_uuid(self):
225 # Test that invalid UUID returns errors.
226 user_emails = ['aperson@example.com']
227 # UUIDs are 32bit and 4 is not a valid email.
228 form = ChangeSubscriptionForm(
229 user_emails, '4', 'aperson@example.com', {'subscriber': '4'}
231 self.assertEqual(form.is_valid(), False)
232 self.assertEqual(
233 form.errors['subscriber'][0],
234 'Invalid: "4" should be either email or UUID',
238 class TestListNew(TestCase):
239 def test_form_fields_list(self):
240 domain_choices = [
241 ('mailman.most-desirable.org', 'mailman.most-desirable.org')
243 style_choices = [
244 ('legacy-default', 'Ordinary discussion mailing list style.'),
245 ('legacy-announce', 'Announce only mailing list style.'),
247 form = ListNew(
248 domain_choices,
249 style_choices,
251 'listname': 'xyz',
252 'mail_host': 'mailman.most-desirable.org',
253 'list_owner': 'contact@mailman.most-desirable.org',
254 'advertised': 'True',
255 'list_style': 'legacy-default',
256 'description': 'The Most Desirable organization',
259 self.assertTrue(form.is_valid(), form.errors)
261 def test_form_fields_list_invalid(self):
262 domain_choices = [
263 ('mailman.most-desirable.org', 'mailman.most-desirable.org')
265 style_choices = [
266 ('legacy-default', 'Ordinary discussion mailing list style.'),
267 ('legacy-announce', 'Announce only mailing list style.'),
269 form = ListNew(
270 domain_choices,
271 style_choices,
273 'listname': 'xy#z',
274 'mail_host': 'mailman.most-desirable.org',
275 'list_owner': 'mailman.most-desirable.org',
276 'advertised': 'abcd',
277 'list_style': 'defg',
278 'description': 'The Most Desirable organization',
281 self.assertFalse(form.is_valid())
282 # Test that all invalid fields are actually checked.
283 for field in ('list_owner', 'advertised'):
284 self.assertTrue(field in form.errors)
285 self.assertTrue(
286 'Enter a valid email address.' in form.errors['list_owner']
288 self.assertTrue(
289 'Select a valid choice. abcd is not one of the available choices.'
290 in form.errors['advertised']
293 def test_form_without_domain_choices(self):
294 form = ListNew(
297 'listname': 'xyz',
298 'mail_host': 'mailman.most-desirable.org',
299 'list_owner': 'contact@mailman.most-desirable.org',
300 'advertised': 'True',
301 'description': 'The Most Desirable organization',
304 # Without domain choices, the form is not going to be valid.
305 self.assertFalse(form.is_valid())
306 self.assertTrue(
307 form.fields['mail_host'].help_text
308 == 'Site admin has not created any domains' # noqa: W504
311 def test_listname_validation(self):
312 domain_choices = [
313 ('mailman.most-desirable.org', 'mailman.most-desirable.org')
315 style_choices = [
316 ('legacy-default', 'Ordinary discussion mailing list style.'),
317 ('legacy-announce', 'Announce only mailing list style.'),
319 form = ListNew(
320 domain_choices,
321 style_choices,
323 'listname': 'xy@z',
324 'mail_host': 'mailman.most-desirable.org',
325 'list_owner': 'mailman.most-desirable.org',
326 'advertised': 'abcd',
327 'description': 'The Most Desirable organization',
330 self.assertFalse(form.is_valid())
331 self.assertTrue('listname' in form.errors)
332 self.assertTrue(
333 'Please enter a valid listname' in form.errors['listname']
336 @unittest.expectedFailure
337 def test_listname_validation_errors_sane(self):
338 # This test is going to fail right now, but needs to be fixed.
339 form = ListNew(
340 [('mailman.most-desirable.org', 'mailman.most-desirable.org')],
342 'listname': 'xy#z',
343 'mail_host': 'mailman.most-desirable.org',
344 'list_owner': 'mailman.most-desirable.org',
345 'advertised': 'abcd',
346 'description': 'The Most Desirable organization',
349 self.assertFalse(form.is_valid())
350 self.assertTrue('listname' in form.errors)
351 self.assertEqual(
352 'Please enter a valid listname, "@" is not allowed in listname',
353 form.errors['listname'],
356 def test_form_fields_order(self):
357 domain_choices = [
358 ('mailman.most-desirable.org', 'mailman.most-desirable.org')
360 style_choices = [
361 ('legacy-default', 'Ordinary discussion mailing list style.'),
362 ('legacy-announce', 'Announce only mailing list style.'),
364 form = ListNew(
365 domain_choices,
366 style_choices,
368 'listname': 'xyz',
369 'mail_host': 'mailman.most-desirable.org',
370 'list_owner': 'mailman@most-desirable.org',
371 'list_style': 'legacy-default',
372 'advertised': 'True',
373 'description': 'The Most Desirable organization',
376 self.assertTrue(form.is_valid())
377 # The order of the fields should remain exactly like this.
378 self.assertEqual(
379 list(form.fields),
381 'listname',
382 'mail_host',
383 'list_owner',
384 'advertised',
385 'list_style',
386 'description',
391 class TestListIdentityForm(TestCase):
392 def test_not_required_fields(self):
393 # Only advertised is the required form field.
394 form = ListIdentityForm(
396 'advertised': 'True',
398 mlist=None,
400 self.assertTrue(form.is_valid(), form.errors)
402 def test_field_validations(self):
403 form = ListIdentityForm(
405 'advertised': 'abcd',
406 'description': 'This is the most desirable organization',
407 'info': 'This is a larger description of this mailing list.',
408 'display_name': 'Most Desirable Mailing List',
409 'subject_prefix': ' [Most Desirable] ',
410 'preferred_language': 'en',
411 'member_roster_visibility': 'public',
413 mlist=None,
415 self.assertFalse(form.is_valid())
416 self.assertTrue('advertised' in form.errors)
417 self.assertEqual(
419 'Select a valid choice. abcd is not one of the available choices.' # noqa: E501
421 form.errors['advertised'],
423 # We shouldn't be removing trailing whitespaces, but we
424 # should remove the leading ones.
425 self.assertEqual(
426 form.cleaned_data['subject_prefix'],
427 '[Most Desirable] ',
431 class TestListMassSubscription(TestCase):
432 def test_all_valid_email_formats(self):
433 form = ListMassSubscription(
435 'emails': """
436 jdoe@example.com
437 <jdoe@example.com>
438 John Doe <jdoe@example.com>
439 "John Doe" <jdoe@example.com>
440 jdoe@example.com (John Doe)"""
443 self.assertTrue(form.is_valid())
445 def test_required_fields(self):
446 form = ListMassSubscription({'email': ' '})
447 self.assertFalse(form.is_valid())
448 self.assertEqual(['This field is required.'], form.errors['emails'])
449 form = ListMassSubscription({'email': '----'})
450 self.assertFalse(form.is_valid())
451 self.assertEqual(['This field is required.'], form.errors['emails'])
453 @override_settings(
454 POSTORIUS_DEFAULTS={
455 'mass_subscription_pre_confirm': True,
456 'mass_subscription_pre_approve': True,
457 'mass_subscription_pre_verify': True,
458 'mass_subscription_invite': True,
461 def test_pre_verified_scenarios_with_override(self):
462 # Test when setting is True
463 form = ListMassSubscription({'emails': "abc@example.com"})
464 self.assertTrue(form.fields['pre_confirmed'].initial)
465 self.assertTrue(form.fields['pre_approved'].initial)
466 self.assertTrue(form.fields['pre_verified'].initial)
467 self.assertTrue(form.fields['invitation'].initial)
469 @override_settings(
470 POSTORIUS_DEFAULTS={
471 'mass_subscription_pre_confirm': False,
472 'mass_subscription_pre_approve': False,
473 'mass_subscription_pre_verify': False,
474 'mass_subscription_invite': False,
477 def test_pre_verified_scenarios_with_override_false(self):
478 # Test when setting is False
479 form = ListMassSubscription({'emails': "abc@example.com"})
480 self.assertFalse(form.fields['pre_confirmed'].initial)
481 self.assertFalse(form.fields['pre_approved'].initial)
482 self.assertFalse(form.fields['pre_verified'].initial)
483 self.assertFalse(form.fields['invitation'].initial)
485 @override_settings(POSTORIUS_DEFAULTS={})
486 def test_pre_verified_scenarios_with_no_override(self):
487 # Test when setting is empty
488 form = ListMassSubscription({'emails': "abc@example.com"})
489 self.assertTrue(form.fields['pre_confirmed'].initial)
490 self.assertTrue(form.fields['pre_approved'].initial)
491 self.assertFalse(form.fields['pre_verified'].initial)
492 self.assertFalse(form.fields['invitation'].initial)
495 class TestListMassRemoval(TestCase):
496 def test_all_valid_formats(self):
497 form = ListMassRemoval(
499 'emails': """
500 jdoe@example.com
501 <jdoe@example.com>
502 John Doe <jdoe@example.com>
503 "John Doe" <jdoe@example.com>
504 jdoe@example.com (John Doe)"""
507 self.assertTrue(form.is_valid())
510 class TestAddBanForm(TestCase):
511 def test_form_validity(self):
512 form = AddBanForm({'email': 'jdoe@example.com'})
513 self.assertTrue(form.is_valid())
515 def test_missing_fields_errors(self):
516 form = AddBanForm({})
517 self.assertFalse(form.is_valid())
518 self.assertTrue('email' in form.errors)
519 self.assertEqual(
520 form.errors['email'], ['Please enter an email address.']
523 @unittest.expectedFailure
524 def test_invalid_fields_type(self):
525 # Valid values for email is either a regexp or an email address.
526 # However, this is currently not validated by the form.
527 form = AddBanForm({'email': 'invalid@'})
528 self.assertFalse(form.is_valid())
529 self.assertTrue('email' in form.errors)
530 self.assertEqual(
531 form.errors['email'], ['Please enter a valid email address.']
535 class TestListHeaderMatchForm(TestCase):
536 def test_form_validity(self):
537 # Test by putting only required fields.
538 form = ListHeaderMatchForm(
539 {'header': 'To', 'pattern': 'value@example.com'}
541 self.assertTrue(form.is_valid())
542 # Test all fileds.
543 form = ListHeaderMatchForm(
545 'header': 'To',
546 'pattern': 'value@example.com',
547 'action': 'accept',
550 self.assertTrue(form.is_valid())
551 # Defer is not a valid action, so validation should fail here.
552 form = ListHeaderMatchForm(
553 {'header': 'To', 'pattern': 'value@example.com', 'action': 'defer'}
555 self.assertFalse(form.is_valid())
556 self.assertTrue('action' in form.errors)
559 class TestMemberModeration(TestCase):
560 def test_moderation_action_validity(self):
561 form = MemberModeration({'moderation_action': 'moderation'})
562 self.assertFalse(form.is_valid())
563 self.assertTrue('moderation_action' in form.errors)
564 self.assertEqual(
565 form.errors['moderation_action'],
567 'Select a valid choice. moderation is not one of the available choices.' # noqa: E501
571 def test_required_fields(self):
572 form = MemberModeration({})
573 self.assertTrue(form.is_valid())
576 class TestListAutomaticResponsesForm(TestCase):
578 fields = (
579 'autorespond_owner',
580 'autoresponse_owner_text',
581 'autorespond_postings',
582 'autoresponse_postings_text',
583 'autorespond_requests',
584 'autoresponse_request_text',
585 'autoresponse_grace_period',
586 'send_welcome_message',
587 'welcome_message_uri',
588 'send_goodbye_message',
589 'goodbye_message_uri',
590 'admin_immed_notify',
591 'admin_notify_mchanges',
594 def prepare_formdata(self, values):
595 return dict(
597 (key, val)
598 for key, val in zip(self.fields, values)
599 if val is not None
601 ) # noqa
603 def test_required_fields_only(self):
604 values = (
605 'respond_and_continue',
606 None,
607 'respond_and_continue',
608 None,
609 'respond_and_continue',
610 None,
611 '2',
612 None,
613 None,
614 None,
615 None,
616 None,
618 formdata = self.prepare_formdata(values)
619 form = ListAutomaticResponsesForm(formdata, mlist=None)
620 self.assertTrue(form.is_valid())
622 def test_all_values(self):
623 values = (
624 'respond_and_continue',
625 'Autorespond text',
626 'respond_and_continue',
627 'Autorespond text',
628 'respond_and_continue',
629 'Autorespond text',
630 '2',
631 'True',
632 'http://example.com/welcome_text',
633 'True',
634 'http://example.com/goodbye_message',
635 'True',
636 'False',
638 formdata = self.prepare_formdata(values)
639 form = ListAutomaticResponsesForm(formdata, mlist=None)
640 print(form.errors)
641 self.assertTrue(form.is_valid())
644 class TestAlterMessageForm(TestCase):
646 fields = (
647 'filter_content',
648 'collapse_alternatives',
649 'convert_html_to_plaintext',
650 'anonymous_list',
651 'include_rfc2369_headers',
652 'allow_list_posts',
653 'reply_list_posts',
654 'reply_to_address',
655 'first_strip_reply_to',
656 'reply_goes_to_list',
657 'posting_pipeline',
660 def prepare_formdata(self, values):
661 return dict(
663 (key, val)
664 for key, val in zip(self.fields, values)
665 if val is not None
667 ) # noqa
670 class TestDMARCMitigationsForm(TestCase):
671 def test_required_fields(self):
672 # All fields in the form are optional, so an empty form should be
673 # valid.
674 form = DMARCMitigationsForm({}, mlist=None)
675 self.assertTrue(form.is_valid())
677 def test_all_fields(self):
678 formdata = dict(
679 dmarc_mitigate_action='munge_from',
680 dmarc_mitigate_unconditionally='True',
681 dmarc_addresses='user@example.com\n^.*@example.net',
682 dmarc_moderation_notice='This is a moderation notice',
683 dmarc_wrapped_message_text='This is wrapped message text',
685 form = DMARCMitigationsForm(formdata, mlist=None)
686 self.assertTrue(form.is_valid())
689 class TestDigestSettingsForm(TestCase):
690 def test_required_fields(self):
691 form = DigestSettingsForm({}, mlist=None)
692 self.assertFalse(form.is_valid())
693 self.assertTrue('digest_size_threshold' in form.errors)
694 self.assertEqual(
695 form.errors['digest_size_threshold'], ['This field is required.']
697 form = DigestSettingsForm({'digest_size_threshold': 40}, mlist=None)
698 self.assertTrue(form.is_valid())
700 def test_all_fields(self):
701 formdata = dict(
702 digests_enabled='True',
703 digests_send_periodic='True',
704 digests_volume_frequency='daily',
705 digest_size_threshold='10',
707 form = DigestSettingsForm(formdata, mlist=None)
708 self.assertTrue(form.is_valid())
711 class TestMessageAcceptanceForm(TestCase):
713 fields = (
714 'acceptable_aliases',
715 'require_explicit_destination',
716 'administrivia',
717 'default_member_action',
718 'default_nonmember_action',
719 'max_message_size',
720 'max_num_recipients',
723 def prepare_formdata(self, values):
724 return dict(
726 (key, val)
727 for key, val in zip(self.fields, values)
728 if val is not None
730 ) # noqa
732 def test_required_fields(self):
733 # Without any fields, form should not be valid.
734 form = MessageAcceptanceForm({}, mlist=None)
735 self.assertFalse(form.is_valid())
736 # Now lets try with only required fields.
737 values = (None, None, None, 'hold', 'hold', 40, 100)
738 form = MessageAcceptanceForm(self.prepare_formdata(values), mlist=None)
739 print(form.errors)
740 self.assertTrue(form.is_valid())
742 def test_all_fields(self):
743 pass
746 class TestArchiveSettingsForm(TestCase):
747 def setUp(self):
748 self.mlist = create_mock_list()
749 archivers = {'pipermail': True, 'hyperkitty': True}
750 self.mlist.archivers.keys.side_effect = archivers.keys
751 self.mlist.archivers.__getitem__.side_effect = archivers.__getitem__
752 self.mlist.archivers.__iter__.side_effect = archivers.__iter__
753 self.mlist.archivers.__contains__.side_effect = archivers.__contains__
755 def test_required_fields(self):
756 # First try without any fields.
757 form = ArchiveSettingsForm({}, mlist=self.mlist)
758 self.assertFalse(form.is_valid())
759 self.assertTrue('archive_policy' in form.errors)
760 # Now, with only required fields, this should be a valid form.
761 form = ArchiveSettingsForm(
762 dict(archive_policy='public'), mlist=self.mlist
764 self.assertTrue(form.is_valid())
766 def test_all_fields(self):
767 formdata = dict(
768 archive_policy='public', archivers=['pipermail', 'hyperkitty']
770 form = ArchiveSettingsForm(formdata, mlist=self.mlist)
771 self.assertTrue(form.is_valid())
773 def test_setup_archivers_populated(self):
774 formdata = dict(
775 archive_policy='public', archivers=['pipermail', 'hyperkitty']
777 form = ArchiveSettingsForm(
778 formdata, mlist=self.mlist, initial={'archivers': None}
780 self.assertTrue(form.is_valid())
781 self.assertEqual(
782 form.initial['archivers'], ['hyperkitty', 'pipermail']
785 def test_optional_archive_rendering_field(self):
786 # Test that archive rendering mode is set only when Hyperkitty is
787 # installed.
788 formdata = dict(archive_policy='public', archivers=['pipermail'])
789 form = ArchiveSettingsForm(
790 formdata, mlist=self.mlist, initial={'archivers': None}
792 self.assertTrue(form.is_valid())
793 self.assertFalse('archive_rendering_mode' in form.fields)
794 # With Hyperkitty installed, the field should show up.
795 with unittest.mock.patch(
796 'postorius.forms.list_forms.apps.is_installed', return_value=True
798 formdata = dict(archive_policy='public', archivers=['pipermail'])
799 form = ArchiveSettingsForm(
800 formdata, mlist=self.mlist, initial={'archivers': None}
802 self.assertTrue(form.is_valid())
803 self.assertTrue('archive_rendering_mode' in form.fields)
806 class TestMemberPolicyForm(TestCase):
807 def test_required_fields(self):
808 form = MemberPolicyForm({}, mlist=None)
809 self.assertFalse(form.is_valid())
810 self.assertTrue('subscription_policy' in form.errors)
811 self.assertTrue('unsubscription_policy' in form.errors)
812 form = MemberPolicyForm(
813 dict(
814 subscription_policy='confirm', unsubscription_policy='confirm'
816 mlist=None,
818 self.assertTrue(form.is_valid())
821 class TestListAnonymousSubscribe(TestCase):
822 def test_required_fields_only(self):
823 form = ListAnonymousSubscribe(dict(email='bob@exmaple.com'))
824 self.assertTrue(form.is_valid())
826 def test_email_is_validated(self):
827 form = ListAnonymousSubscribe(dict(email='invalid'))
828 self.assertFalse(form.is_valid())
829 self.assertTrue('email' in form.errors)
830 self.assertEqual(
831 form.errors['email'], ['Please enter a valid email address.']
834 def test_all_fields(self):
835 form = ListAnonymousSubscribe(
836 dict(email='bob@example.com', display_name='Bob')
838 self.assertTrue(form.is_valid())