From 8818ff559d2181dea44c4436ae189971d653cc4c Mon Sep 17 00:00:00 2001 From: igennova Date: Wed, 1 Apr 2026 00:24:07 +0530 Subject: [PATCH 1/3] Refactor setups_untag tests --- tests/routers/openml/setups_untag_test.py | 117 ++++++++++++++-------- 1 file changed, 74 insertions(+), 43 deletions(-) diff --git a/tests/routers/openml/setups_untag_test.py b/tests/routers/openml/setups_untag_test.py index 985df7d..2abfa52 100644 --- a/tests/routers/openml/setups_untag_test.py +++ b/tests/routers/openml/setups_untag_test.py @@ -1,4 +1,3 @@ -import re from http import HTTPStatus import httpx @@ -6,7 +5,10 @@ from sqlalchemy import text from sqlalchemy.ext.asyncio import AsyncConnection -from tests.users import ApiKey +from core.errors import SetupNotFoundError, TagNotFoundError, TagNotOwnedError +from database.users import User +from routers.openml.setups import untag_setup +from tests.users import ADMIN_USER, OWNER_USER, SOME_USER, ApiKey async def test_setup_untag_missing_auth(py_api: httpx.AsyncClient) -> None: @@ -16,70 +18,99 @@ async def test_setup_untag_missing_auth(py_api: httpx.AsyncClient) -> None: assert response.json()["detail"] == "No API key provided." -async def test_setup_untag_unknown_setup(py_api: httpx.AsyncClient) -> None: - response = await py_api.post( - f"/setup/untag?api_key={ApiKey.SOME_USER}", - json={"setup_id": 999999, "tag": "test_tag"}, - ) - assert response.status_code == HTTPStatus.NOT_FOUND - assert re.match( - r"Setup \d+ not found.", - response.json()["detail"], +@pytest.mark.mut +async def test_setup_untag_api_success( + py_api: httpx.AsyncClient, expdb_test: AsyncConnection +) -> None: + tag = "setup_untag_via_http" + await expdb_test.execute( + text("INSERT INTO setup_tag (id, tag, uploader) VALUES (1, :tag, 2);"), + parameters={"tag": tag}, ) - -async def test_setup_untag_tag_not_found(py_api: httpx.AsyncClient) -> None: response = await py_api.post( f"/setup/untag?api_key={ApiKey.SOME_USER}", - json={"setup_id": 1, "tag": "non_existent_tag_12345"}, + json={"setup_id": 1, "tag": tag}, ) - assert response.status_code == HTTPStatus.NOT_FOUND - assert re.match( - r"Setup \d+ does not have tag '\S+'.", - response.json()["detail"], + + assert response.status_code == HTTPStatus.OK + expected = {"setup_untag": {"id": "1", "tag": []}} + assert expected == response.json() + + rows = await expdb_test.execute( + text("SELECT * FROM setup_tag WHERE id = 1 AND tag = :tag"), + parameters={"tag": tag}, ) + assert len(rows.all()) == 0 + + +# ── Direct call tests: untag_setup ── + + +async def test_setup_untag_unknown_setup(expdb_test: AsyncConnection) -> None: + with pytest.raises(SetupNotFoundError, match=r"Setup \d+ not found."): + await untag_setup( + setup_id=999999, + tag="test_tag", + user=SOME_USER, + expdb_db=expdb_test, + ) + + +async def test_setup_untag_tag_not_found(expdb_test: AsyncConnection) -> None: + tag = "non_existent_tag_12345" + with pytest.raises(TagNotFoundError, match=rf"Setup 1 does not have tag '{tag}'\."): + await untag_setup( + setup_id=1, + tag=tag, + user=SOME_USER, + expdb_db=expdb_test, + ) @pytest.mark.mut -async def test_setup_untag_not_owned_by_you( - py_api: httpx.AsyncClient, expdb_test: AsyncConnection -) -> None: +async def test_setup_untag_not_owned_by_you(expdb_test: AsyncConnection) -> None: + tag = "setup_untag_forbidden" await expdb_test.execute( - text("INSERT INTO setup_tag (id, tag, uploader) VALUES (1, 'test_unit_tag_123', 2);") - ) - response = await py_api.post( - f"/setup/untag?api_key={ApiKey.OWNER_USER}", - json={"setup_id": 1, "tag": "test_unit_tag_123"}, - ) - assert response.status_code == HTTPStatus.FORBIDDEN - assert re.match( - r"You may not remove tag '\S+' of setup \d+ because it was not created by you.", - response.json()["detail"], + text("INSERT INTO setup_tag (id, tag, uploader) VALUES (1, :tag, 2);"), + parameters={"tag": tag}, ) + with pytest.raises( + TagNotOwnedError, + match=rf"You may not remove tag '{tag}' of setup 1 because it was not created by you\.", + ): + await untag_setup( + setup_id=1, + tag=tag, + user=OWNER_USER, + expdb_db=expdb_test, + ) @pytest.mark.mut @pytest.mark.parametrize( - "api_key", - [ApiKey.SOME_USER, ApiKey.ADMIN], + "user", + [SOME_USER, ADMIN_USER], ids=["Owner", "Administrator"], ) -async def test_setup_untag_success( - api_key: str, py_api: httpx.AsyncClient, expdb_test: AsyncConnection -) -> None: +async def test_setup_untag_direct_success(user: User, expdb_test: AsyncConnection) -> None: + tag = "setup_untag_via_direct" await expdb_test.execute( - text("INSERT INTO setup_tag (id, tag, uploader) VALUES (1, 'test_success_tag', 2)") + text("INSERT INTO setup_tag (id, tag, uploader) VALUES (1, :tag, 2);"), + parameters={"tag": tag}, ) - response = await py_api.post( - f"/setup/untag?api_key={api_key}", - json={"setup_id": 1, "tag": "test_success_tag"}, + result = await untag_setup( + setup_id=1, + tag=tag, + user=user, + expdb_db=expdb_test, ) - assert response.status_code == HTTPStatus.OK - assert response.json() == {"setup_untag": {"id": "1", "tag": []}} + assert result == {"setup_untag": {"id": "1", "tag": []}} rows = await expdb_test.execute( - text("SELECT * FROM setup_tag WHERE id = 1 AND tag = 'test_success_tag'") + text("SELECT * FROM setup_tag WHERE id = 1 AND tag = :tag"), + parameters={"tag": tag}, ) assert len(rows.all()) == 0 From 98ed60981a59eb836d83089bee5c7d6bcb491f78 Mon Sep 17 00:00:00 2001 From: igennova Date: Wed, 1 Apr 2026 00:51:41 +0530 Subject: [PATCH 2/3] valid suggestion --- tests/routers/openml/setups_untag_test.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/routers/openml/setups_untag_test.py b/tests/routers/openml/setups_untag_test.py index 2abfa52..b2b48b6 100644 --- a/tests/routers/openml/setups_untag_test.py +++ b/tests/routers/openml/setups_untag_test.py @@ -85,6 +85,11 @@ async def test_setup_untag_not_owned_by_you(expdb_test: AsyncConnection) -> None user=OWNER_USER, expdb_db=expdb_test, ) + rows = await expdb_test.execute( + text("SELECT * FROM setup_tag WHERE id = 1 AND tag = :tag"), + parameters={"tag": tag}, + ) + assert len(rows.all()) == 1 @pytest.mark.mut From eb289bd311917bb26a14db9dab196bf3e4851217 Mon Sep 17 00:00:00 2001 From: igennova Date: Fri, 3 Apr 2026 00:08:30 +0530 Subject: [PATCH 3/3] removed redundant test --- tests/routers/openml/setups_untag_test.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/routers/openml/setups_untag_test.py b/tests/routers/openml/setups_untag_test.py index b2b48b6..3adc37f 100644 --- a/tests/routers/openml/setups_untag_test.py +++ b/tests/routers/openml/setups_untag_test.py @@ -6,7 +6,6 @@ from sqlalchemy.ext.asyncio import AsyncConnection from core.errors import SetupNotFoundError, TagNotFoundError, TagNotOwnedError -from database.users import User from routers.openml.setups import untag_setup from tests.users import ADMIN_USER, OWNER_USER, SOME_USER, ApiKey @@ -93,12 +92,10 @@ async def test_setup_untag_not_owned_by_you(expdb_test: AsyncConnection) -> None @pytest.mark.mut -@pytest.mark.parametrize( - "user", - [SOME_USER, ADMIN_USER], - ids=["Owner", "Administrator"], -) -async def test_setup_untag_direct_success(user: User, expdb_test: AsyncConnection) -> None: +async def test_setup_untag_admin_removes_tag_uploaded_by_another_user( + expdb_test: AsyncConnection, +) -> None: + """Administrator can remove a tag uploaded by another user.""" tag = "setup_untag_via_direct" await expdb_test.execute( text("INSERT INTO setup_tag (id, tag, uploader) VALUES (1, :tag, 2);"), @@ -108,7 +105,7 @@ async def test_setup_untag_direct_success(user: User, expdb_test: AsyncConnectio result = await untag_setup( setup_id=1, tag=tag, - user=user, + user=ADMIN_USER, expdb_db=expdb_test, )