code.gitea.io/gitea@v1.22.3/routers/web/repo/wiki_test.go (about) 1 // Copyright 2017 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package repo 5 6 import ( 7 "io" 8 "net/http" 9 "net/url" 10 "testing" 11 12 "code.gitea.io/gitea/models/db" 13 repo_model "code.gitea.io/gitea/models/repo" 14 "code.gitea.io/gitea/models/unittest" 15 "code.gitea.io/gitea/modules/git" 16 "code.gitea.io/gitea/modules/gitrepo" 17 "code.gitea.io/gitea/modules/web" 18 "code.gitea.io/gitea/services/contexttest" 19 "code.gitea.io/gitea/services/forms" 20 wiki_service "code.gitea.io/gitea/services/wiki" 21 22 "github.com/stretchr/testify/assert" 23 ) 24 25 const ( 26 content = "Wiki contents for unit tests" 27 message = "Wiki commit message for unit tests" 28 ) 29 30 func wikiEntry(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) *git.TreeEntry { 31 wikiRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) 32 assert.NoError(t, err) 33 defer wikiRepo.Close() 34 commit, err := wikiRepo.GetBranchCommit("master") 35 assert.NoError(t, err) 36 entries, err := commit.ListEntries() 37 assert.NoError(t, err) 38 for _, entry := range entries { 39 if entry.Name() == wiki_service.WebPathToGitPath(wikiName) { 40 return entry 41 } 42 } 43 return nil 44 } 45 46 func wikiContent(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) string { 47 entry := wikiEntry(t, repo, wikiName) 48 if !assert.NotNil(t, entry) { 49 return "" 50 } 51 reader, err := entry.Blob().DataAsync() 52 assert.NoError(t, err) 53 defer reader.Close() 54 bytes, err := io.ReadAll(reader) 55 assert.NoError(t, err) 56 return string(bytes) 57 } 58 59 func assertWikiExists(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) { 60 assert.NotNil(t, wikiEntry(t, repo, wikiName)) 61 } 62 63 func assertWikiNotExists(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) { 64 assert.Nil(t, wikiEntry(t, repo, wikiName)) 65 } 66 67 func assertPagesMetas(t *testing.T, expectedNames []string, metas any) { 68 pageMetas, ok := metas.([]PageMeta) 69 if !assert.True(t, ok) { 70 return 71 } 72 if !assert.Len(t, pageMetas, len(expectedNames)) { 73 return 74 } 75 for i, pageMeta := range pageMetas { 76 assert.EqualValues(t, expectedNames[i], pageMeta.Name) 77 } 78 } 79 80 func TestWiki(t *testing.T) { 81 unittest.PrepareTestEnv(t) 82 83 ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki") 84 ctx.SetParams("*", "Home") 85 contexttest.LoadRepo(t, ctx, 1) 86 Wiki(ctx) 87 assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) 88 assert.EqualValues(t, "Home", ctx.Data["Title"]) 89 assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"]) 90 91 ctx, _ = contexttest.MockContext(t, "user2/repo1/jpeg.jpg") 92 ctx.SetParams("*", "jpeg.jpg") 93 contexttest.LoadRepo(t, ctx, 1) 94 Wiki(ctx) 95 assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) 96 assert.Equal(t, "/user2/repo1/wiki/raw/jpeg.jpg", ctx.Resp.Header().Get("Location")) 97 } 98 99 func TestWikiPages(t *testing.T) { 100 unittest.PrepareTestEnv(t) 101 102 ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/?action=_pages") 103 contexttest.LoadRepo(t, ctx, 1) 104 WikiPages(ctx) 105 assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) 106 assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"]) 107 } 108 109 func TestNewWiki(t *testing.T) { 110 unittest.PrepareTestEnv(t) 111 112 ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/?action=_new") 113 contexttest.LoadUser(t, ctx, 2) 114 contexttest.LoadRepo(t, ctx, 1) 115 NewWiki(ctx) 116 assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) 117 assert.EqualValues(t, ctx.Tr("repo.wiki.new_page"), ctx.Data["Title"]) 118 } 119 120 func TestNewWikiPost(t *testing.T) { 121 for _, title := range []string{ 122 "New page", 123 "&&&&", 124 } { 125 unittest.PrepareTestEnv(t) 126 127 ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/?action=_new") 128 contexttest.LoadUser(t, ctx, 2) 129 contexttest.LoadRepo(t, ctx, 1) 130 web.SetForm(ctx, &forms.NewWikiForm{ 131 Title: title, 132 Content: content, 133 Message: message, 134 }) 135 NewWikiPost(ctx) 136 assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) 137 assertWikiExists(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)) 138 assert.Equal(t, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)), content) 139 } 140 } 141 142 func TestNewWikiPost_ReservedName(t *testing.T) { 143 unittest.PrepareTestEnv(t) 144 145 ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/?action=_new") 146 contexttest.LoadUser(t, ctx, 2) 147 contexttest.LoadRepo(t, ctx, 1) 148 web.SetForm(ctx, &forms.NewWikiForm{ 149 Title: "_edit", 150 Content: content, 151 Message: message, 152 }) 153 NewWikiPost(ctx) 154 assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) 155 assert.EqualValues(t, ctx.Tr("repo.wiki.reserved_page", "_edit"), ctx.Flash.ErrorMsg) 156 assertWikiNotExists(t, ctx.Repo.Repository, "_edit") 157 } 158 159 func TestEditWiki(t *testing.T) { 160 unittest.PrepareTestEnv(t) 161 162 ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/Home?action=_edit") 163 ctx.SetParams("*", "Home") 164 contexttest.LoadUser(t, ctx, 2) 165 contexttest.LoadRepo(t, ctx, 1) 166 EditWiki(ctx) 167 assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) 168 assert.EqualValues(t, "Home", ctx.Data["Title"]) 169 assert.Equal(t, wikiContent(t, ctx.Repo.Repository, "Home"), ctx.Data["content"]) 170 171 ctx, _ = contexttest.MockContext(t, "user2/repo1/wiki/jpeg.jpg?action=_edit") 172 ctx.SetParams("*", "jpeg.jpg") 173 contexttest.LoadUser(t, ctx, 2) 174 contexttest.LoadRepo(t, ctx, 1) 175 EditWiki(ctx) 176 assert.EqualValues(t, http.StatusForbidden, ctx.Resp.Status()) 177 } 178 179 func TestEditWikiPost(t *testing.T) { 180 for _, title := range []string{ 181 "Home", 182 "New/<page>", 183 } { 184 unittest.PrepareTestEnv(t) 185 ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/Home?action=_new") 186 ctx.SetParams("*", "Home") 187 contexttest.LoadUser(t, ctx, 2) 188 contexttest.LoadRepo(t, ctx, 1) 189 web.SetForm(ctx, &forms.NewWikiForm{ 190 Title: title, 191 Content: content, 192 Message: message, 193 }) 194 EditWikiPost(ctx) 195 assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status()) 196 assertWikiExists(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)) 197 assert.Equal(t, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)), content) 198 if title != "Home" { 199 assertWikiNotExists(t, ctx.Repo.Repository, "Home") 200 } 201 } 202 } 203 204 func TestDeleteWikiPagePost(t *testing.T) { 205 unittest.PrepareTestEnv(t) 206 207 ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/Home?action=_delete") 208 contexttest.LoadUser(t, ctx, 2) 209 contexttest.LoadRepo(t, ctx, 1) 210 DeleteWikiPagePost(ctx) 211 assert.EqualValues(t, http.StatusOK, ctx.Resp.Status()) 212 assertWikiNotExists(t, ctx.Repo.Repository, "Home") 213 } 214 215 func TestWikiRaw(t *testing.T) { 216 for filepath, filetype := range map[string]string{ 217 "jpeg.jpg": "image/jpeg", 218 "images/jpeg.jpg": "image/jpeg", 219 "files/Non-Renderable-File.zip": "application/octet-stream", 220 "Page With Spaced Name": "text/plain; charset=utf-8", 221 "Page-With-Spaced-Name": "text/plain; charset=utf-8", 222 "Page With Spaced Name.md": "", // there is no "Page With Spaced Name.md" in repo 223 "Page-With-Spaced-Name.md": "text/plain; charset=utf-8", 224 } { 225 unittest.PrepareTestEnv(t) 226 227 ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/raw/"+url.PathEscape(filepath)) 228 ctx.SetParams("*", filepath) 229 contexttest.LoadUser(t, ctx, 2) 230 contexttest.LoadRepo(t, ctx, 1) 231 WikiRaw(ctx) 232 if filetype == "" { 233 assert.EqualValues(t, http.StatusNotFound, ctx.Resp.Status(), "filepath: %s", filepath) 234 } else { 235 assert.EqualValues(t, http.StatusOK, ctx.Resp.Status(), "filepath: %s", filepath) 236 assert.EqualValues(t, filetype, ctx.Resp.Header().Get("Content-Type"), "filepath: %s", filepath) 237 } 238 } 239 } 240 241 func TestDefaultWikiBranch(t *testing.T) { 242 unittest.PrepareTestEnv(t) 243 244 // repo with no wiki 245 repoWithNoWiki := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) 246 assert.False(t, repoWithNoWiki.HasWiki()) 247 assert.NoError(t, wiki_service.ChangeDefaultWikiBranch(db.DefaultContext, repoWithNoWiki, "main")) 248 249 // repo with wiki 250 assert.NoError(t, repo_model.UpdateRepositoryCols(db.DefaultContext, &repo_model.Repository{ID: 1, DefaultWikiBranch: "wrong-branch"})) 251 252 ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki") 253 ctx.SetParams("*", "Home") 254 contexttest.LoadRepo(t, ctx, 1) 255 assert.Equal(t, "wrong-branch", ctx.Repo.Repository.DefaultWikiBranch) 256 Wiki(ctx) // after the visiting, the out-of-sync database record will update the branch name to "master" 257 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 258 assert.Equal(t, "master", ctx.Repo.Repository.DefaultWikiBranch) 259 260 // invalid branch name should fail 261 assert.Error(t, wiki_service.ChangeDefaultWikiBranch(db.DefaultContext, repo, "the bad name")) 262 repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 263 assert.Equal(t, "master", repo.DefaultWikiBranch) 264 265 // the same branch name, should succeed (actually a no-op) 266 assert.NoError(t, wiki_service.ChangeDefaultWikiBranch(db.DefaultContext, repo, "master")) 267 repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 268 assert.Equal(t, "master", repo.DefaultWikiBranch) 269 270 // change to another name 271 assert.NoError(t, wiki_service.ChangeDefaultWikiBranch(db.DefaultContext, repo, "main")) 272 repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 273 assert.Equal(t, "main", repo.DefaultWikiBranch) 274 }