Commit cd193001 authored by Aurel's avatar Aurel

remove synchronization state from workflow

parent 0ac3057e
...@@ -37,6 +37,7 @@ from Products.ERP5Type import PropertySheet ...@@ -37,6 +37,7 @@ from Products.ERP5Type import PropertySheet
from Products.ERP5SyncML.Utils import PdataHelper from Products.ERP5SyncML.Utils import PdataHelper
from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
_MARKER = [] _MARKER = []
class SyncMLSignature(XMLObject): class SyncMLSignature(XMLObject):
...@@ -65,6 +66,32 @@ class SyncMLSignature(XMLObject): ...@@ -65,6 +66,32 @@ class SyncMLSignature(XMLObject):
, PropertySheet.Document , PropertySheet.Document
, PropertySheet.SyncMLSignature ) , PropertySheet.SyncMLSignature )
security.declareProtected(Permissions.ModifyPortalContent, 'synchronize')
def synchronize(self):
"""
This is call when subscription get confirmation of the data synchronization
This copy & reset some properties if needed
"""
edit_kw = {}
temporary_data = self.getTemporaryData()
if temporary_data is not None:
# This happens when we have sent the xml
# and we just get the confirmation
self.setData(temporary_data)
edit_kw["temporary_data"] = None
if self.isForce():
edit_kw["force"] = False
if self.hasPartialData():
edit_kw["partial_data"] = None
if self.hasSubscriberXupdate():
edit_kw["subscriber_xupdate"] = None
if self.hasPublisherXupdate():
edit_kw["publisher_xupdate"] = None
if len(edit_kw):
self.edit(**edit_kw)
security.declareProtected(Permissions.ModifyPortalContent, 'setData') security.declareProtected(Permissions.ModifyPortalContent, 'setData')
def setData(self, value): def setData(self, value):
""" """
...@@ -248,24 +275,6 @@ class SyncMLSignature(XMLObject): ...@@ -248,24 +275,6 @@ class SyncMLSignature(XMLObject):
else: else:
return self._baseGetPublisherXupdate(default) return self._baseGetPublisherXupdate(default)
security.declareProtected(Permissions.ModifyPortalContent,
'reset')
def reset(self, no_conflict=False):
"""
Clear Signature and change validation_state to not_synchronized
no_conflict : prevent the reset of signature for which conflict
has not been marked resolved, this is usefull when
resetting all signature at the beginning of a sync process
XXX Use a better name and a positive value by default
"""
if no_conflict and self.getValidationState() in (
'conflict',
'conflict_resolved_with_merge',
'conflict_resolved_with_client_command_winning'):
return
if self.getValidationState() != 'not_synchronized':
self.drift()
security.declareProtected(Permissions.ModifyPortalContent, security.declareProtected(Permissions.ModifyPortalContent,
'getConflictList') 'getConflictList')
def getConflictList(self): def getConflictList(self):
...@@ -274,22 +283,6 @@ class SyncMLSignature(XMLObject): ...@@ -274,22 +283,6 @@ class SyncMLSignature(XMLObject):
""" """
return self.contentValues() return self.contentValues()
security.declareProtected(Permissions.ModifyPortalContent,
'setConflictList')
def setConflictList(self, conflict_list):
"""
XXX is it still usefull ?
"""
return
security.declareProtected(Permissions.ModifyPortalContent,
'resetConflictList')
def resetConflictList(self):
"""
XXX is it still usefull ?
"""
return
security.declareProtected(Permissions.ModifyPortalContent, security.declareProtected(Permissions.ModifyPortalContent,
'delConflict') 'delConflict')
def delConflict(self, conflict): def delConflict(self, conflict):
......
...@@ -437,9 +437,6 @@ class SyncMLSubscription(XMLObject): ...@@ -437,9 +437,6 @@ class SyncMLSubscription(XMLObject):
if document is not None: if document is not None:
signature.setReference(document.getPath()) signature.setReference(document.getPath())
elif signature.getValidationState() == 'synchronized':
# Reset status of signature synchronization
signature.drift()
path_list.append(signature.getPath()) path_list.append(signature.getPath())
force = signature.isForce() # XXX-must check the use of this later force = signature.isForce() # XXX-must check the use of this later
else: else:
...@@ -556,8 +553,8 @@ class SyncMLSubscription(XMLObject): ...@@ -556,8 +553,8 @@ class SyncMLSubscription(XMLObject):
elif action['command'] == 'Delete': elif action['command'] == 'Delete':
status_code="success" status_code="success"
document = self.getDocumentFromGid(signature.getId()) document = self.getDocumentFromGid(signature.getId())
# syncml_logger.info("Deleting signature %s & doc %s" %(signature.getPath(), syncml_logger.info("Deleting signature %s & doc %s" %(signature.getPath(),
# document.getPath())) document.getPath()))
path_list.remove(signature.getPath()) path_list.remove(signature.getPath())
if document is not None: if document is not None:
# XXX Can't we get conflict ? # XXX Can't we get conflict ?
...@@ -578,7 +575,7 @@ class SyncMLSubscription(XMLObject): ...@@ -578,7 +575,7 @@ class SyncMLSubscription(XMLObject):
# Now update signature status regarding conflict list # Now update signature status regarding conflict list
if action['command'] != "Delete" and signature: if action['command'] != "Delete" and signature:
if len(conflict_list): if len(conflict_list):
status_code="conflict" status_code = "conflict"
signature.changeToConflict() signature.changeToConflict()
# Register the data received which generated the diff # Register the data received which generated the diff
# XXX Why ? # XXX Why ?
...@@ -589,8 +586,8 @@ class SyncMLSubscription(XMLObject): ...@@ -589,8 +586,8 @@ class SyncMLSubscription(XMLObject):
else: else:
signature.setData(str(xml_document)) signature.setData(str(xml_document))
signature.synchronize() signature.synchronize()
syncml_logger.debug("change state of signature to %s" syncml_logger.info("change state of signature to %s with %s"
% (signature.getValidationState(),)) % (signature.getValidationState(), signature.getData()))
if signature: if signature:
# Generate status about the object synchronized # Generate status about the object synchronized
...@@ -604,9 +601,8 @@ class SyncMLSubscription(XMLObject): ...@@ -604,9 +601,8 @@ class SyncMLSubscription(XMLObject):
message_ref=request_message_id) message_ref=request_message_id)
else: # We want to retrieve more data else: # We want to retrieve more data
syncml_logger.info("we need to retrieve more data for %s" % (signature,)) syncml_logger.info("we need to retrieve more data for %s"
if signature.getValidationState() != 'partial': % (signature.getRelativeUrl(),))
signature.changeToPartial()
signature.appendPartialData(incoming_data) signature.appendPartialData(incoming_data)
# XXX Must check if size is present into the xml # XXX Must check if size is present into the xml
# if not, client might ask it to server with a 411 alert # if not, client might ask it to server with a 411 alert
...@@ -683,6 +679,38 @@ class SyncMLSubscription(XMLObject): ...@@ -683,6 +679,38 @@ class SyncMLSubscription(XMLObject):
def getSearchablePath(self): def getSearchablePath(self):
return "%s%%" %(self.getPath().replace('_', '\_'),) return "%s%%" %(self.getPath().replace('_', '\_'),)
def _generateSyncCommand(self, action, signature, data_diff ,document_data, gid,
conduit, syncml_response):
"""
Generate a sync command for a given data
"""
more_data = False
if signature:
if len(data_diff) > MAX_LEN and not self.getIsActivityEnabled():
# XXX-Aurel : I do not think splitting is working when running in activity
syncml_logger.info("data for %s too big, splitting..." %(signature.getPath(),))
more_data = True
data_diff, rest_string = cutXML(data_diff, MAX_LEN)
# Store the remaining data to send it later
signature.setPartialData(rest_string)
signature.setPartialAction(action)
else:
# The data will be copied in 'data' property once we get
# confirmation that the document was well synchronized
signature.setTemporaryData(document_data)
# Generate the message
syncml_logger.info("adding sync command %s for %s" %(action, gid))
syncml_response.addSyncCommand(
sync_command=action,
gid=gid,
data=data_diff,
more_data=more_data,
media_type=conduit.getContentType())
return more_data
def _getSyncMLData(self, syncml_response, min_gid, max_gid): def _getSyncMLData(self, syncml_response, min_gid, max_gid):
""" """
Compare data from source with data stored in signature from previous Compare data from source with data stored in signature from previous
...@@ -695,7 +723,6 @@ class SyncMLSubscription(XMLObject): ...@@ -695,7 +723,6 @@ class SyncMLSubscription(XMLObject):
""" """
syncml_logger.info("getSyncMLData, min %s - max %r" % (min_gid, max_gid,)) syncml_logger.info("getSyncMLData, min %s - max %r" % (min_gid, max_gid,))
finished = True
conduit = self.getConduit() conduit = self.getConduit()
portal = self.getPortalObject() portal = self.getPortalObject()
traverse = portal.restrictedTraverse traverse = portal.restrictedTraverse
...@@ -722,27 +749,25 @@ class SyncMLSubscription(XMLObject): ...@@ -722,27 +749,25 @@ class SyncMLSubscription(XMLObject):
% (min_gid, max_gid)) % (min_gid, max_gid))
path_list = [] path_list = []
more_data = False
for result in object_list: for result in object_list:
# XXX We need a way to stop the loop when we reach a given packet size
document_path = result.path document_path = result.path
gid = result.gid gid = result.gid
document_data = result.data document_data = result.data
# XXX must find a better way to prevent sending
# no object due to a too small limit
signature = self.getSignatureFromGid(gid) signature = self.getSignatureFromGid(gid)
more_data = False
if signature: if signature:
syncml_logger.info("signature is %s = %s" %(signature.getRelativeUrl(), syncml_logger.info("signature is %s = %s" %(signature.getRelativeUrl(),
signature.getValidationState())) signature.getValidationState()))
if not document_data:
raise ValueError("No data for %s / %s" %(gid, document_path))
# For the case it was never synchronized, we have to send everything # For the case it was never synchronized, we have to send everything
if not signature or sync_all: if not signature or sync_all:
# Either it is the first time we get this object # Either it is the first time we get this object
# either the synchronization process required # either the synchronization process required
# to send every data again as if it was never done before # to send every data again as if it was never done before
if not document_data:
# XXX Which case leads here ?
raise ValueError("No data for %s / %s" %(gid, document_path))
continue
if create_signature: if create_signature:
if not signature: if not signature:
signature = self.newContent(portal_type='SyncML Signature', signature = self.newContent(portal_type='SyncML Signature',
...@@ -751,32 +776,41 @@ class SyncMLSubscription(XMLObject): ...@@ -751,32 +776,41 @@ class SyncMLSubscription(XMLObject):
temporary_data=document_data) temporary_data=document_data)
syncml_logger.info("Created a signature %s for gid = %s, path %s" syncml_logger.info("Created a signature %s for gid = %s, path %s"
% (signature.getPath(), gid, document_path)) % (signature.getPath(), gid, document_path))
if len(document_data) > MAX_LEN: if signature:
syncml_logger.info("data too big, sending multiple message") path_list.append(signature.getPath())
more_data = True more_data = self._generateSyncCommand(
finished = False action=ADD_ACTION,
document_data, rest_string = cutXML(document_data, MAX_LEN) signature=signature,
# Store the remaining data to send it later data_diff=document_data,
signature.setPartialData(rest_string) document_data=document_data,
signature.setPartialAction(ADD_ACTION) gid=gid,
signature.changeToPartial() conduit=conduit,
else: syncml_response=syncml_response)
# The data will be copied in 'data' property once we get
# confirmation that the document was well synchronized
signature.setTemporaryData(document_data)
signature.doSync()
syncml_logger.info("signature %s is syncing"
% (signature.getRelativeUrl(),))
# Generate the message elif signature.hasPartialData():
# Case of partially sent data
# XXX Cutting must be managed by conduit
# Here it is too specific to XML data
xml_string = signature.getFirstPdataChunk(MAX_LEN)
if signature.hasPartialData():
more_data = True
# We need to convert XML to a CDATA type to prevent collision
# with syncml's XML
document_data = etree.CDATA(xml_string.decode('utf-8'))
path_list.append(signature.getPath())
syncml_logger.info("adding partial sync command for %s" %(gid,))
syncml_response.addSyncCommand( syncml_response.addSyncCommand(
sync_command=ADD_ACTION, sync_command=signature.getPartialAction(),
gid=gid, gid=gid,
data=document_data, data=document_data,
more_data=more_data, more_data=more_data,
media_type=conduit.getContentType()) media_type=conduit.getContentType())
elif signature.getValidationState() in ('not_synchronized', 'synchronized', if not more_data:
syncml_logger.info("signature %s is syncing from partial"
% (signature.getRelativeUrl(),))
elif signature.getValidationState() in ('no_conflict',
'conflict_resolved_with_merge'): 'conflict_resolved_with_merge'):
# We don't have synchronized this object yet but it has a signature # We don't have synchronized this object yet but it has a signature
if signature.getValidationState() == 'conflict_resolved_with_merge': if signature.getValidationState() == 'conflict_resolved_with_merge':
...@@ -784,17 +818,22 @@ class SyncMLSubscription(XMLObject): ...@@ -784,17 +818,22 @@ class SyncMLSubscription(XMLObject):
# Server can get confirmation of sync although it has not yet # Server can get confirmation of sync although it has not yet
# send its data modification to the client # send its data modification to the client
# This must be checked against specifications # This must be checked against specifications
# Right now, this message will tell the other side to apply the
# diff without checking conflicts
# We then send the modifications
syncml_response.addConfirmationMessage( syncml_response.addConfirmationMessage(
source_ref=signature.getId(), source_ref=gid,
sync_code='conflict_resolved_with_merge', sync_code='conflict_resolved_with_merge',
command='Replace') command='Replace')
syncml_logger.info("\tMD5 is %s for %s" %((signature.checkMD5(document_data)), syncml_logger.info("\tMD5 is %s for %s" %((signature.checkMD5(document_data)),
signature.getReference())) signature.getReference()))
if not signature.checkMD5(document_data): if not signature.checkMD5(document_data):
# MD5 checksum tell there is a modification of the object # MD5 checksum tell there is a modification of the object
# XXX this diff generation must managed by the conduit
# we just need to have conduit.generateDocumentDiff(new_data, former_data)
if conduit.getContentType() != 'text/xml': if conduit.getContentType() != 'text/xml':
# If there is no xml, we re-send the whole object # If there is no xml, we re-send the whole object
# XXX this must be managed by conduit ?
data_diff = document_data data_diff = document_data
else: else:
# Compute the diff # Compute the diff
...@@ -803,59 +842,30 @@ class SyncMLSubscription(XMLObject): ...@@ -803,59 +842,30 @@ class SyncMLSubscription(XMLObject):
'gid', gid) 'gid', gid)
data_diff = conduit.generateDiff(new_data=new_document, data_diff = conduit.generateDiff(new_data=new_document,
former_data=previous_document) former_data=previous_document)
if not data_diff: if not data_diff:
# MD5 Checksum can detect changes like <lang/> != <lang></lang> # MD5 Checksum can detect changes like <lang/> != <lang></lang>
# but Diff generator will return no diff for it # but Diff generator will return no diff for it
# in this case, no need to send diff # in this case, no need to send diff
if signature.getValidationState() != "synchronized": syncml_logger.info("\tFake diff, signature %s is synchronized"
signature.synchronize()
syncml_logger.debug("signature %s is synchronized"
% (signature.getRelativeUrl(),)) % (signature.getRelativeUrl(),))
path_list.append(signature.getPath())
continue continue
# Split data if necessary # Reindex modified document
if len(data_diff) > MAX_LEN: path_list.append(signature.getPath())
syncml_logger.info("data too big, sending multiple messages") syncml_logger.info("\tGot a diff for %s : %s" %(gid, data_diff))
more_data = True more_data = self._generateSyncCommand(
finished = False action=REPLACE_ACTION,
data_diff, rest_string = cutXML(data_diff, MAX_LEN) signature=signature,
signature.setPartialData(rest_string) data_diff=data_diff,
signature.setPartialAction(REPLACE_ACTION) document_data=document_data,
if signature.getValidationState() != 'partial':
signature.changeToPartial()
syncml_logger.info("signature %s is partial"
% (signature.getRelativeUrl(),))
else:
# Store the new representation of the document
# It will be copy to "data" property once synchronization
# is confirmed
signature.setTemporaryData(document_data)
signature.doSync()
syncml_logger.debug("signature %s is syncing"
% (signature.getRelativeUrl(),))
# Generate the command
syncml_logger.debug("will send Replace command with %s"
% (data_diff,))
syncml_response.addSyncCommand(
sync_command=REPLACE_ACTION,
gid=gid, gid=gid,
data=data_diff, conduit=conduit,
more_data=more_data, syncml_response=syncml_response)
media_type=conduit.getContentType())
elif signature.getValidationState() != 'synchronized':
# We should not have this case when we are in CONFLICT_MERGE
syncml_logger.debug("signature %s is synchronized"
% (signature.getRelativeUrl(),))
signature.synchronize()
elif signature.getValidationState() == \ elif signature.getValidationState() == \
'conflict_resolved_with_client_command_winning': 'conflict_resolved_with_client_command_winning':
# We have decided to apply the update # We have decided to apply the update
# XXX previous_xml will be geXML instead of getTempXML because # XXX previous_xml will be getXML instead of getTempXML because
# some modification was already made and the update # some modification was already made and the update
# may not apply correctly # may not apply correctly
xml_update = signature.getPartialData() xml_update = signature.getPartialData()
...@@ -875,47 +885,14 @@ class SyncMLSubscription(XMLObject): ...@@ -875,47 +885,14 @@ class SyncMLSubscription(XMLObject):
syncml_logger.debug("signature %s is synchronized" syncml_logger.debug("signature %s is synchronized"
% (signature.getRelativeUrl(),)) % (signature.getRelativeUrl(),))
elif signature.getValidationState() == 'partial': if more_data:
# Case of partially sent data
xml_string = signature.getPartialData()
# XXX Cutting must be managed by conduit
# Here it is too specific to XML data
if len(xml_string) > MAX_LEN:
syncml_logger.info("Remaining data too big, splitting it...")
more_data = True
finished = False
xml_string = signature.getFirstPdataChunk(MAX_LEN)
xml_string = etree.CDATA(xml_string.decode('utf-8'))
syncml_response.addSyncCommand(
sync_command=signature.getPartialAction(),
gid=gid,
data=xml_string,
more_data=more_data,
media_type=self.getContentType())
if not more_data:
signature.doSync()
syncml_logger.debug("signature %s is syncing"
% (signature.getRelativeUrl(),))
elif signature.getValidationState() in ('syncing'):
raise ValueError("Must not get signature in %s state here, signature is %s"
% (signature.getValidationState(),
signature.getPath(),))
if signature:
path_list.append(signature.getPath())
if not more_data:
pass
else:
syncml_logger.info("Splitting document") syncml_logger.info("Splitting document")
break break
self.SQLCatalog_indexSyncMLDocumentList(path_list) self.SQLCatalog_indexSyncMLDocumentList(path_list)
syncml_logger.info("_getSyncMLData end with finished %s" syncml_logger.info("_getSyncMLData end with more_data %s"
% (finished,)) % (more_data,))
return finished return not more_data
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getConduit') 'getConduit')
......
...@@ -115,7 +115,7 @@ class EngineMixin(object): ...@@ -115,7 +115,7 @@ class EngineMixin(object):
'conflict_resolved_with_merge'): 'conflict_resolved_with_merge'):
# We will have to apply the update, and we should not care # We will have to apply the update, and we should not care
# about conflicts, so we have to force the update # about conflicts, so we have to force the update
signature.drift() signature.noConflict()
signature.setForce(True) signature.setForce(True)
syncml_logger.error("\tObject merged %s" % syncml_logger.error("\tObject merged %s" %
(status['source'] or status['target'])) (status['source'] or status['target']))
...@@ -125,6 +125,8 @@ class EngineMixin(object): ...@@ -125,6 +125,8 @@ class EngineMixin(object):
'conflict_resolved_with_client_command_winning')): 'conflict_resolved_with_client_command_winning')):
syncml_logger.error("\tObject synchronized %s" % syncml_logger.error("\tObject synchronized %s" %
(status['source'] or status['target'],)) (status['source'] or status['target'],))
if signature.getValidationState() != "no_conflict":
signature.noConflict()
signature.synchronize() signature.synchronize()
elif status['status_code'] == resolveSyncmlStatusCode('chunk_accepted'): elif status['status_code'] == resolveSyncmlStatusCode('chunk_accepted'):
syncml_logger.info("Chunk was accepted for %s" % (object_gid,)) syncml_logger.info("Chunk was accepted for %s" % (object_gid,))
......
...@@ -318,12 +318,12 @@ class TestERP5DocumentSyncMLMixin(TestERP5SyncMLMixin): ...@@ -318,12 +318,12 @@ class TestERP5DocumentSyncMLMixin(TestERP5SyncMLMixin):
for document in document_server.objectValues(): for document in document_server.objectValues():
state_list = self.getSynchronizationState(document) state_list = self.getSynchronizationState(document)
for state in state_list: for state in state_list:
self.assertEqual(state[1], 'synchronized') self.assertEqual(state[1], 'no_conflict')
document_client1 = self.getDocumentClient1() document_client1 = self.getDocumentClient1()
for document in document_client1.objectValues(): for document in document_client1.objectValues():
state_list = self.getSynchronizationState(document) state_list = self.getSynchronizationState(document)
for state in state_list: for state in state_list:
self.assertEqual(state[1], 'synchronized') self.assertEqual(state[1], 'no_conflict')
# Check for each signature that the tempXML is None # Check for each signature that the tempXML is None
for sub in portal_sync.contentValues(portal_type='SyncML Subscription'): for sub in portal_sync.contentValues(portal_type='SyncML Subscription'):
for m in sub.contentValues(): for m in sub.contentValues():
...@@ -420,13 +420,7 @@ class TestERP5DocumentSyncML(TestERP5DocumentSyncMLMixin): ...@@ -420,13 +420,7 @@ class TestERP5DocumentSyncML(TestERP5DocumentSyncMLMixin):
def getTitle(self): def getTitle(self):
return "ERP5 Document SyncML" return "ERP5 Document SyncML"
def setupPublicationAndSubscriptionIdGenerator(self):
portal_sync = self.getSynchronizationTool()
sub1 = portal_sync[self.sub_id1]
pub = portal_sync[self.pub_id]
def checkSynchronizationStateIsConflict(self, portal_type='Text'): def checkSynchronizationStateIsConflict(self, portal_type='Text'):
portal_sync = self.getSynchronizationTool()
document_server = self.getDocumentServer() document_server = self.getDocumentServer()
for document in document_server.objectValues(): for document in document_server.objectValues():
if document.getId()==self.id1: if document.getId()==self.id1:
...@@ -643,7 +637,6 @@ class TestERP5DocumentSyncML(TestERP5DocumentSyncMLMixin): ...@@ -643,7 +637,6 @@ class TestERP5DocumentSyncML(TestERP5DocumentSyncMLMixin):
recognize objects (because by default, getGid==getId. Here, we will see recognize objects (because by default, getGid==getId. Here, we will see
if it also works with a somewhat strange getGid if it also works with a somewhat strange getGid
""" """
self.setupPublicationAndSubscriptionIdGenerator()
nb_document = self.createDocumentServerList() nb_document = self.createDocumentServerList()
# This will test adding object # This will test adding object
self.synchronize(self.sub_id1) self.synchronize(self.sub_id1)
......
...@@ -332,33 +332,33 @@ class TestERP5SyncMLMixin(TestMixin): ...@@ -332,33 +332,33 @@ class TestERP5SyncMLMixin(TestMixin):
for person in person_server.objectValues(): for person in person_server.objectValues():
state_list = self.getSynchronizationState(person) state_list = self.getSynchronizationState(person)
for state in state_list: for state in state_list:
self.assertEquals(state[1], 'synchronized') self.assertEquals(state[1], 'no_conflict')
person_client1 = self.getPersonClient1() person_client1 = self.getPersonClient1()
for person in person_client1.objectValues(): for person in person_client1.objectValues():
state_list = self.getSynchronizationState(person) state_list = self.getSynchronizationState(person)
for state in state_list: for state in state_list:
self.assertEquals(state[1], 'synchronized') self.assertEquals(state[1], 'no_conflict')
person_client2 = self.getPersonClient2() person_client2 = self.getPersonClient2()
for person in person_client2.objectValues(): for person in person_client2.objectValues():
state_list = self.getSynchronizationState(person) state_list = self.getSynchronizationState(person)
for state in state_list: for state in state_list:
self.assertEquals(state[1], 'synchronized') self.assertEquals(state[1], 'no_conflict')
# Check for each signature that the tempXML is None # Check for each signature that the tempXML is None
for sub in portal_sync.contentValues(portal_type='SyncML Subscription'): for sub in portal_sync.contentValues(portal_type='SyncML Subscription'):
for m in sub.contentValues(): for m in sub.contentValues():
self.assertEquals(m.getTemporaryData(), None) self.assertEquals(m.getTemporaryData(), None)
self.assertEquals(m.getPartialData(), None) self.assertEquals(m.getPartialData(), None)
self.assertEquals(m.getValidationState(), "synchronized") self.assertEquals(m.getValidationState(), "no_conflict")
for pub in portal_sync.contentValues(portal_type='SyncML Publication'): for pub in portal_sync.contentValues(portal_type='SyncML Publication'):
for sub in pub.contentValues(portal_type='SyncML Subscription'): for sub in pub.contentValues(portal_type='SyncML Subscription'):
for m in sub.contentValues(): for m in sub.contentValues():
self.assertEquals(m.getPartialData(), None) self.assertEquals(m.getPartialData(), None)
self.assertEquals(m.getValidationState(), "synchronized") self.assertEquals(m.getValidationState(), "no_conflict")
def verifyFirstNameAndLastNameAreNotSynchronized(self, first_name, def verifyFirstNameAndLastNameAreNotSynchronized(self, first_name,
last_name, person_server, person_client): last_name, person_server, person_client):
""" """
verify that the first and last name are NOT synchronized verify that the first and last name are NOT no_conflict
""" """
self.assertNotEqual(person_server.getFirstName(), first_name) self.assertNotEqual(person_server.getFirstName(), first_name)
self.assertNotEqual(person_server.getLastName(), last_name) self.assertNotEqual(person_server.getLastName(), last_name)
...@@ -484,7 +484,6 @@ class TestERP5SyncML(TestERP5SyncMLMixin): ...@@ -484,7 +484,6 @@ class TestERP5SyncML(TestERP5SyncMLMixin):
pub.setConduitModuleId('ERP5ConduitTitleGid') pub.setConduitModuleId('ERP5ConduitTitleGid')
def checkSynchronizationStateIsConflict(self): def checkSynchronizationStateIsConflict(self):
portal_sync = self.getSynchronizationTool()
person_server = self.getPersonServer() person_server = self.getPersonServer()
for person in person_server.objectValues(): for person in person_server.objectValues():
if person.getId()==self.id1: if person.getId()==self.id1:
...@@ -754,7 +753,6 @@ return [context[%r]] ...@@ -754,7 +753,6 @@ return [context[%r]]
# We will try to get the state of objects # We will try to get the state of objects
# that are just synchronized # that are just synchronized
self.test_08_FirstSynchronization() self.test_08_FirstSynchronization()
portal_sync = self.getSynchronizationTool()
person_server = self.getPersonServer() person_server = self.getPersonServer()
person1_s = person_server._getOb(self.id1) person1_s = person_server._getOb(self.id1)
state_list_s = self.getSynchronizationState(person1_s) state_list_s = self.getSynchronizationState(person1_s)
...@@ -785,6 +783,8 @@ return [context[%r]] ...@@ -785,6 +783,8 @@ return [context[%r]]
kw = {'first_name':self.first_name1,'last_name':self.last_name1} kw = {'first_name':self.first_name1,'last_name':self.last_name1}
person1_c.edit(**kw) person1_c.edit(**kw)
#person1_c.setModificationDate(DateTime()+1) #person1_c.setModificationDate(DateTime()+1)
# import ipdb
# ipdb.set_trace()
self.synchronize(self.sub_id1) self.synchronize(self.sub_id1)
self.checkSynchronizationStateIsSynchronized() self.checkSynchronizationStateIsSynchronized()
person1_s = person_server._getOb(self.id1) person1_s = person_server._getOb(self.id1)
...@@ -951,8 +951,6 @@ return [context[%r]] ...@@ -951,8 +951,6 @@ return [context[%r]]
person_server.manage_delObjects(self.id1) person_server.manage_delObjects(self.id1)
person_client1 = self.getPersonClient1() person_client1 = self.getPersonClient1()
person_client1.manage_delObjects(self.id2) person_client1.manage_delObjects(self.id2)
# import ipdb
# ipdb.set_trace()
self.synchronize(self.sub_id1) self.synchronize(self.sub_id1)
self.synchronize(self.sub_id2) self.synchronize(self.sub_id2)
self.checkSynchronizationStateIsSynchronized() self.checkSynchronizationStateIsSynchronized()
...@@ -1601,7 +1599,7 @@ return [context[%r]] ...@@ -1601,7 +1599,7 @@ return [context[%r]]
publication = self.addPublication() publication = self.addPublication()
self.addRefreshFormClientOnlySubscription() self.addRefreshFormClientOnlySubscription()
nb_person = self.populatePersonClient1() self.populatePersonClient1()
portal_sync = self.getSynchronizationTool() portal_sync = self.getSynchronizationTool()
subscription1 = portal_sync[self.sub_id1] subscription1 = portal_sync[self.sub_id1]
self.assertEquals(subscription1.getSyncmlAlertCode(), self.assertEquals(subscription1.getSyncmlAlertCode(),
......
...@@ -28,9 +28,7 @@ ...@@ -28,9 +28,7 @@
# #
############################################################################## ##############################################################################
from testERP5SyncML import TestERP5SyncMLMixin from testERP5SyncML import TestERP5SyncMLMixin
from zLOG import LOG
class TestERP5SyncMLVCard(TestERP5SyncMLMixin): class TestERP5SyncMLVCard(TestERP5SyncMLMixin):
......
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