@ -1,42 +1,31 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
# Copyright 2014-2017 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
# Copyright 2014-2018 Therp BV <https://therp.nl>.
# License AGPL-3.0 or later (https ://www.gnu.org/licenses/agpl.html).
from lxml import etree
from lxml import etree
from odoo.exceptions import ValidationError
from odoo.exceptions import ValidationError
from odoo.tests import common
from . import common
from ..tablib import Tab
class FakeTab ( ) :
def __init__ ( self , id , name ) :
self . id = id
self . name = name
class TestPartnerTabs ( common . SingleTransactionCase ) :
class TestPartnerTabs ( common . TestCommon ) :
post_install = True
post_install = True
def test_create_tab ( self ) :
def test_create_tab ( self ) :
tab_model = self . env [ ' res.partner.tab ' ]
partner_model = self . env [ ' res.partner ' ]
new_tab = tab_model . create ( {
' code ' : ' executive ' ,
' name ' : ' Executive members ' ,
' contact_type ' : ' c ' } )
self . assertTrue ( bool ( new_tab ) )
# There should now be a field in res_partner for the new tab.
fieldname = partner_model . _get_tab_fieldname ( new_tab )
self . assertTrue ( fieldname in partner_model . _fields )
# The form view for partner should now also contain the tab,
# if the view contains tabs in the first place.
self . assertTrue ( bool ( self . tab_board ) )
tab_obj = Tab ( self . tab_board )
# fields_view_get should force the creation of the new tabs.
view_partner_form = self . env . ref ( ' base.view_partner_form ' )
view_partner_form = self . env . ref ( ' base.view_partner_form ' )
view = partner_model . with_context ( ) . fields_view_get (
view = self . partner_model . with_context ( ) . fields_view_get (
view_id = view_partner_form . id , view_type = ' form ' )
view_id = view_partner_form . id , view_type = ' form ' )
# The form view for partner should now also contain field 'id'.
tree = etree . fromstring ( view [ ' arch ' ] )
tree = etree . fromstring ( view [ ' arch ' ] )
field = tree . xpath ( ' //field[@name= " id " ] ' )
field = tree . xpath ( ' //field[@name= " id " ] ' )
self . assertTrue ( field , ' Id field does not exist. ' )
self . assertTrue ( field , ' Id field does not exist. ' )
# There should now be a field in res_partner for the new tab.
fieldname = tab_obj . get_fieldname ( )
self . assertTrue ( fieldname in self . partner_model . _fields )
# And we should have a field for the tab:
# And we should have a field for the tab:
field = tree . xpath ( ' //field[@name= " %s " ] ' % fieldname )
field = tree . xpath ( ' //field[@name= " %s " ] ' % fieldname )
self . assertTrue (
self . assertTrue (
@ -44,7 +33,8 @@ class TestPartnerTabs(common.SingleTransactionCase):
' Tab field %s does not exist in %s . ' %
' Tab field %s does not exist in %s . ' %
( fieldname , etree . tostring ( tree ) ) )
( fieldname , etree . tostring ( tree ) ) )
# There should be no effect on the tree view:
# There should be no effect on the tree view:
view = partner_model . with_context ( ) . fields_view_get ( view_type = ' tree ' )
view = self . partner_model . with_context ( ) . fields_view_get (
view_type = ' tree ' )
tree = etree . fromstring ( view [ ' arch ' ] )
tree = etree . fromstring ( view [ ' arch ' ] )
field = tree . xpath ( ' //field[@name= " %s " ] ' % fieldname )
field = tree . xpath ( ' //field[@name= " %s " ] ' % fieldname )
self . assertFalse (
self . assertFalse (
@ -53,165 +43,83 @@ class TestPartnerTabs(common.SingleTransactionCase):
( fieldname , etree . tostring ( tree ) ) )
( fieldname , etree . tostring ( tree ) ) )
def test_tab_modifications ( self ) :
def test_tab_modifications ( self ) :
category_model = self . env [ ' res.partner.category ' ]
tab_model = self . env [ ' res.partner.tab ' ]
type_model = self . env [ ' res.partner.relation.type ' ]
category_government = category_model . create ( { ' name ' : ' Government ' } )
executive_tab = tab_model . create ( {
tab_executive = self . tab_model . create ( {
' code ' : ' executive ' ,
' code ' : ' executive ' ,
' name ' : ' Executive members ' } )
' name ' : ' Executive members ' } )
self . assertTrue ( bool ( executive_tab ) )
type_has_ chairperson = type_model . create ( {
self . assertTrue ( bool ( tab_executive ) )
type_chairperson = self . type_model . create ( {
' name ' : ' has chairperson ' ,
' name ' : ' has chairperson ' ,
' name_inverse ' : ' is chairperson for ' ,
' name_inverse ' : ' is chairperson for ' ,
' contact_type_left ' : ' p ' , # This emulates a user mistake.
' contact_type_right ' : ' p ' ,
' contact_type_right ' : ' p ' ,
' tab_left_id ' : executive_tab . id } )
self . assertTrue ( bool ( type_has_ chairperson ) )
' tab_left_id ' : tab_ executive. id } )
self . assertTrue ( bool ( type_chairperson ) )
# If we change tab now to be only valid on company partners
# If we change tab now to be only valid on company partners
# the tab_left_id field should be cleared from the type:
# the tab_left_id field should be cleared from the type:
executive_tab . write ( {
' contact_type ' : ' c ' ,
' partner_category_id ' : category_government . id } )
self . assertFalse ( type_has_chairperson . tab_left_id . id )
tab_executive . write ( { ' contact_type ' : ' c ' } )
self . assertFalse ( type_chairperson . tab_left_id . id )
# Trying to set the tab back on type should be impossible:
# Trying to set the tab back on type should be impossible:
with self . assertRaises ( ValidationError ) :
with self . assertRaises ( ValidationError ) :
type_has_chairperson . write ( { ' tab_left_id ' : executive_tab . id } )
# We should be able to change tab, if also changing contact type
# and category:
type_has_chairperson . write ( {
' partner_category_left ' : category_government . id ,
type_chairperson . write ( { ' tab_left_id ' : tab_executive . id } )
# We should be able to change tab, if also changing contact type.
type_chairperson . write ( {
' contact_type_left ' : ' c ' ,
' contact_type_left ' : ' c ' ,
' tab_left_id ' : executive_tab . id } )
' tab_left_id ' : tab_executive . id } )
self . assertEqual (
self . assertEqual (
type_has_ chairperson . tab_left_id . id ,
executive_tab . id )
# Unlinking the tab should reset the tab name on relations:
executive_tab . unlink ( )
type_chairperson . tab_left_id . id ,
tab_ executive. id )
# Unlinking the tab should reset the tab_left_id on relation type.
tab_ executive. unlink ( )
self . assertEqual (
self . assertEqual (
type_has_ chairperson . tab_left_id . id ,
type_chairperson . tab_left_id . id ,
False )
False )
def test_relation_type_modifications ( self ) :
category_model = self . env [ ' res.partner.category ' ]
tab_model = self . env [ ' res.partner.tab ' ]
type_model = self . env [ ' res.partner.relation.type ' ]
category_government = category_model . create ( { ' name ' : ' Government ' } )
category_positions = category_model . create ( { ' name ' : ' Positions ' } )
executive_tab = tab_model . create ( {
' code ' : ' executive ' ,
' name ' : ' Executive members ' ,
' contact_type ' : ' c ' ,
' partner_category_id ' : category_government . id } )
self . assertTrue ( bool ( executive_tab ) )
positions_tab = tab_model . create ( {
' code ' : ' positions ' ,
' name ' : ' Positions held ' ,
' contact_type ' : ' p ' ,
' partner_category_id ' : category_positions . id } )
self . assertTrue ( bool ( executive_tab ) )
type_has_chairperson = type_model . create ( {
' name ' : ' has chairperson ' ,
' name_inverse ' : ' is chairperson for ' ,
' partner_category_left ' : category_government . id ,
' contact_type_left ' : ' c ' ,
' tab_left_id ' : executive_tab . id ,
' partner_category_right ' : category_positions . id ,
' contact_type_right ' : ' p ' ,
' tab_right_id ' : positions_tab . id } )
self . assertTrue ( bool ( type_has_chairperson ) )
def test_type_modifications ( self ) :
self . assertTrue ( bool ( self . tab_board ) )
self . assertTrue ( bool ( self . tab_positions ) )
self . assertTrue ( bool ( self . type_chairperson ) )
# Trying to clear either category should raise ValidationError:
# Trying to clear either category should raise ValidationError:
with self . assertRaises ( ValidationError ) :
with self . assertRaises ( ValidationError ) :
type_has _chairperson . write ( { ' partner_category_left ' : False } )
self . type_chairperson . write ( { ' partner_category_left ' : False } )
with self . assertRaises ( ValidationError ) :
with self . assertRaises ( ValidationError ) :
type_has _chairperson . write ( { ' partner_category_right ' : False } )
self . type_chairperson . write ( { ' partner_category_right ' : False } )
# Trying to clear either contact type should raise ValidationError:
# Trying to clear either contact type should raise ValidationError:
with self . assertRaises ( ValidationError ) :
with self . assertRaises ( ValidationError ) :
type_has _chairperson . write ( { ' contact_type_left ' : False } )
self . type_chairperson . write ( { ' contact_type_left ' : False } )
with self . assertRaises ( ValidationError ) :
with self . assertRaises ( ValidationError ) :
type_has _chairperson . write ( { ' contact_type_right ' : False } )
self . type_chairperson . write ( { ' contact_type_right ' : False } )
def test_relations ( self ) :
def test_relations ( self ) :
""" Test relations shown on tab. """
""" Test relations shown on tab. """
tab_model = self . env [ ' res.partner.tab ' ]
type_model = self . env [ ' res.partner.relation.type ' ]
partner_model = self . env [ ' res.partner ' ]
relation_model = self . env [ ' res.partner.relation ' ]
relation_all_model = self . env [ ' res.partner.relation.all ' ]
relation_all_model = self . env [ ' res.partner.relation.all ' ]
executive_tab = tab_model . create ( {
' code ' : ' executive ' ,
' name ' : ' Executive members ' } )
self . assertTrue ( bool ( executive_tab ) )
type_has_chairperson = type_model . create ( {
' name ' : ' has chairperson ' ,
' name_inverse ' : ' is chairperson for ' ,
' contact_type_right ' : ' p ' ,
' tab_left_id ' : executive_tab . id } )
self . assertTrue ( bool ( type_has_chairperson ) )
big_company = partner_model . create ( {
' name ' : ' Big company ' ,
' is_company ' : True ,
' ref ' : ' BIG ' } )
self . assertTrue ( bool ( big_company ) )
important_person = partner_model . create ( {
' name ' : ' Bart Simpson ' ,
' is_company ' : False ,
' ref ' : ' BS ' } )
self . assertTrue ( bool ( important_person ) )
relation_company_chair = relation_model . create ( {
' left_partner_id ' : big_company . id ,
' type_id ' : type_has_chairperson . id ,
' right_partner_id ' : important_person . id } )
self . assertTrue ( bool ( relation_company_chair ) )
self . assertTrue ( bool ( self . tab_board ) )
self . assertTrue ( bool ( self . type_ceo ) )
self . assertTrue ( bool ( self . partner_big_company ) )
self . assertTrue ( bool ( self . partner_important_person ) )
self . assertTrue ( bool ( self . relation_company_ceo ) )
# Now we should be able to find the relation with the tab_id:
# Now we should be able to find the relation with the tab_id:
relation_all_company_chair = relation_all_model . search ( [
( ' tab_id ' , ' = ' , executive_tab . id ) ] , limit = 1 )
self . assertTrue ( bool ( relation_all_company_chair ) )
self . assertEqual (
relation_company_chair . left_partner_id . id ,
relation_all_company_chair . this_partner_id . id )
board_partners = relation_all_model . search ( [
( ' tab_id ' , ' = ' , self . tab_board . id ) ] )
self . assertTrue ( bool ( board_partners ) )
self . assertIn (
self . partner_big_company ,
[ relation . this_partner_id for relation in board_partners ] )
# We should find the company on the partner through tab field:
# We should find the company on the partner through tab field:
fieldname = partner_model . _get_tab_fieldname ( executive_tab )
self . assertTrue ( fieldname in partner_model . _fields )
executive_partners = big_company [ fieldname ]
self . assertEqual ( len ( executive_partners ) , 1 )
tab_obj = Tab ( self . tab_board )
fieldname = tab_obj . get_fieldname ( )
self . assertTrue ( fieldname in self . partner_model . _fields )
board_partners = self . partner_big_company [ fieldname ]
self . assertEqual ( len ( board_partners ) , 1 )
self . assertEqual (
self . assertEqual (
executive _partners. other_partner_id . id ,
important_person . id )
board_partners . other_partner_id . id ,
self . partner_important_person . id )
# When adding a new relation on a tab, type must be for tab.
# When adding a new relation on a tab, type must be for tab.
onchange_result = executive _partners. with_context (
default_tab_id = executive_tab . id
onchange_result = board_partners . with_context (
default_tab_id = self . tab_board . id
) . onchange_partner_id ( )
) . onchange_partner_id ( )
self . assertTrue ( onchange_result )
self . assertTrue ( onchange_result )
self . assertIn ( ' domain ' , onchange_result )
self . assertIn ( ' domain ' , onchange_result )
self . assertIn ( ' type_selection_id ' , onchange_result [ ' domain ' ] )
self . assertIn ( ' type_selection_id ' , onchange_result [ ' domain ' ] )
self . assertEqual (
self . assertEqual (
onchange_result [ ' domain ' ] [ ' type_selection_id ' ] [ - 1 ] ,
onchange_result [ ' domain ' ] [ ' type_selection_id ' ] [ - 1 ] ,
( ' tab_id ' , ' = ' , executive_tab . id ) )
def test_update_tabs ( self ) :
""" Test the function that will create tabs during module loading. """
tab_model = self . env [ ' res.partner.tab ' ]
partner_model = self . env [ ' res.partner ' ]
executive_tab = tab_model . create ( {
' code ' : ' executive ' ,
' name ' : ' Executive members ' } )
self . assertTrue ( bool ( executive_tab ) )
tabfield_executive_name = partner_model . _get_tab_fieldname (
executive_tab )
# Create some fake tab fields (should be removed).
tab_123 = FakeTab ( 123 , ' First tab ' )
tab_456 = FakeTab ( 456 , ' Second tab ' )
# Add "tab fields"
partner_model . _add_tab_field ( tab_123 )
tabfield_123_name = partner_model . _get_tab_fieldname ( tab_123 )
self . assertEqual (
partner_model . _fields [ tabfield_123_name ] . string , tab_123 . name )
partner_model . _add_tab_field ( tab_456 )
tabfield_456_name = partner_model . _get_tab_fieldname ( tab_456 )
self . assertEqual (
partner_model . _fields [ tabfield_456_name ] . string , tab_456 . name )
# Now call hook method
partner_model . _register_hook ( )
self . assertFalse ( tabfield_123_name in partner_model . _fields )
self . assertFalse ( tabfield_456_name in partner_model . _fields )
self . assertTrue ( tabfield_executive_name in partner_model . _fields )
( ' tab_id ' , ' = ' , self . tab_board . id ) )