Index: quintagroup.transmogrifier.simpleblog2quills/trunk/README.txt
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/README.txt	(revision 309)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/README.txt	(revision 359)
@@ -5,3 +5,37 @@
 --------
 
-Configuration of collective.transmogrifier pipeline for migrating SimpleBlog content to Quills content
+Configuration of collective.transmogrifier pipeline for migrating SimpleBlog
+content to Quills content.
+
+Installation
+------------
+
+See docs/INSTALL.txt for installation instructions.
+
+Supported Plone versions
+------------------------
+
+This package was designed to work and tested on next Plone versions:
+
+ - Plone 3.1.5
+
+    Quills_ plone product is required, now version 1.6 is supported.
+
+
+Running tests
+-------------
+
+    Run next command:
+
+    bin/instance test -s quintagroup.transmogrifier.simpleblog2quills \
+        -m test_import
+
+Credits
+-------
+
+Design and development
+   `Bohdan Koval`_ at Quintagroup_
+
+.. _Quills: http://plone.org/products/quills/releases/1.6/quills-1-6-beta1.tgz
+.. _Bohdan Koval: mailto:koval@quintagroup.com
+.. _Quintagroup: http://www.quintagroup.com/
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/TODO.txt
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/TODO.txt	(revision 359)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/TODO.txt	(revision 359)
@@ -0,0 +1,8 @@
+TODO
+====
+
+ - add GS profile with configuration of blog content types workflows
+
+ - add schema extender that adds ``tags`` field for WeblogEntry
+
+ - fix some misterious problem when running two package's tests modules at once
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/configure.zcml
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/configure.zcml	(revision 309)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/configure.zcml	(revision 359)
@@ -1,7 +1,6 @@
 <configure
     xmlns="http://namespaces.zope.org/zope"
-    xmlns:five="http://namespaces.zope.org/five"
     xmlns:transmogrifier="http://namespaces.plone.org/transmogrifier"
