Commit 86951172 authored by Jérome Perrin's avatar Jérome Perrin

ERP5Type: make TempBase use TemporaryDocumentMixin

Now that TemporaryDocumentMixin and TempBase implementation details have
been made consistent, there's no reason to duplicate code.

This also make TempBase uses TemporaryDocumentMixin of __setstate__, so
TempBase have more sane behaviour when being pickled.
parent b2e03135
Pipeline #19399 failed with stage
in 0 seconds
......@@ -82,6 +82,14 @@ class SessionToolTestCase(ERP5TypeTestCase):
session = self.portal.portal_sessions[self.session_id]
self.assertEqual(primitives_kw, session)
def test_store_temp_base(self):
portal_sessions = self.portal.portal_sessions
from Products.ERP5Type.Document import newTempBase
session = portal_sessions.newContent(
self.session_id,
temp_base=newTempBase(self.portal, 'temp_base', title='Temp Base'))
self.assertEqual(session['temp_base'].getTitle(), 'Temp Base')
def test_store_temp_object(self):
portal_sessions = self.portal.portal_sessions
session = portal_sessions.newContent(
......
......@@ -70,6 +70,7 @@ from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
from Products.ERP5Type.Accessor.TypeDefinition import list_types
from Products.ERP5Type.Accessor import Base as BaseAccessor
from Products.ERP5Type.mixin.property_translatable import PropertyTranslatableBuiltInDictMixIn
from Products.ERP5Type.mixin.temporary import TemporaryDocumentMixin
from Products.ERP5Type.XMLExportImport import Base_asXML
from Products.ERP5Type.Cache import CachingMethod, clearCache, getReadOnlyTransactionCache
from .Accessor import WorkflowState
......@@ -3626,51 +3627,16 @@ def removeIContentishInterface(cls):
removeIContentishInterface(Base)
class TempBase(Base):
"""A version of Base that does not persist in ZODB.
class TempBase(TemporaryDocumentMixin, Base):
"""A version of Base that does not persist in ZODB.
This class only has the Base methods, so most of the times it is
preferable to use a temporary portal type instead.
"""
isIndexable = ConstantGetter('isIndexable', value=False)
isTempDocument = ConstantGetter('isTempDocument', value=True)
# Declarative security
security = ClassSecurityInfo()
def reindexObject(self, *args, **kw):
pass
def recursiveReindexObject(self, *args, **kw):
pass
def activate(self, *args, **kw):
return self
def setUid(self, value):
self.uid = value # Required for Listbox so that no casting happens when we use TempBase to create new objects
def setTitle(self, value):
"""
Required so that getProperty('title') will work on tempBase objects
The dynamic acquisition work very well for a lot of properties, but
not for title. For example, if we do setProperty('organisation_url'), then
even if organisation_url is not in a propertySheet, the method getOrganisationUrl
will be generated. But this does not work for title, because I(seb)'m almost sure
there is somewhere a method '_setTitle' or 'setTitle' with no method getTitle on Base.
That why setProperty('title') and getProperty('title') does not work.
"""
self.title = value
def getTitle(self):
"""
Returns the title of this document
"""
return getattr(aq_base(self), 'title', None)
security.declarePublic('setProperty')
security.declarePublic('getProperty')
security.declarePublic('edit')
# Persistence.Persistent is one of the superclasses of TempBase, and on Zope2.8
......
......@@ -41,7 +41,7 @@ from OFS.Folder import Folder as OFS_Folder
from persistent import Persistent, wref
from ZODB.serialize import ObjectWriter, ObjectReader
from Products.ERP5Type import Permissions
from Products.ERP5Type.Base import Base, WorkflowMethod
from Products.ERP5Type.Base import Base, TempBase, WorkflowMethod
log = logging.getLogger('ERP5Type')
log.trace = lambda *args, **kw: log.log(5, *args, **kw)
......@@ -165,6 +165,8 @@ if 1:
if klass.__module__ in ('erp5.portal_type', 'erp5.temp_portal_type'):
return Base__setstate__(self, value)
if klass is TempBase:
return Base__setstate__(self, value)
try:
portal_type = value.get('portal_type') or klass.portal_type
except AttributeError:
......
......@@ -236,7 +236,7 @@ class TestERP5Type(ERP5TypeTestCase, LogInterceptor):
'newTemp*(self, ID) will be removed, use self.newContent(temp_object=True, id=ID, portal_type=...)',
DeprecationWarning, 2)
def test_03_NewTempObject(self):
def test_newTempBase(self):
# Products.ERP5Type.Document.newTempBase is another (not recommended) way
# of creating temp objects
import Products.ERP5Type.Document
......@@ -246,19 +246,33 @@ class TestERP5Type(ERP5TypeTestCase, LogInterceptor):
self.assertTrue(o.isTempObject())
self.assertTrue(guarded_import("Products.ERP5Type.Document", fromlist=["newTempBase"]))
def test_TempObjectPersistent(self):
def _test_temp_object_persistent(self, temp_object):
# Temp objects can not be stored in ZODB
temp_object = self.portal.person_module.newContent(portal_type='Person', temp_object=True)
self.assertTrue(temp_object.isTempObject())
# they can be pickled
self.assertTrue(pickle.dumps(aq_base(temp_object)))
# they can be unpickled
import ZODB.broken
self.assertNotIsInstance(
pickle.loads(pickle.dumps(aq_base(temp_object))),
ZODB.broken.Broken,
)
# but they can not be saved in ZODB accidentally
self.portal.person_module.oops = temp_object
self.assertRaisesRegexp(Exception, "Temporary objects can't be pickled", self.commit)
self.abort()
def test_temp_object_persistent(self):
temp_object = self.portal.person_module.newContent(portal_type='Person', temp_object=True)
self._test_temp_object_persistent(temp_object)
def test_newTempBase_persistent(self):
import Products.ERP5Type.Document
temp_object = Products.ERP5Type.Document.newTempBase(self.portal, 'id')
self._test_temp_object_persistent(temp_object)
def test_warnings_redirected_to_event_log(self):
self._catch_log_errors()
self.addCleanup(self._ignore_log_errors)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment