Skip to content

Commit b2f1d3f

Browse files
committed
tests/_internal/remotes/test_gitlab(test) Add tests for GitLab subgroup support
why: Verify that GitLab subgroups with slash notation are correctly URL-encoded as %2F in API requests. what: - Add test_gitlab_subgroup_url_encoding for parent/child paths - Add test_gitlab_deeply_nested_subgroup for a/b/c/d paths - Both tests verify the URL contains properly encoded %2F sequences
1 parent b6bd08e commit b2f1d3f

1 file changed

Lines changed: 118 additions & 0 deletions

File tree

tests/_internal/remotes/test_gitlab.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import json
66
import typing as t
7+
import urllib.request
78

89
import pytest
910

@@ -156,3 +157,120 @@ def test_gitlab_uses_path_not_name(
156157
repos = list(importer.fetch_repos(options))
157158
assert len(repos) == 1
158159
assert repos[0].name == "my-project" # Uses 'path', not 'name'
160+
161+
162+
class MockHTTPResponse:
163+
"""Mock HTTP response for subgroup test."""
164+
165+
def __init__(self, body: bytes, headers: dict[str, str] | None = None) -> None:
166+
self._body = body
167+
self._headers = headers or {}
168+
self.status = 200
169+
self.code = 200
170+
171+
def read(self) -> bytes:
172+
return self._body
173+
174+
def getheaders(self) -> list[tuple[str, str]]:
175+
return list(self._headers.items())
176+
177+
def __enter__(self) -> MockHTTPResponse:
178+
return self
179+
180+
def __exit__(self, *args: t.Any) -> None:
181+
pass
182+
183+
184+
def test_gitlab_subgroup_url_encoding(
185+
monkeypatch: pytest.MonkeyPatch,
186+
) -> None:
187+
"""Test that GitLab subgroups are URL-encoded correctly.
188+
189+
Subgroups use slash notation (e.g., parent/child) which must be
190+
URL-encoded as %2F in API requests.
191+
"""
192+
captured_urls: list[str] = []
193+
194+
response_json = [
195+
{
196+
"path": "subgroup-project",
197+
"name": "Subgroup Project",
198+
"http_url_to_repo": "https://gitlab.com/parent/child/subgroup-project.git",
199+
"web_url": "https://gitlab.com/parent/child/subgroup-project",
200+
"description": "Project in subgroup",
201+
"topics": [],
202+
"star_count": 10,
203+
"archived": False,
204+
"default_branch": "main",
205+
"namespace": {"path": "parent/child"},
206+
}
207+
]
208+
209+
def urlopen_capture(
210+
request: urllib.request.Request,
211+
timeout: int | None = None,
212+
) -> MockHTTPResponse:
213+
captured_urls.append(request.full_url)
214+
return MockHTTPResponse(json.dumps(response_json).encode())
215+
216+
monkeypatch.setattr("urllib.request.urlopen", urlopen_capture)
217+
218+
importer = GitLabImporter()
219+
options = ImportOptions(mode=ImportMode.ORG, target="parent/child")
220+
repos = list(importer.fetch_repos(options))
221+
222+
# Verify the URL was encoded correctly
223+
assert len(captured_urls) == 1
224+
assert "parent%2Fchild" in captured_urls[0], (
225+
f"Expected URL-encoded subgroup path 'parent%2Fchild', got: {captured_urls[0]}"
226+
)
227+
assert "/groups/parent%2Fchild/projects" in captured_urls[0]
228+
229+
# Verify repos were returned
230+
assert len(repos) == 1
231+
assert repos[0].name == "subgroup-project"
232+
233+
234+
def test_gitlab_deeply_nested_subgroup(
235+
monkeypatch: pytest.MonkeyPatch,
236+
) -> None:
237+
"""Test that deeply nested subgroups (multiple slashes) work correctly."""
238+
captured_urls: list[str] = []
239+
240+
response_json = [
241+
{
242+
"path": "deep-project",
243+
"name": "Deep Project",
244+
"http_url_to_repo": "https://gitlab.com/a/b/c/d/deep-project.git",
245+
"web_url": "https://gitlab.com/a/b/c/d/deep-project",
246+
"description": "Deeply nested project",
247+
"topics": [],
248+
"star_count": 5,
249+
"archived": False,
250+
"default_branch": "main",
251+
"namespace": {"path": "a/b/c/d"},
252+
}
253+
]
254+
255+
def urlopen_capture(
256+
request: urllib.request.Request,
257+
timeout: int | None = None,
258+
) -> MockHTTPResponse:
259+
captured_urls.append(request.full_url)
260+
return MockHTTPResponse(json.dumps(response_json).encode())
261+
262+
monkeypatch.setattr("urllib.request.urlopen", urlopen_capture)
263+
264+
importer = GitLabImporter()
265+
# Test with 4 levels of nesting: a/b/c/d
266+
options = ImportOptions(mode=ImportMode.ORG, target="a/b/c/d")
267+
repos = list(importer.fetch_repos(options))
268+
269+
# Verify URL encoding - each slash should become %2F
270+
assert len(captured_urls) == 1
271+
assert "a%2Fb%2Fc%2Fd" in captured_urls[0], (
272+
f"Expected URL-encoded path 'a%2Fb%2Fc%2Fd', got: {captured_urls[0]}"
273+
)
274+
275+
assert len(repos) == 1
276+
assert repos[0].name == "deep-project"

0 commit comments

Comments
 (0)