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 82569 2007-12-30 12:21:47Z 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 zope.testing.cleanup import cleanUp
00026 
00027 from Products.GenericSetup.tests.common import DummyExportContext
00028 from Products.GenericSetup.tests.common import DummyImportContext
00029 
00030 
00031 class SiteStructureExporterTests(unittest.TestCase):
00032 
00033     def _getExporter(self):
00034         from Products.CMFCore.exportimport.content import exportSiteStructure
00035         return exportSiteStructure
00036 
00037     def _getImporter(self):
00038         from Products.CMFCore.exportimport.content import importSiteStructure
00039         return importSiteStructure
00040 
00041     def _makeSetupTool(self):
00042         from Products.GenericSetup.tool import SetupTool
00043         return SetupTool('portal_setup')
00044 
00045     def _setUpAdapters(self):
00046         from zope.app.testing import ztapi
00047         #from OFS.Image import File
00048 
00049         from Products.GenericSetup.interfaces import IFilesystemExporter
00050         from Products.GenericSetup.interfaces import IFilesystemImporter
00051         from Products.GenericSetup.interfaces import ICSVAware
00052         from Products.GenericSetup.interfaces import IINIAware
00053         from Products.CMFCore.interfaces import IFolderish
00054 
00055         from Products.CMFCore.exportimport.content import \
00056              StructureFolderWalkingAdapter
00057         from Products.GenericSetup.content import \
00058              CSVAwareFileAdapter
00059         from Products.GenericSetup.content import \
00060              INIAwareFileAdapter
00061 
00062         #from Products.CMFCore.exportimport.content import \
00063         #        OFSFileAdapter
00064 
00065         ztapi.provideAdapter(IFolderish,
00066                              IFilesystemExporter,
00067                              StructureFolderWalkingAdapter,
00068                             )
00069 
00070         ztapi.provideAdapter(IFolderish,
00071                              IFilesystemImporter,
00072                              StructureFolderWalkingAdapter,
00073                             )
00074 
00075         ztapi.provideAdapter(ICSVAware,
00076                              IFilesystemExporter,
00077                              CSVAwareFileAdapter,
00078                             )
00079 
00080         ztapi.provideAdapter(ICSVAware,
00081                              IFilesystemImporter,
00082                              CSVAwareFileAdapter,
00083                             )
00084 
00085         ztapi.provideAdapter(IINIAware,
00086                              IFilesystemExporter,
00087                              INIAwareFileAdapter,
00088                             )
00089 
00090         ztapi.provideAdapter(IINIAware,
00091                              IFilesystemImporter,
00092                              INIAwareFileAdapter,
00093                             )
00094 
00095     def tearDown(self):
00096         cleanUp()
00097 
00098     def test_export_empty_site(self):
00099         self._setUpAdapters()
00100         site = _makeFolder('site', site_folder=True)
00101         site.title = 'test_export_empty_site'
00102         site.description = 'Testing export of an empty site.'
00103         context = DummyExportContext(site)
00104         exporter = self._getExporter()
00105         exporter(context)
00106 
00107         self.assertEqual(len(context._wrote), 2)
00108         filename, text, content_type = context._wrote[0]
00109         self.assertEqual(filename, 'structure/.objects')
00110         self.assertEqual(content_type, 'text/comma-separated-values')
00111 
00112         objects = [x for x in reader(StringIO(text))]
00113         self.assertEqual(len(objects), 0)
00114 
00115         filename, text, content_type = context._wrote[1]
00116         self.assertEqual(filename, 'structure/.properties')
00117         self.assertEqual(content_type, 'text/plain')
00118 
00119         parser = ConfigParser()
00120         parser.readfp(StringIO(text))
00121 
00122         self.assertEqual(parser.get('DEFAULT', 'Title'),
00123                          site.title)
00124         self.assertEqual(parser.get('DEFAULT', 'Description'),
00125                          site.description)
00126 
00127     def test_export_empty_site_with_setup_tool(self):
00128         self._setUpAdapters()
00129         site = _makeFolder('site', site_folder=True)
00130         site._setObject('setup_tool', self._makeSetupTool())
00131         site.title = 'test_export_empty_site_with_setup_tool'
00132         site.description = 'Testing export of an empty site with setup tool.'
00133         context = DummyExportContext(site)
00134         exporter = self._getExporter()
00135         exporter(context)
00136 
00137         self.assertEqual(len(context._wrote), 2)
00138         filename, text, content_type = context._wrote[0]
00139         self.assertEqual(filename, 'structure/.objects')
00140         self.assertEqual(content_type, 'text/comma-separated-values')
00141 
00142         objects = [x for x in reader(StringIO(text))]
00143         self.assertEqual(len(objects), 0)
00144 
00145         filename, text, content_type = context._wrote[1]
00146         self.assertEqual(filename, 'structure/.properties')
00147         self.assertEqual(content_type, 'text/plain')
00148 
00149         parser = ConfigParser()
00150         parser.readfp(StringIO(text))
00151 
00152         self.assertEqual(parser.get('DEFAULT', 'Title'),
00153                          site.title)
00154         self.assertEqual(parser.get('DEFAULT', 'Description'),
00155                          site.description)
00156 
00157     def test_export_site_with_non_exportable_simple_items(self):
00158         self._setUpAdapters()
00159         ITEM_IDS = ('foo', 'bar', 'baz')
00160 
00161         site = _makeFolder('site', site_folder=True)
00162         site.title = 'AAA'
00163         site.description = 'BBB'
00164         for id in ITEM_IDS:
00165             site._setObject(id, _makeItem(id))
00166 
00167         context = DummyExportContext(site)
00168         exporter = self._getExporter()
00169         exporter(context)
00170 
00171         self.assertEqual(len(context._wrote), 2)
00172         filename, text, content_type = context._wrote[0]
00173         self.assertEqual(filename, 'structure/.objects')
00174         self.assertEqual(content_type, 'text/comma-separated-values')
00175 
00176         objects = [x for x in reader(StringIO(text))]
00177         self.assertEqual(len(objects), 3)
00178         for index in range(len(ITEM_IDS)):
00179             self.assertEqual(objects[index][0], ITEM_IDS[index])
00180             self.assertEqual(objects[index][1], TEST_CONTENT)
00181 
00182         filename, text, content_type = context._wrote[1]
00183         self.assertEqual(filename, 'structure/.properties')
00184         self.assertEqual(content_type, 'text/plain')
00185         parser = ConfigParser()
00186         parser.readfp(StringIO(text))
00187 
00188         self.assertEqual(parser.get('DEFAULT', 'title'), 'AAA')
00189         self.assertEqual(parser.get('DEFAULT', 'description'), 'BBB')
00190 
00191     def test_export_site_with_exportable_simple_items(self):
00192         self._setUpAdapters()
00193         ITEM_IDS = ('foo', 'bar', 'baz')
00194 
00195         site = _makeFolder('site', site_folder=True)
00196         site.title = 'AAA'
00197         site.description = 'BBB'
00198         for id in ITEM_IDS:
00199             site._setObject(id, _makeINIAware(id))
00200 
00201         context = DummyExportContext(site)
00202         exporter = self._getExporter()
00203         exporter(context)
00204 
00205         self.assertEqual(len(context._wrote), 2 + len(ITEM_IDS))
00206         filename, text, content_type = context._wrote[0]
00207         self.assertEqual(filename, 'structure/.objects')
00208         self.assertEqual(content_type, 'text/comma-separated-values')
00209 
00210         objects = [x for x in reader(StringIO(text))]
00211         self.assertEqual(len(objects), 3)
00212         for index in range(len(ITEM_IDS)):
00213             self.assertEqual(objects[index][0], ITEM_IDS[index])
00214             self.assertEqual(objects[index][1], TEST_INI_AWARE)
00215 
00216             filename, text, content_type = context._wrote[index+2]
00217             self.assertEqual(filename, 'structure/%s.ini' % ITEM_IDS[index])
00218             object = site._getOb(ITEM_IDS[index])
00219             self.assertEqual(text.strip(),
00220                              object.as_ini().strip())
00221             self.assertEqual(content_type, 'text/plain')
00222 
00223         filename, text, content_type = context._wrote[1]
00224         self.assertEqual(filename, 'structure/.properties')
00225         self.assertEqual(content_type, 'text/plain')
00226         parser = ConfigParser()
00227         parser.readfp(StringIO(text))
00228 
00229         self.assertEqual(parser.get('DEFAULT', 'title'), 'AAA')
00230         self.assertEqual(parser.get('DEFAULT', 'description'), 'BBB')
00231 
00232     def test_export_site_with_subfolders(self):
00233         self._setUpAdapters()
00234         FOLDER_IDS = ('foo', 'bar', 'baz')
00235 
00236         site = _makeFolder('site', site_folder=True)
00237         site.title = 'AAA'
00238         site.description = 'BBB'
00239         for id in FOLDER_IDS:
00240             folder = _makeFolder(id)
00241             folder.title = 'Title: %s' % id
00242             folder.description = 'xyzzy'
00243             site._setObject(id, folder)
00244 
00245         context = DummyExportContext(site)
00246         exporter = self._getExporter()
00247         exporter(context)
00248 
00249         self.assertEqual(len(context._wrote), 2 + (2 *len(FOLDER_IDS)))
00250         filename, text, content_type = context._wrote[0]
00251         self.assertEqual(filename, 'structure/.objects')
00252         self.assertEqual(content_type, 'text/comma-separated-values')
00253 
00254         objects = [x for x in reader(StringIO(text))]
00255         self.assertEqual(len(objects), 3)
00256 
00257         for index in range(len(FOLDER_IDS)):
00258             id = FOLDER_IDS[index]
00259             self.assertEqual(objects[index][0], id)
00260             self.assertEqual(objects[index][1], TEST_FOLDER)
00261 
00262             filename, text, content_type = context._wrote[2 + (2 * index)]
00263             self.assertEqual(filename, '/'.join(('structure', id, '.objects')))
00264             self.assertEqual(content_type, 'text/comma-separated-values')
00265             subobjects = [x for x in reader(StringIO(text))]
00266             self.assertEqual(len(subobjects), 0)
00267 
00268             filename, text, content_type = context._wrote[2 + (2 * index) + 1]
00269             self.assertEqual(filename,
00270                              '/'.join(('structure', id, '.properties')))
00271             self.assertEqual(content_type, 'text/plain')
00272             parser = ConfigParser()
00273             parser.readfp(StringIO(text))
00274 
00275             self.assertEqual(parser.get('DEFAULT', 'Title'), 'Title: %s' % id)
00276 
00277         filename, text, content_type = context._wrote[1]
00278         self.assertEqual(filename, 'structure/.properties')
00279         self.assertEqual(content_type, 'text/plain')
00280 
00281         parser = ConfigParser()
00282         parser.readfp(StringIO(text))
00283 
00284         self.assertEqual(parser.get('DEFAULT', 'title'), 'AAA')
00285         self.assertEqual(parser.get('DEFAULT', 'description'), 'BBB')
00286 
00287     def test_export_site_with_csvaware(self):
00288         self._setUpAdapters()
00289 
00290         site = _makeFolder('site', site_folder=True)
00291         site.title = 'test_export_site_with_csvaware'
00292         site.description = 'Testing export of an site with CSV-aware content.'
00293 
00294         site._setObject('aware', _makeCSVAware('aware'))
00295 
00296         context = DummyExportContext(site)
00297         exporter = self._getExporter()
00298         exporter(context)
00299 
00300         self.assertEqual(len(context._wrote), 3)
00301         filename, text, content_type = context._wrote[0]
00302         self.assertEqual(filename, 'structure/.objects')
00303         self.assertEqual(content_type, 'text/comma-separated-values')
00304 
00305         objects = [x for x in reader(StringIO(text))]
00306         self.assertEqual(len(objects), 1)
00307         self.assertEqual(objects[0][0], 'aware')
00308         self.assertEqual(objects[0][1], TEST_CSV_AWARE)
00309 
00310         filename, text, content_type = context._wrote[1]
00311         self.assertEqual(filename, 'structure/.properties')
00312         self.assertEqual(content_type, 'text/plain')
00313 
00314         parser = ConfigParser()
00315         parser.readfp(StringIO(text))
00316 
00317         self.assertEqual(parser.get('DEFAULT', 'Title'),
00318                                     site.title)
00319         self.assertEqual(parser.get('DEFAULT', 'Description'),
00320                                     site.description)
00321 
00322         filename, text, content_type = context._wrote[2]
00323         self.assertEqual(filename, 'structure/aware.csv')
00324         self.assertEqual(content_type, 'text/comma-separated-values')
00325         rows = [x for x in reader(StringIO(text))]
00326         self.assertEqual(len(rows), 2)
00327         self.assertEqual(rows[0][0], 'one')
00328         self.assertEqual(rows[0][1], 'two')
00329         self.assertEqual(rows[0][2], 'three')
00330         self.assertEqual(rows[1][0], 'four')
00331         self.assertEqual(rows[1][1], 'five')
00332         self.assertEqual(rows[1][2], 'six')
00333 
00334     def test_import_empty_site(self):
00335         self._setUpAdapters()
00336         site = _makeFolder('site', site_folder=True)
00337         context = DummyImportContext(site)
00338         context._files['structure/.objects'] = ''
00339         importer = self._getImporter()
00340         self.assertEqual(len(site.objectIds()), 0)
00341         importer(context)
00342         self.assertEqual(len(site.objectIds()), 0)
00343 
00344     def test_import_empty_site_with_setup_tool(self):
00345         self._setUpAdapters()
00346         site = _makeFolder('site', site_folder=True)
00347         site._setObject('setup_tool', self._makeSetupTool())
00348         context = DummyImportContext(site)
00349         importer = self._getImporter()
00350 
00351         self.assertEqual(len(site.objectIds()), 1)
00352         self.assertEqual(site.objectIds()[0], 'setup_tool')
00353         importer(context)
00354         self.assertEqual(len(site.objectIds()), 1)
00355         self.assertEqual(site.objectIds()[0], 'setup_tool')
00356 
00357     def test_import_site_with_subfolders(self):
00358         from Products.GenericSetup.tests.test_content \
00359             import _PROPERTIES_TEMPLATE
00360         self._setUpAdapters()
00361         FOLDER_IDS = ('foo', 'bar', 'baz')
00362 
00363         site = _makeFolder('site', site_folder=True)
00364 
00365         context = DummyImportContext(site)
00366 
00367         for id in FOLDER_IDS:
00368             context._files['structure/%s/.objects' % id] = ''
00369             context._files['structure/%s/.properties' % id] = (
00370                 _PROPERTIES_TEMPLATE % id )
00371 
00372         _ROOT_OBJECTS = '\n'.join(['%s,%s' % (id, TEST_FOLDER)
00373                                         for id in FOLDER_IDS])
00374 
00375         context._files['structure/.objects'] = _ROOT_OBJECTS
00376         context._files['structure/.properties'] = (
00377                 _PROPERTIES_TEMPLATE % 'Test Site')
00378 
00379         importer = self._getImporter()
00380         importer(context)
00381 
00382         content = site.contentValues()
00383         self.assertEqual(len(content), len(FOLDER_IDS))
00384 
00385     def test_import_site_with_subitems(self):
00386         self._setUpAdapters()
00387         ITEM_IDS = ('foo', 'bar', 'baz')
00388 
00389         site = _makeFolder('site', site_folder=True)
00390 
00391         context = DummyImportContext(site)
00392         # We want to add 'baz' to 'foo', without losing 'bar'
00393         context._files['structure/.objects'] = '\n'.join(
00394                             ['%s,%s' % (x, TEST_INI_AWARE) for x in ITEM_IDS])
00395         for index in range(len(ITEM_IDS)):
00396             id = ITEM_IDS[index]
00397             context._files[
00398                     'structure/%s.ini' % id] = KNOWN_INI % ('Title: %s' % id,
00399                                                             'xyzzy',
00400                                                            )
00401         importer = self._getImporter()
00402         importer(context)
00403 
00404         after = site.objectIds()
00405         self.assertEqual(len(after), len(ITEM_IDS))
00406         for found_id, expected_id in zip(after, ITEM_IDS):
00407             self.assertEqual(found_id, expected_id)
00408 
00409     def test_import_site_with_subitems_and_blanklines_dotobjects(self):
00410         self._setUpAdapters()
00411         ITEM_IDS = ('foo', 'bar', 'baz')
00412 
00413         site = _makeFolder('site', site_folder=True)
00414 
00415         context = DummyImportContext(site)
00416         # We want to add 'baz' to 'foo', without losing 'bar'
00417         correct = '\n'.join(['%s,%s' % (x, TEST_INI_AWARE) for x in ITEM_IDS])
00418         broken = correct + '\n\n'
00419         context._files['structure/.objects'] = broken
00420         for index in range(len(ITEM_IDS)):
00421             id = ITEM_IDS[index]
00422             context._files[
00423                     'structure/%s.ini' % id] = KNOWN_INI % ('Title: %s' % id,
00424                                                             'xyzzy',
00425                                                            )
00426         importer = self._getImporter()
00427         importer(context)
00428 
00429         after = site.objectIds()
00430         self.assertEqual(len(after), len(ITEM_IDS))
00431         for found_id, expected_id in zip(after, ITEM_IDS):
00432             self.assertEqual(found_id, expected_id)
00433 
00434     def test_import_site_with_subitem_unknown_portal_type(self):
00435         self._setUpAdapters()
00436         ITEM_IDS = ('foo', 'bar', 'baz')
00437 
00438         site = _makeFolder('site', site_folder=True)
00439 
00440         context = DummyImportContext(site)
00441         # We want to add 'baz' to 'foo', without losing 'bar'
00442         context._files['structure/.objects'] = '\n'.join(
00443                                 ['%s,Unknown Type' % x for x in ITEM_IDS])
00444         for index in range(len(ITEM_IDS)):
00445             id = ITEM_IDS[index]
00446             context._files[
00447                     'structure/%s.ini' % id] = KNOWN_INI % ('Title: %s' % id,
00448                                                             'xyzzy',
00449                                                            )
00450 
00451         importer = self._getImporter()
00452         importer(context)
00453 
00454         after = site.objectIds()
00455         self.assertEqual(len(after), 0)
00456         self.assertEqual(len(context._notes), len(ITEM_IDS))
00457         for level, component, message in context._notes:
00458             self.assertEqual(component, 'SFWA')
00459             self.failUnless(message.startswith("Couldn't make"))
00460 
00461     def test_reimport_no_structure_no_delete(self):
00462         self._setUpAdapters()
00463         ITEM_IDS = ('foo', 'bar', 'baz')
00464 
00465         site = _makeFolder('site', site_folder=True)
00466         for id in ITEM_IDS:
00467             site._setObject(id, _makeItem(id))
00468 
00469         context = DummyImportContext(site)
00470         # no defined structure => no deletion
00471         context._files['structure/.objects'] = ''
00472 
00473         importer = self._getImporter()
00474         importer(context)
00475 
00476         self.assertEqual(len(site.objectIds()), len(ITEM_IDS))
00477 
00478     def test_reimport_with_structure_does_delete(self):
00479         self._setUpAdapters()
00480         ITEM_IDS = ('foo', 'bar', 'baz')
00481 
00482         site = _makeFolder('site', site_folder=True)
00483         for id in ITEM_IDS:
00484             site._setObject(id, _makeItem(id))
00485             site._getOb(id).before = True
00486 
00487         context = DummyImportContext(site)
00488         # defined structure => object deleted and recreated
00489         context._files['structure/.objects'] = '\n'.join(
00490             ['%s,%s' % (x, TEST_INI_AWARE) for x in ITEM_IDS])
00491         for index in range(len(ITEM_IDS)):
00492             id = ITEM_IDS[index]
00493             context._files[
00494                     'structure/%s.ini' % id] = KNOWN_INI % ('Title: %s' % id,
00495                                                             'xyzzy',
00496                                                            )
00497 
00498         importer = self._getImporter()
00499         importer(context)
00500 
00501         self.assertEqual(len(site.objectIds()), len(ITEM_IDS))
00502         for obj in site.objectValues():
00503             self.failIf(hasattr(obj, 'before'))
00504 
00505     def test_reimport_with_structure_and_preserve(self):
00506         self._setUpAdapters()
00507         ITEM_IDS = ('foo', 'bar', 'baz')
00508 
00509         site = _makeFolder('site', site_folder=True)
00510         for id in ITEM_IDS:
00511             site._setObject(id, _makeINIAware(id))
00512             site._getOb(id).before = True
00513 
00514         context = DummyImportContext(site)
00515         context._files['structure/.objects'] = '\n'.join(
00516             ['%s,%s' % (x, TEST_INI_AWARE) for x in ITEM_IDS])
00517         for index in range(len(ITEM_IDS)):
00518             id = ITEM_IDS[index]
00519             context._files[
00520                     'structure/%s.ini' % id] = KNOWN_INI % ('Title: %s' % id,
00521                                                             'xyzzy',
00522                                                            )
00523         context._files['structure/.preserve'] = '*'
00524 
00525         importer = self._getImporter()
00526         importer(context)
00527 
00528         after = site.objectIds()
00529         self.assertEqual(len(after), len(ITEM_IDS))
00530         for i in range(len(ITEM_IDS)):
00531             self.assertEqual(after[i], ITEM_IDS[i])
00532             self.assertEqual(getattr(site._getOb(after[i]), 'before', None),
00533                              True)
00534 
00535     def test_reimport_with_structure_and_preserve_partial(self):
00536         self._setUpAdapters()
00537         ITEM_IDS = ('foo', 'bar', 'baz')
00538 
00539         site = _makeFolder('site', site_folder=True)
00540         for id in ITEM_IDS:
00541             site._setObject(id, _makeINIAware(id))
00542             site._getOb(id).before = True
00543 
00544         context = DummyImportContext(site)
00545         context._files['structure/.objects'] = '\n'.join(
00546             ['%s,%s' % (x, TEST_INI_AWARE) for x in ITEM_IDS])
00547         for index in range(len(ITEM_IDS)):
00548             id = ITEM_IDS[index]
00549             context._files[
00550                     'structure/%s.ini' % id] = KNOWN_INI % ('Title: %s' % id,
00551                                                             'xyzzy',
00552                                                            )
00553         context._files['structure/.preserve'] = 'b*'
00554 
00555         importer = self._getImporter()
00556         importer(context)
00557 
00558         after = site.objectValues()
00559         self.assertEqual(len(after), len(ITEM_IDS))
00560         for obj in after:
00561             if obj.getId().startswith('b'):
00562                 self.assertEqual(getattr(obj, 'before', None), True)
00563             else:
00564                 self.assertEqual(getattr(obj, 'before', None), None)
00565 
00566     def test_reimport_with_structure_partial_preserve_and_delete(self):
00567         self._setUpAdapters()
00568         ITEM_IDS = ('foo', 'bar', 'baz')
00569 
00570         site = _makeFolder('site', site_folder=True)
00571         for id in ITEM_IDS:
00572             site._setObject(id, _makeINIAware(id))
00573             site._getOb(id).before = True
00574 
00575         context = DummyImportContext(site)
00576         context._files['structure/.objects'] = '\n'.join(
00577             ['%s,%s' % (x, TEST_INI_AWARE) for x in ITEM_IDS[:-1]])
00578         for index in range(len(ITEM_IDS)):
00579             id = ITEM_IDS[index]
00580             context._files[
00581                     'structure/%s.ini' % id] = KNOWN_INI % ('Title: %s' % id,
00582                                                             'xyzzy',
00583                                                            )
00584         context._files['structure/.preserve'] = 'foo'
00585         context._files['structure/.delete'] = 'baz'
00586 
00587         importer = self._getImporter()
00588         importer(context)
00589 
00590         after = site.objectIds()
00591         self.assertEqual(len(after), len(ITEM_IDS) - 1)
00592         self.failIf('baz' in after)
00593         self.assertEqual(getattr(site.foo, 'before', None), True)
00594         self.failIf(hasattr(site.bar, 'before'))
00595 
00596     def test_import_site_with_subfolders_and_preserve(self):
00597         self._setUpAdapters()
00598 
00599         site = _makeFolder('site', site_folder=True)
00600         site._setObject('foo', _makeFolder('foo'))
00601         site.foo._setObject('bar', _makeFolder('bar'))
00602 
00603         context = DummyImportContext(site)
00604         # We want to add 'baz' to 'foo', without losing 'bar'
00605         context._files['structure/.objects'] = 'foo,%s' % TEST_FOLDER
00606         context._files['structure/.preserve'] = '*'
00607         context._files['structure/foo/.objects'] = 'baz,%s' % TEST_FOLDER
00608         context._files['structure/foo/.preserve'] = '*'
00609         context._files['structure/foo/baz/.objects'] = ''
00610 
00611         importer = self._getImporter()
00612         importer(context)
00613 
00614         self.assertEqual(len(site.objectIds()), 1)
00615         self.assertEqual(site.objectIds()[0], 'foo')
00616 
00617         self.assertEqual(len(site.foo.objectIds()), 2, site.foo.objectIds())
00618         self.assertEqual(site.foo.objectIds()[0], 'bar')
00619         self.assertEqual(site.foo.objectIds()[1], 'baz')
00620 
00621 
00622 TEST_CSV_AWARE = 'Test CSV Aware'
00623 KNOWN_CSV = """\
00624 one,two,three
00625 four,five,six
00626 """
00627 
00628 def _makeCSVAware(id):
00629     from OFS.SimpleItem import SimpleItem
00630     from zope.interface import implements
00631     from Products.CMFCore.interfaces import IDynamicType
00632     from Products.GenericSetup.interfaces import ICSVAware
00633 
00634     class _TestCSVAware(SimpleItem):
00635         implements(IDynamicType, ICSVAware)
00636         _was_put = None
00637         portal_type = TEST_CSV_AWARE
00638 
00639         def getPortalTypeName(self):
00640             return self.portal_type
00641 
00642         def as_csv(self):
00643             return KNOWN_CSV
00644 
00645         def put_csv(self, text):
00646             self._was_put = text
00647 
00648     aware = _TestCSVAware()
00649     aware._setId(id)
00650 
00651     return aware
00652 
00653 
00654 TEST_INI_AWARE = 'Test INI Aware'
00655 KNOWN_INI = """\
00656 [DEFAULT]
00657 title = %s
00658 description = %s
00659 """
00660 
00661 def _makeINIAware(id):
00662     from OFS.SimpleItem import SimpleItem
00663     from zope.interface import implements
00664     from Products.CMFCore.interfaces import IDynamicType
00665     from Products.GenericSetup.interfaces import IINIAware
00666 
00667     class _TestINIAware(SimpleItem):
00668         implements(IDynamicType, IINIAware)
00669         _was_put = None
00670         title = 'INI title'
00671         description = 'INI description'
00672         portal_type = TEST_INI_AWARE
00673 
00674         def getPortalTypeName(self):
00675             return self.portal_type
00676 
00677         def as_ini(self):
00678             return KNOWN_INI % (self.title, self.description)
00679 
00680         def put_ini(self, text):
00681             self._was_put = text
00682 
00683     aware = _TestINIAware()
00684     aware._setId(id)
00685 
00686     return aware
00687 
00688 
00689 TEST_DAV_AWARE = 'Test DAV Aware'
00690 KNOWN_DAV = """\
00691 Title: %s
00692 Description: %s
00693 
00694 %s
00695 """
00696 
00697 def _makeDAVAware(id):
00698     from OFS.SimpleItem import SimpleItem
00699     from zope.interface import implements
00700     from Products.CMFCore.interfaces import IDynamicType
00701     from Products.GenericSetup.interfaces import IDAVAware
00702 
00703     class _TestDAVAware(SimpleItem):
00704         implements(IDynamicType, IDAVAware)
00705         _was_put = None
00706         title = 'DAV title'
00707         description = 'DAV description'
00708         body = 'DAV body'
00709         portal_type = TEST_DAV_AWARE
00710 
00711         def getPortalTypeName(self):
00712             return self.portal_type
00713 
00714         def manage_FTPget(self):
00715             return KNOWN_DAV % (self.title, self.description, self.body)
00716 
00717         def PUT(self, REQUEST, RESPONSE):
00718             self._was_put = REQUEST.get('BODY', '')
00719             stream = REQUEST.get('BODYFILE', None)
00720             self._was_put_as_read = stream.read()
00721 
00722     aware = _TestDAVAware()
00723     aware._setId(id)
00724 
00725     return aware
00726 
00727 
00728 TEST_CONTENT = 'Test Content'
00729 
00730 def _makeItem(self):
00731     from OFS.SimpleItem import SimpleItem
00732     from zope.interface import implements
00733     from Products.CMFCore.interfaces import IDynamicType
00734 
00735     class _TestContent(SimpleItem):
00736         implements(IDynamicType)
00737         portal_type = TEST_CONTENT
00738 
00739         def getPortalTypeName(self):
00740             return self.portal_type
00741 
00742     aware = _TestContent()
00743     aware._setId(id)
00744 
00745     return aware
00746 
00747 
00748 TEST_FOLDER = 'Test Folder'
00749 
00750 def _makeFolder(id, site_folder=False):
00751     from Products.CMFCore.PortalFolder import PortalFolder
00752     from Products.CMFCore.TypesTool import TypesTool
00753     from Products.CMFCore.tests.base.dummy import DummyType
00754 
00755     class _TypeInfo(DummyType):
00756         def _getId(self):
00757             return self._id
00758         def constructInstance(self, container, id, *args, **kw):
00759             portal_type = self._getId()
00760             if portal_type == TEST_FOLDER:
00761                 content = PortalFolder(id)
00762             elif portal_type == TEST_CONTENT:
00763                 content = _makeItem()
00764                 content._setId(id)
00765             elif portal_type == TEST_INI_AWARE:
00766                 content = _makeINIAware(id)
00767             elif portal_type == TEST_CSV_AWARE:
00768                 content = _makeCSVAware(id)
00769             else:
00770                 raise ValueError, 'Ugh'
00771             content.portal_type = portal_type
00772             container._setObject(id, content)
00773             return container._getOb(id)
00774 
00775     folder = PortalFolder(id)
00776     folder.portal_type = TEST_FOLDER
00777     if site_folder:
00778         tool = folder.portal_types = TypesTool()
00779         tool._setObject(TEST_CSV_AWARE, _TypeInfo(TEST_CSV_AWARE))
00780         tool._setObject(TEST_INI_AWARE, _TypeInfo(TEST_INI_AWARE))
00781         tool._setObject(TEST_CONTENT, _TypeInfo(TEST_CONTENT))
00782         tool._setObject(TEST_FOLDER, _TypeInfo(TEST_FOLDER))
00783 
00784     return folder
00785 
00786 
00787 def test_suite():
00788     suite = unittest.TestSuite()
00789     suite.addTest(unittest.makeSuite(SiteStructureExporterTests))
00790     return suite
00791 
00792 if __name__ == '__main__':
00793     unittest.main(defaultTest='test_suite')