Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

markdown_test.go 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. package markdown_test
  2. import (
  3. "fmt"
  4. "strconv"
  5. "testing"
  6. "strings"
  7. . "code.gitea.io/gitea/modules/markdown"
  8. "code.gitea.io/gitea/modules/setting"
  9. "github.com/stretchr/testify/assert"
  10. )
  11. const AppURL = "http://localhost:3000/"
  12. const Repo = "gogits/gogs"
  13. const AppSubURL = AppURL + Repo + "/"
  14. var numericMetas = map[string]string{
  15. "format": "https://someurl.com/{user}/{repo}/{index}",
  16. "user": "someUser",
  17. "repo": "someRepo",
  18. "style": IssueNameStyleNumeric,
  19. }
  20. var alphanumericMetas = map[string]string{
  21. "format": "https://someurl.com/{user}/{repo}/{index}",
  22. "user": "someUser",
  23. "repo": "someRepo",
  24. "style": IssueNameStyleAlphanumeric,
  25. }
  26. // numericLink an HTML to a numeric-style issue
  27. func numericIssueLink(baseURL string, index int) string {
  28. return link(URLJoin(baseURL, strconv.Itoa(index)), fmt.Sprintf("#%d", index))
  29. }
  30. // alphanumLink an HTML link to an alphanumeric-style issue
  31. func alphanumIssueLink(baseURL string, name string) string {
  32. return link(URLJoin(baseURL, name), name)
  33. }
  34. // urlContentsLink an HTML link whose contents is the target URL
  35. func urlContentsLink(href string) string {
  36. return link(href, href)
  37. }
  38. // link an HTML link
  39. func link(href, contents string) string {
  40. return fmt.Sprintf("<a href=\"%s\">%s</a>", href, contents)
  41. }
  42. func testRenderIssueIndexPattern(t *testing.T, input, expected string, metas map[string]string) {
  43. assert.Equal(t, expected,
  44. string(RenderIssueIndexPattern([]byte(input), AppSubURL, metas)))
  45. }
  46. func TestRender_IssueIndexPattern(t *testing.T) {
  47. // numeric: render inputs without valid mentions
  48. test := func(s string) {
  49. testRenderIssueIndexPattern(t, s, s, nil)
  50. testRenderIssueIndexPattern(t, s, s, numericMetas)
  51. }
  52. // should not render anything when there are no mentions
  53. test("")
  54. test("this is a test")
  55. test("test 123 123 1234")
  56. test("#")
  57. test("# # #")
  58. test("# 123")
  59. test("#abcd")
  60. test("##1234")
  61. test("test#1234")
  62. test("#1234test")
  63. test(" test #1234test")
  64. // should not render issue mention without leading space
  65. test("test#54321 issue")
  66. // should not render issue mention without trailing space
  67. test("test #54321issue")
  68. }
  69. func TestRender_IssueIndexPattern2(t *testing.T) {
  70. setting.AppURL = AppURL
  71. setting.AppSubURL = AppSubURL
  72. // numeric: render inputs with valid mentions
  73. test := func(s, expectedFmt string, indices ...int) {
  74. links := make([]interface{}, len(indices))
  75. for i, index := range indices {
  76. links[i] = numericIssueLink(URLJoin(setting.AppSubURL, "issues"), index)
  77. }
  78. expectedNil := fmt.Sprintf(expectedFmt, links...)
  79. testRenderIssueIndexPattern(t, s, expectedNil, nil)
  80. for i, index := range indices {
  81. links[i] = numericIssueLink("https://someurl.com/someUser/someRepo/", index)
  82. }
  83. expectedNum := fmt.Sprintf(expectedFmt, links...)
  84. testRenderIssueIndexPattern(t, s, expectedNum, numericMetas)
  85. }
  86. // should render freestanding mentions
  87. test("#1234 test", "%s test", 1234)
  88. test("test #8 issue", "test %s issue", 8)
  89. test("test issue #1234", "test issue %s", 1234)
  90. // should render mentions in parentheses
  91. test("(#54321 issue)", "(%s issue)", 54321)
  92. test("test (#9801 extra) issue", "test (%s extra) issue", 9801)
  93. test("test (#1)", "test (%s)", 1)
  94. // should render multiple issue mentions in the same line
  95. test("#54321 #1243", "%s %s", 54321, 1243)
  96. test("wow (#54321 #1243)", "wow (%s %s)", 54321, 1243)
  97. test("(#4)(#5)", "(%s)(%s)", 4, 5)
  98. test("#1 (#4321) test", "%s (%s) test", 1, 4321)
  99. }
  100. func TestRender_IssueIndexPattern3(t *testing.T) {
  101. setting.AppURL = AppURL
  102. setting.AppSubURL = AppSubURL
  103. // alphanumeric: render inputs without valid mentions
  104. test := func(s string) {
  105. testRenderIssueIndexPattern(t, s, s, alphanumericMetas)
  106. }
  107. test("")
  108. test("this is a test")
  109. test("test 123 123 1234")
  110. test("#")
  111. test("##1234")
  112. test("# 123")
  113. test("#abcd")
  114. test("test #123")
  115. test("abc-1234") // issue prefix must be capital
  116. test("ABc-1234") // issue prefix must be _all_ capital
  117. test("ABCDEFGHIJK-1234") // the limit is 10 characters in the prefix
  118. test("ABC1234") // dash is required
  119. test("test ABC- test") // number is required
  120. test("test -1234 test") // prefix is required
  121. test("testABC-123 test") // leading space is required
  122. test("test ABC-123test") // trailing space is required
  123. test("ABC-0123") // no leading zero
  124. }
  125. func TestRender_IssueIndexPattern4(t *testing.T) {
  126. setting.AppURL = AppURL
  127. setting.AppSubURL = AppSubURL
  128. // alphanumeric: render inputs with valid mentions
  129. test := func(s, expectedFmt string, names ...string) {
  130. links := make([]interface{}, len(names))
  131. for i, name := range names {
  132. links[i] = alphanumIssueLink("https://someurl.com/someUser/someRepo/", name)
  133. }
  134. expected := fmt.Sprintf(expectedFmt, links...)
  135. testRenderIssueIndexPattern(t, s, expected, alphanumericMetas)
  136. }
  137. test("OTT-1234 test", "%s test", "OTT-1234")
  138. test("test T-12 issue", "test %s issue", "T-12")
  139. test("test issue ABCDEFGHIJ-1234567890", "test issue %s", "ABCDEFGHIJ-1234567890")
  140. }
  141. func TestRender_AutoLink(t *testing.T) {
  142. setting.AppURL = AppURL
  143. setting.AppSubURL = AppSubURL
  144. test := func(input, expected string) {
  145. buffer := RenderSpecialLink([]byte(input), setting.AppSubURL, nil, false)
  146. assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
  147. buffer = RenderSpecialLink([]byte(input), setting.AppSubURL, nil, true)
  148. assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
  149. }
  150. // render valid issue URLs
  151. test(URLJoin(setting.AppSubURL, "issues", "3333"),
  152. numericIssueLink(URLJoin(setting.AppSubURL, "issues"), 3333))
  153. // render external issue URLs
  154. tmp := "http://1111/2222/ssss-issues/3333?param=blah&blahh=333"
  155. test(tmp, "<a href=\""+tmp+"\">#3333 <i class='comment icon'></i></a>")
  156. test("http://test.com/issues/33333", numericIssueLink("http://test.com/issues", 33333))
  157. test("https://issues/333", numericIssueLink("https://issues", 333))
  158. // render valid commit URLs
  159. tmp = URLJoin(AppSubURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae")
  160. test(tmp, "<a href=\""+tmp+"\">d8a994ef24</a>")
  161. tmp += "#diff-2"
  162. test(tmp, "<a href=\""+tmp+"\">d8a994ef24 (diff-2)</a>")
  163. // render other commit URLs
  164. tmp = "https://external-link.gogs.io/gogs/gogs/commit/d8a994ef243349f321568f9e36d5c3f444b99cae#diff-2"
  165. test(tmp, "<a href=\""+tmp+"\">d8a994ef24 (diff-2)</a>")
  166. }
  167. func TestRender_StandardLinks(t *testing.T) {
  168. setting.AppURL = AppURL
  169. setting.AppSubURL = AppSubURL
  170. test := func(input, expected, expectedWiki string) {
  171. buffer := RenderString(input, setting.AppSubURL, nil)
  172. assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
  173. bufferWiki := RenderWiki([]byte(input), setting.AppSubURL, nil)
  174. assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(bufferWiki))
  175. }
  176. googleRendered := `<p><a href="https://google.com/" rel="nofollow">https://google.com/</a></p>`
  177. test("<https://google.com/>", googleRendered, googleRendered)
  178. lnk := URLJoin(AppSubURL, "WikiPage")
  179. lnkWiki := URLJoin(AppSubURL, "wiki", "WikiPage")
  180. test("[WikiPage](WikiPage)",
  181. `<p><a href="`+lnk+`" rel="nofollow">WikiPage</a></p>`,
  182. `<p><a href="`+lnkWiki+`" rel="nofollow">WikiPage</a></p>`)
  183. }
  184. func TestRender_ShortLinks(t *testing.T) {
  185. setting.AppURL = AppURL
  186. setting.AppSubURL = AppSubURL
  187. tree := URLJoin(AppSubURL, "src", "master")
  188. test := func(input, expected, expectedWiki string) {
  189. buffer := RenderString(input, tree, nil)
  190. assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
  191. buffer = RenderWiki([]byte(input), setting.AppSubURL, nil)
  192. assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer)))
  193. }
  194. rawtree := URLJoin(AppSubURL, "raw", "master")
  195. url := URLJoin(tree, "Link")
  196. imgurl := URLJoin(rawtree, "Link.jpg")
  197. urlWiki := URLJoin(AppSubURL, "wiki", "Link")
  198. imgurlWiki := URLJoin(AppSubURL, "wiki", "raw", "Link.jpg")
  199. favicon := "http://google.com/favicon.ico"
  200. test(
  201. "[[Link]]",
  202. `<p><a href="`+url+`" rel="nofollow">Link</a></p>`,
  203. `<p><a href="`+urlWiki+`" rel="nofollow">Link</a></p>`)
  204. test(
  205. "[[Link.jpg]]",
  206. `<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" alt="Link.jpg" title="Link.jpg"/></a></p>`,
  207. `<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" alt="Link.jpg" title="Link.jpg"/></a></p>`)
  208. test(
  209. "[["+favicon+"]]",
  210. `<p><a href="`+favicon+`" rel="nofollow"><img src="`+favicon+`" title="favicon.ico"/></a></p>`,
  211. `<p><a href="`+favicon+`" rel="nofollow"><img src="`+favicon+`" title="favicon.ico"/></a></p>`)
  212. test(
  213. "[[Name|Link]]",
  214. `<p><a href="`+url+`" rel="nofollow">Name</a></p>`,
  215. `<p><a href="`+urlWiki+`" rel="nofollow">Name</a></p>`)
  216. test(
  217. "[[Name|Link.jpg]]",
  218. `<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" alt="Name" title="Name"/></a></p>`,
  219. `<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" alt="Name" title="Name"/></a></p>`)
  220. test(
  221. "[[Name|Link.jpg|alt=AltName]]",
  222. `<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" alt="AltName" title="AltName"/></a></p>`,
  223. `<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" alt="AltName" title="AltName"/></a></p>`)
  224. test(
  225. "[[Name|Link.jpg|title=Title]]",
  226. `<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" alt="Title" title="Title"/></a></p>`,
  227. `<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" alt="Title" title="Title"/></a></p>`)
  228. test(
  229. "[[Name|Link.jpg|alt=AltName|title=Title]]",
  230. `<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" alt="AltName" title="Title"/></a></p>`,
  231. `<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" alt="AltName" title="Title"/></a></p>`)
  232. test(
  233. "[[Name|Link.jpg|alt=\"AltName\"|title='Title']]",
  234. `<p><a href="`+imgurl+`" rel="nofollow"><img src="`+imgurl+`" alt="AltName" title="Title"/></a></p>`,
  235. `<p><a href="`+imgurlWiki+`" rel="nofollow"><img src="`+imgurlWiki+`" alt="AltName" title="Title"/></a></p>`)
  236. }
  237. func TestRender_Commits(t *testing.T) {
  238. setting.AppURL = AppURL
  239. setting.AppSubURL = AppSubURL
  240. test := func(input, expected string) {
  241. buffer := RenderString(input, setting.AppSubURL, nil)
  242. assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
  243. }
  244. var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579"
  245. var commit = URLJoin(AppSubURL, "commit", sha)
  246. var subtree = URLJoin(commit, "src")
  247. var tree = strings.Replace(subtree, "/commit/", "/tree/", -1)
  248. var src = strings.Replace(subtree, "/commit/", "/src/", -1)
  249. test(sha, `<p><a href="`+commit+`" rel="nofollow">b6dd6210ea</a></p>`)
  250. test(commit, `<p><a href="`+commit+`" rel="nofollow">b6dd6210ea</a></p>`)
  251. test(tree, `<p><a href="`+src+`" rel="nofollow">b6dd6210ea/src</a></p>`)
  252. }
  253. func TestRender_Images(t *testing.T) {
  254. setting.AppURL = AppURL
  255. setting.AppSubURL = AppSubURL
  256. test := func(input, expected string) {
  257. buffer := RenderString(input, setting.AppSubURL, nil)
  258. assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
  259. }
  260. url := "../../.images/src/02/train.jpg"
  261. title := "Train"
  262. result := URLJoin(AppSubURL, url)
  263. test(
  264. "!["+title+"]("+url+")",
  265. `<p><a href="`+result+`" rel="nofollow"><img src="`+result+`" alt="`+title+`"></a></p>`)
  266. test(
  267. "[["+title+"|"+url+"]]",
  268. `<p><a href="`+result+`" rel="nofollow"><img src="`+result+`" alt="`+title+`" title="`+title+`"/></a></p>`)
  269. }
  270. func TestRender_CrossReferences(t *testing.T) {
  271. setting.AppURL = AppURL
  272. setting.AppSubURL = AppSubURL
  273. test := func(input, expected string) {
  274. buffer := RenderString(input, setting.AppSubURL, nil)
  275. assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
  276. }
  277. test(
  278. "gogits/gogs#12345",
  279. `<p><a href="`+URLJoin(AppURL, "gogits", "gogs", "issues", "12345")+`" rel="nofollow">gogits/gogs#12345</a></p>`)
  280. }
  281. func TestRegExp_MentionPattern(t *testing.T) {
  282. trueTestCases := []string{
  283. "@Unknwon",
  284. "@ANT_123",
  285. "@xxx-DiN0-z-A..uru..s-xxx",
  286. " @lol ",
  287. " @Te/st",
  288. }
  289. falseTestCases := []string{
  290. "@ 0",
  291. "@ ",
  292. "@",
  293. "",
  294. "ABC",
  295. }
  296. for _, testCase := range trueTestCases {
  297. res := MentionPattern.MatchString(testCase)
  298. if !res {
  299. println()
  300. println(testCase)
  301. }
  302. assert.True(t, res)
  303. }
  304. for _, testCase := range falseTestCases {
  305. res := MentionPattern.MatchString(testCase)
  306. if res {
  307. println()
  308. println(testCase)
  309. }
  310. assert.False(t, res)
  311. }
  312. }
  313. func TestRegExp_IssueNumericPattern(t *testing.T) {
  314. trueTestCases := []string{
  315. "#1234",
  316. "#0",
  317. "#1234567890987654321",
  318. }
  319. falseTestCases := []string{
  320. "# 1234",
  321. "# 0",
  322. "# ",
  323. "#",
  324. "#ABC",
  325. "#1A2B",
  326. "",
  327. "ABC",
  328. }
  329. for _, testCase := range trueTestCases {
  330. assert.True(t, IssueNumericPattern.MatchString(testCase))
  331. }
  332. for _, testCase := range falseTestCases {
  333. assert.False(t, IssueNumericPattern.MatchString(testCase))
  334. }
  335. }
  336. func TestRegExp_IssueAlphanumericPattern(t *testing.T) {
  337. trueTestCases := []string{
  338. "ABC-1234",
  339. "A-1",
  340. "RC-80",
  341. "ABCDEFGHIJ-1234567890987654321234567890",
  342. }
  343. falseTestCases := []string{
  344. "RC-08",
  345. "PR-0",
  346. "ABCDEFGHIJK-1",
  347. "PR_1",
  348. "",
  349. "#ABC",
  350. "",
  351. "ABC",
  352. "GG-",
  353. "rm-1",
  354. }
  355. for _, testCase := range trueTestCases {
  356. assert.True(t, IssueAlphanumericPattern.MatchString(testCase))
  357. }
  358. for _, testCase := range falseTestCases {
  359. assert.False(t, IssueAlphanumericPattern.MatchString(testCase))
  360. }
  361. }
  362. func TestRegExp_Sha1CurrentPattern(t *testing.T) {
  363. trueTestCases := []string{
  364. "d8a994ef243349f321568f9e36d5c3f444b99cae",
  365. "abcdefabcdefabcdefabcdefabcdefabcdefabcd",
  366. }
  367. falseTestCases := []string{
  368. "test",
  369. "abcdefg",
  370. "abcdefghijklmnopqrstuvwxyzabcdefghijklmn",
  371. "abcdefghijklmnopqrstuvwxyzabcdefghijklmO",
  372. }
  373. for _, testCase := range trueTestCases {
  374. assert.True(t, Sha1CurrentPattern.MatchString(testCase))
  375. }
  376. for _, testCase := range falseTestCases {
  377. assert.False(t, Sha1CurrentPattern.MatchString(testCase))
  378. }
  379. }
  380. func TestRegExp_ShortLinkPattern(t *testing.T) {
  381. trueTestCases := []string{
  382. "[[stuff]]",
  383. "[[]]",
  384. "[[stuff|title=Difficult name with spaces*!]]",
  385. }
  386. falseTestCases := []string{
  387. "test",
  388. "abcdefg",
  389. "[[]",
  390. "[[",
  391. "[]",
  392. "]]",
  393. "abcdefghijklmnopqrstuvwxyz",
  394. }
  395. for _, testCase := range trueTestCases {
  396. assert.True(t, ShortLinkPattern.MatchString(testCase))
  397. }
  398. for _, testCase := range falseTestCases {
  399. assert.False(t, ShortLinkPattern.MatchString(testCase))
  400. }
  401. }
  402. func TestRegExp_AnySHA1Pattern(t *testing.T) {
  403. testCases := map[string][]string{
  404. "https://github.com/jquery/jquery/blob/a644101ed04d0beacea864ce805e0c4f86ba1cd1/test/unit/event.js#L2703": []string{
  405. "https",
  406. "github.com",
  407. "jquery",
  408. "jquery",
  409. "blob",
  410. "a644101ed04d0beacea864ce805e0c4f86ba1cd1",
  411. "test/unit/event.js",
  412. "L2703",
  413. },
  414. "https://github.com/jquery/jquery/blob/a644101ed04d0beacea864ce805e0c4f86ba1cd1/test/unit/event.js": []string{
  415. "https",
  416. "github.com",
  417. "jquery",
  418. "jquery",
  419. "blob",
  420. "a644101ed04d0beacea864ce805e0c4f86ba1cd1",
  421. "test/unit/event.js",
  422. "",
  423. },
  424. "https://github.com/jquery/jquery/commit/0705be475092aede1eddae01319ec931fb9c65fc": []string{
  425. "https",
  426. "github.com",
  427. "jquery",
  428. "jquery",
  429. "commit",
  430. "0705be475092aede1eddae01319ec931fb9c65fc",
  431. "",
  432. "",
  433. },
  434. "https://github.com/jquery/jquery/tree/0705be475092aede1eddae01319ec931fb9c65fc/src": []string{
  435. "https",
  436. "github.com",
  437. "jquery",
  438. "jquery",
  439. "tree",
  440. "0705be475092aede1eddae01319ec931fb9c65fc",
  441. "src",
  442. "",
  443. },
  444. "https://try.gogs.io/gogs/gogs/commit/d8a994ef243349f321568f9e36d5c3f444b99cae#diff-2": []string{
  445. "https",
  446. "try.gogs.io",
  447. "gogs",
  448. "gogs",
  449. "commit",
  450. "d8a994ef243349f321568f9e36d5c3f444b99cae",
  451. "",
  452. "diff-2",
  453. },
  454. }
  455. for k, v := range testCases {
  456. assert.Equal(t, AnySHA1Pattern.FindStringSubmatch(k)[1:], v)
  457. }
  458. }
  459. func TestRegExp_IssueFullPattern(t *testing.T) {
  460. testCases := map[string][]string{
  461. "https://github.com/gogits/gogs/pull/3244": []string{
  462. "https",
  463. "github.com/gogits/gogs/pull/",
  464. "3244",
  465. "",
  466. "",
  467. },
  468. "https://github.com/gogits/gogs/issues/3247#issuecomment-231517079": []string{
  469. "https",
  470. "github.com/gogits/gogs/issues/",
  471. "3247",
  472. "#issuecomment-231517079",
  473. "",
  474. },
  475. "https://try.gogs.io/gogs/gogs/issues/4#issue-685": []string{
  476. "https",
  477. "try.gogs.io/gogs/gogs/issues/",
  478. "4",
  479. "#issue-685",
  480. "",
  481. },
  482. "https://youtrack.jetbrains.com/issue/JT-36485": []string{
  483. "https",
  484. "youtrack.jetbrains.com/issue/",
  485. "JT-36485",
  486. "",
  487. "",
  488. },
  489. "https://youtrack.jetbrains.com/issue/JT-36485#comment=27-1508676": []string{
  490. "https",
  491. "youtrack.jetbrains.com/issue/",
  492. "JT-36485",
  493. "#comment=27-1508676",
  494. "",
  495. },
  496. }
  497. for k, v := range testCases {
  498. assert.Equal(t, IssueFullPattern.FindStringSubmatch(k)[1:], v)
  499. }
  500. }
  501. func TestMisc_IsMarkdownFile(t *testing.T) {
  502. setting.Markdown.FileExtensions = []string{".md", ".markdown", ".mdown", ".mkd"}
  503. trueTestCases := []string{
  504. "test.md",
  505. "wow.MARKDOWN",
  506. "LOL.mDoWn",
  507. }
  508. falseTestCases := []string{
  509. "test",
  510. "abcdefg",
  511. "abcdefghijklmnopqrstuvwxyz",
  512. "test.md.test",
  513. }
  514. for _, testCase := range trueTestCases {
  515. assert.True(t, IsMarkdownFile(testCase))
  516. }
  517. for _, testCase := range falseTestCases {
  518. assert.False(t, IsMarkdownFile(testCase))
  519. }
  520. }
  521. func TestMisc_IsReadmeFile(t *testing.T) {
  522. trueTestCases := []string{
  523. "readme",
  524. "README",
  525. "readME.mdown",
  526. "README.md",
  527. }
  528. falseTestCases := []string{
  529. "test.md",
  530. "wow.MARKDOWN",
  531. "LOL.mDoWn",
  532. "test",
  533. "abcdefg",
  534. "abcdefghijklmnopqrstuvwxyz",
  535. "test.md.test",
  536. }
  537. for _, testCase := range trueTestCases {
  538. assert.True(t, IsReadmeFile(testCase))
  539. }
  540. for _, testCase := range falseTestCases {
  541. assert.False(t, IsReadmeFile(testCase))
  542. }
  543. }
  544. func TestMisc_IsSameDomain(t *testing.T) {
  545. setting.AppURL = AppURL
  546. setting.AppSubURL = AppSubURL
  547. var sha = "b6dd6210eaebc915fd5be5579c58cce4da2e2579"
  548. var commit = URLJoin(AppSubURL, "commit", sha)
  549. assert.True(t, IsSameDomain(commit))
  550. assert.False(t, IsSameDomain("http://google.com/ncr"))
  551. assert.False(t, IsSameDomain("favicon.ico"))
  552. }
  553. // Test cases without ambiguous links
  554. var sameCases = []string{
  555. // dear imgui wiki markdown extract: special wiki syntax
  556. `Wiki! Enjoy :)
  557. - [[Links, Language bindings, Engine bindings|Links]]
  558. - [[Tips]]
  559. Ideas and codes
  560. - Bezier widget (by @r-lyeh) https://github.com/ocornut/imgui/issues/786
  561. - Node graph editors https://github.com/ocornut/imgui/issues/306
  562. - [[Memory Editor|memory_editor_example]]
  563. - [[Plot var helper|plot_var_example]]`,
  564. // wine-staging wiki home extract: tables, special wiki syntax, images
  565. `## What is Wine Staging?
  566. **Wine Staging** on website [wine-staging.com](http://wine-staging.com).
  567. ## Quick Links
  568. Here are some links to the most important topics. You can find the full list of pages at the sidebar.
  569. | [[images/icon-install.png]] | [[Installation]] |
  570. |--------------------------------|----------------------------------------------------------|
  571. | [[images/icon-usage.png]] | [[Usage]] |
  572. `,
  573. // libgdx wiki page: inline images with special syntax
  574. `[Excelsior JET](http://www.excelsiorjet.com/) allows you to create native executables for Windows, Linux and Mac OS X.
  575. 1. [Package your libGDX application](https://github.com/libgdx/libgdx/wiki/Gradle-on-the-Commandline#packaging-for-the-desktop)
  576. [[images/1.png]]
  577. 2. Perform a test run by hitting the Run! button.
  578. [[images/2.png]]`,
  579. }
  580. func testAnswers(baseURLContent, baseURLImages string) []string {
  581. return []string{
  582. `<p>Wiki! Enjoy :)</p>
  583. <ul>
  584. <li><a href="` + baseURLContent + `Links" rel="nofollow">Links, Language bindings, Engine bindings</a></li>
  585. <li><a href="` + baseURLContent + `Tips" rel="nofollow">Tips</a></li>
  586. </ul>
  587. <p>Ideas and codes</p>
  588. <ul>
  589. <li>Bezier widget (by <a href="` + AppURL + `r-lyeh" rel="nofollow">@r-lyeh</a>)<a href="https://github.com/ocornut/imgui/issues/786" rel="nofollow">#786</a></li>
  590. <li>Node graph editors<a href="https://github.com/ocornut/imgui/issues/306" rel="nofollow">#306</a></li>
  591. <li><a href="` + baseURLContent + `memory_editor_example" rel="nofollow">Memory Editor</a></li>
  592. <li><a href="` + baseURLContent + `plot_var_example" rel="nofollow">Plot var helper</a></li>
  593. </ul>
  594. `,
  595. `<h2>What is Wine Staging?</h2>
  596. <p><strong>Wine Staging</strong> on website <a href="http://wine-staging.com" rel="nofollow">wine-staging.com</a>.</p>
  597. <h2>Quick Links</h2>
  598. <p>Here are some links to the most important topics. You can find the full list of pages at the sidebar.</p>
  599. <table>
  600. <thead>
  601. <tr>
  602. <th><a href="` + baseURLImages + `images/icon-install.png" rel="nofollow"><img src="` + baseURLImages + `images/icon-install.png" alt="images/icon-install.png" title="icon-install.png"/></a></th>
  603. <th><a href="` + baseURLContent + `Installation" rel="nofollow">Installation</a></th>
  604. </tr>
  605. </thead>
  606. <tbody>
  607. <tr>
  608. <td><a href="` + baseURLImages + `images/icon-usage.png" rel="nofollow"><img src="` + baseURLImages + `images/icon-usage.png" alt="images/icon-usage.png" title="icon-usage.png"/></a></td>
  609. <td><a href="` + baseURLContent + `Usage" rel="nofollow">Usage</a></td>
  610. </tr>
  611. </tbody>
  612. </table>
  613. `,
  614. `<p><a href="http://www.excelsiorjet.com/" rel="nofollow">Excelsior JET</a> allows you to create native executables for Windows, Linux and Mac OS X.</p>
  615. <ol>
  616. <li><a href="https://github.com/libgdx/libgdx/wiki/Gradle-on-the-Commandline#packaging-for-the-desktop" rel="nofollow">Package your libGDX application</a>
  617. <a href="` + baseURLImages + `images/1.png" rel="nofollow"><img src="` + baseURLImages + `images/1.png" alt="images/1.png" title="1.png"/></a></li>
  618. <li>Perform a test run by hitting the Run! button.
  619. <a href="` + baseURLImages + `images/2.png" rel="nofollow"><img src="` + baseURLImages + `images/2.png" alt="images/2.png" title="2.png"/></a></li>
  620. </ol>
  621. `,
  622. }
  623. }
  624. func TestTotal_RenderString(t *testing.T) {
  625. answers := testAnswers(URLJoin(AppSubURL, "src", "master/"), URLJoin(AppSubURL, "raw", "master/"))
  626. for i := 0; i < len(sameCases); i++ {
  627. line := RenderString(sameCases[i], URLJoin(AppSubURL, "src", "master/"), nil)
  628. assert.Equal(t, answers[i], line)
  629. }
  630. testCases := []string{}
  631. for i := 0; i < len(testCases); i += 2 {
  632. line := RenderString(testCases[i], AppSubURL, nil)
  633. assert.Equal(t, testCases[i+1], line)
  634. }
  635. }
  636. func TestTotal_RenderWiki(t *testing.T) {
  637. answers := testAnswers(URLJoin(AppSubURL, "wiki/"), URLJoin(AppSubURL, "wiki", "raw/"))
  638. for i := 0; i < len(sameCases); i++ {
  639. line := RenderWiki([]byte(sameCases[i]), AppSubURL, nil)
  640. assert.Equal(t, answers[i], line)
  641. }
  642. testCases := []string{
  643. // Guard wiki sidebar: special syntax
  644. `[[Guardfile-DSL / Configuring-Guard|Guardfile-DSL---Configuring-Guard]]`,
  645. // rendered
  646. `<p><a href="` + AppSubURL + `wiki/Guardfile-DSL---Configuring-Guard" rel="nofollow">Guardfile-DSL / Configuring-Guard</a></p>
  647. `,
  648. // special syntax
  649. `[[Name|Link]]`,
  650. // rendered
  651. `<p><a href="` + AppSubURL + `wiki/Link" rel="nofollow">Name</a></p>
  652. `,
  653. }
  654. for i := 0; i < len(testCases); i += 2 {
  655. line := RenderWiki([]byte(testCases[i]), AppSubURL, nil)
  656. assert.Equal(t, testCases[i+1], line)
  657. }
  658. }