/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5557.1.7 by John Arbash Meinel
Merge in the bzr.dev 5582
1
# Copyright (C) 2006-2011 Canonical Ltd
0.4.1 by Martin Pool
Start lp-register command
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0.4.1 by Martin Pool
Start lp-register command
16
0.4.8 by Martin Pool
More instrumentation of xmlrpc requests
17
import base64
18
from StringIO import StringIO
2978.5.1 by John Arbash Meinel
Fix bug #162494, 'bzr register-branch' needs proper auth handling.
19
import urlparse
0.4.5 by Martin Pool
Add structured test for parameters passed through xmlrpc
20
import xmlrpclib
21
2978.5.1 by John Arbash Meinel
Fix bug #162494, 'bzr register-branch' needs proper auth handling.
22
from bzrlib import (
23
    config,
24
    tests,
25
    ui,
26
    )
5582.1.2 by Jelmer Vernooij
Add NEWS entry, comment. Remove unnecessary code.
27
from bzrlib.tests import TestCaseWithTransport
0.4.1 by Martin Pool
Start lp-register command
28
0.4.5 by Martin Pool
Add structured test for parameters passed through xmlrpc
29
# local import
2898.3.8 by James Henstridge
Get rid of relative imports in Launchpad plugin.
30
from bzrlib.plugins.launchpad.lp_registration import (
0.4.26 by Martin Pool
(register-branch) Add test for link_branch_to_bug and fix its parameters
31
        BaseRequest,
32
        BranchBugLinkRequest,
33
        BranchRegistrationRequest,
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
34
        ResolveLaunchpadPathRequest,
0.4.26 by Martin Pool
(register-branch) Add test for link_branch_to_bug and fix its parameters
35
        LaunchpadService,
36
        )
0.4.5 by Martin Pool
Add structured test for parameters passed through xmlrpc
37
0.4.7 by Martin Pool
Start making provision to test using a mock xmlrpc transport.
38
0.4.12 by Martin Pool
doc
39
# TODO: Test that the command-line client, making sure that it'll pass the
40
# request through to a dummy transport, and that the transport will validate
41
# the results passed in.  Not sure how to get the transport object back out to
42
# validate that its OK - may not be necessary.
43
44
# TODO: Add test for (and implement) other command-line options to set
0.4.14 by Martin Pool
Update xmlrpc api
45
# project, author_email, description.
0.4.12 by Martin Pool
doc
46
47
# TODO: project_id is not properly handled -- must be passed in rpc or path.
48
0.4.8 by Martin Pool
More instrumentation of xmlrpc requests
49
class InstrumentedXMLRPCConnection(object):
50
    """Stands in place of an http connection for the purposes of testing"""
51
52
    def __init__(self, testcase):
53
        self.testcase = testcase
54
55
    def getreply(self):
56
        """Fake the http reply.
57
58
        :returns: (errcode, errmsg, headers)
59
        """
60
        return (200, 'OK', [])
61
5582.1.1 by Bazaar Builbot Net
Quick-and-dirty hack to fix bug #654733
62
    def getresponse(self, buffering=True):
5582.1.2 by Jelmer Vernooij
Add NEWS entry, comment. Remove unnecessary code.
63
        """Fake the http reply.
64
65
        This is used when running on Python 2.7, where xmlrpclib uses
66
        httplib.HTTPConnection in a different way than before.
67
        """
5582.1.1 by Bazaar Builbot Net
Quick-and-dirty hack to fix bug #654733
68
        class FakeHttpResponse(object):
69
70
            def __init__(self, status, reason, headers, body):
71
                self.status = status
72
                self.reason = reason
73
                self.headers = headers
74
                self.body = body
75
76
            def read(self, size=-1):
77
                return self.body.read(size)
78
79
        return FakeHttpResponse(200, 'OK', [], self.getfile())
80
0.4.8 by Martin Pool
More instrumentation of xmlrpc requests
81
    def getfile(self):
82
        """Return a fake file containing the response content."""
