blob: 9336ac8604274b9557a9660c8eb0ea978f73ee6e [file] [log] [blame]
Benjamin Peterson92035012008-12-27 16:00:54 +00001"""Tests for distutils.command.register."""
2import sys
3import os
4import unittest
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +00005import getpass
Tarek Ziadébaf51802009-03-31 21:37:16 +00006import urllib
Tarek Ziadé5af55c62009-05-16 16:52:13 +00007import warnings
8
Éric Araujo70ec44a2010-11-06 02:44:43 +00009from test.support import check_warnings, run_unittest
Benjamin Peterson92035012008-12-27 16:00:54 +000010
Tarek Ziadébaf51802009-03-31 21:37:16 +000011from distutils.command import register as register_module
Benjamin Peterson92035012008-12-27 16:00:54 +000012from distutils.command.register import register
13from distutils.core import Distribution
Tarek Ziadé5af55c62009-05-16 16:52:13 +000014from distutils.errors import DistutilsSetupError
Benjamin Peterson92035012008-12-27 16:00:54 +000015
16from distutils.tests import support
17from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase
18
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +000019PYPIRC_NOPASSWORD = """\
20[distutils]
21
22index-servers =
23 server1
24
25[server1]
26username:me
27"""
28
29WANTED_PYPIRC = """\
30[distutils]
31index-servers =
32 pypi
33
34[pypi]
35username:tarek
36password:password
37"""
38
39class Inputs(object):
Benjamin Peterson92035012008-12-27 16:00:54 +000040 """Fakes user inputs."""
41 def __init__(self, *answers):
42 self.answers = answers
43 self.index = 0
44
45 def __call__(self, prompt=''):
46 try:
47 return self.answers[self.index]
48 finally:
49 self.index += 1
50
Tarek Ziadébaf51802009-03-31 21:37:16 +000051class FakeOpener(object):
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +000052 """Fakes a PyPI server"""
53 def __init__(self):
Tarek Ziadébaf51802009-03-31 21:37:16 +000054 self.reqs = []
Benjamin Peterson92035012008-12-27 16:00:54 +000055
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +000056 def __call__(self, *args):
Tarek Ziadébaf51802009-03-31 21:37:16 +000057 return self
58
59 def open(self, req):
60 self.reqs.append(req)
61 return self
62
63 def read(self):
64 return 'xxx'
Benjamin Peterson92035012008-12-27 16:00:54 +000065
Tarek Ziadé5af55c62009-05-16 16:52:13 +000066class RegisterTestCase(PyPIRCCommandTestCase):
Benjamin Peterson92035012008-12-27 16:00:54 +000067
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +000068 def setUp(self):
Hirokazu Yamamoto2703fd92009-05-29 09:14:04 +000069 super(RegisterTestCase, self).setUp()
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +000070 # patching the password prompt
71 self._old_getpass = getpass.getpass
72 def _getpass(prompt):
73 return 'password'
74 getpass.getpass = _getpass
Tarek Ziadébaf51802009-03-31 21:37:16 +000075 self.old_opener = urllib.request.build_opener
76 self.conn = urllib.request.build_opener = FakeOpener()
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +000077
78 def tearDown(self):
79 getpass.getpass = self._old_getpass
Tarek Ziadébaf51802009-03-31 21:37:16 +000080 urllib.request.build_opener = self.old_opener
Hirokazu Yamamoto2703fd92009-05-29 09:14:04 +000081 super(RegisterTestCase, self).tearDown()
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +000082
Tarek Ziadé5af55c62009-05-16 16:52:13 +000083 def _get_cmd(self, metadata=None):
84 if metadata is None:
85 metadata = {'url': 'xxx', 'author': 'xxx',
86 'author_email': 'xxx',
87 'name': 'xxx', 'version': 'xxx'}
Tarek Ziadébaf51802009-03-31 21:37:16 +000088 pkg_info, dist = self.create_dist(**metadata)
89 return register(dist)
90
Benjamin Peterson92035012008-12-27 16:00:54 +000091 def test_create_pypirc(self):
92 # this test makes sure a .pypirc file
93 # is created when requested.
94
Tarek Ziadébaf51802009-03-31 21:37:16 +000095 # let's create a register instance
96 cmd = self._get_cmd()
Benjamin Peterson92035012008-12-27 16:00:54 +000097
98 # we shouldn't have a .pypirc file yet
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000099 self.assertTrue(not os.path.exists(self.rc))
Benjamin Peterson92035012008-12-27 16:00:54 +0000100
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +0000101 # patching input and getpass.getpass
Benjamin Peterson92035012008-12-27 16:00:54 +0000102 # so register gets happy
103 #
104 # Here's what we are faking :
105 # use your existing login (choice 1.)
106 # Username : 'tarek'
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +0000107 # Password : 'password'
Benjamin Peterson92035012008-12-27 16:00:54 +0000108 # Save your login (y/N)? : 'y'
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +0000109 inputs = Inputs('1', 'tarek', 'y')
Benjamin Peterson467a7bd2008-12-27 17:00:44 +0000110 register_module.input = inputs.__call__
Benjamin Peterson92035012008-12-27 16:00:54 +0000111 # let's run the command
Tarek Ziadébaf51802009-03-31 21:37:16 +0000112 try:
113 cmd.run()
114 finally:
115 del register_module.input
Benjamin Peterson92035012008-12-27 16:00:54 +0000116
117 # we should have a brand new .pypirc file
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000118 self.assertTrue(os.path.exists(self.rc))
Benjamin Peterson92035012008-12-27 16:00:54 +0000119
120 # with the content similar to WANTED_PYPIRC
Éric Araujobee5cef2010-11-05 23:51:56 +0000121 f = open(self.rc)
122 try:
123 content = f.read()
124 self.assertEquals(content, WANTED_PYPIRC)
125 finally:
126 f.close()
Benjamin Peterson92035012008-12-27 16:00:54 +0000127
128 # now let's make sure the .pypirc file generated
129 # really works : we shouldn't be asked anything
130 # if we run the command again
131 def _no_way(prompt=''):
132 raise AssertionError(prompt)
Tarek Ziadébaf51802009-03-31 21:37:16 +0000133 register_module.input = _no_way
Benjamin Peterson92035012008-12-27 16:00:54 +0000134
Tarek Ziadébaf51802009-03-31 21:37:16 +0000135 cmd.show_response = 1
Benjamin Peterson92035012008-12-27 16:00:54 +0000136 cmd.run()
137
138 # let's see what the server received : we should
139 # have 2 similar requests
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000140 self.assertTrue(self.conn.reqs, 2)
Tarek Ziadébaf51802009-03-31 21:37:16 +0000141 req1 = dict(self.conn.reqs[0].headers)
142 req2 = dict(self.conn.reqs[1].headers)
143
144 self.assertEquals(req1['Content-length'], '1374')
145 self.assertEquals(req2['Content-length'], '1374')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000146 self.assertTrue((b'xxx') in self.conn.reqs[1].data)
Benjamin Peterson92035012008-12-27 16:00:54 +0000147
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +0000148 def test_password_not_in_file(self):
149
Tarek Ziadébaf51802009-03-31 21:37:16 +0000150 self.write_file(self.rc, PYPIRC_NOPASSWORD)
151 cmd = self._get_cmd()
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +0000152 cmd._set_config()
153 cmd.finalize_options()
154 cmd.send_metadata()
155
156 # dist.password should be set
157 # therefore used afterwards by other commands
Tarek Ziadébaf51802009-03-31 21:37:16 +0000158 self.assertEquals(cmd.distribution.password, 'password')
159
160 def test_registering(self):
161 # this test runs choice 2
162 cmd = self._get_cmd()
163 inputs = Inputs('2', 'tarek', 'tarek@ziade.org')
164 register_module.input = inputs.__call__
165 try:
166 # let's run the command
167 cmd.run()
168 finally:
169 del register_module.input
170
171 # we should have send a request
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000172 self.assertTrue(self.conn.reqs, 1)
Tarek Ziadébaf51802009-03-31 21:37:16 +0000173 req = self.conn.reqs[0]
174 headers = dict(req.headers)
175 self.assertEquals(headers['Content-length'], '608')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000176 self.assertTrue((b'tarek') in req.data)
Tarek Ziadébaf51802009-03-31 21:37:16 +0000177
178 def test_password_reset(self):
179 # this test runs choice 3
180 cmd = self._get_cmd()
181 inputs = Inputs('3', 'tarek@ziade.org')
182 register_module.input = inputs.__call__
183 try:
184 # let's run the command
185 cmd.run()
186 finally:
187 del register_module.input
188
189 # we should have send a request
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000190 self.assertTrue(self.conn.reqs, 1)
Tarek Ziadébaf51802009-03-31 21:37:16 +0000191 req = self.conn.reqs[0]
192 headers = dict(req.headers)
193 self.assertEquals(headers['Content-length'], '290')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000194 self.assertTrue((b'tarek') in req.data)
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +0000195
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000196 def test_strict(self):
197 # testing the script option
198 # when on, the register command stops if
199 # the metadata is incomplete or if
200 # long_description is not reSt compliant
201
202 # empty metadata
203 cmd = self._get_cmd({})
204 cmd.ensure_finalized()
205 cmd.strict = 1
206 self.assertRaises(DistutilsSetupError, cmd.run)
207
208 # we don't test the reSt feature if docutils
Tarek Ziadé36797272010-07-22 12:50:05 +0000209 # is not installed
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000210 try:
211 import docutils
Tarek Ziadé36797272010-07-22 12:50:05 +0000212 except ImportError:
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000213 return
214
215 # metadata are OK but long_description is broken
216 metadata = {'url': 'xxx', 'author': 'xxx',
217 'author_email': 'xxx',
218 'name': 'xxx', 'version': 'xxx',
219 'long_description': 'title\n==\n\ntext'}
220
221 cmd = self._get_cmd(metadata)
222 cmd.ensure_finalized()
223 cmd.strict = 1
224 self.assertRaises(DistutilsSetupError, cmd.run)
225
226 # now something that works
227 metadata['long_description'] = 'title\n=====\n\ntext'
228 cmd = self._get_cmd(metadata)
229 cmd.ensure_finalized()
230 cmd.strict = 1
Tarek Ziadé4bcceef2010-10-03 14:18:09 +0000231 inputs = Inputs('1', 'tarek', 'y')
232 register_module.input = inputs.__call__
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000233 # let's run the command
234 try:
235 cmd.run()
236 finally:
Tarek Ziadé4bcceef2010-10-03 14:18:09 +0000237 del register_module.input
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000238
239 # strict is not by default
240 cmd = self._get_cmd()
241 cmd.ensure_finalized()
Tarek Ziadé4bcceef2010-10-03 14:18:09 +0000242 inputs = Inputs('1', 'tarek', 'y')
243 register_module.input = inputs.__call__
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000244 # let's run the command
245 try:
246 cmd.run()
247 finally:
Tarek Ziadé4bcceef2010-10-03 14:18:09 +0000248 del register_module.input
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000249
250 def test_check_metadata_deprecated(self):
251 # makes sure make_metadata is deprecated
252 cmd = self._get_cmd()
253 with check_warnings() as w:
254 warnings.simplefilter("always")
255 cmd.check_metadata()
256 self.assertEquals(len(w.warnings), 1)
257
Benjamin Peterson92035012008-12-27 16:00:54 +0000258def test_suite():
Tarek Ziadé5af55c62009-05-16 16:52:13 +0000259 return unittest.makeSuite(RegisterTestCase)
Benjamin Peterson92035012008-12-27 16:00:54 +0000260
261if __name__ == "__main__":
Éric Araujo70ec44a2010-11-06 02:44:43 +0000262 run_unittest(test_suite())