view test.py @ 25:73756a9e87a6

added to observer test
author Atul Varma <varmaa@toolness.com>
date Wed, 23 Dec 2009 22:51:41 -0800
parents e61a42133a33
children 057f6f0eac22
line wrap: on
line source

import unittest
import StringIO
from copy import deepcopy
from datetime import datetime

import simplejson as json
import pymongo
import bzapi

connection = pymongo.Connection('localhost', 27017)
testdb = connection.bzapi_testing_db

class TimestampTests(unittest.TestCase):
    def test_datetime_from_iso(self):
        date = bzapi.datetime_from_iso('2009-06-11T22:31:24Z')
        self.assertEqual(str(date), '2009-06-11 22:31:24')

    def test_datetime_from_rfc1123(self):
        date = bzapi.datetime_from_rfc1123('Wed, 23 Dec 2009 20:42:59 GMT')
        self.assertEqual(str(date), '2009-12-23 20:42:59')

class OpenUrlTests(unittest.TestCase):
    class FakeUrllib2(object):
        class FakeRequest(object):
            def __init__(self, url):
                self.url = url

            def add_header(self, name, value):
                pass

        def __init__(self):
            self._responses = {}

        def Request(self, url):
            return self.FakeRequest(url)

        def set_url(self, url, response):
            if not isinstance(response, basestring):
                response = json.dumps(response)
            self._responses[url] = response

        def urlopen(self, request):
            return StringIO.StringIO(self._responses[request.url])

    def test_open_url_works_without_query_args(self):
        urllib2 = self.FakeUrllib2()
        urllib2.set_url('http://foo/', 'boo')
        self.assertEqual(
            bzapi.open_url(url='http://foo/',
                           headers={'Content-Type': 'text/plain'},
                           urllib2=urllib2).read(),
            'boo'
            )

    def test_open_url_works_with_query_args(self):
        urllib2 = self.FakeUrllib2()
        urllib2.set_url('http://foo/?blah=hi+there', 'meh')
        self.assertEqual(
            bzapi.open_url(url='http://foo/',
                           query_args={'blah': 'hi there'},
                           headers={'Content-Type': 'text/plain'},
                           urllib2=urllib2).read(),
            'meh'
            )

class _MongoTestCase(unittest.TestCase):
    _collections = []

    def _reset_collections(self):
        for name in self._collections:
            testdb[name].remove({})

    def setUp(self):
        self._reset_collections()

    def tearDown(self):
        self._reset_collections()

class CachedSearchTests(_MongoTestCase):
    class FakeApi(object):
        def __init__(self):
            self._bugs = {}

        def add_fake_bug(self, **info):
            for name in ['last_change_time', 'creation_time']:
                if name not in info:
                    info[name] = '2009-06-11T22:31:24Z'
            self._bugs[info['id']] = info

        def get(self, url, **kwargs):
            if url != '/bug':
                raise ValueError(url)
            if 'id' in kwargs and kwargs['id_mode'] == 'include':
                ids = kwargs['id'].split(",")
                bugs = [self._bugs[bugid] for bugid in ids]
            else:
                bugs = self._bugs.values()
            bugs = deepcopy(bugs)
            if kwargs.get('comments') != '1':
                for info in bugs:
                    if 'comments' in info:
                        del info['comments']
            return {'data': {'bugs': bugs},
                    'date': datetime.utcnow()}

    _collections = ['bugs']

    def setUp(self):
        _MongoTestCase.setUp(self)
        self.api = self.FakeApi()
        self.search = bzapi.CachedSearch(self.api, testdb.bugs)

    def test_update_with_no_bugs(self):
        self.search.update()
        self.assertEqual(testdb.bugs.find().count(), 0)

    def test_update_with_bug(self):
        self.api.add_fake_bug(id='1034', comments='blah')
        self.search.update()
        self.assertEqual(testdb.bugs.find({'comments': 'blah'}).count(), 1)

    def test_observers_are_notified(self):
        notifications = []

        class Observer(object):
            def notify(self, info):
                notifications.append(info)

        self.api.add_fake_bug(id='1034')
        self.search.add_observer(Observer())

        self.search.update()
        self.assertEqual(len(notifications), 1)
        self.assertEqual(notifications[0]['bug'], '1034')

        # Ensure updating w/o state change doesn't trigger
        # observers.
        self.search.update()
        self.assertEqual(len(notifications), 1)

class ApiTests(_MongoTestCase):
    class FakeOpenUrl(object):
        def __init__(self):
            self._responses = {}

        def set(self, url, query_args, response):
            if not isinstance(response, basestring):
                response = json.dumps(response)
            self._responses[url + repr(query_args)] = response

        def __call__(self, url, headers, query_args=None):
            response = self._responses[url + repr(query_args)]
            return StringIO.StringIO(response)

    _FAKE_CONFIG = {'product': {}}

    _collections = ['api']

    def setUp(self):
        _MongoTestCase.setUp(self)
        self.config = deepcopy(self._FAKE_CONFIG)

    def _get_basic_fake_api(self, **kwargs):
        opener = self.FakeOpenUrl()
        opener.set('http://foo/latest/configuration', kwargs,
                   self.config)
        api = bzapi.BugzillaApi('http://foo/latest', testdb.api,
                                open_url=opener, **kwargs)
        return api

    def test_bzapi_uses_username_and_password(self):
        api = self._get_basic_fake_api(username='foo',
                                       password='bar')
        api._open_url.set('http://foo/latest/stuff',
                          {'username': 'foo',
                           'password': 'bar'},
                          {})
        api.get('/stuff')

    def test_bzapi_raises_err_on_bad_component(self):
        self.config['product']['Mozilla Labs'] = {'component': {'Jetpack': {}}}
        api = self._get_basic_fake_api()
        self.assertRaises(ValueError,
                          api.get,
                          '/blah',
                          product='Mozilla Labs',
                          component='nonexistent')

    def test_bzapi_raises_err_on_bad_product(self):
        api = self._get_basic_fake_api()
        self.assertRaises(ValueError,
                          api.get,
                          '/blah',
                          product='nonexistent')

    def test_bzapi_validates_product_and_component(self):
        self.config['product']['Mozilla Labs'] = {'component': {'Jetpack': {}}}
        api = self._get_basic_fake_api()
        api._open_url.set('http://foo/latest/stuff',
                          {'product': 'Mozilla Labs',
                           'component': 'Jetpack'},
                          {})
        api.get('/stuff', product='Mozilla Labs', component='Jetpack')

    def test_bzapi_removes_dots_from_config(self):
        self.config['product']['addons.mozilla.org'] = {}
        api = self._get_basic_fake_api()
        self.assertTrue('addons_DOT_mozilla_DOT_org' in api.config['product'])

if __name__ == '__main__':
    unittest.main()