83
        return StringIO('''\
84
<?xml version="1.0" ?>
85
<methodResponse>
0.4.11 by Martin Pool
Check the correct params are seen by the server
86
    <params>
87
        <param>
88
            <value>
89
                <string>victoria dock</string>
90
            </value>
91
        </param>
92
    </params>
0.4.8 by Martin Pool
More instrumentation of xmlrpc requests
93
</methodResponse>''')
94
95
96
0.4.7 by Martin Pool
Start making provision to test using a mock xmlrpc transport.
97
class InstrumentedXMLRPCTransport(xmlrpclib.Transport):
98
2027.2.2 by Marien Zwart
Fixes for python 2.5.
99
    # Python 2.5's xmlrpclib looks for this.
100
    _use_datetime = False
101
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
102
    def __init__(self, testcase, expect_auth):
0.4.7 by Martin Pool
Start making provision to test using a mock xmlrpc transport.
103
        self.testcase = testcase
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
104
        self.expect_auth = expect_auth
5582.1.3 by Jelmer Vernooij
Revert _connection change, as it is apparently needed for Python >= 2.7.0 && Python < 2.7.2.
105
        self._connection = (None, None)
0.4.7 by Martin Pool
Start making provision to test using a mock xmlrpc transport.
106
107
    def make_connection(self, host):
108
        host, http_headers, x509 = self.get_host_info(host)
109
        test = self.testcase
0.4.10 by Martin Pool
Move test-specific values out of InstrumentedXMLRPCTransport
110
        self.connected_host = host
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
111
        if self.expect_auth:
112
            auth_hdrs = [v for k,v in http_headers if k == 'Authorization']
3376.2.15 by Martin Pool
Fix assertions in Launchpad registration tests
113
            if len(auth_hdrs) != 1:
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
114
                raise AssertionError("multiple auth headers: %r"
115
                    % (auth_hdrs,))
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
116
            authinfo = auth_hdrs[0]
117
            expected_auth = 'testuser@launchpad.net:testpassword'
118
            test.assertEquals(authinfo,
119
                    'Basic ' + base64.encodestring(expected_auth).strip())
3376.2.15 by Martin Pool
Fix assertions in Launchpad registration tests
120
        elif http_headers:
121
            raise AssertionError()
0.4.8 by Martin Pool
More instrumentation of xmlrpc requests
122
        return InstrumentedXMLRPCConnection(test)
0.4.7 by Martin Pool
Start making provision to test using a mock xmlrpc transport.
123
124
    def send_request(self, connection, handler_path, request_body):
125
        test = self.testcase
126
        self.got_request = True
127
128
    def send_host(self, conn, host):
129
        pass
130
131
    def send_user_agent(self, conn):
132
        # TODO: send special user agent string, including bzrlib version
133
        # number
134
        pass
135
136
    def send_content(self, conn, request_body):
137
        unpacked, method = xmlrpclib.loads(request_body)
3376.2.15 by Martin Pool
Fix assertions in Launchpad registration tests
138
        if None in unpacked:
139
            raise AssertionError(
140
                "xmlrpc result %r shouldn't contain None" % (unpacked,))
0.4.10 by Martin Pool
Move test-specific values out of InstrumentedXMLRPCTransport
141
        self.sent_params = unpacked
0.4.7 by Martin Pool
Start making provision to test using a mock xmlrpc transport.
142
143
0.4.22 by Martin Pool
(register-branch) Update tests to be in-process calls to a mock server.
144
class MockLaunchpadService(LaunchpadService):
145
2898.4.1 by James Henstridge
Make it possible to make unauthenticated XML-RPC requests.
146
    def send_request(self, method_name, method_params, authenticated):
0.4.22 by Martin Pool
(register-branch) Update tests to be in-process calls to a mock server.
147
        """Stash away the method details rather than sending them to a real server"""
148
        self.called_method_name = method_name
149
        self.called_method_params = method_params
2898.4.1 by James Henstridge
Make it possible to make unauthenticated XML-RPC requests.
150
        self.called_authenticated = authenticated
