1
# Copyright (C) 2006 Canonical Ltd
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.
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.
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
from StringIO import StringIO
22
from bzrlib.tests import TestCase, TestSkipped
25
from lp_registration import (
28
BranchRegistrationRequest,
33
# TODO: Test that the command-line client, making sure that it'll pass the
34
# request through to a dummy transport, and that the transport will validate
35
# the results passed in. Not sure how to get the transport object back out to
36
# validate that its OK - may not be necessary.
38
# TODO: Add test for (and implement) other command-line options to set
39
# project, author_email, description.
41
# TODO: project_id is not properly handled -- must be passed in rpc or path.
43
class InstrumentedXMLRPCConnection(object):
44
"""Stands in place of an http connection for the purposes of testing"""
46
def __init__(self, testcase):
47
self.testcase = testcase
50
"""Fake the http reply.
52
:returns: (errcode, errmsg, headers)
54
return (200, 'OK', [])
57
"""Return a fake file containing the response content."""
59
<?xml version="1.0" ?>
64
<string>victoria dock</string>
72
class InstrumentedXMLRPCTransport(xmlrpclib.Transport):
74
# Python 2.5's xmlrpclib looks for this.
77
def __init__(self, testcase):
78
self.testcase = testcase
80
def make_connection(self, host):
81
host, http_headers, x509 = self.get_host_info(host)
83
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())
90
return InstrumentedXMLRPCConnection(test)
92
def send_request(self, connection, handler_path, request_body):
94
self.got_request = True
96
def send_host(self, conn, host):
99
def send_user_agent(self, conn):
100
# TODO: send special user agent string, including bzrlib version
104
def send_content(self, conn, request_body):
105
unpacked, method = xmlrpclib.loads(request_body)
106
assert None not in unpacked, \
107
"xmlrpc result %r shouldn't contain None" % (unpacked,)
108
self.sent_params = unpacked
111
class MockLaunchpadService(LaunchpadService):
113
def send_request(self, method_name, method_params):
114
"""Stash away the method details rather than sending them to a real server"""
115
self.called_method_name = method_name
116
self.called_method_params = method_params
119
class TestBranchRegistration(TestCase):
120
SAMPLE_URL = 'http://bazaar-vcs.org/bzr/bzr.dev/'
121
SAMPLE_OWNER = 'jhacker@foo.com'
122
SAMPLE_BRANCH_ID = 'bzr.dev'
125
super(TestBranchRegistration, self).setUp()
126
# 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']
130
def test_register_help(self):
131
"""register-branch accepts --help"""
132
out, err = self.run_bzr('register-branch', '--help')
133
self.assertContainsRe(out, r'Register a branch')
135
def test_register_no_url(self):
136
"""register-branch command requires parameters"""
137
self.run_bzr('register-branch', retcode=3)
139
def test_register_dry_run(self):
140
out, err = self.run_bzr('register-branch',
141
'http://test-server.com/bzr/branch',
143
self.assertEquals(out, 'Branch registered.\n')
145
def test_onto_transport(self):
146
"""Test how the request is sent by transmitting across a mock Transport"""
147
# use a real transport, but intercept at the http/xml layer
148
transport = InstrumentedXMLRPCTransport(self)
149
service = LaunchpadService(transport)
150
service.registrant_email = 'testuser@launchpad.net'
151
service.registrant_password = 'testpassword'
152
rego = BranchRegistrationRequest('http://test-server.com/bzr/branch',
156
'author@launchpad.net',
159
self.assertEquals(transport.connected_host, 'xmlrpc.launchpad.net')
160
self.assertEquals(len(transport.sent_params), 6)
161
self.assertEquals(transport.sent_params,
162
('http://test-server.com/bzr/branch', # branch_url
163
'branch-id', # branch_name
164
'my test branch', # branch_title
166
'author@launchpad.net',
168
self.assertTrue(transport.got_request)
170
def test_subclass_request(self):
171
"""Define a new type of xmlrpc request"""
172
class DummyRequest(BaseRequest):
173
_methodname = 'dummy_request'
174
def _request_params(self):
177
service = MockLaunchpadService()
178
service.registrant_email = 'test@launchpad.net'
179
service.registrant_password = ''
180
request = DummyRequest()
181
request.submit(service)
182
self.assertEquals(service.called_method_name, 'dummy_request')
183
self.assertEquals(service.called_method_params, (42,))
185
def test_mock_server_registration(self):
186
"""Send registration to mock server"""
188
class MockRegistrationService(MockLaunchpadService):
189
def send_request(self, method_name, method_params):
190
test_case.assertEquals(method_name, "register_branch")
191
test_case.assertEquals(list(method_params),
192
['url', 'name', 'title', 'description', 'email', 'name'])
194
service = MockRegistrationService()
195
rego = BranchRegistrationRequest('url', 'name', 'title',
196
'description', 'email', 'name')
197
result = rego.submit(service)
198
self.assertEquals(result, 'result')
200
def test_mock_server_registration_with_defaults(self):
201
"""Send registration to mock server"""
203
class MockRegistrationService(MockLaunchpadService):
204
def send_request(self, method_name, method_params):
205
test_case.assertEquals(method_name, "register_branch")
206
test_case.assertEquals(list(method_params),
207
['http://server/branch', 'branch', '', '', '', ''])
209
service = MockRegistrationService()
210
rego = BranchRegistrationRequest('http://server/branch')
211
result = rego.submit(service)
212
self.assertEquals(result, 'result')
214
def test_mock_bug_branch_link(self):
215
"""Send bug-branch link to mock server"""
217
class MockService(MockLaunchpadService):
218
def send_request(self, method_name, method_params):
219
test_case.assertEquals(method_name, "link_branch_to_bug")
220
test_case.assertEquals(list(method_params),
221
['http://server/branch', 1234, ''])
222
return 'http://launchpad.net/bug/1234'
223
service = MockService()
224
rego = BranchBugLinkRequest('http://server/branch', 1234)
225
result = rego.submit(service)
226
self.assertEquals(result, 'http://launchpad.net/bug/1234')