You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

context_tests.go 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // Copyright 2017 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. // Package contexttest provides utilities for testing Web/API contexts with models.
  4. package contexttest
  5. import (
  6. gocontext "context"
  7. "io"
  8. "net/http"
  9. "net/http/httptest"
  10. "net/url"
  11. "strings"
  12. "testing"
  13. access_model "code.gitea.io/gitea/models/perm/access"
  14. repo_model "code.gitea.io/gitea/models/repo"
  15. "code.gitea.io/gitea/models/unittest"
  16. user_model "code.gitea.io/gitea/models/user"
  17. "code.gitea.io/gitea/modules/context"
  18. "code.gitea.io/gitea/modules/git"
  19. "code.gitea.io/gitea/modules/templates"
  20. "code.gitea.io/gitea/modules/translation"
  21. "code.gitea.io/gitea/modules/web/middleware"
  22. "github.com/go-chi/chi/v5"
  23. "github.com/stretchr/testify/assert"
  24. )
  25. func mockRequest(t *testing.T, reqPath string) *http.Request {
  26. method, path, found := strings.Cut(reqPath, " ")
  27. if !found {
  28. method = "GET"
  29. path = reqPath
  30. }
  31. requestURL, err := url.Parse(path)
  32. assert.NoError(t, err)
  33. req := &http.Request{Method: method, URL: requestURL, Form: url.Values{}}
  34. req = req.WithContext(middleware.WithContextData(req.Context()))
  35. return req
  36. }
  37. type MockContextOption struct {
  38. Render context.Render
  39. }
  40. // MockContext mock context for unit tests
  41. func MockContext(t *testing.T, reqPath string, opts ...MockContextOption) (*context.Context, *httptest.ResponseRecorder) {
  42. var opt MockContextOption
  43. if len(opts) > 0 {
  44. opt = opts[0]
  45. }
  46. if opt.Render == nil {
  47. opt.Render = &MockRender{}
  48. }
  49. resp := httptest.NewRecorder()
  50. req := mockRequest(t, reqPath)
  51. base, baseCleanUp := context.NewBaseContext(resp, req)
  52. _ = baseCleanUp // during test, it doesn't need to do clean up. TODO: this can be improved later
  53. base.Data = middleware.GetContextData(req.Context())
  54. base.Locale = &translation.MockLocale{}
  55. ctx := context.NewWebContext(base, opt.Render, nil)
  56. chiCtx := chi.NewRouteContext()
  57. ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx)
  58. return ctx, resp
  59. }
  60. // MockAPIContext mock context for unit tests
  61. func MockAPIContext(t *testing.T, reqPath string) (*context.APIContext, *httptest.ResponseRecorder) {
  62. resp := httptest.NewRecorder()
  63. req := mockRequest(t, reqPath)
  64. base, baseCleanUp := context.NewBaseContext(resp, req)
  65. base.Data = middleware.GetContextData(req.Context())
  66. base.Locale = &translation.MockLocale{}
  67. ctx := &context.APIContext{Base: base}
  68. _ = baseCleanUp // during test, it doesn't need to do clean up. TODO: this can be improved later
  69. chiCtx := chi.NewRouteContext()
  70. ctx.Base.AppendContextValue(chi.RouteCtxKey, chiCtx)
  71. return ctx, resp
  72. }
  73. // LoadRepo load a repo into a test context.
  74. func LoadRepo(t *testing.T, ctx gocontext.Context, repoID int64) {
  75. var doer *user_model.User
  76. repo := &context.Repository{}
  77. switch ctx := ctx.(type) {
  78. case *context.Context:
  79. ctx.Repo = repo
  80. doer = ctx.Doer
  81. case *context.APIContext:
  82. ctx.Repo = repo
  83. doer = ctx.Doer
  84. default:
  85. assert.Fail(t, "context is not *context.Context or *context.APIContext")
  86. return
  87. }
  88. repo.Repository = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
  89. var err error
  90. repo.Owner, err = user_model.GetUserByID(ctx, repo.Repository.OwnerID)
  91. assert.NoError(t, err)
  92. repo.RepoLink = repo.Repository.Link()
  93. repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo.Repository, doer)
  94. assert.NoError(t, err)
  95. }
  96. // LoadRepoCommit loads a repo's commit into a test context.
  97. func LoadRepoCommit(t *testing.T, ctx gocontext.Context) {
  98. var repo *context.Repository
  99. switch ctx := ctx.(type) {
  100. case *context.Context:
  101. repo = ctx.Repo
  102. case *context.APIContext:
  103. repo = ctx.Repo
  104. default:
  105. assert.Fail(t, "context is not *context.Context or *context.APIContext")
  106. return
  107. }
  108. gitRepo, err := git.OpenRepository(ctx, repo.Repository.RepoPath())
  109. assert.NoError(t, err)
  110. defer gitRepo.Close()
  111. branch, err := gitRepo.GetHEADBranch()
  112. assert.NoError(t, err)
  113. assert.NotNil(t, branch)
  114. if branch != nil {
  115. repo.Commit, err = gitRepo.GetBranchCommit(branch.Name)
  116. assert.NoError(t, err)
  117. }
  118. }
  119. // LoadUser load a user into a test context
  120. func LoadUser(t *testing.T, ctx gocontext.Context, userID int64) {
  121. doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID})
  122. switch ctx := ctx.(type) {
  123. case *context.Context:
  124. ctx.Doer = doer
  125. case *context.APIContext:
  126. ctx.Doer = doer
  127. default:
  128. assert.Fail(t, "context is not *context.Context or *context.APIContext")
  129. return
  130. }
  131. }
  132. // LoadGitRepo load a git repo into a test context. Requires that ctx.Repo has
  133. // already been populated.
  134. func LoadGitRepo(t *testing.T, ctx *context.Context) {
  135. assert.NoError(t, ctx.Repo.Repository.LoadOwner(ctx))
  136. var err error
  137. ctx.Repo.GitRepo, err = git.OpenRepository(ctx, ctx.Repo.Repository.RepoPath())
  138. assert.NoError(t, err)
  139. }
  140. type MockRender struct{}
  141. func (tr *MockRender) TemplateLookup(tmpl string, _ gocontext.Context) (templates.TemplateExecutor, error) {
  142. return nil, nil
  143. }
  144. func (tr *MockRender) HTML(w io.Writer, status int, _ string, _ any, _ gocontext.Context) error {
  145. if resp, ok := w.(http.ResponseWriter); ok {
  146. resp.WriteHeader(status)
  147. }
  148. return nil
  149. }