code.gitea.io/gitea@v1.22.3/services/wiki/wiki_test.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package wiki 5 6 import ( 7 "math/rand" 8 "strings" 9 "testing" 10 11 repo_model "code.gitea.io/gitea/models/repo" 12 "code.gitea.io/gitea/models/unittest" 13 user_model "code.gitea.io/gitea/models/user" 14 "code.gitea.io/gitea/modules/git" 15 "code.gitea.io/gitea/modules/gitrepo" 16 17 _ "code.gitea.io/gitea/models/actions" 18 19 "github.com/stretchr/testify/assert" 20 ) 21 22 func TestMain(m *testing.M) { 23 unittest.MainTest(m) 24 } 25 26 func TestWebPathSegments(t *testing.T) { 27 a := WebPathSegments("a%2Fa/b+c/d-e/f-g.-") 28 assert.EqualValues(t, []string{"a/a", "b c", "d e", "f-g"}, a) 29 } 30 31 func TestUserTitleToWebPath(t *testing.T) { 32 type test struct { 33 Expected string 34 UserTitle string 35 } 36 for _, test := range []test{ 37 {"unnamed", ""}, 38 {"unnamed", "."}, 39 {"unnamed", ".."}, 40 {"wiki-name", "wiki name"}, 41 {"title.md.-", "title.md"}, 42 {"wiki-name.-", "wiki-name"}, 43 {"the+wiki-name.-", "the wiki-name"}, 44 {"a%2Fb", "a/b"}, 45 {"a%25b", "a%b"}, 46 } { 47 assert.EqualValues(t, test.Expected, UserTitleToWebPath("", test.UserTitle)) 48 } 49 } 50 51 func TestWebPathToDisplayName(t *testing.T) { 52 type test struct { 53 Expected string 54 WebPath WebPath 55 } 56 for _, test := range []test{ 57 {"wiki name", "wiki-name"}, 58 {"wiki-name", "wiki-name.-"}, 59 {"name with / slash", "name-with %2F slash"}, 60 {"name with % percent", "name-with %25 percent"}, 61 {"2000-01-02 meeting", "2000-01-02+meeting.-.md"}, 62 {"a b", "a%20b.md"}, 63 } { 64 _, displayName := WebPathToUserTitle(test.WebPath) 65 assert.EqualValues(t, test.Expected, displayName) 66 } 67 } 68 69 func TestWebPathToGitPath(t *testing.T) { 70 type test struct { 71 Expected string 72 WikiName WebPath 73 } 74 for _, test := range []test{ 75 {"wiki-name.md", "wiki%20name"}, 76 {"wiki-name.md", "wiki+name"}, 77 {"wiki name.md", "wiki%20name.md"}, 78 {"wiki%20name.md", "wiki%2520name.md"}, 79 {"2000-01-02-meeting.md", "2000-01-02+meeting"}, 80 {"2000-01-02 meeting.-.md", "2000-01-02%20meeting.-"}, 81 } { 82 assert.EqualValues(t, test.Expected, WebPathToGitPath(test.WikiName)) 83 } 84 } 85 86 func TestGitPathToWebPath(t *testing.T) { 87 type test struct { 88 Expected string 89 Filename string 90 } 91 for _, test := range []test{ 92 {"hello-world", "hello-world.md"}, // this shouldn't happen, because it should always have a ".-" suffix 93 {"hello-world", "hello world.md"}, 94 {"hello-world.-", "hello-world.-.md"}, 95 {"hello+world.-", "hello world.-.md"}, 96 {"symbols-%2F", "symbols %2F.md"}, 97 } { 98 name, err := GitPathToWebPath(test.Filename) 99 assert.NoError(t, err) 100 assert.EqualValues(t, test.Expected, name) 101 } 102 for _, badFilename := range []string{ 103 "nofileextension", 104 "wrongfileextension.txt", 105 } { 106 _, err := GitPathToWebPath(badFilename) 107 assert.Error(t, err) 108 assert.True(t, repo_model.IsErrWikiInvalidFileName(err)) 109 } 110 _, err := GitPathToWebPath("badescaping%%.md") 111 assert.Error(t, err) 112 assert.False(t, repo_model.IsErrWikiInvalidFileName(err)) 113 } 114 115 func TestUserWebGitPathConsistency(t *testing.T) { 116 maxLen := 20 117 b := make([]byte, maxLen) 118 for i := 0; i < 1000; i++ { 119 l := rand.Intn(maxLen) 120 for j := 0; j < l; j++ { 121 r := rand.Intn(0x80-0x20) + 0x20 122 b[j] = byte(r) 123 } 124 125 userTitle := strings.TrimSpace(string(b[:l])) 126 if userTitle == "" || userTitle == "." || userTitle == ".." { 127 continue 128 } 129 webPath := UserTitleToWebPath("", userTitle) 130 gitPath := WebPathToGitPath(webPath) 131 132 webPath1, _ := GitPathToWebPath(gitPath) 133 _, userTitle1 := WebPathToUserTitle(webPath1) 134 gitPath1 := WebPathToGitPath(webPath1) 135 136 assert.EqualValues(t, userTitle, userTitle1, "UserTitle for userTitle: %q", userTitle) 137 assert.EqualValues(t, webPath, webPath1, "WebPath for userTitle: %q", userTitle) 138 assert.EqualValues(t, gitPath, gitPath1, "GitPath for userTitle: %q", userTitle) 139 } 140 } 141 142 func TestRepository_InitWiki(t *testing.T) { 143 unittest.PrepareTestEnv(t) 144 // repo1 already has a wiki 145 repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 146 assert.NoError(t, InitWiki(git.DefaultContext, repo1)) 147 148 // repo2 does not already have a wiki 149 repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) 150 assert.NoError(t, InitWiki(git.DefaultContext, repo2)) 151 assert.True(t, repo2.HasWiki()) 152 } 153 154 func TestRepository_AddWikiPage(t *testing.T) { 155 assert.NoError(t, unittest.PrepareTestDatabase()) 156 const wikiContent = "This is the wiki content" 157 const commitMsg = "Commit message" 158 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 159 doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) 160 for _, userTitle := range []string{ 161 "Another page", 162 "Here's a <tag> and a/slash", 163 } { 164 t.Run("test wiki exist: "+userTitle, func(t *testing.T) { 165 webPath := UserTitleToWebPath("", userTitle) 166 assert.NoError(t, AddWikiPage(git.DefaultContext, doer, repo, webPath, wikiContent, commitMsg)) 167 // Now need to show that the page has been added: 168 gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) 169 if !assert.NoError(t, err) { 170 return 171 } 172 defer gitRepo.Close() 173 masterTree, err := gitRepo.GetTree(repo.DefaultWikiBranch) 174 assert.NoError(t, err) 175 gitPath := WebPathToGitPath(webPath) 176 entry, err := masterTree.GetTreeEntryByPath(gitPath) 177 assert.NoError(t, err) 178 assert.EqualValues(t, gitPath, entry.Name(), "%s not added correctly", userTitle) 179 }) 180 } 181 182 t.Run("check wiki already exist", func(t *testing.T) { 183 t.Parallel() 184 // test for already-existing wiki name 185 err := AddWikiPage(git.DefaultContext, doer, repo, "Home", wikiContent, commitMsg) 186 assert.Error(t, err) 187 assert.True(t, repo_model.IsErrWikiAlreadyExist(err)) 188 }) 189 190 t.Run("check wiki reserved name", func(t *testing.T) { 191 t.Parallel() 192 // test for reserved wiki name 193 err := AddWikiPage(git.DefaultContext, doer, repo, "_edit", wikiContent, commitMsg) 194 assert.Error(t, err) 195 assert.True(t, repo_model.IsErrWikiReservedName(err)) 196 }) 197 } 198 199 func TestRepository_EditWikiPage(t *testing.T) { 200 assert.NoError(t, unittest.PrepareTestDatabase()) 201 202 const newWikiContent = "This is the new content" 203 const commitMsg = "Commit message" 204 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 205 doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) 206 for _, newWikiName := range []string{ 207 "Home", // same name as before 208 "New home", 209 "New/name/with/slashes", 210 } { 211 webPath := UserTitleToWebPath("", newWikiName) 212 unittest.PrepareTestEnv(t) 213 assert.NoError(t, EditWikiPage(git.DefaultContext, doer, repo, "Home", webPath, newWikiContent, commitMsg)) 214 215 // Now need to show that the page has been added: 216 gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) 217 assert.NoError(t, err) 218 masterTree, err := gitRepo.GetTree(repo.DefaultWikiBranch) 219 assert.NoError(t, err) 220 gitPath := WebPathToGitPath(webPath) 221 entry, err := masterTree.GetTreeEntryByPath(gitPath) 222 assert.NoError(t, err) 223 assert.EqualValues(t, gitPath, entry.Name(), "%s not edited correctly", newWikiName) 224 225 if newWikiName != "Home" { 226 _, err := masterTree.GetTreeEntryByPath("Home.md") 227 assert.Error(t, err) 228 } 229 gitRepo.Close() 230 } 231 } 232 233 func TestRepository_DeleteWikiPage(t *testing.T) { 234 unittest.PrepareTestEnv(t) 235 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 236 doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) 237 assert.NoError(t, DeleteWikiPage(git.DefaultContext, doer, repo, "Home")) 238 239 // Now need to show that the page has been added: 240 gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) 241 if !assert.NoError(t, err) { 242 return 243 } 244 defer gitRepo.Close() 245 masterTree, err := gitRepo.GetTree(repo.DefaultWikiBranch) 246 assert.NoError(t, err) 247 gitPath := WebPathToGitPath("Home") 248 _, err = masterTree.GetTreeEntryByPath(gitPath) 249 assert.Error(t, err) 250 } 251 252 func TestPrepareWikiFileName(t *testing.T) { 253 unittest.PrepareTestEnv(t) 254 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) 255 gitRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo) 256 if !assert.NoError(t, err) { 257 return 258 } 259 defer gitRepo.Close() 260 261 tests := []struct { 262 name string 263 arg string 264 existence bool 265 wikiPath string 266 wantErr bool 267 }{{ 268 name: "add suffix", 269 arg: "Home", 270 existence: true, 271 wikiPath: "Home.md", 272 wantErr: false, 273 }, { 274 name: "test special chars", 275 arg: "home of and & or wiki page!", 276 existence: false, 277 wikiPath: "home-of-and-%26-or-wiki-page%21.md", 278 wantErr: false, 279 }} 280 for _, tt := range tests { 281 t.Run(tt.name, func(t *testing.T) { 282 webPath := UserTitleToWebPath("", tt.arg) 283 existence, newWikiPath, err := prepareGitPath(gitRepo, repo.DefaultWikiBranch, webPath) 284 if (err != nil) != tt.wantErr { 285 assert.NoError(t, err) 286 return 287 } 288 if existence != tt.existence { 289 if existence { 290 t.Errorf("expect to find no escaped file but we detect one") 291 } else { 292 t.Errorf("expect to find an escaped file but we could not detect one") 293 } 294 } 295 assert.EqualValues(t, tt.wikiPath, newWikiPath) 296 }) 297 } 298 } 299 300 func TestPrepareWikiFileName_FirstPage(t *testing.T) { 301 unittest.PrepareTestEnv(t) 302 303 // Now create a temporaryDirectory 304 tmpDir := t.TempDir() 305 306 err := git.InitRepository(git.DefaultContext, tmpDir, true, git.Sha1ObjectFormat.Name()) 307 assert.NoError(t, err) 308 309 gitRepo, err := git.OpenRepository(git.DefaultContext, tmpDir) 310 if !assert.NoError(t, err) { 311 return 312 } 313 defer gitRepo.Close() 314 315 existence, newWikiPath, err := prepareGitPath(gitRepo, "master", "Home") 316 assert.False(t, existence) 317 assert.NoError(t, err) 318 assert.EqualValues(t, "Home.md", newWikiPath) 319 } 320 321 func TestWebPathConversion(t *testing.T) { 322 assert.Equal(t, "path/wiki", WebPathToURLPath(WebPath("path/wiki"))) 323 assert.Equal(t, "wiki", WebPathToURLPath(WebPath("wiki"))) 324 assert.Equal(t, "", WebPathToURLPath(WebPath(""))) 325 } 326 327 func TestWebPathFromRequest(t *testing.T) { 328 assert.Equal(t, WebPath("a%2Fb"), WebPathFromRequest("a/b")) 329 assert.Equal(t, WebPath("a"), WebPathFromRequest("a")) 330 assert.Equal(t, WebPath("b"), WebPathFromRequest("a/../b")) 331 }