testDomainTool.py 17.6 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
from Products.ERP5.tests.testPredicate import TestPredicateMixIn, REGION_FRANCE_PATH, REGION_GERMANY_PATH, GROUP_STOREVER_PATH, GROUP_OTHER_PATH
32
from DateTime import DateTime
33
from AccessControl.SecurityManagement import newSecurityManager
34
from zLOG import LOG
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

  def getPortalId(self):
    return self.getPortal().getId()

60 61 62
  def getResourceModule(self):
    return getattr(self.getPortal(), self.resource_module, None)

63
  def getSaleOrderModule(self):
64
    return getattr(self.getPortal(),'sale_order_module',None)
65 66 67 68 69

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

  def getPredicate(self):
70
    return self.getOrganisationModule()['1']
71 72 73

  def createData(self):
    # We have no place to put a Predicate, we will put it in a
74
    # Organisation Module
75 76
    portal = self.getPortal()
    type_tool = self.getTypeTool()
77
    module_type = type_tool['Organisation Module']
78
    module_type.allowed_content_types += ('Mapped Value',)
79
    organisation_module = self.getOrganisationModule()
80 81
    if organisation_module.hasContent('1'):
      organisation_module.deleteContent('1')
82
    predicate = organisation_module.newContent(id='1',portal_type='Mapped Value')
83 84
    predicate.setCriterion('quantity',identity=None,min=None,max=None)
    
85
    resource_module = self.getResourceModule()
86 87
    if resource_module.hasContent('1'):
      resource_module.deleteContent('1')
88
    self.resource = resource = resource_module.newContent(id='1',portal_type=self.resource_type)
89 90
    resource.newContent(id='blue',portal_type=self.resource_variation_type)
    resource.newContent(id='red',portal_type=self.resource_variation_type)
91
    resource.setVariationBaseCategoryList(['variation'])
92 93
    if resource.hasContent('default_supply_line'):
      resource.deleteContent('default_supply_line')
94 95
    self.supply_line = supply_line = resource.newContent(id='default_supply_line',portal_type='Supply Line')

96 97
    # Then create an order with a particular line
    order_module = self.getSaleOrderModule()
98 99 100
    if order_module.hasContent('1'):
      order_module.deleteContent('1')
    order = order_module.newContent(id='1',portal_type='Sale Order')
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
    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')
117 118 119

    get_transaction().commit()
    self.tic()
120 121 122 123 124 125 126

  def checkPredicate(self, test=None):

    predicate = self.getPredicate()
    #predicate.setMembershipCriterionBaseCategoryList([])
    #predicate.setMembershipCriterionCategoryList([])
    #predicate.setCriterion('quantity',identity=45,min=None,max=None)
127
    #predicate.immediateReindexObject()
128 129 130 131 132


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

133
    # ignore simulation rules, which are now predicates
134 135 136 137 138
    rule_query = Query(
        operator='AND',
        portal_type=['!=%s' % x for x
          in domain_tool.getPortalRuleTypeList()
          + ('Base Domain', 'Contribution Predicate')])
139

140
    # Test with order line and predicate to none
141 142
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,
        portal_type=rule_query)
143 144 145 146 147
    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)
148 149
    get_transaction().commit()
    self.tic()
150 151
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,
        portal_type=rule_query)
152 153 154 155
    self.assertEquals(len(predicate_list),1)

    # Test with order line not none and predicate to identity
    order_line.setQuantity(45)
156
    kw = {'portal_type':'Mapped Value'}
157
    predicate.setCriterion('quantity',identity=45,min=None,max=None)
158 159
    get_transaction().commit()
    self.tic()
160
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
161
    self.assertEquals(len(predicate_list),1)
162

163
    order_line.setQuantity(40)
164 165
    get_transaction().commit()
    self.tic()
166
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
167 168 169 170 171 172
    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)
173 174
    get_transaction().commit()
    self.tic()
175
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
176
    self.assertEquals(len(predicate_list),1)
177

178
    order_line.setQuantity(10)
179 180
    get_transaction().commit()
    self.tic()
181 182
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,
        portal_type=rule_query)
183 184 185 186 187 188
    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)
189 190
    get_transaction().commit()
    self.tic()
191
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
192
    self.assertEquals(len(predicate_list),1)
193

194
    order_line.setQuantity(60)
195 196
    get_transaction().commit()
    self.tic()
197
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
198 199 200 201 202 203
    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)
204 205
    get_transaction().commit()
    self.tic()
206
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
207
    self.assertEquals(len(predicate_list),0)
208

209
    order_line.setQuantity(60)
210 211
    get_transaction().commit()
    self.tic()
212
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
213
    self.assertEquals(len(predicate_list),0)
214

215
    order_line.setQuantity(45)
216
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
217 218
    get_transaction().commit()
    self.tic()
219 220 221 222 223 224
    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'])
225 226
    get_transaction().commit()
    self.tic()
227
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
228
    self.assertEquals(len(predicate_list),0)
229

