Merge ~twom/launchpad:text-types-in-registry-xmlrpc into launchpad:master

Proposed by Tom Wardill
Status: Merged
Approved by: Tom Wardill
Approved revision: 66a17aa8245722c9e288f492b3c7c3b5e1a8795b
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~twom/launchpad:text-types-in-registry-xmlrpc
Merge into: launchpad:master
Diff against target: 210 lines (+157/-3)
2 files modified
lib/lp/registry/tests/test_xmlrpc.py (+153/-3)
lib/lp/registry/xmlrpc/mailinglist.py (+4/-0)
Reviewer Review Type Date Requested Status
Colin Watson Approve
Review via email: mp+388121@code.launchpad.net

Commit message

Fix mailinglist XMLRPC callsites for text types

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) wrote :

Thanks for fixing up my mistake.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/registry/tests/test_xmlrpc.py b/lib/lp/registry/tests/test_xmlrpc.py
2index 5217f8c..79bf7f8 100644
3--- a/lib/lp/registry/tests/test_xmlrpc.py
4+++ b/lib/lp/registry/tests/test_xmlrpc.py
5@@ -5,12 +5,35 @@
6
7 __metaclass__ = type
8
9+from email import message_from_string
10+from textwrap import dedent
11+
12 from six.moves import xmlrpc_client
13+from zope.component import getUtility
14 from zope.security.proxy import removeSecurityProxy
15
16-from lp.registry.enums import PersonVisibility
17-from lp.testing import TestCaseWithFactory
18-from lp.testing.layers import DatabaseFunctionalLayer
19+from lp.registry.enums import (
20+ PersonVisibility,
21+ TeamMembershipPolicy,
22+ )
23+from lp.registry.interfaces.mailinglist import (
24+ IMailingListSet,
25+ IMessageApprovalSet,
26+ MailingListStatus,
27+ PostedMessageStatus,
28+ )
29+from lp.registry.interfaces.person import PersonalStanding
30+from lp.services.config import config
31+from lp.testing import (
32+ admin_logged_in,
33+ person_logged_in,
34+ TestCaseWithFactory,
35+ )
36+from lp.testing.layers import (
37+ DatabaseFunctionalLayer,
38+ LaunchpadFunctionalLayer,
39+ )
40+from lp.testing.mail_helpers import pop_notifications
41 from lp.testing.xmlrpc import XMLRPCTestTransport
42
43
44@@ -58,3 +81,130 @@ class TestCanonicalSSOApplication(TestCaseWithFactory):
45 public_rpc_proxy.getPersonDetailsByOpenIDIdentifier,
46 openid_identifier)
47 self.assertEqual(404, e.errcode)
48+
49+
50+class TestMailingListXMLRPC(TestCaseWithFactory):
51+
52+ layer = DatabaseFunctionalLayer
53+
54+ def setUp(self):
55+ super(TestMailingListXMLRPC, self).setUp()
56+ self.rpc_proxy = xmlrpc_client.ServerProxy(
57+ 'http://xmlrpc-private.launchpad.test:8087/mailinglists',
58+ transport=XMLRPCTestTransport())
59+
60+ def test_getMembershipInformation(self):
61+ team, member = self.factory.makeTeamWithMailingListSubscribers(
62+ 'team', auto_subscribe=False)
63+ result = self.rpc_proxy.getMembershipInformation(
64+ [team.name])
65+ self.assertIn(team.name, result.keys())
66+
67+ def test_reportStatus(self):
68+ # Successful constructions lead to ACTIVE lists.
69+ team = self.factory.makeTeam(name='team')
70+ team_list = getUtility(IMailingListSet).new(team, team.teamowner)
71+ self.rpc_proxy.getPendingActions()
72+ self.rpc_proxy.reportStatus({'team': 'success'})
73+ self.assertEqual(MailingListStatus.ACTIVE, team_list.status)
74+
75+ def test_isTeamPublic(self):
76+ self.factory.makeTeam(
77+ name='team-a', visibility=PersonVisibility.PUBLIC)
78+ self.factory.makeTeam(
79+ name='team-b', visibility=PersonVisibility.PRIVATE)
80+ self.assertIs(True, self.rpc_proxy.isTeamPublic('team-a'))
81+ self.assertIs(False, self.rpc_proxy.isTeamPublic('team-b'))
82+
83+ def test_isRegisteredInLaunchpad(self):
84+ self.factory.makeTeam(email='me@fndor.dom')
85+ self.assertFalse(
86+ self.rpc_proxy.isRegisteredInLaunchpad('me@fndor.dom'))
87+
88+ def test_inGoodStanding(self):
89+ self.factory.makePerson(email='no@eg.dom')
90+ yes_person = self.factory.makePerson(email='yes@eg.dom')
91+ with admin_logged_in():
92+ yes_person.personal_standing = PersonalStanding.GOOD
93+ self.assertIs(True, self.rpc_proxy.inGoodStanding('yes@eg.dom'))
94+ self.assertIs(False, self.rpc_proxy.inGoodStanding('no@eg.dom'))
95+
96+ def test_updateTeamAddresses(self):
97+ staging_config_name = self.factory.getUniqueString()
98+ config.push(
99+ staging_config_name,
100+ '\n[launchpad]\nis_demo: True\n'
101+ '\n[mailman]\nbuild_host_name: lists.launchpad.test\n')
102+ try:
103+ self.rpc_proxy.updateTeamAddresses('lists.launchpad.net')
104+ finally:
105+ config.pop(staging_config_name)
106+
107+
108+
109+class TestMailingListXMLRPCMessage(TestCaseWithFactory):
110+
111+ layer = LaunchpadFunctionalLayer
112+
113+ def setUp(self):
114+ super(TestMailingListXMLRPCMessage, self).setUp()
115+ self.rpc_proxy = xmlrpc_client.ServerProxy(
116+ 'http://xmlrpc-private.launchpad.test:8087/mailinglists',
117+ transport=XMLRPCTestTransport())
118+
119+ def makeMailingListAndHeldMessage(self, private=False):
120+ if private:
121+ visibility = PersonVisibility.PRIVATE
122+ else:
123+ visibility = PersonVisibility.PUBLIC
124+ owner = self.factory.makePerson()
125+ team = self.factory.makeTeam(
126+ name='team', owner=owner, visibility=visibility,
127+ membership_policy=TeamMembershipPolicy.RESTRICTED)
128+ with person_logged_in(owner):
129+ self.factory.makeMailingList(team, owner)
130+ sender = self.factory.makePerson(email='me@eg.dom')
131+ with person_logged_in(sender):
132+ message = message_from_string(dedent("""\
133+ From: me@eg.dom
134+ To: team@lists.launchpad.test
135+ Subject: A question
136+ Message-ID: <first-post>
137+ Date: Fri, 01 Aug 2000 01:08:59 -0000\n
138+ I have a question about this team.
139+ """))
140+ return team, sender, message
141+
142+ def test_holdMessage(self):
143+ # Calling holdMessages send a copy of the message text to Lp
144+ # and notifies a team admins to moderate it.
145+ team, sender, message = self.makeMailingListAndHeldMessage()
146+ pop_notifications()
147+ info = self.rpc_proxy.holdMessage('team', message.as_string())
148+ notifications = pop_notifications()
149+ found = getUtility(IMessageApprovalSet).getMessageByMessageID(
150+ '<first-post>')
151+ self.assertIs(True, info)
152+ self.assertIsNot(None, found)
153+ self.assertEqual(1, len(notifications))
154+ self.assertEqual(
155+ 'New mailing list message requiring approval for Team',
156+ notifications[0]['subject'])
157+ self.assertTextMatchesExpressionIgnoreWhitespace(
158+ '.*http://launchpad.test/~team/\+mailinglist-moderate.*',
159+ notifications[0].get_payload())
160+ self.assertEqual({}, self.rpc_proxy.getMessageDispositions())
161+
162+ def test_getMessageDispositions_accept(self):
163+ # List moderators can approve messages.
164+ team, sender, message = self.makeMailingListAndHeldMessage()
165+ pop_notifications()
166+ self.rpc_proxy.holdMessage('team', message.as_string())
167+ found = getUtility(IMessageApprovalSet).getMessageByMessageID(
168+ '<first-post>')
169+ found.approve(team.teamowner)
170+ self.assertEqual(PostedMessageStatus.APPROVAL_PENDING, found.status)
171+ self.assertEqual(
172+ {'<first-post>': ['team', 'accept']},
173+ self.rpc_proxy.getMessageDispositions())
174+ self.assertEqual(PostedMessageStatus.APPROVED, found.status)
175diff --git a/lib/lp/registry/xmlrpc/mailinglist.py b/lib/lp/registry/xmlrpc/mailinglist.py
176index 9a16123..6467dd5 100644
177--- a/lib/lp/registry/xmlrpc/mailinglist.py
178+++ b/lib/lp/registry/xmlrpc/mailinglist.py
179@@ -10,6 +10,7 @@ __all__ = [
180
181 import re
182
183+from six import ensure_text
184 from six.moves import xmlrpc_client
185 from zope.component import getUtility
186 from zope.interface import implementer
187@@ -106,6 +107,7 @@ class MailingListAPIView(LaunchpadXMLRPCView):
188 """See `IMailingListAPIView`."""
189 list_set = getUtility(IMailingListSet)
190 for team_name, action_status in statuses.items():
191+ team_name = ensure_text(team_name)
192 mailing_list = list_set.get(team_name)
193 if mailing_list is None:
194 return faults.NoSuchTeamMailingList(team_name)
195@@ -136,6 +138,7 @@ class MailingListAPIView(LaunchpadXMLRPCView):
196
197 def getMembershipInformation(self, teams):
198 """See `IMailingListAPIView`."""
199+ teams = [ensure_text(team) for team in teams]
200 mailing_list_set = getUtility(IMailingListSet)
201 response = {}
202 # There are two sets of email addresses we need. The first is the set
203@@ -243,6 +246,7 @@ class MailingListAPIView(LaunchpadXMLRPCView):
204 # pass 8-bit strings.
205 if isinstance(bytes, xmlrpc_client.Binary):
206 bytes = bytes.data
207+ team_name = ensure_text(team_name)
208 # Although it is illegal for an email header to have unencoded
209 # non-ascii characters, it is better to let the list owner
210 # process the message than to cause an oops.

Subscribers

People subscribed via source and target branches

to status/vote changes: