testDomainTool.py 28.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
##############################################################################
#
# Copyright (c) 2004 Nexedi SARL and Contributors. All Rights Reserved.
#          Sebastien Robin <seb@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################

29
import unittest
30

31

32 33
from Products.ERP5.tests.testPredicate import TestPredicateMixIn, \
    REGION_FRANCE_PATH, REGION_GERMANY_PATH, GROUP_STOREVER_PATH
34 35
from DateTime import DateTime
from zLOG import LOG
36
from Products.ZSQLCatalog.SQLCatalog import Query
37

38
class TestDomainTool(TestPredicateMixIn):
39 40 41

  # Different variables used for this test
  run_all_test = 1
42 43 44
  resource_type='Apparel Component'
  resource_variation_type='Apparel Component Variation'
  resource_module = 'apparel_component_module'
45 46 47 48 49 50 51 52 53 54 55

  def getTitle(self):
    """
    """
    return "Domain Tool"

  def getBusinessTemplateList(self):
    """
      Return the list of business templates.

    """
Sebastien Robin's avatar
Sebastien Robin committed
56
    return ('erp5_base','erp5_pdm', 'erp5_trade', 'erp5_apparel')
57

58 59 60 61 62 63 64 65 66 67 68 69 70 71
  def afterSetUp(self):
    domain_tool = self.getDomainTool()

    # Query to restrict searches to 'interesting' predicates:
    # - ignore simulation rules, which are now predicates
    # - ignore as well constraints, which are predicates
    self.portal_type_query = Query(
        operator='AND',
        portal_type=['!=%s' % x for x
          in domain_tool.getPortalRuleTypeList()
          + ('Base Domain', 'Contribution Predicate')
          + domain_tool.getPortalConstraintTypeList()])
    super(TestDomainTool, self).afterSetUp()

72
  def beforeTearDown(self):
73
    self.abort()
74 75 76 77 78 79 80 81 82 83 84 85 86

    for system_preference in self.portal.portal_preferences.objectValues(portal_type='System Preference'):
      if system_preference.getPreferenceState() != 'disabled':
        system_preference.disable()
    def deleteAll(module):
      module.manage_delObjects(ids=list(module.objectIds()))
    deleteAll(self.portal.organisation_module)
    deleteAll(self.portal.product_module)
    deleteAll(self.portal.sale_supply_module)
    deleteAll(self.portal.sale_order_module)

    self.tic()

87 88 89
  def getPortalId(self):
    return self.getPortal().getId()

90 91 92
  def getResourceModule(self):
    return getattr(self.getPortal(), self.resource_module, None)

93
  def getSaleOrderModule(self):
94
    return getattr(self.getPortal(),'sale_order_module',None)
95 96 97 98 99

  def getOrderLine(self):
    return self.getSaleOrderModule()['1']['1']

  def getPredicate(self):
100
    return self.getOrganisationModule()['1']
101 102 103

  def createData(self):
    # We have no place to put a Predicate, we will put it in a
104 105
    # Organisation Module
    organisation_module = self.getOrganisationModule()
106 107 108 109
    module_type = organisation_module.getTypeInfo()
    content_type_set = set(module_type.getTypeAllowedContentTypeList())
    content_type_set.add('Mapped Value')
    module_type._setTypeAllowedContentTypeList(tuple(content_type_set))
110 111
    if organisation_module.hasContent('1'):
      organisation_module.deleteContent('1')
112
    predicate = organisation_module.newContent(id='1',portal_type='Mapped Value')
113 114
    predicate.setCriterion('quantity',identity=None,min=None,max=None)
    
115
    resource_module = self.getResourceModule()
116 117
    if resource_module.hasContent('1'):
      resource_module.deleteContent('1')
118
    self.resource = resource = resource_module.newContent(id='1',portal_type=self.resource_type)
119 120
    resource.newContent(id='blue',portal_type=self.resource_variation_type)
    resource.newContent(id='red',portal_type=self.resource_variation_type)
121
    resource.setVariationBaseCategoryList(['variation'])
122 123
    if resource.hasContent('default_supply_line'):
      resource.deleteContent('default_supply_line')
