chore: fix tests (#37760)

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
wxiaoguang
2026-05-18 23:47:24 +08:00
committed by GitHub
parent 912afcaa51
commit c37b5241d7
5 changed files with 34 additions and 168 deletions

3
go.mod
View File

@@ -104,7 +104,6 @@ require (
github.com/urfave/cli-docs/v3 v3.1.0 github.com/urfave/cli-docs/v3 v3.1.0
github.com/urfave/cli/v3 v3.6.1 github.com/urfave/cli/v3 v3.6.1
github.com/wneessen/go-mail v0.7.3 github.com/wneessen/go-mail v0.7.3
github.com/xeipuuv/gojsonschema v1.2.0
github.com/yohcop/openid-go v1.0.1 github.com/yohcop/openid-go v1.0.1
github.com/yuin/goldmark v1.8.2 github.com/yuin/goldmark v1.8.2
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
@@ -272,8 +271,6 @@ require (
github.com/woodsbury/decimal128 v1.3.0 // indirect github.com/woodsbury/decimal128 v1.3.0 // indirect
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/zeebo/blake3 v0.2.4 // indirect github.com/zeebo/blake3 v0.2.4 // indirect
github.com/zeebo/xxh3 v1.1.0 // indirect github.com/zeebo/xxh3 v1.1.0 // indirect

7
go.sum
View File

@@ -731,13 +731,6 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=

View File

@@ -42,8 +42,8 @@ func TestAPIGetRawFileOrLFS(t *testing.T) {
lfs := lfsCommitAndPushTest(t, dstPath, testFileSizeSmall)[0] lfs := lfsCommitAndPushTest(t, dstPath, testFileSizeSmall)[0]
reqLFS := NewRequest(t, "GET", "/api/v1/repos/user2/repo-lfs-test/media/"+lfs).AddTokenAuth(httpContext.Token) reqLFS := NewRequest(t, "GET", "/api/v1/repos/user2/repo-lfs-test/media/"+lfs).AddTokenAuth(httpContext.Token)
respLFS := MakeRequestNilResponseRecorder(t, reqLFS, http.StatusOK) respLFS := MakeRequest(t, reqLFS, http.StatusOK)
assert.Equal(t, testFileSizeSmall, respLFS.Length) assert.Equal(t, testFileSizeSmall, respLFS.Body.Len())
}) })
}) })
} }

View File

