testDomainTool.py 24.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
from DateTime import DateTime
35
from Products.ZSQLCatalog.SQLCatalog import Query
36

37
class TestDomainTool(TestPredicateMixIn):
38 39 40

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

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

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

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

57 58 59 60 61 62 63 64 65 66 67 68 69 70
  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()

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

    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()

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

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

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

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

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

  def createData(self):
    # We have no place to put a Predicate, we will put it in a
103 104
    # Organisation Module
    organisation_module = self.getOrganisationModule()
105 106 107 108
    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))
109 110
    if organisation_module.hasContent('1'):
      organisation_module.deleteContent('1')
111
    predicate = organisation_module.newContent(id='1',portal_type='Mapped Value')
112
    predicate.setCriterion('quantity',identity=None,min=None,max=None)
113

114
    resource_module = self.getResourceModule()
115 116
    if resource_module.hasContent('1'):
      resource_module.deleteContent('1')
117
    self.resource = resource = resource_module.newContent(id='1',portal_type=self.resource_type)
118 119
    resource.newContent(id='blue',portal_type=self.resource_variation_type)
    resource.newContent(id='red',portal_type=self.resource_variation_type)
120
    resource.setVariationBaseCategoryList(['variation'])
121 122
    if resource.hasContent('default_supply_line'):
      resource.deleteContent('default_supply_line')
123 124
    self.supply_line = supply_line = resource.newContent(id='default_supply_line',portal_type='Supply Line')

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

    self.tic()
148 149 150 151

  def checkPredicate(self, test=None):
    predicate = self.getPredicate()
    order_line = self.getOrderLine()
152 153 154 155 156 157 158
    searchPredicateList = self.getDomainTool().searchPredicateList
    def assertPredicateItemsMatchingOrderLineEqual(expected, **kw):
      self.tic()
      self.assertItemsEqual(
        expected,
        searchPredicateList(order_line, test=test, **kw),
      )
159 160

    # Test with order line and predicate to none
161 162
    # Actually, a predicate where nothing is defined is ok
    assertPredicateItemsMatchingOrderLineEqual([predicate], portal_type=self.portal_type_query)
163 164
    # Test with order line not none and predicate to none
    order_line.setQuantity(45)
165
    assertPredicateItemsMatchingOrderLineEqual([predicate], portal_type=self.portal_type_query)
166 167
    # Test with order line not none and predicate to identity
    order_line.setQuantity(45)
168 169
    predicate.setCriterion('quantity', identity=45, min=None, max=None)
    assertPredicateItemsMatchingOrderLineEqual([predicate], portal_type='Mapped Value')
170
    order_line.setQuantity(40)
171
    assertPredicateItemsMatchingOrderLineEqual([], portal_type='Mapped Value')
172 173
    # Test with order line not none and predicate to min
    order_line.setQuantity(45)
174 175
    predicate.setCriterion('quantity', identity=None, min=30, max=None)
    assertPredicateItemsMatchingOrderLineEqual([predicate], portal_type='Mapped Value')
176
    order_line.setQuantity(10)
177
    assertPredicateItemsMatchingOrderLineEqual([], portal_type=self.portal_type_query) # XXX: mistake in the test ?
178 179
    # Test with order line not none and predicate to max
    order_line.setQuantity(45)
180 181
    predicate.setCriterion('quantity', identity=None, min=None, max=50)
    assertPredicateItemsMatchingOrderLineEqual([predicate], portal_type='Mapped Value')
182
    order_line.setQuantity(60)
183
    assertPredicateItemsMatchingOrderLineEqual([], portal_type='Mapped Value')
184 185
    # Test with order line not none and predicate to min max
    order_line.setQuantity(20)
186 187
    predicate.setCriterion('quantity', identity=None, min=30, max=50)
    assertPredicateItemsMatchingOrderLineEqual([], portal_type='Mapped Value')
188
    order_line.setQuantity(60)
189
    assertPredicateItemsMatchingOrderLineEqual([], portal_type='Mapped Value')
190
    order_line.setQuantity(45)
191
    assertPredicateItemsMatchingOrderLineEqual([predicate], portal_type='Mapped Value')
192 193 194 195
    # Test with order line not none and predicate to min max
    # and also predicate to a category
    predicate.setMembershipCriterionBaseCategoryList(['region'])
    predicate.setMembershipCriterionCategoryList(['region/europe'])
196
    assertPredicateItemsMatchingOrderLineEqual([], portal_type='Mapped Value')
197
    order_line.setCategoryList(['region/africa'])
198
    assertPredicateItemsMatchingOrderLineEqual([], portal_type='Mapped Value')
199
    order_line.setCategoryList(['region/europe'])
200
    assertPredicateItemsMatchingOrderLineEqual([predicate], portal_type='Mapped Value')
201
    order_line.setQuantity(60)
202
    assertPredicateItemsMatchingOrderLineEqual([], portal_type='Mapped Value')
203 204 205 206 207
    # Test with order line not none and predicate to date min and date max
    self.supply_line.setBasePrice(23)
    self.supply_line.setPricedQuantity(1)
    self.supply_line.setDefaultResourceValue(self.resource)
    order_line.setDefaultResourceValue(self.resource)
208 209
    self.assertEqual(self.supply_line.getDefaultResourceValue(), self.resource)
    self.assertEqual(order_line.getDefaultResourceValue(), self.resource)
210 211 212 213 214 215
    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)
216
    assertPredicateItemsMatchingOrderLineEqual([], portal_type='Supply Line')
217 218
    current_date = DateTime('2005/04/09 10:47:26.388 GMT-4')
    order_line.setStartDate(current_date)
219
    assertPredicateItemsMatchingOrderLineEqual([self.supply_line], portal_type='Supply Line')
220

221
  def test_01_SearchPredidateListWithNoTest(self):
222 223 224
    self.createData()
    self.checkPredicate(test=0)

225
  def test_02_SearchPredidateListWithTest(self):
226 227 228
    self.createData()
    self.checkPredicate(test=1)

229
  def test_03_GenerateMappedValue(self):
230
    self.createData()
231
    self.supply_line.setVariationBaseCategoryList(['colour'])
232 233 234
    self.supply_line.setBasePrice(23)
    self.supply_line.setPricedQuantity(1)
    self.supply_line.setDefaultResourceValue(self.resource)
235
    #self.supply_line.setMultimembershipCriterionBaseCategoryList(['resource'])
236
    self.supply_line.setMappedValuePropertyList(['base_price','priced_quantity'])
237
    #self.supply_line.setMembershipCriterionCategoryList(['resource/%s' % self.resource.getRelativeUrl()])
238
    self.tic()
239 240
    domain_tool = self.getDomainTool()
    context = self.resource.asContext(categories=['resource/%s' % self.resource.getRelativeUrl()])
241
    mapped_value = domain_tool.generateMappedValue(context, portal_type="Supply Line")
242
    self.assertEqual(mapped_value.getBasePrice(),23)
243

244
  def test_04_GenerateMappedValueWithRanges(self):
245 246 247 248 249 250 251 252 253
    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)
    self.supply_line.setMappedValuePropertyList(['base_price','priced_quantity'])
254
    self.tic()
255 256 257 258 259 260 261
    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)
262
    self.assertEqual(mapped_value,None)
263 264 265
    current_date = DateTime('2005/04/09')
    order_line.setStartDate(current_date)
    mapped_value = domain_tool.generateMappedValue(order_line,**kw)
266
    self.assertEqual(mapped_value.getBasePrice(),23)
267

268
  def test_05_GenerateMappedValueWithVariation(self):
269
    self.createData()
270
    self.supply_line.setVariationBaseCategoryList(['colour'])
271 272 273 274
    self.supply_line.setBasePrice(23)
    self.supply_line.setPricedQuantity(1)
    self.supply_line.setDefaultResourceValue(self.resource)
    self.supply_line.setMappedValuePropertyList(['base_price','priced_quantity'])
275
    self.resource.setPVariationBaseCategoryList(['variation'])
276 277 278
    self.supply_line.updateCellRange(base_id='path')
    cell_range = self.supply_line.SupplyLine_asCellRange()
    for range in cell_range[0]:
279
      cell = self.supply_line.newCell(range,base_id='path',portal_type='Supply Cell')
280 281 282 283 284 285 286 287 288 289
      cell.setMappedValuePropertyList(['base_price','priced_quantity'])
      cell.setMultimembershipCriterionBaseCategoryList(['resource','variation'])
      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)

290 291 292 293
    right_price_list = [45,26]
    price_list = [x.getBasePrice() for x in self.supply_line.objectValues()]
    self.failIfDifferentSet(price_list,right_price_list)

294 295 296 297 298 299 300 301 302 303 304 305
    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

306 307 308 309
    def sort_key_method(x):
      hasCellContent = getattr(x, 'hasCellContent', None)
      return bool(hasCellContent and hasCellContent(base_id='path'))

310
    self.tic()
311
    domain_tool = self.getDomainTool()
312 313 314
    context = self.resource.asContext(
                     categories=['resource/%s' % self.resource.getRelativeUrl(),
                     'variation/%s/blue' % self.resource.getRelativeUrl()])
