Skip to content

Commit 01db887

Browse files
olexii4cursoragent
andcommitted
test: add IPv6 URL parsing examples
Cover IPv6 hosts for GitLab (including context path and port), GitHub server URLs, and Azure DevOps endpoints. Signed-off-by: Oleksii Orel <oorel@redhat.com> Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 1c59dc9 commit 01db887

File tree

4 files changed

+90
-13
lines changed

4 files changed

+90
-13
lines changed

wsmaster/che-core-api-factory-azure-devops/src/test/java/org/eclipse/che/api/factory/server/azure/devops/AzureDevOpsURLParserTest.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012-2025 Red Hat, Inc.
2+
* Copyright (c) 2012-2026 Red Hat, Inc.
33
* This program and the accompanying materials are made
44
* available under the terms of the Eclipse Public License 2.0
55
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -60,6 +60,25 @@ public void shouldParseWithUrlBranch() {
6060
assertEquals(azureDevOpsUrl.getBranch(), "main");
6161
}
6262

63+
@Test
64+
public void shouldParseServerUrlWithIpv6Host() {
65+
// given
66+
azureDevOpsURLParser =
67+
new AzureDevOpsURLParser(
68+
mock(DevfileFilenamesProvider.class),
69+
mock(PersonalAccessTokenManager.class),
70+
"https://[2001:db8::1]/");
71+
72+
// when
73+
AzureDevOpsUrl azureDevOpsUrl =
74+
azureDevOpsURLParser.parse("https://[2001:db8::1]/MyOrg/MyProject/_git/MyRepo", null);
75+
76+
// then
77+
assertEquals(azureDevOpsUrl.getOrganization(), "MyOrg");
78+
assertEquals(azureDevOpsUrl.getProject(), "MyProject");
79+
assertEquals(azureDevOpsUrl.getRepository(), "MyRepo");
80+
}
81+
6382
@Test(dataProvider = "parsing")
6483
public void testParse(
6584
String url,

wsmaster/che-core-api-factory-github/src/test/java/org/eclipse/che/api/factory/server/github/GithubURLParserTest.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012-2025 Red Hat, Inc.
2+
* Copyright (c) 2012-2026 Red Hat, Inc.
33
* This program and the accompanying materials are made
44
* available under the terms of the Eclipse Public License 2.0
55
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -100,6 +100,28 @@ public void shouldParseWithUrlBranch() throws ApiException {
100100
assertEquals(githubUrl.getBranch(), "master");
101101
}
102102

103+
@Test
104+
public void shouldParseGithubServerUrlWithIpv6Host() throws ApiException {
105+
// given
106+
githubUrlParser =
107+
new GithubURLParser(
108+
personalAccessTokenManager,
109+
devfileFilenamesProvider,
110+
githubApiClient,
111+
"https://[2001:db8::1]",
112+
false);
113+
when(githubApiClient.isConnected(eq("https://[2001:db8::1]"))).thenReturn(true);
114+
when(devfileFilenamesProvider.getConfiguredDevfileFilenames())
115+
.thenReturn(asList("devfile.yaml", ".devfile.yaml"));
116+
117+
// when
118+
GithubUrl githubUrl = githubUrlParser.parse("https://[2001:db8::1]/eclipse/che", null);
119+
120+
// then
121+
assertEquals(githubUrl.getUsername(), "eclipse");
122+
assertEquals(githubUrl.getRepository(), "che");
123+
}
124+
103125
/** Check URLs are valid with regexp */
104126
@Test(dataProvider = "UrlsProvider")
105127
public void checkRegexp(String url) {

wsmaster/che-core-api-factory-gitlab-common/src/main/java/org/eclipse/che/api/factory/server/gitlab/AbstractGitlabUrlParser.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,24 @@ public AbstractGitlabUrlParser(
7878
//
7979
// In that case, we treat "/scm" as part of the fixed endpoint prefix, not as part of the
8080
// repository path.
81-
final String endpointWithoutScheme =
82-
trimmedEndpoint.substring(trimmedEndpoint.indexOf("://") + 3);
83-
final int firstSlashIdx = endpointWithoutScheme.indexOf('/');
84-
final String authority =
85-
firstSlashIdx >= 0
86-
? endpointWithoutScheme.substring(0, firstSlashIdx)
87-
: endpointWithoutScheme;
88-
final String endpointPath =
89-
firstSlashIdx >= 0 ? endpointWithoutScheme.substring(firstSlashIdx) : "";
81+
final String authorityFromUri = uri.getAuthority();
82+
// Review feedback: use "hostname" naming instead of "endpointWithoutScheme".
83+
final String hostname = authorityFromUri;
84+
final String endpointPath = uri.getPath() == null ? "" : uri.getPath();
85+
86+
// What if URI#getAuthority() is null? Fallback to string parsing.
87+
final String authority;
88+
if (hostname != null) {
89+
authority = hostname;
90+
} else {
91+
final int schemeSeparatorIdx = trimmedEndpoint.indexOf("://");
92+
final String withoutScheme =
93+
schemeSeparatorIdx >= 0
94+
? trimmedEndpoint.substring(schemeSeparatorIdx + 3)
95+
: trimmedEndpoint;
96+
final int firstSlashIdx = withoutScheme.indexOf('/');
97+
authority = firstSlashIdx >= 0 ? withoutScheme.substring(0, firstSlashIdx) : withoutScheme;
98+
}
9099

91100
// authority may be:
92101
// - gitlab-server.com
@@ -104,7 +113,10 @@ public AbstractGitlabUrlParser(
104113

105114
// HTTP(S) patterns should match the configured endpoint prefix (including any extra path
106115
// segment). SSH pattern should match host only.
107-
final String httpHostForRegex = Pattern.quote(hostOnly + endpointPath);
116+
// For HTTP(S) patterns we include any configured endpointPath and keep the port (if any) as a
117+
// part of the "host" group. This allows GitlabUrl#getProviderUrl() to return values like
118+
// "https://host:8443/scm" even though GitlabUrl models "host" and "port" separately.
119+
final String httpHostForRegex = Pattern.quote(authority + endpointPath);
108120
final String sshHostForRegex = Pattern.quote(hostOnly);
109121
for (String gitlabUrlPatternTemplate : gitlabUrlPatternTemplates) {
110122
gitlabUrlPatterns.add(

wsmaster/che-core-api-factory-gitlab/src/test/java/org/eclipse/che/api/factory/server/gitlab/GitlabUrlParserTest.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012-2025 Red Hat, Inc.
2+
* Copyright (c) 2012-2026 Red Hat, Inc.
33
* This program and the accompanying materials are made
44
* available under the terms of the Eclipse Public License 2.0
55
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -89,6 +89,30 @@ public void shouldGetProviderUrlWithExtraSegment() throws ApiException {
8989
assertEquals(gitlabUrl.getProviderUrl(), "https://gitlab-server.com/scm");
9090
}
9191

92+
@Test
93+
public void shouldGetProviderUrlWithExtraSegmentOnIpv6Endpoint() throws ApiException {
94+
gitlabUrlParser =
95+
new GitlabUrlParser(
96+
"https://[2001:db8::1]/scm",
97+
devfileFilenamesProvider,
98+
mock(PersonalAccessTokenManager.class));
99+
GitlabUrl gitlabUrl =
100+
gitlabUrlParser.parse("https://[2001:db8::1]/scm/user/project/test.git", null);
101+
assertEquals(gitlabUrl.getProviderUrl(), "https://[2001:db8::1]/scm");
102+
}
103+
104+
@Test
105+
public void shouldGetProviderUrlWithExtraSegmentOnIpv6EndpointWithPort() throws ApiException {
106+
gitlabUrlParser =
107+
new GitlabUrlParser(
108+
"https://[2001:db8::1]:8443/scm",
109+
devfileFilenamesProvider,
110+
mock(PersonalAccessTokenManager.class));
111+
GitlabUrl gitlabUrl =
112+
gitlabUrlParser.parse("https://[2001:db8::1]:8443/scm/user/project/test.git", null);
113+
assertEquals(gitlabUrl.getProviderUrl(), "https://[2001:db8::1]:8443/scm");
114+
}
115+
92116
@Test
93117
public void shouldParseWithUrlBranch() throws ApiException {
94118
GitlabUrl gitlabUrl =

0 commit comments

Comments
 (0)