1. Brantley Harris
  2. onpython3yet

Source

onpython3yet / onpython3yet / packages / tests / test_views.py


from __future__ import with_statement
import urllib
import unittest

import fudge
from django.test import TestCase as DjangoTestCase
from django.core.urlresolvers import reverse
from nose.tools import eq_
from pyquery import PyQuery as pq
import simplejson

from packages.models import Package, PackageRequirement
import packages.views


def teardown_data():
    for pr in PackageRequirement.objects.all():
        pr.delete()
    for p in Package.objects.all():
        p.delete()


class TestPackages(DjangoTestCase):

    def tearDown(self):
        teardown_data()
        fudge.clear_expectations()

    @fudge.with_fakes
    def test_fetch_package_and_requirements(self):
        fake_xmlrpclib = fudge.Fake('xmlrpclib').provides('Server')
        fake_server = fake_xmlrpclib.returns_fake()
        fake_search = (fake_server.expects('search')
                            .with_args({'name':'Adamanteus'})
                            .returns([{'name': 'Adamanteus', 'version': '0.5',
                                       'summary': ('Database Backups with '
                                                   'Version Control')}])
                            .next_call()
                            .with_args({'name':'pymongo'})
                            .returns([{'name': 'pymongo', 'version': '0.5'}])
                            .next_call()
                            .with_args({'name':'mercurial'})
                            .returns([{'name': 'Mercurial',
                                       'version': '0.5'}])
                        )
        # fake_releases =
        #   fake_server.expects('package_releases').returns(['0.5'])
        fake_data = (fake_server.expects('release_data')
                            .with_args('Adamanteus', '0.5')
                            .returns({
                                'requires': ['pymongo', 'mercurial'],
                                'classifiers': [
                                    # pretend that this package supports
                                    # python 3:
                                    'Programming Language :: Python :: 3.0'
                                ]
                            })
                            .next_call()
                            .with_args('pymongo', '0.5')
                            .returns({'requires': []})
                            .next_call()
                            .with_args('Mercurial', '0.5')
                            .returns({'requires': []})
                    )

        with fudge.patched_context(packages.views, "xmlrpclib",
                                   fake_xmlrpclib):
            response = self.client.get(reverse('packages.fetch',
                                       args=('Adamanteus',)))

        self.assertRedirects(response, reverse('packages.show',
                             args=('Adamanteus',)))
        package = Package.objects.filter(name='Adamanteus')[0]
        self.assertEqual(package.current_version, '0.5')
        self.assertEqual(package.supports_python_3, True)
        self.assertEqual(package.summary,
                         "Database Backups with Version Control")
        self.assertEqual(package.description, None)

        reqs = sorted([r.required_package.name for r in
                       package.requirements.all()])
        self.assertEqual(reqs, [u'Mercurial', u'pymongo'])

        self.assertEqual(Package.objects.filter(name='pymongo').count(),
                         1)
        self.assertEqual(Package.objects.filter(name='Mercurial').count(),
                         1)

    @fudge.with_fakes
    def test_update_package_and_requirements(self):
        foobar = Package(name='foobar')
        foobar.save()
        p = Package(name='Adamanteus', supports_python_3=False)
        p.requirements.add(PackageRequirement(package=p,
                                              required_package=foobar))
        p.save()

        fake_xmlrpclib = fudge.Fake('xmlrpclib').provides('Server')
        fake_server = fake_xmlrpclib.returns_fake()
        fake_search = (fake_server.expects('search')
                            .with_args({'name':'Adamanteus'})
                            .returns([{'name': 'Adamanteus', 'version': '0.5',
                                       'summary': ('Database Backups with '
                                                   'Version Control')}])
                            .next_call()
                            .with_args({'name':'pymongo'})
                            .returns([{'name': 'pymongo', 'version': '0.5'}])
                            .next_call()
                            .with_args({'name':'mercurial'})
                            .returns([{'name': 'Mercurial',
                                       'version': '0.5'}])
                        )
        # fake_releases =
        #   fake_server.expects('package_releases').returns(['0.5'])
        fake_data = (fake_server.expects('release_data')
                            .with_args('Adamanteus', '0.5')
                            .returns({
                                'requires': ['pymongo', 'mercurial'],
                                'classifiers': [
                                    # pretend that this package supports
                                    # python 3:
                                    'Programming Language :: Python :: 3.0'
                                ]
                            })
                            .next_call()
                            .with_args('pymongo', '0.5')
                            .returns({'requires': []})
                            .next_call()
                            .with_args('Mercurial', '0.5')
                            .returns({'requires': []})
                    )

        with fudge.patched_context(packages.views, "xmlrpclib",
                                   fake_xmlrpclib):
            response = self.client.get(reverse('packages.fetch',
                                       args=('Adamanteus',)))
            self.assertRedirects(response, reverse('packages.show',
                                 args=('Adamanteus',)))

            package = Package.objects.filter(name='Adamanteus')[0]
            self.assertEqual(package.supports_python_3, True)

            reqs = sorted([r.required_package.name for r in
                           package.requirements.all()])
            self.assertEqual(reqs, [u'Mercurial', u'pymongo'])

        self.assertEqual(Package.objects.filter(name='Adamanteus').count(), 1)
        self.assertEqual(Package.objects.filter(name='pymongo').count(), 1)
        self.assertEqual(Package.objects.filter(name='Mercurial').count(), 1)
        self.assertEqual(Package.objects.filter(name='foobar').count(), 1)

    @fudge.with_fakes
    def test_fetch_urlencoded_package(self):

        fake_xmlrpclib = fudge.Fake('xmlrpclib').provides('Server')
        fake_server = fake_xmlrpclib.returns_fake()
        fake_search = (fake_server.expects('search')
                            .with_args({'name':'Amara XML Toolkit'})
                            .returns([{'name': 'Amara XML Toolkit',
                                       'version': '0.5'}])
                        )
        # fake_releases =
        #       fake_server.expects('package_releases').returns(['0.5'])
        fake_data = (fake_server.expects('release_data')
                            .with_args('Amara XML Toolkit', '0.5')
                            .returns({'requires': []})
                    )

        with fudge.patched_context(packages.views, "xmlrpclib",
                                   fake_xmlrpclib):
            # note that django automatically urldecodes but
            # it doesn't hurt to check!
            response = self.client.get(reverse('packages.fetch',
                                args=(urllib.quote('Amara XML Toolkit'),)))

    @fudge.with_fakes
    def test_skip_missing_requirements(self):

        fake_xmlrpclib = fudge.Fake('xmlrpclib').provides('Server')
        fake_server = fake_xmlrpclib.returns_fake()
        fake_search = (fake_server.expects('search')
                            .with_args({'name':'Adamanteus'})
                            .returns([{'name': 'Adamanteus',
                                       'version': '0.5'}])
                            .next_call()
                            .with_args({'name':'bogus'})
                            # force a missing requirement:
                            .returns([{'name': 'other', 'version': '0.1'},
                                      {'name': 'other2', 'version': '0.1'}])
                        )
        # fake_releases =
        #       fake_server.expects('package_releases').returns(['0.5'])
        fake_data = (fake_server.expects('release_data')
                            .with_args('Adamanteus', '0.5')
                            .returns({
                                'requires': ['bogus']
                            })
                    )

        with fudge.patched_context(packages.views, "xmlrpclib",
                                   fake_xmlrpclib):

            response = self.client.get(reverse('packages.fetch',
                                       args=('Adamanteus',)))
            self.assertRedirects(response, reverse('packages.show',
                                 args=('Adamanteus',)))

            package = Package.objects.filter(name='Adamanteus')[0]

            reqs = sorted([r.required_package.name for r in
                           package.requirements.all()])
            self.assertEqual(reqs, [])

    @fudge.with_fakes
    def test_skip_requirements_when_no_results(self):

        fake_xmlrpclib = fudge.Fake('xmlrpclib').provides('Server')
        fake_server = fake_xmlrpclib.returns_fake()
        fake_search = (fake_server.expects('search')
                            .with_args({'name':'Adamanteus'})
                            .returns([{'name': 'Adamanteus',
                                       'version': '0.5'}])
                            .next_call()
                            .with_args({'name':'bogus'})
                            # force no results:
                            .returns([])
                        )
        # fake_releases =
        #   fake_server.expects('package_releases').returns(['0.5'])
        fake_data = (fake_server.expects('release_data')
                            .with_args('Adamanteus', '0.5')
                            .returns({
                                'requires': ['bogus']
                            })
                    )

        with fudge.patched_context(packages.views, "xmlrpclib",
                                   fake_xmlrpclib):

            response = self.client.get(reverse('packages.fetch',
                                       args=('Adamanteus',)))
            self.assertRedirects(response, reverse('packages.show',
                                 args=('Adamanteus',)))

            package = Package.objects.filter(name='Adamanteus')[0]

            reqs = sorted([r.required_package.name for r in
                           package.requirements.all()])
            self.assertEqual(reqs, [])

    @fudge.with_fakes
    def test_package_cannot_require_itself(self):

        fake_xmlrpclib = fudge.Fake('xmlrpclib').provides('Server')
        fake_server = fake_xmlrpclib.returns_fake()
        fake_search = (fake_server.expects('search')
                            .times_called(1)
                            .with_args({'name':'Adamanteus'})
                            .returns([{'name': 'Adamanteus',
                                       'version': '0.5'}])
                        )
        # fake_releases =
        #   fake_server.expects('package_releases').returns(['0.5'])
        fake_data = (fake_server.expects('release_data')
                            .with_args('Adamanteus', '0.5')
                            .returns({
                                'requires': ['Adamanteus']
                            })
                    )

        with fudge.patched_context(packages.views, "xmlrpclib",
                                   fake_xmlrpclib):

            response = self.client.get(reverse('packages.fetch',
                                       args=('Adamanteus',)))
            self.assertRedirects(response, reverse('packages.show',
                                 args=('Adamanteus',)))

            package = Package.objects.filter(name='Adamanteus')[0]

            reqs = sorted([r.required_package.name for r in
                           package.requirements.all()])
            self.assertEqual(reqs, [])