@@ -5,7 +5,6 @@ package integration
import ( import (
"context" "context"
"encoding/hex"
"fmt" "fmt"
"io" "io"
mathRand "math/rand/v2" mathRand "math/rand/v2"
@@ -246,8 +245,8 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
// Request raw paths // Request raw paths
req := NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", little)) req := NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", little))
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, testFileSizeSmall, resp.Length) assert.Equal(t, testFileSizeSmall, resp.Body.Len())
if setting.LFS.StartServer { if setting.LFS.StartServer {
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS)) req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
@@ -261,8 +260,8 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
if !testing.Short() { if !testing.Short() {
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", big)) req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", big))
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, testFileSizeLarge, resp.Length) assert.Equal(t, testFileSizeLarge, resp.Body.Len())
if setting.LFS.StartServer { if setting.LFS.StartServer {
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", bigLFS)) req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", bigLFS))
@@ -287,22 +286,22 @@ func mediaTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS
// Request media paths // Request media paths
req := NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", little)) req := NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", little))
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, testFileSizeSmall, resp.Length) assert.Equal(t, testFileSizeSmall, resp.Body.Len())
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS)) req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, testFileSizeSmall, resp.Length) assert.Equal(t, testFileSizeSmall, resp.Body.Len())
if !testing.Short() { if !testing.Short() {
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", big)) req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", big))
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, testFileSizeLarge, resp.Length) assert.Equal(t, testFileSizeLarge, resp.Body.Len())
if setting.LFS.StartServer { if setting.LFS.StartServer {
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", bigLFS)) req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", bigLFS))
resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
assert.Equal(t, testFileSizeLarge, resp.Length) assert.Equal(t, testFileSizeLarge, resp.Body.Len())
} }
} }
}) })
@@ -560,13 +559,11 @@ func doMergeFork(ctx, baseCtx APITestContext, baseBranch, headBranch string) fun
t.Run("EnsureCanSeePull", doEnsureCanSeePull(baseCtx, pr)) t.Run("EnsureCanSeePull", doEnsureCanSeePull(baseCtx, pr))
// Then get the diff string // Then get the diff string
var diffHash string var diffContent string
var diffLength int
t.Run("GetDiff", func(t *testing.T) { t.Run("GetDiff", func(t *testing.T) {
req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d.diff", url.PathEscape(baseCtx.Username), url.PathEscape(baseCtx.Reponame), pr.Index)) req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d.diff", url.PathEscape(baseCtx.Username), url.PathEscape(baseCtx.Reponame), pr.Index))
resp := ctx.Session.MakeRequestNilResponseHashSumRecorder(t, req, http.StatusOK) resp := ctx.Session.MakeRequest(t, req, http.StatusOK)
diffHash = string(resp.Hash.Sum(nil)) diffContent = resp.Body.String()
diffLength = resp.Length
}) })
// Now: Merge the PR & make sure that doesn't break the PR page or change its diff // Now: Merge the PR & make sure that doesn't break the PR page or change its diff
@@ -578,17 +575,17 @@ func doMergeFork(ctx, baseCtx APITestContext, baseBranch, headBranch string) fun
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, oldMergeBase, pr2.MergeBase) assert.Equal(t, oldMergeBase, pr2.MergeBase)
}) })
t.Run("EnsurDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffHash, diffLength)) t.Run("EnsurDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffContent))
// Then: Delete the head branch & make sure that doesn't break the PR page or change its diff // Then: Delete the head branch & make sure that doesn't break the PR page or change its diff
t.Run("DeleteHeadBranch", doBranchDelete(baseCtx, baseCtx.Username, baseCtx.Reponame, headBranch)) t.Run("DeleteHeadBranch", doBranchDelete(baseCtx, baseCtx.Username, baseCtx.Reponame, headBranch))
t.Run("EnsureCanSeePull", doEnsureCanSeePull(baseCtx, pr)) t.Run("EnsureCanSeePull", doEnsureCanSeePull(baseCtx, pr))
t.Run("EnsureDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffHash, diffLength)) t.Run("EnsureDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffContent))
// Delete the head repository & make sure that doesn't break the PR page or change its diff // Delete the head repository & make sure that doesn't break the PR page or change its diff
t.Run("DeleteHeadRepository", doAPIDeleteRepository(ctx)) t.Run("DeleteHeadRepository", doAPIDeleteRepository(ctx))
t.Run("EnsureCanSeePull", doEnsureCanSeePull(baseCtx, pr)) t.Run("EnsureCanSeePull", doEnsureCanSeePull(baseCtx, pr))
t.Run("EnsureDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffHash, diffLength)) t.Run("EnsureDiffNoChange", doEnsureDiffNoChange(baseCtx, pr, diffContent))
} }
} }
@@ -632,15 +629,12 @@ func doEnsureCanSeePull(ctx APITestContext, pr api.PullRequest) func(t *testing.
} }
} }
func doEnsureDiffNoChange(ctx APITestContext, pr api.PullRequest, diffHash string, diffLength int) func(t *testing.T) { func doEnsureDiffNoChange(ctx APITestContext, pr api.PullRequest, diffContent string) func(t *testing.T) {
return func(t *testing.T) { return func(t *testing.T) {
req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d.diff", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), pr.Index)) req := NewRequest(t, "GET", fmt.Sprintf("/%s/%s/pulls/%d.diff", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), pr.Index))
resp := ctx.Session.MakeRequestNilResponseHashSumRecorder(t, req, http.StatusOK) resp := ctx.Session.MakeRequest(t, req, http.StatusOK)
actual := string(resp.Hash.Sum(nil)) actual := resp.Body.String()
actualLength := resp.Length assert.Equal(t, diffContent, actual)
equal := diffHash == actual
assert.True(t, equal, "Unexpected change in the diff string: expected hash: %s size: %d but was actually: %s size: %d", hex.EncodeToString([]byte(diffHash)), diffLength, hex.EncodeToString([]byte(actual)), actualLength)
} }
} }