124 125
    self.supply_line = supply_line = resource.newContent(id='default_supply_line',portal_type='Supply Line')

126 127
    # Then create an order with a particular line
    order_module = self.getSaleOrderModule()
128 129 130
    if order_module.hasContent('1'):
      order_module.deleteContent('1')
    order = order_module.newContent(id='1',portal_type='Sale Order')
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
    line = order.newContent(id='1',portal_type='Sale Order Line')

    # Then create a base category
    portal_categories = self.getCategoryTool()
    for bc in ('region', ):
      if not hasattr(portal_categories, bc):
        portal_categories.newContent(portal_type='Base Category',id=bc)
      portal_categories[bc].setAcquisitionMaskValue(1)
      portal_categories[bc].setAcquisitionCopyValue(0)
      portal_categories[bc].setAcquisitionAppendValue(0)
      if not 'europe' in portal_categories[bc].objectIds():
        big_region = portal_categories[bc].newContent(id='europe',portal_type='Category')
      if not 'africa' in portal_categories[bc].objectIds():
        big_region = portal_categories[bc].newContent(id='africa',portal_type='Category')
      if not 'asia' in portal_categories[bc].objectIds():
        big_region = portal_categories[bc].newContent(id='asia',portal_type='Category')
147 148

    self.tic()
149 150 151 152 153 154 155

  def checkPredicate(self, test=None):

    predicate = self.getPredicate()
    #predicate.setMembershipCriterionBaseCategoryList([])
    #predicate.setMembershipCriterionCategoryList([])
    #predicate.setCriterion('quantity',identity=45,min=None,max=None)
156
    #predicate.immediateReindexObject()
157 158 159 160 161 162


    order_line = self.getOrderLine()
    domain_tool = self.getDomainTool()

    # Test with order line and predicate to none
163
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,
164
        portal_type=self.portal_type_query)
165 166 167 168 169
    self.assertEquals(len(predicate_list),1) # Actually, a predicate where
                                             # nothing is defined is ok

    # Test with order line not none and predicate to none
    order_line.setQuantity(45)
170
    self.tic()
171
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,
172
        portal_type=self.portal_type_query)
173 174 175 176
    self.assertEquals(len(predicate_list),1)

    # Test with order line not none and predicate to identity
    order_line.setQuantity(45)
177
    kw = {'portal_type':'Mapped Value'}
178
    predicate.setCriterion('quantity',identity=45,min=None,max=None)
179
    self.tic()
180
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
181
    self.assertEquals(len(predicate_list),1)
182

183
    order_line.setQuantity(40)
184
    self.tic()
185
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
186 187 188 189 190 191
    self.assertEquals(len(predicate_list),0)

    # Test with order line not none and predicate to min
    order_line.setQuantity(45)
    predicate = self.getPredicate()
    predicate.setCriterion('quantity',identity=None,min=30,max=None)
192
    self.tic()
193
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
194
    self.assertEquals(len(predicate_list),1)
195

196
    order_line.setQuantity(10)
197
    self.tic()
198
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,
199
        portal_type=self.portal_type_query)
200 201 202 203 204 205
    self.assertEquals(len(predicate_list),0)

    # Test with order line not none and predicate to max
    order_line.setQuantity(45)
    predicate = self.getPredicate()
    predicate.setCriterion('quantity',identity=None,min=None,max=50)
206
    self.tic()
207
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
208
    self.assertEquals(len(predicate_list),1)
209

210
    order_line.setQuantity(60)
211
    self.tic()
212
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
213 214 215 216 217 218
    self.assertEquals(len(predicate_list),0)

    # Test with order line not none and predicate to min max
    order_line.setQuantity(20)
    predicate = self.getPredicate()
    predicate.setCriterion('quantity',identity=None,min=30,max=50)
219
    self.tic()
220
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
221
    self.assertEquals(len(predicate_list),0)
222

223
    order_line.setQuantity(60)
224
    self.tic()
225
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
226
    self.assertEquals(len(predicate_list),0)
227

228
    order_line.setQuantity(45)
