Skip to content

Commit 8cbe591

Browse files
committed
test(api): add unit tests for feature flags and types
This adds unit tests for the new logic introduced with the feature flags API. - Verifies the custom `save()` method in `ProjectFeatureFlag` correctly handles renaming by using the old name in the URL and the new name in the request body. - Verifies the `CommaSeparatedStringAttribute` correctly converts a Python list to a comma-separated string for API calls. - Verifies the `JsonAttribute` correctly handles JSON string parsing.
1 parent b41e3a1 commit 8cbe591

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""
2+
Unit tests for Project Feature Flag User Lists.
3+
"""
4+
5+
import pytest
6+
import responses
7+
8+
from gitlab import Gitlab
9+
10+
11+
@pytest.fixture
12+
def project():
13+
gl = Gitlab("http://localhost", private_token="private_token", api_version="4")
14+
return gl.projects.get(1, lazy=True)
15+
16+
17+
def test_create_user_list_with_list_conversion(project):
18+
"""
19+
Verify that passing a list of integers for user_xids is converted
20+
to a comma-separated string in the API payload.
21+
"""
22+
with responses.RequestsMock() as rs:
23+
rs.add(
24+
responses.POST,
25+
"http://localhost/api/v4/projects/1/feature_flags_user_lists",
26+
json={"iid": 1, "name": "list", "user_xids": "1,2,3"},
27+
status=201,
28+
)
29+
30+
project.feature_flags_user_lists.create(
31+
{"name": "list", "user_xids": [1, 2, 3]}
32+
)
33+
34+
assert len(rs.calls) == 1
35+
# Verify that the list [1, 2, 3] was converted to "1,2,3" in the JSON body
36+
assert b'"user_xids": "1,2,3"' in rs.calls[0].request.body
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""
2+
Unit tests for Project Feature Flags.
3+
"""
4+
5+
import pytest
6+
import responses
7+
8+
from gitlab import Gitlab
9+
from gitlab.v4.objects import ProjectFeatureFlag
10+
11+
12+
@pytest.fixture
13+
def project():
14+
gl = Gitlab("http://localhost", private_token="private_token", api_version="4")
15+
return gl.projects.get(1, lazy=True)
16+
17+
18+
def test_feature_flag_rename(project):
19+
"""
20+
Verify that renaming a feature flag uses the old name in the URL
21+
and the new name in the payload.
22+
"""
23+
flag_content = {"name": "old_name", "version": "new_version_flag", "active": True}
24+
flag = ProjectFeatureFlag(project.feature_flags, flag_content)
25+
26+
# Simulate fetching from API (populates _attrs)
27+
flag._attrs = flag_content.copy()
28+
flag._updated_attrs = {}
29+
30+
# Rename locally
31+
flag.name = "new_name"
32+
33+
with responses.RequestsMock() as rs:
34+
rs.add(
35+
responses.PUT,
36+
"http://localhost/api/v4/projects/1/feature_flags/old_name",
37+
json={"name": "new_name", "version": "new_version_flag", "active": True},
38+
status=200,
39+
)
40+
41+
flag.save()
42+
43+
assert len(rs.calls) == 1
44+
# URL should use the old name (ID)
45+
assert rs.calls[0].request.url.endswith("/feature_flags/old_name")
46+
# Body should contain the new name
47+
assert b'"name": "new_name"' in rs.calls[0].request.body
48+
assert flag.name == "new_name"

tests/unit/test_types.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,40 @@ def test_csv_string_attribute_get_for_api_from_int_list():
122122
def test_lowercase_string_attribute_get_for_api():
123123
o = types.LowercaseStringAttribute("FOO")
124124
assert o.get_for_api(key="spam") == ("spam", "foo")
125+
126+
127+
# JSONAttribute tests
128+
def test_json_attribute() -> None:
129+
attr = types.JsonAttribute()
130+
131+
attr.set_from_cli('{"key": "value"}')
132+
assert attr.get() == {"key": "value"}
133+
134+
attr.set_from_cli(" ")
135+
assert attr.get() is None
136+
137+
138+
# CommaSeparatedStringAttribute tests
139+
def test_comma_separated_string_attribute() -> None:
140+
# Test with list of integers
141+
attr = types.CommaSeparatedStringAttribute([1, 2, 3])
142+
assert attr.get_for_api(key="ids") == ("ids", "1,2,3")
143+
144+
# Test with list of strings
145+
attr = types.CommaSeparatedStringAttribute(["a", "b"])
146+
assert attr.get_for_api(key="names") == ("names", "a,b")
147+
148+
# Test with string value (should be preserved)
149+
attr = types.CommaSeparatedStringAttribute("1,2,3")
150+
assert attr.get_for_api(key="ids") == ("ids", "1,2,3")
151+
152+
# Test CLI setting
153+
attr = types.CommaSeparatedStringAttribute()
154+
attr.set_from_cli("1, 2, 3")
155+
assert attr.get() == ["1", "2", "3"]
156+
157+
attr.set_from_cli("")
158+
assert attr.get() == []
159+
160+
# Verify transform_in_post is True
161+
assert types.CommaSeparatedStringAttribute.transform_in_post is True

0 commit comments

Comments
 (0)