Skip to content

Commit 5edd2e6

Browse files
rickbrouwerJohnVillalovos
authored andcommitted
feat(api): add support for avatar removal
When attempting to remove for example a group or project avatar by setting it to an empty string, the current implementation raises a validation error about unsupported file formats.
1 parent 8dbdd7e commit 5edd2e6

File tree

7 files changed

+125
-0
lines changed

7 files changed

+125
-0
lines changed

docs/gl_objects/groups.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ Set the avatar image for a group::
8282
group.avatar = open('path/to/file.png', 'rb')
8383
group.save()
8484

85+
Remove the avatar image for a group::
86+
87+
group.avatar = ""
88+
group.save()
89+
8590
Remove a group::
8691

8792
gl.groups.delete(group_id)

docs/gl_objects/projects.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ Set the avatar image for a project::
109109
project.avatar = open('path/to/file.png', 'rb')
110110
project.save()
111111

112+
Remove the avatar image for a project::
113+
114+
project.avatar = ""
115+
project.save()
116+
112117
Delete a project::
113118

114119
gl.projects.delete(project_id)

docs/gl_objects/topics.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,16 @@ Delete a topic::
5050
Merge a source topic into a target topic::
5151

5252
gl.topics.merge(topic_id, target_topic_id)
53+
54+
Set the avatar image for a topic::
55+
56+
# the avatar image can be passed as data (content of the file) or as a file
57+
# object opened in binary mode
58+
topic.avatar = open('path/to/file.png', 'rb')
59+
topic.save()
60+
61+
Remove the avatar image for a topic::
62+
63+
topic.avatar = ""
64+
topic.save()
65+

gitlab/utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ def _transform_types(
188188

189189
# if the type is FileAttribute we need to pass the data as file
190190
if isinstance(gitlab_attribute, types.FileAttribute) and transform_files:
191+
# The GitLab API accepts mixed types
192+
# (e.g. a file for avatar image or empty string for removing the avatar)
193+
# So if string is empty, keep it in data dict
194+
if isinstance(data[attr_name], str) and data[attr_name] == "":
195+
continue
196+
191197
key = gitlab_attribute.get_file_name(attr_name)
192198
files[attr_name] = (key, data.pop(attr_name))
193199
continue

tests/functional/api/test_groups.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,34 @@ def test_group_labels(group):
138138
label.delete()
139139

140140

141+
def test_group_avatar_upload(gl, group, fixture_dir):
142+
"""Test uploading an avatar to a group."""
143+
# Upload avatar
144+
with open(fixture_dir / "avatar.png", "rb") as avatar_file:
145+
group.avatar = avatar_file
146+
group.save()
147+
148+
# Verify the avatar was set
149+
updated_group = gl.groups.get(group.id)
150+
assert updated_group.avatar_url is not None
151+
152+
153+
def test_group_avatar_remove(gl, group, fixture_dir):
154+
"""Test removing an avatar from a group."""
155+
# First set an avatar
156+
with open(fixture_dir / "avatar.png", "rb") as avatar_file:
157+
group.avatar = avatar_file
158+
group.save()
159+
160+
# Now remove the avatar
161+
group.avatar = ""
162+
group.save()
163+
164+
# Verify the avatar was removed
165+
updated_group = gl.groups.get(group.id)
166+
assert updated_group.avatar_url is None
167+
168+
141169
@pytest.mark.gitlab_premium
142170
@pytest.mark.xfail(reason="/ldap/groups endpoint not documented")
143171
def test_ldap_groups(gl):

tests/functional/api/test_projects.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,29 @@ def test_project_members(user, project):
4848
member.delete()
4949

5050

51+
def test_project_avatar_upload(gl, project, fixture_dir):
52+
"""Test uploading an avatar to a project."""
53+
with open(fixture_dir / "avatar.png", "rb") as avatar_file:
54+
project.avatar = avatar_file
55+
project.save()
56+
57+
updated_project = gl.projects.get(project.id)
58+
assert updated_project.avatar_url is not None
59+
60+
61+
def test_project_avatar_remove(gl, project, fixture_dir):
62+
"""Test removing an avatar from a project."""
63+
with open(fixture_dir / "avatar.png", "rb") as avatar_file:
64+
project.avatar = avatar_file
65+
project.save()
66+
67+
project.avatar = ""
68+
project.save()
69+
70+
updated_project = gl.projects.get(project.id)
71+
assert updated_project.avatar_url is None
72+
73+
5174
def test_project_badges(project):
5275
badge_image = "http://example.com"
5376
badge_link = "http://example/img.svg"

tests/functional/api/test_topics.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,48 @@ def test_topics(gl, gitlab_version):
3131
assert merged_topic["id"] == topic2.id
3232

3333
topic2.delete()
34+
35+
36+
def test_topic_avatar_upload(gl, fixture_dir):
37+
"""Test uploading an avatar to a topic."""
38+
39+
topic = gl.topics.create(
40+
{
41+
"name": "avatar-topic",
42+
"description": "Topic with avatar",
43+
"title": "Avatar Topic",
44+
}
45+
)
46+
47+
with open(fixture_dir / "avatar.png", "rb") as avatar_file:
48+
topic.avatar = avatar_file
49+
topic.save()
50+
51+
updated_topic = gl.topics.get(topic.id)
52+
assert updated_topic.avatar_url is not None
53+
54+
topic.delete()
55+
56+
57+
def test_topic_avatar_remove(gl, fixture_dir):
58+
"""Test removing an avatar from a topic."""
59+
60+
topic = gl.topics.create(
61+
{
62+
"name": "avatar-topic-remove",
63+
"description": "Remove avatar",
64+
"title": "Remove Avatar",
65+
}
66+
)
67+
68+
with open(fixture_dir / "avatar.png", "rb") as avatar_file:
69+
topic.avatar = avatar_file
70+
topic.save()
71+
72+
topic.avatar = ""
73+
topic.save()
74+
75+
updated_topic = gl.topics.get(topic.id)
76+
assert updated_topic.avatar_url is None
77+
78+
topic.delete()

0 commit comments

Comments
 (0)