Skip to content

Commit aac199e

Browse files
igennovaigennova
andauthored
tests: refactor setup untag tests (#304)
# Description - One happy-path check via the test client with a full expected JSON body. - Other cases call untag_setup directly. - Parametrized direct success for owner and admin; SQL uses bound parameters. --------- Co-authored-by: igennova <luckynegi025@gmail.com>
1 parent bbcf3ab commit aac199e

1 file changed

Lines changed: 77 additions & 44 deletions

File tree

Lines changed: 77 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import re
21
from http import HTTPStatus
32

43
import httpx
54
import pytest
65
from sqlalchemy import text
76
from sqlalchemy.ext.asyncio import AsyncConnection
87

9-
from tests.users import ApiKey
8+
from core.errors import SetupNotFoundError, TagNotFoundError, TagNotOwnedError
9+
from routers.openml.setups import untag_setup
10+
from tests.users import ADMIN_USER, OWNER_USER, SOME_USER, ApiKey
1011

1112

1213
async def test_setup_untag_missing_auth(py_api: httpx.AsyncClient) -> None:
@@ -16,70 +17,102 @@ async def test_setup_untag_missing_auth(py_api: httpx.AsyncClient) -> None:
1617
assert response.json()["detail"] == "No API key provided."
1718

1819

19-
async def test_setup_untag_unknown_setup(py_api: httpx.AsyncClient) -> None:
20-
response = await py_api.post(
21-
f"/setup/untag?api_key={ApiKey.SOME_USER}",
22-
json={"setup_id": 999999, "tag": "test_tag"},
23-
)
24-
assert response.status_code == HTTPStatus.NOT_FOUND
25-
assert re.match(
26-
r"Setup \d+ not found.",
27-
response.json()["detail"],
20+
@pytest.mark.mut
21+
async def test_setup_untag_api_success(
22+
py_api: httpx.AsyncClient, expdb_test: AsyncConnection
23+
) -> None:
24+
tag = "setup_untag_via_http"
25+
await expdb_test.execute(
26+
text("INSERT INTO setup_tag (id, tag, uploader) VALUES (1, :tag, 2);"),
27+
parameters={"tag": tag},
2828
)
2929

30-
31-
async def test_setup_untag_tag_not_found(py_api: httpx.AsyncClient) -> None:
3230
response = await py_api.post(
3331
f"/setup/untag?api_key={ApiKey.SOME_USER}",
34-
json={"setup_id": 1, "tag": "non_existent_tag_12345"},
32+
json={"setup_id": 1, "tag": tag},
3533
)
36-
assert response.status_code == HTTPStatus.NOT_FOUND
37-
assert re.match(
38-
r"Setup \d+ does not have tag '\S+'.",
39-
response.json()["detail"],
34+
35+
assert response.status_code == HTTPStatus.OK
36+
expected = {"setup_untag": {"id": "1", "tag": []}}
37+
assert expected == response.json()
38+
39+
rows = await expdb_test.execute(
40+
text("SELECT * FROM setup_tag WHERE id = 1 AND tag = :tag"),
41+
parameters={"tag": tag},
4042
)
43+
assert len(rows.all()) == 0
44+
45+
46+
# ── Direct call tests: untag_setup ──
47+
48+
49+
async def test_setup_untag_unknown_setup(expdb_test: AsyncConnection) -> None:
50+
with pytest.raises(SetupNotFoundError, match=r"Setup \d+ not found."):
51+
await untag_setup(
52+
setup_id=999999,
53+
tag="test_tag",
54+
user=SOME_USER,
55+
expdb_db=expdb_test,
56+
)
57+
58+
59+
async def test_setup_untag_tag_not_found(expdb_test: AsyncConnection) -> None:
60+
tag = "non_existent_tag_12345"
61+
with pytest.raises(TagNotFoundError, match=rf"Setup 1 does not have tag '{tag}'\."):
62+
await untag_setup(
63+
setup_id=1,
64+
tag=tag,
65+
user=SOME_USER,
66+
expdb_db=expdb_test,
67+
)
4168

4269

4370
@pytest.mark.mut
44-
async def test_setup_untag_not_owned_by_you(
45-
py_api: httpx.AsyncClient, expdb_test: AsyncConnection
46-
) -> None:
71+
async def test_setup_untag_not_owned_by_you(expdb_test: AsyncConnection) -> None:
72+
tag = "setup_untag_forbidden"
4773
await expdb_test.execute(
48-
text("INSERT INTO setup_tag (id, tag, uploader) VALUES (1, 'test_unit_tag_123', 2);")
49-
)
50-
response = await py_api.post(
51-
f"/setup/untag?api_key={ApiKey.OWNER_USER}",
52-
json={"setup_id": 1, "tag": "test_unit_tag_123"},
74+
text("INSERT INTO setup_tag (id, tag, uploader) VALUES (1, :tag, 2);"),
75+
parameters={"tag": tag},
5376
)
54-
assert response.status_code == HTTPStatus.FORBIDDEN
55-
assert re.match(
56-
r"You may not remove tag '\S+' of setup \d+ because it was not created by you.",
57-
response.json()["detail"],
77+
with pytest.raises(
78+
TagNotOwnedError,
79+
match=rf"You may not remove tag '{tag}' of setup 1 because it was not created by you\.",
80+
):
81+
await untag_setup(
82+
setup_id=1,
83+
tag=tag,
84+
user=OWNER_USER,
85+
expdb_db=expdb_test,
86+
)
87+
rows = await expdb_test.execute(
88+
text("SELECT * FROM setup_tag WHERE id = 1 AND tag = :tag"),
89+
parameters={"tag": tag},
5890
)
91+
assert len(rows.all()) == 1
5992

6093

6194
@pytest.mark.mut
62-
@pytest.mark.parametrize(
63-
"api_key",
64-
[ApiKey.SOME_USER, ApiKey.ADMIN],
65-
ids=["Owner", "Administrator"],
66-
)
67-
async def test_setup_untag_success(
68-
api_key: str, py_api: httpx.AsyncClient, expdb_test: AsyncConnection
95+
async def test_setup_untag_admin_removes_tag_uploaded_by_another_user(
96+
expdb_test: AsyncConnection,
6997
) -> None:
98+
"""Administrator can remove a tag uploaded by another user."""
99+
tag = "setup_untag_via_direct"
70100
await expdb_test.execute(
71-
text("INSERT INTO setup_tag (id, tag, uploader) VALUES (1, 'test_success_tag', 2)")
101+
text("INSERT INTO setup_tag (id, tag, uploader) VALUES (1, :tag, 2);"),
102+
parameters={"tag": tag},
72103
)
73104

74-
response = await py_api.post(
75-
f"/setup/untag?api_key={api_key}",
76-
json={"setup_id": 1, "tag": "test_success_tag"},
105+
result = await untag_setup(
106+
setup_id=1,
107+
tag=tag,
108+
user=ADMIN_USER,
109+
expdb_db=expdb_test,
77110
)
78111

79-
assert response.status_code == HTTPStatus.OK
80-
assert response.json() == {"setup_untag": {"id": "1", "tag": []}}
112+
assert result == {"setup_untag": {"id": "1", "tag": []}}
81113

82114
rows = await expdb_test.execute(
83-
text("SELECT * FROM setup_tag WHERE id = 1 AND tag = 'test_success_tag'")
115+
text("SELECT * FROM setup_tag WHERE id = 1 AND tag = :tag"),
116+
parameters={"tag": tag},
84117
)
85118
assert len(rows.all()) == 0

0 commit comments

Comments
 (0)