0.4.22 by Martin Pool
(register-branch) Update tests to be in-process calls to a mock server.
151
152
3200.2.1 by Robert Collins
* The ``register-branch`` command will now use the public url of the branch
153
class TestBranchRegistration(TestCaseWithTransport):
0.4.4 by Martin Pool
Start forming xmlrpc requests
154
0.4.23 by Martin Pool
(register-branch) fix ordering of parameters and restore transport-level test.
155
    def setUp(self):
156
        super(TestBranchRegistration, self).setUp()
157
        # make sure we have a reproducible standard environment
5570.3.6 by Vincent Ladeuil
Get rid of all _captureVar() calls, no test failures, pfew.
158
        self.overrideEnv('BZR_LP_XMLRPC_URL', None)
0.4.23 by Martin Pool
(register-branch) fix ordering of parameters and restore transport-level test.
159
0.4.22 by Martin Pool
(register-branch) Update tests to be in-process calls to a mock server.
160
    def test_register_help(self):
161
        """register-branch accepts --help"""
2581.1.4 by Martin Pool
fixup run_bzr syntax in launchpad plugin
162
        out, err = self.run_bzr(['register-branch', '--help'])
0.4.2 by Martin Pool
Rename command to 'register-branch'
163
        self.assertContainsRe(out, r'Register a branch')
164
3200.2.1 by Robert Collins
* The ``register-branch`` command will now use the public url of the branch
165
    def test_register_no_url_no_branch(self):
0.4.22 by Martin Pool
(register-branch) Update tests to be in-process calls to a mock server.
166
        """register-branch command requires parameters"""
3200.2.1 by Robert Collins
* The ``register-branch`` command will now use the public url of the branch
167
        self.make_repository('.')
168
        self.run_bzr_error(
169
            ['register-branch requires a public branch url - '
170
             'see bzr help register-branch'],
171
            'register-branch')
172
173
    def test_register_no_url_in_published_branch_no_error(self):
174
        b = self.make_branch('.')
175
        b.set_public_branch('http://test-server.com/bzr/branch')
176
        out, err = self.run_bzr(['register-branch', '--dry-run'])
177
        self.assertEqual('Branch registered.\n', out)
178
        self.assertEqual('', err)
179
180
    def test_register_no_url_in_unpublished_branch_errors(self):
181
        b = self.make_branch('.')
182
        out, err = self.run_bzr_error(['no public branch'],
183
            ['register-branch', '--dry-run'])
184
        self.assertEqual('', out)
0.4.3 by Martin Pool
More command line processing
185
1668.1.12 by Martin Pool
(launchpad plugin) Improved --dry-run that uses a dummy xmlrpc service.
186
    def test_register_dry_run(self):
2581.1.4 by Martin Pool
fixup run_bzr syntax in launchpad plugin
187
        out, err = self.run_bzr(['register-branch',
1668.1.12 by Martin Pool
(launchpad plugin) Improved --dry-run that uses a dummy xmlrpc service.
188
                                'http://test-server.com/bzr/branch',
2581.1.4 by Martin Pool
fixup run_bzr syntax in launchpad plugin
189
                                '--dry-run'])
1668.1.12 by Martin Pool
(launchpad plugin) Improved --dry-run that uses a dummy xmlrpc service.
190
        self.assertEquals(out, 'Branch registered.\n')
0.4.4 by Martin Pool
Start forming xmlrpc requests
191
0.4.23 by Martin Pool
(register-branch) fix ordering of parameters and restore transport-level test.
192
    def test_onto_transport(self):
4634.165.3 by Vincent Ladeuil
Delete all references to edge.launchpad.net in code and associated tests.
193
        """How the request is sent by transmitting across a mock Transport"""
0.4.23 by Martin Pool
(register-branch) fix ordering of parameters and restore transport-level test.
194
        # use a real transport, but intercept at the http/xml layer
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
195
        transport = InstrumentedXMLRPCTransport(self, expect_auth=True)
