Files
gitea/services/migrations/migrate_test.go
T
Lunny Xiaoandbircni a2da5cd7b5 feat(migrations): add migration from Bitbucket Server (Data Center) (#39913)
Add migration from Bitbucket Server (Data Center). It has no issues,
wiki, milestones or releases, so those are not offered.

Migrated: git data with tags and LFS, and pull requests with state,
draft flag, merge commit/base, comments, approvals and inline code
comments including resolved threads. Multi-line ranges become a `Lines
a-b:` text prefix, as Gitea anchors code comments to one line. Auth is
an HTTP access token (personal, project or repository) or
username/password; 429 responses are retried.

Changes outside the downloader:
- `ReviewComment.Resolved`, applied by the uploader.
- The uploader creates a fork PR's head branch from its head commit when
already in the repository, instead of fetching the fork (Bitbucket keeps
it in `refs/pull-requests/<id>/from`; private forks need credentials).

Tested with unit tests, responses recorded from Bitbucket 10.5.1, and an
end-to-end migration. Independent of
https://github.com/go-gitea/gitea/pull/38607 (Bitbucket Cloud); the
service type enum value needs adjusting for whichever lands second.

---------

Co-authored-by: bircni <bircni@icloud.com>
2026-10-23 19:25:29 +00:00

74 lines
2.6 KiB
Go

// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package migrations
import (
"errors"
"fmt"
"net/http"
"path/filepath"
"testing"
user_model "gitea.dev/models/user"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/setting"
"gitea.dev/modules/test"
"gitea.dev/modules/util"
"github.com/google/go-github/v92/github"
"github.com/stretchr/testify/assert"
)
func TestIsAuthenticationError(t *testing.T) {
errDummy := errors.New("dummy")
cases := []struct {
name string
want bool
err error
}{
{"git authentication failed", true, gitcmd.NewRunStdError(errDummy, "fatal: Authentication failed for 'https://host/repo.git/'")},
{"git could not read username", true, fmt.Errorf("%w", gitcmd.NewRunStdError(errDummy, "fatal: could not read Username for 'https://host'"))},
{"github unauthorized", true, util.SanitizeErrorCredentialURLs(&github.ErrorResponse{Response: &http.Response{StatusCode: http.StatusUnauthorized}})},
{"github other", false, &github.ErrorResponse{Response: &http.Response{StatusCode: http.StatusNotFound}}},
{"github nil response", false, &github.ErrorResponse{}},
{"bitbucket server unauthorized", true, fmt.Errorf("wrapped: %w", &bbsStatusError{Status: http.StatusUnauthorized})},
{"bitbucket server forbidden", true, &bbsStatusError{Status: http.StatusForbidden}},
{"bitbucket server not found", false, &bbsStatusError{Status: http.StatusNotFound}},
{"unrelated error", false, errDummy},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
assert.Equal(t, c.want, IsAuthenticationError(c.err))
})
}
}
func TestMigrateWhiteBlocklist(t *testing.T) {
adminUser := &user_model.User{IsAdmin: true}
nonAdminUser := &user_model.User{}
defer test.MockVariableValue(&setting.Migrations.AllowedHostList, "")()
defer test.MockVariableValue(&setting.Migrations.BlockedHostList, "8.8.4.4")()
assert.NoError(t, IsMigrateURLAllowed("https://8.8.8.8/go-gitea/gitea.git", nonAdminUser))
assert.Error(t, IsMigrateURLAllowed("https://8.8.4.4/go-gitea/gitea.git", nonAdminUser))
assert.Error(t, IsMigrateURLAllowed("https://[64:ff9b::a9fe:a9fe]/go-gitea/gitea.git", nonAdminUser))
old := setting.ImportLocalPaths
setting.ImportLocalPaths = false
assert.Error(t, IsMigrateURLAllowed("/home/foo/bar/goo", adminUser))
setting.ImportLocalPaths = true
abs, err := filepath.Abs(".")
assert.NoError(t, err)
assert.NoError(t, IsMigrateURLAllowed(abs, adminUser))
assert.Error(t, IsMigrateURLAllowed(abs, nonAdminUser))
nonAdminUser.AllowImportLocal = true
assert.NoError(t, IsMigrateURLAllowed(abs, nonAdminUser))
setting.ImportLocalPaths = old
}