summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2011-04-22 19:58:07 -0400
committerBarry Warsaw2011-04-22 19:58:07 -0400
commit989267f6edbf55a1109d24c2b5e20051ea6a24a8 (patch)
tree8b290e5760cbb28d43a24a3e1460bdf7043c78a4
parentea77dd42093f453c4f3f3aad22d33952b3e3ec5a (diff)
downloadmailman-989267f6edbf55a1109d24c2b5e20051ea6a24a8.tar.gz
mailman-989267f6edbf55a1109d24c2b5e20051ea6a24a8.tar.zst
mailman-989267f6edbf55a1109d24c2b5e20051ea6a24a8.zip
-rw-r--r--src/mailman/interfaces/member.py12
-rw-r--r--src/mailman/model/docs/mailinglist.txt11
-rw-r--r--src/mailman/model/mailinglist.py5
-rw-r--r--src/mailman/rest/tests/test_membership.py50
4 files changed, 69 insertions, 9 deletions
diff --git a/src/mailman/interfaces/member.py b/src/mailman/interfaces/member.py
index fc635f21c..0676bfe78 100644
--- a/src/mailman/interfaces/member.py
+++ b/src/mailman/interfaces/member.py
@@ -28,6 +28,7 @@ __all__ = [
'MemberRole',
'MembershipError',
'MembershipIsBannedError',
+ 'MissingPreferredAddressError',
'NotAMemberError',
]
@@ -104,6 +105,17 @@ class MembershipIsBannedError(MembershipError):
self._address, self._mlist)
+class MissingPreferredAddressError(MembershipError):
+ """A user without a preferred address attempted to subscribe."""
+
+ def __init__(self, user):
+ super(MissingPreferredAddressError, self).__init__()
+ self._user = user
+
+ def __str__(self):
+ return 'User must have a preferred address: {0}'.format(self._user)
+
+
class NotAMemberError(MembershipError):
"""The address is not a member of the mailing list."""
diff --git a/src/mailman/model/docs/mailinglist.txt b/src/mailman/model/docs/mailinglist.txt
index ec9e37ee0..4d3250e76 100644
--- a/src/mailman/model/docs/mailinglist.txt
+++ b/src/mailman/model/docs/mailinglist.txt
@@ -152,3 +152,14 @@ this address is their preferred address.
>>> mlist.subscribe(user.preferred_address)
<Member: dave.person@example.com
on aardvark@example.com as MemberRole.member>
+
+A user cannot subscribe to a mailing list without a preferred address.
+
+ >>> user = user_manager.create_user('eperson@example.com', 'Elly Person')
+ >>> address = list(user.addresses)[0]
+ >>> address.verified_on = now()
+ >>> mlist.subscribe(user)
+ Traceback (most recent call last):
+ ...
+ MissingPreferredAddressError: User must have a preferred address:
+ <User "Elly Person" (2) at ...>
diff --git a/src/mailman/model/mailinglist.py b/src/mailman/model/mailinglist.py
index 2b205775e..9294fe7cc 100644
--- a/src/mailman/model/mailinglist.py
+++ b/src/mailman/model/mailinglist.py
@@ -43,7 +43,8 @@ from mailman.interfaces.domain import IDomainManager
from mailman.interfaces.languages import ILanguageManager
from mailman.interfaces.mailinglist import (
IAcceptableAlias, IAcceptableAliasSet, IMailingList, Personalization)
-from mailman.interfaces.member import AlreadySubscribedError, MemberRole
+from mailman.interfaces.member import (
+ AlreadySubscribedError, MemberRole, MissingPreferredAddressError)
from mailman.interfaces.mime import FilterType
from mailman.interfaces.user import IUser
from mailman.model import roster
@@ -458,6 +459,8 @@ class MailingList(Model):
raise AlreadySubscribedError(
self.fqdn_listname, subscriber.email, role)
elif IUser.providedBy(subscriber):
+ if subscriber.preferred_address is None:
+ raise MissingPreferredAddressError(subscriber)
member = store.find(
Member,
Member.role == role,
diff --git a/src/mailman/rest/tests/test_membership.py b/src/mailman/rest/tests/test_membership.py
index 1a911c688..7f6d5c237 100644
--- a/src/mailman/rest/tests/test_membership.py
+++ b/src/mailman/rest/tests/test_membership.py
@@ -73,7 +73,7 @@ class TestMembership(unittest.TestCase):
self.assertEqual(exc.msg, '404 Not Found')
else:
raise AssertionError('Expected HTTPError')
-
+
def test_try_to_leave_list_with_bogus_address(self):
# Try to leave a mailing list using an invalid membership address.
try:
@@ -151,13 +151,47 @@ class TestMembership(unittest.TestCase):
self.assertEqual(len(members), 1)
self.assertEqual(members[0].address.email, 'hugh/person@example.com')
- ## def test_join_as_user_with_preferred_address(self):
- ## anne = self._usermanager.create_user('anne@example.com')
- ## list(anne.addresses)[0].verified_on = now()
- ## self._mlist.subscribe(anne)
- ## config.db.commit()
- ## content, response = call_api('http://localhost:9001/3.0/members')
- ## raise AssertionError('incomplete test')
+ def test_join_as_user_with_preferred_address(self):
+ anne = self._usermanager.create_user('anne@example.com')
+ preferred = list(anne.addresses)[0]
+ preferred.verified_on = now()
+ anne.preferred_address = preferred
+ self._mlist.subscribe(anne)
+ config.db.commit()
+ content, response = call_api('http://localhost:9001/3.0/members')
+ self.assertEqual(response.status, 200)
+ self.assertEqual(int(content['total_size']), 1)
+ entry_0 = content['entries'][0]
+ self.assertEqual(entry_0['self_link'],
+ 'http://localhost:9001/3.0/members/1')
+ self.assertEqual(entry_0['role'], 'member')
+ self.assertEqual(entry_0['user'], 'http://localhost:9001/3.0/users/1')
+ self.assertEqual(entry_0['address'], 'anne@example.com')
+ self.assertEqual(entry_0['fqdn_listname'], 'test@example.com')
+
+ def test_member_changes_preferred_address(self):
+ anne = self._usermanager.create_user('anne@example.com')
+ preferred = list(anne.addresses)[0]
+ preferred.verified_on = now()
+ anne.preferred_address = preferred
+ self._mlist.subscribe(anne)
+ config.db.commit()
+ # Take a look at Anne's current membership.
+ content, response = call_api('http://localhost:9001/3.0/members')
+ self.assertEqual(int(content['total_size']), 1)
+ entry_0 = content['entries'][0]
+ self.assertEqual(entry_0['address'], 'anne@example.com')
+ # Anne registers a new address and makes it her preferred address.
+ # There are no changes to her membership.
+ new_preferred = anne.register('aperson@example.com')
+ new_preferred.verified_on = now()
+ anne.preferred_address = new_preferred
+ config.db.commit()
+ # Take another look at Anne's current membership.
+ content, response = call_api('http://localhost:9001/3.0/members')
+ self.assertEqual(int(content['total_size']), 1)
+ entry_0 = content['entries'][0]
+ self.assertEqual(entry_0['address'], 'aperson@example.com')