diff --git a/server/forge/gitlab/convert.go b/server/forge/gitlab/convert.go index ad6dbea58..51d16bac3 100644 --- a/server/forge/gitlab/convert.go +++ b/server/forge/gitlab/convert.go @@ -303,7 +303,9 @@ func extractFromPath(str string) (string, string, error) { if len(s) < minPathComponents { return "", "", fmt.Errorf("minimum match not found") } - return s[0], s[1], nil + owner := strings.Join(s[:len(s)-1], "/") + name := s[len(s)-1] + return owner, name, nil } func convertLabels(from []*gitlab.EventLabel) []string { diff --git a/server/forge/gitlab/gitlab_test.go b/server/forge/gitlab/gitlab_test.go index 5197b9d01..5e0a5afe6 100644 --- a/server/forge/gitlab/gitlab_test.go +++ b/server/forge/gitlab/gitlab_test.go @@ -300,3 +300,68 @@ func Test_GitLab(t *testing.T) { }) }) } + +func TestExtractFromPath(t *testing.T) { + type testCase struct { + name string + input string + wantOwner string + wantName string + errContains string + } + + tests := []testCase{ + { + name: "basic two components", + input: "owner/repo", + wantOwner: "owner", + wantName: "repo", + }, + { + name: "three components", + input: "owner/group/repo", + wantOwner: "owner/group", + wantName: "repo", + }, + { + name: "many components", + input: "owner/group/subgroup/deep/repo", + wantOwner: "owner/group/subgroup/deep", + wantName: "repo", + }, + { + name: "empty string", + input: "", + errContains: "minimum match not found", + }, + { + name: "single component", + input: "onlyrepo", + errContains: "minimum match not found", + }, + { + name: "trailing slash", + input: "owner/repo/", + wantOwner: "owner/repo", + wantName: "", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + owner, name, err := extractFromPath(tc.input) + + // Check error expectations + if tc.errContains != "" { + if assert.Error(t, err) { + assert.Contains(t, err.Error(), tc.errContains) + } + return + } + + assert.NoError(t, err) + assert.EqualValues(t, tc.wantOwner, owner) + assert.EqualValues(t, tc.wantName, name) + }) + } +}