View File

@@ -9,8 +9,6 @@ import (
"encoding/base64" "encoding/base64"
"flag" "flag"
"fmt" "fmt"
"hash"
"hash/fnv"
"io" "io"
"net/http" "net/http"
"net/http/cookiejar" "net/http/cookiejar"
@@ -38,49 +36,10 @@ import (
"github.com/PuerkitoBio/goquery" "github.com/PuerkitoBio/goquery"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/xeipuuv/gojsonschema"
) )
var testWebRoutes *web.Router var testWebRoutes *web.Router
type NilResponseRecorder struct {
httptest.ResponseRecorder
Length int
}
func (n *NilResponseRecorder) Write(b []byte) (int, error) {
n.Length += len(b)
return len(b), nil
}
// NewRecorder returns an initialized ResponseRecorder.
func NewNilResponseRecorder() *NilResponseRecorder {
return &NilResponseRecorder{
ResponseRecorder: *httptest.NewRecorder(),
}
}
type NilResponseHashSumRecorder struct {
httptest.ResponseRecorder
Hash hash.Hash
Length int
}
func (n *NilResponseHashSumRecorder) Write(b []byte) (int, error) {
_, _ = n.Hash.Write(b)
n.Length += len(b)
return len(b), nil
}
// NewRecorder returns an initialized ResponseRecorder.
func NewNilResponseHashSumRecorder() *NilResponseHashSumRecorder {
return &NilResponseHashSumRecorder{
Hash: fnv.New32(),
ResponseRecorder: *httptest.NewRecorder(),
}
}
func testMain(m *testing.M) int { func testMain(m *testing.M) int {
defer log.GetManager().Close() defer log.GetManager().Close()
@@ -177,42 +136,6 @@ func (s *TestSession) MakeRequest(t testing.TB, rw *RequestWrapper, expectedStat
return resp return resp
} }
func (s *TestSession) MakeRequestNilResponseRecorder(t testing.TB, rw *RequestWrapper, expectedStatus int) *NilResponseRecorder {
t.Helper()
req := rw.Request
baseURL, err := url.Parse(setting.AppURL)
assert.NoError(t, err)
for _, c := range s.jar.Cookies(baseURL) {
req.AddCookie(c)
}
resp := MakeRequestNilResponseRecorder(t, rw, expectedStatus)
ch := http.Header{}
ch.Add("Cookie", strings.Join(resp.Header()["Set-Cookie"], ";"))
cr := http.Request{Header: ch}
s.jar.SetCookies(baseURL, cr.Cookies())
return resp
}
func (s *TestSession) MakeRequestNilResponseHashSumRecorder(t testing.TB, rw *RequestWrapper, expectedStatus int) *NilResponseHashSumRecorder {
t.Helper()
req := rw.Request
baseURL, err := url.Parse(setting.AppURL)
assert.NoError(t, err)
for _, c := range s.jar.Cookies(baseURL) {
req.AddCookie(c)
}
resp := MakeRequestNilResponseHashSumRecorder(t, rw, expectedStatus)
ch := http.Header{}
ch.Add("Cookie", strings.Join(resp.Header()["Set-Cookie"], ";"))
cr := http.Request{Header: ch}
s.jar.SetCookies(baseURL, cr.Cookies())
return resp
}
const userPassword = "password" const userPassword = "password"
func emptyTestSession(t testing.TB) *TestSession { func emptyTestSession(t testing.TB) *TestSession {
@@ -268,7 +191,11 @@ func getTokenForLoggedInUser(t testing.TB, session *TestSession, scopes ...auth.
req := NewRequestWithURLValues(t, "POST", "/user/settings/applications", urlValues) req := NewRequestWithURLValues(t, "POST", "/user/settings/applications", urlValues)
session.MakeRequest(t, req, http.StatusSeeOther) session.MakeRequest(t, req, http.StatusSeeOther)
flashes := session.GetCookieFlashMessage() flashes := session.GetCookieFlashMessage()
return flashes.InfoMsg assert.NotNil(t, flashes)
if flashes != nil {
return flashes.InfoMsg
}
return ""
} }
type RequestWrapper struct { type RequestWrapper struct {
@@ -336,7 +263,7 @@ func NewRequestWithBody(t testing.TB, method, urlStr string, body io.Reader) *Re
t.Fatalf("invalid url str: %s", urlStr) t.Fatalf("invalid url str: %s", urlStr)
} }
req, err := http.NewRequest(method, urlStr, body) req, err := http.NewRequest(method, urlStr, body)
require.NoError(t, err) assert.NoError(t, err)
if req.URL.User != nil { if req.URL.User != nil {
req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(req.URL.User.String()))) req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(req.URL.User.String())))
} }
@@ -364,35 +291,8 @@ func MakeRequest(t testing.TB, rw *RequestWrapper, expectedStatus int) *httptest
if expectedStatus != NoExpectedStatus { if expectedStatus != NoExpectedStatus {
if expectedStatus != recorder.Code { if expectedStatus != recorder.Code {
logUnexpectedResponse(t, recorder) logUnexpectedResponse(t, recorder)
require.Equal(t, expectedStatus, recorder.Code, "Request: %s %s", req.Method, req.URL.String()) // don't use "require" which exits the test case and makes "wait group" wait forever
} assert.Equal(t, expectedStatus, recorder.Code, "Request: %s %s", req.Method, req.URL.String())
}
return recorder
}
func MakeRequestNilResponseRecorder(t testing.TB, rw *RequestWrapper, expectedStatus int) *NilResponseRecorder {
t.Helper()
req := rw.Request
recorder := NewNilResponseRecorder()
testWebRoutes.ServeHTTP(recorder, req)
if expectedStatus != NoExpectedStatus {
if !assert.Equal(t, expectedStatus, recorder.Code,
"Request: %s %s", req.Method, req.URL.String()) {
logUnexpectedResponse(t, &recorder.ResponseRecorder)
}
}
return recorder
}
func MakeRequestNilResponseHashSumRecorder(t testing.TB, rw *RequestWrapper, expectedStatus int) *NilResponseHashSumRecorder {
t.Helper()
req := rw.Request
recorder := NewNilResponseHashSumRecorder()
testWebRoutes.ServeHTTP(recorder, req)
if expectedStatus != NoExpectedStatus {
if !assert.Equal(t, expectedStatus, recorder.Code,
"Request: %s %s", req.Method, req.URL.String()) {
logUnexpectedResponse(t, &recorder.ResponseRecorder)
} }
} }
return recorder return recorder
@@ -428,25 +328,7 @@ func DecodeJSON[T any](t testing.TB, resp *httptest.ResponseRecorder, v T) (ret
// FIXME: JSON-KEY-CASE: for testing purpose only, because many structs don't provide `json` tags, they just use capitalized field names // FIXME: JSON-KEY-CASE: for testing purpose only, because many structs don't provide `json` tags, they just use capitalized field names
decoder := json.NewDecoderCaseInsensitive(resp.Body) decoder := json.NewDecoderCaseInsensitive(resp.Body)
require.NoError(t, decoder.Decode(&v)) // don't use "require" which exits the test case and makes "wait group" wait forever
assert.NoError(t, decoder.Decode(&v))
return v return v
} }
func VerifyJSONSchema(t testing.TB, resp *httptest.ResponseRecorder, schemaFile string) {
t.Helper()
schemaFilePath := filepath.Join(filepath.Dir(setting.AppPath), "tests", "integration", "schemas", schemaFile)
_, schemaFileErr := os.Stat(schemaFilePath)
assert.NoError(t, schemaFileErr)
schema, schemaFileReadErr := os.ReadFile(schemaFilePath)
assert.NoError(t, schemaFileReadErr)
assert.NotEmpty(t, schema)
nodeinfoSchema := gojsonschema.NewStringLoader(string(schema))
nodeinfoString := gojsonschema.NewStringLoader(resp.Body.String())
result, schemaValidationErr := gojsonschema.Validate(nodeinfoSchema, nodeinfoString)
assert.NoError(t, schemaValidationErr)
assert.Empty(t, result.Errors())
assert.True(t, result.Valid())
}