Back to index

plone3  3.1.7
test_criteria.py
Go to the documentation of this file.
00001 #  ATContentTypes http://plone.org/products/atcontenttypes/
00002 #  Archetypes reimplementation of the CMF core types
00003 #  Copyright (c) 2003-2006 AT Content Types development team
00004 #
00005 #  This program is free software; you can redistribute it and/or modify
00006 #  it under the terms of the GNU General Public License as published by
00007 #  the Free Software Foundation; either version 2 of the License, or
00008 #  (at your option) any later version.
00009 #
00010 #  This program is distributed in the hope that it will be useful,
00011 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 #  GNU General Public License for more details.
00014 #
00015 #  You should have received a copy of the GNU General Public License
00016 #  along with this program; if not, write to the Free Software
00017 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 #
00019 """
00020 """
00021 
00022 __author__ = 'Christian Heimes <tiran@cheimes.de>'
00023 __docformat__ = 'restructuredtext'
00024 from DateTime import DateTime
00025 
00026 from Testing import ZopeTestCase # side effect import. leave it here.
00027 from Products.ATContentTypes.tests import atcttestcase
00028 from Missing import MV
00029 
00030 from Products.Archetypes.atapi import *
00031 
00032 from Interface.Verify import verifyObject
00033 from Products.Archetypes.interfaces.base import IBaseContent
00034 from Products.Archetypes.interfaces.referenceable import IReferenceable
00035 from Products.Archetypes.interfaces.metadata import IExtensibleMetadata
00036 
00037 from Products.ATContentTypes.interfaces import IATTopicCriterion
00038 
00039 from Products.ATContentTypes.criteria.base import ATBaseCriterion
00040 from Products.ATContentTypes.criteria.date import ATDateCriteria 
00041 from Products.ATContentTypes.criteria.list import ATListCriterion
00042 from Products.ATContentTypes.criteria.simpleint import ATSimpleIntCriterion
00043 from Products.ATContentTypes.criteria.simplestring import \
00044     ATSimpleStringCriterion
00045 from Products.ATContentTypes.criteria.sort import ATSortCriterion
00046 from Products.ATContentTypes.criteria.selection import ATSelectionCriterion
00047 from Products.ATContentTypes.criteria.daterange import ATDateRangeCriterion
00048 from Products.ATContentTypes.criteria.reference import ATReferenceCriterion
00049 from Products.ATContentTypes.criteria.boolean import ATBooleanCriterion
00050 from Products.ATContentTypes.criteria.portaltype import ATPortalTypeCriterion
00051 from Products.ATContentTypes.criteria.currentauthor import \
00052     ATCurrentAuthorCriterion
00053 from Products.ATContentTypes.criteria.path import ATPathCriterion
00054 from Products.ATContentTypes.criteria.relativepath import ATRelativePathCriterion
00055 tests = []
00056 
00057 # z3 imports
00058 from Products.ATContentTypes.interface import IATTopicCriterion as Z3IATTopicCriterion
00059 from zope.interface.verify import verifyObject as Z3verifyObject
00060 
00061 class CriteriaTest(atcttestcase.ATCTSiteTestCase):
00062 
00063     klass = None
00064     portal_type = None
00065     title = None
00066     meta_type = None
00067 
00068     def afterSetUp(self):
00069         atcttestcase.ATCTSiteTestCase.afterSetUp(self)
00070         self.dummy = self.createDummy(self.klass)
00071 
00072     def createDummy(self, klass, id='dummy'):
00073         folder = self.folder
00074         if klass is not None:
00075             dummy = klass(id, 'dummyfield')
00076             # put dummy in context of portal
00077             folder._setObject(id, dummy)
00078             dummy = getattr(folder, id)
00079             dummy.initializeArchetype()
00080         else:
00081             dummy = None
00082         return dummy
00083 
00084     def test_000testsetup(self):
00085         if self.klass is not None:
00086             self.failUnless(self.klass)
00087             self.failUnless(self.portal_type)
00088             self.failUnless(self.title)
00089             self.failUnless(self.meta_type)
00090         
00091     def test_multipleCreateVariants(self):
00092         klass = self.klass
00093         id = 'dummy'
00094         field = 'dummyfield'
00095         if klass is not None:
00096             dummy = klass(id, field)
00097             self.failUnless(dummy.getId(), id)
00098             self.failUnless(dummy.Field(), field)
00099 
00100             dummy = klass(id=id, field=field)
00101             self.failUnless(dummy.getId(), id)
00102             self.failUnless(dummy.Field(), field)
00103 
00104             dummy = klass(field, oid=id)
00105             self.failUnless(dummy.getId(), id)
00106             self.failUnless(dummy.Field(), field)
00107 
00108             dummy = klass(field=field, oid=id)
00109             self.failUnless(dummy.getId(), id)
00110             self.failUnless(dummy.Field(), field)
00111 
00112     def test_typeInfo(self):
00113         if self.dummy is not None:
00114             ti = self.dummy.getTypeInfo()
00115             self.failUnlessEqual(ti.getId(), self.portal_type)
00116             self.failUnlessEqual(ti.Title(), self.title)
00117             self.failUnlessEqual(ti.Metatype(), self.meta_type)
00118         
00119     def test_implements(self):
00120         if self.dummy is not None:
00121             self.failIf(IReferenceable.isImplementedBy(self.dummy))
00122             self.failIf(IExtensibleMetadata.isImplementedBy(self.dummy))
00123             self.failIf(self.dummy.isReferenceable)
00124             self.failUnless(IBaseContent.isImplementedBy(self.dummy))
00125             self.failUnless(IATTopicCriterion.isImplementedBy(self.dummy))
00126             self.failUnless(verifyObject(IBaseContent, self.dummy))
00127             self.failUnless(verifyObject(IATTopicCriterion, self.dummy))
00128 
00129     def test_Z3implements(self):
00130         if self.dummy is not None:
00131             iface = Z3IATTopicCriterion
00132             self.failUnless(Z3verifyObject(iface, self.dummy))
00133 
00134 class TestATBaseCriterion(CriteriaTest):
00135     klass = ATBaseCriterion
00136     title = 'Base Criterion'
00137     meta_type = 'ATBaseCriterion'
00138     portal_type = 'ATBaseCriterion'
00139 
00140     def test_typeInfo(self):
00141         # not registered
00142         pass
00143 
00144 tests.append(TestATBaseCriterion)
00145 
00146 
00147 class TestATDateCriteria(CriteriaTest):
00148     klass = ATDateCriteria
00149     title = 'Friendly Date Criteria'
00150     meta_type = 'ATFriendlyDateCriteria'
00151     portal_type = 'ATDateCriteria'
00152 
00153     def test_LessThanPast(self):
00154         # A query of the form 'Less than 14 days ago' should generate a min:max
00155         # query with a start 14 days in the past and an end in the present
00156         self.dummy.Schema()['field'].set(self.dummy,'created')
00157         self.dummy.setOperation('less')
00158         self.dummy.setDateRange('-')
00159         self.dummy.setValue('14')
00160         expected_begin = (DateTime() - 14).earliestTime()
00161         items = self.dummy.getCriteriaItems()
00162         self.assertEquals(len(items),1)
00163         query = items[0][1]
00164         field = items[0][0]
00165         self.assertEquals(field, 'created')
00166         #range should start in past at the beginning of the day
00167         self.assertEquals(query['query'][0], expected_begin)
00168         # range should end today
00169         self.assertEquals(query['query'][1].earliestTime(),
00170                                                     DateTime().earliestTime())
00171         self.assertEquals(query['range'], 'min:max')
00172 
00173     def test_LessThanFuture(self):
00174         # A query of the form 'Less than 14 days in the future' should generate
00175         # a min:max query with an end 14 days in the future and a start in the
00176         # present
00177         self.dummy.Schema()['field'].set(self.dummy,'created')
00178         self.dummy.setOperation('less')
00179         self.dummy.setDateRange('+')
00180         self.dummy.setValue('14')
00181         expected_end = (DateTime() + 14).latestTime()
00182         items = self.dummy.getCriteriaItems()
00183         self.assertEquals(len(items),1)
00184         query = items[0][1]
00185         #Range should end on future date at the end of the day
00186         self.assertEquals(query['query'][1], expected_end)
00187         #Range should start today
00188         self.assertEquals(query['query'][0].earliestTime(),
00189                                                     DateTime().earliestTime())
00190         self.assertEquals(query['range'], 'min:max')
00191 
00192     def test_MoreThanPast(self):
00193         # A query of the form 'More than 14 days ago' should generate a max
00194         # query with the value set to a date 14 days in the past.
00195         self.dummy.Schema()['field'].set(self.dummy,'created')
00196         self.dummy.setOperation('more')
00197         self.dummy.setDateRange('-')
00198         self.dummy.setValue('14')
00199         expected_begin = (DateTime() - 14).earliestTime()
00200         items = self.dummy.getCriteriaItems()
00201         self.assertEquals(len(items),1)
00202         query = items[0][1]
00203         self.assertEquals(query['query'], expected_begin)
00204         self.assertEquals(query['range'], 'max')
00205 
00206     def test_MoreThanFuture(self):
00207         # A query of the form 'More than 14 days in the future' should generate
00208         # a min query with the value set to a date 14 days in the future.
00209         self.dummy.Schema()['field'].set(self.dummy,'created')
00210         self.dummy.setOperation('more')
00211         self.dummy.setDateRange('+')
00212         self.dummy.setValue('14')
00213         expected_begin = (DateTime() + 14).earliestTime()
00214         items = self.dummy.getCriteriaItems()
00215         self.assertEquals(len(items),1)
00216         query = items[0][1]
00217         self.assertEquals(query['query'], expected_begin)
00218         self.assertEquals(query['range'], 'min')
00219 
00220     def test_MoreThanNow(self):
00221         # A query of the form 'More than Now' should generate
00222         # a min query with the value set to the present, regardless of the
00223         # past future setting.
00224         self.dummy.Schema()['field'].set(self.dummy,'created')
00225         self.dummy.setOperation('more')
00226         self.dummy.setDateRange('+')
00227         self.dummy.setValue('0')
00228         expected_begin = DateTime().earliestTime()
00229         items = self.dummy.getCriteriaItems()
00230         self.assertEquals(len(items),1)
00231         query = items[0][1]
00232         self.assertEquals(query['query'].earliestTime(), expected_begin)
00233         self.assertEquals(query['range'], 'min')
00234         # Change past/future setting
00235         self.dummy.setDateRange('-')
00236         self.assertEquals(query['query'].earliestTime(), expected_begin)
00237         self.assertEquals(query['range'], 'min')
00238 
00239     def test_MoreThanNow(self):
00240         # A query of the form 'Less than Now' should generate
00241         # a max query with the value set to the present, regardless of the
00242         # past future setting.
00243         self.dummy.Schema()['field'].set(self.dummy,'created')
00244         self.dummy.setOperation('less')
00245         self.dummy.setDateRange('+')
00246         self.dummy.setValue('0')
00247         expected_begin = DateTime().earliestTime()
00248         items = self.dummy.getCriteriaItems()
00249         self.assertEquals(len(items),1)
00250         query = items[0][1]
00251         self.assertEquals(query['query'].earliestTime(), expected_begin)
00252         self.assertEquals(query['range'], 'max')
00253         # Change past/future setting
00254         self.dummy.setDateRange('-')
00255         self.assertEquals(query['query'].earliestTime(), expected_begin)
00256         self.assertEquals(query['range'], 'max')
00257 
00258 tests.append(TestATDateCriteria)
00259 
00260 
00261 class TestATListCriterion(CriteriaTest):
00262     klass = ATListCriterion
00263     title = 'List Criterion'
00264     meta_type = 'ATListCriterion'
00265     portal_type = 'ATListCriterion'
00266 
00267     def test_list_query(self):
00268         self.dummy.Schema()['field'].set(self.dummy,'Subject')
00269         self.dummy.setOperator('or')
00270         self.dummy.setValue(('1','2','3'))
00271         items = self.dummy.getCriteriaItems()
00272         self.assertEquals(len(items),1)
00273         query = items[0][1]
00274         field = items[0][0]
00275         self.assertEquals(field, 'Subject')
00276         self.assertEquals(query['query'], ('1','2','3'))
00277         self.assertEquals(query['operator'], 'or')
00278 
00279 tests.append(TestATListCriterion)
00280 
00281 
00282 class TestATSimpleIntCriterion(CriteriaTest):
00283     klass = ATSimpleIntCriterion
00284     title = 'Simple Int Criterion'
00285     meta_type = 'ATSimpleIntCriterion'
00286     portal_type = 'ATSimpleIntCriterion'
00287 
00288     def test_base_int_query(self):
00289         self.dummy.Schema()['field'].set(self.dummy,'getObjPositionInParent')
00290         self.dummy.setDirection('')
00291         self.dummy.setValue(12)
00292         items = self.dummy.getCriteriaItems()
00293         self.assertEquals(len(items),1)
00294         query = items[0][1]
00295         field = items[0][0]
00296         self.assertEquals(field, 'getObjPositionInParent')
00297         self.assertEquals(query['query'], 12)
00298 
00299     def test_int_min(self):
00300         self.dummy.Schema()['field'].set(self.dummy,'getObjPositionInParent')
00301         self.dummy.setDirection('min')
00302         self.dummy.setValue(12)
00303         items = self.dummy.getCriteriaItems()
00304         self.assertEquals(len(items),1)
00305         query = items[0][1]
00306         self.assertEquals(query['query'], 12)
00307         self.assertEquals(query['range'], 'min')
00308 
00309     def test_int_max(self):
00310         self.dummy.Schema()['field'].set(self.dummy,'getObjPositionInParent')
00311         self.dummy.setDirection('max')
00312         self.dummy.setValue(12)
00313         items = self.dummy.getCriteriaItems()
00314         self.assertEquals(len(items),1)
00315         query = items[0][1]
00316         self.assertEquals(query['query'], 12)
00317         self.assertEquals(query['range'], 'max')
00318 
00319     def test_int_between(self):
00320         self.dummy.Schema()['field'].set(self.dummy,'getObjPositionInParent')
00321         self.dummy.setDirection('min:max')
00322         self.dummy.setValue(12)
00323         self.dummy.setValue2(17)
00324         items = self.dummy.getCriteriaItems()
00325         self.assertEquals(len(items),1)
00326         query = items[0][1]
00327         self.assertEquals(query['query'], (12,17))
00328         self.assertEquals(query['range'], 'min:max')
00329 
00330 tests.append(TestATSimpleIntCriterion)
00331 
00332 
00333 class TestATSimpleStringCriterion(CriteriaTest):
00334     klass = ATSimpleStringCriterion
00335     title = 'Simple String Criterion'
00336     meta_type = 'ATSimpleStringCriterion'
00337     portal_type = 'ATSimpleStringCriterion'
00338 
00339     def test_string_query(self):
00340         self.dummy.Schema()['field'].set(self.dummy,'Subject')
00341         self.dummy.setValue('a*')
00342         items = self.dummy.getCriteriaItems()
00343         self.assertEquals(len(items),1)
00344         query = items[0][1]
00345         field = items[0][0]
00346         self.assertEquals(field, 'Subject')
00347         self.assertEquals(query, 'a*')
00348 
00349 tests.append(TestATSimpleStringCriterion)
00350 
00351 
00352 class TestATSortCriterion(CriteriaTest):
00353     klass = ATSortCriterion
00354     title = 'Sort Criterion'
00355     meta_type = 'ATSortCriterion'
00356     portal_type = 'ATSortCriterion'
00357 
00358     def test_sort_query(self):
00359         self.dummy.Schema()['field'].set(self.dummy,'getObjPositionInParent')
00360         self.dummy.setReversed(False)
00361         items = self.dummy.getCriteriaItems()
00362         self.assertEquals(len(items),1)
00363         self.assertEquals(items[0][0], 'sort_on')
00364         self.assertEquals(items[0][1], 'getObjPositionInParent')
00365 
00366     def test_list_query_reversed(self):
00367         self.dummy.Schema()['field'].set(self.dummy,'getObjPositionInParent')
00368         self.dummy.setReversed(True)
00369         items = self.dummy.getCriteriaItems()
00370         self.assertEquals(len(items),2)
00371         self.assertEquals(items[0][0], 'sort_on')
00372         self.assertEquals(items[0][1], 'getObjPositionInParent')
00373         self.assertEquals(items[1][0], 'sort_order')
00374         self.assertEquals(items[1][1], 'reverse')
00375 
00376 tests.append(TestATSortCriterion)
00377 
00378 
00379 class TestATSelectionCriterion(CriteriaTest):
00380     klass = ATSelectionCriterion
00381     title = 'Selection Criterion'
00382     meta_type = 'ATSelectionCriterion'
00383     portal_type = 'ATSelectionCriterion'
00384 
00385     #Same as list criterion but without operator and with special vocabulary
00386     def test_selection_query(self):
00387         self.dummy.Schema()['field'].set(self.dummy,'Subject')
00388         self.dummy.setValue(('1','2','3'))
00389         self.dummy.setOperator('and')
00390         items = self.dummy.getCriteriaItems()
00391         self.assertEquals(len(items),1)
00392         query = items[0][1]
00393         field = items[0][0]
00394         self.assertEquals(field, 'Subject')
00395         self.assertEquals(query['query'], ('1','2','3'))
00396         self.assertEquals(query['operator'], 'and')
00397 
00398     def test_vocabulary(self):
00399         #Should return some ids
00400         self.dummy.Schema()['field'].set(self.dummy,'getId')
00401         self.failUnless(self.dummy.getCurrentValues())
00402 
00403     def test_vocabulary_sorted(self):
00404         #Should return sorted ids
00405         self.dummy.Schema()['field'].set(self.dummy,'getId')
00406         orig_vocab = [a.lower() for a in list(self.dummy.getCurrentValues())]
00407         sorted_vocab = orig_vocab[:]
00408         sorted_vocab.sort()
00409         self.assertEqual(orig_vocab,sorted_vocab)
00410 
00411 tests.append(TestATSelectionCriterion)
00412 
00413 
00414 class TestATDateRangeCriterion(CriteriaTest):
00415     klass = ATDateRangeCriterion
00416     title = 'Date Range Criterion'
00417     meta_type = 'ATDateRangeCriterion'
00418     portal_type = 'ATDateRangeCriterion'
00419 
00420     def test_date_range_query(self):
00421         self.dummy.Schema()['field'].set(self.dummy,'created')
00422         now = DateTime()
00423         self.dummy.setStart(now)
00424         self.dummy.setEnd(now+5)
00425         items = self.dummy.getCriteriaItems()
00426         self.assertEquals(len(items),1)
00427         query = items[0][1]
00428         field = items[0][0]
00429         self.assertEquals(field, 'created')
00430         self.assertEquals(query['query'][0], now)
00431         self.assertEquals(query['query'][1], now+5)
00432         self.assertEquals(query['range'], 'min:max')
00433 
00434 tests.append(TestATDateRangeCriterion)
00435 
00436 
00437 class TestATReferenceCriterion(CriteriaTest):
00438     klass = ATReferenceCriterion
00439     title = 'Reference Criterion'
00440     meta_type = 'ATReferenceCriterion'
00441     portal_type = 'ATReferenceCriterion'
00442 
00443     #Same as list criterion but without operator and with special vocabulary
00444     def test_reference_query(self):
00445         self.dummy.Schema()['field'].set(self.dummy,'getRawRelatedItems')
00446         self.folder.invokeFactory('Document', 'doc1')
00447         uid = self.folder.doc1.UID()
00448         self.dummy.setValue((uid,))
00449         self.dummy.setOperator('and')
00450         items = self.dummy.getCriteriaItems()
00451         self.assertEquals(len(items),1)
00452         query = items[0][1]
00453         field = items[0][0]
00454         self.assertEquals(field, 'getRawRelatedItems')
00455         self.assertEquals(query['query'], (uid,))
00456         self.assertEquals(query['operator'], 'and')
00457 
00458     def test_reference_vocab(self):
00459         self.dummy.Schema()['field'].set(self.dummy,'getRawRelatedItems')
00460         self.folder.invokeFactory('Document', 'doc1')
00461         self.folder.invokeFactory('Document', 'doc2')
00462         uid1 = self.folder.doc1.UID()
00463         uid2 = self.folder.doc2.UID()
00464         self.folder.doc1.setRelatedItems([uid2])
00465         self.folder.doc2.setRelatedItems([uid1])
00466         self.folder.doc1.reindexObject()
00467         self.folder.doc2.reindexObject()
00468         vocab = self.dummy.getCurrentValues()
00469         self.assertEquals(len(vocab),2)
00470         self.failUnless(uid1 in vocab.keys())
00471         self.failUnless(uid2 in vocab.keys())
00472         self.failUnless('doc1' in vocab.values())
00473         self.failUnless('doc2' in vocab.values())
00474 
00475 tests.append(TestATReferenceCriterion)
00476 
00477 
00478 class TestATBooleanCriterion(CriteriaTest):
00479     klass = ATBooleanCriterion
00480     title = 'Boolean Criterion'
00481     meta_type = 'ATBooleanCriterion'
00482     portal_type = 'ATBooleanCriterion'
00483     
00484     def test_boolean_query_true(self):
00485         self.dummy.Schema()['field'].set(self.dummy,'isPrincipiaFolderish')
00486         self.dummy.setBool(True)
00487         items = self.dummy.getCriteriaItems()
00488         self.assertEquals(len(items),1)
00489         query = items[0][1]
00490         field = items[0][0]
00491         self.assertEquals(field, 'isPrincipiaFolderish')
00492         self.assertEquals(query, [1,True,'1','True'])
00493     
00494     def test_boolean_query_false(self):
00495         self.dummy.Schema()['field'].set(self.dummy,'isPrincipiaFolderish')
00496         self.dummy.setBool(False)
00497         items = self.dummy.getCriteriaItems()
00498         self.assertEquals(len(items),1)
00499         query = items[0][1]
00500         field = items[0][0]
00501         self.assertEquals(field, 'isPrincipiaFolderish')
00502         self.assertEquals(query, [0,'',False,'0','False', None, (), [], {}, MV])
00503 
00504 tests.append(TestATBooleanCriterion)
00505 
00506 
00507 class TestATPortalTypeCriterion(CriteriaTest):
00508     klass = ATPortalTypeCriterion
00509     title = 'Portal Types Criterion'
00510     meta_type = 'ATPortalTypeCriterion'
00511     portal_type = 'ATPortalTypeCriterion'
00512 
00513     #Same as list criterion but without operator and with special vocabulary
00514     def test_portaltype_query(self):
00515         self.dummy.Schema()['field'].set(self.dummy,'portal_type')
00516         self.dummy.setValue(('Document','Folder','Topic'))
00517         items = self.dummy.getCriteriaItems()
00518         self.assertEquals(len(items),1)
00519         query = items[0][1]
00520         field = items[0][0]
00521         self.assertEquals(field, 'portal_type')
00522         self.assertEquals(query, ('Document','Folder','Topic'))
00523 
00524     def test_vocabulary(self):
00525         #Should return standard types, but not blacklisted types
00526         self.dummy.Schema()['field'].set(self.dummy,'portal_types')
00527         self.failUnless('Document' in self.dummy.getCurrentValues().keys())
00528         self.failUnless('ATSimpleStringCriterion' not in self.dummy.getCurrentValues().keys())
00529 
00530     def test_vocabulary_sorts_by_type(self):
00531         #Should return standard types, but not blacklisted types
00532         self.dummy.Schema()['field'].set(self.dummy,'Type')
00533         type_ids, type_names = self.dummy.getCurrentValues().keys(), self.dummy.getCurrentValues().values()
00534         self.failUnless(type_names.index('Page') > type_names.index('Event'))
00535         self.dummy.Schema()['field'].set(self.dummy,'portal_types')
00536         type_ids, type_names = self.dummy.getCurrentValues().keys(), self.dummy.getCurrentValues().values()
00537         self.failUnless(type_names.index('Document')< type_names.index('Event'))
00538 
00539     def test_types_v_portaltypes(self):
00540         #Using the Types index as field should cause the vocabulary to use the
00541         #type Title rather than the type name
00542         self.dummy.Schema()['field'].set(self.dummy,'portal_type')
00543         type_ids, type_names = self.dummy.getCurrentValues().keys(), self.dummy.getCurrentValues().values()
00544         self.failUnless('Large Plone Folder' in type_names)
00545         self.failUnless('Large Folder' not in type_names)
00546         self.dummy.Schema()['field'].set(self.dummy,'Type')
00547         type_ids, type_names = self.dummy.getCurrentValues().keys(), self.dummy.getCurrentValues().values()
00548         self.failUnless('Large Plone Folder' not in type_names)
00549         self.failUnless('Large Folder' in type_names)
00550         #ensure that blacklisted types aren't here either
00551         self.failUnless('Simple String Criterion' not in type_names)
00552 
00553     def test_type_ids_names(self):
00554         # test introduced when fixing Plone bug #6981
00555         self.dummy.Schema()['field'].set(self.dummy,'Type')
00556         type_ids, type_names = self.dummy.getCurrentValues().keys(), self.dummy.getCurrentValues().values()
00557         self.failUnless('Page' in type_ids)
00558         self.failUnless('Page' in type_names)
00559         self.failIf('Document' in type_ids)
00560         self.failIf('Document' in type_names)
00561         # use type id everytime
00562         self.dummy.Schema()['field'].set(self.dummy,'portal_type')
00563         type_ids, type_names = self.dummy.getCurrentValues().keys(), self.dummy.getCurrentValues().values()
00564         self.failUnless('Document' in type_ids)
00565         self.failUnless('Document' in type_names)
00566         self.failIf('Page' in type_ids)
00567         self.failIf('Page' in type_names)
00568         
00569         
00570 tests.append(TestATPortalTypeCriterion)
00571 
00572 
00573 class TestATCurrentAuthorCriterion(CriteriaTest):
00574     klass = ATCurrentAuthorCriterion
00575     title = 'Current Author Criterion'
00576     meta_type = 'ATCurrentAuthorCriterion'
00577     portal_type = 'ATCurrentAuthorCriterion'
00578 
00579     def afterSetUp(self):
00580         CriteriaTest.afterSetUp(self)
00581         self.portal.acl_users._doAddUser('member', 'secret', ['Member'], [])
00582         self.portal.acl_users._doAddUser('reviewer', 'secret', ['Reviewer'], [])
00583 
00584     def test_author_query(self):
00585         self.dummy.Schema()['field'].set(self.dummy,'creator')
00586         self.login('member')
00587         items = self.dummy.getCriteriaItems()
00588         self.assertEquals(len(items),1)
00589         query = items[0][1]
00590         field = items[0][0]
00591         self.assertEquals(field, 'creator')
00592         self.assertEquals(query, 'member')
00593         self.login('reviewer')
00594         items = self.dummy.getCriteriaItems()
00595         self.assertEquals(len(items),1)
00596         query = items[0][1]
00597         field = items[0][0]
00598         self.assertEquals(field, 'creator')
00599         self.assertEquals(query, 'reviewer')
00600 
00601 tests.append(TestATCurrentAuthorCriterion)
00602 
00603 
00604 class TestATRelativePathCriterion(CriteriaTest):
00605     klass = ATRelativePathCriterion
00606     title = 'Relative Path Criterion'
00607     meta_type = 'ATRelativePathCriterion'
00608     portal_type = 'ATRelativePathCriterion'
00609 
00610     def afterSetUp(self):
00611         CriteriaTest.afterSetUp(self)
00612         self.setRoles(['Manager'])
00613         # build folder structure
00614         self.portal.invokeFactory('Folder', 'folderA')
00615         self.portal.invokeFactory('Folder', 'folderB')
00616         self.portal.folderA.invokeFactory('Folder', 'folderA1')
00617         self.portal.folderB.invokeFactory('Folder', 'folderB1')
00618         
00619         # create topic in folderA1
00620         self.portal.folderA.folderA1.invokeFactory('Topic', 'new_topic', title='New Topic')
00621         
00622         self.topic  = self.portal.folderA.folderA1.new_topic
00623         # Add a path criterion
00624         self.path_crit = self.topic.addCriterion('path', 'ATRelativePathCriterion')
00625 
00626     def test_relative_path_query1(self):
00627         self.path_crit.setRelativePath('..')   # should give the parent==folderA1 
00628         self.failUnless(self.path_crit.getCriteriaItems() == (('path', {'query': '/plone/folderA/folderA1', 'depth': 1}),))
00629         
00630     def test_relative_path_query2(self):
00631         self.path_crit.setRelativePath('../..')   # should give folderA
00632         self.failUnless(self.path_crit.getCriteriaItems() == (('path', {'query': '/plone/folderA', 'depth': 1}),))
00633         
00634     def test_relative_path_query3(self):
00635         self.path_crit.setRelativePath('../../..')   # should give the /plone (portal) 
00636         self.failUnless(self.path_crit.getCriteriaItems() == (('path', {'query': '/plone', 'depth': 1}),))
00637         
00638     def test_relative_path_query4(self):
00639         self.path_crit.setRelativePath('../../../../../../..')   # should give the /plone (portal): cannot go higher than the portal
00640         self.failUnless(self.path_crit.getCriteriaItems() == (('path', {'query': '/plone', 'depth': 1}),))
00641         
00642     def test_relative_path_query5(self):
00643         self.path_crit.setRelativePath('../../../folderB')   # should give folderB 
00644         self.failUnless(self.path_crit.getCriteriaItems() == (('path', {'query': '/plone/folderB', 'depth': 1}),))
00645         
00646     def test_relative_path_query6(self):
00647         self.path_crit.setRelativePath('/folderB')   # should give folderB also (absolute paths are supported)
00648         self.failUnless(self.path_crit.getCriteriaItems() == (('path', {'query': '/plone/folderB', 'depth': 1}),))
00649         
00650     def test_relative_path_query7(self):
00651         self.path_crit.setRelativePath('../../folderA1/../../folderB/folderB1/..')   # should give folderB 
00652         self.failUnless(self.path_crit.getCriteriaItems() == (('path', {'query': '/plone/folderB', 'depth': 1}),))
00653 
00654     def test_relative_path_query8(self):
00655         self.path_crit.setRelativePath('.')   # should give the new_topic 
00656         self.failUnless(self.path_crit.getCriteriaItems() == (('path', {'query': '/plone/folderA/folderA1/new_topic', 'depth': 1}),))
00657         
00658 tests.append(TestATRelativePathCriterion)
00659 
00660 class TestATPathCriterion(CriteriaTest):
00661     klass = ATPathCriterion
00662     title = 'Path Criterion'
00663     meta_type = 'ATPathCriterion'
00664     portal_type = 'ATPathCriterion'
00665 
00666     def test_path_query(self):
00667         # ensure that the path and recurse settings result in a proper query
00668         self.dummy.Schema()['field'].set(self.dummy,'path')
00669         self.folder.invokeFactory('Document', 'doc1')
00670         uid = self.folder.doc1.UID()
00671         self.dummy.setValue((uid,))
00672         self.dummy.setRecurse(True)
00673         items = self.dummy.getCriteriaItems()
00674         self.assertEquals(len(items),1)
00675         query = items[0][1]
00676         field = items[0][0]
00677         self.assertEquals(field, 'path')
00678         self.assertEquals(tuple(query['query']), ('/plone/Members/test_user_1_/doc1',))
00679         self.assertEquals(query['depth'], -1)
00680         self.dummy.setRecurse(False)
00681         items = self.dummy.getCriteriaItems()
00682         query = items[0][1]
00683         self.assertEquals(query['depth'], 1)
00684 
00685     # Some reference errors were making this impossible
00686     def test_path_criteria_can_be_removed(self):
00687         self.setRoles(['Manager', 'Member'])
00688         self.folder.invokeFactory('Topic', 'new_topic', title='New Topic')
00689         topic  = self.folder.new_topic
00690         # Add a path criterion
00691         path_crit = topic.addCriterion('path', 'ATPathCriterion')
00692         # Give it a reference
00693         path_crit.setValue([topic.UID()])
00694         # The error is masked when not in debug mode or as manager, though it
00695         # still has consequences
00696         from App.config import getConfiguration
00697         config = getConfiguration()
00698         orig_debug = config.debug_mode
00699         config.debug_mode = True
00700         self.setRoles(['Member'])
00701         # Delete the topic
00702         try:
00703             self.folder.manage_delObjects(['new_topic'])
00704         except AttributeError:
00705             config.debug_mode = orig_debug
00706             self.fail("Deleting a topic with path criteria raises an error!")
00707         config.debug_mode = orig_debug
00708 
00709 tests.append(TestATPathCriterion)
00710 
00711 class TestCriterionRegistry(atcttestcase.ATCTSiteTestCase):
00712 
00713     def afterSetUp(self):
00714         from Products.ATContentTypes.criteria import _criterionRegistry
00715         atcttestcase.ATCTSiteTestCase.afterSetUp(self)
00716         self.crit_registry = _criterionRegistry
00717 
00718     def testRegisterCriteria(self):
00719         # Ensure that the criteria registering and unregistering mechanism
00720         # works as expected
00721         # check if the expected criteria is there
00722         self.failUnless(ATDateCriteria in self.crit_registry.listCriteria())
00723         self.failUnless(self.crit_registry.indicesByCriterion('ATFriendlyDateCriteria'))
00724         # remove and ensure that it was removed
00725         self.crit_registry.unregister(ATDateCriteria)
00726         self.failIf(ATDateCriteria in self.crit_registry.listCriteria())
00727         # add and ensure that it was added
00728         self.crit_registry.register(ATDateCriteria, ('Bogus Index',))
00729         self.failUnless(ATDateCriteria in self.crit_registry.listCriteria())
00730         self.assertEqual(self.crit_registry.indicesByCriterion('ATFriendlyDateCriteria'),
00731                                                         ('Bogus Index',))
00732 
00733     def testCriteriaIndexLookupOnBadIndex(self):
00734         # Make sure we don't throw errors when someone has a non-default index
00735         # type in their catalog.
00736         self.crit_registry.criteriaByIndex('My Bad Index Type')
00737 
00738 tests.append(TestCriterionRegistry)
00739 
00740 import unittest
00741 def test_suite():
00742     suite = unittest.TestSuite()
00743     for test in tests:
00744         suite.addTest(unittest.makeSuite(test))
00745     return suite