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.3KB

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