Source

bloodhound-rpc / trunk / bhrpc / tests / product.py

Full commit
# -*- coding: utf-8 -*-
"""
License: BSD

Apache(TM) Bloodhound test cases for product models rewritten for RPC

(c) 2013      ::: Olemis Lang (olemis+trac@gmail.com)
"""
from trac.core import TracError

__author__ = 'Olemis Lang <olemis+trac@gmail.com>'

import xmlrpclib

from multiproduct.api import DEFAULT_PRODUCT

from bhrpc.tests import BloodhoundRpcTestCase
from tracrpc.tests import rpc_testenv, unittest

class RpcProductTestCase(BloodhoundRpcTestCase):
    """Test product API in product scope

    Important : Use different product prefix + name to leave meaningless
    test errors out of test reports. Even if bloodhound_product table is
    cleaned up after running each test associated data is not ; therefore
    leading to multiple violations of PRIMARY KEY and UNIQUE constraints
    while initializing product with the same product prefix even if created
    for another test case.
    """
    scope = 'p'
    scope_label = '[PRODUCT]'

    @property
    def prefix(self):
        return '%s_%s' % (self.scope, self._testMethodName)

    def shortDescription(self):
        sd = BloodhoundRpcTestCase.shortDescription(self)
        return self.scope_label + ' ' + sd if sd else sd

    def setUp(self):
        BloodhoundRpcTestCase.setUp(self)
        self.anon = xmlrpclib.ServerProxy(rpc_testenv.url_anon)
        self.user = xmlrpclib.ServerProxy(rpc_testenv.url_user)
        self.admin = xmlrpclib.ServerProxy(rpc_testenv.url_admin)

    def tearDown(self):
        rpc_testenv.global_env.db_transaction('DELETE FROM bloodhound_product'
                                              ' WHERE prefix <> %s', 
                                              DEFAULT_PRODUCT)
        BloodhoundRpcTestCase.tearDown(self)

    def test_create(self):
        """test saving new Product"""

        self.admin.product.create(self.prefix, 'new', 'new')

        check_products = self.admin.product.getAll()

        self.assertEqual(['@', self.prefix], sorted(check_products))
        self.assertEqual([self.prefix, 'new', 'new', 'admin'],
                         self.admin.product.get(self.prefix))

    def test_create_duplicate_key(self):
        """test attempted saving of Product with existing key fails"""

        self.admin.product.create(self.prefix, 'original', 'first product')

        with self.assertRaises(xmlrpclib.Fault) as test_cm:
            self.admin.product.create(self.prefix, 'dupe', 'dupe primary key')
        self.assertEqual(1, test_cm.exception.faultCode)
        self.assertEquals("'Product prefix='%(prefix)s' already "
                          "exists {'name': 'dupe', "
                          "'prefix': '%(prefix)s', 'owner': 'admin', "
                          "'description': 'dupe primary key'}' while executing"
                          " 'product.create()'" % {'prefix' : self.prefix}, 
                          test_cm.exception.faultString)

        with self.assertRaises(xmlrpclib.Fault) as test_cm:
            self.admin.product.create(self.prefix + '1', 'original',
                                      'dupe unique field')
        self.assertEqual(1, test_cm.exception.faultCode)
        self.assertEquals("'Product name='original' already exists"
                          " {'name': 'original', 'prefix': '%(prefix)s', "
                          "'owner': 'admin', 'description': 'dupe unique field'}'"
                          " while executing 'product.create()'" %
                                {'prefix' : self.prefix + '1'}, 
                          test_cm.exception.faultString)
    
    def test_create_no_owner(self):
        """test saving new Product when owner is missing"""

        is_global_scope = self.scope != 'p'
        # Grant anonymous user with required permissions
        rpc_testenv._tracadmin('permission', 'add', 'anonymous', 'TRAC_ADMIN', 
                               globalenv=is_global_scope)
        rpc_testenv._tracadmin('permission', 'add', 'anonymous', 'XML_RPC', 
                               globalenv=is_global_scope)
        # Ensure anonymous super-user access will be reverted after this test
        self.addCleanup(rpc_testenv._tracadmin, 'permission', 'remove',
                        'anonymous', 'TRAC_ADMIN', globalenv=is_global_scope)

        with self.assertRaises(xmlrpclib.Fault) as test_cm:
            self.anon.product.create(self.prefix + '1', 'test product',
                                     'no owner')
        self.assertEqual(1, test_cm.exception.faultCode)
        self.assertEquals("'Product owner must be specified' while executing "
                          "'product.create()'",
                          test_cm.exception.faultString)

        self.anon.product.create(self.prefix + '2', 'test product', 'with owner', 'user')
        
        self.assertEqual(['@', self.prefix + '2'], 
                         sorted(self.user.product.getAll()))
        self.assertEqual([self.prefix + '2', 'test product', 'with owner', 'user'],
                         self.user.product.get(self.prefix + '2'))

    def test_get_missing(self):
        """tests that get will not fail for missing products"""

        # FIXME: None is returned as 0
        self.assertEqual(0, int(self.admin.product.get(u'äëïöü')))

    def test_update(self):
        """tests that we can use update to push data to the database"""

        self.admin.product.create(self.prefix, 'test project', 
                                  'a test project')

        product = self.admin.product.get(self.prefix)
        self.assertEqual('test project', product[1])

        self.admin.product.update(self.prefix, {'name' : 'updated', 
                                         'description' : 'nothing'})
        comp_product = self.admin.product.get(self.prefix)
        self.assertEqual([self.prefix, 'updated', 'nothing', 'admin'], 
                         comp_product)

    def test_field_set(self):
        """tests that we can update a single field data"""

        self.admin.product.create(self.prefix, 'test project', 
                                  'a test project')

        product = self.admin.product.get(self.prefix)
        self.assertEqual('a test project', product[2])

        self.admin.product.update(self.prefix, 
                                  {'description' : 'test change of description', 
                                   'whatever' : 'ignore'})
        comp_product = self.admin.product.get(self.prefix)
        self.assertEqual([self.prefix, 'test project', 'test change of description', 
                          'admin'], comp_product)

class RpcGlobalProductTestCase(RpcProductTestCase):
    """Test product API in global scope
    """
    scope = 'g'
    scope_label = '[GLOBAL]'

    def setUp(self):
        BloodhoundRpcTestCase.setUp(self)
        self.anon = xmlrpclib.ServerProxy(rpc_testenv.url_global_anon)
        self.user = xmlrpclib.ServerProxy(rpc_testenv.url_global_user)
        self.admin = xmlrpclib.ServerProxy(rpc_testenv.url_global_admin)


def test_suite():
    test_suite = unittest.TestSuite()
    test_suite.addTest(unittest.makeSuite(RpcProductTestCase))
    test_suite.addTest(unittest.makeSuite(RpcGlobalProductTestCase))
    return test_suite

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