Skip to content

Commit 65422cf

Browse files
authored
[SYNPY-1557] Sync a Linked Folder Bug (#1157)
* fixes docstring * protocol docstring * fix imports * adds integration test for expected behavior * adds fix * merge weirdness * fix test docstring
1 parent cd8820a commit 65422cf

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

synapseclient/models/mixins/storable_container.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,13 +686,15 @@ async def _follow_link(
686686
or not (entity := entity_bundle.get("entity", None))
687687
or not (links_to := entity.get("linksTo", None))
688688
or not (link_class_name := entity.get("linksToClassName", None))
689+
or not (link_target_name := entity.get("name", None))
689690
or not (link_target_id := links_to.get("targetId", None))
690691
):
691692
return
692693

693694
pending_tasks = self._create_task_for_child(
694695
child={
695696
"id": link_target_id,
697+
"name": link_target_name,
696698
"type": link_class_name,
697699
},
698700
recursive=recursive,

tests/integration/synapseutils/test_synapseutils_sync.py

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1992,7 +1992,7 @@ async def test_folder_sync_from_synapse_files_spread_across_folders(
19921992
assert pd.isna(matching_row[ACTIVITY_DESCRIPTION_COLUMN].values[0])
19931993
assert found_matching_file
19941994

1995-
async def test_sync_from_synapse_follow_links(
1995+
async def test_sync_from_synapse_follow_links_files(
19961996
self,
19971997
syn: Synapse,
19981998
schedule_for_cleanup: Callable[..., None],
@@ -2082,6 +2082,95 @@ async def test_sync_from_synapse_follow_links(
20822082
assert pd.isna(matching_row[ACTIVITY_NAME_COLUMN].values[0])
20832083
assert pd.isna(matching_row[ACTIVITY_DESCRIPTION_COLUMN].values[0])
20842084

2085+
async def test_sync_from_synapse_follow_links_folder(
2086+
self,
2087+
syn: Synapse,
2088+
schedule_for_cleanup: Callable[..., None],
2089+
project_model: Project,
2090+
) -> None:
2091+
"""
2092+
Testing for this case:
2093+
2094+
project_model (root)
2095+
├── folder_with_files
2096+
│ ├── file1 (uploaded)
2097+
│ └── file2 (uploaded)
2098+
└── folder_with_links - This is the folder we are syncing from
2099+
└── link_to_folder_with_files -> ../folder_with_files
2100+
"""
2101+
# GIVEN a folder
2102+
folder_with_files = await Folder(
2103+
name=str(uuid.uuid4()), parent_id=project_model.id
2104+
).store_async()
2105+
schedule_for_cleanup(folder_with_files.id)
2106+
2107+
# AND two files in the folder
2108+
temp_files = [utils.make_bogus_uuid_file() for _ in range(2)]
2109+
file_entities = []
2110+
for file in temp_files:
2111+
schedule_for_cleanup(file)
2112+
file_entity = syn.store(SynapseFile(path=file, parent=folder_with_files.id))
2113+
schedule_for_cleanup(file_entity["id"])
2114+
file_entities.append(file_entity)
2115+
2116+
# AND a second folder to sync from
2117+
folder_with_links = await Folder(
2118+
name=str(uuid.uuid4()), parent_id=project_model.id
2119+
).store_async()
2120+
schedule_for_cleanup(folder_with_links.id)
2121+
2122+
# AND a link to folder_with_files in folder_with_links
2123+
syn.store(obj=Link(targetId=folder_with_files.id, parent=folder_with_links.id))
2124+
2125+
# AND a temp directory to write the manifest file to
2126+
temp_dir = tempfile.mkdtemp()
2127+
2128+
# WHEN I sync the parent folder from Synapse
2129+
sync_result = synapseutils.syncFromSynapse(
2130+
syn=syn, entity=folder_with_links.id, path=temp_dir, followLink=True
2131+
)
2132+
2133+
# THEN I expect that the result has all of the files
2134+
assert len(sync_result) == 2
2135+
2136+
# AND each of the files are the ones we uploaded
2137+
for file in sync_result:
2138+
assert file in file_entities
2139+
2140+
# AND the manifest that is created matches the expected values
2141+
manifest_df = pd.read_csv(os.path.join(temp_dir, MANIFEST_FILE), sep="\t")
2142+
assert manifest_df.shape[0] == 2
2143+
assert PATH_COLUMN in manifest_df.columns
2144+
assert PARENT_COLUMN in manifest_df.columns
2145+
assert USED_COLUMN in manifest_df.columns
2146+
assert EXECUTED_COLUMN in manifest_df.columns
2147+
assert ACTIVITY_NAME_COLUMN in manifest_df.columns
2148+
assert ACTIVITY_DESCRIPTION_COLUMN in manifest_df.columns
2149+
assert CONTENT_TYPE_COLUMN in manifest_df.columns
2150+
assert ID_COLUMN in manifest_df.columns
2151+
assert SYNAPSE_STORE_COLUMN in manifest_df.columns
2152+
assert NAME_COLUMN in manifest_df.columns
2153+
assert manifest_df.shape[1] == 10
2154+
2155+
for file in sync_result:
2156+
matching_row = manifest_df[manifest_df[PATH_COLUMN] == file[PATH_COLUMN]]
2157+
assert not matching_row.empty
2158+
assert matching_row[PARENT_COLUMN].values[0] == file[PARENT_ATTRIBUTE]
2159+
assert (
2160+
matching_row[CONTENT_TYPE_COLUMN].values[0] == file[CONTENT_TYPE_COLUMN]
2161+
)
2162+
assert matching_row[ID_COLUMN].values[0] == file[ID_COLUMN]
2163+
assert (
2164+
matching_row[SYNAPSE_STORE_COLUMN].values[0]
2165+
== file[SYNAPSE_STORE_COLUMN]
2166+
)
2167+
assert matching_row[NAME_COLUMN].values[0] == file[NAME_COLUMN]
2168+
2169+
assert pd.isna(matching_row[USED_COLUMN].values[0])
2170+
assert pd.isna(matching_row[EXECUTED_COLUMN].values[0])
2171+
assert pd.isna(matching_row[ACTIVITY_NAME_COLUMN].values[0])
2172+
assert pd.isna(matching_row[ACTIVITY_DESCRIPTION_COLUMN].values[0])
2173+
20852174
async def test_sync_from_synapse_follow_links_sync_contains_all_folders(
20862175
self,
20872176
syn: Synapse,

0 commit comments

Comments
 (0)