Skip to content

Commit

Permalink
Avoid an edge case where content types would end up without fields
Browse files Browse the repository at this point in the history
  • Loading branch information
frapell committed Apr 19, 2022
1 parent a4ddc23 commit 80169e0
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 17 deletions.
2 changes: 2 additions & 0 deletions news/165.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Avoid an edge case where content types would end up without fields
[frapell]
17 changes: 3 additions & 14 deletions plone/dexterity/fti.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,10 @@

def get_suffix(fti):
mtime = getattr(fti, "_p_mtime", None)
# Python 2 rounds floats when we use the str function on them.

# Python 2:
# >>> str(1637689348.9999528)
# '1637689349.0'

# Python 3:
# >>> str(1637689348.9999528)
# '1637689348.9999528'

# This was causing the schema names in Python 2 to take an unexpected format,
# causing errors.
# So, we need to use the repr function, which doesn't round floats.
# There is no need to use the actual float, an int is good enough
# and we avoid issues when the mtime has no milliseconds
if mtime:
return repr(mtime)
return str(int(mtime))
return ""


Expand Down
4 changes: 2 additions & 2 deletions plone/dexterity/tests/test_fti.py
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ def test_loockup_schema_with_p_mtime_roundable(self):
self.mock_utility(portal, ISiteRoot)

# Generated schema name must be this.
schemaName = "site_5_1637689348_2_9999528_0_testtype"
schemaName = "site_5_1637689348_0_testtype"
setattr(plone.dexterity.schema.generated, schemaName, ITestSchema)

self.assertEqual(ITestSchema, fti.lookupSchema())
Expand Down Expand Up @@ -1014,7 +1014,7 @@ class IBlank1(Interface):

# Set source interface
# Generated schema name must be this.
schemaName = "siteid_5_1637689348_2_9999528_0_testtype"
schemaName = "siteid_5_1637689348_0_testtype"
setattr(plone.dexterity.schema.generated, schemaName, IBlank1)

# Sync this with schema
Expand Down
52 changes: 51 additions & 1 deletion plone/dexterity/tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from .case import MockTestCase
from plone.dexterity import schema
from plone.dexterity.fti import DexterityFTI
from plone.dexterity.fti import get_suffix
from plone.dexterity.interfaces import IContentType
from plone.dexterity.interfaces import IDexterityFTI
from plone.dexterity.interfaces import IDexteritySchema
Expand Down Expand Up @@ -50,7 +51,6 @@ class IDummy(Interface):
self.mock_utility(fti_mock, IDexterityFTI, u"testtype")

factory = schema.SchemaModuleFactory()

schemaName = schema.portalTypeToSchemaName("testtype", prefix="site")
klass = factory(schemaName, schema.generated)

Expand All @@ -61,6 +61,56 @@ class IDummy(Interface):
self.assertEqual("plone.dexterity.schema.generated", klass.__module__)
self.assertEqual(("dummy",), tuple(zope.schema.getFieldNames(klass)))

def test_default_schema_with_mtime(self):

# Mock schema model
class IDummy(Interface):
dummy = zope.schema.TextLine(title=u"Dummy")

mock_model = Model({u"": IDummy})

# Mock FTI
fti_mock = Mock(spec=DexterityFTI)
fti_mock.lookupModel = Mock(return_value=mock_model)
fti_mock._p_mtime = 1650380190.961898
self.mock_utility(fti_mock, IDexterityFTI, u"testtype")

factory = schema.SchemaModuleFactory()
schemaName = schema.portalTypeToSchemaName("testtype", prefix="site", suffix=get_suffix(fti_mock))
klass = factory(schemaName, schema.generated)

self.assertTrue(isinstance(klass, InterfaceClass))
self.assertTrue(klass.isOrExtends(IDexteritySchema))
self.assertTrue(IContentType.providedBy(klass))
self.assertEqual(schemaName, klass.__name__)
self.assertEqual("plone.dexterity.schema.generated", klass.__module__)
self.assertEqual(("dummy",), tuple(zope.schema.getFieldNames(klass)))

def test_default_schema_with_mtime_no_millis(self):

# Mock schema model
class IDummy(Interface):
dummy = zope.schema.TextLine(title=u"Dummy")

mock_model = Model({u"": IDummy})

# Mock FTI
fti_mock = Mock(spec=DexterityFTI)
fti_mock.lookupModel = Mock(return_value=mock_model)
fti_mock._p_mtime = 1650380190.0
self.mock_utility(fti_mock, IDexterityFTI, u"testtype")

factory = schema.SchemaModuleFactory()
schemaName = schema.portalTypeToSchemaName("testtype", prefix="site", suffix=get_suffix(fti_mock))
klass = factory(schemaName, schema.generated)

self.assertTrue(isinstance(klass, InterfaceClass))
self.assertTrue(klass.isOrExtends(IDexteritySchema))
self.assertTrue(IContentType.providedBy(klass))
self.assertEqual(schemaName, klass.__name__)
self.assertEqual("plone.dexterity.schema.generated", klass.__module__)
self.assertEqual(("dummy",), tuple(zope.schema.getFieldNames(klass)))

def test_named_schema(self):

# Mock schema model
Expand Down

0 comments on commit 80169e0

Please sign in to comment.