Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion synapseclient/api/entity_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,12 @@ async def _handle_file_entity(
entity_instance.file_handle = FileHandle().fill_from_dict(
synapse_instance=file_handle
)
entity_instance._fill_from_file_handle()
# Synapse omits the file handle from the bundle when the caller lacks DOWNLOAD
# permission (e.g. unmet access requirements). Only copy file handle fields onto
# the entity when one was returned so that `dataFileHandleId` from the entity
# is preserved.
if file_handle:
entity_instance._fill_from_file_handle()
Comment thread
thomasyu888 marked this conversation as resolved.
Resolved

if download_file:
if file_handle:
Expand Down
26 changes: 26 additions & 0 deletions tests/unit/synapseclient/models/async/unit_test_file_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,32 @@ async def test_get_with_id(self) -> None:
assert result.file_handle.is_preview
assert result.file_handle.external_url == FILE_HANDLE_EXTERNAL_URL

async def test_get_with_unmet_access_requirement(self) -> None:
# GIVEN an example file
file = File(id=SYN_123, download_file=False)

# AND an entity bundle where Synapse withheld the file handle because the
# caller has unmet access requirements
bundle = self.get_example_rest_api_file_output()
bundle["fileHandles"] = []
bundle["restrictionInformation"] = {"hasUnmetAccessRequirement": True}

# WHEN I get the example file
with patch(
"synapseclient.api.entity_factory.get_entity_id_bundle2",
new_callable=AsyncMock,
return_value=bundle,
):
result = await file.get_async(synapse_client=self.syn)

# THEN the data_file_handle_id from the entity should be preserved
assert result.id == SYN_123
assert result.data_file_handle_id == DATA_FILE_HANDLE_ID

# AND the file handle should have no metadata filled in
assert result.file_handle.id is None
assert result.content_md5 is None

async def test_get_with_path(self) -> None:
# GIVEN an example file
file = File(path=PATH, description=MODIFIED_DESCRIPTION)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,33 @@ async def side_effect(**kwargs):
assert result.id == SYN_123
assert result.name == RECORD_SET_NAME

async def test_get_async_with_unmet_access_requirement(self) -> None:
# GIVEN a RecordSet with an id
record_set = RecordSet(id=SYN_123, download_file=False)

# AND an entity bundle where Synapse withheld the file handle because the
# caller has unmet access requirements
bundle = {
"entity": _get_record_set_entity_response(),
"fileHandles": [],
"restrictionInformation": {"hasUnmetAccessRequirement": True},
}

# WHEN I call get_async
with patch(
"synapseclient.api.entity_factory.get_entity_id_bundle2",
new_callable=AsyncMock,
return_value=bundle,
):
result = await record_set.get_async(synapse_client=self.syn)

# THEN the data_file_handle_id from the entity should be preserved
assert result.id == SYN_123
assert result.data_file_handle_id == DATA_FILE_HANDLE_ID

# AND the file handle should have no metadata filled in
assert result.file_handle.id is None

async def test_get_async_with_path(self) -> None:
# GIVEN a RecordSet with a path (looking up by local file)
record_set = RecordSet(path=PATH)
Expand Down
Loading