From fdc6ff22baba912a51c96d8c925670d70209bfcf Mon Sep 17 00:00:00 2001 From: Rijul Poudel Date: Wed, 22 Jul 2026 13:22:53 -0500 Subject: [PATCH 1/3] [test]: preserve imported data and mapping --- specifyweb/backend/workbench/tests.py | 53 +++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/specifyweb/backend/workbench/tests.py b/specifyweb/backend/workbench/tests.py index 8a452c79416..3530be85cb6 100644 --- a/specifyweb/backend/workbench/tests.py +++ b/specifyweb/backend/workbench/tests.py @@ -118,3 +118,56 @@ def test_create_record_set(self) -> None: rs = Recordset.objects.get(id=recordset_id) self.assertEqual(rs.recordsetitems.count(), 3) + + # [WorkBench] Preserve imported data and mapping after reopening a dataset + def test_preserve_imported_data_and_mapping(self) -> None: + client = Client() + client.force_login(self.specifyuser) + + columns = ["Catalog Number", "Remarks"] + rows = [["123", "First row"], ["456", "Second row"]] + uploadplan = { + "baseTableName": "collectionobject", + "uploadable": { + "uploadTable": { + "wbcols": { + "catalognumber": "Catalog Number", + "remarks": "Remarks", + }, + "static": {}, + "toOne": {}, + "toMany": {}, + } + }, + } + + response = client.post( + "/api/workbench/dataset/", + data={ + "name": "Imported dataset", + "columns": columns, + "rows": rows, + "importedfilename": "records.csv", + }, + content_type="application/json", + ) + self.assertEqual(response.status_code, 201) + datasetid = json.loads(response.content)["id"] + + response = client.put( + f"/api/workbench/dataset/{datasetid}/", + data={"uploadplan": uploadplan}, + content_type="application/json", + ) + self.assertEqual(response.status_code, 204) + + response = client.get(f"/api/workbench/dataset/{datasetid}/") + self.assertEqual(response.status_code, 200) + dataset = json.loads(response.content) + + self.assertEqual(dataset["columns"], columns) + self.assertEqual( + [row[: len(columns)] for row in dataset["rows"]], + rows, + ) + self.assertEqual(dataset["uploadplan"], uploadplan) \ No newline at end of file From ad91a09d17114d8153dbb6d22a23857c6ec198b1 Mon Sep 17 00:00:00 2001 From: Rijul Poudel Date: Wed, 22 Jul 2026 13:35:13 -0500 Subject: [PATCH 2/3] [fix]: assert complete workbench rows --- specifyweb/backend/workbench/tests.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/specifyweb/backend/workbench/tests.py b/specifyweb/backend/workbench/tests.py index 3530be85cb6..92da19098f1 100644 --- a/specifyweb/backend/workbench/tests.py +++ b/specifyweb/backend/workbench/tests.py @@ -167,7 +167,8 @@ def test_preserve_imported_data_and_mapping(self) -> None: self.assertEqual(dataset["columns"], columns) self.assertEqual( - [row[: len(columns)] for row in dataset["rows"]], - rows, + dataset["rows"], + [row + [""] for row in rows], ) - self.assertEqual(dataset["uploadplan"], uploadplan) \ No newline at end of file + self.assertEqual(dataset["uploadplan"], uploadplan) + \ No newline at end of file From 0aeae1f7aa8037e6943dcf9fbf9d6dedc9595ff8 Mon Sep 17 00:00:00 2001 From: "Caroline D." <108160931+CarolineDenis@users.noreply.github.com> Date: Tue, 28 Jul 2026 08:15:21 +0000 Subject: [PATCH 3/3] Lint code with ESLint and Prettier Triggered by 785660ba90ff99c92ffceafeb99cac953b947cc4 on branch refs/heads/issue-8338 --- .../frontend/js_src/lib/components/Errors/ErrorDialog.tsx | 4 +--- .../js_src/lib/components/SetupTool/setupResources.ts | 3 +-- .../js_src/lib/components/WbUtils/datasetVariants.tsx | 6 ++---- .../js_src/lib/localization/utils/validateWeblate.ts | 1 - 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/specifyweb/frontend/js_src/lib/components/Errors/ErrorDialog.tsx b/specifyweb/frontend/js_src/lib/components/Errors/ErrorDialog.tsx index 33dee9aec75..788a316f603 100644 --- a/specifyweb/frontend/js_src/lib/components/Errors/ErrorDialog.tsx +++ b/specifyweb/frontend/js_src/lib/components/Errors/ErrorDialog.tsx @@ -48,9 +48,7 @@ const errorBody = ( ), discourseLink: (label): JSX.Element => ( - - {label} - + {label} ), }} string={mainText.errorResolutionSecondDescription()} diff --git a/specifyweb/frontend/js_src/lib/components/SetupTool/setupResources.ts b/specifyweb/frontend/js_src/lib/components/SetupTool/setupResources.ts index 64360d3c645..aeb037e1ed3 100644 --- a/specifyweb/frontend/js_src/lib/components/SetupTool/setupResources.ts +++ b/specifyweb/frontend/js_src/lib/components/SetupTool/setupResources.ts @@ -156,8 +156,7 @@ export const resources: RA = [ resourceName: 'institution', label: setupToolText.institution(), description: setupToolText.institutionDescription(), - documentationUrl: - 'https://speciforum.org/t/guided-setup/3234', + documentationUrl: 'https://speciforum.org/t/guided-setup/3234', fields: [ { name: 'name', diff --git a/specifyweb/frontend/js_src/lib/components/WbUtils/datasetVariants.tsx b/specifyweb/frontend/js_src/lib/components/WbUtils/datasetVariants.tsx index dd8ca3826a8..76a5757f362 100644 --- a/specifyweb/frontend/js_src/lib/components/WbUtils/datasetVariants.tsx +++ b/specifyweb/frontend/js_src/lib/components/WbUtils/datasetVariants.tsx @@ -55,8 +55,7 @@ const baseWbVariant = { doSuccessful: wbText.uploadSuccessful(), }, }, - documentationUrl: - 'https://speciforum.org/t/the-specify-7-workbench/540', + documentationUrl: 'https://speciforum.org/t/the-specify-7-workbench/540', } as const; // Defines a shared interface to access dataset variants @@ -145,8 +144,7 @@ export const datasetVariants = { route: (id: number) => `/specify/attachments/import/${id}`, // Actually, in retrorespect, this would be a nice feature metaRoute: f.never, - documentationUrl: - 'https://speciforum.org/t/batch-attachment-uploader/1374', + documentationUrl: 'https://speciforum.org/t/batch-attachment-uploader/1374', }, } as const; diff --git a/specifyweb/frontend/js_src/lib/localization/utils/validateWeblate.ts b/specifyweb/frontend/js_src/lib/localization/utils/validateWeblate.ts index d37b73ddf9b..40c6123a697 100644 --- a/specifyweb/frontend/js_src/lib/localization/utils/validateWeblate.ts +++ b/specifyweb/frontend/js_src/lib/localization/utils/validateWeblate.ts @@ -96,7 +96,6 @@ const doFetch = async (url: string): Promise> => headers: { Authorization: getToken() }, }).then(async (response) => response.json()); - const fetchComponents = async ( url = componentsApiUrl ): Promise>> =>