mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-25 06:45:43 +03:00
dc04044716
assert.Fail() will continue to execute the code while assert.FailNow() not. I thought those uses of assert.Fail() should exit immediately. PS: perhaps it's a good idea to use [require](https://pkg.go.dev/github.com/stretchr/testify/require) somewhere because the assert package's default behavior does not exit when an error occurs, which makes it difficult to find the root error reason.
155 lines
4.8 KiB
Go
155 lines
4.8 KiB
Go
// Copyright 2017 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// Package contexttest provides utilities for testing Web/API contexts with models.
|
|
package contexttest
|
|
|
|
import (
|
|
gocontext "context"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
|
|
access_model "code.gitea.io/gitea/models/perm/access"
|
|
repo_model "code.gitea.io/gitea/models/repo"
|
|
"code.gitea.io/gitea/models/unittest"
|
|
user_model "code.gitea.io/gitea/models/user"
|
|
"code.gitea.io/gitea/modules/context"
|
|
"code.gitea.io/gitea/modules/git"
|
|
"code.gitea.io/gitea/modules/templates"
|
|
"code.gitea.io/gitea/modules/translation"
|
|
"code.gitea.io/gitea/modules/web/middleware"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func mockRequest(t *testing.T, reqPath string) *http.Request {
|
|
method, path, found := strings.Cut(reqPath, " ")
|
|
if !found {
|
|
method = "GET"
|
|
path = reqPath
|
|
}
|
|
requestURL, err := url.Parse(path)
|
|
assert.NoError(t, err)
|
|
req := &http.Request{Method: method, URL: requestURL, Form: url.Values{}}
|
|
req = req.WithContext(middleware.WithContextData(req.Context()))
|
|
return req
|
|
}
|
|
|
|
// MockContext mock context for unit tests
|
|
func MockContext(t *testing.T, reqPath string) (*context.Context, *httptest.ResponseRecorder) {
|
|
resp := httptest.NewRecorder()
|
|
req := mockRequest(t, reqPath)
|
|
base, baseCleanUp := context.NewBaseContext(resp, req)
|
|
_ = baseCleanUp // during test, it doesn't need to do clean up. TODO: this can be improved later
|
|
base.Data = middleware.GetContextData(req.Context())
|
|
base.Locale = &translation.MockLocale{}
|
|
|
|
ctx := context.NewWebContext(base, &MockRender{}, nil)
|
|
|
|
chiCtx := chi.NewRouteContext()
|
|
ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx)
|
|
return ctx, resp
|
|
}
|
|
|
|
// MockAPIContext mock context for unit tests
|
|
func MockAPIContext(t *testing.T, reqPath string) (*context.APIContext, *httptest.ResponseRecorder) {
|
|
resp := httptest.NewRecorder()
|
|
req := mockRequest(t, reqPath)
|
|
base, baseCleanUp := context.NewBaseContext(resp, req)
|
|
base.Data = middleware.GetContextData(req.Context())
|
|
base.Locale = &translation.MockLocale{}
|
|
ctx := &context.APIContext{Base: base}
|
|
_ = baseCleanUp // during test, it doesn't need to do clean up. TODO: this can be improved later
|
|
|
|
chiCtx := chi.NewRouteContext()
|
|
ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx)
|
|
return ctx, resp
|
|
}
|
|
|
|
// LoadRepo load a repo into a test context.
|
|
func LoadRepo(t *testing.T, ctx gocontext.Context, repoID int64) {
|
|
var doer *user_model.User
|
|
repo := &context.Repository{}
|
|
switch ctx := ctx.(type) {
|
|
case *context.Context:
|
|
ctx.Repo = repo
|
|
doer = ctx.Doer
|
|
case *context.APIContext:
|
|
ctx.Repo = repo
|
|
doer = ctx.Doer
|
|
default:
|
|
assert.FailNow(t, "context is not *context.Context or *context.APIContext")
|
|
}
|
|
|
|
repo.Repository = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
|
|
var err error
|
|
repo.Owner, err = user_model.GetUserByID(ctx, repo.Repository.OwnerID)
|
|
assert.NoError(t, err)
|
|
repo.RepoLink = repo.Repository.Link()
|
|
repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo.Repository, doer)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
// LoadRepoCommit loads a repo's commit into a test context.
|
|
func LoadRepoCommit(t *testing.T, ctx gocontext.Context) {
|
|
var repo *context.Repository
|
|
switch ctx := ctx.(type) {
|
|
case *context.Context:
|
|
repo = ctx.Repo
|
|
case *context.APIContext:
|
|
repo = ctx.Repo
|
|
default:
|
|
assert.FailNow(t, "context is not *context.Context or *context.APIContext")
|
|
}
|
|
|
|
gitRepo, err := git.OpenRepository(ctx, repo.Repository.RepoPath())
|
|
assert.NoError(t, err)
|
|
defer gitRepo.Close()
|
|
branch, err := gitRepo.GetHEADBranch()
|
|
assert.NoError(t, err)
|
|
assert.NotNil(t, branch)
|
|
if branch != nil {
|
|
repo.Commit, err = gitRepo.GetBranchCommit(branch.Name)
|
|
assert.NoError(t, err)
|
|
}
|
|
}
|
|
|
|
// LoadUser load a user into a test context
|
|
func LoadUser(t *testing.T, ctx gocontext.Context, userID int64) {
|
|
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID})
|
|
switch ctx := ctx.(type) {
|
|
case *context.Context:
|
|
ctx.Doer = doer
|
|
case *context.APIContext:
|
|
ctx.Doer = doer
|
|
default:
|
|
assert.FailNow(t, "context is not *context.Context or *context.APIContext")
|
|
}
|
|
}
|
|
|
|
// LoadGitRepo load a git repo into a test context. Requires that ctx.Repo has
|
|
// already been populated.
|
|
func LoadGitRepo(t *testing.T, ctx *context.Context) {
|
|
assert.NoError(t, ctx.Repo.Repository.LoadOwner(ctx))
|
|
var err error
|
|
ctx.Repo.GitRepo, err = git.OpenRepository(ctx, ctx.Repo.Repository.RepoPath())
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
type MockRender struct{}
|
|
|
|
func (tr *MockRender) TemplateLookup(tmpl string, _ gocontext.Context) (templates.TemplateExecutor, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func (tr *MockRender) HTML(w io.Writer, status int, _ string, _ any, _ gocontext.Context) error {
|
|
if resp, ok := w.(http.ResponseWriter); ok {
|
|
resp.WriteHeader(status)
|
|
}
|
|
return nil
|
|
}
|