Barry Warsaw pushed to branch master at mailman / Mailman
Commits: fdc95199 by Aurélien Bompard at 2016-07-12T19:06:19-04:00 REST: allow setting a member's moderation_action to None - - - - - 5ef33f75 by Aurélien Bompard at 2016-07-12T19:06:19-04:00 Fix import order - - - - - 9e7bab1d by Barry Warsaw at 2016-07-12T19:37:53-04:00 allow_none -> allow_blank - - - - - 9b31555c by Barry Warsaw at 2016-07-12T19:41:56-04:00 Add NEWS - - - - - 6 changed files: - src/mailman/docs/NEWS.rst - src/mailman/rest/docs/membership.rst - src/mailman/rest/members.py - src/mailman/rest/tests/test_validator.py - src/mailman/rest/validator.py - src/mailman/rest/wsgiapp.py Changes: ===================================== src/mailman/docs/NEWS.rst ===================================== --- a/src/mailman/docs/NEWS.rst +++ b/src/mailman/docs/NEWS.rst @@ -206,6 +206,9 @@ REST set ``absorb_existing=True`` in the POST data, the existing user will be merged into the newly created on. Given by Aurélien Bompard. * Port to Falcon 1.0 (Closes #20) + * A member's ``moderation_action`` can be reset, allowing fallback to the + list's ``default_member_action`` by setting the attribute to the empty + string in the REST API. Given by Aurélien Bompard. Other ----- ===================================== src/mailman/rest/docs/membership.rst ===================================== --- a/src/mailman/rest/docs/membership.rst +++ b/src/mailman/rest/docs/membership.rst @@ -962,6 +962,28 @@ the attribute to the member's resource. moderation_action: hold ... +It can be reset to the list default by patching an empty value. +:: + + >>> dump_json('http://localhost:9001/3.0/members/10', { + ... 'moderation_action': '', + ... }, method='PATCH') + content-length: 0 + date: ... + server: ... + status: 204 + + >>> dump_json('http://localhost:9001/3.0/members/10') + address: http://localhost:9001/3.0/addresses/hper...@example.com + delivery_mode: regular + email: hper...@example.com + http_etag: "..." + list_id: ant.example.com + member_id: 10 + role: member + self_link: http://localhost:9001/3.0/members/10 + user: http://localhost:9001/3.0/users/7 + Handling the list of banned addresses ===================================== ===================================== src/mailman/rest/members.py ===================================== --- a/src/mailman/rest/members.py +++ b/src/mailman/rest/members.py @@ -167,7 +167,7 @@ class AMember(_MemberBase): values = Validator( address=str, delivery_mode=enum_validator(DeliveryMode), - moderation_action=enum_validator(Action), + moderation_action=enum_validator(Action, allow_blank=True), _optional=('address', 'delivery_mode', 'moderation_action'), )(request) except ValueError as error: ===================================== src/mailman/rest/tests/test_validator.py ===================================== --- a/src/mailman/rest/tests/test_validator.py +++ b/src/mailman/rest/tests/test_validator.py @@ -20,9 +20,10 @@ import unittest from mailman.core.api import API30, API31 +from mailman.interfaces.action import Action from mailman.interfaces.usermanager import IUserManager from mailman.rest.validator import ( - list_of_strings_validator, subscriber_validator) + enum_validator, list_of_strings_validator, subscriber_validator) from mailman.testing.layers import RESTLayer from zope.component import getUtility @@ -80,3 +81,13 @@ class TestValidators(unittest.TestCase): def test_subscriber_validator_email_address_API31(self): self.assertEqual(subscriber_validator(API31)('a...@example.com'), 'a...@example.com') + + def test_enum_validator_valid(self): + self.assertEqual(enum_validator(Action)('hold'), Action.hold) + + def test_enum_validator_invalid(self): + self.assertRaises(ValueError, + enum_validator(Action), 'not-a-thing') + + def test_enum_validator_blank(self): + self.assertEqual(enum_validator(Action, allow_blank=True)(''), None) ===================================== src/mailman/rest/validator.py ===================================== --- a/src/mailman/rest/validator.py +++ b/src/mailman/rest/validator.py @@ -52,12 +52,15 @@ class ReadOnlyPATCHRequestError(RESTError): class enum_validator: """Convert an enum value name into an enum value.""" - def __init__(self, enum_class): + def __init__(self, enum_class, *, allow_blank=False): self._enum_class = enum_class + self._allow_blank = allow_blank def __call__(self, enum_value): # This will raise a KeyError if the enum value is unknown. The # Validator API requires turning this into a ValueError. + if not enum_value and self._allow_blank: + return None try: return self._enum_class[enum_value] except KeyError as exception: ===================================== src/mailman/rest/wsgiapp.py ===================================== --- a/src/mailman/rest/wsgiapp.py +++ b/src/mailman/rest/wsgiapp.py @@ -200,6 +200,8 @@ class RootedAPI(API): # Let Falcon parse the form data into the request object's # .params attribute. self.req_options.auto_parse_form_urlencoded = True + # Don't ignore empty query parameters. + self.req_options.keep_blank_qs_values = True # Override the base class implementation to wrap a transactional # handler around the call, so that the current transaction is View it on GitLab: https://gitlab.com/mailman/mailman/compare/0e37e111c1d2e83d37743d124628e65eb56a8b5a...9b31555c180aa703d6fed0dc2cbaeda51de124c3
_______________________________________________ Mailman-checkins mailing list Mailman-checkins@python.org Unsubscribe: https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org