• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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