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.

MarkupProcessorTest.java 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. package com.gitblit.wicket;
  2. import static org.junit.Assert.*;
  3. import java.io.IOException;
  4. import java.util.Collections;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.Map;
  8. import com.gitblit.manager.IManager;
  9. import com.gitblit.manager.IPluginManager;
  10. import com.gitblit.manager.IRuntimeManager;
  11. import com.gitblit.models.PluginRegistry;
  12. import com.gitblit.tests.mock.MockGitblitContext;
  13. import com.gitblit.tests.mock.MockRuntimeManager;
  14. import org.apache.wicket.util.tester.WicketTester;
  15. import org.jsoup.Jsoup;
  16. import org.jsoup.nodes.Document;
  17. import org.junit.Before;
  18. import org.junit.Test;
  19. import com.gitblit.Keys;
  20. import com.gitblit.tests.mock.MemorySettings;
  21. import com.gitblit.utils.JSoupXssFilter;
  22. import com.gitblit.wicket.MarkupProcessor.MarkupDocument;
  23. import ro.fortsoft.pf4j.PluginState;
  24. import ro.fortsoft.pf4j.PluginWrapper;
  25. import ro.fortsoft.pf4j.Version;
  26. public class MarkupProcessorTest
  27. {
  28. private WicketTester tester;
  29. private MockGitblitContext gbctx;
  30. @Before
  31. public void setUp()
  32. {
  33. IRuntimeManager rm = new MockRuntimeManager(getSettings());
  34. gbctx = new MockGitblitContext();
  35. gbctx.addManager(rm);
  36. tester = new WicketTester(new GitBlitWebApp(null, null,
  37. rm,
  38. getPluginManager(),
  39. null, null, null,
  40. null, null, null,
  41. null, null, null));
  42. }
  43. /*
  44. * The unit tests for MarkupProcessor have two major goals.
  45. * One is to check that links are rendered correctly, and
  46. * the second one is that XSS protection is working.
  47. *
  48. * The proper rendering of markup for the various Wiki/Markdown
  49. * languages is not in focus. This, as a secondary goal, the Wiki/Md
  50. * syntax rendering can be tested to make sure that when switching to
  51. * a new or updated wiki syntax library nothing breaks and the pages
  52. * are still rendered correctly.
  53. * Or, to make sure things actually render correctly, because currently
  54. * they don't as cen be seen with reference images and wiki links,
  55. * for example.
  56. */
  57. @Test
  58. public void testParseMdRepoRelativeLink()
  59. {
  60. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  61. String markup = "link: [a page](file.md)";
  62. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  63. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  64. String href = doc.getElementsByAttribute("href").attr("href");
  65. assertEquals("Incorrect link rendered","doc/testrepo/12345abcde/file.md", href);
  66. }
  67. @Test
  68. public void testParseMdRepoRelativeLinkSubfolder()
  69. {
  70. String psep ="%2F";
  71. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  72. String markup = "link: [a file](folder/file.md)";
  73. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  74. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  75. String href = doc.getElementsByAttribute("href").attr("href");
  76. assertEquals("Incorrect link rendered","doc/testrepo/12345abcde/folder"+psep+"file.md", href);
  77. }
  78. @Test
  79. public void testParseMdRepoRelativeLinkSubSubfolder()
  80. {
  81. String psep ="%2F";
  82. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  83. String markup = "link: [a file](sub/folder/file.md)";
  84. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  85. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  86. String href = doc.getElementsByAttribute("href").attr("href");
  87. assertEquals("Incorrect link rendered","doc/testrepo/12345abcde/sub"+psep+"folder"+psep+"file.md", href);
  88. }
  89. @Test
  90. public void testParseMdRepoRelativeLinkUtf8()
  91. {
  92. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  93. String markup = "link: [a page](日本語.md)";
  94. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  95. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  96. String href = doc.getElementsByAttribute("href").attr("href");
  97. assertEquals("Incorrect link rendered","doc/testrepo/12345abcde/%E6%97%A5%E6%9C%AC%E8%AA%9E.md", href);
  98. }
  99. @Test
  100. public void testParseMdRepoRelativeLinkSubfolderUtf8()
  101. {
  102. String psep ="%2F";
  103. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  104. String markup = "link: [a file](folder/receitas_de_culinária/file.md)";
  105. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  106. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  107. String href = doc.getElementsByAttribute("href").attr("href");
  108. assertEquals("Incorrect link rendered","doc/testrepo/12345abcde/folder"+psep+"receitas_de_culin%C3%A1ria"+psep+"file.md", href);
  109. }
  110. @Test
  111. public void testParseMdExternalLink()
  112. {
  113. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  114. String markup = "link: [a website](http://example.com/page.html)";
  115. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  116. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  117. String href = doc.getElementsByAttribute("href").attr("href");
  118. assertEquals("Incorrect link rendered","http://example.com/page.html", href);
  119. }
  120. @Test
  121. public void testParseMdExternalLinkBare()
  122. {
  123. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  124. String markup = "link: <http://example.com/page.html>";
  125. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  126. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  127. String href = doc.getElementsByAttribute("href").attr("href");
  128. assertEquals("Incorrect link rendered","http://example.com/page.html", href);
  129. }
  130. // We leave it up to the document author to write working links in the document
  131. @Test
  132. public void testParseMdExternalLinkUtf8()
  133. {
  134. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  135. String markup = "link: [Japanese](http://example.com/lang/日本語.html)";
  136. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  137. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  138. String href = doc.getElementsByAttribute("href").attr("href");
  139. assertEquals("Incorrect link rendered","http://example.com/lang/日本語.html", href);
  140. }
  141. @Test
  142. public void testParseMdRepoRelativeRefLink()
  143. {
  144. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  145. String markup = "link: [a page][1]\n\n[1]: file.md";
  146. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  147. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  148. String href = doc.getElementsByAttribute("href").attr("href");
  149. assertEquals("Incorrect link rendered","doc/testrepo/12345abcde/file.md", href);
  150. }
  151. @Test
  152. public void testParseMdRepoRelativeRefLinkSubfolder()
  153. {
  154. String psep ="%2F";
  155. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  156. String markup = "link: [a file][file]\n\n[file]: folder/file.md";
  157. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  158. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  159. String href = doc.getElementsByAttribute("href").attr("href");
  160. assertEquals("Incorrect link rendered","doc/testrepo/12345abcde/folder"+psep+"file.md", href);
  161. }
  162. @Test
  163. public void testParseMdRepoRelativeRefLinkSubSubfolder()
  164. {
  165. String psep ="%2F";
  166. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  167. String markup = "link: [a file][l1] \n\n[l1]: sub/folder/file.md";
  168. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  169. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  170. String href = doc.getElementsByAttribute("href").attr("href");
  171. assertEquals("Incorrect link rendered","doc/testrepo/12345abcde/sub"+psep+"folder"+psep+"file.md", href);
  172. }
  173. @Test
  174. public void testParseMdRepoRelativeRefLinkUtf8()
  175. {
  176. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  177. String markup = "link: [a page][x]\n\n[x]: 日本語.md";
  178. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  179. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  180. String href = doc.getElementsByAttribute("href").attr("href");
  181. assertEquals("Incorrect link rendered","doc/testrepo/12345abcde/%65%E5%67%2C%8A%Ee.md", href);
  182. }
  183. @Test
  184. public void testParseMdRepoRelativeRefLinkSubfolderUtf8()
  185. {
  186. String psep ="%2F";
  187. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  188. String markup = "link: [a file][xy]\n\n[xy]: folder/receitas_de_culinária/file.md";
  189. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  190. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  191. String href = doc.getElementsByAttribute("href").attr("href");
  192. assertEquals("Incorrect link rendered","doc/testrepo/12345abcde/folder"+psep+"receitas_de_culin%C3%A1ria"+psep+"file.md", href);
  193. }
  194. @Test
  195. public void testParseMdExternalRefLink()
  196. {
  197. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  198. String markup = "link: [a website][ex]\n\n[ex]: http://example.com/page.html";
  199. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  200. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  201. String href = doc.getElementsByAttribute("href").attr("href");
  202. assertEquals("Incorrect link rendered","http://example.com/page.html", href);
  203. }
  204. /*
  205. * Apparently wiki style links currently do not work in Markdown.
  206. @Test
  207. public void testParseMdWikiLink()
  208. {
  209. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  210. String markup = "link: [[page]]";
  211. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  212. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  213. String href = doc.getElementsByAttribute("href").attr("href");
  214. assertEquals("Incorrect link rendered","doc/testrepo/12345abcde/page", href);
  215. }
  216. */
  217. @Test
  218. public void testParseMdRepoRelativeImage()
  219. {
  220. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  221. String markup = "image: ![a graphic](graphic.gif)";
  222. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  223. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  224. String ref = doc.getElementsByAttribute("src").attr("src");
  225. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  226. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/graphic.gif", ref);
  227. markup = "image: ![a graphic](graphic.gif \"Some graphic\")";
  228. mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  229. doc = Jsoup.parseBodyFragment(mdoc.html);
  230. ref = doc.getElementsByAttribute("src").attr("src");
  231. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  232. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/graphic.gif", ref);
  233. }
  234. @Test
  235. public void testParseMdRepoRelativeImageUtf8()
  236. {
  237. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  238. String markup = "image: ![look the dog](ドッグ.gif)";
  239. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  240. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  241. String ref = doc.getElementsByAttribute("src").attr("src");
  242. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  243. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/%E3%83%89%E3%83%83%E3%82%B0.gif", ref);
  244. markup = "image: ![look the dog](ドッグ.gif \"シーバ\")";
  245. mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  246. doc = Jsoup.parseBodyFragment(mdoc.html);
  247. ref = doc.getElementsByAttribute("src").attr("src");
  248. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  249. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/%E3%83%89%E3%83%83%E3%82%B0.gif", ref);
  250. }
  251. @Test
  252. public void testParseMdRepoRelativeImageSubfolder()
  253. {
  254. String psep ="!";
  255. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  256. String markup = "image: ![a graphic](results/graphic.gif)";
  257. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  258. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  259. String ref = doc.getElementsByAttribute("src").attr("src");
  260. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  261. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/results"+psep+"graphic.gif", ref);
  262. markup = "image: ![a graphic](results/graphic.gif \"Some graphic\")";
  263. mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  264. doc = Jsoup.parseBodyFragment(mdoc.html);
  265. ref = doc.getElementsByAttribute("src").attr("src");
  266. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  267. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/results"+psep+"graphic.gif", ref);
  268. }
  269. @Test
  270. public void testParseMdRepoRelativeImageSubfolderUtf8()
  271. {
  272. String psep ="!";
  273. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  274. String markup = "image: ![a cat](folder/картинки/cat.jpg)";
  275. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  276. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  277. String ref = doc.getElementsByAttribute("src").attr("src");
  278. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  279. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/folder"+psep+"%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B8"+psep+"cat.jpg", ref);
  280. markup = "image: ![a cat](folder/картинки/cat.jpg \"Кошка\")";
  281. mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  282. doc = Jsoup.parseBodyFragment(mdoc.html);
  283. ref = doc.getElementsByAttribute("src").attr("src");
  284. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  285. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/folder"+psep+"%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B8"+psep+"cat.jpg", ref);
  286. }
  287. @Test
  288. public void testParseMdExternalImage()
  289. {
  290. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  291. String markup = "image: ![a cat](http://example.com/cats/meow.jpg)";
  292. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  293. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  294. String ref = doc.getElementsByAttribute("src").attr("src");
  295. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  296. assertEquals("Incorrect image src rendered","http://example.com/cats/meow.jpg", ref);
  297. markup = "image: ![a cat](http://example.com/cats/meow.jpg \"Miau\")";
  298. mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  299. doc = Jsoup.parseBodyFragment(mdoc.html);
  300. ref = doc.getElementsByAttribute("src").attr("src");
  301. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  302. assertEquals("Incorrect image src rendered","http://example.com/cats/meow.jpg", ref);
  303. }
  304. @Test
  305. public void testParseMdRepoRelativeRefImage()
  306. {
  307. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  308. String markup = "image: ![a graphic][1]\n\n[1]: graphic.gif";
  309. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  310. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  311. String ref = doc.getElementsByAttribute("src").attr("src");
  312. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  313. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/graphic.gif", ref);
  314. markup = "image: ![a graphic][2]\n\n[2]: graphic.gif \"Some graphic\"";
  315. mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  316. doc = Jsoup.parseBodyFragment(mdoc.html);
  317. ref = doc.getElementsByAttribute("src").attr("src");
  318. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  319. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/graphic.gif", ref);
  320. }
  321. @Test
  322. public void testParseMdRepoRelativeRefImageUtf8()
  323. {
  324. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  325. String markup = "image: ![look the dog][1]\n\n[1]: ドッグ.gif";
  326. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  327. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  328. String ref = doc.getElementsByAttribute("src").attr("src");
  329. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  330. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/%E3%83%89%E3%83%83%E3%82%B0.gif", ref);
  331. markup = "image: ![look the dog][1]\n\n[1]: ドッグ.gif \"シーバ\"";
  332. mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  333. doc = Jsoup.parseBodyFragment(mdoc.html);
  334. ref = doc.getElementsByAttribute("src").attr("src");
  335. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  336. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/%E3%83%89%E3%83%83%E3%82%B0.gif", ref);
  337. }
  338. @Test
  339. public void testParseMdRepoRelativeRefImageSubfolder()
  340. {
  341. String psep ="!";
  342. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  343. String markup = "image: ![a cat][cat]\n\n[cat]: folder/cat.jpg";
  344. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  345. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  346. String ref = doc.getElementsByAttribute("src").attr("src");
  347. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  348. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/folder"+psep+"cat.jpg", ref);
  349. markup = "image: ![a cat][cat]\n\n[cat]: folder/cat.jpg \"Кошка\"";
  350. mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  351. doc = Jsoup.parseBodyFragment(mdoc.html);
  352. ref = doc.getElementsByAttribute("src").attr("src");
  353. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  354. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/folder"+psep+"cat.jpg", ref);
  355. }
  356. @Test
  357. public void testParseMdRepoRelativeRefImageSubfolderUtf8()
  358. {
  359. String psep ="!";
  360. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  361. String markup = "image: ![a cat][i1]\n\n[i1]: folder/картинки/cat.jpg";
  362. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  363. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  364. String ref = doc.getElementsByAttribute("src").attr("src");
  365. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  366. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/folder"+psep+"%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B8"+psep+"cat.jpg", ref);
  367. markup = "image: ![a cat][i1]\n\n[i1]: folder/картинки/cat.jpg \"Кошка\"";
  368. mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  369. doc = Jsoup.parseBodyFragment(mdoc.html);
  370. ref = doc.getElementsByAttribute("src").attr("src");
  371. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  372. assertEquals("Incorrect image src rendered","../raw/testrepo/12345abcde/folder"+psep+"%D0%BA%D0%B0%D1%80%D1%82%D0%B8%D0%BD%D0%BA%D0%B8"+psep+"cat.jpg", ref);
  373. }
  374. @Test
  375. public void testParseMdExternalRefImage()
  376. {
  377. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  378. String markup = "image: ![a cat][1]\n\n[1]: http://example.com/cats/meow.jpg";
  379. MarkupDocument mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  380. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  381. String ref = doc.getElementsByAttribute("src").attr("src");
  382. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  383. assertEquals("Incorrect image src rendered","http://example.com/cats/meow.jpg", ref);
  384. markup = "image: ![a cat][1]\n\n[1]: http://example.com/cats/meow.jpg \"Miau\"";
  385. mdoc = mp.parse("testrepo", "12345abcde", "main.md", markup);
  386. doc = Jsoup.parseBodyFragment(mdoc.html);
  387. ref = doc.getElementsByAttribute("src").attr("src");
  388. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  389. assertEquals("Incorrect image src rendered","http://example.com/cats/meow.jpg", ref);
  390. }
  391. @Test
  392. public void testParseMediaWikiRepoRelativeLink()
  393. {
  394. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  395. String psep = "%2F";
  396. String markup = "link: [[document]]";
  397. MarkupDocument mdoc = mp.parse("wikirepo", "12345abcde", "main.mw", markup);
  398. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  399. String ref = doc.getElementsByAttribute("href").attr("href");
  400. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  401. assertEquals("Incorrect link href rendered","doc/wikirepo/12345abcde/wiki"+ psep + "document", ref);
  402. }
  403. @Test
  404. public void testParseMediaWikiRepoRelativeLinkUtf8()
  405. {
  406. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  407. String psep = "%2F";
  408. String markup = "link: [[日本語]]";
  409. MarkupDocument mdoc = mp.parse("wikirepo", "12345abcde", "main.mw", markup);
  410. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  411. String href = doc.getElementsByAttribute("href").attr("href");
  412. assertEquals("Incorrect link rendered","doc/wikirepo/12345abcde/wiki" + psep + "%E6%97%A5%E6%9C%AC%E8%AA%9E", href);
  413. }
  414. @Test
  415. public void testParseMediaWikiExternalLink()
  416. {
  417. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  418. String psep = "%2F";
  419. String markup = "link: [http://example.com/some/document.html document]";
  420. MarkupDocument mdoc = mp.parse("wikirepo", "12345abcde", "main.mw", markup);
  421. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  422. String ref = doc.getElementsByAttribute("href").attr("href");
  423. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  424. assertEquals("Incorrect link href rendered","http://example.com/some/document.html", ref);
  425. }
  426. @Test
  427. public void testParseMediaWikiExternalLinkNumbered()
  428. {
  429. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  430. String psep = "%2F";
  431. String markup = "link: [http://example.com/some/document.html]";
  432. MarkupDocument mdoc = mp.parse("wikirepo", "12345abcde", "main.mw", markup);
  433. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  434. String ref = doc.getElementsByAttribute("href").attr("href");
  435. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  436. assertEquals("Incorrect link href rendered","http://example.com/some/document.html", ref);
  437. }
  438. @Test
  439. public void testParseMediaWikiExternalLinkBare()
  440. {
  441. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  442. String psep = "%2F";
  443. String markup = "link: http://example.com/some/document.html";
  444. MarkupDocument mdoc = mp.parse("wikirepo", "12345abcde", "main.mw", markup);
  445. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  446. String ref = doc.getElementsByAttribute("href").attr("href");
  447. assertFalse("No reference attribute found: " + mdoc.html, ref.isEmpty());
  448. assertEquals("Incorrect link href rendered","http://example.com/some/document.html", ref);
  449. }
  450. // We leave it up to the document author to write working links in the document
  451. @Test
  452. public void testParseMediaWikiExternalLinkUtf8()
  453. {
  454. MarkupProcessor mp = new MarkupProcessor(getSettings(), new JSoupXssFilter());
  455. String psep = "%2F";
  456. String markup = "link: [http://example.com/lang/日本語.html Japanese]";
  457. MarkupDocument mdoc = mp.parse("wikirepo", "12345abcde", "main.mw", markup);
  458. Document doc = Jsoup.parseBodyFragment(mdoc.html);
  459. String href = doc.getElementsByAttribute("href").attr("href");
  460. assertEquals("Incorrect link rendered","http://example.com/lang/日本語.html", href);
  461. }
  462. private MemorySettings getSettings()
  463. {
  464. Map<String, Object> backingMap = new HashMap<String, Object>();
  465. backingMap.put(Keys.web.documents, "readme");
  466. backingMap.put(Keys.web.blobEncodings, "UTF-8 ISO-8859-1");
  467. backingMap.put(Keys.web.confluenceExtensions, "confluence");
  468. backingMap.put(Keys.web.markdownExtensions, "md mkd markdown MD MKD");
  469. backingMap.put(Keys.web.mediawikiExtensions, "mw mediawiki");
  470. backingMap.put(Keys.web.textileExtensions, "textile");
  471. backingMap.put(Keys.web.tracwikiExtensions, "tracwiki");
  472. backingMap.put(Keys.web.twikiExtensions, "twiki");
  473. backingMap.put(Keys.web.forwardSlashCharacter, "/");
  474. backingMap.put(Keys.web.mountParameters, true);
  475. MemorySettings ms = new MemorySettings(backingMap);
  476. return ms;
  477. }
  478. private IPluginManager getPluginManager()
  479. {
  480. return new IPluginManager()
  481. {
  482. @Override
  483. public Version getSystemVersion()
  484. {
  485. return null;
  486. }
  487. @Override
  488. public void startPlugins()
  489. {
  490. }
  491. @Override
  492. public void stopPlugins()
  493. {
  494. }
  495. @Override
  496. public PluginState startPlugin(String pluginId)
  497. {
  498. return null;
  499. }
  500. @Override
  501. public PluginState stopPlugin(String pluginId)
  502. {
  503. return null;
  504. }
  505. @Override
  506. public List<Class<?>> getExtensionClasses(String pluginId)
  507. {
  508. return null;
  509. }
  510. @Override
  511. public <T> List<T> getExtensions(Class<T> type)
  512. {
  513. return null;
  514. }
  515. @Override
  516. public List<PluginWrapper> getPlugins()
  517. {
  518. return Collections.emptyList();
  519. }
  520. @Override
  521. public PluginWrapper getPlugin(String pluginId)
  522. {
  523. return null;
  524. }
  525. @Override
  526. public PluginWrapper whichPlugin(Class<?> clazz)
  527. {
  528. return null;
  529. }
  530. @Override
  531. public boolean disablePlugin(String pluginId)
  532. {
  533. return false;
  534. }
  535. @Override
  536. public boolean enablePlugin(String pluginId)
  537. {
  538. return false;
  539. }
  540. @Override
  541. public boolean uninstallPlugin(String pluginId)
  542. {
  543. return false;
  544. }
  545. @Override
  546. public boolean refreshRegistry(boolean verifyChecksum)
  547. {
  548. return false;
  549. }
  550. @Override
  551. public boolean installPlugin(String url, boolean verifyChecksum) throws IOException
  552. {
  553. return false;
  554. }
  555. @Override
  556. public boolean upgradePlugin(String pluginId, String url, boolean verifyChecksum) throws IOException
  557. {
  558. return false;
  559. }
  560. @Override
  561. public List<PluginRegistry.PluginRegistration> getRegisteredPlugins()
  562. {
  563. return null;
  564. }
  565. @Override
  566. public List<PluginRegistry.PluginRegistration> getRegisteredPlugins(PluginRegistry.InstallState state)
  567. {
  568. return null;
  569. }
  570. @Override
  571. public PluginRegistry.PluginRegistration lookupPlugin(String idOrName)
  572. {
  573. return null;
  574. }
  575. @Override
  576. public PluginRegistry.PluginRelease lookupRelease(String idOrName, String version)
  577. {
  578. return null;
  579. }
  580. @Override
  581. public IManager start()
  582. {
  583. return null;
  584. }
  585. @Override
  586. public IManager stop()
  587. {
  588. return null;
  589. }
  590. };
  591. }
  592. }