229
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
230
    self.tic()
231 232 233 234 235 236
    self.assertEquals(len(predicate_list),1)

    # Test with order line not none and predicate to min max
    # and also predicate to a category
    predicate.setMembershipCriterionBaseCategoryList(['region'])
    predicate.setMembershipCriterionCategoryList(['region/europe'])
237
    self.tic()
238
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
239
    self.assertEquals(len(predicate_list),0)
240

241
    order_line.setCategoryList(['region/africa'])
242
    self.tic()
243
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
244
    self.assertEquals(len(predicate_list),0)
245

246
    order_line.setCategoryList(['region/europe'])
247
    self.tic()
248
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
249
    self.assertEquals(len(predicate_list),1)
250

251
    order_line.setQuantity(60)
252
    self.tic()
253
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
254 255
    self.assertEquals(len(predicate_list),0)

256 257 258 259 260 261
    # Test with order line not none and predicate to date min and date max
    kw = {'portal_type':'Supply Line'}
    self.supply_line.setBasePrice(23)
    self.supply_line.setPricedQuantity(1)
    self.supply_line.setDefaultResourceValue(self.resource)
    order_line.setDefaultResourceValue(self.resource)
262 263
    self.assertEquals(self.supply_line.getDefaultResourceValue(),self.resource)
    self.assertEquals(order_line.getDefaultResourceValue(),self.resource)
264 265 266 267 268 269
    date1 = DateTime('2005/04/08 10:47:26.388 GMT-4')
    date2 = DateTime('2005/04/10 10:47:26.388 GMT-4')
    self.supply_line.setStartDateRangeMin(date1)
    self.supply_line.setStartDateRangeMax(date2)
    current_date = DateTime('2005/04/1 10:47:26.388 GMT-4')
    order_line.setStartDate(current_date)
270
    self.tic()
271 272
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
    self.assertEquals(len(predicate_list),0)
273

274 275
    current_date = DateTime('2005/04/09 10:47:26.388 GMT-4')
    order_line.setStartDate(current_date)
276
    self.tic()
277 278 279
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
    self.assertEquals(len(predicate_list),1)

