Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/__init__.py
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/__init__.py (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/__init__.py (revision 1498)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/__init__.py
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/__init__.py (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/__init__.py (revision 1498)
@@ -0,0 +1,1 @@
+# i'm a package
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/configure.zcml
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/configure.zcml (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/configure.zcml (revision 1498)
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/exporting.py
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/exporting.py (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/exporting.py (revision 1498)
@@ -0,0 +1,82 @@
+from xml.dom import minidom
+
+from zope.interface import Interface, implements
+
+from Products.Archetypes import atapi
+from Products.Marshall.config import AT_NS
+from Products.PageTemplates.TALES import CompilerError
+
+from quintagroup.transmogrifier.interfaces import IExportDataCorrector
+from quintagroup.transmogrifier.adapters.exporting import ReferenceExporter
+
+class IPloneFormMailer(Interface):
+ """ Marker interface for PloneFormMailer content type
+ """
+
+class PloneFormMailerExporter(ReferenceExporter):
+ """ Marshalls PloneFormMailer to XML.
+ """
+ implements(IExportDataCorrector)
+
+ def __init__(self, context):
+ self.context = context
+ self.tales_fnames = ['recipient_name', 'bcc_recipients', 'cc_recipients']
+ self.mail_subject_field = 'subject'
+
+ def __call__(self, data):
+ xml = data['data']
+ xml = self.exportReferences(xml)
+ data['data'] = self.exportFormFields(xml)
+ return data
+
+ def exportFormFields(self, data):
+ """ Reformat xml file and add Formulator fields.
+ """
+ # reformat xml tree
+ doc = minidom.parseString(data)
+ root = doc.documentElement
+
+ # some TALES fields must be exported as value of executed expression
+ schema = self.context.Schema()
+ for fname in self.tales_fnames:
+ nodes = [i for i in root.getElementsByTagName('field') if i.getAttribute('name') == fname]
+ for node in nodes:
+ root.removeChild(node)
+ # trying to get value of TALES field
+ # if expression can't be evaluated skip this field
+ try:
+ values = schema[fname].getAccessor(self.context)()
+ except CompilerError:
+ continue
+ if not isinstance(values, (list, tuple)):
+ values = [values]
+ values = filter(None, values)
+ for value in values:
+ node = doc.createElementNS(AT_NS, "field")
+ name_attr = doc.createAttribute("name")
+ name_attr.value = fname
+ node.setAttributeNode(name_attr)
+ value_node = doc.createTextNode(str(value))
+ node.appendChild(value_node)
+ node.normalize()
+ root.appendChild(node)
+
+ # PloneFormMailer overrides standard 'subject' schema field with it's own,
+ # which is a subject of a message. That's why it isn't exported as ''
+ # element (it is concerned with current implementation of Marshall's CMF namespaces
+ value = atapi.BaseObject.__getitem__(self.context, self.mail_subject_field)
+ if value:
+ node = doc.createElementNS(AT_NS, "field")
+ name_attr = doc.createAttribute("name")
+ name_attr.value = self.mail_subject_field
+ node.setAttributeNode(name_attr)
+ value_node = doc.createTextNode(str(value))
+ node.appendChild(value_node)
+ node.normalize()
+ root.appendChild(node)
+
+ # append form fields
+ fm_doc = minidom.parseString(self.context.form.get_xml())
+ root.appendChild(fm_doc.documentElement)
+
+ return doc.toxml('utf-8')
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formgen.zcml
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formgen.zcml (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formgen.zcml (revision 1498)
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formmailer-formfolder.xsl
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formmailer-formfolder.xsl (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formmailer-formfolder.xsl (revision 1498)
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ formPrologue
+
+
+
+
+
+
+ formEpilogue
+
+
+
+
+
+ thanksPageOverride
+
+
+
+
+
+ afterValidationOverride
+
+
+
+
+
+
+
+
+
+
+
+
+ FormFolder
+
+
+
+
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formmaileradapter.xsl
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formmaileradapter.xsl (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formmaileradapter.xsl (revision 1498)
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ recipientOverride
+
+
+
+
+
+
+ subjectOverride
+
+
+
+
+
+
+ body_type
+
+
+ plain
+
+
+ html
+
+
+ plain
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formthankspage.xsl
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formthankspage.xsl (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/formthankspage.xsl (revision 1498)
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ thanksPrologue
+
+
+
+
+
+
+
+
+
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/import.cfg
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/import.cfg (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/import.cfg (revision 1498)
@@ -0,0 +1,25 @@
+[transmogrifier]
+pipeline =
+ reader
+ manifestimporter
+ substitution
+ constructor
+ xslt
+ datacorrector
+ fileimporter
+ demarshaller
+ referencesimporter
+ propertiesimporter
+ commentsimporter
+ IMPORTING
+include = quintagroup.transmogrifier:import.cfg
+
+[substitution]
+blueprint = quintagroup.transmogrifier.substitution
+key = _type
+PloneFormMailer = FormFolder
+
+[xslt]
+blueprint = quintagroup.transmogrifier.xslt
+from-key = _old_type
+to-key = _type
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/importing.py
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/importing.py (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/importing.py (revision 1498)
@@ -0,0 +1,522 @@
+import logging
+import os.path
+from xml.dom import minidom
+from DateTime import DateTime
+
+from zope.interface import implements, Interface
+from zope.component import getUtility
+
+from ZODB.POSException import ConflictError
+from Acquisition import aq_inner, aq_parent
+
+from Products.Marshall.registry import getComponent
+from Products.Marshall.config import AT_NS
+from Products.CMFPlone.utils import _createObjectByType
+
+from quintagroup.transmogrifier.interfaces import IImportDataCorrector
+from quintagroup.transmogrifier.adapters.importing import ReferenceImporter
+from quintagroup.transmogrifier.xslt import XSLTSection
+
+BOOL_FIELD_PROPS = ['enabled', 'required', 'hidden']
+
+FIELD_MAP = {
+ 'StringField' : 'FormStringField',
+ 'EmailField' : ('FormStringField', {'fgStringValidator': 'isEmail'}),
+ 'LinkField' : ('FormStringField', {'fgStringValidator': 'isURL'}),
+ 'PatternField' : 'FormStringField',
+
+ 'TextAreaField' : 'FormTextField',
+ 'RawTextAreaField': 'FormTextField',
+
+ 'PasswordField' : 'FormPasswordField',
+ 'LabelField' : 'FormRichLabelField', #FormLabelField
+
+ 'IntegerField' : 'FormIntegerField',
+ 'FloatField' : 'FormFixedPointField',
+
+ 'DateTimeField' : 'FormDateField',
+ 'FileField' : 'FormFileField',
+
+ 'LinesField' : 'FormLinesField',
+
+ 'CheckBoxField' : 'FormBooleanField',
+ 'ListField' : ('FormSelectionField', {'fgFormat': 'select'}),
+ 'RadioField' : ('FormSelectionField', {'fgFormat': 'radio'}),
+ 'MultiListField': ('FormMultiSelectionField', {'fgFormat': 'select'}),
+ 'MultiCheckBoxField':('FormMultiSelectionField', {'fgFormat': 'checkbox'}),
+ }
+
+class IXMLDemarshaller(Interface):
+ """
+ """
+ def demarshall(obj, data):
+ """
+ """
+
+class FormFolderImporter(ReferenceImporter):
+ """ Demarshaller of PloneFormGen's FormFolder content type.
+ """
+ implements(IImportDataCorrector)
+
+ def __init__(self, context, transmogrifier):
+ self.context = context
+ self.demarshaller = getComponent("atxml")
+ self.auto_added_fgfields = ['replyto', 'topic', 'comments']
+ self.date_fields = {}
+
+ def __call__(self, data):
+ data = super(FormFolderImporter, self).__call__(data)
+ xml = data['data']
+ data['data'] = self.transformWithMinidom(xml)
+
+ # update FormMailerAdapter and FormThanksPage objects
+ cleaned_xml = self.updateMailer(xml)
+
+ self.updateResponsePage(cleaned_xml)
+
+ self.updateFormFields(xml)
+
+ return data
+
+ def transformWithMinidom(self, xml):
+ """ Do some extra transformations on xml document (that can be done by XSLT).
+ """
+ doc = minidom.parseString(xml)
+ root = doc.documentElement
+
+ # get 'modification_date' and 'creation_date' for next usage when creating fields
+ for i in root.getElementsByTagName('xmp:CreateDate'):
+ self.date_fields['creation_date'] = i.firstChild.nodeValue.strip()
+ for i in root.getElementsByTagName('xmp:ModifyDate'):
+ self.date_fields['modification_date'] = i.firstChild.nodeValue.strip()
+
+ # xxx: update button labels (those elements are now skiped by xslt)
+ # PFM has only one field 'form_buttons', but PFG has two: 'submitLabel', 'resetLabel' and
+ # field 'useCancelButton'
+
+ # add element for setting of 'thanksPage' field to 'thank-you' FormThanksPage
+ elem = doc.createElementNS(AT_NS, "field")
+ name_attr = doc.createAttribute("name")
+ name_attr.value = 'thanksPage'
+ elem.setAttributeNode(name_attr)
+ value = doc.createTextNode('thank-you')
+ elem.appendChild(value)
+ root.appendChild(elem)
+
+ # update 'thanksPageOverride' field
+ elem = [i for i in doc.getElementsByTagName('field') if i.getAttribute('name') == 'thanksPageOverride']
+ if elem:
+ elem = elem[0]
+ old_text = elem.firstChild
+ new_text = doc.createTextNode('redirect_to:' + old_text.nodeValue.strip())
+ elem.removeChild(old_text)
+ elem.appendChild(new_text)
+
+ # xxx: update 'afterValidationOverride' field
+ # 'afterValidationOverride' is TALES expression, but PFM's 'cpyaction' is name
+ # of controller python script
+ elem = [i for i in doc.getElementsByTagName('field')
+ if i.getAttribute('name') == 'afterValidationOverride']
+ if elem:
+ elem = elem[0]
+ old_text = elem.firstChild
+ new_text = doc.createTextNode('string:' + old_text.nodeValue.strip())
+ elem.removeChild(old_text)
+ elem.appendChild(new_text)
+
+ # xxx: update 'onDisplayOverride' field (this element is now skiped by xslt)
+ # 'onDisplayOverride' is TALES expression, but PFM's 'before_script' is python script
+ # in 'scripts' subfolder
+
+ return doc.toxml('utf-8')
+
+ def updateMailer(self, xml):
+ mailer = self.context['mailer']
+ transformed = self.transformWithXSLT(xml, 'FormMailerAdapter')
+ self.demarshaller.demarshall(mailer, transformed)
+ mailer.indexObject()
+ return transformed
+
+ def updateResponsePage(self, xml):
+ page = self.context['thank-you']
+ transformed = self.transformWithXSLT(xml, 'FormThanksPage')
+ self.demarshaller.demarshall(page, transformed)
+ # override default value of description field
+ page.getField('description').getMutator(page)('')
+ page.indexObject()
+ return transformed
+
+ def transformWithXSLT(self, xml, to):
+ """ Apply XSLT transformations using XSLT transmogrifier section.
+ """
+ item = dict(
+ _from='PloneFormMailer',
+ _to=to,
+ _files=dict(
+ marshall=dict(
+ name='.marshall.xml',
+ data=xml
+ )
+ )
+ )
+ section = XSLTSection(object(), 'xslt', {'blueprint': ''}, iter((item,)))
+ for i in section: pass
+ return item['_files']['marshall']['data']
+
+ def updateFormFields(self, data):
+ """ Walk trough xml tree and create fields in FormFolder.
+ """
+ # delete fields that were added on FormFolder creation
+ for oid in [i for i in self.auto_added_fgfields if i in self.context]:
+ self.context._delObject(oid)
+
+ doc = minidom.parseString(data)
+ root = doc.documentElement
+ form_element = root.getElementsByTagName('form')
+ if not form_element:
+ return
+ groups = form_element[0].getElementsByTagName('group')
+ for group in groups:
+ group_title = group.getElementsByTagName('title')[0]
+ group_title = str(group_title.firstChild.nodeValue).strip()
+ if group_title == 'Default':
+ for field in group.getElementsByTagName('field'):
+ field_id = str(field.getElementsByTagName('id')[0].firstChild.nodeValue).strip()
+ field_type = str(field.getElementsByTagName('type')[0].firstChild.nodeValue).strip()
+ self.createField(field_type, field_id, field, self.context)
+ else:
+ fieldset = self.createFieldset(group_title)
+ if not fieldset:
+ return
+ for field in group.getElementsByTagName('field'):
+ field_id = str(field.getElementsByTagName('id')[0].firstChild.nodeValue).strip()
+ field_type = str(field.getElementsByTagName('type')[0].firstChild.nodeValue).strip()
+ self.createField(field_type, field_id, field, fieldset)
+
+ def createField(self, type_name, field_id, field_node, context=None):
+ """ Created formfield and update it from field_node's xml tree.
+
+ Use demarshalling adapter.
+ """
+ if FIELD_MAP.get(type_name) is None:
+ return
+
+ if isinstance(FIELD_MAP[type_name], tuple):
+ type_name, options = FIELD_MAP[type_name]
+ else:
+ type_name, options = FIELD_MAP[type_name], {}
+ # update options with 'creation_date' and 'modification_date', that are
+ # the same as in FormFolder (dates on fields must be the same)
+ options.update(self.date_fields)
+
+ if field_id not in context.contentIds():
+ try:
+ field = _createObjectByType(type_name, context, field_id)
+ except ConflictError:
+ raise
+ except:
+ return
+ else:
+ field = context._getOb(field_id)
+
+ try:
+ IXMLDemarshaller(field).demarshall(field_node, **options)
+ except ConflictError:
+ raise
+
+ def createFieldset(self, title):
+ """ Create FieldsetFolder with id=title
+ """
+ if title not in self.context.contentIds():
+ try:
+ fieldset = _createObjectByType('FieldsetFolder', self.context, title)
+ except ConflictError:
+ raise
+ except:
+ return
+ else:
+ fieldset = self.context._getOb(title)
+ fieldset.Schema()['title'].getMutator(fieldset)(title)
+
+ return fieldset
+
+class BaseFieldDemarshaller(object):
+ """ Base class for demarshallers of PloneFormGen's fields from PloneFormMailer fields.
+ """
+ implements(IXMLDemarshaller)
+
+ def __init__(self, context):
+ self.context = context
+
+ def demarshall(self, node, **kw):
+ self.extractData(node)
+ # update data dictionary form keyword arguments
+ for k, v in kw.items():
+ self.data[k] = v
+ # call special hook for changing data
+ self.modifyData()
+
+ # update instance
+ schema = self.context.Schema()
+ for fname, value in self.data.items():
+ if not schema.has_key(fname):
+ continue
+ mutator = schema[fname].getMutator(self.context)
+ if not mutator:
+ continue
+ mutator(value)
+
+ self.context.indexObject()
+
+ def extractData(self, node):
+ tree = XMLObject()
+ elementToObject(tree, node)
+ simplify_single_entries(tree)
+
+ data = {}
+ values = tree.first.field.first.values
+ for name in values.getElementNames():
+ value = getattr(values.first, name)
+ if value.attributes.get('type') == 'float':
+ data[name] = float(value.text)
+ elif value.attributes.get('type') == 'int':
+ data[name] = int(value.text)
+ # boolean property is exported as int, fix that
+ if name in BOOL_FIELD_PROPS:
+ data[name] = bool(data[name])
+ elif value.attributes.get('type') == 'list':
+ # XXX bare eval here (this may be a security leak ?)
+ data[name] = eval(str(value.text))
+ elif value.attributes.get('type') == 'datetime':
+ data[name] = DateTime(value.text)
+ else:
+ data[name] = str(value.text)
+
+ # get tales expressions
+ tales = tree.first.field.first.tales
+ for name in tales.getElementNames():
+ value = getattr(tales.first, name)
+ data["tales:"+name] = str(value.text)
+
+ self.data = data
+
+ def modifyData(self):
+ pass
+
+ def renameEntry(self, old, new):
+ if self.data.has_key(old):
+ self.data[new] = self.data.pop(old)
+
+ def entryIsDigit(self, key):
+ """ Formulator exports empty fields in xml as empty elements without
+ 'type' attribute. That's is why we get in data dictionary for
+ integer fields values that are empty strings. This method is
+ used to check whether integer field has integer value.
+ """
+ if key in self.data and isinstance(self.data[key], int):
+ return True
+ else:
+ return False
+
+class StringFieldDemarshaller(BaseFieldDemarshaller):
+ """ Demarshaller of StringField and other fields of this kind.
+ """
+
+ def modifyData(self):
+ self.renameEntry('default', 'fgDefault')
+ if self.entryIsDigit('display_maxwidth'):
+ self.renameEntry('display_maxwidth', 'fgmaxlength')
+ if self.entryIsDigit('display_width'):
+ self.renameEntry('display_width', 'fgsize')
+
+class TextFieldDemarshaller(BaseFieldDemarshaller):
+ """ Demarshaller of TextField.
+ """
+
+ def modifyData(self):
+ self.renameEntry('default', 'fgDefault')
+ if self.entryIsDigit('max_length'):
+ self.renameEntry('max_length', 'fgmaxlength')
+ if self.entryIsDigit('height'):
+ self.renameEntry('height', 'fgRows')
+
+class LabelFieldDemarshaller(BaseFieldDemarshaller):
+ """ Demarshaller of LabelField.
+ """
+
+ def modifyData(self):
+ self.renameEntry('default', 'fgDefault')
+
+class IntegerFieldDemarshaller(BaseFieldDemarshaller):
+ """ Demarshaller of IntegerField.
+ """
+
+ def modifyData(self):
+ self.renameEntry('default', 'fgDefault')
+ if self.entryIsDigit('display_maxwidth'):
+ self.renameEntry('display_maxwidth', 'fgmaxlength')
+ if self.entryIsDigit('display_width'):
+ self.renameEntry('display_width', 'fgsize')
+ if self.entryIsDigit('start'):
+ self.renameEntry('start', 'minval')
+ if self.entryIsDigit('end'):
+ self.renameEntry('end', 'maxval')
+
+class DateTimeFieldDemarshaller(BaseFieldDemarshaller):
+ """ Demarshaller of DateTimeField.
+ """
+
+ def modifyData(self):
+ if 'default' in self.data:
+ # convert from DateTime object to string
+ self.data['default'] = str(self.data['default'])
+ self.renameEntry('default', 'fgDefault')
+ # date_only is boolean flag
+ self.data['fgShowHM'] = not bool(self.data['date_only'])
+ if 'start_datetime' in self.data:
+ self.data['start_datetime'] = self.data['start_datetime'].year()
+ self.renameEntry('start_datetime', 'fgStartingYear')
+ if 'end_datetime' in self.data:
+ self.data['end_datetime'] = self.data['end_datetime'].year()
+ self.renameEntry('end_datetime', 'fgEndingYear')
+
+class LinesFieldDemarshaller(BaseFieldDemarshaller):
+ """ Demarshaller of LinesField.
+ """
+
+ def modifyData(self):
+ self.renameEntry('default', 'fgDefault')
+ if self.entryIsDigit('height'):
+ self.renameEntry('height', 'fgRows')
+
+class BooleanFieldDemarshaller(BaseFieldDemarshaller):
+ """ Demarshaller of BooleanField.
+ """
+
+ def modifyData(self):
+ self.data['default'] = bool(self.data['default'])
+ self.renameEntry('default', 'fgDefault')
+
+
+class SelectionFieldDemarshaller(BaseFieldDemarshaller):
+ """ Demarshaller of SelectionField.
+ """
+
+ def modifyData(self):
+ self.renameEntry('default', 'fgDefault')
+ l = []
+ for i in self.data['items']:
+ i = list(i)
+ i.reverse()
+ l.append(i)
+ self.data['items'] = ['|'.join(i) for i in l]
+ self.renameEntry('items', 'fgVocabulary')
+
+class MultiSelectFieldDemarshaller(SelectionFieldDemarshaller):
+ """ Demarshaller of MultiSelectField.
+ """
+
+ def modifyData(self):
+ super(MultiSelectFieldDemarshaller, self).modifyData()
+ if self.entryIsDigit('size'):
+ self.renameEntry('size', 'fgRows')
+
+
+# next code was stolen from Formulator product
+from xml.dom.minidom import parse, parseString, Node
+
+# an extremely simple system for loading in XML into objects
+
+class Object:
+ pass
+
+class XMLObject:
+ def __init__(self):
+ self.elements = Object()
+ self.first = Object()
+ self.attributes = {}
+ self.text = ''
+
+ def getElementNames(self):
+ return [element for element in dir(self.elements)
+ if not element.startswith('__')]
+
+ def getAttributes(self):
+ return self.attributes
+
+def elementToObject(parent, node):
+ # create an object to represent element node
+ object = XMLObject()
+ # make object attributes off node attributes
+ for key, value in node.attributes.items():
+ object.attributes[key] = value
+ # make lists of child elements (or ignore them)
+ for child in node.childNodes:
+ nodeToObject(object, child)
+ # add ourselves to parent node
+ name = str(node.nodeName)
+ l = getattr(parent.elements, name, [])
+ l.append(object)
+ setattr(parent.elements, name, l)
+
+def attributeToObject(parent, node):
+ # should never be called
+ pass
+
+def textToObject(parent, node):
+ # add this text to parents text content
+ parent.text += node.data
+
+def processingInstructionToObject(parent, node):
+ # don't do anything with these
+ pass
+
+def commentToObject(parent, node):
+ # don't do anything with these
+ pass
+
+def documentToObject(parent, node):
+ elementToObject(parent, node.documentElement)
+
+def documentTypeToObject(parent, node):
+ # don't do anything with these
+ pass
+
+_map = {
+ Node.ELEMENT_NODE: elementToObject,
+ Node.ATTRIBUTE_NODE: attributeToObject,
+ Node.TEXT_NODE: textToObject,
+ # Node.CDATA_SECTION_NODE:
+ # Node.ENTITY_NODE:
+ Node.PROCESSING_INSTRUCTION_NODE: processingInstructionToObject,
+ Node.COMMENT_NODE: commentToObject,
+ Node.DOCUMENT_NODE: documentToObject,
+ Node.DOCUMENT_TYPE_NODE: documentTypeToObject,
+# Node.NOTATION_NODE:
+ }
+
+def nodeToObject(parent, node):
+ _map[node.nodeType](parent, node)
+
+def simplify_single_entries(object):
+ for name in object.getElementNames():
+ l = getattr(object.elements, name)
+ # set the first subelement (in case it's just one, this is easy)
+ setattr(object.first, name, l[0])
+ # now do the same for rest
+ for element in l:
+ simplify_single_entries(element)
+
+def XMLToObjectsFromFile(path):
+ return XMLToObjects(parse(path))
+
+def XMLToObjectsFromString(s):
+ return XMLToObjects(parseString(s))
+
+def XMLToObjects(document):
+ object = XMLObject()
+ documentToObject(object, document)
+ document.unlink()
+ simplify_single_entries(object)
+ return object
+
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/overrides.zcml
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/overrides.zcml (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/overrides.zcml (revision 1498)
@@ -0,0 +1,12 @@
+
+
+
+
+
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/__init__.py
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/__init__.py (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/__init__.py (revision 1498)
@@ -0,0 +1,1 @@
+# i'm a package
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/complex_form.xml
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/complex_form.xml (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/complex_form.xml (revision 1498)
@@ -0,0 +1,646 @@
+
+
+
+ Test form
+
+
+ admin
+
+
+ 2007-05-15T08:41:51Z
+
+
+ 2007-12-04T09:25:47Z
+
+
+ complex-form
+
+
+ None
+
+
+ 2007/12/04 03:25:47.294 US/Central
+
+
+ string:Test form submit
+
+
+ Test
+
+
+ string:recipient@mail.org
+
+
+ cc1@mail.org
+
+
+ cc2@mail.org
+
+
+ bcc1@mail.org
+
+
+ bcc2@mail.org
+
+
+ Header1: value1
+
+
+ Header2: value2
+
+
+ Next are input fields
+
+
+ You have filled all necessary fields
+
+
+ It's built on Plone
+
+
+ <tal:block i18n:domain="pfm"
+ tal:define="form here/form;
+ groups form/get_groups;">
+<html>
+<body style="font-family:verdana,sans-serif;">
+<p tal:condition="here/getBodyPre" tal:content="here/getBodyPre" />
+<p tal:condition="options/prepend" tal:content="options/prepend" />
+
+<tal:block tal:repeat="group groups">
+ <h1 tal:condition="python:group!='Default'" tal:content="group" />
+ <table style="font-family:verdana,sans-serif;">
+ <tbody valign="top">
+ <tal:block tal:repeat="field python:form.get_fields_in_group(group)">
+ <tr>
+ <th i18n:translate="" style="text-align:right; white-space: nowrap; border-bottom: 1px solid #cccccc;" tal:content="field/title" />
+ <td>
+ <div tal:repeat="line field/mailsplitter">
+ <span tal:content="line"/>
+ </div>
+ </td>
+ </tr>
+ </tal:block>
+ </tbody>
+ </table>
+</tal:block>
+
+<p tal:condition="options/append" tal:content="options/append" />
+<p tal:condition="here/getBodyPost" tal:content="here/getBodyPost" />
+<pre tal:content="here/getFooter" />
+</body>
+</html>
+</tal:block>
+
+
+ text/html
+
+
+
+<p>form prologue</p>
+
+
+
+
+<p>form epilogue</p>
+
+
+
+ Submit|submit|submit|context
+
+
+ Reset|reset|reset|standalone
+
+
+ The form was sent.
+
+
+
+ <p>Thank you for submiting it.<br /></p>
+
+
+
+ string:test
+
+
+ script
+
+
+ 738f9995ffd82394ff8a3fb75450c354
+
+
+ PloneFormMailer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/fieldset_form.xml
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/fieldset_form.xml (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/fieldset_form.xml (revision 1498)
@@ -0,0 +1,159 @@
+
+
+
+
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_export.py
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_export.py (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_export.py (revision 1498)
@@ -0,0 +1,107 @@
+import time
+import unittest
+from xml.dom import minidom
+
+from Testing import ZopeTestCase
+from Products.CMFPlone.tests.PloneTestCase import PloneTestCase
+from Products.Marshall.registry import getComponent
+
+try:
+ import Products.PloneFormMailer
+ HAS_PFM = True
+except ImportError:
+ HAS_PFM = False
+
+# next condition is required, because a test preparation
+# raises errors on Plone 3+
+if HAS_PFM:
+ from quintagroup.transmogrify.pfm2pfg.exporting import PloneFormMailerExporter
+
+ ZopeTestCase.installProduct('Formulator')
+ ZopeTestCase.installProduct('MimetypesRegistry')
+ ZopeTestCase.installProduct('PortalTransforms')
+ ZopeTestCase.installProduct('Archetypes')
+ ZopeTestCase.installProduct('PloneFormMailer')
+ ZopeTestCase.installProduct('TALESField')
+
+ def setupPloneFormMailerTestCase(app, quiet=0):
+ get_transaction().begin()
+ _start = time.time()
+ if not quiet:
+ ZopeTestCase._print('Adding PloneFormMailer ... ')
+ app.portal.portal_quickinstaller.installProduct('PloneFormMailer')
+ get_transaction().commit()
+ if not quiet:
+ ZopeTestCase._print('done (%.3fs)\n' % (time.time()-_start,))
+
+ app = ZopeTestCase.app()
+ setupPloneFormMailerTestCase(app, quiet=True)
+ ZopeTestCase.close(app)
+
+class TestExport(PloneTestCase):
+ """Test case for proping up a test portal."""
+ def afterSetUp(self):
+ self.loginPortalOwner()
+ self.portal.invokeFactory('PloneFormMailer', id='form')
+ form = self.portal.form
+ ['recipient_name', 'bcc_recipients', 'cc_recipients']
+ form.setRecipientName("string:Recipient")
+ form.setCCRecipients([
+ 'string:cc1@mail.org',
+ 'string:cc2@mail.org'
+ ])
+ form.setBCCRecipients([
+ 'string:bcc1@mail.org',
+ 'string:bcc2@mail.org'
+ ])
+ form.setSubject('string:Email subject')
+
+ def _testField(self, xml, name, values):
+ """ Check whether marshalled in xml format field has some values.
+ """
+ doc = minidom.parseString(xml)
+ elems = [i for i in doc.getElementsByTagName('field') if i.getAttribute('name') == name]
+ if type(values) not in (list, tuple):
+ values = [values]
+ fields = []
+ for i in elems:
+ fields.append(i.firstChild.nodeValue.strip())
+ return values == fields
+
+ def test_data_corrector(self):
+ _, _, xml = getComponent('atxml').marshall(self.portal.form)
+ data = {'name': '', 'data': xml}
+ #import pdb; pdb.set_trace()
+ adapter = PloneFormMailerExporter(self.portal.form)
+ adapter(data)
+ xml = data['data']
+ self.assertEqual(self._testField(xml, 'recipient_name', 'Recipient'), True)
+ self.assertEqual(
+ self._testField(xml,
+ 'cc_recipients',
+ ['cc1@mail.org', 'cc2@mail.org']),
+ True
+ )
+ self.assertEqual(
+ self._testField(xml,
+ 'bcc_recipients',
+ ['bcc1@mail.org', 'bcc2@mail.org']),
+ True
+ )
+ self.assertEqual(self._testField(xml, 'subject', 'string:Email subject'), True)
+
+ def test_bad_tales_field(self):
+ self.portal.form.setRecipientName("bad tales expression")
+ _, _, xml = getComponent('atxml').marshall(self.portal.form)
+ data = {'name': '', 'data': xml}
+ #import pdb; pdb.set_trace()
+ adapter = PloneFormMailerExporter(self.portal.form)
+ adapter(data)
+ xml = data['data']
+ #import pdb; pdb.set_trace()
+ self.assertEqual(self._testField(xml, 'recipient_name', 'bad tales expression'), False)
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(TestExport))
+ return suite
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_import.cfg
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_import.cfg (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_import.cfg (revision 1498)
@@ -0,0 +1,23 @@
+[transmogrifier]
+pipeline =
+ source
+ substitution
+ constructor
+ xslt
+ datacorrector
+ demarshaller
+ referencesimporter
+include = quintagroup.transmogrifier:import.cfg
+
+[source]
+blueprint = quintagroup.transmogrify.pfm2pfg.tests.source
+
+[substitution]
+blueprint = quintagroup.transmogrifier.substitution
+key = _type
+PloneFormMailer = FormFolder
+
+[xslt]
+blueprint = quintagroup.transmogrifier.xslt
+from-key = _old_type
+to-key = _type
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_import.py
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_import.py (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_import.py (revision 1498)
@@ -0,0 +1,455 @@
+import unittest
+import os.path
+import email
+
+from zope.interface import classProvides, implements
+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 ISectionBlueprint, ISection, ITransmogrifier
+
+class Source(object):
+ classProvides(ISectionBlueprint)
+ implements(ISection)
+
+ def __init__(self, transmogrifier, name, options, previous):
+ self.previous = previous
+
+ def __iter__(self):
+ for item in self.previous:
+ yield item
+
+ fname = os.path.join(os.path.dirname(__file__), 'complex_form.xml')
+ xml = file(fname).read()
+ item = dict(
+ _type='PloneFormMailer',
+ _path='complex-form',
+ _files=dict(
+ marshall=dict(
+ name='.marshall.xml',
+ data=xml
+ )
+ )
+ )
+ yield item
+
+ fname = os.path.join(os.path.dirname(__file__), 'fieldset_form.xml')
+ xml = file(fname).read()
+ item = dict(
+ _type='PloneFormMailer',
+ _path='fieldset-form',
+ _files=dict(
+ marshall=dict(
+ name='.marshall.xml',
+ data=xml
+ )
+ )
+ )
+ yield item
+
+ztc.installProduct('PloneFormGen')
+
+@onsetup
+def setup_product():
+ fiveconfigure.debug_mode = True
+ import quintagroup.transmogrify.pfm2pfg
+ zcml.load_config('configure.zcml', quintagroup.transmogrify.pfm2pfg)
+ import quintagroup.transmogrify.pfm2pfg.tests
+ zcml.load_config('test_import.zcml', quintagroup.transmogrify.pfm2pfg.tests)
+ fiveconfigure.debug_mode = False
+
+setup_product()
+ptc.setupPloneSite(products=['PloneFormGen'])
+
+class TestImport(ptc.PloneTestCase):
+ """ Test importing of PloneFormGen content.
+ """
+
+ def afterSetUp(self):
+ if 'complex-form' not in self.portal:
+ # run transmogrifier pipeline
+ transmogrifier = ITransmogrifier(self.portal)
+ transmogrifier('test_import')
+
+ def beforeTearDown(self):
+ transaction.commit()
+
+ def test_form_folder(self):
+ self.failUnless('complex-form' in self.portal)
+ form = self.portal['complex-form']
+
+ self.assertEqual(form['title'], 'Test form')
+ self.assertEqual(form.getFormPrologue(), '
form prologue
')
+ self.assertEqual(form.getFormEpilogue(), 'form epilogue
')
+ self.assertEqual(form['thanksPageOverride'], 'redirect_to:string:test')
+ self.assertEqual(form['afterValidationOverride'], 'string:script')
+
+ def test_mailer(self):
+ form = self.portal['complex-form']
+ self.failUnless('mailer' in form)
+ mailer = form['mailer']
+
+ self.assertEqual(mailer['subjectOverride'], 'string:Test form submit')
+ self.assertEqual(mailer['recipient_name'], 'Test')
+ self.assertEqual(mailer['recipientOverride'], 'string:recipient@mail.org')
+ self.assertEqual(mailer['additional_headers'], ('Header1: value1', 'Header2: value2'))
+ self.assertEqual(mailer['body_type'], 'html')
+ self.assertEqual(mailer.getBody_pre(), 'Next are input fields')
+ self.assertEqual(mailer.getBody_post(), 'You have filled all necessary fields')
+ self.assertEqual(mailer.getBody_footer(), 'It\'s built on Plone')
+ self.assertEqual(mailer['cc_recipients'], ('cc1@mail.org', 'cc2@mail.org'))
+ self.assertEqual(mailer['bcc_recipients'], ('bcc1@mail.org', 'bcc2@mail.org'))
+
+ self.assertEqual(mailer.created(), form.created())
+ self.assertEqual(mailer.modified(), form.modified())
+
+ def test_thanks_page(self):
+ form = self.portal['complex-form']
+ self.failUnless('thank-you' in form)
+ page = form['thank-you']
+
+ self.assertEqual(page.Title(), 'The form was sent.')
+ self.assertEqual(page.getThanksPrologue(),
+ 'Thank you for submiting it.
')
+
+ self.assertEqual(page.created(), form.created())
+ self.assertEqual(page.modified(), form.modified())
+
+ def test_string_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field1' not in form)
+ field = form['field1']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormStringField')
+ self.assertEqual(field['title'], 'String field')
+ self.assertEqual(field.Description(), 'field description')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['hidden'], False)
+ self.assertEqual(field['fgDefault'], '')
+ self.assertEqual(field['fgmaxlength'], 255)
+ self.assertEqual(field['fgsize'], 20)
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_email_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field2' not in form)
+ field = form['field2']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormStringField')
+ self.assertEqual(field['title'], 'Email field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['hidden'], False)
+ self.assertEqual(field['fgDefault'], 'test@mail.com')
+ self.assertEqual(field['fgmaxlength'], 255)
+ self.assertEqual(field['fgsize'], 20)
+ self.assertEqual(field['fgStringValidator'], 'isEmail')
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_link_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field3' not in form)
+ field = form['field3']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormStringField')
+ self.assertEqual(field['title'], 'Link field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], False)
+ self.assertEqual(field['hidden'], False)
+ self.assertEqual(field['fgDefault'], '')
+ self.assertEqual(field['fgmaxlength'], 15)
+ self.assertEqual(field['fgsize'], 20)
+ self.assertEqual(field['fgStringValidator'], 'isURL')
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_pattern_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field4' not in form)
+ field = form['field4']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormStringField')
+ self.assertEqual(field['title'], 'Pattern field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['hidden'], True)
+ self.assertEqual(field['fgDefault'], '')
+ self.assertEqual(field['fgmaxlength'], 255)
+ self.assertEqual(field['fgsize'], 20)
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_textarea_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field5' not in form)
+ field = form['field5']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormTextField')
+ self.assertEqual(field['title'], 'Text area field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['hidden'], False)
+ self.assertEqual(field.getFgDefault(), '')
+ self.assertEqual(field['fgmaxlength'], 1000)
+ self.assertEqual(field['fgRows'], 5)
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_rawtextarea_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field6' not in form)
+ field = form['field6']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormTextField')
+ self.assertEqual(field['title'], 'Raw text area field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['hidden'], False)
+ self.assertEqual(field.getFgDefault(), '')
+ self.assertEqual(field['fgmaxlength'], '0')
+ self.assertEqual(field['fgRows'], 5)
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_password_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field7' not in form)
+ field = form['field7']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormPasswordField')
+ self.assertEqual(field['title'], 'Password field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['fgDefault'], '')
+ self.assertEqual(field['fgmaxlength'], 255)
+ self.assertEqual(field['fgsize'], 20)
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_label_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field8' not in form)
+ field = form['field8']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormRichLabelField')
+ self.assertEqual(field['title'], 'Label field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['fgDefault'], 'label text')
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_integer_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field9' not in form)
+ field = form['field9']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormIntegerField')
+ self.assertEqual(field['title'], 'Integer field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['fgDefault'], '55')
+ self.assertEqual(field['fgmaxlength'], 40)
+ self.assertEqual(field['fgsize'], 20)
+ self.assertEqual(field['minval'], 10)
+ self.assertEqual(field['maxval'], 1000)
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_float_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field10' not in form)
+ field = form['field10']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormFixedPointField')
+ self.assertEqual(field['title'], 'Float field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['fgDefault'], '')
+ self.assertEqual(field['fgmaxlength'], 10)
+ self.assertEqual(field['fgsize'], 20)
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_datetime_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field11' not in form)
+ field = form['field11']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormDateField')
+ self.assertEqual(field['title'], 'Date time field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['fgDefault'], '2008/10/10 10:10:00 GMT+3')
+ self.assertEqual(field['fgStartingYear'], 2006)
+ self.assertEqual(field['fgEndingYear'], 2010)
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_file_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field12' not in form)
+ field = form['field12']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormFileField')
+ self.assertEqual(field['title'], 'File field')
+ self.assertEqual(field.Description(), '')
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_lines_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field13' not in form)
+ field = form['field13']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormLinesField')
+ self.assertEqual(field['title'], 'Lines field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['fgDefault'], ('first', 'second', 'third'))
+ self.assertEqual(field['fgRows'], 5)
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_checkbox_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field14' not in form)
+ field = form['field14']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormBooleanField')
+ self.assertEqual(field['title'], 'Checkbox field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['fgDefault'], True)
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_list_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field15' not in form)
+ field = form['field15']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormSelectionField')
+ self.assertEqual(field['title'], 'List field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['fgDefault'], 'first')
+ self.assertEqual(field['fgVocabulary'], ('first|First', 'second|Second', 'third|Third'))
+ self.assertEqual(field['fgFormat'], 'select')
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_radio_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field16' not in form)
+ field = form['field16']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormSelectionField')
+ self.assertEqual(field['title'], 'Radio field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['fgDefault'], 'first')
+ self.assertEqual(field['fgVocabulary'], ('first|First', 'second|Second', 'third|Third'))
+ self.assertEqual(field['fgFormat'], 'radio')
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_multilist_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field17' not in form)
+ field = form['field17']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormMultiSelectionField')
+ self.assertEqual(field['title'], 'Multi list field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['fgDefault'], ('first', 'third'))
+ self.assertEqual(field['fgVocabulary'], ('first|First', 'second|Second', 'third|Third'))
+ self.assertEqual(field['fgFormat'], 'select')
+ self.assertEqual(field['fgRows'], 5)
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_multicheckbox_field(self):
+ form = self.portal['complex-form']
+ self.failIf('field18' not in form)
+ field = form['field18']
+
+ self.assertEqual(field.getPortalTypeName(), 'FormMultiSelectionField')
+ self.assertEqual(field['title'], 'Multi checkbox field')
+ self.assertEqual(field.Description(), '')
+ self.assertEqual(field['required'], True)
+ self.assertEqual(field['fgDefault'], ('first', 'third'))
+ self.assertEqual(field['fgVocabulary'], ('first|First', 'second|Second', 'third|Third'))
+ self.assertEqual(field['fgFormat'], 'checkbox')
+
+ self.assertEqual(field.created(), form.created())
+ self.assertEqual(field.modified(), form.modified())
+
+ def test_fieldset(self):
+ self.failIf('fieldset-form' not in self.portal)
+ form = self.portal['fieldset-form']
+ self.assertEqual(form.objectIds(), ['mailer', 'thank-you', 'checkbox', 'datetime', 'Other'])
+
+ fieldset = form['Other']
+ self.assertEqual(fieldset['title'], 'Other')
+ self.assertEqual(fieldset.objectIds(), ['email', 'float', 'string'])
+
+class FakeRequest(dict):
+
+ def __init__(self, **kwargs):
+ self.form = kwargs
+
+class TestSubmit(ptc.PloneTestCase):
+ """ test ya_gpg.py """
+
+ def dummy_send(self, mfrom, mto, messageText):
+ self.mfrom = mfrom
+ self.mto = mto
+ self.messageText = messageText
+
+ def afterSetUp(self):
+ transmogrifier = ITransmogrifier(self.portal)
+ transmogrifier('test_import')
+ self.form = getattr(self.folder, 'complex-form')
+ for i in self.form.contentValues():
+ field = i.getField('required')
+ if field is not None:
+ field.getMutator(i)(False)
+ self.mailhost = self.folder.MailHost
+ self.mailhost._send = self.dummy_send
+
+ def test_submitting(self):
+ """ Test submitting of form """
+ request = FakeRequest(field2='field2@mail.org')
+ errors = self.form.fgvalidate(REQUEST=request)
+ msg = email.message_from_string(self.messageText)
+ self.assertEqual(msg.get('To'), 'Test ')
+ self.assertEqual(msg.get('Subject'), '=?utf-8?q?Test_form_submit?=')
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(TestImport))
+ suite.addTest(unittest.makeSuite(TestSubmit))
+ return suite
Index: quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_import.zcml
===================================================================
--- quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_import.zcml (revision 1498)
+++ quintagroup.transmogrify.pfm2pfg/trunk/quintagroup/transmogrify/pfm2pfg/tests/test_import.zcml (revision 1498)
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+