Back to index

plone3  3.1.7
test_content.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2005 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """Filesystem exporter / importer adapter unit tests.
00014 
00015 $Id: test_content.py 82572 2007-12-30 12:38:03Z jens $
00016 """
00017 
00018 import unittest
00019 import Testing
00020 
00021 from csv import reader
00022 from ConfigParser import ConfigParser
00023 from StringIO import StringIO
00024 
00025 from OFS.interfaces import IObjectManager
00026 from OFS.interfaces import ISimpleItem
00027 from OFS.interfaces import IPropertyManager
00028 from Products.GenericSetup.tests.common import DummyExportContext
00029 from Products.GenericSetup.tests.common import DummyImportContext
00030 from zope.testing.cleanup import cleanUp
00031 
00032 from conformance import ConformsToIINIAware
00033 from conformance import ConformsToIFilesystemExporter
00034 from conformance import ConformsToIFilesystemImporter
00035 
00036 
00037 class SimpleINIAwareTests(unittest.TestCase, ConformsToIINIAware):
00038 
00039     def _getTargetClass(self):
00040         from Products.GenericSetup.content import SimpleINIAware
00041         return SimpleINIAware
00042 
00043     def test_as_ini_no_properties(self):
00044         context = _makePropertied('no_properties')
00045         context._properties = ()
00046         adapter = self._getTargetClass()(context)
00047         text = adapter.as_ini()
00048         parser = ConfigParser()
00049         parser.readfp(StringIO(text))
00050         self.failIf(parser.sections())
00051         default_options = parser.defaults()
00052         self.assertEqual(len(default_options), 0)
00053 
00054     def test_as_ini_string_property(self):
00055         TITLE = 'String Property'
00056         DESCR = 'Another property'
00057         context = _makePropertied('string_property')
00058         context.title = TITLE
00059         context._setProperty('description', DESCR)
00060         adapter = self._getTargetClass()(context)
00061         text = adapter.as_ini()
00062         parser = ConfigParser()
00063         parser.readfp(StringIO(text))
00064         self.failIf(parser.sections())
00065         default_options = parser.defaults()
00066         self.assertEqual(len(default_options), 2)
00067         self.assertEqual(default_options['title'].strip(), TITLE)
00068         self.assertEqual(default_options['description'].strip(), DESCR)
00069 
00070     def test_as_ini_other_properties(self):
00071         from DateTime.DateTime import DateTime
00072         INTPROP = 42
00073         FLOATPROP = 3.1415926
00074         DATESTR = '2005-11-07T12:00:00.000Z'
00075         context = _makePropertied('string_property')
00076         context._properties = ()
00077         context._setProperty('int_prop', INTPROP, 'int')
00078         context._setProperty('float_prop', FLOATPROP, 'float')
00079         context._setProperty('date_prop', DateTime(DATESTR), 'date')
00080         adapter = self._getTargetClass()(context)
00081         text = adapter.as_ini()
00082         parser = ConfigParser()
00083         parser.readfp(StringIO(text))
00084         self.failIf(parser.sections())
00085         default_options = parser.defaults()
00086         self.assertEqual(len(default_options), 3)
00087         self.assertEqual(default_options['int_prop'], str(INTPROP))
00088         self.assertEqual(default_options['float_prop'], str(FLOATPROP))
00089         self.assertEqual(default_options['date_prop'], str(DateTime(DATESTR)))
00090 
00091     def test_put_ini_empty(self):
00092         context = _makePropertied('empty_ini')
00093         adapter = self._getTargetClass()(context)
00094         context._properties = ()
00095         self.failIf(context.propertyItems())
00096         adapter.put_ini('')
00097         self.failIf(context.propertyItems())
00098 
00099     def test_put_ini_with_values_stripped(self):
00100         context = _makePropertied('empty_ini')
00101         adapter = self._getTargetClass()(context)
00102         adapter.put_ini('[DEFAULT]\ntitle = Foo \ndescription = bar ')
00103         props = context.propdict()
00104         self.assertEqual(len(props), 2)
00105         self.failUnless('title' in props)
00106         self.failUnless('description' in props)
00107         self.assertEqual(context.title, 'Foo')
00108         self.assertEqual(context.description, 'bar')
00109 
00110     def test_put_ini_other_properties(self):
00111         from DateTime.DateTime import DateTime
00112         INTPROP = 42
00113         FLOATPROP = 3.1415926
00114         DATESTR = '2005-11-07T12:00:00.000Z'
00115         DATESTR2 = '2005-11-09T12:00:00.000Z'
00116         context = _makePropertied('string_property')
00117         context._properties = ()
00118         context._setProperty('int_prop', INTPROP, 'int')
00119         context._setProperty('float_prop', FLOATPROP, 'float')
00120         context._setProperty('date_prop', DateTime(DATESTR), 'date')
00121         adapter = self._getTargetClass()(context)
00122         adapter.put_ini('''\
00123 [DEFAULT]
00124 int_prop = 13 
00125 \nfloat_prop = 2.818
00126 \ndate_prop = %s''' % DATESTR2)
00127         self.assertEqual(len(context.propertyIds()), 3)
00128         self.assertEqual(context.int_prop, 13)
00129         self.assertEqual(context.float_prop, 2.818)
00130         self.assertEqual(context.date_prop, DateTime(DATESTR2))
00131 
00132 
00133 class FolderishExporterImporterTests(unittest.TestCase):
00134 
00135     def tearDown(self):
00136         cleanUp()
00137 
00138     def _getExporter(self):
00139         from Products.GenericSetup.content import exportSiteStructure
00140         return exportSiteStructure
00141 
00142     def _getImporter(self):
00143         from Products.GenericSetup.content import importSiteStructure
00144         return importSiteStructure
00145 
00146     def _makeSetupTool(self):
00147         from Products.GenericSetup.tool import SetupTool
00148         return SetupTool('portal_setup')
00149 
00150     def _setUpAdapters(self):
00151         from OFS.Folder import Folder
00152         from zope.app.testing import ztapi
00153         #from OFS.Image import File
00154 
00155         from Products.GenericSetup.interfaces import IFilesystemExporter
00156         from Products.GenericSetup.interfaces import IFilesystemImporter
00157         from Products.GenericSetup.interfaces import ICSVAware
00158         from Products.GenericSetup.interfaces import IINIAware
00159         from Products.GenericSetup.interfaces import IDAVAware
00160 
00161         from Products.GenericSetup.content import \
00162              SimpleINIAware
00163         from Products.GenericSetup.content import \
00164              FolderishExporterImporter
00165         from Products.GenericSetup.content import \
00166              CSVAwareFileAdapter
00167         from Products.GenericSetup.content import \
00168              INIAwareFileAdapter
00169         from Products.GenericSetup.content import \
00170              DAVAwareFileAdapter
00171 
00172         ztapi.provideAdapter(IObjectManager,
00173                              IFilesystemExporter,
00174                              FolderishExporterImporter,
00175                             )
00176 
00177         ztapi.provideAdapter(IObjectManager,
00178                              IFilesystemImporter,
00179                              FolderishExporterImporter,
00180                             )
00181 
00182         ztapi.provideAdapter(IPropertyManager,
00183                              IINIAware,
00184                              SimpleINIAware,
00185                             )
00186 
00187         ztapi.provideAdapter(ICSVAware,
00188                              IFilesystemExporter,
00189                              CSVAwareFileAdapter,
00190                             )
00191 
00192         ztapi.provideAdapter(ICSVAware,
00193                              IFilesystemImporter,
00194                              CSVAwareFileAdapter,
00195                             )
00196 
00197         ztapi.provideAdapter(IINIAware,
00198                              IFilesystemExporter,
00199                              INIAwareFileAdapter,
00200                             )
00201 
00202         ztapi.provideAdapter(IINIAware,
00203                              IFilesystemImporter,
00204                              INIAwareFileAdapter,
00205                             )
00206 
00207         ztapi.provideAdapter(IDAVAware,
00208                              IFilesystemExporter,
00209                              DAVAwareFileAdapter,
00210                             )
00211 
00212         ztapi.provideAdapter(IDAVAware,
00213                              IFilesystemImporter,
00214                              DAVAwareFileAdapter,
00215                             )
00216 
00217 
00218     def test_export_empty_site(self):
00219         self._setUpAdapters()
00220         site = _makeFolder('site')
00221         site.title = 'test_export_empty_site'
00222         site.description = 'Testing export of an empty site.'
00223         context = DummyExportContext(site)
00224         exporter = self._getExporter()
00225         exporter(context)
00226 
00227         self.assertEqual(len(context._wrote), 2)
00228         filename, text, content_type = context._wrote[0]
00229         self.assertEqual(filename, 'structure/.objects')
00230         self.assertEqual(content_type, 'text/comma-separated-values')
00231 
00232         objects = [x for x in reader(StringIO(text))]
00233         self.assertEqual(len(objects), 0)
00234 
00235         filename, text, content_type = context._wrote[1]
00236         self.assertEqual(filename, 'structure/.properties')
00237         self.assertEqual(content_type, 'text/plain')
00238 
00239         parser = ConfigParser()
00240         parser.readfp(StringIO(text))
00241 
00242         defaults = parser.defaults()
00243         self.assertEqual(len(defaults), 1)
00244         self.assertEqual(defaults['title'], site.title)
00245 
00246     def test_export_empty_site_with_setup_tool(self):
00247         self._setUpAdapters()
00248         site = _makeFolder('site')
00249         site._setObject('setup_tool', self._makeSetupTool())
00250         site._updateProperty('title', 'test_export_empty_site_with_setup_tool')
00251         site._setProperty('description',
00252                           'Testing export of an empty site with setup tool.')
00253         context = DummyExportContext(site)
00254         exporter = self._getExporter()
00255         exporter(context)
00256 
00257         self.assertEqual(len(context._wrote), 2)
00258         filename, text, content_type = context._wrote[0]
00259         self.assertEqual(filename, 'structure/.objects')
00260         self.assertEqual(content_type, 'text/comma-separated-values')
00261 
00262         objects = [x for x in reader(StringIO(text))]
00263         self.assertEqual(len(objects), 0)
00264 
00265         filename, text, content_type = context._wrote[1]
00266         self.assertEqual(filename, 'structure/.properties')
00267         self.assertEqual(content_type, 'text/plain')
00268 
00269         parser = ConfigParser()
00270         parser.readfp(StringIO(text))
00271 
00272         defaults = parser.defaults()
00273         self.assertEqual(len(defaults), 2)
00274         self.assertEqual(defaults['title'], site.title)
00275         self.assertEqual(defaults['description'], site.description)
00276 
00277     def test_export_site_with_non_exportable_simple_items(self):
00278         from Products.GenericSetup.utils import _getDottedName
00279         self._setUpAdapters()
00280         ITEM_IDS = ('foo', 'bar', 'baz')
00281 
00282         site = _makeFolder('site')
00283         site.title = 'AAA'
00284         site._setProperty('description', 'CCC')
00285         item = _makeItem('aside')
00286         dotted = _getDottedName(item.__class__)
00287         for id in ITEM_IDS:
00288             site._setObject(id, _makeItem(id))
00289 
00290         context = DummyExportContext(site)
00291         exporter = self._getExporter()
00292         exporter(context)
00293 
00294         self.assertEqual(len(context._wrote), 2)
00295         filename, text, content_type = context._wrote[0]
00296         self.assertEqual(filename, 'structure/.objects')
00297         self.assertEqual(content_type, 'text/comma-separated-values')
00298 
00299         objects = [x for x in reader(StringIO(text))]
00300         self.assertEqual(len(objects), 3)
00301         for index in range(len(ITEM_IDS)):
00302             self.assertEqual(objects[index][0], ITEM_IDS[index])
00303             self.assertEqual(objects[index][1], dotted)
00304 
00305         filename, text, content_type = context._wrote[1]
00306         self.assertEqual(filename, 'structure/.properties')
00307         self.assertEqual(content_type, 'text/plain')
00308         parser = ConfigParser()
00309         parser.readfp(StringIO(text))
00310 
00311         defaults = parser.defaults()
00312         self.assertEqual(len(defaults), 2)
00313         self.assertEqual(defaults['title'], 'AAA')
00314         self.assertEqual(defaults['description'], 'CCC')
00315 
00316     def test_export_site_with_exportable_simple_items(self):
00317         from Products.GenericSetup.utils import _getDottedName
00318         self._setUpAdapters()
00319         ITEM_IDS = ('foo', 'bar', 'baz')
00320 
00321         site = _makeFolder('site')
00322         site.title = 'AAA'
00323         site._setProperty('description', 'CCC')
00324         aware = _makeINIAware('aside')
00325         dotted = _getDottedName(aware.__class__)
00326         for id in ITEM_IDS:
00327             site._setObject(id, _makeINIAware(id))
00328 
00329         context = DummyExportContext(site)
00330         exporter = self._getExporter()
00331         exporter(context)
00332 
00333         self.assertEqual(len(context._wrote), 2 + len(ITEM_IDS))
00334         filename, text, content_type = context._wrote[0]
00335         self.assertEqual(filename, 'structure/.objects')
00336         self.assertEqual(content_type, 'text/comma-separated-values')
00337 
00338         objects = [x for x in reader(StringIO(text))]
00339         self.assertEqual(len(objects), 3)
00340         for index in range(len(ITEM_IDS)):
00341             self.assertEqual(objects[index][0], ITEM_IDS[index])
00342             self.assertEqual(objects[index][1], dotted)
00343 
00344             filename, text, content_type = context._wrote[index+2]
00345             self.assertEqual(filename, 'structure/%s.ini' % ITEM_IDS[index])
00346             object = site._getOb(ITEM_IDS[index])
00347             self.assertEqual(text.strip(),
00348                              object.as_ini().strip())
00349             self.assertEqual(content_type, 'text/plain')
00350 
00351         filename, text, content_type = context._wrote[1]
00352         self.assertEqual(filename, 'structure/.properties')
00353         self.assertEqual(content_type, 'text/plain')
00354         parser = ConfigParser()
00355         parser.readfp(StringIO(text))
00356 
00357         defaults = parser.defaults()
00358         self.assertEqual(len(defaults), 2)
00359         self.assertEqual(defaults['title'], 'AAA')
00360         self.assertEqual(defaults['description'], 'CCC')
00361 
00362     def test_export_site_with_subfolders(self):
00363         from Products.GenericSetup.utils import _getDottedName
00364         self._setUpAdapters()
00365         FOLDER_IDS = ('foo', 'bar', 'baz')
00366 
00367         site = _makeFolder('site')
00368         site.title = 'AAA'
00369         site._setProperty('description', 'CCC')
00370         aside = _makeFolder('aside')
00371         dotted = _getDottedName(aside.__class__)
00372         for id in FOLDER_IDS:
00373             folder = _makeFolder(id)
00374             folder.title = 'Title: %s' % id
00375             site._setObject(id, folder)
00376 
00377         context = DummyExportContext(site)
00378         exporter = self._getExporter()
00379         exporter(context)
00380 
00381         self.assertEqual(len(context._wrote), 2 + (2 *len(FOLDER_IDS)))
00382         filename, text, content_type = context._wrote[0]
00383         self.assertEqual(filename, 'structure/.objects')
00384         self.assertEqual(content_type, 'text/comma-separated-values')
00385 
00386         objects = [x for x in reader(StringIO(text))]
00387         self.assertEqual(len(objects), 3)
00388 
00389         for index in range(len(FOLDER_IDS)):
00390             id = FOLDER_IDS[index]
00391             self.assertEqual(objects[index][0], id)
00392             self.assertEqual(objects[index][1], dotted)
00393 
00394             filename, text, content_type = context._wrote[2 + (2 * index)]
00395             self.assertEqual(filename, '/'.join(('structure', id, '.objects')))
00396             self.assertEqual(content_type, 'text/comma-separated-values')
00397             subobjects = [x for x in reader(StringIO(text))]
00398             self.assertEqual(len(subobjects), 0)
00399 
00400             filename, text, content_type = context._wrote[2 + (2 * index) + 1]
00401             self.assertEqual(filename,
00402                              '/'.join(('structure', id, '.properties')))
00403             self.assertEqual(content_type, 'text/plain')
00404             parser = ConfigParser()
00405             parser.readfp(StringIO(text))
00406 
00407             defaults = parser.defaults()
00408             self.assertEqual(len(defaults), 1)
00409             self.assertEqual(defaults['title'], 'Title: %s' % id)
00410 
00411         filename, text, content_type = context._wrote[1]
00412         self.assertEqual(filename, 'structure/.properties')
00413         self.assertEqual(content_type, 'text/plain')
00414 
00415         parser = ConfigParser()
00416         parser.readfp(StringIO(text))
00417 
00418         defaults = parser.defaults()
00419         self.assertEqual(len(defaults), 2)
00420         self.assertEqual(defaults['title'], 'AAA')
00421         self.assertEqual(defaults['description'], 'CCC')
00422 
00423     def test_export_site_with_csvaware(self):
00424         from Products.GenericSetup.utils import _getDottedName
00425         self._setUpAdapters()
00426 
00427         site = _makeFolder('site')
00428         site.title = 'test_export_site_with_csvaware'
00429         site._setProperty('description',
00430                           'Testing export of an site with CSV-aware content.')
00431 
00432         aware = _makeCSVAware('aware')
00433         site._setObject('aware', aware)
00434 
00435         context = DummyExportContext(site)
00436         exporter = self._getExporter()
00437         exporter(context)
00438 
00439         self.assertEqual(len(context._wrote), 3)
00440         filename, text, content_type = context._wrote[0]
00441         self.assertEqual(filename, 'structure/.objects')
00442         self.assertEqual(content_type, 'text/comma-separated-values')
00443 
00444         objects = [x for x in reader(StringIO(text))]
00445         self.assertEqual(len(objects), 1)
00446         self.assertEqual(objects[0][0], 'aware')
00447         self.assertEqual(objects[0][1], _getDottedName(aware.__class__))
00448 
00449         filename, text, content_type = context._wrote[1]
00450         self.assertEqual(filename, 'structure/.properties')
00451         self.assertEqual(content_type, 'text/plain')
00452 
00453         parser = ConfigParser()
00454         parser.readfp(StringIO(text))
00455 
00456         defaults = parser.defaults()
00457         self.assertEqual(len(defaults), 2)
00458         self.assertEqual(defaults['title'], site.title)
00459         self.assertEqual(defaults['description'], site.description)
00460 
00461         filename, text, content_type = context._wrote[2]
00462         self.assertEqual(filename, 'structure/aware.csv')
00463         self.assertEqual(content_type, 'text/comma-separated-values')
00464         rows = [x for x in reader(StringIO(text))]
00465         self.assertEqual(len(rows), 2)
00466         self.assertEqual(rows[0][0], 'one')
00467         self.assertEqual(rows[0][1], 'two')
00468         self.assertEqual(rows[0][2], 'three')
00469         self.assertEqual(rows[1][0], 'four')
00470         self.assertEqual(rows[1][1], 'five')
00471         self.assertEqual(rows[1][2], 'six')
00472 
00473     def test_import_empty_site(self):
00474         self._setUpAdapters()
00475         site = _makeFolder('site')
00476         context = DummyImportContext(site)
00477         context._files['structure/.objects'] = ''
00478         importer = self._getImporter()
00479         self.assertEqual(len(site.objectIds()), 0)
00480         importer(context)
00481         self.assertEqual(len(site.objectIds()), 0)
00482 
00483     def test_import_empty_site_with_setup_tool(self):
00484         self._setUpAdapters()
00485         site = _makeFolder('site')
00486         site._setObject('setup_tool', self._makeSetupTool())
00487         context = DummyImportContext(site)
00488         importer = self._getImporter()
00489 
00490         self.assertEqual(len(site.objectIds()), 1)
00491         self.assertEqual(site.objectIds()[0], 'setup_tool')
00492         importer(context)
00493         self.assertEqual(len(site.objectIds()), 1)
00494         self.assertEqual(site.objectIds()[0], 'setup_tool')
00495 
00496     def test_import_site_with_subfolders(self):
00497         from Products.GenericSetup.utils import _getDottedName
00498         self._setUpAdapters()
00499         FOLDER_IDS = ('foo', 'bar', 'baz')
00500 
00501         site = _makeFolder('site')
00502         dotted = _getDottedName(site.__class__)
00503 
00504         context = DummyImportContext(site)
00505 
00506         for id in FOLDER_IDS:
00507             context._files['structure/%s/.objects' % id] = ''
00508             context._files['structure/%s/.properties' % id] = (
00509                 _PROPERTIES_TEMPLATE % id )
00510 
00511         _ROOT_OBJECTS = '\n'.join(['%s,%s' % (id, dotted)
00512                                         for id in FOLDER_IDS])
00513 
00514         context._files['structure/.objects'] = _ROOT_OBJECTS
00515         context._files['structure/.properties'] = (
00516                 _PROPERTIES_TEMPLATE % 'Test Site')
00517 
00518         importer = self._getImporter()
00519         importer(context)
00520 
00521         content = site.objectValues()
00522         self.assertEqual(len(content), len(FOLDER_IDS))
00523 
00524     def test_import_site_with_subitems(self):
00525         from Products.GenericSetup.utils import _getDottedName
00526         from faux_objects import KNOWN_INI
00527         from faux_objects import TestINIAware
00528         dotted = _getDottedName(TestINIAware)
00529         self._setUpAdapters()
00530         ITEM_IDS = ('foo', 'bar', 'baz')
00531 
00532         site = _makeFolder('site')
00533 
00534         context = DummyImportContext(site)
00535         # We want to add 'baz' to 'foo', without losing 'bar'
00536         context._files['structure/.objects'] = '\n'.join(
00537                             ['%s,%s' % (x, dotted) for x in ITEM_IDS])
00538         for index in range(len(ITEM_IDS)):
00539             id = ITEM_IDS[index]
00540             context._files[
00541                     'structure/%s.ini' % id] = KNOWN_INI % ('Title: %s' % id,
00542                                                             'xyzzy',
00543                                                            )
00544         importer = self._getImporter()
00545         importer(context)
00546 
00547         after = site.objectIds()
00548         self.assertEqual(len(after), len(ITEM_IDS))
00549         for found_id, expected_id in zip(after, ITEM_IDS):
00550             self.assertEqual(found_id, expected_id)
00551 
00552     def test_import_site_with_subitems_and_blanklines_dotobjects(self):
00553         from Products.GenericSetup.utils import _getDottedName
00554         from faux_objects import KNOWN_INI
00555         from faux_objects import TestINIAware
00556         dotted = _getDottedName(TestINIAware)
00557         self._setUpAdapters()
00558         ITEM_IDS = ('foo', 'bar', 'baz')
00559 
00560         site = _makeFolder('site')
00561 
00562         context = DummyImportContext(site)
00563         # We want to add 'baz' to 'foo', without losing 'bar'
00564         correct = '\n'.join(['%s,%s' % (x, dotted) for x in ITEM_IDS])
00565         broken = correct + '\n\n'
00566         context._files['structure/.objects'] = broken
00567         for index in range(len(ITEM_IDS)):
00568             id = ITEM_IDS[index]
00569             context._files[
00570                     'structure/%s.ini' % id] = KNOWN_INI % ('Title: %s' % id,
00571                                                             'xyzzy',
00572                                                            )
00573         importer = self._getImporter()
00574         importer(context)
00575 
00576         after = site.objectIds()
00577         self.assertEqual(len(after), len(ITEM_IDS))
00578         for found_id, expected_id in zip(after, ITEM_IDS):
00579             self.assertEqual(found_id, expected_id)
00580 
00581     def test_import_site_with_subitem_unknown_portal_type(self):
00582         from faux_objects import KNOWN_INI
00583         self._setUpAdapters()
00584         ITEM_IDS = ('foo', 'bar', 'baz')
00585 
00586         site = _makeFolder('site')
00587 
00588         context = DummyImportContext(site)
00589         # We want to add 'baz' to 'foo', without losing 'bar'
00590         context._files['structure/.objects'] = '\n'.join(
00591                                 ['%s,Unknown Type' % x for x in ITEM_IDS])
00592         for index in range(len(ITEM_IDS)):
00593             id = ITEM_IDS[index]
00594             context._files[
00595                     'structure/%s.ini' % id] = KNOWN_INI % ('Title: %s' % id,
00596                                                             'xyzzy',
00597                                                            )
00598 
00599         importer = self._getImporter()
00600         importer(context)
00601 
00602         after = site.objectIds()
00603         self.assertEqual(len(after), 0)
00604         self.assertEqual(len(context._notes), len(ITEM_IDS))
00605         for level, component, message in context._notes:
00606             self.assertEqual(component, 'SFWA')
00607             self.failUnless(message.startswith("Couldn't make"))
00608 
00609     def test_import_site_with_subitems_and_no_preserve(self):
00610         self._setUpAdapters()
00611         ITEM_IDS = ('foo', 'bar', 'baz')
00612 
00613         site = _makeFolder('site')
00614         for id in ITEM_IDS:
00615             site._setObject(id, _makeItem(id))
00616 
00617         context = DummyImportContext(site)
00618         # We want to add 'baz' to 'foo', without losing 'bar'
00619         context._files['structure/.objects'] = ''
00620 
00621         importer = self._getImporter()
00622         importer(context)
00623 
00624         self.assertEqual(len(site.objectIds()), 0)
00625 
00626     def test_import_site_with_subitemss_and_preserve(self):
00627         self._setUpAdapters()
00628         ITEM_IDS = ('foo', 'bar', 'baz')
00629 
00630         site = _makeFolder('site')
00631         for id in ITEM_IDS:
00632             site._setObject(id, _makeItem(id))
00633 
00634         context = DummyImportContext(site)
00635         # We want to add 'baz' to 'foo', without losing 'bar'
00636         context._files['structure/.objects'] = ''
00637         context._files['structure/.preserve'] = '*'
00638 
00639         importer = self._getImporter()
00640         importer(context)
00641 
00642         after = site.objectIds()
00643         self.assertEqual(len(after), len(ITEM_IDS))
00644         for i in range(len(ITEM_IDS)):
00645             self.assertEqual(after[i], ITEM_IDS[i])
00646 
00647     def test_import_site_with_subitemss_and_preserve_partial(self):
00648         self._setUpAdapters()
00649         ITEM_IDS = ('foo', 'bar', 'baz')
00650 
00651         site = _makeFolder('site')
00652         for id in ITEM_IDS:
00653             site._setObject(id, _makeItem(id))
00654 
00655         context = DummyImportContext(site)
00656         # We want to add 'baz' to 'foo', without losing 'bar'
00657         context._files['structure/.objects'] = ''
00658         context._files['structure/.preserve'] = 'b*'
00659 
00660         importer = self._getImporter()
00661         importer(context)
00662 
00663         after = site.objectIds()
00664         self.assertEqual(len(after), 2)
00665         self.assertEqual(after[0], 'bar')
00666         self.assertEqual(after[1], 'baz')
00667 
00668     def test_import_site_with_subfolders_and_preserve(self):
00669         from Products.GenericSetup.utils import _getDottedName
00670         self._setUpAdapters()
00671 
00672         site = _makeFolder('site')
00673         site._setObject('foo', _makeFolder('foo'))
00674         foo = site._getOb('foo')
00675         foo._setObject('bar', _makeFolder('bar'))
00676         bar = foo._getOb('bar')
00677 
00678         context = DummyImportContext(site)
00679         # We want to add 'baz' to 'foo', without losing 'bar'
00680         context._files['structure/.objects'
00681                       ] = 'foo,%s' % _getDottedName(foo.__class__)
00682         context._files['structure/.preserve'] = '*'
00683         context._files['structure/foo/.objects'
00684                       ] = 'baz,%s' % _getDottedName(bar.__class__)
00685         context._files['structure/foo/.preserve'] = '*'
00686         context._files['structure/foo/baz/.objects'] = ''
00687 
00688         importer = self._getImporter()
00689         importer(context)
00690 
00691         self.assertEqual(len(site.objectIds()), 1)
00692         self.assertEqual(site.objectIds()[0], 'foo')
00693 
00694         self.assertEqual(len(foo.objectIds()), 2, site.foo.objectIds())
00695         self.assertEqual(foo.objectIds()[0], 'bar')
00696         self.assertEqual(foo.objectIds()[1], 'baz')
00697 
00698 
00699 class Test_globpattern(unittest.TestCase):
00700 
00701     NAMELIST = ('foo', 'bar', 'baz', 'bam', 'qux', 'quxx', 'quxxx')
00702 
00703     def _checkResults(self, globpattern, namelist, expected):
00704         from Products.GenericSetup.content import _globtest
00705         found = _globtest(globpattern, namelist)
00706         self.assertEqual(len(found), len(expected))
00707         for found_item, expected_item in zip(found, expected):
00708             self.assertEqual(found_item, expected_item)
00709 
00710     def test_star(self):
00711         self._checkResults('*', self.NAMELIST, self.NAMELIST)
00712 
00713     def test_simple(self):
00714         self._checkResults('b*', self.NAMELIST,
00715                             [x for x in self.NAMELIST if x.startswith('b')])
00716 
00717     def test_multiple(self):
00718         self._checkResults('b*\n*x', self.NAMELIST,
00719                             [x for x in self.NAMELIST
00720                                 if x.startswith('b') or x.endswith('x')])
00721 
00722 
00723 class CSVAwareFileAdapterTests(unittest.TestCase,
00724                                ConformsToIFilesystemExporter,
00725                                ConformsToIFilesystemImporter,
00726                               ):
00727 
00728     def _getTargetClass(self):
00729         from Products.GenericSetup.content import CSVAwareFileAdapter
00730         return CSVAwareFileAdapter
00731 
00732     def _makeOne(self, context, *args, **kw):
00733         return self._getTargetClass()(context, *args, **kw)
00734 
00735     def test_export_with_known_CSV(self):
00736         from faux_objects import KNOWN_CSV
00737         sheet = _makeCSVAware('config')
00738 
00739         adapter = self._makeOne(sheet)
00740         context = DummyExportContext(None)
00741         adapter.export(context, 'subpath/to/sheet')
00742 
00743         self.assertEqual(len(context._wrote), 1)
00744         filename, text, content_type = context._wrote[0]
00745         self.assertEqual(filename, 'subpath/to/sheet/config.csv')
00746         self.assertEqual(content_type, 'text/comma-separated-values')
00747 
00748         self.assertEqual(text.strip(), KNOWN_CSV.strip())
00749 
00750     def test_import_with_known_CSV(self):
00751         ORIG_CSV = """\
00752 one,two,three
00753 four,five,six
00754 """
00755         NEW_CSV = """\
00756 four,five,six
00757 one,two,three
00758 """
00759         sheet = _makeCSVAware('config', ORIG_CSV)
00760 
00761         adapter = self._makeOne(sheet)
00762         context = DummyImportContext(None)
00763         context._files['subpath/to/sheet/config.csv'] = NEW_CSV
00764         adapter.import_(context, 'subpath/to/sheet')
00765 
00766         self.assertEqual(sheet._was_put.getvalue().strip(), NEW_CSV.strip())
00767 
00768 
00769 _PROPERTIES_TEMPLATE = """
00770 [DEFAULT]
00771 Title = %s
00772 Description = This is a test
00773 """
00774 
00775 class INIAwareFileAdapterTests(unittest.TestCase,
00776                                ConformsToIFilesystemExporter,
00777                                ConformsToIFilesystemImporter,
00778                                ):
00779 
00780     def _getTargetClass(self):
00781         from Products.GenericSetup.content import INIAwareFileAdapter
00782         return INIAwareFileAdapter
00783 
00784     def _makeOne(self, context, *args, **kw):
00785         return self._getTargetClass()(context, *args, **kw)
00786 
00787     def test_export_ini_file(self):
00788         ini_file = _makeINIAware('ini_file.html')
00789         adapter = self._makeOne(ini_file)
00790         context = DummyExportContext(None)
00791         adapter.export(context, 'subpath/to')
00792 
00793         self.assertEqual(len(context._wrote), 1)
00794         filename, text, content_type = context._wrote[0]
00795         self.assertEqual(filename, 'subpath/to/ini_file.html.ini')
00796         self.assertEqual(content_type, 'text/plain')
00797 
00798         self.assertEqual(text.strip(), ini_file.as_ini().strip())
00799 
00800     def test_import_ini_file(self):
00801         from faux_objects import KNOWN_INI
00802         ini_file = _makeINIAware('ini_file.html')
00803         adapter = self._makeOne(ini_file)
00804         context = DummyImportContext(None)
00805         context._files['subpath/to/ini_file.html.ini'] = (
00806                         KNOWN_INI % ('Title: ini_file', 'abc'))
00807 
00808         adapter.import_(context, 'subpath/to')
00809         text = ini_file._was_put
00810         parser = ConfigParser()
00811         parser.readfp(StringIO(text))
00812         self.assertEqual(parser.get('DEFAULT', 'title'), 'Title: ini_file')
00813         self.assertEqual(parser.get('DEFAULT', 'description'), 'abc')
00814 
00815 
00816 class DAVAwareFileAdapterTests(unittest.TestCase,
00817                                ConformsToIFilesystemExporter,
00818                                ConformsToIFilesystemImporter,
00819                                ):
00820 
00821     def _getTargetClass(self):
00822         from Products.GenericSetup.content import DAVAwareFileAdapter
00823         return DAVAwareFileAdapter
00824 
00825     def _makeOne(self, context, *args, **kw):
00826         return self._getTargetClass()(context, *args, **kw)
00827 
00828     def test_export_dav_file(self):
00829         dav_file = _makeDAVAware('dav_file.html')
00830         adapter = self._makeOne(dav_file)
00831         context = DummyExportContext(None)
00832         adapter.export(context, 'subpath/to')
00833 
00834         self.assertEqual(len(context._wrote), 1)
00835         filename, text, content_type = context._wrote[0]
00836         self.assertEqual(filename, 'subpath/to/dav_file.html')
00837         self.assertEqual(content_type, 'text/plain')
00838         self.assertEqual(text.strip(), dav_file.manage_FTPget().strip())
00839 
00840     def test_import_dav_file(self):
00841         from faux_objects import KNOWN_DAV
00842         VALUES = ('Title: dav_file', 'Description: abc', 'body goes here')
00843         dav_file = _makeDAVAware('dav_file.html')
00844         adapter = self._makeOne(dav_file)
00845         context = DummyImportContext(None)
00846         context._files['subpath/to/dav_file.html'] = KNOWN_DAV % VALUES
00847 
00848         adapter.import_(context, 'subpath/to')
00849         text = dav_file._was_put == KNOWN_DAV % VALUES
00850 
00851 
00852 def _makePropertied(id):
00853     from faux_objects import TestSimpleItemWithProperties
00854 
00855     propertied = TestSimpleItemWithProperties()
00856     propertied._setId(id)
00857 
00858     return propertied
00859 
00860 def _makeCSVAware(id, csv=None):
00861     from faux_objects import TestCSVAware
00862 
00863     aware = TestCSVAware()
00864     aware._setId(id)
00865     if csv is not None:
00866         aware._csv = csv
00867 
00868     return aware
00869 
00870 
00871 def _makeINIAware(id):
00872     from faux_objects import TestINIAware
00873 
00874     aware = TestINIAware()
00875     aware._setId(id)
00876 
00877     return aware
00878 
00879 
00880 def _makeDAVAware(id):
00881     from faux_objects import TestDAVAware
00882 
00883     aware = TestDAVAware()
00884     aware._setId(id)
00885 
00886     return aware
00887 
00888 
00889 def _makeItem(id):
00890     from faux_objects import TestSimpleItem
00891 
00892     aware = TestSimpleItem()
00893     aware._setId(id)
00894 
00895     return aware
00896 
00897 
00898 def _makeFolder(id):
00899     from OFS.Folder import Folder
00900     from zope.interface import directlyProvides
00901     from zope.interface import providedBy
00902 
00903     folder = Folder(id)
00904     directlyProvides(folder, providedBy(folder)
00905                              + IObjectManager + IPropertyManager)
00906 
00907     return folder
00908 
00909 
00910 def test_suite():
00911     suite = unittest.TestSuite()
00912     suite.addTest(unittest.makeSuite(SimpleINIAwareTests))
00913     suite.addTest(unittest.makeSuite(FolderishExporterImporterTests))
00914     suite.addTest(unittest.makeSuite(Test_globpattern))
00915     suite.addTest(unittest.makeSuite(CSVAwareFileAdapterTests))
00916     suite.addTest(unittest.makeSuite(INIAwareFileAdapterTests))
00917     suite.addTest(unittest.makeSuite(DAVAwareFileAdapterTests))
00918     return suite
00919 
00920 if __name__ == '__main__':
00921     unittest.main(defaultTest='test_suite')