| 
		
			Lotta		
			 
			
				
					Online
				
			
		
			Platinum Boarder		
			 Messaggi: 450Ringraziamenti ricevuti 14
			
				Karma: 3  			
		
																				 | 
	
		Ho un problema con una test unit su un metodo onchange. 
In sintesi il metodo onchange funziona nell'uso normale, ma durante il test le query eseguite per i controlli sono vuote...
 
IL CODICE 
Un metodo onchange, verifica che il valore immesso in un campo (codicefiscale) non sia già presente nel database. Per farlo esegue una una normale query self.search(…..)  class ResPartner(models.Model):
    """ Extends res.partner to add Italian Fiscal Code
    """
    # Private attributes
    _inherit = 'res.partner'
#…. omissis
    # Fields declaration
    fiscalcode = fields.Char(
        'Fiscal Code', size=16, help="Italian Fiscal Code")
    is_soletrader = fields.Boolean(
        string='Sole Trader',
        default=False,
        readonly=False,
        help="Checked if company is a sole trader")
#… omissis
    @api.multi
    @api.onchange('fiscalcode', 'parent_id')
    def onchange_fiscalcode(self):
        """ Partners not in same parent/child relationship should
        have different fiscal code.
        A proper warning is displayed.
        """
        set_trace()
        self.ensure_one()
        if not self.fiscalcode:
            # fiscalcode empty
            return {}
        # search any partner with same fiscal code in this compamy
        same_fiscalcode_partners = self.env['res.partner'].search([
            ('fiscalcode', '=', self.fiscalcode),
            ('fiscalcode', '!=', False),
            ('company_id', '=', self.company_id.id),
            ])
        if not same_fiscalcode_partners:
            # there is no partner with same fiscalcode.
            # Safe condition. return
            return {}
        if isinstance(self.id, models.NewId) and not self.parent_id:
            # new record with no parent BUT there are other partners
            # with same fiscal code
            is_fc_present = True
        else:
            # new or old record with parent
            # get first parent to start searching
            parent = self
            while parent.parent_id:
                parent = parent.parent_id
            # all partners in our family tree
            related_partners = self.env['res.partner'].search([
                ('id', 'child_of', parent.id),
                ('company_id', '=', self.company_id.id),
                ])
            # any partner with same fiscal code OUT of our family tree ?
            is_fc_present = self.env['res.partner'].search([
                ('id', 'in', same_fiscalcode_partners.ids),
                ('id', 'not in', related_partners.ids),
                ('company_id', '=', self.company_id.id),
                ])
        if is_fc_present:
            title = _('Partner fiscal code is not unique')
            message = _('WARNING:\n'
                        'Partner fiscal code must be unique per'
                        ' company except for partner with'
                        ' parent/child relationship.'
                        ' Partners with same fiscal code'
                        ' and not related, are:\n %s!') % (
                            ', '.join(x.name for x in
                                      same_fiscalcode_partners))
            result = {
                'warning': {'title': title,
                            'message': message, }, }
        else:
            result = {}
        return result
Nella unità di test (TransientCase) creo un primo record con un certo codice fiscale, e cerco poi di crearne un secondo invocando onchange, aspettandomi un messaggio di warning.
 class TestPartner(TransactionCase):
    """ Each test method is run independently and the database transaction
    is rolled back after each.
    """
    def setUp(self):
        """initializes the self.env attribute The test runner will
        run then one after the other with a call to setUp() before
        each test method and a call to tearDown() after each
        """
        super(TestPartner, self).setUp()
# -------------------------------------------------------------------
    def test_partner_onchange_fiscalcode(self):
        """ Test onchange method when an existing ficsalcode
        is provided to a new partner. 
        Needed to cover >77% for codecov...  :-( 
        """
        # Get an empty recordset
        partner = self.env['res.partner']
        # Retrieve the onchange specifications
        specs = partner._onchange_spec()
        
        # create first partner with normal fiscalcode for private citizen
        parent = self.env['res.partner'].create(
            {'name': u'Test1 Private Italian Citizen',
             'email': u"foo@gmail.com",
             'is_company': True,
             'is_soletrader': True,
             'fiscalcode': u'BNZVCN32S10E573Z', })
        test1=self.env['res.partner'].search([('fiscalcode','=','BNZVCN32S10E573Z')])
        # Prepare the values to create a child record with same fiscalcode
        values = {'name': u'OnChange Test2',
                  'email': u"foo@gmail.com",
                  'is_company': False,
                  'is_soletrader': False,
                  'parent_id': parent.id,
                  'fiscalcode': u'BNZVCN32S10E573Z', }
        # Get the result of the onchange method for fiscalcode field:
        self.env.invalidate_all()
        result = partner.onchange(values, ['fiscalcode'], specs)
        # warning: This is a dictionary containing a warning message 
        # that the web client will display to the user
        warning = result.get('warning', {})
        # check onchange method produced NO warning
        self.assertTrue(warning)
PROBLEMA 
la query di onchange durante il test restituisce un recordset vuoto (??), alias non trova il codicefiscale appena inserito nello stesso metodo di test (TransactionCase)
 
DEBUG 
debuggando le varie chiamate, mi sono accorto che nel modulo test:
 
il primo record viene creato correttamentei parametri values vengono correttamente e tutti ricevuti dal metodo onchangedentro onchange_fiscalcode la query same_fiscalcode_partners = self.env[ 'res.partner'].search([..... è vuotaHo provato anche a "forzare" la query nel onchange da self.search() a self.env[ 'res.partner' ].search([, ma la query restituisce sempre un recordset vuoto....
 
DOMANDA 
Sto facendo degli errori di logica o è un bug ? 
Il TransactionCase non dovrebbe garantire che il record creato nel metodo di test (con il codicefiscale cercato) sia presente nel DB, e cancellato solo DOPO il termine del metodo ? 
Come posso fare per invocare onchange non su un record nuovo (dizionario di valori passati) , ma su un record  esistente ?	 |