74
82
# Python 2.5's xmlrpclib looks for this.
75
83
_use_datetime = False
77
def __init__(self, testcase):
85
def __init__(self, testcase, expect_auth):
78
86
self.testcase = testcase
87
self.expect_auth = expect_auth
80
89
def make_connection(self, host):
81
90
host, http_headers, x509 = self.get_host_info(host)
82
91
test = self.testcase
83
92
self.connected_host = host
84
auth_hdrs = [v for k,v in http_headers if k == 'Authorization']
85
assert len(auth_hdrs) == 1
86
authinfo = auth_hdrs[0]
87
expected_auth = 'testuser@launchpad.net:testpassword'
88
test.assertEquals(authinfo,
89
'Basic ' + base64.encodestring(expected_auth).strip())
94
auth_hdrs = [v for k,v in http_headers if k == 'Authorization']
95
if len(auth_hdrs) != 1:
96
raise AssertionError("multiple auth headers: %r"
98
authinfo = auth_hdrs[0]
99
expected_auth = 'testuser@launchpad.net:testpassword'
100
test.assertEquals(authinfo,
101
'Basic ' + base64.encodestring(expected_auth).strip())
103
raise AssertionError()
90
104
return InstrumentedXMLRPCConnection(test)
92
106
def send_request(self, connection, handler_path, request_body):
104
118
def send_content(self, conn, request_body):
105
119
unpacked, method = xmlrpclib.loads(request_body)
106
assert None not in unpacked, \
107
"xmlrpc result %r shouldn't contain None" % (unpacked,)
121
raise AssertionError(
122
"xmlrpc result %r shouldn't contain None" % (unpacked,))
108
123
self.sent_params = unpacked
111
126
class MockLaunchpadService(LaunchpadService):
113
def send_request(self, method_name, method_params):
128
def send_request(self, method_name, method_params, authenticated):
114
129
"""Stash away the method details rather than sending them to a real server"""
115
130
self.called_method_name = method_name
116
131
self.called_method_params = method_params
119
class TestBranchRegistration(TestCase):
132
self.called_authenticated = authenticated
135
class TestBranchRegistration(TestCaseWithTransport):
120
136
SAMPLE_URL = 'http://bazaar-vcs.org/bzr/bzr.dev/'
121
137
SAMPLE_OWNER = 'jhacker@foo.com'
122
138
SAMPLE_BRANCH_ID = 'bzr.dev'
125
141
super(TestBranchRegistration, self).setUp()
126
142
# make sure we have a reproducible standard environment
127
if 'BZR_LP_XMLRPC_URL' in os.environ:
128
del os.environ['BZR_LP_XMLRPC_URL']
143
self._captureVar('BZR_LP_XMLRPC_URL', None)
130
145
def test_register_help(self):
131
146
"""register-branch accepts --help"""
132
out, err = self.run_bzr('register-branch', '--help')
147
out, err = self.run_bzr(['register-branch', '--help'])
133
148
self.assertContainsRe(out, r'Register a branch')
135
def test_register_no_url(self):
150
def test_register_no_url_no_branch(self):
136
151
"""register-branch command requires parameters"""
137
self.run_bzr('register-branch', retcode=3)
152
self.make_repository('.')
154
['register-branch requires a public branch url - '
155
'see bzr help register-branch'],
158
def test_register_no_url_in_published_branch_no_error(self):
159
b = self.make_branch('.')
160
b.set_public_branch('http://test-server.com/bzr/branch')
161
out, err = self.run_bzr(['register-branch', '--dry-run'])
162
self.assertEqual('Branch registered.\n', out)
163
self.assertEqual('', err)
165
def test_register_no_url_in_unpublished_branch_errors(self):
166
b = self.make_branch('.')
167
out, err = self.run_bzr_error(['no public branch'],
168
['register-branch', '--dry-run'])
169
self.assertEqual('', out)
139
171
def test_register_dry_run(self):
140
out, err = self.run_bzr('register-branch',
172
out, err = self.run_bzr(['register-branch',
141
173
'http://test-server.com/bzr/branch',
143
175
self.assertEquals(out, 'Branch registered.\n')
145
177
def test_onto_transport(self):
146
178
"""Test how the request is sent by transmitting across a mock Transport"""
147
179
# use a real transport, but intercept at the http/xml layer
148
transport = InstrumentedXMLRPCTransport(self)
180
transport = InstrumentedXMLRPCTransport(self, expect_auth=True)
149
181
service = LaunchpadService(transport)
150
182
service.registrant_email = 'testuser@launchpad.net'
151
183
service.registrant_password = 'testpassword'
168
200
self.assertTrue(transport.got_request)
202
def test_onto_transport_unauthenticated(self):
203
"""Test how an unauthenticated request is transmitted across a mock Transport"""
204
transport = InstrumentedXMLRPCTransport(self, expect_auth=False)
205
service = LaunchpadService(transport)
206
resolve = ResolveLaunchpadPathRequest('bzr')
207
resolve.submit(service)
208
self.assertEquals(transport.connected_host, 'xmlrpc.edge.launchpad.net')
209
self.assertEquals(len(transport.sent_params), 1)
210
self.assertEquals(transport.sent_params, ('bzr', ))
211
self.assertTrue(transport.got_request)
170
213
def test_subclass_request(self):
171
214
"""Define a new type of xmlrpc request"""
172
215
class DummyRequest(BaseRequest):
186
229
"""Send registration to mock server"""
188
231
class MockRegistrationService(MockLaunchpadService):
189
def send_request(self, method_name, method_params):
232
def send_request(self, method_name, method_params, authenticated):
190
233
test_case.assertEquals(method_name, "register_branch")
191
234
test_case.assertEquals(list(method_params),
192
235
['url', 'name', 'title', 'description', 'email', 'name'])
236
test_case.assertEquals(authenticated, True)
194
238
service = MockRegistrationService()
195
239
rego = BranchRegistrationRequest('url', 'name', 'title',
201
245
"""Send registration to mock server"""
203
247
class MockRegistrationService(MockLaunchpadService):
204
def send_request(self, method_name, method_params):
248
def send_request(self, method_name, method_params, authenticated):
205
249
test_case.assertEquals(method_name, "register_branch")
206
250
test_case.assertEquals(list(method_params),
207
251
['http://server/branch', 'branch', '', '', '', ''])
252
test_case.assertEquals(authenticated, True)
209
254
service = MockRegistrationService()
210
255
rego = BranchRegistrationRequest('http://server/branch')
215
260
"""Send bug-branch link to mock server"""
217
262
class MockService(MockLaunchpadService):
218
def send_request(self, method_name, method_params):
263
def send_request(self, method_name, method_params, authenticated):
219
264
test_case.assertEquals(method_name, "link_branch_to_bug")
220
265
test_case.assertEquals(list(method_params),
221
266
['http://server/branch', 1234, ''])
267
test_case.assertEquals(authenticated, True)
222
268
return 'http://launchpad.net/bug/1234'
223
269
service = MockService()
224
270
rego = BranchBugLinkRequest('http://server/branch', 1234)
225
271
result = rego.submit(service)
226
272
self.assertEquals(result, 'http://launchpad.net/bug/1234')
274
def test_mock_resolve_lp_url(self):
276
class MockService(MockLaunchpadService):
277
def send_request(self, method_name, method_params, authenticated):
278
test_case.assertEquals(method_name, "resolve_lp_path")
279
test_case.assertEquals(list(method_params), ['bzr'])
280
test_case.assertEquals(authenticated, False)
282
'bzr+ssh://bazaar.launchpad.net~bzr/bzr/trunk',
283
'sftp://bazaar.launchpad.net~bzr/bzr/trunk',
284
'bzr+http://bazaar.launchpad.net~bzr/bzr/trunk',
285
'http://bazaar.launchpad.net~bzr/bzr/trunk'])
286
service = MockService()
287
resolve = ResolveLaunchpadPathRequest('bzr')
288
result = resolve.submit(service)
289
self.assertTrue('urls' in result)
290
self.assertEquals(result['urls'], [
291
'bzr+ssh://bazaar.launchpad.net~bzr/bzr/trunk',
292
'sftp://bazaar.launchpad.net~bzr/bzr/trunk',
293
'bzr+http://bazaar.launchpad.net~bzr/bzr/trunk',
294
'http://bazaar.launchpad.net~bzr/bzr/trunk'])
297
class TestGatherUserCredentials(tests.TestCaseInTempDir):
300
super(TestGatherUserCredentials, self).setUp()
301
# make sure we have a reproducible standard environment
302
self._captureVar('BZR_LP_XMLRPC_URL', None)
304
def test_gather_user_credentials_has_password(self):
305
service = LaunchpadService()
306
service.registrant_password = 'mypassword'
307
# This should be a basic no-op, since we already have the password
308
service.gather_user_credentials()
309
self.assertEqual('mypassword', service.registrant_password)
311
def test_gather_user_credentials_from_auth_conf(self):
312
auth_path = config.authentication_config_filename()
313
service = LaunchpadService()
314
g_conf = config.GlobalConfig()
315
g_conf.set_user_option('email', 'Test User <test@user.com>')
316
f = open(auth_path, 'wb')
318
scheme, hostinfo = urlparse.urlsplit(service.service_url)[:2]
319
f.write('[section]\n'
322
'user=test@user.com\n'
323
'password=testpass\n'
324
% (scheme, hostinfo))
327
self.assertIs(None, service.registrant_password)
328
service.gather_user_credentials()
329
self.assertEqual('test@user.com', service.registrant_email)
330
self.assertEqual('testpass', service.registrant_password)
332
def test_gather_user_credentials_prompts(self):
333
service = LaunchpadService()
334
self.assertIs(None, service.registrant_password)
335
g_conf = config.GlobalConfig()
336
g_conf.set_user_option('email', 'Test User <test@user.com>')
337
stdout = tests.StringIOWrapper()
338
ui.ui_factory = tests.TestUIFactory(stdin='userpass\n',
340
self.assertIs(None, service.registrant_password)
341
service.gather_user_credentials()
342
self.assertEqual('test@user.com', service.registrant_email)
343
self.assertEqual('userpass', service.registrant_password)
344
self.assertContainsRe(stdout.getvalue(),
345
'launchpad.net password for test@user\\.com')