From 23bba7afc7eeb4d75539d46ae75b74e2513b75c1 Mon Sep 17 00:00:00 2001 From: Juan Pablo Vega Date: Wed, 22 Apr 2026 13:53:02 +0200 Subject: [PATCH] [fix] Resolve broken testset uploads --- api/oss/src/apis/fastapi/testsets/router.py | 12 ++ api/oss/src/core/testsets/service.py | 3 + .../testsets/test_testsets_files.py | 144 ++++++++++++++++++ 3 files changed, 159 insertions(+) diff --git a/api/oss/src/apis/fastapi/testsets/router.py b/api/oss/src/apis/fastapi/testsets/router.py index 05bf8b5643..e244bfd870 100644 --- a/api/oss/src/apis/fastapi/testsets/router.py +++ b/api/oss/src/apis/fastapi/testsets/router.py @@ -1240,8 +1240,20 @@ async def create_testset_revision_from_file( status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, ) from e + base_revision = await self.testsets_service.fetch_testset_revision( + project_id=UUID(request.state.project_id), + testset_revision_ref=Reference(id=testset_revision_id), + ) + if not base_revision: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Testset revision {testset_revision_id} not found.", + ) + testset_revision_commit_request = TestsetRevisionCommitRequest( testset_revision_commit=TestsetRevisionCommit( + testset_id=base_revision.testset_id, + testset_variant_id=base_revision.testset_variant_id, testset_revision_id=testset_revision_id, data=testset_revision_data, ), diff --git a/api/oss/src/core/testsets/service.py b/api/oss/src/core/testsets/service.py index 245e09fd56..4c594ad14a 100644 --- a/api/oss/src/core/testsets/service.py +++ b/api/oss/src/core/testsets/service.py @@ -887,6 +887,9 @@ async def commit_testset_revision( testset_revision_commit.data.testcases = None + if not testset_revision_commit.slug: + testset_revision_commit.slug = uuid4().hex[-12:] + revision_commit_payload = self._sanitize_testset_revision_payload( testset_revision_commit.model_dump( mode="json", diff --git a/api/oss/tests/pytest/acceptance/testsets/test_testsets_files.py b/api/oss/tests/pytest/acceptance/testsets/test_testsets_files.py index 22d06ad3a6..0dbab559d6 100644 --- a/api/oss/tests/pytest/acceptance/testsets/test_testsets_files.py +++ b/api/oss/tests/pytest/acceptance/testsets/test_testsets_files.py @@ -210,6 +210,150 @@ def test_fetch_testset_to_json_file(self, authed_api): assert len(parsed) == len(testcases_data) # ---------------------------------------------------------------------- + def test_create_testset_revision_from_csv_file(self, authed_api): + # ARRANGE -------------------------------------------------------------- + slug = uuid4().hex + + testset = { + "slug": slug, + "name": "Testset Name", + "description": "This is a testset description.", + "data": { + "testcases": [ + {"data": {"column1": "data1", "column2": "data2"}}, + ], + }, + } + + response = authed_api( + "POST", + "/simple/testsets/", + json={"testset": testset}, + ) + assert response.status_code == 200 + simple_testset = response.json()["testset"] + testset_revision_id = simple_testset["revision_id"] + # ---------------------------------------------------------------------- + + # ACT ------------------------------------------------------------------ + testcases_data = [ + {"column1": "new1", "column2": "new2"}, + {"column1": "new3", "column2": "new4"}, + ] + + with TemporaryFile("w+", newline="") as csvfile: + writer = DictWriter(csvfile, fieldnames=testcases_data[0].keys()) + writer.writeheader() + writer.writerows(testcases_data) + csvfile.seek(0) + + files = {"file": ("testset.csv", csvfile, "text/csv")} + data = {"file_type": "csv"} + + response = authed_api( + "POST", + f"/testsets/revisions/{testset_revision_id}/upload", + files=files, + data=data, + ) + # ---------------------------------------------------------------------- + + # ASSERT --------------------------------------------------------------- + assert response.status_code == 200 + body = response.json() + assert body["count"] == 1 + new_revision = body["testset_revision"] + assert new_revision is not None + assert new_revision["id"] != testset_revision_id + assert new_revision["testset_id"] == simple_testset["id"] + assert len(new_revision["data"]["testcases"]) == len(testcases_data) + # ---------------------------------------------------------------------- + + def test_create_testset_revision_from_json_file(self, authed_api): + # ARRANGE -------------------------------------------------------------- + slug = uuid4().hex + + testset = { + "slug": slug, + "name": "Testset Name", + "description": "This is a testset description.", + "data": { + "testcases": [ + {"data": {"column1": "data1"}}, + ], + }, + } + + response = authed_api( + "POST", + "/simple/testsets/", + json={"testset": testset}, + ) + assert response.status_code == 200 + simple_testset = response.json()["testset"] + testset_revision_id = simple_testset["revision_id"] + # ---------------------------------------------------------------------- + + # ACT ------------------------------------------------------------------ + testcases_data = [ + {"column1": "alpha", "column2": "beta"}, + {"column1": "gamma", "column2": "delta"}, + {"column1": "epsilon", "column2": "zeta"}, + ] + + with TemporaryFile("w+", newline="") as jsonfile: + jsonfile.write(dumps(testcases_data)) + jsonfile.seek(0) + + files = {"file": ("testset.json", jsonfile, "application/json")} + data = {"file_type": "json"} + + response = authed_api( + "POST", + f"/testsets/revisions/{testset_revision_id}/upload", + files=files, + data=data, + ) + # ---------------------------------------------------------------------- + + # ASSERT --------------------------------------------------------------- + assert response.status_code == 200 + body = response.json() + assert body["count"] == 1 + new_revision = body["testset_revision"] + assert new_revision is not None + assert new_revision["id"] != testset_revision_id + assert new_revision["testset_id"] == simple_testset["id"] + assert len(new_revision["data"]["testcases"]) == len(testcases_data) + # ---------------------------------------------------------------------- + + def test_create_testset_revision_from_file_unknown_revision_returns_404( + self, authed_api + ): + # ACT ------------------------------------------------------------------ + unknown_revision_id = uuid4() + + with TemporaryFile("w+", newline="") as csvfile: + writer = DictWriter(csvfile, fieldnames=["column1"]) + writer.writeheader() + writer.writerow({"column1": "data1"}) + csvfile.seek(0) + + files = {"file": ("testset.csv", csvfile, "text/csv")} + data = {"file_type": "csv"} + + response = authed_api( + "POST", + f"/testsets/revisions/{unknown_revision_id}/upload", + files=files, + data=data, + ) + # ---------------------------------------------------------------------- + + # ASSERT --------------------------------------------------------------- + assert response.status_code == 404 + # ---------------------------------------------------------------------- + def test_edit_testset_from_file(self, authed_api): # FIRST UPLOAD THEN UPLOAD AGAIN WITH CHANGES