mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 19:11:25 +01:00
Repository arguments and --repo accept NAME (owned by the active account, or the --sudo user), OWNER/NAME.git and HOST/OWNER/NAME next to URLs; --host, TEA_HOST and GITEA_INSTANCE_URL accept a bare HOST[:PORT][/PATH], which takes the scheme of the configured instance it names, else https. --repo origin in a clone with that remote suggests --remote origin. Account errors name the instance, the accounts that are logged in and where the instance came from, such as "no account for https://gitea.com (instance from git remote \"origin\")", instead of "no selected account". Signed-off-by: bircni <bircni@icloud.com>
130 lines
6.2 KiB
Go
130 lines
6.2 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package settings
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestRepositoryURL(t *testing.T) {
|
|
ports := map[string]Host{"https://example.org:3000/base": {}, "https://example.org:3000": {}}
|
|
bases := map[string]Host{"https://example.org": {}, "https://example.org/base": {}}
|
|
sshPorts := map[string]Host{
|
|
"https://example.org/first": {SSHHost: "git.example.org:2222"},
|
|
"https://example.org/second": {SSHHost: "git.example.org:2223"},
|
|
}
|
|
for _, test := range []struct {
|
|
raw string
|
|
hosts map[string]Host
|
|
wantHost, wantRepo string
|
|
wantErr string
|
|
}{
|
|
{raw: "https://example.org:3000/base/alice/project.git", hosts: ports, wantHost: "https://example.org:3000/base", wantRepo: "alice/project"},
|
|
{raw: "https://unconfigured.example.org/group/alice/project.git", wantHost: "https://unconfigured.example.org/group", wantRepo: "alice/project"},
|
|
{raw: "ssh://git@git.example.org:2223/alice/project.git", hosts: sshPorts, wantHost: "https://example.org/second", wantRepo: "alice/project"},
|
|
{raw: "git@git.example.org:alice/project.git", hosts: sshPorts, wantErr: "does not match"},
|
|
{raw: "git@example.org:owner/repo.git", hosts: bases, wantErr: "multiple instances"},
|
|
{raw: "https://example.org/alice/project/issues/7", hosts: bases, wantErr: "ambiguous"},
|
|
{raw: "https://example.org/alice/project/pulls/3", hosts: bases, wantErr: "ambiguous"},
|
|
{raw: "https://example.org/base/alice/project/src/branch/main", hosts: bases, wantErr: "ambiguous"},
|
|
{raw: "https://example.org/alice/project/actions/runs/9", hosts: bases, wantErr: "ambiguous"},
|
|
{raw: "https://unconfigured.example.org/alice/project/issues/7", wantErr: "ambiguous"},
|
|
{raw: "https://unconfigured.example.org/alice/project/issues", wantErr: "ambiguous"},
|
|
{raw: "https://unconfigured.example.org/alice/project/pulls", wantErr: "ambiguous"},
|
|
{raw: "https://unconfigured.example.org/alice/project/src/branch/main", wantErr: "ambiguous"},
|
|
{raw: "https://unconfigured.example.org/group/alice/issues.git", wantHost: "https://unconfigured.example.org/group", wantRepo: "alice/issues"},
|
|
{raw: "ssh://git:private-test-password@example.org/alice/project.git", wantErr: "must not embed credentials"},
|
|
} {
|
|
host, repo, err := RepositoryURL(test.raw, test.hosts)
|
|
if test.wantErr != "" {
|
|
require.ErrorContains(t, err, test.wantErr, test.raw)
|
|
require.NotContains(t, err.Error(), "private-test-password")
|
|
continue
|
|
}
|
|
require.NoError(t, err, test.raw)
|
|
require.Equal(t, test.wantHost, host, test.raw)
|
|
require.Equal(t, test.wantRepo, repo, test.raw)
|
|
}
|
|
}
|
|
|
|
func TestRemoteIsSSH(t *testing.T) {
|
|
for remote, want := range map[string]bool{
|
|
"ssh://git@example.org/alice/project.git": true,
|
|
"git@example.org:alice/project.git": true,
|
|
"https://example.org/alice/project.git": false,
|
|
"http://example.org/alice/project.git": false,
|
|
"file:///tmp/repo.git": false,
|
|
} {
|
|
require.Equal(t, want, RemoteIsSSH(remote), remote)
|
|
}
|
|
}
|
|
|
|
func TestParseRemoteReadsSCPStyleRemotes(t *testing.T) {
|
|
u, err := ParseRemote("git@git.example.org:alice/project.git")
|
|
require.NoError(t, err)
|
|
require.Equal(t, "ssh://git@git.example.org/alice/project.git", u.String())
|
|
}
|
|
|
|
func TestParseRepositoryAcceptsShorthands(t *testing.T) {
|
|
hosts := map[string]Host{"http://localhost:3001": {}, "https://example.org/gitea": {}, "https://example.org": {}}
|
|
for _, tc := range []struct {
|
|
raw string
|
|
want RepositoryRef
|
|
err string
|
|
}{
|
|
{raw: "project", want: RepositoryRef{Name: "project"}},
|
|
{raw: "alice/project", want: RepositoryRef{Owner: "alice", Name: "project"}},
|
|
{raw: "alice/project.git", want: RepositoryRef{Owner: "alice", Name: "project"}},
|
|
{raw: " alice/project ", want: RepositoryRef{Owner: "alice", Name: "project"}},
|
|
{raw: "localhost:3001/alice/project", want: RepositoryRef{Host: "http://localhost:3001", Owner: "alice", Name: "project"}},
|
|
{raw: "LOCALHOST:3001/alice/project.git", want: RepositoryRef{Host: "http://localhost:3001", Owner: "alice", Name: "project"}},
|
|
{raw: "example.org/gitea/alice/project", want: RepositoryRef{Host: "https://example.org/gitea", Owner: "alice", Name: "project"}},
|
|
{raw: "example.org/alice/project", want: RepositoryRef{Host: "https://example.org", Owner: "alice", Name: "project"}},
|
|
{raw: "gitea.com/gitea/tea", want: RepositoryRef{Host: "https://gitea.com", Owner: "gitea", Name: "tea"}},
|
|
{raw: "http://localhost:3001/alice/project.git", want: RepositoryRef{Host: "http://localhost:3001", Owner: "alice", Name: "project"}},
|
|
{raw: "a/b/c/d", err: `invalid repository "a/b/c/d": use OWNER/REPO, HOST/OWNER/REPO or a URL`},
|
|
{raw: "alice/", err: "invalid repository"},
|
|
{raw: "../x", err: "invalid repository"},
|
|
{raw: "", err: "invalid repository"},
|
|
} {
|
|
got, err := ParseRepository(tc.raw, hosts)
|
|
if tc.err != "" {
|
|
require.ErrorContains(t, err, tc.err, tc.raw)
|
|
continue
|
|
}
|
|
require.NoError(t, err, tc.raw)
|
|
require.Equal(t, tc.want, got, tc.raw)
|
|
}
|
|
require.Equal(t, "project", RepositoryRef{Name: "project"}.Slug())
|
|
require.Equal(t, "alice/project", RepositoryRef{Owner: "alice", Name: "project"}.Slug())
|
|
}
|
|
|
|
func TestResolveHostAcceptsBareHosts(t *testing.T) {
|
|
hosts := map[string]Host{"http://localhost:3001": {}, "https://example.org/gitea": {}}
|
|
for raw, want := range map[string]string{
|
|
"localhost:3001": "http://localhost:3001",
|
|
"localhost:3001/": "http://localhost:3001",
|
|
"example.org/gitea": "https://example.org/gitea",
|
|
"gitea.com": "https://gitea.com",
|
|
"https://localhost:3001": "https://localhost:3001",
|
|
"https://gitea.com:443/x/": "https://gitea.com/x",
|
|
"http://example.org/gitea/": "http://example.org/gitea",
|
|
} {
|
|
got, err := ResolveHost(raw, hosts)
|
|
require.NoError(t, err, raw)
|
|
require.Equal(t, want, got, raw)
|
|
}
|
|
_, err := ResolveHost("localhost:3001", map[string]Host{"http://localhost:3001": {}, "https://localhost:3001": {}})
|
|
require.ErrorContains(t, err, "include the scheme")
|
|
_, err = ResolveHost("bad host", hosts)
|
|
require.ErrorContains(t, err, `invalid instance "bad host"`)
|
|
}
|
|
|
|
func TestValidSlugRejectsSCPStyleRemotes(t *testing.T) {
|
|
require.True(t, ValidSlug("alice/project"))
|
|
require.False(t, ValidSlug("git@example.org:alice/project.git"))
|
|
}
|