diff options
| author | Stephen A. Goss | 2011-08-24 17:05:48 -0700 |
|---|---|---|
| committer | Stephen A. Goss | 2011-08-24 17:05:48 -0700 |
| commit | ed21226dee1d139f6c8641f8253ed6eb51bbad10 (patch) | |
| tree | e5dc3dd10e21213916a485babaea4f0d37af00bf | |
| parent | 043562c695387a12e655997abf41cef77cb3d3a4 (diff) | |
| download | mailman-ed21226dee1d139f6c8641f8253ed6eb51bbad10.tar.gz mailman-ed21226dee1d139f6c8641f8253ed6eb51bbad10.tar.zst mailman-ed21226dee1d139f6c8641f8253ed6eb51bbad10.zip | |
LP 833132: add delivery_mode to member info in REST API, and make PATCHable with tests
| -rw-r--r-- | src/mailman/rest/docs/addresses.txt | 5 | ||||
| -rw-r--r-- | src/mailman/rest/docs/membership.rst | 104 | ||||
| -rw-r--r-- | src/mailman/rest/members.py | 30 |
3 files changed, 129 insertions, 10 deletions
diff --git a/src/mailman/rest/docs/addresses.txt b/src/mailman/rest/docs/addresses.txt index d82396e6b..71ab1f0f3 100644 --- a/src/mailman/rest/docs/addresses.txt +++ b/src/mailman/rest/docs/addresses.txt @@ -169,6 +169,7 @@ Elle can get her memberships for each of her email addresses. ... 'elle@example.com/memberships') entry 0: address: elle@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: "..." role: member @@ -176,6 +177,7 @@ Elle can get her memberships for each of her email addresses. user: http://localhost:9001/3.0/users/2 entry 1: address: elle@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: "..." role: member @@ -204,6 +206,7 @@ does not show up in the list of memberships for his other address. ... 'elle@example.com/memberships') entry 0: address: elle@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: "..." role: member @@ -211,6 +214,7 @@ does not show up in the list of memberships for his other address. user: http://localhost:9001/3.0/users/2 entry 1: address: elle@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: "..." role: member @@ -224,6 +228,7 @@ does not show up in the list of memberships for his other address. ... 'eperson@example.com/memberships') entry 0: address: eperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: "..." role: member diff --git a/src/mailman/rest/docs/membership.rst b/src/mailman/rest/docs/membership.rst index bed4f425d..46c61631f 100644 --- a/src/mailman/rest/docs/membership.rst +++ b/src/mailman/rest/docs/membership.rst @@ -42,6 +42,7 @@ the REST interface. >>> dump_json('http://localhost:9001/3.0/members') entry 0: address: bperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -55,6 +56,7 @@ Bart's specific membership can be accessed directly: >>> dump_json('http://localhost:9001/3.0/members/1') address: bperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -68,6 +70,7 @@ the REST interface. >>> dump_json('http://localhost:9001/3.0/members') entry 0: address: bperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -75,6 +78,7 @@ the REST interface. user: http://localhost:9001/3.0/users/1 entry 1: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -93,6 +97,7 @@ subscribes, she is returned first. >>> dump_json('http://localhost:9001/3.0/members') entry 0: address: aperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -100,6 +105,7 @@ subscribes, she is returned first. user: http://localhost:9001/3.0/users/3 entry 1: address: bperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -107,6 +113,7 @@ subscribes, she is returned first. user: http://localhost:9001/3.0/users/1 entry 2: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -129,6 +136,7 @@ User ids are different than member ids. >>> dump_json('http://localhost:9001/3.0/members') entry 0: address: aperson@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: ... role: member @@ -136,6 +144,7 @@ User ids are different than member ids. user: http://localhost:9001/3.0/users/3 entry 1: address: cperson@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: ... role: member @@ -143,6 +152,7 @@ User ids are different than member ids. user: http://localhost:9001/3.0/users/2 entry 2: address: aperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -150,6 +160,7 @@ User ids are different than member ids. user: http://localhost:9001/3.0/users/3 entry 3: address: bperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -157,6 +168,7 @@ User ids are different than member ids. user: http://localhost:9001/3.0/users/1 entry 4: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -172,6 +184,7 @@ We can also get just the members of a single mailing list. ... 'http://localhost:9001/3.0/lists/ant@example.com/roster/member') entry 0: address: aperson@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: ... role: member @@ -179,6 +192,7 @@ We can also get just the members of a single mailing list. user: http://localhost:9001/3.0/users/3 entry 1: address: cperson@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: ... role: member @@ -203,6 +217,7 @@ mailing list. >>> dump_json('http://localhost:9001/3.0/members') entry 0: address: dperson@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: ... role: moderator @@ -210,6 +225,7 @@ mailing list. user: http://localhost:9001/3.0/users/4 entry 1: address: aperson@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: ... role: member @@ -217,6 +233,7 @@ mailing list. user: http://localhost:9001/3.0/users/3 entry 2: address: cperson@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: ... role: member @@ -224,6 +241,7 @@ mailing list. user: http://localhost:9001/3.0/users/2 entry 3: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: owner @@ -231,6 +249,7 @@ mailing list. user: http://localhost:9001/3.0/users/2 entry 4: address: aperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -238,6 +257,7 @@ mailing list. user: http://localhost:9001/3.0/users/3 entry 5: address: bperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -245,6 +265,7 @@ mailing list. user: http://localhost:9001/3.0/users/1 entry 6: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -260,6 +281,7 @@ We can access all the owners of a list. ... 'http://localhost:9001/3.0/lists/bee@example.com/roster/owner') entry 0: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: owner @@ -278,6 +300,7 @@ A specific member can always be referenced by their role and address. >>> dump_json('http://localhost:9001/3.0/lists/' ... 'bee@example.com/owner/cperson@example.com') address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: owner @@ -292,6 +315,7 @@ example, we can search for all the memberships of a particular address. ... }) entry 0: address: aperson@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: ... role: member @@ -299,6 +323,7 @@ example, we can search for all the memberships of a particular address. user: http://localhost:9001/3.0/users/3 entry 1: address: aperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -315,6 +340,7 @@ Or, we can find all the memberships for a particular mailing list. ... }) entry 0: address: aperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -322,6 +348,7 @@ Or, we can find all the memberships for a particular mailing list. user: http://localhost:9001/3.0/users/3 entry 1: address: bperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -329,6 +356,7 @@ Or, we can find all the memberships for a particular mailing list. user: http://localhost:9001/3.0/users/1 entry 2: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -336,12 +364,13 @@ Or, we can find all the memberships for a particular mailing list. user: http://localhost:9001/3.0/users/2 entry 3: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: owner self_link: http://localhost:9001/3.0/members/7 user: http://localhost:9001/3.0/users/2 - http_etag: "66836d0f23bed36fa9e0cda1e5dec7e5b0797743" + http_etag: "..." start: 0 total_size: 4 @@ -354,6 +383,7 @@ list. ... }) entry 0: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -361,6 +391,7 @@ list. user: http://localhost:9001/3.0/users/2 entry 1: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: owner @@ -378,6 +409,7 @@ Or, we can find all the memberships for an address with a specific role. ... }) entry 0: address: cperson@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: ... role: member @@ -385,6 +417,7 @@ Or, we can find all the memberships for an address with a specific role. user: http://localhost:9001/3.0/users/2 entry 1: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -403,6 +436,7 @@ Finally, we can search for a specific member given all three criteria. ... }) entry 0: address: cperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: ... role: member @@ -450,6 +484,7 @@ Elly is now a known user, and a member of the mailing list. ... entry 3: address: eperson@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: ... role: member @@ -487,6 +522,7 @@ list with her preferred address. ... entry 4: address: gwen@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: "..." role: member @@ -509,6 +545,7 @@ the new address. ... entry 4: address: gwen.person@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: "..." role: member @@ -565,7 +602,68 @@ Fred joins the `ant` mailing list but wants MIME digest delivery. >>> memberships[0] <Member: Fred Person <fperson@example.com> on ant@example.com as MemberRole.member> + >>> print memberships[0].delivery_mode.enumname + mime_digests + + >>> dump_json('http://localhost:9001/3.0/members/10') + address: fperson@example.com + delivery_mode: mime_digests + fqdn_listname: ant@example.com + http_etag: "..." + role: member + self_link: http://localhost:9001/3.0/members/10 + user: http://localhost:9001/3.0/users/7 +Fred wants to change his delivery from MIME digest back to regular delivery. +This can be done by PATCH'ing his member with the `delivery_mode` +parameter. +:: + + >>> transaction.abort() + >>> dump_json('http://localhost:9001/3.0/members/10', { + ... 'delivery_mode': 'regular', + ... }, method='PATCH') + content-length: 0 + date: ... + server: ... + status: 204 + + >>> dump_json('http://localhost:9001/3.0/members/10') + address: fperson@example.com + delivery_mode: regular + fqdn_listname: ant@example.com + http_etag: "..." + role: member + self_link: http://localhost:9001/3.0/members/10 + user: http://localhost:9001/3.0/users/7 + +You can't PATCH a nonexistent member object. +:: + + >>> dump_json('http://localhost:9001/3.0/members/99', { + ... 'delivery_mode': 'regular', + ... }, method='PATCH') + Traceback (most recent call last): + ... + HTTPError: HTTP Error 404: 404 Not Found + +You can't PATCH a member with no attributes. +:: + + >>> dump_json('http://localhost:9001/3.0/members/10', method='PATCH') + Traceback (most recent call last): + ... + HTTPError: HTTP Error 400: 400 Bad Request + +You can't PATCH a member with anything other than `address` or `delivery_mode`. +:: + + >>> dump_json('http://localhost:9001/3.0/members/10', { + ... 'powers': 'super', + ... }, method='PATCH') + Traceback (most recent call last): + ... + HTTPError: HTTP Error 400: Unexpected parameters: powers Changing delivery address ========================= @@ -601,6 +699,7 @@ addresses. ... entry 5: address: herb@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: "..." role: member @@ -609,6 +708,7 @@ addresses. ... entry 10: address: herb@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: "..." role: member @@ -664,6 +764,7 @@ his membership ids have not changed. ... 'hperson@example.com/memberships') entry 0: address: hperson@example.com + delivery_mode: regular fqdn_listname: ant@example.com http_etag: "..." role: member @@ -671,6 +772,7 @@ his membership ids have not changed. user: http://localhost:9001/3.0/users/8 entry 1: address: hperson@example.com + delivery_mode: regular fqdn_listname: bee@example.com http_etag: "..." role: member diff --git a/src/mailman/rest/members.py b/src/mailman/rest/members.py index 047c375bb..2ddd24dc9 100644 --- a/src/mailman/rest/members.py +++ b/src/mailman/rest/members.py @@ -59,6 +59,7 @@ class _MemberBase(resource.Resource, CollectionMixin): role=role, user=path_to('users/{0}'.format(member.user.user_id)), self_link=path_to('members/{0}'.format(member.member_id)), + delivery_mode=member.delivery_mode, ) def _get_collection(self, request): @@ -124,17 +125,28 @@ class AMember(_MemberBase): This is how subscription changes are done. """ - # Currently, only the `address` parameter can be patched. - values = Validator(address=unicode)(request) - assert len(values) == 1, 'Unexpected values' - email = values['address'] - address = getUtility(IUserManager).get_address(email) - if address is None: - return http.bad_request([], b'Address not registered') + # Currently, only the `address` or `delivery_mode` parameters can be patched. + if self._member is None: + return http.not_found() try: - self._member.address = address - except (MembershipError, UnverifiedAddressError) as error: + values = Validator(address=unicode, + delivery_mode=enum_validator(DeliveryMode), + _optional=('delivery_mode', 'address'))(request) + except ValueError as error: return http.bad_request([], str(error)) + if len(values) == 0: + return http.bad_request() + if 'address' in values: + email = values['address'] + address = getUtility(IUserManager).get_address(email) + if address is None: + return http.bad_request([], b'Address not registered') + try: + self._member.address = address + except (MembershipError, UnverifiedAddressError) as error: + return http.bad_request([], str(error)) + if 'delivery_mode' in values: + self._member.preferences.delivery_mode = values['delivery_mode'] return no_content() |