class TestRequirementViews(DjangoTestCase):

    def test_parse_query(self):
        r = self.client.get(reverse('packages.requirements'), data={'r':"""
                                                                foo
                                                                bar"""})
        eq_(r.status_code, 200)
        doc = pq(r.content)
        d = doc('#requirements-results').attr('data-requirements')
        eq_(d.split(';;;'),
            ['foo','bar'])
        eq_(doc('#requirements-results').attr('data-url'),
            reverse('packages.query'))


class TestQuery(DjangoTestCase):

    def tearDown(self):
        teardown_data()
        fudge.clear_expectations()

    @fudge.with_fakes
    def test_pkg_not_found(self):
        fake_xmlrpclib = fudge.Fake('xmlrpclib').provides('Server')
        fake_server = (fake_xmlrpclib.returns_fake().expects('search')
                                     # No results:
                                     .returns([])
        )
        with fudge.patched_context(packages.views, "xmlrpclib",
                                   fake_xmlrpclib):
            r = self.client.post(reverse('packages.query'),
                                 {'name':'NonExistant'})
        eq_(r.status_code, 200)
        data = simplejson.loads(r.content)
        eq_(data['name'], 'NonExistant')
        eq_(data['found_pkg'], False)
        eq_(data['not_found_reason'], 'Does not exist on PyPI')

    @fudge.with_fakes
    def test_pkg_found(self):
        pkg = Package.objects.create(name='somecrazypkg',
                                     supports_python_3=True)
        fake_xmlrpclib = fudge.Fake('xmlrpclib').provides('Server')
        fake_server = fake_xmlrpclib.returns_fake()
        with fudge.patched_context(packages.views, "xmlrpclib",
                                   fake_xmlrpclib):
            r = self.client.post(reverse('packages.query'),
                                 {'name':'somecrazypkg'})
        eq_(r.status_code, 200)
        data = simplejson.loads(r.content)
        eq_(data['name'], 'somecrazypkg')
        eq_(data['found_pkg'], True)
        eq_(data['supports_python_3'], True)


class TestDependedOn(DjangoTestCase):

    def setUp(self):
        Package.objects.create(name='aaz', supports_python_3=False)
        Package.objects.create(name='baz', supports_python_3=False)
        Package.objects.create(name='caz', supports_python_3=False)
        Package.objects.create(name='daz', supports_python_3=False)
    
    def get(self, *args, **kw):
        r = self.client.get(reverse('packages.depended_on'), *args, **kw)
        eq_(r.status_code, 200)
        return simplejson.loads(r.content)

    def tearDown(self):
        teardown_data()

    def test_pkg(self):
        data = self.get()
        p = data['packages'][0]
        eq_(p['name'], 'aaz')
        eq_(p['show_pkg_url'], reverse('packages.show', args=[p['name']]))
        eq_(p['required_count'], 0)

    def test_slicing(self):
        data = self.get({'start': 0, 'offset': 2})
        eq_([p['name'] for p in data['packages']],
            ['aaz', 'baz'])
        data = self.get({'start': 1, 'offset': 2})
        eq_([p['name'] for p in data['packages']],
            ['baz', 'caz'])