summaryrefslogtreecommitdiffstats
path: root/services/contexttest
diff options
context:
space:
mode:
Diffstat (limited to 'services/contexttest')
-rw-r--r--services/contexttest/context_tests.go208
1 files changed, 208 insertions, 0 deletions
diff --git a/services/contexttest/context_tests.go b/services/contexttest/context_tests.go
new file mode 100644
index 0000000..7c829f3
--- /dev/null
+++ b/services/contexttest/context_tests.go
@@ -0,0 +1,208 @@
+// 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"
+ "maps"
+ "net/http"
+ "net/http/httptest"
+ "net/url"
+ "strings"
+ "testing"
+ "time"
+
+ org_model "code.gitea.io/gitea/models/organization"
+ 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/gitrepo"
+ "code.gitea.io/gitea/modules/templates"
+ "code.gitea.io/gitea/modules/translation"
+ "code.gitea.io/gitea/modules/web/middleware"
+ "code.gitea.io/gitea/services/context"
+
+ "github.com/go-chi/chi/v5"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+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)
+ require.NoError(t, err)
+ req := &http.Request{Method: method, URL: requestURL, Form: maps.Clone(requestURL.Query()), Header: http.Header{}}
+ req = req.WithContext(middleware.WithContextData(req.Context()))
+ return req
+}
+
+type MockContextOption struct {
+ Render context.Render
+}
+
+// MockContext mock context for unit tests
+func MockContext(t *testing.T, reqPath string, opts ...MockContextOption) (*context.Context, *httptest.ResponseRecorder) {
+ var opt MockContextOption
+ if len(opts) > 0 {
+ opt = opts[0]
+ }
+ if opt.Render == nil {
+ opt.Render = &MockRender{}
+ }
+ 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, opt.Render, nil)
+ ctx.PageData = map[string]any{}
+ ctx.Data["PageStartTime"] = time.Now()
+ 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
+}
+
+func MockPrivateContext(t *testing.T, reqPath string) (*context.PrivateContext, *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.PrivateContext{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)
+ require.NoError(t, err)
+ repo.RepoLink = repo.Repository.Link()
+ repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo.Repository, doer)
+ require.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")
+ }
+
+ if repo.GitRepo == nil {
+ assert.FailNow(t, "must call LoadGitRepo")
+ }
+
+ branch, err := repo.GitRepo.GetHEADBranch()
+ require.NoError(t, err)
+ assert.NotNil(t, branch)
+ if branch != nil {
+ repo.Commit, err = repo.GitRepo.GetBranchCommit(branch.Name)
+ require.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")
+ }
+}
+
+// LoadOrganization load an org into a test context
+func LoadOrganization(t *testing.T, ctx gocontext.Context, orgID int64) {
+ org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{ID: orgID})
+ switch ctx := ctx.(type) {
+ case *context.Context:
+ ctx.Org.Organization = org
+ case *context.APIContext:
+ ctx.Org.Organization = org
+ 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 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")
+ }
+
+ require.NoError(t, repo.Repository.LoadOwner(ctx))
+ var err error
+ repo.GitRepo, err = gitrepo.OpenRepository(ctx, repo.Repository)
+ require.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
+}