diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2023-09-01 19:26:07 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-01 11:26:07 +0000 |
commit | e8aae43f56fedd6f7b04affd378c2c4ed2af9d78 (patch) | |
tree | a9b03cbf3f926f2cd27eb4d3c18126aec1cc7aa9 /modules/contexttest | |
parent | fcb4941d47217f3a369148d98b07e27205f385b8 (diff) | |
download | gitea-e8aae43f56fedd6f7b04affd378c2c4ed2af9d78.tar.gz gitea-e8aae43f56fedd6f7b04affd378c2c4ed2af9d78.zip |
Move web/api context related testing function into a separate package (#26859)
Just like `models/unittest`, the testing helper functions should be in a
separate package: `contexttest`
And complete the TODO:
> // TODO: move this function to other packages, because it depends on
"models" package
Diffstat (limited to 'modules/contexttest')
-rw-r--r-- | modules/contexttest/context_tests.go | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/modules/contexttest/context_tests.go b/modules/contexttest/context_tests.go new file mode 100644 index 0000000000..f8fb0859e3 --- /dev/null +++ b/modules/contexttest/context_tests.go @@ -0,0 +1,159 @@ +// 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) + ctx.Flash = &middleware.Flash{Values: url.Values{}} + + 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.Fail(t, "context is not *context.Context or *context.APIContext") + return + } + + 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.Fail(t, "context is not *context.Context or *context.APIContext") + return + } + + 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.Fail(t, "context is not *context.Context or *context.APIContext") + return + } +} + +// 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 +} |