Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
erp5
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
7
Merge Requests
7
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Jérome Perrin
erp5
Commits
2de58ec4
Commit
2de58ec4
authored
Nov 28, 2022
by
Jérome Perrin
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'upstream/master' into zope4py2
parents
341fdcf0
f269e6ca
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
225 additions
and
82 deletions
+225
-82
bt5/erp5_base/ActionTemplateItem/portal_types/External%20Identifier/change_function.xml
...em/portal_types/External%20Identifier/change_function.xml
+81
-0
bt5/erp5_base/bt/template_action_path_list
bt5/erp5_base/bt/template_action_path_list
+1
-0
bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testProxyField.py
...emplateItem/portal_components/test.erp5.testProxyField.py
+15
-3
bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testZODBHistory.py
...mplateItem/portal_components/test.erp5.testZODBHistory.py
+4
-5
bt5/erp5_forge/TestTemplateItem/portal_components/test.erp5.testTemplateTool.py
...plateItem/portal_components/test.erp5.testTemplateTool.py
+6
-0
bt5/erp5_ui_test_core/ExtensionTemplateItem/portal_components/extension.erp5.ERP5Zuite.py
...emplateItem/portal_components/extension.erp5.ERP5Zuite.py
+6
-1
bt5/erp5_upgrader/TestTemplateItem/portal_components/test.erp5.testUpgrader.py
...tTemplateItem/portal_components/test.erp5.testUpgrader.py
+1
-1
product/ERP5/Document/BusinessTemplate.py
product/ERP5/Document/BusinessTemplate.py
+40
-12
product/ERP5/Tool/TemplateTool.py
product/ERP5/Tool/TemplateTool.py
+1
-0
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_getZODBHistoryList.py
...ateItem/portal_skins/erp5_core/Base_getZODBHistoryList.py
+1
-1
product/ERP5Form/ProxyField.py
product/ERP5Form/ProxyField.py
+10
-1
product/ERP5Form/dtml/proxyFieldEdit.dtml
product/ERP5Form/dtml/proxyFieldEdit.dtml
+1
-1
product/ERP5Form/dtml/proxyFieldTales.dtml
product/ERP5Form/dtml/proxyFieldTales.dtml
+1
-1
product/ERP5Type/ERP5Type.py
product/ERP5Type/ERP5Type.py
+1
-4
product/ERP5Type/dynamic/component_package.py
product/ERP5Type/dynamic/component_package.py
+9
-0
product/ERP5Type/tests/ERP5TypeFunctionalTestCase.py
product/ERP5Type/tests/ERP5TypeFunctionalTestCase.py
+3
-0
product/ERP5Type/tests/runTestSuite.py
product/ERP5Type/tests/runTestSuite.py
+3
-0
product/ERP5Type/tests/runUnitTest.py
product/ERP5Type/tests/runUnitTest.py
+2
-22
product/ZSQLCatalog/SQLCatalog.py
product/ZSQLCatalog/SQLCatalog.py
+39
-30
No files found.
bt5/erp5_base/ActionTemplateItem/portal_types/External%20Identifier/change_function.xml
0 → 100644
View file @
2de58ec4
<?xml version="1.0"?>
<ZopeData>
<record
id=
"1"
aka=
"AAAAAAAAAAE="
>
<pickle>
<global
name=
"ActionInformation"
module=
"Products.CMFCore.ActionInformation"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
action
</string>
</key>
<value>
<persistent>
<string
encoding=
"base64"
>
AAAAAAAAAAI=
</string>
</persistent>
</value>
</item>
<item>
<key>
<string>
categories
</string>
</key>
<value>
<tuple>
<string>
action_type/object_jio_action
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
category
</string>
</key>
<value>
<string>
object_jio_action
</string>
</value>
</item>
<item>
<key>
<string>
condition
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
description
</string>
</key>
<value>
<none/>
</value>
</item>
<item>
<key>
<string>
icon
</string>
</key>
<value>
<string></string>
</value>
</item>
<item>
<key>
<string>
id
</string>
</key>
<value>
<string>
change_function
</string>
</value>
</item>
<item>
<key>
<string>
permissions
</string>
</key>
<value>
<tuple>
<string>
Modify portal content
</string>
</tuple>
</value>
</item>
<item>
<key>
<string>
priority
</string>
</key>
<value>
<float>
2.0
</float>
</value>
</item>
<item>
<key>
<string>
title
</string>
</key>
<value>
<string>
Change Function
</string>
</value>
</item>
<item>
<key>
<string>
visible
</string>
</key>
<value>
<int>
1
</int>
</value>
</item>
</dictionary>
</pickle>
</record>
<record
id=
"2"
aka=
"AAAAAAAAAAI="
>
<pickle>
<global
name=
"Expression"
module=
"Products.CMFCore.Expression"
/>
</pickle>
<pickle>
<dictionary>
<item>
<key>
<string>
text
</string>
</key>
<value>
<string>
string:${object_url}/Base_viewChangeIdDialog
</string>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
bt5/erp5_base/bt/template_action_path_list
View file @
2de58ec4
...
...
@@ -44,6 +44,7 @@ Embedded File | fullsize_view
Embedded File | view
Embedded File | web_view
Embedded Folder | view
External Identifier | change_function
External Identifier | view
Fax | change_function
Fax | view
...
...
bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testProxyField.py
View file @
2de58ec4
...
...
@@ -402,9 +402,9 @@ return printed
'Base_viewGeek'
,
'View'
)
form
=
skin_folder
.
_getOb
(
'Base_viewGeek'
,
None
)
form
.
manage_addField
(
'my_
title'
,
'Title
'
,
'ProxyField'
)
form
.
manage_addField
(
'my_
proxy_field'
,
'Proxy
'
,
'ProxyField'
)
field
=
form
.
my_
title
field
=
form
.
my_
proxy_field
self
.
assertFalse
(
form
.
get_fields
())
self
.
assertEqual
([
field
],
form
.
get_fields
(
include_disabled
=
True
))
...
...
@@ -413,10 +413,22 @@ return printed
self
.
assertEqual
(
''
,
field
.
get_tales
(
'default'
))
regexp
=
'^%s$'
%
re
.
escape
(
"Can't find the template field of"
" <ProxyField at /%s/portal_skins/erp5_geek/Base_viewGeek/my_
title
>"
" <ProxyField at /%s/portal_skins/erp5_geek/Base_viewGeek/my_
proxy_field
>"
%
self
.
portal
.
getId
())
for
func
in
(
field
.
render
,
partial
(
field
.
get_value
,
'default'
)
,
partial
(
field
.
get_recursive_tales
,
'default'
)
):
self
.
assertRaisesRegexp
(
BrokenProxyField
,
regexp
,
func
)
# we can still view the field in ZMI
form
.
manage_main
()
field
.
manage_main
()
# and repair it
form
.
manage_addField
(
'my_field'
,
'Title'
,
'StringField'
)
field
.
manage_edit
(
{
'field_form_id'
:
'Base_viewGeek'
,
'field_field_id'
:
'my_field'
,
})
self
.
assertEqual
(
field
.
getTemplateField
(),
form
.
my_field
)
bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testZODBHistory.py
View file @
2de58ec4
...
...
@@ -84,7 +84,6 @@ class TestZODBHistory(ERP5TypeTestCase):
self
.
assertTrue
(
len
(
history_list
)
>
0
)
d
=
history_list
[
0
]
changes
=
d
[
'changes'
]
self
.
assertEqual
(
changes
[
'portal_type'
],
'Organisation'
)
self
.
assertEqual
(
changes
[
'id'
],
'org'
)
self
.
assertTrue
(
changes
[
'uid'
]
is
not
None
)
...
...
@@ -140,7 +139,7 @@ class TestZODBHistory(ERP5TypeTestCase):
document
.
edit
(
title
=
'ネクセディ'
,
default_address_city
=
'千代田区'
)
self
.
commit
()
_
,
change
,
=
document
.
Base_getZODBHistoryList
()
self
.
assertIn
(
'title:ネクセディ'
,
change
.
getProperty
(
'changes'
))
self
.
assertIn
(
'title:
ネクセディ'
,
change
.
getProperty
(
'changes'
))
# no encoding error
document
.
Base_viewZODBHistory
()
...
...
@@ -167,9 +166,9 @@ class TestZODBHistory(ERP5TypeTestCase):
document
.
Base_viewZODBHistory
()
change
,
=
document
.
Base_getZODBHistoryList
()
self
.
assertIn
(
'data:(binary)'
,
change
.
getProperty
(
'changes'
))
self
.
assertIn
(
'content_type:image/png'
,
change
.
getProperty
(
'changes'
))
self
.
assertIn
(
'title:ロゴ'
,
change
.
getProperty
(
'changes'
))
self
.
assertIn
(
'data:
(binary)'
,
change
.
getProperty
(
'changes'
))
self
.
assertIn
(
'content_type:
image/png'
,
change
.
getProperty
(
'changes'
))
self
.
assertIn
(
'title:
ロゴ'
,
change
.
getProperty
(
'changes'
))
def
test_suite
():
...
...
bt5/erp5_forge/TestTemplateItem/portal_components/test.erp5.testTemplateTool.py
View file @
2de58ec4
...
...
@@ -104,6 +104,9 @@ class TestTemplateTool(ERP5TypeTestCase):
self
.
assertEqual
(
test_web
.
getPortalType
(),
'Business Template'
)
self
.
assertEqual
(
test_web
.
getTitle
(),
'test_web'
)
self
.
assertEqual
(
len
(
test_web
.
getRevision
()),
28
)
self
.
assertEqual
(
test_web
.
getPublicationUrl
(),
'http://www.erp5.org/dists/snapshot/test_bt5/test_web.bt5'
)
def
_svn_setup_ssl
(
self
):
"""
...
...
@@ -139,6 +142,8 @@ class TestTemplateTool(ERP5TypeTestCase):
self
.
assertEqual
(
test_web
.
getPortalType
(),
'Business Template'
)
self
.
assertEqual
(
test_web
.
getTitle
(),
'test_web'
)
self
.
assertEqual
(
len
(
test_web
.
getRevision
()),
28
)
self
.
assertEqual
(
test_web
.
getPublicationUrl
(),
bt5_url
)
def
test_00_updateBusinessTemplateFromUrl_simple
(
self
):
"""
...
...
@@ -549,6 +554,7 @@ class TestTemplateTool(ERP5TypeTestCase):
bt
=
self
.
templates_tool
.
getInstalledBusinessTemplate
(
bt5_name
,
strict
=
True
)
self
.
assertNotEquals
(
bt
,
None
)
self
.
assertEqual
(
bt
.
getTitle
(),
bt5_name
)
self
.
assertEqual
(
bt
.
getPublicationUrl
(),
self
.
_getBTPathAndIdList
([
bt5_name
])[
0
][
0
])
# Repeat operation, the bt5 should be ignored
self
.
templates_tool
.
installBusinessTemplateListFromRepository
([
bt5_name
])
...
...
bt5/erp5_ui_test_core/ExtensionTemplateItem/portal_components/extension.erp5.ERP5Zuite.py
View file @
2de58ec4
import
itertools
import
time
from
Products.CMFActivity.Activity.Queue
import
VALIDATION_ERROR_DELAY
from
Products.CMFActivity.ActivityTool
import
getCurrentNode
def
waitForActivities
(
self
,
delay
=
100
,
count
=
None
):
"""
...
...
@@ -9,13 +10,17 @@ def waitForActivities(self, delay=100, count=None):
RuntimeError is raised in case there is no way
to finish activities.
"""
activity_tool
=
self
.
getPortalObject
().
portal_activities
assert
not
(
activity_tool
.
isSubscribed
()
and
getCurrentNode
()
in
activity_tool
.
getProcessingNodeList
())
if
count
is
not
None
:
# BBB
# completely arbitrary conversion factor: count used to default to 1000
# and I (just as arbitrarily) converted that into a 100s default maximum
# tolerable wait delay before bailing.
delay
=
count
/
10.
deadline
=
time
.
time
()
+
delay
activity_tool
=
self
.
getPortalObject
().
portal_activities
for
call_count
in
itertools
.
count
():
x
=
activity_tool
.
getMessageList
()
if
not
x
:
...
...
bt5/erp5_upgrader/TestTemplateItem/portal_components/test.erp5.testUpgrader.py
View file @
2de58ec4
...
...
@@ -786,7 +786,7 @@ class TestUpgrader(ERP5TypeTestCase):
def
stepCheckPersonTitleHistory
(
self
,
sequence
=
None
):
self
.
assertEqual
(
[
x
.
changes
for
x
in
self
.
portal
.
person_module
[
'1'
].
Base_getZODBHistoryList
()[
-
3
:]],
[(
'title:
M. pre_upgrade'
,),
(
'title:M. upgrader'
,),
(
'title:
M. post_upgrade'
,)])
[(
'title:
M. pre_upgrade'
,),
(
'title: M. upgrader'
,),
(
'title:
M. post_upgrade'
,)])
def
test_upgrade_activities_are_run_sequentially
(
self
):
"""
...
...
product/ERP5/Document/BusinessTemplate.py
View file @
2de58ec4
...
...
@@ -77,17 +77,18 @@ from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from
OFS.Traversable
import
NotFound
from
OFS
import
SimpleItem
from
OFS.Image
import
Pdata
import
coverage
from
io
import
BytesIO
from
copy
import
deepcopy
from
zExceptions
import
BadRequest
from
Products.ERP5Type.XMLExportImport
import
exportXML
,
customImporters
from
Products.ERP5Type.Workflow
import
WorkflowHistoryList
from
zLOG
import
LOG
,
WARNING
,
INFO
from
zLOG
import
LOG
,
WARNING
,
INFO
,
PROBLEM
from
warnings
import
warn
from
lxml.etree
import
parse
from
xml.sax.saxutils
import
escape
from
Products.CMFCore.Expression
import
Expression
from
six.moves.urllib.parse
import
quote
,
unquote
from
six.moves.urllib.parse
import
quote
,
unquote
,
urlparse
from
difflib
import
unified_diff
import
posixpath
import
transaction
...
...
@@ -97,6 +98,7 @@ import threading
from
ZODB.broken
import
Broken
,
BrokenModified
from
Products.ERP5.genbt5list
import
BusinessTemplateRevision
,
\
item_name_list
,
item_set
from
Products.ERP5Type.mixin.component
import
ComponentMixin
CACHE_DATABASE_PATH
=
None
try
:
...
...
@@ -1156,22 +1158,33 @@ class ObjectTemplateItem(BaseTemplateItem):
"""
pass
def
onNewObject
(
self
,
obj
):
def
onNewObject
(
self
,
obj
,
context
):
"""
Installation hook.
Called when installation process determined that object to install is
new on current site (it's not replacing an existing object).
`obj` parameter is the newly created object in its acquisition context.
`context` is the business template instance, in its acquisition context.
Can be overridden by subclasses.
"""
pass
if
isinstance
(
obj
,
(
PythonScript
,
ComponentMixin
))
and
coverage
.
Coverage
.
current
():
relative_path
=
'/'
.
join
(
obj
.
getPhysicalPath
()[
len
(
context
.
getPortalObject
().
getPhysicalPath
()):])
filename
=
os
.
path
.
join
(
context
.
getPublicationUrl
(),
self
.
__class__
.
__name__
,
relative_path
+
'.py'
)
if
os
.
path
.
exists
(
filename
):
obj
.
_erp5_coverage_filename
=
filename
else
:
LOG
(
'BusinessTemplate'
,
PROBLEM
,
'Could not find file for %s'
%
filename
)
def
onReplaceObject
(
self
,
obj
):
def
onReplaceObject
(
self
,
obj
,
context
):
"""
Installation hook.
Called when installation process determined that object to install is
to replace an existing object on current site (it's not new).
`obj` parameter is the replaced object in its acquisition context.
`context` is the business template instance, in its acquisition context.
Can be overridden by subclasses.
"""
pass
...
...
@@ -1416,9 +1429,9 @@ class ObjectTemplateItem(BaseTemplateItem):
if
not
object_existed
:
# A new object was added, call the hook
self
.
onNewObject
(
obj
)
self
.
onNewObject
(
obj
,
context
)
else
:
self
.
onReplaceObject
(
obj
)
self
.
onReplaceObject
(
obj
,
context
)
# mark a business template installation so in 'PortalType_afterClone' scripts
# we can implement logical for reseting or not attributes (i.e reference).
...
...
@@ -1972,9 +1985,11 @@ class CategoryTemplateItem(ObjectTemplateItem):
def
beforeInstall
(
self
):
self
.
_installed_new_category
=
False
return
super
(
CategoryTemplateItem
,
self
).
beforeInstall
()
def
onNewObject
(
self
,
obj
):
def
onNewObject
(
self
,
obj
,
context
):
self
.
_installed_new_category
=
True
return
super
(
CategoryTemplateItem
,
self
).
onNewObject
(
obj
,
context
)
def
afterInstall
(
self
):
if
self
.
_installed_new_category
:
...
...
@@ -2392,7 +2407,8 @@ class WorkflowTemplateItem(ObjectTemplateItem):
continue
raise
container_ids
=
container
.
objectIds
()
if
object_id
in
container_ids
:
# Object already exists
object_existed
=
object_id
in
container_ids
if
object_existed
:
self
.
_backupObject
(
action
,
trashbin
,
container_path
,
object_id
,
keep_subobjects
=
1
)
container
.
manage_delObjects
([
object_id
])
obj
=
self
.
_objects
[
path
]
...
...
@@ -2402,6 +2418,11 @@ class WorkflowTemplateItem(ObjectTemplateItem):
obj
=
container
.
_getOb
(
object_id
)
obj
.
manage_afterClone
(
obj
)
obj
.
wl_clearLocks
()
if
not
object_existed
:
# A new object was added, call the hook
self
.
onNewObject
(
obj
,
context
)
else
:
self
.
onReplaceObject
(
obj
,
context
)
def
uninstall
(
self
,
context
,
**
kw
):
object_path
=
kw
.
get
(
'object_path'
,
None
)
...
...
@@ -4218,7 +4239,7 @@ class _ZodbComponentTemplateItem(ObjectTemplateItem):
raise
NotImplementedError
def
__init__
(
self
,
id_list
,
tool_id
=
'portal_components'
,
**
kw
):
ObjectTemplateItem
.
__init__
(
self
,
id_list
,
tool_id
=
tool_id
,
**
kw
)
super
(
_ZodbComponentTemplateItem
,
self
).
__init__
(
id_list
,
tool_id
=
tool_id
,
**
kw
)
def
isKeepWorkflowObjectLastHistoryOnly
(
self
,
path
):
"""
...
...
@@ -4248,9 +4269,13 @@ class _ZodbComponentTemplateItem(ObjectTemplateItem):
obj
.
workflow_history
[
wf_id
]
=
WorkflowHistoryList
([
wf_history
])
def
onNewObject
(
self
,
_
):
def
onNewObject
(
self
,
obj
,
context
):
self
.
_do_reset
=
True
onReplaceObject
=
onNewObject
return
super
(
_ZodbComponentTemplateItem
,
self
).
onNewObject
(
obj
,
context
)
def
onReplaceObject
(
self
,
obj
,
context
):
self
.
_do_reset
=
True
return
super
(
_ZodbComponentTemplateItem
,
self
).
onReplaceObject
(
obj
,
context
)
def
afterInstall
(
self
):
"""
...
...
@@ -5718,6 +5743,9 @@ Business Template is a set of definitions, such as skins, portal types and categ
value
=
self
.
getProperty
(
id
)
if
not
value
:
continue
if
id
==
'publication_url'
:
if
urlparse
(
value
).
scheme
in
(
'file'
,
''
):
continue
if
prop_type
in
(
'text'
,
'string'
,
'int'
,
'boolean'
):
bta
.
addObject
(
str
(
value
),
name
=
id
,
path
=
'bt'
,
ext
=
''
)
elif
prop_type
in
(
'lines'
,
'tokens'
):
...
...
product/ERP5/Tool/TemplateTool.py
View file @
2de58ec4
...
...
@@ -401,6 +401,7 @@ class TemplateTool (BaseTool):
bt = self._download_local(path, id)
bt.build(no_action=True)
bt.setPublicationUrl(url)
return bt
security.declareProtected('
Import
/
Export
objects
', '
importBase64EncodedText
')
...
...
product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Base_getZODBHistoryList.py
View file @
2de58ec4
...
...
@@ -16,7 +16,7 @@ def beautifyChange(change_dict):
six
.
text_type
(
property_value
,
'utf-8'
)
except
UnicodeDecodeError
:
property_value
=
'(binary)'
change_list
.
append
(
'{}:{}'
.
format
(
property_name
,
property_value
))
change_list
.
append
(
'{}:
{}'
.
format
(
property_name
,
property_value
))
return
change_list
try
:
...
...
product/ERP5Form/ProxyField.py
View file @
2de58ec4
...
...
@@ -171,8 +171,9 @@ class ProxyField(ZMIField):
Surcharged values from proxied field.
"""
# Edit template field attributes
template_field
=
self
.
get
Recursive
TemplateField
()
template_field
=
self
.
getTemplateField
()
if
template_field
is
not
None
:
template_field
=
self
.
getRecursiveTemplateField
()
# Check the surcharged checkboxes
surcharge_list
=
[]
...
...
@@ -581,6 +582,14 @@ class ProxyField(ZMIField):
# ("form_id and field_id don't define a valid template")
pass
security
.
declareProtected
(
'View'
,
'title'
)
def
title
(
self
):
"""The title of this field."""
try
:
return
super
(
ProxyField
,
self
).
title
()
except
BrokenProxyField
:
return
'broken'
security
.
declareProtected
(
'Access contents information'
,
'has_value'
)
def
has_value
(
self
,
id
):
"""
...
...
product/ERP5Form/dtml/proxyFieldEdit.dtml
View file @
2de58ec4
...
...
@@ -11,7 +11,7 @@ Surcharge <dtml-var meta_type> properties here.
<form action="manage_edit" method="POST">
<table cellspacing="0" cellpadding="2" border="0">
<dtml-let proxy_field="this()"
current_field="proxy_field.getRecursiveTemplateField()">
current_field="
None if proxy_field.getTemplateField() is None else
proxy_field.getRecursiveTemplateField()">
<!-- First, display ProxyField properties -->
<!-- see: Formulator/dtml/fieldEdit.dtml -->
...
...
product/ERP5Form/dtml/proxyFieldTales.dtml
View file @
2de58ec4
...
...
@@ -68,7 +68,7 @@ This tab can therefore not be used.
<!-- XXX Loop until find not a proxy field -->
<dtml-let proxy_field="this()"
current_field="proxy_field.getRecursiveTemplateField()">
current_field="
None if proxy_field.getTemplateField() is None else
proxy_field.getRecursiveTemplateField()">
<dtml-if "current_field is not None">
<dtml-let form="current_field.tales_form">
...
...
product/ERP5Type/ERP5Type.py
View file @
2de58ec4
...
...
@@ -399,6 +399,7 @@ class ERP5TypeInformation(XMLObject,
self
.
getId
(),
temp
=
temp_object
)
base_ob
=
klass
(
id
)
assert
base_ob
.
portal_type
==
self
.
getId
()
ob
=
base_ob
.
__of__
(
container
)
if
temp_object
:
...
...
@@ -422,10 +423,6 @@ class ERP5TypeInformation(XMLObject,
if
getattr
(
base_ob
,
'uid'
,
None
)
is
None
:
ob
.
uid
=
portal
.
portal_catalog
.
newUid
()
# Portal type has to be set before setting other attributes
# in order to initialize aq_dynamic
ob
.
portal_type
=
self
.
getId
()
if
compute_local_role
:
# Do not reindex object because it's already done by manage_afterAdd
self
.
updateLocalRolesOnDocument
(
ob
,
reindex
=
False
)
...
...
product/ERP5Type/dynamic/component_package.py
View file @
2de58ec4
...
...
@@ -36,6 +36,7 @@ import imp
import
collections
from
six
import
reraise
import
coverage
from
Products.ERP5Type.Utils
import
ensure_list
from
Products.ERP5.ERP5Site
import
getSite
from
Products.ERP5Type
import
product_path
as
ERP5Type_product_path
...
...
@@ -333,6 +334,14 @@ class ComponentDynamicPackage(ModuleType):
# This must be set for imports at least (see PEP 302)
module
.
__file__
=
'<'
+
relative_url
+
'>'
if
coverage
.
Coverage
.
current
():
if
hasattr
(
component
,
'_erp5_coverage_filename'
):
module
.
__file__
=
component
.
_erp5_coverage_filename
else
:
LOG
(
"ERP5Type.Tool.ComponentTool"
,
WARNING
,
"No coverage filesystem mapping for %s"
%
(
module_fullname_alias
or
module_fullname
))
# Only useful for get_source(), do it before exec'ing the source code
# so that the source code is properly display in case of error
...
...
product/ERP5Type/tests/ERP5TypeFunctionalTestCase.py
View file @
2de58ec4
...
...
@@ -420,6 +420,9 @@ class ERP5TypeFunctionalTestCase(ERP5TypeTestCase):
# create browser_id_manager
if
not
"browser_id_manager"
in
self
.
portal
.
objectIds
():
self
.
portal
.
manage_addProduct
[
'Sessions'
].
constructBrowserIdManager
()
# unsubscribe from activities, we'll use Zuite_waitForActivities to
# process activities
self
.
portal
.
portal_activities
.
unsubscribe
()
self
.
commit
()
self
.
setSystemPreference
()
# non-recursive results clean of portal_tests/ or portal_tests/``run_only``
...
...
product/ERP5Type/tests/runTestSuite.py
View file @
2de58ec4
...
...
@@ -140,6 +140,9 @@ def main():
args
.
test_node_title
,
suite
.
allow_restart
,
test_suite_title
,
args
.
project_title
)
if
test_result
is
not
None
:
os
.
environ
[
'ERP5_TEST_RESULT_REVISION'
]
=
test_result
.
revision
os
.
environ
[
'ERP5_TEST_RESULT_ID'
]
=
test_result
.
test_result_path
.
split
(
'/'
)[
-
1
]
assert
revision
==
test_result
.
revision
,
(
revision
,
test_result
.
revision
)
while
suite
.
acquire
():
test
=
test_result
.
start
(
suite
.
running
.
keys
())
...
...
product/ERP5Type/tests/runUnitTest.py
View file @
2de58ec4
...
...
@@ -12,10 +12,7 @@ import errno
import
random
import
transaction
from
glob
import
glob
try
:
from
coverage
import
coverage
except
ImportError
:
coverage
=
None
WIN
=
os
.
name
==
'nt'
...
...
@@ -27,8 +24,6 @@ Options:
-v, --verbose produce verbose output
-h, --help this help screen
-p, --profile print profiling results at the end
--coverage=STRING Use the given path as a coverage config file and
thus enable code coverateg report
--portal_id=STRING force id of the portal. Useful when using
--data_fs_path to run tests on an existing
Data.fs
...
...
@@ -640,11 +635,6 @@ def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
signal
.
signal
(
signal
.
SIGINT
,
shutdown
)
signal
.
signal
(
signal
.
SIGHUP
,
shutdown
)
coverage_config
=
os
.
environ
.
get
(
'coverage'
,
None
)
if
coverage_config
:
coverage_process
=
coverage
(
config_file
=
coverage_config
)
coverage_process
.
start
()
try
:
save
=
int
(
os
.
environ
.
get
(
'erp5_save_data_fs'
,
0
))
load
=
int
(
os
.
environ
.
get
(
'erp5_load_data_fs'
,
0
))
...
...
@@ -719,11 +709,6 @@ def runUnitTestList(test_list, verbosity=1, debug=0, run_only=None):
# disconnected from it.
wcfs_server
.
stop
()
if
coverage_config
:
coverage_process
.
stop
()
coverage_process
.
save
()
coverage_process
.
html_report
()
if
save
and
save_mysql
:
save_mysql
(
verbosity
)
...
...
@@ -749,7 +734,7 @@ def main(argument_list=None):
sys
.
argv
.
extend
(
old_argv
[
1
:])
try
:
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
"hpvD"
,
[
"help"
,
"verbose"
,
"profile"
,
"
coverage="
,
"
portal_id="
,
"hpvD"
,
[
"help"
,
"verbose"
,
"profile"
,
"portal_id="
,
"data_fs_path="
,
"bt5_path="
,
"firefox_bin="
,
...
...
@@ -812,11 +797,6 @@ def main(argument_list=None):
elif
opt
==
'-D'
:
debug
=
1
os
.
environ
[
"erp5_debug_mode"
]
=
str
(
debug
)
elif
opt
==
"--coverage"
:
if
coverage
:
os
.
environ
[
'coverage'
]
=
arg
else
:
_print
(
"WARNING Coverage module not found"
)
elif
opt
in
(
"-p"
,
"--profile"
):
os
.
environ
[
'PROFILE_TESTS'
]
=
"1"
# profiling of setup and teardown is disabled by default, just set
...
...
product/ZSQLCatalog/SQLCatalog.py
View file @
2de58ec4
...
...
@@ -1867,7 +1867,8 @@ class Catalog(Folder,
else
:
if
related_key_definition
is
not
None
:
search_key
=
search_key
.
getSearchKey
(
sql_catalog
=
self
,
related_key_definition
=
related_key_definition
)
related_key_definition
=
related_key_definition
,
search_key_name
=
search_key_name
)
return
search_key
security
.
declareProtected
(
access_contents_information
,
'buildSingleQuery'
)
...
...
@@ -1885,17 +1886,18 @@ class Catalog(Folder,
from it.
"""
return
self
.
_buildQuery
(
buildQueryFromSearchKey
=
lambda
search_key
:
search_key
.
buildQuery
(
lambda
search_key
:
search_key
.
buildQuery
(
value
,
logical_operator
=
logical_operator
,
comparison_operator
=
comparison_operator
,
),
key
=
key
,
search_key_name
=
search_key_name
,
ignore_unknown_columns
=
ignore_unknown_columns
,
key
,
search_key_name
,
ignore_unknown_columns
,
)
def
_buildQueryFromAbstractSyntaxTreeNode
(
self
,
node
,
search_key
,
wrap
,
ignore_unknown_columns
):
def
_buildQueryFromAbstractSyntaxTreeNode
(
self
,
node
,
search_key
,
wrap
,
ignore_unknown_columns
):
"""
node
Abstract syntax tree node (see SearchText/AdvancedSearchTextParser.py,
...
...
@@ -1952,7 +1954,10 @@ class Catalog(Folder,
return
result
security
.
declareProtected
(
access_contents_information
,
'buildQueryFromAbstractSyntaxTreeNode'
)
def
buildQueryFromAbstractSyntaxTreeNode
(
self
,
node
,
key
,
wrap
=
lambda
x
:
x
,
ignore_unknown_columns
=
False
):
def
buildQueryFromAbstractSyntaxTreeNode
(
self
,
node
,
key
,
search_key_name
=
None
,
wrap
=
lambda
x
:
x
,
ignore_unknown_columns
=
False
):
"""
Build a query from given Abstract Syntax Tree (AST) node by recursing in
its childs.
...
...
@@ -1966,17 +1971,18 @@ class Catalog(Folder,
Expected node API is described in interfaces/abstract_syntax_node.py .
"""
return
self
.
_buildQuery
(
buildQueryFromSearchKey
=
lambda
search_key
:
self
.
_buildQueryFromAbstractSyntaxTreeNode
(
lambda
search_key
:
self
.
_buildQueryFromAbstractSyntaxTreeNode
(
node
,
search_key
,
wrap
,
ignore_unknown_columns
,
),
key
=
key
,
ignore_unknown_columns
=
ignore_unknown_columns
,
key
,
search_key_name
,
ignore_unknown_columns
,
)
def
_buildQuery
(
self
,
buildQueryFromSearchKey
,
key
,
search_key_name
=
None
,
ignore_unknown_columns
=
False
):
def
_buildQuery
(
self
,
buildQueryFromSearchKey
,
key
,
search_key_name
,
ignore_unknown_columns
):
"""
Determine the SearchKey to use to generate a Query, and call buildQueryFromSearchKey with it.
"""
...
...
@@ -1996,7 +2002,7 @@ class Catalog(Folder,
related_key_definition
=
related_key_definition
,
search_key_name
=
search_key_name
,
)
result
=
buildQueryFromSearchKey
(
search_key
=
build_key
)
result
=
buildQueryFromSearchKey
(
build_key
)
if
related_key_definition
is
not
None
:
result
=
search_key
.
buildQuery
(
sql_catalog
=
self
,
related_key_definition
=
related_key_definition
,
...
...
@@ -2049,32 +2055,35 @@ class Catalog(Folder,
# We have an empty value, do not create a query from it
empty_value_dict
[
key
]
=
value
else
:
if
isinstance
(
value
,
dict
):
# Dictionnary: might contain the search key to use.
search_key_name
=
value
.
get
(
'key'
)
# Backward compatibility: former "Keyword" key is now named
# "KeywordKey".
if
search_key_name
==
'Keyword'
:
search_key_name
=
value
[
'key'
]
=
'KeywordKey'
# Backward compatibility: former "ExactMatch" is now only available
# as "RawKey"
elif
search_key_name
==
'ExactMatch'
:
search_key_name
=
value
[
'key'
]
=
'RawKey'
if
isinstance
(
value
,
BaseQuery
):
# Query instance: use as such, ignore key.
result
=
value
elif
isinstance
(
value
,
(
basestring
,
dict
)):
# String: parse using key's default search key.
raw_value
=
value
wrap
=
lambda
x
:
x
if
isinstance
(
value
,
dict
):
# De-wrap value for parsing, and re-wrap when building queries.
def
wrap
(
x
):
result
=
raw_value
.
copy
()
result
[
'query'
]
=
x
return
result
# Dictionary: might contain the search key to use.
search_key_name
=
value
.
pop
(
'key'
,
None
)
# Backward compatibility: former "Keyword" key is now named
# "KeywordKey".
if
search_key_name
==
'Keyword'
:
search_key_name
=
'KeywordKey'
# Backward compatibility: former "ExactMatch" is now only available
# as "RawKey"
elif
search_key_name
==
'ExactMatch'
:
search_key_name
=
'RawKey'
# De-wrap value for parsing.
value
=
value
[
'query'
]
# If necessary, re-wrap when building queries.
if
len
(
raw_value
)
>
1
:
def
wrap
(
x
):
result
=
raw_value
.
copy
()
result
[
'query'
]
=
x
return
result
else
:
raw_value
=
value
else
:
wrap
=
lambda
x
:
x
search_key_name
=
None
search_key
=
self
.
getColumnDefaultSearchKey
(
key
,
search_key_name
=
search_key_name
)
...
...
@@ -2093,7 +2102,7 @@ class Catalog(Folder,
)
else
:
result
=
self
.
buildQueryFromAbstractSyntaxTreeNode
(
abstract_syntax_tree
,
key
,
wrap
,
abstract_syntax_tree
,
key
,
search_key_name
,
wrap
,
ignore_unknown_columns
=
ignore_unknown_columns
,
)
else
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment