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
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Romain Courteaud
erp5
Commits
b737b469
Commit
b737b469
authored
Dec 12, 2017
by
Tomáš Peterka
Committed by
Tomáš Peterka
Dec 12, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[hal_json_style] Prefer getter over attribute on raw objects
Fixes bug /#/bug_module/20171211-153B610 /reviewed-on
!526
parent
e579ec15
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
65 additions
and
9 deletions
+65
-9
bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py
...rtal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py
+11
-8
bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py
...plateItem/portal_components/test.erp5.testHalJsonStyle.py
+54
-1
No files found.
bt5/erp5_hal_json_style/SkinTemplateItem/portal_skins/erp5_hal_json_style/ERP5Document_getHateoas.py
View file @
b737b469
...
...
@@ -191,13 +191,22 @@ def getAttrFromAnything(search_result, select, search_property_getter, search_pr
if
"."
in
select
:
select
=
select
[
select
.
rindex
(
'.'
)
+
1
:]
# prepare accessor/getter name because this must be the first tried possibility
# getter is preferred way how to obtain properties - property itself is the second
if
not
select
.
startswith
(
'get'
)
and
select
[
0
]
not
in
string
.
ascii_uppercase
:
# maybe a hidden getter (variable accessible by a getter)
accessor_name
=
'get'
+
UpperCase
(
select
)
else
:
# or obvious getter (starts with "get" or Capital letter - Script)
accessor_name
=
select
# 1. resolve attribute on a raw object (all wrappers removed) using
# lowest-level secure getattr method given object type
raw_search_result
=
search_result
if
hasattr
(
search_result
,
'aq_base'
):
raw_search_result
=
search_result
.
aq_base
if
search_property_hasser
(
raw_search_result
,
select
):
# BUT! only if there is no accessor (because that is the prefered way)
if
search_property_hasser
(
raw_search_result
,
select
)
and
not
hasattr
(
raw_search_result
,
accessor_name
)
:
contents_value
=
search_property_getter
(
raw_search_result
,
select
)
# 2. use the fact that wrappers (brain or acquisition wrapper) use
...
...
@@ -207,12 +216,6 @@ def getAttrFromAnything(search_result, select, search_property_getter, search_pr
unwrapped_search_result
=
search_result
.
aq_self
if
contents_value
is
None
:
if
not
select
.
startswith
(
'get'
)
and
select
[
0
]
not
in
string
.
ascii_uppercase
:
# maybe a hidden getter (variable accessible by a getter)
accessor_name
=
'get'
+
UpperCase
(
select
)
else
:
# or obvious getter (starts with "get" or Capital letter - Script)
accessor_name
=
select
# again we check on a unwrapped object to avoid acquisition resolution
# which would certainly find something which we don't want
try
:
...
...
bt5/erp5_hal_json_style/TestTemplateItem/portal_components/test.erp5.testHalJsonStyle.py
View file @
b737b469
...
...
@@ -990,7 +990,7 @@ return [Object(debit_price=1000.00, credit_price=100.00),
Object(debit_price=10.00, credit_price=0.00)]
"""
)
@
simulate
(
'Test_listProducts'
,
'*args, **kwargs'
,
"""
return context.getPortalObject().foo_module.
v
alues()
return context.getPortalObject().foo_module.
contentV
alues()
"""
)
@
simulate
(
'Test_listCatalog'
,
'*args, **kwargs'
,
"""
return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id', 'ASC')])
...
...
@@ -1058,6 +1058,59 @@ return context.getPortalObject().portal_catalog(portal_type='Foo', sort_on=[('id
self
.
assertEqual
(
result_dict
[
'_embedded'
][
'contents'
][
1
][
'getTotalQuantity'
],
0
)
class
TestERP5Person_getHateoas_mode_search
(
ERP5HALJSONStyleSkinsMixin
):
"""Test HAL_JSON operations on cataloged Persons and other allowed content types of Person Module."""
def
afterSetUp
(
self
):
self
.
person
=
self
.
portal
.
person_module
.
newContent
(
portal_type
=
'Person'
,
first_name
=
"Benoit"
,
last_name
=
"Mandelbrot"
)
self
.
tic
()
def
beforeTearDown
(
self
):
self
.
portal
.
person_module
.
deleteContent
(
self
.
person
.
getId
())
@
simulate
(
'Base_getRequestUrl'
,
'*args, **kwargs'
,
'return "http://example.org/bar"'
)
@
simulate
(
'Base_getRequestHeader'
,
'*args, **kwargs'
,
'return "application/hal+json"'
)
@
simulate
(
'Test_listPersons'
,
'*args, **kwargs'
,
"""
return context.getPortalObject().person_module.contentValues(portal_type="Person")
"""
)
@
simulate
(
'Test_listPersonsCatalog'
,
'*args, **kwargs'
,
"""
return context.getPortalObject().portal_catalog.searchResults(portal_type="Person")
"""
)
@
changeSkin
(
'Hal'
)
def
test_getHateoas_person_title_search
(
self
):
"""Person has amazing property of having attribute "title" and "getTitle" with different return values.
Value resolution must prefer getter over raw attribute.
"""
fake_request
=
do_fake_request
(
"GET"
)
result
=
self
.
portal
.
web_site_module
.
hateoas
.
ERP5Document_getHateoas
(
REQUEST
=
fake_request
,
mode
=
"search"
,
local_roles
=
[
"Assignor"
,
"Assignee"
],
list_method
=
'Test_listPersons'
,
select_list
=
[
'title'
]
# attribute which must be resolved through getter
)
result_dict
=
json
.
loads
(
result
)
titles
=
[
result
[
'title'
]
for
result
in
result_dict
[
'_embedded'
][
'contents'
]]
# getTitle() composes title from first_name and last_name while attribute "title" remains empty
self
.
assertIn
(
"Benoit Mandelbrot"
,
titles
)
result
=
self
.
portal
.
web_site_module
.
hateoas
.
ERP5Document_getHateoas
(
REQUEST
=
fake_request
,
mode
=
"search"
,
local_roles
=
[
"Assignor"
,
"Assignee"
],
list_method
=
'Test_listPersonsCatalog'
,
select_list
=
[
'title'
]
# attribute which must be resolved through getter
)
result_dict
=
json
.
loads
(
result
)
titles
=
[
result
[
'title'
]
for
result
in
result_dict
[
'_embedded'
][
'contents'
]]
# getTitle() composes title from first_name and last_name while attribute "title" remains empty
self
.
assertIn
(
"Benoit Mandelbrot"
,
titles
)
class
TestERP5PDM_getHateoas_mode_search
(
ERP5HALJSONStyleSkinsMixin
):
"""This class allows ticking for Movements to be picked up by activities."""
...
...
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