1"""Tests for distutils.command.register.""" 2# -*- encoding: utf8 -*- 3import sys 4import os 5import unittest 6import getpass 7import urllib2 8import warnings 9 10from test.test_support import check_warnings, run_unittest 11 12from distutils.command import register as register_module 13from distutils.command.register import register 14from distutils.core import Distribution 15from distutils.errors import DistutilsSetupError 16 17from distutils.tests import support 18from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase 19 20PYPIRC_NOPASSWORD = """\ 21[distutils] 22 23index-servers = 24 server1 25 26[server1] 27username:me 28""" 29 30WANTED_PYPIRC = """\ 31[distutils] 32index-servers = 33 pypi 34 35[pypi] 36username:tarek 37password:password 38""" 39 40class RawInputs(object): 41 """Fakes user inputs.""" 42 def __init__(self, *answers): 43 self.answers = answers 44 self.index = 0 45 46 def __call__(self, prompt=''): 47 try: 48 return self.answers[self.index] 49 finally: 50 self.index += 1 51 52class FakeOpener(object): 53 """Fakes a PyPI server""" 54 def __init__(self): 55 self.reqs = [] 56 57 def __call__(self, *args): 58 return self 59 60 def open(self, req): 61 self.reqs.append(req) 62 return self 63 64 def read(self): 65 return 'xxx' 66 67class RegisterTestCase(PyPIRCCommandTestCase): 68 69 def setUp(self): 70 super(RegisterTestCase, self).setUp() 71 # patching the password prompt 72 self._old_getpass = getpass.getpass 73 def _getpass(prompt): 74 return 'password' 75 getpass.getpass = _getpass 76 self.old_opener = urllib2.build_opener 77 self.conn = urllib2.build_opener = FakeOpener() 78 79 def tearDown(self): 80 getpass.getpass = self._old_getpass 81 urllib2.build_opener = self.old_opener 82 super(RegisterTestCase, self).tearDown() 83 84 def _get_cmd(self, metadata=None): 85 if metadata is None: 86 metadata = {'url': 'xxx', 'author': 'xxx', 87 'author_email': 'xxx', 88 'name': 'xxx', 'version': 'xxx'} 89 pkg_info, dist = self.create_dist(**metadata) 90 return register(dist) 91 92 def test_create_pypirc(self): 93 # this test makes sure a .pypirc file 94 # is created when requested. 95 96 # let's create a register instance 97 cmd = self._get_cmd() 98 99 # we shouldn't have a .pypirc file yet 100 self.assertTrue(not os.path.exists(self.rc)) 101 102 # patching raw_input and getpass.getpass 103 # so register gets happy 104 # 105 # Here's what we are faking : 106 # use your existing login (choice 1.) 107 # Username : 'tarek' 108 # Password : 'password' 109 # Save your login (y/N)? : 'y' 110 inputs = RawInputs('1', 'tarek', 'y') 111 register_module.raw_input = inputs.__call__ 112 # let's run the command 113 try: 114 cmd.run() 115 finally: 116 del register_module.raw_input 117 118 # we should have a brand new .pypirc file 119 self.assertTrue(os.path.exists(self.rc)) 120 121 # with the content similar to WANTED_PYPIRC 122 f = open(self.rc) 123 try: 124 content = f.read() 125 self.assertEqual(content, WANTED_PYPIRC) 126 finally: 127 f.close() 128 129 # now let's make sure the .pypirc file generated 130 # really works : we shouldn't be asked anything 131 # if we run the command again 132 def _no_way(prompt=''): 133 raise AssertionError(prompt) 134 register_module.raw_input = _no_way 135 136 cmd.show_response = 1 137 cmd.run() 138 139 # let's see what the server received : we should 140 # have 2 similar requests 141 self.assertEqual(len(self.conn.reqs), 2) 142 req1 = dict(self.conn.reqs[0].headers) 143 req2 = dict(self.conn.reqs[1].headers) 144 self.assertEqual(req2['Content-length'], req1['Content-length']) 145 self.assertTrue('xxx' in self.conn.reqs[1].data) 146 147 def test_password_not_in_file(self): 148 149 self.write_file(self.rc, PYPIRC_NOPASSWORD) 150 cmd = self._get_cmd() 151 cmd._set_config() 152 cmd.finalize_options() 153 cmd.send_metadata() 154 155 # dist.password should be set 156 # therefore used afterwards by other commands 157 self.assertEqual(cmd.distribution.password, 'password') 158 159 def test_registering(self): 160 # this test runs choice 2 161 cmd = self._get_cmd() 162 inputs = RawInputs('2', 'tarek', 'tarek@ziade.org') 163 register_module.raw_input = inputs.__call__ 164 try: 165 # let's run the command 166 cmd.run() 167 finally: 168 del register_module.raw_input 169 170 # we should have send a request 171 self.assertEqual(len(self.conn.reqs), 1) 172 req = self.conn.reqs[0] 173 headers = dict(req.headers) 174 self.assertEqual(headers['Content-length'], '608') 175 self.assertTrue('tarek' in req.data) 176 177 def test_password_reset(self): 178 # this test runs choice 3 179 cmd = self._get_cmd() 180 inputs = RawInputs('3', 'tarek@ziade.org') 181 register_module.raw_input = inputs.__call__ 182 try: 183 # let's run the command 184 cmd.run() 185 finally: 186 del register_module.raw_input 187 188 # we should have send a request 189 self.assertEqual(len(self.conn.reqs), 1) 190 req = self.conn.reqs[0] 191 headers = dict(req.headers) 192 self.assertEqual(headers['Content-length'], '290') 193 self.assertTrue('tarek' in req.data) 194 195 def test_strict(self): 196 # testing the script option 197 # when on, the register command stops if 198 # the metadata is incomplete or if 199 # long_description is not reSt compliant 200 201 # empty metadata 202 cmd = self._get_cmd({}) 203 cmd.ensure_finalized() 204 cmd.strict = 1 205 self.assertRaises(DistutilsSetupError, cmd.run) 206 207 # we don't test the reSt feature if docutils 208 # is not installed 209 try: 210 import docutils 211 except ImportError: 212 return 213 214 # metadata are OK but long_description is broken 215 metadata = {'url': 'xxx', 'author': 'xxx', 216 'author_email': u'éxéxé', 217 'name': 'xxx', 'version': 'xxx', 218 'long_description': 'title\n==\n\ntext'} 219 220 cmd = self._get_cmd(metadata) 221 cmd.ensure_finalized() 222 cmd.strict = 1 223 self.assertRaises(DistutilsSetupError, cmd.run) 224 225 # now something that works 226 metadata['long_description'] = 'title\n=====\n\ntext' 227 cmd = self._get_cmd(metadata) 228 cmd.ensure_finalized() 229 cmd.strict = 1 230 inputs = RawInputs('1', 'tarek', 'y') 231 register_module.raw_input = inputs.__call__ 232 # let's run the command 233 try: 234 cmd.run() 235 finally: 236 del register_module.raw_input 237 238 # strict is not by default 239 cmd = self._get_cmd() 240 cmd.ensure_finalized() 241 inputs = RawInputs('1', 'tarek', 'y') 242 register_module.raw_input = inputs.__call__ 243 # let's run the command 244 try: 245 cmd.run() 246 finally: 247 del register_module.raw_input 248 249 def test_check_metadata_deprecated(self): 250 # makes sure make_metadata is deprecated 251 cmd = self._get_cmd() 252 with check_warnings() as w: 253 warnings.simplefilter("always") 254 cmd.check_metadata() 255 self.assertEqual(len(w.warnings), 1) 256 257def test_suite(): 258 return unittest.makeSuite(RegisterTestCase) 259 260if __name__ == "__main__": 261 run_unittest(test_suite()) 262