0.4.30 by Martin Pool
Fix wierd syntax errors in test
196
        service = LaunchpadService(transport)
0.4.23 by Martin Pool
(register-branch) fix ordering of parameters and restore transport-level test.
197
        service.registrant_email = 'testuser@launchpad.net'
198
        service.registrant_password = 'testpassword'
0.4.7 by Martin Pool
Start making provision to test using a mock xmlrpc transport.
199
        rego = BranchRegistrationRequest('http://test-server.com/bzr/branch',
0.4.23 by Martin Pool
(register-branch) fix ordering of parameters and restore transport-level test.
200
                'branch-id',
201
                'my test branch',
202
                'description',
203
                'author@launchpad.net',
204
                'product')
0.4.20 by Bjorn Tillenius
try to fix the tests.
205
        rego.submit(service)
5243.1.1 by Martin
Use the production server in the launchpad plugin rather than edge
206
        self.assertEquals(transport.connected_host, 'xmlrpc.launchpad.net')
0.4.14 by Martin Pool
Update xmlrpc api
207
        self.assertEquals(len(transport.sent_params), 6)
0.4.11 by Martin Pool
Check the correct params are seen by the server
208
        self.assertEquals(transport.sent_params,
0.4.23 by Martin Pool
(register-branch) fix ordering of parameters and restore transport-level test.
209
                ('http://test-server.com/bzr/branch',  # branch_url
210
                 'branch-id',                          # branch_name
211
                 'my test branch',                     # branch_title
212
                 'description',
213
                 'author@launchpad.net',
214
                 'product'))
0.4.8 by Martin Pool
More instrumentation of xmlrpc requests
215
        self.assertTrue(transport.got_request)
0.4.13 by Martin Pool
Update xmlrpc api to pass product name as a parameter.
216
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
217
    def test_onto_transport_unauthenticated(self):
4634.165.3 by Vincent Ladeuil
Delete all references to edge.launchpad.net in code and associated tests.
218
        """An unauthenticated request is transmitted across a mock Transport"""
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
219
        transport = InstrumentedXMLRPCTransport(self, expect_auth=False)
220
        service = LaunchpadService(transport)
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
221
        resolve = ResolveLaunchpadPathRequest('bzr')
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
222
        resolve.submit(service)
5243.1.1 by Martin
Use the production server in the launchpad plugin rather than edge
223
        self.assertEquals(transport.connected_host, 'xmlrpc.launchpad.net')
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
224
        self.assertEquals(len(transport.sent_params), 1)
225
        self.assertEquals(transport.sent_params, ('bzr', ))
226
        self.assertTrue(transport.got_request)
227
0.4.22 by Martin Pool
(register-branch) Update tests to be in-process calls to a mock server.
228
    def test_subclass_request(self):
229
        """Define a new type of xmlrpc request"""
230
        class DummyRequest(BaseRequest):
231
            _methodname = 'dummy_request'
232
            def _request_params(self):
233
                return (42,)
234
235
        service = MockLaunchpadService()
236
        service.registrant_email = 'test@launchpad.net'
237
        service.registrant_password = ''
238
        request = DummyRequest()
239
        request.submit(service)
240
        self.assertEquals(service.called_method_name, 'dummy_request')
241
        self.assertEquals(service.called_method_params, (42,))
242
0.4.24 by Martin Pool
(register-branch) additional test case against mock server
243
    def test_mock_server_registration(self):
244
        """Send registration to mock server"""
245
        test_case = self
246
        class MockRegistrationService(MockLaunchpadService):
2898.4.1 by James Henstridge
Make it possible to make unauthenticated XML-RPC requests.
247
            def send_request(self, method_name, method_params, authenticated):
0.4.24 by Martin Pool
(register-branch) additional test case against mock server
248
                test_case.assertEquals(method_name, "register_branch")
249
                test_case.assertEquals(list(method_params),
250
                        ['url', 'name', 'title', 'description', 'email', 'name'])
2898.4.1 by James Henstridge
Make it possible to make unauthenticated XML-RPC requests.
251
                test_case.assertEquals(authenticated, True)
0.4.24 by Martin Pool
(register-branch) additional test case against mock server
252
                return 'result'
253
        service = MockRegistrationService()
254
        rego = BranchRegistrationRequest('url', 'name', 'title',
255
                        'description', 'email', 'name')
256
        result = rego.submit(service)
257
        self.assertEquals(result, 'result')
0.4.25 by Martin Pool
(register-branch) additional test for registration with defaults
258
259
    def test_mock_server_registration_with_defaults(self):
260
        """Send registration to mock server"""
261
        test_case = self
262
        class MockRegistrationService(MockLaunchpadService):
2898.4.1 by James Henstridge
Make it possible to make unauthenticated XML-RPC requests.
263
            def send_request(self, method_name, method_params, authenticated):
0.4.25 by Martin Pool
(register-branch) additional test for registration with defaults
264
                test_case.assertEquals(method_name, "register_branch")
265
                test_case.assertEquals(list(method_params),
266
                        ['http://server/branch', 'branch', '', '', '', ''])
2898.4.1 by James Henstridge
Make it possible to make unauthenticated XML-RPC requests.
267
                test_case.assertEquals(authenticated, True)
0.4.25 by Martin Pool
(register-branch) additional test for registration with defaults
268
                return 'result'
269
        service = MockRegistrationService()
270
        rego = BranchRegistrationRequest('http://server/branch')
271
        result = rego.submit(service)
272
        self.assertEquals(result, 'result')
0.4.26 by Martin Pool
(register-branch) Add test for link_branch_to_bug and fix its parameters
273
274
    def test_mock_bug_branch_link(self):
275
        """Send bug-branch link to mock server"""
276
        test_case = self
277
        class MockService(MockLaunchpadService):
2898.4.1 by James Henstridge
Make it possible to make unauthenticated XML-RPC requests.
278
            def send_request(self, method_name, method_params, authenticated):
0.4.26 by Martin Pool
(register-branch) Add test for link_branch_to_bug and fix its parameters
279
                test_case.assertEquals(method_name, "link_branch_to_bug")
280
                test_case.assertEquals(list(method_params),
281
                        ['http://server/branch', 1234, ''])
2898.4.1 by James Henstridge
Make it possible to make unauthenticated XML-RPC requests.
282
                test_case.assertEquals(authenticated, True)
0.4.26 by Martin Pool
(register-branch) Add test for link_branch_to_bug and fix its parameters
283
                return 'http://launchpad.net/bug/1234'
284
        service = MockService()
285
        rego = BranchBugLinkRequest('http://server/branch', 1234)
286
        result = rego.submit(service)
287
        self.assertEquals(result, 'http://launchpad.net/bug/1234')
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
288
289
    def test_mock_resolve_lp_url(self):
290
        test_case = self
291
        class MockService(MockLaunchpadService):
292
            def send_request(self, method_name, method_params, authenticated):
2898.4.7 by James Henstridge
Fix up tests.
293
                test_case.assertEquals(method_name, "resolve_lp_path")
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
294
                test_case.assertEquals(list(method_params), ['bzr'])
295
                test_case.assertEquals(authenticated, False)
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
296
                return dict(urls=[
297
                        'bzr+ssh://bazaar.launchpad.net~bzr/bzr/trunk',
298
                        'sftp://bazaar.launchpad.net~bzr/bzr/trunk',
299
                        'bzr+http://bazaar.launchpad.net~bzr/bzr/trunk',
300
                        'http://bazaar.launchpad.net~bzr/bzr/trunk'])
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
301
        service = MockService()
2898.4.3 by James Henstridge
Make launchpad_transport_indirect() use XMLRPC to resolve the lp: URL.
302
        resolve = ResolveLaunchpadPathRequest('bzr')
2898.4.2 by James Henstridge
Add ResolveLaunchpadURLRequest() class to handle lp: URL resolution.
303
        result = resolve.submit(service)
