Files
gitea-tea/internal/services/repository_setup_test.go
T

115 lines
5.0 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package services
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"gitea.dev/tea/internal/transport"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRepositoryTemplateUsesAuthenticatedDestination(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
require.Equal(t, "/api/v1/user", r.URL.Path)
_, _ = w.Write([]byte(`{"login":"account"}`))
return
}
require.Equal(t, "/api/v1/repos/owner/template/generate", r.URL.Path)
payload := requestJSON(t, r)
require.Equal(t, "account", payload["owner"])
require.Equal(t, true, payload["git_content"])
require.Equal(t, false, payload["git_hooks"])
_, _ = w.Write([]byte(`{"id":2,"name":"generated"}`))
}))
defer server.Close()
item, err := (Repositories{Client: transport.New(server.URL, "", false)}).Generate(context.Background(), "owner/template", RepositoryTemplateOptions{Name: "generated", Content: true})
require.NoError(t, err)
require.Equal(t, "generated", item.Name)
}
func TestRepositoryMigrationDoesNotRetryOrLeakCredentials(t *testing.T) {
mutations := 0
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mutations++
require.Equal(t, "/api/v1/repos/migrate", r.URL.Path)
payload := requestJSON(t, r)
require.Equal(t, "source-secret", payload["auth_password"])
require.NotContains(t, payload, "Timeout")
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(`{"message":"source-secret"}`))
}))
defer server.Close()
client := transport.New(server.URL, "destination-token", false)
originalTimeout := client.HTTP.Timeout
_, err := (Repositories{Client: client}).Migrate(context.Background(), RepositoryMigrationOptions{Name: "imported", CloneURL: "https://source.test/repo", Service: "git", AuthUser: "source-account", AuthPassword: "source-secret", Timeout: time.Minute})
require.Error(t, err)
require.NotContains(t, err.Error(), "source-secret")
require.Equal(t, 1, mutations)
require.Equal(t, originalTimeout, client.HTTP.Timeout)
}
func TestRepositoryMigrationMapsOptionsAndClearsTokenEcho(t *testing.T) {
client := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "/api/v1/repos/migrate", r.URL.Path)
payload := requestJSON(t, r)
assert.Equal(t, "imported", payload["repo_name"])
assert.Equal(t, "acme", payload["repo_owner"])
assert.Equal(t, "https://source.test/repo", payload["clone_addr"])
assert.Equal(t, "github", payload["service"])
assert.Equal(t, "source-token", payload["auth_token"])
assert.Equal(t, true, payload["issues"])
assert.Equal(t, true, payload["lfs"])
assert.Equal(t, "https://source.test/lfs", payload["lfs_endpoint"])
w.WriteHeader(http.StatusUnprocessableEntity)
_, _ = w.Write([]byte(`{"message":"bad credential source-token"}`))
}))
_, err := (Repositories{Client: client}).Migrate(context.Background(), RepositoryMigrationOptions{
Name: "imported", Owner: "acme", CloneURL: "https://source.test/repo", Service: "github", AuthToken: "source-token",
Issues: true, LFS: true, LFSEndpoint: "https://source.test/lfs",
})
var failure *transport.APIError
require.ErrorAs(t, err, &failure)
require.Equal(t, http.StatusUnprocessableEntity, failure.Status)
require.NotContains(t, err.Error(), "source-token")
}
func TestRepositoryMigrationKeepsMessageWithoutCredentials(t *testing.T) {
client := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusConflict)
_, _ = w.Write([]byte(`{"message":"repository already exists"}`))
}))
_, err := (Repositories{Client: client}).Migrate(context.Background(), RepositoryMigrationOptions{Name: "imported", CloneURL: "https://source.test/repo", Service: "git"})
require.ErrorContains(t, err, "repository already exists")
}
func TestRepositoryMigrateSetsADescriptionBeyondTheSDKByteLimitByEdit(t *testing.T) {
description := strings.Repeat("日", 800) // 2400 bytes, 800 characters
var methods []string
client := newTestClient(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
methods = append(methods, r.Method)
body := requestJSON(t, r)
switch r.Method {
case http.MethodPost:
require.Empty(t, body["description"])
w.WriteHeader(http.StatusCreated)
_, _ = w.Write([]byte(`{"id":2,"name":"imported","full_name":"alice/imported"}`))
case http.MethodPatch:
require.Equal(t, description, body["description"])
_, _ = w.Write([]byte(`{"id":2,"name":"imported","full_name":"alice/imported","description":"` + description + `"}`))
}
}))
migrated, err := (Repositories{Client: client}).Migrate(context.Background(), RepositoryMigrationOptions{Name: "imported", CloneURL: "https://source.test/repo", Service: "git", Description: description})
require.NoError(t, err)
require.Equal(t, []string{http.MethodPost, http.MethodPatch}, methods)
require.Equal(t, description, migrated.Description)
}