201 lines
7.5 KiB
Go
201 lines
7.5 KiB
Go
package forgejo
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestCreateRegistryTokenUsesBasicAuthAndPackageScopes(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
|
if request.Method != http.MethodPost || request.URL.Path != "/api/v1/users/registry-user/tokens" {
|
|
t.Fatal("unexpected Forgejo token request")
|
|
}
|
|
username, password, ok := request.BasicAuth()
|
|
if !ok || username != "registry-user" || password != "password" {
|
|
t.Fatal("Forgejo token request did not use the supplied basic authentication")
|
|
}
|
|
if request.Header.Get("X-Forgejo-OTP") != "123456" || request.Header.Get("Content-Type") != "application/json" {
|
|
t.Fatal("Forgejo token request headers are incorrect")
|
|
}
|
|
var body createTokenRequest
|
|
if err := json.NewDecoder(request.Body).Decode(&body); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if body.Name != "maidn-registry" || !reflect.DeepEqual(body.Scopes, []string{"read:package", "write:package"}) {
|
|
t.Fatal("Forgejo token request did not use the least-privilege package scopes")
|
|
}
|
|
writer.Header().Set("Content-Type", "application/json")
|
|
writer.WriteHeader(http.StatusCreated)
|
|
_, _ = writer.Write([]byte(`{"sha1":"registry-token"}`))
|
|
}))
|
|
defer server.Close()
|
|
|
|
token, err := createRegistryToken(server.Client(), server.URL, "registry-user", "password", "123456", "maidn-registry")
|
|
if err != nil || token != "registry-token" {
|
|
t.Fatal("CreateRegistryToken() did not return the Forgejo token")
|
|
}
|
|
}
|
|
|
|
func TestRepoExistsOnlyCreatesOnNotFound(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
|
writer.WriteHeader(http.StatusUnauthorized)
|
|
}))
|
|
defer server.Close()
|
|
manager := NewRepoManager(server.URL, "token", "owner", "user", "manifests", "cluster", "main", "maidn/bootstrap-test")
|
|
manager.HTTPClient = server.Client()
|
|
if _, err := manager.repoExists("cluster"); err == nil {
|
|
t.Fatal("repoExists() accepted an unauthorized response")
|
|
}
|
|
}
|
|
|
|
func TestEnsureWebhookUpdatesMatchingURL(t *testing.T) {
|
|
requests := 0
|
|
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
|
requests++
|
|
switch request.Method {
|
|
case http.MethodGet:
|
|
if request.URL.Path != "/api/v1/repos/owner/app/hooks" {
|
|
t.Fatalf("unexpected lookup path %q", request.URL.Path)
|
|
}
|
|
_ = json.NewEncoder(writer).Encode([]hook{{ID: 7, URL: "https://tekton.example.test/"}})
|
|
case http.MethodPatch:
|
|
if request.URL.Path != "/api/v1/repos/owner/app/hooks/7" {
|
|
t.Fatalf("unexpected update path %q", request.URL.Path)
|
|
}
|
|
var body hookRequest
|
|
if err := json.NewDecoder(request.Body).Decode(&body); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if body.Type != "" || body.AuthorizationHeader != "Bearer token" || len(body.Events) != 2 {
|
|
t.Fatalf("unexpected hook request: %#v", body)
|
|
}
|
|
writer.WriteHeader(http.StatusOK)
|
|
default:
|
|
t.Fatalf("unexpected method %q", request.Method)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
manager := NewRepoManager(server.URL, "token", "owner", "user", "manifests", "cluster", "main", "maidn/bootstrap-test")
|
|
manager.HTTPClient = server.Client()
|
|
if err := manager.EnsureWebhook("app", "https://tekton.example.test/", "Bearer token"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if requests != 2 {
|
|
t.Fatalf("requests = %d, want 2", requests)
|
|
}
|
|
}
|
|
|
|
func TestEnsureWebhookCreatesMissingWebhook(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
|
switch request.Method {
|
|
case http.MethodGet:
|
|
_ = json.NewEncoder(writer).Encode([]hook{})
|
|
case http.MethodPost:
|
|
var body hookRequest
|
|
if err := json.NewDecoder(request.Body).Decode(&body); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if body.Type != "forgejo" || body.Config["content_type"] != "json" {
|
|
t.Fatalf("unexpected hook request: %#v", body)
|
|
}
|
|
writer.WriteHeader(http.StatusCreated)
|
|
default:
|
|
t.Fatalf("unexpected method %q", request.Method)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
manager := NewRepoManager(server.URL, "token", "owner", "user", "manifests", "cluster", "main", "maidn/bootstrap-test")
|
|
manager.HTTPClient = server.Client()
|
|
if err := manager.EnsureWebhook("app", "https://tekton.example.test/", "Bearer token"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestRepositoryFromURL(t *testing.T) {
|
|
owner, repo, err := RepositoryFromURL("https://git.example.test/team/app.git")
|
|
if err != nil || owner != "team" || repo != "app" {
|
|
t.Fatalf("RepositoryFromURL() = (%q, %q, %v)", owner, repo, err)
|
|
}
|
|
}
|
|
|
|
func TestEnsureRepositoryCreatesWithoutInitialization(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
|
switch request.Method {
|
|
case http.MethodGet:
|
|
writer.WriteHeader(http.StatusNotFound)
|
|
case http.MethodPost:
|
|
var body createRepoRequest
|
|
if err := json.NewDecoder(request.Body).Decode(&body); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if body.AutoInit {
|
|
t.Fatal("application repository must be created without an initial commit")
|
|
}
|
|
writer.WriteHeader(http.StatusCreated)
|
|
default:
|
|
t.Fatalf("unexpected method %q", request.Method)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
manager := NewRepoManager(server.URL, "token", "owner", "user", "manifests", "cluster", "main", "maidn/bootstrap-test")
|
|
manager.HTTPClient = server.Client()
|
|
created, err := manager.EnsureRepository("app", "description")
|
|
if err != nil || !created {
|
|
t.Fatalf("EnsureRepository() = (%t, %v)", created, err)
|
|
}
|
|
}
|
|
|
|
func TestHasRemoteBranchReturnsFalseForMissingBranch(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
|
writer.WriteHeader(http.StatusNotFound)
|
|
}))
|
|
defer server.Close()
|
|
manager := NewRepoManager(server.URL, "token", "owner", "user", "manifests", "cluster", "main", "maidn/bootstrap-test")
|
|
manager.HTTPClient = server.Client()
|
|
if _, err := manager.HasRemoteBranch(server.URL, "main"); err == nil {
|
|
t.Fatal("HasRemoteBranch() accepted a failed git remote lookup")
|
|
}
|
|
}
|
|
|
|
func TestMergePullRequest(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
|
switch request.Method {
|
|
case http.MethodGet:
|
|
_ = json.NewEncoder(writer).Encode([]pullRequest{{Number: 4}})
|
|
case http.MethodPost:
|
|
var body mergePullRequestRequest
|
|
if err := json.NewDecoder(request.Body).Decode(&body); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if body.Do != "merge" || request.URL.Path != "/api/v1/repos/owner/cluster/pulls/4/merge" {
|
|
t.Fatalf("unexpected merge request")
|
|
}
|
|
writer.WriteHeader(http.StatusOK)
|
|
default:
|
|
t.Fatalf("unexpected method %q", request.Method)
|
|
}
|
|
}))
|
|
defer server.Close()
|
|
manager := NewRepoManager(server.URL, "token", "owner", "user", "manifests", "cluster", "main", "maidn/bootstrap-test")
|
|
manager.HTTPClient = server.Client()
|
|
if err := manager.MergePullRequest("cluster", "maidn/bootstrap-test"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestRepoExistsReturnsFalseOnNotFound(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
|
|
writer.WriteHeader(http.StatusNotFound)
|
|
}))
|
|
defer server.Close()
|
|
manager := NewRepoManager(server.URL, "token", "owner", "user", "manifests", "cluster", "main", "maidn/bootstrap-test")
|
|
manager.HTTPClient = server.Client()
|
|
exists, err := manager.repoExists("cluster")
|
|
if err != nil || exists {
|
|
t.Fatalf("repoExists() = (%t, %v), want (false, nil)", exists, err)
|
|
}
|
|
}
|