Skip to content

Commit

Permalink
Allow uid as destination in duplicate and move (#737)
Browse files Browse the repository at this point in the history
  • Loading branch information
Qiwn authored and vangheem committed Nov 21, 2019
1 parent 0a92ea1 commit 0add33a
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 18 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.rst
Expand Up @@ -4,7 +4,8 @@ CHANGELOG
5.1.16 (unreleased)
-------------------

- Nothing changed yet.
- Allow uid as destination in `@duplicate` and `@move`
[qiwn]


5.1.15 (2019-11-20)
Expand Down
4 changes: 2 additions & 2 deletions guillotina/api/content.py
Expand Up @@ -554,7 +554,7 @@ async def __call__(self):
"properties": {
"destination": {
"type": "string",
"description": "Absolute path to destination object from container",
"description": "Absolute path to destination object from container or destination uid",
"required": False,
},
"new_id": {
Expand Down Expand Up @@ -599,7 +599,7 @@ async def move(context, request):
"properties": {
"destination": {
"type": "string",
"description": "Absolute path to destination object from container",
"description": "Absolute path to destination object from container or destination uid",
"required": False,
},
"new_id": {
Expand Down
34 changes: 24 additions & 10 deletions guillotina/content.py
Expand Up @@ -56,6 +56,7 @@
from guillotina.schema.utils import get_default_from_schema
from guillotina.security.security_code import PrincipalPermissionManager
from guillotina.transactions import get_transaction
from guillotina.utils import get_object_by_uid
from guillotina.utils import get_security_policy
from guillotina.utils import navigate_to
from typing import Any
Expand Down Expand Up @@ -652,11 +653,19 @@ async def duplicate(
) -> IResource:
if destination is not None:
if isinstance(destination, str):
container = task_vars.container.get()
if container:
destination_ob = await navigate_to(container, destination)
destination_ob = None
if destination.startswith("/"):
container = task_vars.container.get()
if container:
try:
destination_ob = await navigate_to(container, destination)
except KeyError:
pass
else:
raise PreconditionFailed(context, "Could not find destination object")
try:
destination_ob = await get_object_by_uid(destination)
except KeyError:
pass
else:
destination_ob = destination

Expand Down Expand Up @@ -731,14 +740,19 @@ async def move(
destination_ob = context.__parent__
else:
if isinstance(destination, str):
container = task_vars.container.get()
if container is not None:
destination_ob = None
if destination.startswith("/"):
container = task_vars.container.get()
if container is not None:
try:
destination_ob = await navigate_to(container, destination)
except KeyError:
pass
else:
try:
destination_ob = await navigate_to(container, destination)
destination_ob = await get_object_by_uid(destination)
except KeyError:
destination_ob = None
else:
raise PreconditionFailed(context, "Could not find destination object")
pass
else:
destination_ob = destination

Expand Down
57 changes: 52 additions & 5 deletions guillotina/tests/test_api.py
Expand Up @@ -492,9 +492,23 @@ async def test_move_content(container_requester):
_, status = await requester(
"POST", "/db/guillotina/", data=json.dumps({"@type": "Folder", "id": "container2"})
)
response, status = await requester(
"POST", "/db/guillotina/", data=json.dumps({"@type": "Folder", "id": "container3"})
)
container3_uid = response["@uid"]
_, status = await requester(
"POST", "/db/guillotina/container1", data=json.dumps({"@type": "Item", "id": "foobar"})
)

_, status = await requester(
"POST", "/db/guillotina/container1/foobar/@move", data=json.dumps({"destination": "/wrong_path"})
)
assert status == 412
_, status = await requester(
"POST", "/db/guillotina/container1/foobar/@move", data=json.dumps({"destination": "wrong_uid"})
)
assert status == 412

_, status = await requester(
"POST", "/db/guillotina/container1/foobar/@move", data=json.dumps({"destination": "/container2"})
)
Expand All @@ -504,16 +518,25 @@ async def test_move_content(container_requester):
_, status = await requester("GET", "/db/guillotina/container1/foobar")
assert status == 404

_, status = await requester(
"POST", "/db/guillotina/container2/foobar/@move", data=json.dumps({"destination": container3_uid})
)

_, status = await requester("GET", "/db/guillotina/container3/foobar")
assert status == 200
_, status = await requester("GET", "/db/guillotina/container2/foobar")
assert status == 404

# move back with new id
_, status = await requester(
"POST",
"/db/guillotina/container2/foobar/@move",
"/db/guillotina/container3/foobar/@move",
data=json.dumps({"destination": "/container1", "new_id": "foobar_new"}),
)

_, status = await requester("GET", "/db/guillotina/container1/foobar_new")
assert status == 200
_, status = await requester("GET", "/db/guillotina/container2/foobar")
_, status = await requester("GET", "/db/guillotina/container3/foobar")
assert status == 404


Expand Down Expand Up @@ -553,16 +576,40 @@ async def test_duplicate_content(container_requester):
assert "foobar2" in response
assert "foobar1" in response

await requester("POST", "/db/guillotina/", data=json.dumps({"@type": "Folder", "id": "folder"}))
_, status = await requester(
"POST", "/db/guillotina/foobar1/@duplicate", data=json.dumps({"destination": "/wrong_path"})
)
assert status == 412
_, status = await requester(
"POST", "/db/guillotina/foobar1/@duplicate", data=json.dumps({"destination": "wrong_uid"})
)
assert status == 412

response, _ = await requester(
"POST", "/db/guillotina/", data=json.dumps({"@type": "Folder", "id": "folder"})
)
folder_uid = response["@uid"]

await requester(
"POST",
"/db/guillotina/foobar1/@duplicate",
data=json.dumps({"new_id": "foobar", "destination": "/folder"}),
data=json.dumps({"new_id": "foobar1", "destination": "/folder"}),
)

response, _ = await requester("GET", "/db/guillotina/folder/@ids")
assert len(response) == 1
assert "foobar" in response
assert "foobar1" in response

await requester(
"POST",
"/db/guillotina/foobar1/@duplicate",
data=json.dumps({"new_id": "foobar2", "destination": folder_uid}),
)

response, _ = await requester("GET", "/db/guillotina/folder/@ids")
assert len(response) == 2
assert "foobar1" in response
assert "foobar2" in response


async def test_create_content_fields(container_requester):
Expand Down

0 comments on commit 0add33a

Please sign in to comment.