230
    order_line.setCategoryList(['region/africa'])
231 232
    get_transaction().commit()
    self.tic()
233
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
234
    self.assertEquals(len(predicate_list),0)
235

236
    order_line.setCategoryList(['region/europe'])
237 238
    get_transaction().commit()
    self.tic()
239
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
240
    self.assertEquals(len(predicate_list),1)
241

242
    order_line.setQuantity(60)
243 244
    get_transaction().commit()
    self.tic()
245
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
246 247
    self.assertEquals(len(predicate_list),0)

248 249 250 251 252 253
    # 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)
254 255
    self.assertEquals(self.supply_line.getDefaultResourceValue(),self.resource)
    self.assertEquals(order_line.getDefaultResourceValue(),self.resource)
256 257 258 259 260 261
    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)
262 263
    get_transaction().commit()
    self.tic()
264 265
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
    self.assertEquals(len(predicate_list),0)
266

267 268
    current_date = DateTime('2005/04/09 10:47:26.388 GMT-4')
    order_line.setStartDate(current_date)
269 270
    get_transaction().commit()
    self.tic()
271 272 273
    predicate_list = domain_tool.searchPredicateList(order_line,test=test,**kw)
    self.assertEquals(len(predicate_list),1)

274 275 276 277 278 279 280 281 282 283 284 285 286 287
  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)

288 289 290 291 292
  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()
293
    self.supply_line.setVariationBaseCategoryList(['colour'])
294 295 296
    self.supply_line.setBasePrice(23)
    self.supply_line.setPricedQuantity(1)
    self.supply_line.setDefaultResourceValue(self.resource)
297
    #self.supply_line.setMultimembershipCriterionBaseCategoryList(['resource'])
298
    self.supply_line.setMappedValuePropertyList(['base_price','priced_quantity'])
299
    #self.supply_line.setMembershipCriterionCategoryList(['resource/%s' % self.resource.getRelativeUrl()])
300 301
    get_transaction().commit()
    self.tic()
302 303 304
    domain_tool = self.getDomainTool()
    context = self.resource.asContext(categories=['resource/%s' % self.resource.getRelativeUrl()])
    mapped_value = domain_tool.generateMappedValue(context)
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
    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'])
322 323
    get_transaction().commit()
    self.tic()
324 325 326 327 328 329 330 331 332 333 334
    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)
335 336
    self.assertEquals(mapped_value.getBasePrice(),23)

337
  def test_05_GenerateMappedValueWithVariation(self, quiet=0, run=run_all_test):
338 339 340 341
    if not run: return
    if not quiet:
      self.logMessage('Generate Mapped Value With Variation')
    self.createData()
342
    self.supply_line.setVariationBaseCategoryList(['colour'])
343 344 345 346
    self.supply_line.setBasePrice(23)
    self.supply_line.setPricedQuantity(1)
    self.supply_line.setDefaultResourceValue(self.resource)
    self.supply_line.setMappedValuePropertyList(['base_price','priced_quantity'])
347
    self.resource.setPVariationBaseCategoryList(['variation'])
348 349 350
    self.supply_line.updateCellRange(base_id='path')
    cell_range = self.supply_line.SupplyLine_asCellRange()
    for range in cell_range[0]:
351
      cell = self.supply_line.newCell(range,base_id='path',portal_type='Supply Cell')
352 353 354 355 356 357 358 359 360 361 362
      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)

363 364 365 366
    right_price_list = [45,26]
    price_list = [x.getBasePrice() for x in self.supply_line.objectValues()]
    self.failIfDifferentSet(price_list,right_price_list)

367 368 369 370 371 372 373 374 375 376 377 378
    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

379 380
    get_transaction().commit()
    self.tic()
381
    domain_tool = self.getDomainTool()
382 383 384
    context = self.resource.asContext(
                     categories=['resource/%s' % self.resource.getRelativeUrl(),
                     'variation/%s/blue' % self.resource.getRelativeUrl()])
385 386
    mapped_value = domain_tool.generateMappedValue(context,sort_method=sort_method)
    self.assertEquals(mapped_value.getProperty('base_price'),45)
387 388 389
    context = self.resource.asContext(
                     categories=['resource/%s' % self.resource.getRelativeUrl(),
                     'variation/%s/red' % self.resource.getRelativeUrl()])
390 391 392
    mapped_value = domain_tool.generateMappedValue(context,sort_method=sort_method)
    self.assertEquals(mapped_value.getProperty('base_price'),26)
    # Now check the price
393 394 395 396
    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)
397

398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
  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')
    get_transaction().commit()
    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))
416
    self.assertTrue(predicate_one_match not in portal_domains.searchPredicateList(document, test=1))
417
    # Real test
418
    self.assertTrue(predicate_one_match not in portal_domains.searchPredicateList(document, test=0))
419

420 421 422 423
def test_suite():
  suite = unittest.TestSuite()
  suite.addTest(unittest.makeSuite(TestDomainTool))
  return suite
424