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.

wiki_test.go 9.8KB

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