315 316 317
    mapped_value = domain_tool.generateMappedValue(context,
                     portal_type=self.portal_type_query,
                     sort_method=sort_method)
318
    self.assertEqual(mapped_value.getProperty('base_price'),45)
319 320 321
    mapped_value = domain_tool.generateMappedValue(context,
                     portal_type=self.portal_type_query,
                     sort_key_method=sort_key_method)
322
    self.assertEqual(mapped_value.getProperty('base_price'),45)
323 324 325
    context = self.resource.asContext(
                     categories=['resource/%s' % self.resource.getRelativeUrl(),
                     'variation/%s/red' % self.resource.getRelativeUrl()])
326 327 328
    mapped_value = domain_tool.generateMappedValue(context,
                     portal_type=self.portal_type_query,
                     sort_method=sort_method)
329
    self.assertEqual(mapped_value.getProperty('base_price'),26)
330 331 332
    mapped_value = domain_tool.generateMappedValue(context,
                     portal_type=self.portal_type_query,
                     sort_key_method=sort_key_method)
333
    self.assertEqual(mapped_value.getProperty('base_price'),26)
334
    # Now check the price
335
    self.assertEqual(self.resource.getPrice(context=self.resource.asContext(
336 337 338
                     categories=['resource/%s' % self.resource.getRelativeUrl(),
                     'variation/%s/blue' % self.resource.getRelativeUrl()]),
                     sort_method=sort_method),45)
339
    self.assertEqual(self.resource.getPrice(context=self.resource.asContext(
340 341 342
                     categories=['resource/%s' % self.resource.getRelativeUrl(),
                     'variation/%s/blue' % self.resource.getRelativeUrl()]),
                     sort_key_method=sort_key_method),45)
343

344
  def test_06_SQLQueryDoesNotReturnTooManyPredicates(self):
345 346 347 348 349 350 351 352 353 354 355 356 357
    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))
358
    self.assertTrue(predicate_one_match not in portal_domains.searchPredicateList(document, portal_type=self.portal_type_query, test=1))
359
    # Real test
360
    self.assertTrue(predicate_one_match not in portal_domains.searchPredicateList(document, portal_type=self.portal_type_query, test=0))
361

362
  def test_07_NonLeftJoinModeOfSearchPredicateList(self):
363
    searchPredicateList = self.portal.portal_domains.searchPredicateList
364 365
    # Add system preference
    system_preference = self.portal.portal_preferences.newContent(portal_type='System Preference')
366
    system_preference.setPreferredPredicateCategoryList(['source_section', 'destination_section', 'price_currency'])
367
    # Add sample data
368
    jpy = self.portal.currency_module.newContent(portal_type='Currency', title='JPY', reference='JPY')
369
    jpy.validate()
370
    euro = self.portal.currency_module.newContent(portal_type='Currency', title='EURO', reference='EUR')
371
    euro.validate()
372 373 374 375
    newOrganisation = self.portal.organisation_module.newContent
    company= newOrganisation(portal_type='Organisation', title='Company')
    shop = newOrganisation(portal_type='Organisation', title='Shop')
    supplier = newOrganisation(portal_type='Organisation', title='Supplier')
376
    product_module = self.portal.product_module
377 378
    product1 = product_module.newContent(portal_type='Product', title='Product1')
    product2 = product_module.newContent(portal_type='Product', title='Product2')
379
    supply_module = self.portal.sale_supply_module
380
    supply1 = supply_module.newContent(portal_type='Sale Supply', title='Supply1', source_section_value=supplier, destination_section_value=shop, price_currency_value=jpy)
381
    supply1.validate()
382 383 384
    supply1_line1 = supply1.newContent(portal_type='Sale Supply Line', resource_value=product1)
    supply1_line2 = 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)
385
    supply2.validate()
386 387
    supply2_line1 = 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)
388
    supply3.validate()
389
    supply3_line1 = supply3.newContent(portal_type='Sale Supply Line', resource_value=product1)
390 391 392 393 394
    order = self.portal.sale_order_module.newContent(
      portal_type='Sale Order',
      source_section_value=supplier,
      destination_section_value=shop,
      price_currency_value=jpy)
395 396 397 398
    order_line = order.newContent(
      portal_type='Sale Order Line',
      resource_value=product1,
    )
399 400
    self.tic()