-    i18n_domain="quintagroup.simpleblog2quills">
+    i18n_domain="quintagroup.transmogrifier.simpleblog2quills">
 
     <include package="quintagroup.transmogrifier" />
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests.py
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests.py	(revision 309)
+++ 	(revision )
@@ -1,54 +1,0 @@
-import unittest
-
-from zope.testing import doctestunit
-from zope.component import testing
-from Testing import ZopeTestCase as ztc
-
-from Products.Five import zcml
-from Products.Five import fiveconfigure
-from Products.PloneTestCase import PloneTestCase as ptc
-from Products.PloneTestCase.layer import PloneSite
-ptc.setupPloneSite()
-
-import quintagroup.transmogrifier.simpleblog2quills
-
-class TestCase(ptc.PloneTestCase):
-    class layer(PloneSite):
-        @classmethod
-        def setUp(cls):
-            fiveconfigure.debug_mode = True
-            zcml.load_config('configure.zcml',
-                             quintagroup.transmogrifier.simpleblog2quills)
-            fiveconfigure.debug_mode = False
-
-        @classmethod
-        def tearDown(cls):
-            pass
-
-
-def test_suite():
-    return unittest.TestSuite([
-
-        # Unit tests
-        #doctestunit.DocFileSuite(
-        #    'README.txt', package='quintagroup.transmogrifier.simpleblog2quills',
-        #    setUp=testing.setUp, tearDown=testing.tearDown),
-
-        #doctestunit.DocTestSuite(
-        #    module='quintagroup.transmogrifier.simpleblog2quills.mymodule',
-        #    setUp=testing.setUp, tearDown=testing.tearDown),
-
-
-        # Integration tests that use PloneTestCase
-        #ztc.ZopeDocFileSuite(
-        #    'README.txt', package='quintagroup.transmogrifier.simpleblog2quills',
-        #    test_class=TestCase),
-
-        #ztc.FunctionalDocFileSuite(
-        #    'browser.txt', package='quintagroup.transmogrifier.simpleblog2quills',
-        #    test_class=TestCase),
-
-        ])
-
-if __name__ == '__main__':
-    unittest.main(defaultTest='test_suite')
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/__init__.py
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/__init__.py	(revision 359)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/__init__.py	(revision 359)
@@ -0,0 +1,1 @@
+# i'm a package
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/base.py
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/base.py	(revision 359)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/base.py	(revision 359)
@@ -0,0 +1,43 @@
+import os.path
+
+from zope.interface import classProvides, implements
+
+from collective.transmogrifier.interfaces import ISectionBlueprint, ISection
+
+class Source(object):
+    classProvides(ISectionBlueprint)
+    implements(ISection)
+
+    def __init__(self, transmogrifier, name, options, previous):
+        self.previous = previous
+        self.source = options.get('source', '').strip()
+        self.allow_empty = options.get('allow-empty-items', '').strip() == 'yes' and True or False
+        items_source = options.get('items', '').strip()
+        self.items = []
+        for line in items_source.splitlines():
+            self.items.append([i.strip() for i in line.split(';')])
+
+    def __iter__(self):
+        for item in self.previous:
+            yield item
+
+        for path, type_, fname in self.items:
+            if not fname.startswith('/'):
+                fname = os.path.join(os.path.dirname(__file__), fname)
+            try:
+                fp = file(fname)
+                data = fp.read()
+                fp.close()
+            except IOError, e:
+                if self.allow_empty:
+                    yield dict(_type=type_, _path=path)
+                continue
+
+            item = dict(
+                _type=type_,
+                _path=path,
+                _files={
+                    self.source: {'data': data}
+                }
+            )
+            yield item
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/blog.xml
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/blog.xml	(revision 359)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/blog.xml	(revision 359)
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?><metadata xmlns="http://plone.org/ns/archetypes/" xmlns:cmf="http://cmf.zope.org/namespaces/default/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="adobe:ns:meta">
+    <dc:title>
+        Test Blog
+    </dc:title>
+    <dc:description>
+        This is test blog.
+    </dc:description>
+    <xmp:CreateDate>
+        2005-08-29T11:32:01Z
+    </xmp:CreateDate>
+    <xmp:ModifyDate>
+        2006-04-26T11:04:31Z
+    </xmp:ModifyDate>
+    <field name="id">
+        blog
+    </field>
+    <field name="displayMode">
+        descriptionOnly
+    </field>
+    <field name="displayItems">
+        15
+    </field>
+    <field name="categories">
+        Zope
+    </field>
+    <field name="categories">
+        Plone
+    </field>
+    <field name="tags">
+        Python
+    </field>
+    <field name="tags">
+        Testing
+    </field>
+    <field name="tagsEnabled">
+        True
+    </field>
+    <cmf:type>
+        Blog
+    </cmf:type>
+</metadata>
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/folder.xml
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/folder.xml	(revision 359)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/folder.xml	(revision 359)
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?><metadata xmlns="http://plone.org/ns/archetypes/" xmlns:cmf="http://cmf.zope.org/namespaces/default/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="adobe:ns:meta">
+    <dc:title>
+        Blog folder
+    </dc:title>
+    <dc:description>
+        Folder in blog.
+    </dc:description>
+    <xmp:ModifyDate>
+        2005-11-04T11:31:06Z
+    </xmp:ModifyDate>
+    <field name="id">
+        folder
+    </field>
+    <field name="existingCats">
+        &lt;ul&gt;&lt;li&gt;Zope&lt;/li&gt;&lt;li&gt;Plone&lt;/li&gt;
+    </field>
+    <cmf:type>
+        BlogFolder
+    </cmf:type>
+</metadata>
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/root_entry.xml
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/root_entry.xml	(revision 359)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/root_entry.xml	(revision 359)
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?><metadata xmlns="http://plone.org/ns/archetypes/" xmlns:cmf="http://cmf.zope.org/namespaces/default/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xmp="adobe:ns:meta">
+    <dc:title>
+        Root entry
+    </dc:title>
+    <dc:description>
+        This entry was created in root of blog.
+    </dc:description>
+    <xmp:ModifyDate>
+        2007-11-14T10:32:11Z
+    </xmp:ModifyDate>
+    <field name="id">
+        root-entry
+    </field>
+    <field name="body">
+        &lt;p&gt;We are testing importing of blog entry.&lt;/p&gt;
+    </field>
+    <field name="categories">
+        Plone
+    </field>
+    <field name="categories">
+        Zope
+    </field>
+    <cmf:type>
+        BlogEntry
+    </cmf:type>
+    <cmf:workflow_history>
+        <cmf:workflow id="simpleblog_workflow">
+            <cmf:history>
+                <cmf:var id="action" type="None" value="None"/>
+                <cmf:var id="actor" type="str" value="admin"/>
+                <cmf:var id="comments" type="str" value=""/>
+                <cmf:var id="review_state" type="str" value="draft"/>
+                <cmf:var id="time" type="date" value="2007-11-06 05:25:51"/>
+            </cmf:history>
+            <cmf:history>
+                <cmf:var id="action" type="str" value="publish"/>
+                <cmf:var id="actor" type="str" value="admin"/>
+                <cmf:var id="comments" type="str" value=""/>
+                <cmf:var id="review_state" type="str" value="published"/>
+                <cmf:var id="time" type="date" value="2007-11-14 04:32:11"/>
+            </cmf:history>
+        </cmf:workflow>
+    </cmf:workflow_history>
+    <cmf:security>
+        <cmf:local_role role="Owner" user_id="admin"/>
+    </cmf:security>
+</metadata>
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/source.txt
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/source.txt	(revision 359)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/source.txt	(revision 359)
@@ -0,0 +1,53 @@
+Test source section
+===================
+
+>>> source = """
+... [transmogrifier]
+... pipeline =
+...     source
+...     printer
+... 
+... [source]
+... blueprint = quintagroup.transmogrifier.simpleblog2quills.tests.source
+... source = marshall
+... items =
+...     not-existing;       Document;   not-existing-path
+...     not-existing;       File;       /not/existing/absolute/path
+...     plone-blog;         Blog;       blog.xml
+... 
+... [printer]
+... blueprint = collective.transmogrifier.sections.tests.pprinter
+... """
+>>> registerConfig(u'quintagroup.transmogrifier.simpleblog2quills.tests.source', source)
+>>> transmogrifier(u'quintagroup.transmogrifier.simpleblog2quills.tests.source') # doctest: +ELLIPSIS, +REPORT_NDIFF
+{'_files': {'marshall': {'data': ...}},
+ '_path': 'plone-blog',
+ '_type': 'Blog'}
+
+Now we are testing ``allow-empty-items`` option:
+
+>>> source = """
+... [transmogrifier]
+... pipeline =
+...     source
+...     printer
+... 
+... [source]
+... blueprint = quintagroup.transmogrifier.simpleblog2quills.tests.source
+... allow-empty-items = yes
+... source = marshall
+... items =
+...     not-existing;       Document;   not-existing-path
+...     not-existing;       File;       /not/existing/absolute/path
+...     plone-blog;         Blog;       blog.xml
+... 
+... [printer]
+... blueprint = collective.transmogrifier.sections.tests.pprinter
+... """
+>>> registerConfig(u'quintagroup.transmogrifier.simpleblog2quills.tests.source-with-empties', source)
+>>> transmogrifier(u'quintagroup.transmogrifier.simpleblog2quills.tests.source-with-empties') # doctest: +ELLIPSIS, +REPORT_NDIFF
+{'_type': 'Document', '_path': 'not-existing'}
+{'_type': 'File', '_path': 'not-existing'}
+{'_files': {'marshall': {'data': ...}},
+ '_path': 'plone-blog',
+ '_type': 'Blog'}
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_base.py
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_base.py	(revision 359)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_base.py	(revision 359)
@@ -0,0 +1,23 @@
+import unittest
+
+from zope.testing import doctest, cleanup
+
+from Products.Five import zcml
+
+from collective.transmogrifier.tests import tearDown
+from quintagroup.transmogrifier.tests import sectionsSetUp
+
+import quintagroup.transmogrifier.simpleblog2quills.tests
+
+def sourceSetUp(test):
+    sectionsSetUp(test)
+    zcml.load_config('test_import.zcml', quintagroup.transmogrifier.simpleblog2quills.tests)
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTests((
+        doctest.DocFileSuite(
+            'source.txt',
+            setUp=sourceSetUp, tearDown=tearDown),
+    ))
+    return suite
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_import.cfg
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_import.cfg	(revision 359)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_import.cfg	(revision 359)
@@ -0,0 +1,34 @@
+[transmogrifier]
+pipeline =
+    source
+    substitution
+    constructor
+    xslt
+    datacorrector
+    demarshaller
+    referencesimporter
+include = quintagroup.transmogrifier:import.cfg
+
+[source]
+blueprint = quintagroup.transmogrifier.simpleblog2quills.tests.source
+source = marshall
+allow-empty-items = yes
+items =
+#   path;                        type;       file
+    blog;                        Blog;       blog.xml
+    blog/root-entry;             BlogEntry;  root_entry.xml
+    blog/folder;                 BlogFolder; folder.xml
+    blog/folder/folder-entry;    BlogEntry;  folder_entry.xml
+
+[substitution]
+blueprint = quintagroup.transmogrifier.substitution
+key = _type
+Blog = Weblog
+BlogEntry = WeblogEntry
+BlogFolder = Folder
+
+[xslt]
+blueprint = quintagroup.transmogrifier.xslt
+source = marshall
+from-key = _old_type
+to-key = _type
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_import.py
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_import.py	(revision 359)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_import.py	(revision 359)
@@ -0,0 +1,86 @@
+import unittest
+import os.path
+
+import transaction
+
+from Products.Five import zcml
+from Products.Five import fiveconfigure
+from Testing import ZopeTestCase as ztc
+
+from Products.PloneTestCase import PloneTestCase as ptc
+from Products.PloneTestCase.layer import onsetup
+
+from collective.transmogrifier.interfaces import ITransmogrifier
+
+ztc.installProduct('Quills')
+
+@onsetup
+def setup_product():
+    fiveconfigure.debug_mode = True
+    import Products.Five
+    zcml.load_config('configure.zcml', Products.Five)
+    import quintagroup.transmogrifier.simpleblog2quills
+    zcml.load_config('configure.zcml', quintagroup.transmogrifier.simpleblog2quills)
+    import quintagroup.transmogrifier.simpleblog2quills.tests
+    zcml.load_config('test_import.zcml', quintagroup.transmogrifier.simpleblog2quills.tests)
+    # this is needed because 'importStep' unknown directive error is raised somewhere
+    import Products.GenericSetup
+    zcml.load_config('meta.zcml', Products.GenericSetup)
+    import Products.Quills
+    zcml.load_config('configure.zcml', Products.Quills)
+    fiveconfigure.debug_mode = False
+
+setup_product()
+ptc.setupPloneSite(products=['Quills'])
+
+class TestImport(ptc.PloneTestCase):
+    """ Test importing of PloneFormGen content.
+    """
+
+    def afterSetUp(self):
+        self.addProduct('Quills')
+        if 'blog' not in self.portal:
+            # run transmogrifier pipeline
+            transmogrifier = ITransmogrifier(self.portal)
+            transmogrifier('test_import')
+
+    def beforeTearDown(self):
+        transaction.commit()
+
+    def test_site_structure(self):
+        self.failIf('blog' not in self.portal)
+        self.failIf('root-entry' not in self.portal.blog)
+        self.failIf('folder' not in self.portal.blog)
+        self.failIf('folder-entry' not in self.portal.blog.folder)
+
+    def test_blog(self):
+        blog = self.portal['blog']
+
+        self.assertEqual(blog.getPortalTypeName(), 'Weblog')
+        self.assertEqual(blog['title'], 'Test Blog')
+        self.assertEqual(blog.Description(), 'This is test blog.')
+
+    def test_blog_entry(self):
+        entry = self.portal['blog']['root-entry']
+
+        self.assertEqual(entry.getPortalTypeName(), 'WeblogEntry')
+        self.assertEqual(entry['title'], 'Root entry')
+        self.assertEqual(entry.Description(), 'This entry was created in root of blog.')
+        self.assertEqual(entry.getText(), '<p>We are testing importing of blog entry.</p>')
+        self.assertEqual(entry.Subject(), ('Plone', 'Zope'))
+        self.assertEqual(entry.modified().HTML4(), '2007-11-14T10:32:11Z')
+        # now workflow of WeblogEntry is assumed to be 'plone_workflow'
+        # but it must be configured in type configuration
+        self.failIf('plone_workflow' not in entry.workflow_history)
+
+    def test_blog_folder(self):
+        folder = self.portal['blog']['folder']
+
+        self.assertEqual(folder.getPortalTypeName(), 'Folder')
+        self.assertEqual(folder['title'], 'Blog folder')
+        self.assertEqual(folder.Description(), 'Folder in blog.')
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(TestImport))
+    return suite
Index: quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_import.zcml
===================================================================
--- quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_import.zcml	(revision 359)
+++ quintagroup.transmogrifier.simpleblog2quills/trunk/quintagroup/transmogrifier/simpleblog2quills/tests/test_import.zcml	(revision 359)
@@ -0,0 +1,17 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:transmogrifier="http://namespaces.plone.org/transmogrifier">
+
+    <utility
+        component=".base.Source"
+        name="quintagroup.transmogrifier.simpleblog2quills.tests.source"
+        />
+
+    <transmogrifier:registerConfig
+        name="test_import"
+        title="Import pipeline configuration"
+        description="Customized for SimpleBlog/Quills content types content import pipeline."
+        configuration="test_import.cfg"
+        />
+
+</configure>
