rio/internal/repo/repo_test.go
Alexander "PapaTutuWawa b9cc7f30e8
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
feat: Fix and test header parsing
2024-02-03 16:42:08 +01:00

551 lines
18 KiB
Go

package repo
import (
"errors"
"strings"
"testing"
"time"
"git.polynom.me/rio/internal/context"
"git.polynom.me/rio/internal/gitea"
log "github.com/sirupsen/logrus"
)
func TestHeaderFilter(t *testing.T) {
map1 := filterHeaders(
map[string]interface{}{
"Content-Type": "hallo",
"content-Type": "welt",
"content-type": "uwu",
"CONTENT-TYPE": "lol",
"Content-Security-Policy": "none",
},
)
if len(map1) != 1 {
t.Fatalf("filterHeaders allowed %d != 1 headers", len(map1))
}
for key := range map1 {
if strings.ToLower(key) == "content-type" {
t.Fatalf("filterHeaders allowed Content-Type")
}
}
}
func TestPickingCorrectRepositoryDefault(t *testing.T) {
// Test that we default to the <username>.<pages domain> repository, if we have only
// one path component.
log.SetLevel(log.DebugLevel)
client := gitea.GiteaClient{
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
if username != "example-user" {
t.Fatalf("Called with unknown user %s", username)
}
if repositoryName != "example-user.pages.example.org" {
t.Fatalf("Called with unknown repository %s", repositoryName)
}
return gitea.Repository{}, nil
},
HasBranch: func(username, repositoryName, branchName string) bool {
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
return true
}
return false
},
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
t.Fatal("getFile called")
return []byte{}, true, nil
},
LookupCNAME: func(domain string) (string, error) {
t.Fatal("LookupCNAME called")
return "", nil
},
LookupRepoTXT: func(domain string) (string, error) {
t.Fatal("LookupRepoTXT called")
return "", nil
},
}
ctx := &context.GlobalContext{
Gitea: &client,
Cache: &context.CacheContext{
RepositoryInformationCache: context.MakeRepoInfoCache(),
RepositoryPathCache: context.MakeRepoPathCache(),
},
}
res, path, err := RepoFromPath("example-user", "example-user.pages.example.org", "", "index.html", ctx)
if err != nil {
t.Fatalf("An error occured: %v", err)
}
if res == nil {
t.Fatal("Result is nil")
}
if path != "index.html" {
t.Fatalf("Returned path is invalid: %s", path)
}
}
func TestPickingCorrectRepositoryDefaultSubdirectory(t *testing.T) {
// Test that we return the default repository when the first path component does
// not correspong to an existing repository.
log.SetLevel(log.DebugLevel)
client := gitea.GiteaClient{
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
if username != "example-user" {
t.Fatalf("Called with unknown user %s", username)
}
if repositoryName == "assets" {
return gitea.Repository{}, errors.New("gitea.Repository does not exist")
} else if repositoryName == "example-user.pages.example.org" {
return gitea.Repository{}, nil
} else {
t.Fatalf("Called with unknown repository %s", repositoryName)
return gitea.Repository{}, nil
}
},
HasBranch: func(username, repositoryName, branchName string) bool {
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
return true
}
return false
},
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
t.Fatal("getFile called")
return []byte{}, true, nil
},
LookupCNAME: func(domain string) (string, error) {
t.Fatal("LookupCNAME called")
return "", nil
},
LookupRepoTXT: func(domain string) (string, error) {
t.Fatal("LookupRepoTXT called")
return "", nil
},
}
ctx := &context.GlobalContext{
Gitea: &client,
Cache: &context.CacheContext{
RepositoryInformationCache: context.MakeRepoInfoCache(),
RepositoryPathCache: context.MakeRepoPathCache(),
},
}
res, path, err := RepoFromPath("example-user", "example-user.pages.example.org", "", "assets/index.css", ctx)
if err != nil {
t.Fatalf("An error occured: %v", err)
}
if res == nil {
t.Fatal("Result is nil")
}
if path != "assets/index.css" {
t.Fatalf("Returned path is invalid: %s", path)
}
}
func TestPickingCorrectRepositorySubdirectoryNoPagesBranch(t *testing.T) {
// Test that we're picking the correct repository when the first path component
// returns a repository without a pages branch.
log.SetLevel(log.DebugLevel)
client := gitea.GiteaClient{
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
if username != "example-user" {
t.Fatalf("Called with unknown user %s", username)
}
if repositoryName == "blog" {
return gitea.Repository{
Name: "blog",
}, nil
} else if repositoryName == "example-user.pages.example.org" {
return gitea.Repository{
Name: "example-user.pages.example.org",
}, nil
} else {
t.Fatalf("Called with unknown repository %s", repositoryName)
return gitea.Repository{}, nil
}
},
HasBranch: func(username, repositoryName, branchName string) bool {
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
return true
}
return false
},
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
t.Fatal("getFile called")
return []byte{}, true, nil
},
LookupCNAME: func(domain string) (string, error) {
t.Fatal("LookupCNAME called")
return "", nil
},
LookupRepoTXT: func(domain string) (string, error) {
t.Fatal("LookupRepoTXT called")
return "", nil
},
}
ctx := &context.GlobalContext{
Gitea: &client,
Cache: &context.CacheContext{
RepositoryInformationCache: context.MakeRepoInfoCache(),
RepositoryPathCache: context.MakeRepoPathCache(),
},
}
res, path, err := RepoFromPath("example-user", "example-user.pages.example.org", "", "blog/post1.html", ctx)
if err != nil {
t.Fatalf("An error occured: %v", err)
}
if res == nil {
t.Fatal("Result is nil")
}
if res.Name != "example-user.pages.example.org" {
t.Fatalf("Invalid repository selected: %s", res.Name)
}
if path != "blog/post1.html" {
t.Fatalf("Returned path is invalid: %s", path)
}
}
func TestPickingNoRepositoryInvalidCNAME(t *testing.T) {
// Test that we're not picking a repository if the CNAME validation fails.
log.SetLevel(log.DebugLevel)
client := gitea.GiteaClient{
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
if username == "example-user" && repositoryName == "example-user.pages.example.org" {
return gitea.Repository{
Name: "example-user.pages.example.org",
}, nil
} else {
t.Fatalf("Called with unknown repository %s", repositoryName)
return gitea.Repository{}, nil
}
},
HasBranch: func(username, repositoryName, branchName string) bool {
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
return true
}
return false
},
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branch == "pages" && path == "rio.json" {
return []byte("{\"CNAME\": \"some-other-domain.local\"}"), true, nil
}
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
return []byte{}, true, nil
},
LookupCNAME: func(domain string) (string, error) {
return "", errors.New("No CNAME")
},
LookupRepoTXT: func(domain string) (string, error) {
return "", nil
},
}
ctx := &context.GlobalContext{
Gitea: &client,
Cache: &context.CacheContext{
RepositoryInformationCache: context.MakeRepoInfoCache(),
RepositoryPathCache: context.MakeRepoPathCache(),
},
}
_, _, err := RepoFromPath("example-user", "example-user.pages.example.org", "example-user.local", "index.html", ctx)
if err == nil {
t.Fatal("gitea.Repository returned even though CNAME validation should fail")
}
}
func TestPickingRepositoryValidCNAME(t *testing.T) {
// Test that we're picking a repository, given a CNAME, if the CNAME validation succeeds.
log.SetLevel(log.DebugLevel)
client := gitea.GiteaClient{
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
if username == "example-user" && repositoryName == "example-user.local" {
return gitea.Repository{
Name: "example-user.local",
}, nil
} else {
t.Fatalf("Called with unknown repository %s", repositoryName)
return gitea.Repository{}, nil
}
},
HasBranch: func(username, repositoryName, branchName string) bool {
if username == "example-user" && repositoryName == "example-user.local" && branchName == "pages" {
return true
}
return false
},
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
if username == "example-user" && repositoryName == "example-user.local" && branch == "pages" && path == "rio.json" {
return []byte("{\"CNAME\": \"example-user.local\"}"), true, nil
}
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
return []byte{}, true, nil
},
LookupCNAME: func(domain string) (string, error) {
return "", errors.New("No CNAME")
},
LookupRepoTXT: func(domain string) (string, error) {
return "", nil
},
}
ctx := &context.GlobalContext{
Gitea: &client,
Cache: &context.CacheContext{
RepositoryInformationCache: context.MakeRepoInfoCache(),
RepositoryPathCache: context.MakeRepoPathCache(),
},
}
repo, _, err := RepoFromPath("example-user", "example-user.local", "example-user.pages.example.org", "index.html", ctx)
if err != nil {
t.Fatalf("Error returned: %v", err)
}
if repo.Name != "example-user.local" {
t.Fatalf("Invalid repository name returned: %s", repo.Name)
}
}
func TestPickingRepositoryValidCNAMEWithTXTLookup(t *testing.T) {
// Test that we're picking a repository, given a CNAME, if the CNAME validation succeeds
// and the TXT lookup returns something different.
log.SetLevel(log.DebugLevel)
client := gitea.GiteaClient{
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
if username == "example-user" && repositoryName == "some-different-repository" {
return gitea.Repository{
Name: "some-different-repository",
}, nil
} else {
t.Fatalf("Called with unknown repository %s", repositoryName)
return gitea.Repository{}, nil
}
},
HasBranch: func(username, repositoryName, branchName string) bool {
if username == "example-user" && repositoryName == "some-different-repository" && branchName == "pages" {
return true
}
return false
},
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
if username == "example-user" && repositoryName == "some-different-repository" && branch == "pages" && path == "rio.json" {
return []byte("{\"CNAME\": \"example-user.local\"}"), true, nil
}
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
return []byte{}, true, nil
},
LookupCNAME: func(domain string) (string, error) {
return "", errors.New("No CNAME")
},
LookupRepoTXT: func(domain string) (string, error) {
if domain == "example-user.local" {
return "some-different-repository", nil
}
return "", nil
},
}
ctx := &context.GlobalContext{
Gitea: &client,
Cache: &context.CacheContext{
RepositoryInformationCache: context.MakeRepoInfoCache(),
RepositoryPathCache: context.MakeRepoPathCache(),
},
}
repo, _, err := RepoFromPath("example-user", "example-user.local", "example-user.pages.example.org", "index.html", ctx)
if err != nil {
t.Fatalf("Error returned: %v", err)
}
if repo.Name != "some-different-repository" {
t.Fatalf("Invalid repository name returned: %s", repo.Name)
}
}
func TestPickingRepositoryValidCNAMEWithTXTLookupAndSubdirectory(t *testing.T) {
// Test that we're picking a repository, given a CNAME, if the CNAME validation succeeds
// and the TXT lookup returns something different. Additionally, we now have a subdirectory
log.SetLevel(log.DebugLevel)
client := gitea.GiteaClient{
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
if username == "example-user" && repositoryName == "some-different-repository" {
return gitea.Repository{
Name: "some-different-repository",
}, nil
}
return gitea.Repository{}, errors.New("Unknown repository")
},
HasBranch: func(username, repositoryName, branchName string) bool {
if username == "example-user" && repositoryName == "some-different-repository" && branchName == "pages" {
return true
}
return false
},
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
if username == "example-user" && repositoryName == "some-different-repository" && branch == "pages" && path == "rio.json" {
return []byte("{\"CNAME\": \"example-user.local\"}"), true, nil
}
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
return []byte{}, true, nil
},
LookupCNAME: func(domain string) (string, error) {
return "", errors.New("No CNAME")
},
LookupRepoTXT: func(domain string) (string, error) {
if domain == "example-user.local" {
return "some-different-repository", nil
}
return "", nil
},
}
ctx := &context.GlobalContext{
Gitea: &client,
Cache: &context.CacheContext{
RepositoryInformationCache: context.MakeRepoInfoCache(),
RepositoryPathCache: context.MakeRepoPathCache(),
},
}
repo, _, err := RepoFromPath("example-user", "example-user.local", "example-user.pages.example.org", "blog/index.html", ctx)
if err != nil {
t.Fatalf("Error returned: %v", err)
}
if repo.Name != "some-different-repository" {
t.Fatalf("Invalid repository name returned: %s", repo.Name)
}
}
func TestHeaderParsingEmpty(t *testing.T) {
// Test that we are correctly handling a repository with no headers.
log.SetLevel(log.DebugLevel)
client := gitea.GiteaClient{
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
if username == "example-user" && repositoryName == "some-different-repository" {
return gitea.Repository{
Name: "some-different-repository",
}, nil
}
return gitea.Repository{}, errors.New("Unknown repository")
},
HasBranch: func(username, repositoryName, branchName string) bool {
if username == "example-user" && repositoryName == "some-different-repository" && branchName == "pages" {
return true
}
return false
},
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
if username == "example-user" && repositoryName == "some-different-repository" && branch == "pages" && path == "rio.json" {
return []byte("{\"CNAME\": \"example-user.local\"}"), true, nil
}
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
return []byte{}, true, nil
},
LookupCNAME: func(domain string) (string, error) {
return "", errors.New("No CNAME")
},
LookupRepoTXT: func(domain string) (string, error) {
if domain == "example-user.local" {
return "some-different-repository", nil
}
return "", nil
},
}
ctx := &context.GlobalContext{
Gitea: &client,
Cache: &context.CacheContext{
RepositoryInformationCache: context.MakeRepoInfoCache(),
RepositoryPathCache: context.MakeRepoPathCache(),
},
}
info := GetRepositoryInformation("example-user", "some-different-repository", ctx)
if info == nil {
t.Fatalf("No repository information returned")
}
if len(info.Headers) > 0 {
t.Fatalf("Headers returned: %v", info.Headers)
}
}
func TestHeaderParsing(t *testing.T) {
// Test that we are correctly handling a repository with no headers.
log.SetLevel(log.DebugLevel)
client := gitea.GiteaClient{
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
if username == "example-user" && repositoryName == "some-different-repository" {
return gitea.Repository{
Name: "some-different-repository",
}, nil
}
return gitea.Repository{}, errors.New("Unknown repository")
},
HasBranch: func(username, repositoryName, branchName string) bool {
if username == "example-user" && repositoryName == "some-different-repository" && branchName == "pages" {
return true
}
return false
},
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
if username == "example-user" && repositoryName == "some-different-repository" && branch == "pages" && path == "rio.json" {
return []byte("{\"CNAME\": \"example-user.local\", \"headers\": {\"X-Cool-Header\": \"Very nice!\"}}"), true, nil
}
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
return []byte{}, true, nil
},
LookupCNAME: func(domain string) (string, error) {
return "", errors.New("No CNAME")
},
LookupRepoTXT: func(domain string) (string, error) {
if domain == "example-user.local" {
return "some-different-repository", nil
}
return "", nil
},
}
ctx := &context.GlobalContext{
Gitea: &client,
Cache: &context.CacheContext{
RepositoryInformationCache: context.MakeRepoInfoCache(),
RepositoryPathCache: context.MakeRepoPathCache(),
},
}
info := GetRepositoryInformation("example-user", "some-different-repository", ctx)
if info == nil {
t.Fatalf("No repository information returned")
}
if len(info.Headers) != 1 {
t.Fatalf("len(info.Headers) != 1: %v", info.Headers)
}
header, found := info.Headers["X-Cool-Header"]
if !found {
t.Fatal("Header X-Cool-Header not found")
}
if header != "Very nice!" {
t.Fatalf("Invalid header value for X-Cool-Header: \"%s\"", header)
}
}