Files
Gists/internal/web/handlers/git/http_test.go
Thomas Miceli 6a61b720ab Improve test suite (#628)
Signed-off-by: Thomas Miceli <tho.miceli@gmail.com>
2026-03-02 15:43:24 +08:00

236 lines
6.9 KiB
Go

package git_test
import (
"net/url"
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"github.com/thomiceli/opengist/internal/db"
webtest "github.com/thomiceli/opengist/internal/web/test"
)
func gitClone(baseUrl, creds, user, gistId, destDir string) error {
authUrl := baseUrl
if creds != "" {
authUrl = "http://" + creds + "@" + baseUrl[len("http://"):]
}
return exec.Command("git", "clone", authUrl+"/"+user+"/"+gistId+".git", destDir).Run()
}
func gitPush(repoDir, filename, content string) error {
if err := os.WriteFile(filepath.Join(repoDir, filename), []byte(content), 0644); err != nil {
return err
}
if err := exec.Command("git", "-C", repoDir, "add", filename).Run(); err != nil {
return err
}
if err := exec.Command("git", "-C", repoDir, "commit", "-m", "add "+filename).Run(); err != nil {
return err
}
return exec.Command("git", "-C", repoDir, "push", "origin").Run()
}
func TestGitClonePull(t *testing.T) {
s := webtest.Setup(t)
defer webtest.Teardown(t)
baseUrl := s.StartHttpServer(t)
s.Register(t, "thomas")
s.Register(t, "alice")
_, _, user, publicId := s.CreateGist(t, "0")
_, _, _, unlistedId := s.CreateGist(t, "1")
_, _, _, privateId := s.CreateGist(t, "2")
type credTest struct {
name string
creds string
expect [3]bool // [public, unlisted, private]
}
tests := []struct {
name string
settings map[string]string
creds []credTest
}{
{
name: "Default",
creds: []credTest{
{"OwnerAuth", "thomas:thomas", [3]bool{true, true, true}},
{"OtherUserAuth", "alice:alice", [3]bool{true, true, false}},
{"WrongPassword", "thomas:wrong", [3]bool{true, true, false}},
{"WrongUser", "aze:aze", [3]bool{true, true, false}},
{"Anonymous", "", [3]bool{true, true, false}},
},
},
{
name: "RequireLogin",
settings: map[string]string{db.SettingRequireLogin: "1"},
creds: []credTest{
{"OwnerAuth", "thomas:thomas", [3]bool{true, true, true}},
{"OtherUserAuth", "alice:alice", [3]bool{true, true, false}},
{"WrongPassword", "thomas:wrong", [3]bool{false, false, false}},
{"WrongUser", "aze:aze", [3]bool{false, false, false}},
{"Anonymous", "", [3]bool{false, false, false}},
},
},
{
name: "AllowGistsWithoutLogin",
settings: map[string]string{db.SettingRequireLogin: "1", db.SettingAllowGistsWithoutLogin: "1"},
creds: []credTest{
{"OwnerAuth", "thomas:thomas", [3]bool{true, true, true}},
{"OtherUserAuth", "alice:alice", [3]bool{true, true, false}},
{"WrongPassword", "thomas:wrong", [3]bool{true, true, false}},
{"WrongUser", "aze:aze", [3]bool{true, true, false}},
{"Anonymous", "", [3]bool{true, true, false}},
},
},
}
gists := [3]string{publicId, unlistedId, privateId}
labels := [3]string{"Public", "Unlisted", "Private"}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s.Login(t, "thomas")
for k, v := range tt.settings {
s.Request(t, "PUT", "/admin-panel/set-config", url.Values{"key": {k}, "value": {v}}, 200)
}
for _, ct := range tt.creds {
t.Run(ct.name, func(t *testing.T) {
for i, id := range gists {
t.Run(labels[i], func(t *testing.T) {
dest := t.TempDir()
err := gitClone(baseUrl, ct.creds, user, id, dest)
if ct.expect[i] {
require.NoError(t, err)
_, err = os.Stat(filepath.Join(dest, "file.txt"))
require.NoError(t, err)
} else {
require.Error(t, err)
}
})
}
})
}
// Reset settings
s.Login(t, "thomas")
for k := range tt.settings {
s.Request(t, "PUT", "/admin-panel/set-config", url.Values{"key": {k}, "value": {"0"}}, 200)
}
})
}
}
func TestGitPush(t *testing.T) {
s := webtest.Setup(t)
defer webtest.Teardown(t)
baseUrl := s.StartHttpServer(t)
s.Register(t, "thomas")
s.Register(t, "alice")
_, _, user, publicId := s.CreateGist(t, "0")
_, _, _, unlistedId := s.CreateGist(t, "1")
_, _, _, privateId := s.CreateGist(t, "2")
type credTest struct {
name string
creds string
expect [3]bool // [public, unlisted, private]
}
tests := []credTest{
{"OwnerAuth", "thomas:thomas", [3]bool{true, true, true}},
{"OtherUserAuth", "alice:alice", [3]bool{false, false, false}},
{"WrongPassword", "thomas:wrong", [3]bool{false, false, false}},
{"WrongUser", "aze:aze", [3]bool{false, false, false}},
{"Anonymous", "", [3]bool{false, false, false}},
}
gists := [3]string{publicId, unlistedId, privateId}
labels := [3]string{"Public", "Unlisted", "Private"}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
for i, id := range gists {
t.Run(labels[i], func(t *testing.T) {
dest := t.TempDir()
require.NoError(t, gitClone(baseUrl, "thomas:thomas", user, id, dest))
if tt.creds != "thomas:thomas" {
require.NoError(t, exec.Command("git", "-C", dest, "remote", "set-url", "origin",
"http://"+tt.creds+"@"+baseUrl[len("http://"):]+"/"+user+"/"+id+".git").Run())
}
err := gitPush(dest, "newfile.txt", "new content")
if tt.expect[i] {
require.NoError(t, err)
} else {
require.Error(t, err)
}
})
}
})
}
}
func TestGitCreatePush(t *testing.T) {
s := webtest.Setup(t)
defer webtest.Teardown(t)
baseUrl := s.StartHttpServer(t)
s.Register(t, "thomas")
s.Register(t, "alice")
gitInitAndPush := func(t *testing.T, creds, remoteUrl string) error {
dest := t.TempDir()
require.NoError(t, exec.Command("git", "init", "--initial-branch=master", dest).Run())
require.NoError(t, exec.Command("git", "-C", dest, "remote", "add", "origin",
"http://"+creds+"@"+baseUrl[len("http://"):]+remoteUrl).Run())
require.NoError(t, os.WriteFile(filepath.Join(dest, "hello.txt"), []byte("hello"), 0644))
require.NoError(t, exec.Command("git", "-C", dest, "add", "hello.txt").Run())
require.NoError(t, exec.Command("git", "-C", dest, "commit", "-m", "initial").Run())
return exec.Command("git", "-C", dest, "push", "origin").Run()
}
tests := []struct {
name string
creds string
url string
expect bool
gistOwner string // if expect=true, verify gist exists at this owner/identifier
gistId string
}{
{"OwnerCreates", "thomas:thomas", "/thomas/mygist.git", true, "thomas", "mygist"},
{"OtherUserCreatesOnOwnUrl", "alice:alice", "/alice/alicegist.git", true, "alice", "alicegist"},
{"WrongPassword", "thomas:wrong", "/thomas/newgist.git", false, "", ""},
{"OtherUserCannotCreateOnOwner", "alice:alice", "/thomas/hackgist.git", false, "", ""},
{"WrongUser", "aze:aze", "/aze/azegist.git", false, "", ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := gitInitAndPush(t, tt.creds, tt.url)
if tt.expect {
require.NoError(t, err)
gist, err := db.GetGist(tt.gistOwner, tt.gistId)
require.NoError(t, err)
require.NotNil(t, gist)
require.Equal(t, tt.gistId, gist.Identifier())
} else {
require.Error(t, err)
}
})
}
}