401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
    def assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(uses_left_join, expected, **kw):
      kw['context'] = order_line
      kw['portal_type'] = 'Sale Supply Line'
      src = searchPredicateList(src__=1, **kw)
      if uses_left_join:
        self.assertIn('LEFT JOIN', src)
      else:
        self.assertNotIn('LEFT JOIN', src)
      self.assertItemsEqual(expected, searchPredicateList(**kw))

    # Check left join mode
    assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(True, [supply1_line1])
    assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(True, [supply1_line1, supply1_line2, supply2_line1, supply3_line1], tested_base_category_list=['source_section'])
    assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(True, [supply1_line1, supply1_line2, supply3_line1], tested_base_category_list=['source_section', 'destination_section'])
    assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(True, [supply1_line1, supply1_line2], tested_base_category_list=['source_section', 'destination_section', 'price_currency'])
    assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(True, [supply1_line1], tested_base_category_list=['source_section', 'destination_section', 'price_currency', 'resource'])

    # Check inner-join mode
    # Enable system preference and reindex relevant predicates
420 421
    system_preference.enable()
    self.tic()
422
    supply_module.Folder_reindexAll()
423
    self.tic()
424 425 426 427 428 429 430 431 432
    # if document has relations using base categories which are not present in the preference, then left join mode is still used.
    assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(True, [supply1_line1])
    assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(False, [supply1_line1, supply1_line2, supply2_line1, supply3_line1], tested_base_category_list=['source_section'])
    assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(False, [supply1_line1, supply1_line2, supply3_line1], tested_base_category_list=['source_section', 'destination_section'])
    assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(False, [supply1_line1, supply1_line2], tested_base_category_list=['source_section', 'destination_section', 'price_currency'])
    # resource is not in preferred predicate category list, so left join is used
    assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(True, [supply1_line1], tested_base_category_list=['source_section', 'destination_section', 'price_currency', 'resource'])
    # add resource to preference, this enables non-left join mode
    system_preference.setPreferredPredicateCategoryList(['source_section', 'destination_section', 'price_currency', 'resource'])
433 434
    self.portal.portal_caches.clearAllCache()
    self.tic()
435
    supply_module.Folder_reindexAll()
436
    self.tic()
437 438
    # resource is not in preferred predicate category list, so only inner join is used
    assertUsesLeftJoinAndPredicateItemsMatchingOrderLineEqual(False, [supply1_line1], tested_base_category_list=['source_section', 'destination_section', 'price_currency', 'resource'])
439

440 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
  def test_searchPredicateInvalidCategories(self):
    predicate = self.portal.sale_supply_module.newContent(
      portal_type='Sale Supply')
    predicate.validate()
    self.assertNotEquals(predicate.asPredicate(), None)

    context = self.portal.person_module.newContent(
      portal_type='Person',
      region=('broken/category'))

    # An invalid category should raise explicitly, for all parameters of
    # searchPredicateList ( the code paths are different )
    self.assertRaises(TypeError, self.portal.portal_domains.searchPredicateList,
      context=context, portal_type=predicate.portal_type)
    self.assertRaises(TypeError, self.portal.portal_domains.searchPredicateList,
      context=context, portal_type=predicate.portal_type, acquired=False)
    self.assertRaises(TypeError, self.portal.portal_domains.searchPredicateList,
      context=context, portal_type=predicate.portal_type,
      tested_base_category_list=['region'])
    self.assertRaises(TypeError, self.portal.portal_domains.searchPredicateList,
      context=context, portal_type=predicate.portal_type,
      tested_base_category_list=['region'], acquired=False)

    # This is also the case if there are multiple categories (another code
    # path)
    context = self.portal.person_module.newContent(
      portal_type='Person',
      region=('broken/category', 'region'))
    self.assertRaises(TypeError, self.portal.portal_domains.searchPredicateList,
      context=context, portal_type=predicate.portal_type)


472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
  def test_setRelationToBaseDomain(self):
    # category accessors can be useed to set relations to base domains.
    base_domain = self.portal.portal_domains.newContent(
      portal_type='Base Domain')
    # get a document with source accessor
    document = self.portal.sale_order_module.newContent(
      portal_type='Sale Order')

    document.setSourceValue(base_domain)
    self.assertEqual(base_domain, document.getSourceValue())

  def test_setRelationToDomain(self):
    # category accessors can be useed to set relations to domains.
    base_domain = self.portal.portal_domains.newContent(
      portal_type='Base Domain')
    domain = base_domain.newContent(portal_type='Domain')
    # get a document with source accessor
    document = self.portal.sale_order_module.newContent(
      portal_type='Sale Order')

    document.setSourceValue(domain)
    self.assertEqual(domain, document.getSourceValue())

495

496 497 498 499
def test_suite():
  suite = unittest.TestSuite()
  suite.addTest(unittest.makeSuite(TestDomainTool))
  return suite
500