2898.4.4 by James Henstridge
Changes to account for modifications to the XMLRPC API.
304
        self.assertTrue('urls' in result)
305
        self.assertEquals(result['urls'], [
306
                'bzr+ssh://bazaar.launchpad.net~bzr/bzr/trunk',
307
                'sftp://bazaar.launchpad.net~bzr/bzr/trunk',
308
                'bzr+http://bazaar.launchpad.net~bzr/bzr/trunk',
309
                'http://bazaar.launchpad.net~bzr/bzr/trunk'])
2978.5.2 by John Arbash Meinel
merge bzr.dev 2991
310
2978.5.1 by John Arbash Meinel
Fix bug #162494, 'bzr register-branch' needs proper auth handling.
311
312
class TestGatherUserCredentials(tests.TestCaseInTempDir):
313
314
    def setUp(self):
315
        super(TestGatherUserCredentials, self).setUp()
316
        # make sure we have a reproducible standard environment
5570.3.6 by Vincent Ladeuil
Get rid of all _captureVar() calls, no test failures, pfew.
317
        self.overrideEnv('BZR_LP_XMLRPC_URL', None)
2978.5.1 by John Arbash Meinel
Fix bug #162494, 'bzr register-branch' needs proper auth handling.
318
319
    def test_gather_user_credentials_has_password(self):
320
        service = LaunchpadService()
321
        service.registrant_password = 'mypassword'
322
        # This should be a basic no-op, since we already have the password
323
        service.gather_user_credentials()
324
        self.assertEqual('mypassword', service.registrant_password)
325
326
    def test_gather_user_credentials_from_auth_conf(self):
327
        auth_path = config.authentication_config_filename()
328
        service = LaunchpadService()
329
        g_conf = config.GlobalConfig()
330
        g_conf.set_user_option('email', 'Test User <test@user.com>')
331
        f = open(auth_path, 'wb')
332
        try:
333
            scheme, hostinfo = urlparse.urlsplit(service.service_url)[:2]
334
            f.write('[section]\n'
335
                    'scheme=%s\n'
336
                    'host=%s\n'
337
                    'user=test@user.com\n'
338
                    'password=testpass\n'
339
                    % (scheme, hostinfo))
340
        finally:
341
            f.close()
342
        self.assertIs(None, service.registrant_password)
343
        service.gather_user_credentials()
344
        self.assertEqual('test@user.com', service.registrant_email)
345
        self.assertEqual('testpass', service.registrant_password)
346
347
    def test_gather_user_credentials_prompts(self):
348
        service = LaunchpadService()
349
        self.assertIs(None, service.registrant_password)
350
        g_conf = config.GlobalConfig()
351
        g_conf.set_user_option('email', 'Test User <test@user.com>')
352
        stdout = tests.StringIOWrapper()
4368.3.4 by Vincent Ladeuil
Fix plugin test too :-/
353
        stderr = tests.StringIOWrapper()
2978.5.1 by John Arbash Meinel
Fix bug #162494, 'bzr register-branch' needs proper auth handling.
354
        ui.ui_factory = tests.TestUIFactory(stdin='userpass\n',
4368.3.4 by Vincent Ladeuil
Fix plugin test too :-/
355
                                            stdout=stdout, stderr=stderr)
2978.5.1 by John Arbash Meinel
Fix bug #162494, 'bzr register-branch' needs proper auth handling.
356
        self.assertIs(None, service.registrant_password)
357
        service.gather_user_credentials()
358
        self.assertEqual('test@user.com', service.registrant_email)
359
        self.assertEqual('userpass', service.registrant_password)
4368.3.4 by Vincent Ladeuil
Fix plugin test too :-/
360
        self.assertEquals('', stdout.getvalue())
361
        self.assertContainsRe(stderr.getvalue(),
2978.5.1 by John Arbash Meinel
Fix bug #162494, 'bzr register-branch' needs proper auth handling.
362
                             'launchpad.net password for test@user\\.com')
363