Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

context_tests.go 5.4KB

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