280 281 282 283 284 285 286 287 288 289 290 291 292 293
  def test_01_SearchPredidateListWithNoTest(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      self.logMessage('Search Predicate List With No Test')
    self.createData()
    self.checkPredicate(test=0)

  def test_02_SearchPredidateListWithTest(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      self.logMessage('Search Predicate List With Test')
    self.createData()
    self.checkPredicate(test=1)

294 295 296 297 298
  def test_03_GenerateMappedValue(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      self.logMessage('Generate Mapped Value')
    self.createData()
299
    self.supply_line.setVariationBaseCategoryList(['colour'])
300 301 302
    self.supply_line.setBasePrice(23)
    self.supply_line.setPricedQuantity(1)
    self.supply_line.setDefaultResourceValue(self.resource)
303
    #self.supply_line.setMultimembershipCriterionBaseCategoryList(['resource'])
304
    self.supply_line.setMappedValuePropertyList(['base_price','priced_quantity'])
305
    #self.supply_line.setMembershipCriterionCategoryList(['resource/%s' % self.resource.getRelativeUrl()])
306
    self.tic()
307 308
    domain_tool = self.getDomainTool()
    context = self.resource.asContext(categories=['resource/%s' % self.resource.getRelativeUrl()])
309
    mapped_value = domain_tool.generateMappedValue(context, portal_type="Supply Line")
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
    self.assertEquals(mapped_value.getBasePrice(),23)

  def test_04_GenerateMappedValueWithRanges(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      self.logMessage('Generate Mapped Value With Ranges')
    self.createData()
    self.supply_line.setBasePrice(23)
    self.supply_line.setPricedQuantity(1)
    self.supply_line.setDefaultResourceValue(self.resource)
    date1 = DateTime('2005/04/08')
    date2 = DateTime('2005/04/10')
    self.supply_line.setStartDateRangeMin(date1)
    self.supply_line.setStartDateRangeMax(date2)
    LOG('Test04, supply_line.getStartDateRangeMin',0,self.supply_line.getStartDateRangeMin())
    LOG('Test04, supply_line.getStartDateRangeMax',0,self.supply_line.getStartDateRangeMax())
    self.supply_line.setMappedValuePropertyList(['base_price','priced_quantity'])
327
    self.tic()
328 329 330 331 332 333 334 335 336 337 338
    domain_tool = self.getDomainTool()
    order_line = self.getOrderLine()
    order_line.setDefaultResourceValue(self.resource)
    current_date = DateTime('2005/04/01')
    order_line.setStartDate(current_date)
    kw = {'portal_type':('Supply Line','Supply Cell')}
    mapped_value = domain_tool.generateMappedValue(order_line,**kw)
    self.assertEquals(mapped_value,None)
    current_date = DateTime('2005/04/09')
    order_line.setStartDate(current_date)
    mapped_value = domain_tool.generateMappedValue(order_line,**kw)
339 340
    self.assertEquals(mapped_value.getBasePrice(),23)

341
  def test_05_GenerateMappedValueWithVariation(self, quiet=0, run=run_all_test):
342 343 344 345
    if not run: return
    if not quiet:
      self.logMessage('Generate Mapped Value With Variation')
    self.createData()
346
    self.supply_line.setVariationBaseCategoryList(['colour'])
347 348 349 350
    self.supply_line.setBasePrice(23)
    self.supply_line.setPricedQuantity(1)
    self.supply_line.setDefaultResourceValue(self.resource)
    self.supply_line.setMappedValuePropertyList(['base_price','priced_quantity'])
351
    self.resource.setPVariationBaseCategoryList(['variation'])
352 353 354
    self.supply_line.updateCellRange(base_id='path')
    cell_range = self.supply_line.SupplyLine_asCellRange()
    for range in cell_range[0]:
355
      cell = self.supply_line.newCell(range,base_id='path',portal_type='Supply Cell')
356 357 358 359 360 361 362 363 364 365 366
      cell.setMappedValuePropertyList(['base_price','priced_quantity'])
      cell.setMultimembershipCriterionBaseCategoryList(['resource','variation'])
      LOG('test, range',0,range)
      cell.setPricedQuantity(1)
      if range.find('blue')>=0:
        cell.setMembershipCriterionCategoryList([range])
        cell.setBasePrice(45)
      if range.find('red')>=0:
        cell.setMembershipCriterionCategoryList([range])
        cell.setBasePrice(26)

367 368 369 370
    right_price_list = [45,26]
    price_list = [x.getBasePrice() for x in self.supply_line.objectValues()]
    self.failIfDifferentSet(price_list,right_price_list)

371 372 373 374 375 376 377 378 379 380 381 382
    def sort_method(x,y):
      # make sure we get cell before
      if hasattr(x,'hasCellContent'):
        x_cell = x.hasCellContent(base_id='path')
        if x_cell:
          return 1
      if hasattr(y,'hasCellContent'):
        y_cell = y.hasCellContent(base_id='path')
        if y_cell:
          return -1
      return 0

383 384 385 386
    def sort_key_method(x):
      hasCellContent = getattr(x, 'hasCellContent', None)
      return bool(hasCellContent and hasCellContent(base_id='path'))

387
    self.tic()
388
    domain_tool = self.getDomainTool()
389 390 391
    context = self.resource.asContext(
                     categories=['resource/%s' % self.resource.getRelativeUrl(),
                     'variation/%s/blue' % self.resource.getRelativeUrl()])
392 393 394
    mapped_value = domain_tool.generateMappedValue(context,
                     portal_type=self.portal_type_query,
                     sort_method=sort_method)
395
    self.assertEquals(mapped_value.getProperty('base_price'),45)
396 397 398
    mapped_value = domain_tool.generateMappedValue(context,
                     portal_type=self.portal_type_query,
                     sort_key_method=sort_key_method)
399
    self.assertEquals(mapped_value.getProperty('base_price'),45)
400 401 402
    context = self.resource.asContext(
                     categories=['resource/%s' % self.resource.getRelativeUrl(),
                     'variation/%s/red' % self.resource.getRelativeUrl()])
403 404 405
    mapped_value = domain_tool.generateMappedValue(context,
                     portal_type=self.portal_type_query,
                     sort_method=sort_method)
406
    self.assertEquals(mapped_value.getProperty('base_price'),26)
407 408 409
    mapped_value = domain_tool.generateMappedValue(context,
                     portal_type=self.portal_type_query,
                     sort_key_method=sort_key_method)
410
    self.assertEquals(mapped_value.getProperty('base_price'),26)
411
    # Now check the price
412 413 414 415
    self.assertEquals(self.resource.getPrice(context=self.resource.asContext(
                     categories=['resource/%s' % self.resource.getRelativeUrl(),
                     'variation/%s/blue' % self.resource.getRelativeUrl()]),
                     sort_method=sort_method),45)
416 417 418 419
    self.assertEquals(self.resource.getPrice(context=self.resource.asContext(
                     categories=['resource/%s' % self.resource.getRelativeUrl(),
                     'variation/%s/blue' % self.resource.getRelativeUrl()]),
                     sort_key_method=sort_key_method),45)
420

421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
  def test_06_SQLQueryDoesNotReturnTooManyPredicates(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      self.logMessage('Check that SQL query does not return unneeded predicates')
    predicate_both_match = self.createPredicate(
        multimembership_criterion_base_category_list=['group', 'region'],
        membership_criterion_category_list=[GROUP_STOREVER_PATH, REGION_FRANCE_PATH])
    predicate_one_match = self.createPredicate(
        multimembership_criterion_base_category_list=['group', 'region'],
        membership_criterion_category_list=[GROUP_STOREVER_PATH, REGION_GERMANY_PATH])
    document = self.createDocument(group='nexedi/storever',
                                   region='europe/western_europe/france')
    self.tic()
    portal_domains = self.getPortalObject().portal_domains
    # Basic sanity checks
    self.assertTrue(predicate_both_match.test(document))
    self.assertFalse(predicate_one_match.test(document))
438
    self.assertTrue(predicate_one_match not in portal_domains.searchPredicateList(document, portal_type=self.portal_type_query, test=1))
439
    # Real test
440
    self.assertTrue(predicate_one_match not in portal_domains.searchPredicateList(document, portal_type=self.portal_type_query, test=0))
441

442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
  def test_07_NonLeftJoinModeOfSearchPredicateList(self, quiet=0, run=run_all_test):
    if not run: return
    if not quiet:
      self.logMessage('Test non-left join mode of searchPredicateList method')

    # Add system preference
    system_preference = self.portal.portal_preferences.newContent(portal_type='System Preference')
    system_preference.setPreferredPredicateCategoryList(
      ['source_section', 'destination_section', 'price_currency'])

    self.tic()

    # Add sample data
    jpy = self.portal.currency_module.newContent(portal_type='Currency',
                                                 title='JPY',
                                                 reference='JPY')
    jpy.validate()

    euro = self.portal.currency_module.newContent(portal_type='Currency',
                                                 title='EURO',
                                                 reference='EUR')
    euro.validate()

    organisation_module = self.portal.organisation_module
    company= organisation_module.newContent(portal_type='Organisation',
                                            title='Company')
    shop = organisation_module.newContent(portal_type='Organisation',
                                          title='Shop')
    supplier = organisation_module.newContent(portal_type='Organisation',
                                              title='Supplier')

    product_module = self.portal.product_module
    product1 = product_module.newContent(portal_type='Product',
                                         title='Product1')
    product2 = product_module.newContent(portal_type='Product',
                                         title='Product2')

    supply_module = self.portal.sale_supply_module
    supply1 = supply_module.newContent(portal_type='Sale Supply',
                                       title='Supply1',
                                       source_section_value=supplier,
                                       destination_section_value=shop,
                                       price_currency_value=jpy)
    supply1.newContent(portal_type='Sale Supply Line',
                       resource_value=product1)
    supply1.newContent(portal_type='Sale Supply Line',
                       resource_value=product2)
    supply2 = supply_module.newContent(portal_type='Sale Supply',
                                       title='Supply2',
                                       source_section_value=supplier,
                                       destination_section_value=company,
                                       price_currency_value=jpy)
    supply2.newContent(portal_type='Sale Supply Line',
                       resource_value=product2)
    supply3 = supply_module.newContent(portal_type='Sale Supply',
                                       title='Supply3',
                                       source_section_value=supplier,
                                       price_currency_value=euro)
    supply3.newContent(portal_type='Sale Supply Line',
                       resource_value=product1)

    order = self.portal.sale_order_module.newContent(
      portal_type='Sale Order',
      source_section_value=supplier,
      destination_section_value=shop,
      price_currency_value=jpy)
    order_line = order.newContent(portal_type='Sale Order Line',
                                  resource_value=product1)

    self.tic()

    # Test
    # Check traditional left join mode
    domain_tool = self.portal.portal_domains
    searchPredicateList = domain_tool.searchPredicateList
    self.assertEqual(len(
      searchPredicateList(order_line,
                          portal_type='Sale Supply Line')),
                     1)
    self.assert_('LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      src__=1))
    self.assertEqual(len(searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section'])),
                     4)
    self.assert_('LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section',
                                 'price_currency'],
      src__=1))
    self.assertEqual(len(searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section'])),
                     3)
    self.assert_('LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section'],
      src__=1))
    self.assertEqual(len(searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section',
                                 'price_currency'])),
                     2)
    self.assert_('LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section',
                                 'price_currency'],
      src__=1))
    self.assertEqual(len(searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section',
                                 'price_currency', 'resource'])),
                     1)
    self.assert_('LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section',
                                 'price_currency', 'resource'],
      src__=1))
    # if wrong base categories are passed, then nothing is matched
    self.assertEqual(len(searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['WAAA', 'BOOO'])),
                     0)
    self.assert_('LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['WAAA', 'BOOO'],
      src__=1))

    # Check non-left join mode
    # Enable system preference and reindex all
    system_preference.enable()
    self.tic()
    self.portal.ERP5Site_reindexAll()
    self.tic()

    # if tested_base_category_list is not passed, then left join mode is
    # still used.
    self.assertEqual(len(
      searchPredicateList(order_line,
                          portal_type='Sale Supply Line')),
                     1)
    self.assert_('LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      src__=1))

    
    self.assertEqual(len(searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section'])),
                     4)
    self.assert_(not 'LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section',
                                 'price_currency'],
      src__=1))
    self.assertEqual(len(searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section'])),
                     3)
    self.assert_(not 'LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section'],
      src__=1))
    self.assertEqual(len(searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section',
                                 'price_currency'])),
                     2)
    self.assert_(not 'LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section',
                                 'price_currency'],
      src__=1))
    self.assertEqual(len(searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section',
                                 'price_currency', 'resource'])),
                     1)
    # resource is not in preferred predicate category list, so left join
    # is used
    self.assert_('LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['source_section', 'destination_section',
                                 'price_currency', 'resource'],
      src__=1))
    # if wrong base categories are passed, then nothing is matched
    self.assertEqual(len(searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['WAAA', 'BOOO'])),
                     0)
    self.assert_('LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['WAAA', 'BOOO'],
      src__=1))
    # add WAAA and BOOO to preference, this enables non-left join mode
    system_preference.setPreferredPredicateCategoryList(
      ['source_section', 'destination_section', 'price_currency',
       'WAAA', 'BOOO'])
    self.portal.portal_caches.clearAllCache()
    self.tic()
    self.portal.ERP5Site_reindexAll()
    self.tic()
    self.assertEqual(len(searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['WAAA', 'BOOO'])),
                     0)
    self.assert_(not 'LEFT JOIN' in searchPredicateList(
      order_line,
      portal_type='Sale Supply Line',
      tested_base_category_list=['WAAA', 'BOOO'],
      src__=1))


679 680 681 682
def test_suite():
  suite = unittest.TestSuite()
  suite.addTest(unittest.makeSuite(TestDomainTool))
  return suite
683