Commit 6afe0fc8 authored by Jérome Perrin's avatar Jérome Perrin

Merge remote-tracking branch 'nexedi/master' into zope4py2

parents be6c0474 70d11122
...@@ -40,7 +40,7 @@ class CausalityAssignmentMovementGroup(MovementGroup): ...@@ -40,7 +40,7 @@ class CausalityAssignmentMovementGroup(MovementGroup):
portal_type = 'Causality Assignment Movement Group' portal_type = 'Causality Assignment Movement Group'
def _getPropertyDict(self, movement, **kw): def _getPropertyDict(self, movement, **kw):
return self._addCausalityToEdit(movement) return self._addCausalityToEdit(movement, {})
def _separate(self, movement_list, **kw): def _separate(self, movement_list, **kw):
if not movement_list: if not movement_list:
...@@ -51,13 +51,17 @@ class CausalityAssignmentMovementGroup(MovementGroup): ...@@ -51,13 +51,17 @@ class CausalityAssignmentMovementGroup(MovementGroup):
return [[movement_list, property_dict]] return [[movement_list, property_dict]]
def test(self, movement, property_dict, **kw): def test(self, movement, property_dict, **kw):
# We can always update. causality_list = movement.getCausalityList()
if causality_list:
property_dict = property_dict.copy()
for causality in property_dict.get('causality_list', ()):
if causality not in causality_list:
causality_list.append(causality)
property_dict['causality_list'] = causality_list
return True, property_dict return True, property_dict
def _addCausalityToEdit(self, movement, property_dict=None): def _addCausalityToEdit(self, movement, property_dict):
if property_dict is None: causality_list = property_dict.setdefault('causality_list', [])
property_dict = {}
causality_list = property_dict.get('causality_list', [])
root_movement = movement.getRootSimulationMovement() root_movement = movement.getRootSimulationMovement()
# 'order' category is deprecated. it is kept for compatibility. # 'order' category is deprecated. it is kept for compatibility.
movement_list = root_movement.getOrderList() or \ movement_list = root_movement.getOrderList() or \
...@@ -65,5 +69,4 @@ class CausalityAssignmentMovementGroup(MovementGroup): ...@@ -65,5 +69,4 @@ class CausalityAssignmentMovementGroup(MovementGroup):
for delivery_movement in movement_list: for delivery_movement in movement_list:
if delivery_movement not in causality_list: if delivery_movement not in causality_list:
causality_list.append(delivery_movement) causality_list.append(delivery_movement)
property_dict['causality_list'] = causality_list
return property_dict return property_dict
...@@ -36,9 +36,7 @@ class DeliveryCausalityAssignmentMovementGroup(CausalityAssignmentMovementGroup) ...@@ -36,9 +36,7 @@ class DeliveryCausalityAssignmentMovementGroup(CausalityAssignmentMovementGroup)
meta_type = 'ERP5 Delivery Causality Assignment Movement Group' meta_type = 'ERP5 Delivery Causality Assignment Movement Group'
portal_type = 'Delivery Causality Assignment Movement Group' portal_type = 'Delivery Causality Assignment Movement Group'
def _addCausalityToEdit(self, movement, property_dict=None): def _addCausalityToEdit(self, movement, property_dict):
if property_dict is None:
property_dict = {}
if movement.getParentValue().isRootAppliedRule(): if movement.getParentValue().isRootAppliedRule():
# Here movement probably comes from invoice rule, in that situation, we # Here movement probably comes from invoice rule, in that situation, we
# are not able to go up and find a delivery. # are not able to go up and find a delivery.
...@@ -51,10 +49,9 @@ class DeliveryCausalityAssignmentMovementGroup(CausalityAssignmentMovementGroup) ...@@ -51,10 +49,9 @@ class DeliveryCausalityAssignmentMovementGroup(CausalityAssignmentMovementGroup)
delivery_movement = parent.getDeliveryValue() delivery_movement = parent.getDeliveryValue()
if delivery_movement is not None: if delivery_movement is not None:
delivery = delivery_movement.getExplanationValue() delivery = delivery_movement.getExplanationValue()
causality = property_dict.get('causality_list', []) causality = property_dict.setdefault('causality_list', [])
delivery_url = delivery.getRelativeUrl() delivery_url = delivery.getRelativeUrl()
if delivery_url not in causality: if delivery_url not in causality:
causality.append(delivery_url) causality.append(delivery_url)
property_dict['causality_list'] = causality
return property_dict return property_dict
...@@ -42,11 +42,8 @@ class OrderMovementGroup(MovementGroup): ...@@ -42,11 +42,8 @@ class OrderMovementGroup(MovementGroup):
return {'causality_list': [self._getOrderRelativeUrl(movement)]} return {'causality_list': [self._getOrderRelativeUrl(movement)]}
def test(self, movement, property_dict, **kw): def test(self, movement, property_dict, **kw):
if set(property_dict['causality_list']).issubset(movement.getCausalityList()): return set(property_dict['causality_list']
property_dict['causality_list'] = movement.getCausalityList() ).issubset(movement.getCausalityList()), {}
return True, property_dict
else:
return False, property_dict
def _getOrderRelativeUrl(self, movement): def _getOrderRelativeUrl(self, movement):
try: try:
......
...@@ -37,9 +37,17 @@ class IMovementGroup(Interface): ...@@ -37,9 +37,17 @@ class IMovementGroup(Interface):
""" """
def test(document, property_dict, **kw): def test(document, property_dict, **kw):
"""Returns a tuple of 2 values. """Returns a tuple of 2 values.
First one is True if document contains identical values than some First one is True if processed movements can be built to 'document'.
contained property_dict. Second one is a dict of properties that are set to 'document' if the
Second one is a modified version of property_dict. latter is actually chosen: it can be 'property_dict', which was the dict
returned by 'separate' for the considered movements.
'property_dict' shall be treated as immutable recursively. A modified
copy (deeply if necessary) can be returned.
A common implementation is to return a 2-tuple whose first value
is True when properties of 'document' are same as 'property_dict',
then there's usually no property to set and the second value is {}.
TODO: TODO:
- take into account the possibility to use Divergence Testers - take into account the possibility to use Divergence Testers
......
...@@ -323,18 +323,6 @@ class BuilderMixin(XMLObject, Amount, Predicate): ...@@ -323,18 +323,6 @@ class BuilderMixin(XMLObject, Amount, Predicate):
root_group_node.append(movement_list) root_group_node.append(movement_list)
return root_group_node return root_group_node
def _test(self, instance, movement_group_node_list,
divergence_list):
result = True
new_property_dict_list = []
for movement_group_node in movement_group_node_list:
tmp_result, tmp_property_dict = movement_group_node.test(
instance, divergence_list)
if not tmp_result:
result = tmp_result
new_property_dict_list.append(tmp_property_dict)
return result, new_property_dict_list
@staticmethod @staticmethod
def _getSortedPropertyDict(property_dict_list): def _getSortedPropertyDict(property_dict_list):
# Sort the edit keywords according to the order of their movement # Sort the edit keywords according to the order of their movement
...@@ -357,7 +345,6 @@ class BuilderMixin(XMLObject, Amount, Predicate): ...@@ -357,7 +345,6 @@ class BuilderMixin(XMLObject, Amount, Predicate):
def _findUpdatableObject(self, instance_list, movement_group_node_list, def _findUpdatableObject(self, instance_list, movement_group_node_list,
divergence_list): divergence_list):
instance = None
if instance_list: if instance_list:
# we want to check the original delivery first. # we want to check the original delivery first.
# so sort instance_list by that current is exists or not. # so sort instance_list by that current is exists or not.
...@@ -371,16 +358,19 @@ class BuilderMixin(XMLObject, Amount, Predicate): ...@@ -371,16 +358,19 @@ class BuilderMixin(XMLObject, Amount, Predicate):
current = current.getParentValue() current = current.getParentValue()
except AttributeError: except AttributeError:
pass pass
for instance_to_update in instance_list: for instance in instance_list:
result, property_dict_list = self._test( property_dict_list = []
instance_to_update, movement_group_node_list, divergence_list) for movement_group_node in movement_group_node_list:
if result: result, property_dict = movement_group_node.test(
instance = instance_to_update instance, divergence_list)
if not result:
break break
property_dict_list.append(property_dict)
else: else:
property_dict_list = [movement_group_node.getGroupEditDict()
for movement_group_node in movement_group_node_list]
return instance, self._getSortedPropertyDict(property_dict_list) return instance, self._getSortedPropertyDict(property_dict_list)
return None, self._getSortedPropertyDict(
movement_group_node.getGroupEditDict()
for movement_group_node in movement_group_node_list)
security.declarePrivate('buildDeliveryList') security.declarePrivate('buildDeliveryList')
@UnrestrictedMethod @UnrestrictedMethod
......
...@@ -46,6 +46,7 @@ import string ...@@ -46,6 +46,7 @@ import string
import tempfile import tempfile
import glob import glob
import sys import sys
from OFS.Image import Pdata
WORKFLOW_TYPE = 'erp5_workflow' WORKFLOW_TYPE = 'erp5_workflow'
...@@ -7262,8 +7263,14 @@ class TestBusinessTemplate(BusinessTemplateMixin): ...@@ -7262,8 +7263,14 @@ class TestBusinessTemplate(BusinessTemplateMixin):
self.assertEqual(file_content, expected_file_content) self.assertEqual(file_content, expected_file_content)
self.assertEqual(len(file_content), len(expected_file_content)) self.assertEqual(len(file_content), len(expected_file_content))
def stepCheckFileisImportedAsPdata(self, sequence=None, **kw):
self.assertIsInstance(self.portal.portal_templates
.getInstalledBusinessTemplate('erp5_xhtml_style')._skin_item._objects
['portal_skins/erp5_ckeditor/ckeditor/LICENSE.md'].data, Pdata)
def test_text_file_import_export(self): def test_text_file_import_export(self):
""" """
First Check if file is imported as Pdata, then check the following case:
When importing back ace.js containing a last line with whitespaces only, When importing back ace.js containing a last line with whitespaces only,
the last line was not imported, and thus the file could never been the last line was not imported, and thus the file could never been
downloaded completely as its really size was less than the one on the File downloaded completely as its really size was less than the one on the File
...@@ -7271,6 +7278,8 @@ class TestBusinessTemplate(BusinessTemplateMixin): ...@@ -7271,6 +7278,8 @@ class TestBusinessTemplate(BusinessTemplateMixin):
""" """
sequence_list = SequenceList() sequence_list = SequenceList()
sequence_string = """ sequence_string = """
CheckFileisImportedAsPdata
CreateSkinFolder CreateSkinFolder
CreateTextFile CreateTextFile
CheckTextFileContent CheckTextFileContent
......
...@@ -30,7 +30,7 @@ person_mapping = ( ...@@ -30,7 +30,7 @@ person_mapping = (
('gender', 'gender'), ('gender', 'gender'),
('default_telephone_text', 'default_telephone_text'), ('default_telephone_text', 'default_telephone_text'),
('default_mobile_telephone_text', 'default_mobile_telephone_text'), ('default_mobile_telephone_text', 'default_mobile_telephone_text'),
('default_email_text', 'default_email_text'), ('default_email_coordinate_text', 'default_email_coordinate_text'),
('date_of_birth', 'start_date'), ('date_of_birth', 'start_date'),
('nationality', 'nationality'), ('nationality', 'nationality'),
('skill_list', 'default_career_skill_list'), ('skill_list', 'default_career_skill_list'),
......
...@@ -5,7 +5,7 @@ organisation = context.getDestinationDecisionValue(portal_type="Organisation") ...@@ -5,7 +5,7 @@ organisation = context.getDestinationDecisionValue(portal_type="Organisation")
#Mapping #Mapping
organisation_mapping = ( organisation_mapping = (
# (subscription, organisation) # (subscription, organisation)
('default_email_text', 'default_email_text'), ('default_email_coordinate_text', 'default_email_coordinate_text'),
('default_telephone_text', 'default_telephone_text'), ('default_telephone_text', 'default_telephone_text'),
('default_fax_text', 'default_fax_text'), ('default_fax_text', 'default_fax_text'),
('default_address_street_address', 'default_address_street_address'), ('default_address_street_address', 'default_address_street_address'),
......
...@@ -13,7 +13,7 @@ person_mapping = ( ...@@ -13,7 +13,7 @@ person_mapping = (
('date_of_birth', 'birthday'), ('date_of_birth', 'birthday'),
('nationality', 'nationality'), ('nationality', 'nationality'),
('language', 'language'), ('language', 'language'),
('default_email_text', 'default_email_text'), ('default_email_coordinate_text', 'default_email_coordinate_text'),
('default_telephone_telephone_country', 'default_telephone_telephone_country'), ('default_telephone_telephone_country', 'default_telephone_telephone_country'),
('default_telephone_text', 'default_telephone_text'), ('default_telephone_text', 'default_telephone_text'),
('default_fax_text', 'default_fax_text'), ('default_fax_text', 'default_fax_text'),
......
...@@ -33,7 +33,7 @@ if default_email_text is not None: ...@@ -33,7 +33,7 @@ if default_email_text is not None:
message = "We have sent you an email containing your username(s). Please check your inbox and your junk/spam mail for this email." message = "We have sent you an email containing your username(s). Please check your inbox and your junk/spam mail for this email."
if web_site: if web_site:
document_reference = web_site.getCredentialUsernameRecoveryMessageReference() document_reference = web_site.getCredentialUsernameRecoveryMessageReference()
createCredentialRecovery(default_email_text=default_email_text, createCredentialRecovery(default_email_coordinate_text=default_email_text,
destination_decision_value_list=person_list, destination_decision_value_list=person_list,
document_reference=document_reference, document_reference=document_reference,
language=portal.Localizer.get_selected_language()) language=portal.Localizer.get_selected_language())
......
...@@ -23,7 +23,7 @@ credential_request = module.newContent( ...@@ -23,7 +23,7 @@ credential_request = module.newContent(
default_credential_question_question=default_credential_question_question, default_credential_question_question=default_credential_question_question,
default_credential_question_question_free_text=default_credential_question_question_free_text, default_credential_question_question_free_text=default_credential_question_question_free_text,
default_credential_question_answer=default_credential_question_answer, default_credential_question_answer=default_credential_question_answer,
default_email_text=default_email_text, default_email_coordinate_text=default_email_text,
default_telephone_text=default_telephone_text, default_telephone_text=default_telephone_text,
default_mobile_telephone_text=default_mobile_telephone_text, default_mobile_telephone_text=default_mobile_telephone_text,
default_fax_text=default_fax_text, default_fax_text=default_fax_text,
......
...@@ -403,6 +403,8 @@ class TestERP5Credential(ERP5TypeTestCase): ...@@ -403,6 +403,8 @@ class TestERP5Credential(ERP5TypeTestCase):
person = person_result[0].getObject() person = person_result[0].getObject()
self.assertEqual(person.getTitle(), 'Homer Simpson') self.assertEqual(person.getTitle(), 'Homer Simpson')
self.assertEqual(person.getDefaultEmailText(), 'homer.simpson@fox.com') self.assertEqual(person.getDefaultEmailText(), 'homer.simpson@fox.com')
# the obsolete email property is not used
self.assertFalse(person.hasDefaultEmailUrlString())
# check homie can log in the system # check homie can log in the system
self._assertUserExists('homie', 'secret') self._assertUserExists('homie', 'secret')
...@@ -429,7 +431,7 @@ class TestERP5Credential(ERP5TypeTestCase): ...@@ -429,7 +431,7 @@ class TestERP5Credential(ERP5TypeTestCase):
last_name='Simpsons', # add a 's' to the end of the last_name last_name='Simpsons', # add a 's' to the end of the last_name
reference='homie', reference='homie',
password='new_password', password='new_password',
default_email_text='homie.simpsons@fox.com', default_email_coordinate_text='homie.simpsons@fox.com',
destination_decision=homie.getRelativeUrl()) destination_decision=homie.getRelativeUrl())
credential_update.submit() credential_update.submit()
...@@ -456,6 +458,7 @@ class TestERP5Credential(ERP5TypeTestCase): ...@@ -456,6 +458,7 @@ class TestERP5Credential(ERP5TypeTestCase):
self.assertEqual(related_person.getLastName(), 'Simpsons') self.assertEqual(related_person.getLastName(), 'Simpsons')
self.assertEqual(related_person.getDefaultEmailText(), self.assertEqual(related_person.getDefaultEmailText(),
'homie.simpsons@fox.com') 'homie.simpsons@fox.com')
self.assertFalse(related_person.hasDefaultEmailUrlString())
def stepCreateSubscriptionRequestWithSecurityQuestionCategory(self, sequence=None, def stepCreateSubscriptionRequestWithSecurityQuestionCategory(self, sequence=None,
sequence_list=None, **kw): sequence_list=None, **kw):
...@@ -544,7 +547,7 @@ class TestERP5Credential(ERP5TypeTestCase): ...@@ -544,7 +547,7 @@ class TestERP5Credential(ERP5TypeTestCase):
person = person_module.newContent(title='Barney', person = person_module.newContent(title='Barney',
reference='barney', reference='barney',
start_date=DateTime('1970/01/01'), start_date=DateTime('1970/01/01'),
default_email_text='barney@duff.com') default_email_coordinate_text='barney@duff.com')
# create an assignment # create an assignment
assignment = person.newContent(portal_type='Assignment', assignment = person.newContent(portal_type='Assignment',
function='member') function='member')
...@@ -862,6 +865,7 @@ class TestERP5Credential(ERP5TypeTestCase): ...@@ -862,6 +865,7 @@ class TestERP5Credential(ERP5TypeTestCase):
self.assertEqual("Homer", person.getFirstName()) self.assertEqual("Homer", person.getFirstName())
self.assertEqual("Simpson", person.getLastName()) self.assertEqual("Simpson", person.getLastName())
self.assertEqual("homer.simpson@fox.com", person.getDefaultEmailText()) self.assertEqual("homer.simpson@fox.com", person.getDefaultEmailText())
self.assertFalse(person.hasDefaultEmailUrlString())
self.assertEqual(DateTime('1970/01/01'), person.getStartDate()) self.assertEqual(DateTime('1970/01/01'), person.getStartDate())
self.logout() self.logout()
...@@ -878,6 +882,7 @@ class TestERP5Credential(ERP5TypeTestCase): ...@@ -878,6 +882,7 @@ class TestERP5Credential(ERP5TypeTestCase):
self.assertEqual("tom", person.getFirstName()) self.assertEqual("tom", person.getFirstName())
self.assertEqual("Simpson", person.getLastName()) self.assertEqual("Simpson", person.getLastName())
self.assertEqual("tom@host.com", person.getDefaultEmailText()) self.assertEqual("tom@host.com", person.getDefaultEmailText())
self.assertFalse(person.hasDefaultEmailUrlString())
self.assertEqual(DateTime('1970/01/01'), person.getStartDate()) self.assertEqual(DateTime('1970/01/01'), person.getStartDate())
def stepCheckPersonWhenCredentialUpdateFail(self, sequence=None, def stepCheckPersonWhenCredentialUpdateFail(self, sequence=None,
...@@ -1138,6 +1143,7 @@ class TestERP5Credential(ERP5TypeTestCase): ...@@ -1138,6 +1143,7 @@ class TestERP5Credential(ERP5TypeTestCase):
self.assertEqual(credential_request.getFirstName(), "Barney") self.assertEqual(credential_request.getFirstName(), "Barney")
self.assertEqual(credential_request.getDefaultEmailText(), self.assertEqual(credential_request.getDefaultEmailText(),
"barney@duff.com") "barney@duff.com")
self.assertFalse(credential_request.hasDefaultEmailUrlString())
self.assertEqual(credential_request.getRole(), "internal") self.assertEqual(credential_request.getRole(), "internal")
self.assertEqual(credential_request.getFunction(), "member") self.assertEqual(credential_request.getFunction(), "member")
......
...@@ -27,11 +27,11 @@ ...@@ -27,11 +27,11 @@
# #
############################################################################## ##############################################################################
import base64
import hashlib import hashlib
import json import json
import platform import platform
import random import random
from base64 import b64encode
from DateTime import DateTime from DateTime import DateTime
...@@ -47,8 +47,6 @@ class ShaDirMixin(object): ...@@ -47,8 +47,6 @@ class ShaDirMixin(object):
self.portal = self.getPortal() self.portal = self.getPortal()
self.key = 'mykey' + str(random.random()) self.key = 'mykey' + str(random.random())
self.file_name = 'file.txt'
self.urlmd5 = hashlib.md5(self.key).hexdigest()
self.file_content = 'This is the content.' self.file_content = 'This is the content.'
self.file_sha512sum = hashlib.sha512(self.file_content).hexdigest() self.file_sha512sum = hashlib.sha512(self.file_content).hexdigest()
self.distribution = 'pypi' self.distribution = 'pypi'
...@@ -58,21 +56,20 @@ class ShaDirMixin(object): ...@@ -58,21 +56,20 @@ class ShaDirMixin(object):
libc_version = '%s %s' % (platform.libc_ver()[0], platform.libc_ver()[1]) libc_version = '%s %s' % (platform.libc_ver()[0], platform.libc_ver()[1])
self.architecture = '%s %s' % (platform.machine(), libc_version) self.architecture = '%s %s' % (platform.machine(), libc_version)
self.data_list = [json.dumps({'file': self.file_name, self.data_list = [json.dumps({
'urlmd5': self.urlmd5,
'sha512': self.file_sha512sum, 'sha512': self.file_sha512sum,
'creation_date': str(self.creation_date), 'creation_date': str(self.creation_date),
'expiration_date': str(self.expiration_date), 'expiration_date': str(self.expiration_date),
'distribution': self.distribution, 'distribution': self.distribution,
'architecture': self.architecture}), 'architecture': self.architecture}),
"User SIGNATURE goes here."] b64encode("User SIGNATURE goes here.")]
self.data = json.dumps(self.data_list) self.data = json.dumps(self.data_list)
self.sha512sum = hashlib.sha512(self.data).hexdigest() self.sha512sum = hashlib.sha512(self.data).hexdigest()
self.header_dict = { self.header_dict = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': 'Basic %s' % (base64.encodestring('ERP5TypeTestCase:').strip()) 'Authorization': 'Basic ' + b64encode('ERP5TypeTestCase:'),
} }
module = self.portal.web_site_module module = self.portal.web_site_module
......
...@@ -27,11 +27,12 @@ ...@@ -27,11 +27,12 @@
# #
############################################################################## ##############################################################################
import hashlib
import httplib import httplib
import urlparse import urlparse
import json import json
import random import random
from base64 import b64encode
from unittest import expectedFailure from unittest import expectedFailure
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from erp5.component.test.ShaDirMixin import ShaDirMixin from erp5.component.test.ShaDirMixin import ShaDirMixin
...@@ -214,17 +215,15 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase): ...@@ -214,17 +215,15 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase):
self.postInformation() self.postInformation()
self.tic() self.tic()
urlmd5_2 = 'anotherurlmd5' + str(random.random()) sha512_2 = hashlib.sha512(str(random.random())).hexdigest()
sha512_2 = 'anothersha512_2' + str(random.random())
key_2 = 'another_key' + str(random.random()) key_2 = 'another_key' + str(random.random())
data_list_2 = [json.dumps({'file': self.file_name, data_list_2 = [json.dumps({
'urlmd5': urlmd5_2,
'sha512': sha512_2, 'sha512': sha512_2,
'creation_date': str(self.creation_date), 'creation_date': str(self.creation_date),
'expiration_date': str(self.expiration_date), 'expiration_date': str(self.expiration_date),
'distribution': self.distribution, 'distribution': self.distribution,
'architecture': self.architecture}), 'architecture': self.architecture}),
"User SIGNATURE goes here."] b64encode("User SIGNATURE goes here.")]
data_2 = json.dumps(data_list_2) data_2 = json.dumps(data_list_2)
self.postInformation(key_2, data_2) self.postInformation(key_2, data_2)
self.tic() self.tic()
......
...@@ -146,14 +146,10 @@ class TestShaDirExternal(ShaDirMixin, ShaSecurityMixin, ERP5TypeTestCase): ...@@ -146,14 +146,10 @@ class TestShaDirExternal(ShaDirMixin, ShaSecurityMixin, ERP5TypeTestCase):
self.assertEqual(302, result.status) self.assertEqual(302, result.status)
def test_external_post_with_wrong_data(self): def test_external_post_with_wrong_data(self):
"""
The data which is sent to the server must follow a JSON schema.
If the data does not follow the schema it must return the error.
"""
# Removing a required property # Removing a required property
data = json.loads(self.data) data = json.loads(self.data)
data[0] = json.loads(data[0]) data[0] = json.loads(data[0])
data[0].pop('file') del data[0]['sha512']
data[0] = json.dumps(data[0]) data[0] = json.dumps(data[0])
data = json.dumps(data) data = json.dumps(data)
...@@ -165,7 +161,6 @@ class TestShaDirExternal(ShaDirMixin, ShaSecurityMixin, ERP5TypeTestCase): ...@@ -165,7 +161,6 @@ class TestShaDirExternal(ShaDirMixin, ShaSecurityMixin, ERP5TypeTestCase):
data = result.read() data = result.read()
finally: finally:
connection.close() connection.close()
self.assertTrue("Required field 'file' is missing" in data, data) self.assertEqual(400, result.status)
self.assertEqual(500, result.status)
self.assertEqual('text/html; charset=utf-8', self.assertEqual('text/html; charset=utf-8',
result.getheader("content-type")) result.getheader("content-type"))
...@@ -99,6 +99,7 @@ from ZODB.broken import Broken, BrokenModified ...@@ -99,6 +99,7 @@ from ZODB.broken import Broken, BrokenModified
from Products.ERP5.genbt5list import BusinessTemplateRevision, \ from Products.ERP5.genbt5list import BusinessTemplateRevision, \
item_name_list, item_set item_name_list, item_set
from Products.ERP5Type.mixin.component import ComponentMixin from Products.ERP5Type.mixin.component import ComponentMixin
from OFS.Image import File as OFSFile
CACHE_DATABASE_PATH = None CACHE_DATABASE_PATH = None
try: try:
...@@ -878,6 +879,8 @@ class ObjectTemplateItem(BaseTemplateItem): ...@@ -878,6 +879,8 @@ class ObjectTemplateItem(BaseTemplateItem):
# backward-compatibility # backward-compatibility
elif six.PY3 and is_text: elif six.PY3 and is_text:
data = data.decode('utf-8') data = data.decode('utf-8')
if isinstance(obj, OFSFile) and property_name == "data":
data = obj._read_data(data)[0]
try: try:
setattr(obj, property_name, data) setattr(obj, property_name, data)
except BrokenModified: except BrokenModified:
......
...@@ -164,8 +164,15 @@ class MovementGroupNode: ...@@ -164,8 +164,15 @@ class MovementGroupNode:
if not property_list: if not property_list:
return True, {} return True, {}
# else update anyway (eg. CausalityAssignmentMovementGroup etc.) # else update anyway (eg. CausalityAssignmentMovementGroup etc.)
return self._movement_group.test(movement, self._property_dict, result, property_dict = self._movement_group.test(
property_list=property_list) movement, self._property_dict, property_list=property_list)
# The following check is partial because it does not check mutable values
# recursively.
if property_dict is self._property_dict != property_dict:
raise ValueError(
"Movement Group must not modify the passed 'property_dict':"
" copy it, deeply if necessary, before editing properties")
return result, property_dict
else: else:
return True, {} return True, {}
......
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