[FIX] ir.ui.view missing time libraries in qweb rendering context
[odoo/odoo.git] / openerp / tests / common.py
1 # -*- coding: utf-8 -*-
2 """
3 The module :mod:`openerp.tests.common` provides a few helpers and classes to write
4 tests.
5 """
6 import threading
7 import time
8 import unittest2
9 import xmlrpclib
10
11 import openerp
12
13 # The openerp library is supposed already configured.
14 ADDONS_PATH = openerp.tools.config['addons_path']
15 PORT = openerp.tools.config['xmlrpc_port']
16 DB = openerp.tools.config['db_name']
17
18 # If the database name is not provided on the command-line,
19 # use the one on the thread (which means if it is provided on
20 # the command-line, this will break when installing another
21 # database from XML-RPC).
22 if not DB and hasattr(threading.current_thread(), 'dbname'):
23     DB = threading.current_thread().dbname
24
25 HOST = '127.0.0.1'
26
27 ADMIN_USER = 'admin'
28 ADMIN_USER_ID = openerp.SUPERUSER_ID
29 ADMIN_PASSWORD = 'admin'
30
31 def start_openerp():
32     """
33     Start the OpenERP server similary to the openerp-server script.
34     """
35     openerp.service.start_services()
36
37     # Ugly way to ensure the server is listening.
38     time.sleep(2)
39
40 def stop_openerp():
41     """
42     Shutdown the OpenERP server similarly to a single ctrl-c.
43     """
44     openerp.service.stop_services()
45
46 class BaseCase(unittest2.TestCase):
47     """
48     Subclass of TestCase for common OpenERP-specific code.
49     
50     This class is abstract and expects self.cr and self.uid to be initialized by subclasses.
51     """
52
53     @classmethod
54     def cursor(self):
55         return openerp.modules.registry.RegistryManager.get(DB).db.cursor()
56
57     @classmethod
58     def registry(self, model):
59         return openerp.modules.registry.RegistryManager.get(DB)[model]
60
61     @classmethod
62     def ref(self, xid):
63         """ Returns database ID corresponding to a given identifier.
64
65             :param xid: fully-qualified record identifier, in the form ``module.identifier``
66             :raise: ValueError if not found
67         """
68         assert "." in xid, "this method requires a fully qualified parameter, in the following form: 'module.identifier'"
69         module, xid = xid.split('.')
70         _, id = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, module, xid)
71         return id
72
73     @classmethod
74     def browse_ref(self, xid):
75         """ Returns a browsable record for the given identifier.
76
77             :param xid: fully-qualified record identifier, in the form ``module.identifier``
78             :raise: ValueError if not found
79         """
80         assert "." in xid, "this method requires a fully qualified parameter, in the following form: 'module.identifier'"
81         module, xid = xid.split('.')
82         return self.registry('ir.model.data').get_object(self.cr, self.uid, module, xid)
83
84
85 class TransactionCase(BaseCase):
86     """
87     Subclass of BaseCase with a single transaction, rolled-back at the end of
88     each test (method).
89     """
90
91     def setUp(self):
92         # Store cr and uid in class variables, to allow ref() and browse_ref to be BaseCase @classmethods
93         # and still access them
94         TransactionCase.cr = self.cursor()
95         TransactionCase.uid = openerp.SUPERUSER_ID
96
97     def tearDown(self):
98         self.cr.rollback()
99         self.cr.close()
100
101
102 class SingleTransactionCase(BaseCase):
103     """
104     Subclass of BaseCase with a single transaction for the whole class,
105     rolled-back after all the tests.
106     """
107
108     @classmethod
109     def setUpClass(cls):
110         cls.cr = cls.cursor()
111         cls.uid = openerp.SUPERUSER_ID
112
113     @classmethod
114     def tearDownClass(cls):
115         cls.cr.rollback()
116         cls.cr.close()
117
118
119 class RpcCase(unittest2.TestCase):
120     """
121     Subclass of TestCase with a few XML-RPC proxies.
122     """
123
124     def __init__(self, methodName='runTest'):
125         super(RpcCase, self).__init__(methodName)
126
127         class A(object):
128             pass
129         self.proxy = A()
130
131         # Use the old (pre 6.1) API.
132         self.proxy.url_60 = url_60 = 'http://%s:%d/xmlrpc/' % (HOST, PORT)
133         self.proxy.common_60 = xmlrpclib.ServerProxy(url_60 + 'common')
134         self.proxy.db_60 = xmlrpclib.ServerProxy(url_60 + 'db')
135         self.proxy.object_60 = xmlrpclib.ServerProxy(url_60 + 'object')
136         #self.proxy.edi_60 = xmlrpclib.ServerProxy(url_60 + 'edi')
137
138         # Use the new (8) API.
139         self.proxy.url_8 = url_8 = 'http://%s:%d/xmlrpc/2/' % (HOST, PORT)
140         self.proxy.common_8 = xmlrpclib.ServerProxy(url_8 + 'common')
141         self.proxy.db_8 = xmlrpclib.ServerProxy(url_8 + 'db')
142         self.proxy.object_8 = xmlrpclib.ServerProxy(url_8 + 'object')
143
144     @classmethod
145     def generate_database_name(cls):
146         if hasattr(cls, '_database_id'):
147             cls._database_id += 1
148         else:
149             cls._database_id = 0
150         return '_fresh_name_' + str(cls._database_id) + '_'
151
152 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: