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

Reply via email to