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.

site.rs 25KB

6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
5 years ago
6 years ago
5 years ago
5 years ago
6 years ago
7 years ago
6 years ago
6 years ago
7 years ago
6 years ago
7 years ago
6 years ago
5 years ago
7 years ago
6 years ago
6 years ago
6 years ago
7 years ago
5 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
6 years ago
6 years ago
7 years ago
7 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
5 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
5 years ago
6 years ago
6 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. extern crate config;
  2. extern crate site;
  3. mod common;
  4. use std::collections::HashMap;
  5. use std::env;
  6. use std::path::Path;
  7. use common::{build_site, build_site_with_setup};
  8. use config::Taxonomy;
  9. use site::Site;
  10. #[test]
  11. fn can_parse_site() {
  12. let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf();
  13. path.push("test_site");
  14. let mut site = Site::new(&path, "config.toml").unwrap();
  15. site.load().unwrap();
  16. let library = site.library.read().unwrap();
  17. // Correct number of pages (sections do not count as pages)
  18. assert_eq!(library.pages().len(), 22);
  19. let posts_path = path.join("content").join("posts");
  20. // Make sure the page with a url doesn't have any sections
  21. let url_post = library.get_page(&posts_path.join("fixed-url.md")).unwrap();
  22. assert_eq!(url_post.path, "a-fixed-url/");
  23. // Make sure the article in a folder with only asset doesn't get counted as a section
  24. let asset_folder_post =
  25. library.get_page(&posts_path.join("with-assets").join("index.md")).unwrap();
  26. assert_eq!(asset_folder_post.file.components, vec!["posts".to_string()]);
  27. // That we have the right number of sections
  28. assert_eq!(library.sections().len(), 11);
  29. // And that the sections are correct
  30. let index_section = library.get_section(&path.join("content").join("_index.md")).unwrap();
  31. assert_eq!(index_section.subsections.len(), 4);
  32. assert_eq!(index_section.pages.len(), 1);
  33. assert!(index_section.ancestors.is_empty());
  34. let posts_section = library.get_section(&posts_path.join("_index.md")).unwrap();
  35. assert_eq!(posts_section.subsections.len(), 2);
  36. assert_eq!(posts_section.pages.len(), 10);
  37. assert_eq!(
  38. posts_section.ancestors,
  39. vec![*library.get_section_key(&index_section.file.path).unwrap()]
  40. );
  41. // Make sure we remove all the pwd + content from the sections
  42. let basic = library.get_page(&posts_path.join("simple.md")).unwrap();
  43. assert_eq!(basic.file.components, vec!["posts".to_string()]);
  44. assert_eq!(
  45. basic.ancestors,
  46. vec![
  47. *library.get_section_key(&index_section.file.path).unwrap(),
  48. *library.get_section_key(&posts_section.file.path).unwrap(),
  49. ]
  50. );
  51. let tutorials_section =
  52. library.get_section(&posts_path.join("tutorials").join("_index.md")).unwrap();
  53. assert_eq!(tutorials_section.subsections.len(), 2);
  54. let sub1 = library.get_section_by_key(tutorials_section.subsections[0]);
  55. let sub2 = library.get_section_by_key(tutorials_section.subsections[1]);
  56. assert_eq!(sub1.clone().meta.title.unwrap(), "Programming");
  57. assert_eq!(sub2.clone().meta.title.unwrap(), "DevOps");
  58. assert_eq!(tutorials_section.pages.len(), 0);
  59. let devops_section = library
  60. .get_section(&posts_path.join("tutorials").join("devops").join("_index.md"))
  61. .unwrap();
  62. assert_eq!(devops_section.subsections.len(), 0);
  63. assert_eq!(devops_section.pages.len(), 2);
  64. assert_eq!(
  65. devops_section.ancestors,
  66. vec![
  67. *library.get_section_key(&index_section.file.path).unwrap(),
  68. *library.get_section_key(&posts_section.file.path).unwrap(),
  69. *library.get_section_key(&tutorials_section.file.path).unwrap(),
  70. ]
  71. );
  72. let prog_section = library
  73. .get_section(&posts_path.join("tutorials").join("programming").join("_index.md"))
  74. .unwrap();
  75. assert_eq!(prog_section.subsections.len(), 0);
  76. assert_eq!(prog_section.pages.len(), 2);
  77. }
  78. #[test]
  79. fn can_build_site_without_live_reload() {
  80. let (_, _tmp_dir, public) = build_site("test_site");
  81. assert!(&public.exists());
  82. assert!(file_exists!(public, "index.html"));
  83. assert!(file_exists!(public, "sitemap.xml"));
  84. assert!(file_exists!(public, "robots.txt"));
  85. assert!(file_exists!(public, "a-fixed-url/index.html"));
  86. assert!(file_exists!(public, "posts/python/index.html"));
  87. // Shortcodes work
  88. assert!(file_contains!(public, "posts/python/index.html", "Basic shortcode"));
  89. assert!(file_contains!(public, "posts/python/index.html", "Arrrh Bob"));
  90. assert!(file_contains!(public, "posts/python/index.html", "Arrrh Bob_Sponge"));
  91. assert!(file_exists!(public, "posts/tutorials/devops/nix/index.html"));
  92. assert!(file_exists!(public, "posts/with-assets/index.html"));
  93. assert!(file_exists!(public, "posts/no-section/simple/index.html"));
  94. // Sections
  95. assert!(file_exists!(public, "posts/index.html"));
  96. assert!(file_exists!(public, "posts/tutorials/index.html"));
  97. assert!(file_exists!(public, "posts/tutorials/devops/index.html"));
  98. assert!(file_exists!(public, "posts/tutorials/programming/index.html"));
  99. // Ensure subsection pages are correctly filled
  100. assert!(file_contains!(public, "posts/tutorials/index.html", "Sub-pages: 2"));
  101. // Pages and section get their relative path
  102. assert!(file_contains!(public, "posts/tutorials/index.html", "posts/tutorials/_index.md"));
  103. assert!(file_contains!(
  104. public,
  105. "posts/tutorials/devops/nix/index.html",
  106. "posts/tutorials/devops/nix.md"
  107. ));
  108. // aliases work
  109. assert!(file_exists!(public, "an-old-url/old-page/index.html"));
  110. assert!(file_contains!(public, "an-old-url/old-page/index.html", "something-else"));
  111. // html aliases work
  112. assert!(file_exists!(public, "an-old-url/an-old-alias.html"));
  113. assert!(file_contains!(public, "an-old-url/an-old-alias.html", "something-else"));
  114. // redirect_to works
  115. assert!(file_exists!(public, "posts/tutorials/devops/index.html"));
  116. assert!(file_contains!(public, "posts/tutorials/devops/index.html", "docker"));
  117. // We do have categories
  118. assert_eq!(file_exists!(public, "categories/index.html"), true);
  119. assert_eq!(file_exists!(public, "categories/a-category/index.html"), true);
  120. assert_eq!(file_exists!(public, "categories/a-category/rss.xml"), true);
  121. // But no tags
  122. assert_eq!(file_exists!(public, "tags/index.html"), false);
  123. // Theme files are there
  124. assert!(file_exists!(public, "sample.css"));
  125. assert!(file_exists!(public, "some.js"));
  126. // SASS and SCSS files compile correctly
  127. assert!(file_exists!(public, "blog.css"));
  128. assert!(file_contains!(public, "blog.css", "red"));
  129. assert!(file_contains!(public, "blog.css", "blue"));
  130. assert!(!file_contains!(public, "blog.css", "@import \"included\""));
  131. assert!(file_contains!(public, "blog.css", "2rem")); // check include
  132. assert!(!file_exists!(public, "_included.css"));
  133. assert!(file_exists!(public, "scss.css"));
  134. assert!(file_exists!(public, "sass.css"));
  135. assert!(file_exists!(public, "nested_sass/sass.css"));
  136. assert!(file_exists!(public, "nested_sass/scss.css"));
  137. // no live reload code
  138. assert_eq!(file_contains!(public, "index.html", "/livereload.js?port=1112&mindelay=10"), false);
  139. // Both pages and sections are in the sitemap
  140. assert!(file_contains!(
  141. public,
  142. "sitemap.xml",
  143. "<loc>https://replace-this-with-your-url.com/posts/simple/</loc>"
  144. ));
  145. assert!(file_contains!(
  146. public,
  147. "sitemap.xml",
  148. "<loc>https://replace-this-with-your-url.com/posts/</loc>"
  149. ));
  150. // Drafts are not in the sitemap
  151. assert!(!file_contains!(public, "sitemap.xml", "draft"));
  152. // render: false sections are not in the sitemap either
  153. assert!(!file_contains!(public, "sitemap.xml", "posts/2018/</loc>"));
  154. // robots.txt has been rendered from the template
  155. assert!(file_contains!(public, "robots.txt", "User-agent: zola"));
  156. assert!(file_contains!(
  157. public,
  158. "robots.txt",
  159. "Sitemap: https://replace-this-with-your-url.com/sitemap.xml"
  160. ));
  161. }
  162. #[test]
  163. fn can_build_site_with_live_reload() {
  164. let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
  165. site.enable_live_reload(1000);
  166. (site, true)
  167. });
  168. assert!(&public.exists());
  169. assert!(file_exists!(public, "index.html"));
  170. assert!(file_exists!(public, "sitemap.xml"));
  171. assert!(file_exists!(public, "robots.txt"));
  172. assert!(file_exists!(public, "a-fixed-url/index.html"));
  173. assert!(file_exists!(public, "posts/python/index.html"));
  174. assert!(file_exists!(public, "posts/tutorials/devops/nix/index.html"));
  175. assert!(file_exists!(public, "posts/with-assets/index.html"));
  176. // Sections
  177. assert!(file_exists!(public, "posts/index.html"));
  178. assert!(file_exists!(public, "posts/tutorials/index.html"));
  179. assert!(file_exists!(public, "posts/tutorials/devops/index.html"));
  180. assert!(file_exists!(public, "posts/tutorials/programming/index.html"));
  181. // TODO: add assertion for syntax highlighting
  182. // We do have categories
  183. assert_eq!(file_exists!(public, "categories/index.html"), true);
  184. assert_eq!(file_exists!(public, "categories/a-category/index.html"), true);
  185. assert_eq!(file_exists!(public, "categories/a-category/rss.xml"), true);
  186. // But no tags
  187. assert_eq!(file_exists!(public, "tags/index.html"), false);
  188. // no live reload code
  189. assert!(file_contains!(public, "index.html", "/livereload.js"));
  190. // the summary anchor link has been created
  191. assert!(file_contains!(
  192. public,
  193. "posts/python/index.html",
  194. r#"<a name="continue-reading"></a>"#
  195. ));
  196. assert!(file_contains!(public, "posts/draft/index.html", r#"THEME_SHORTCODE"#));
  197. }
  198. #[test]
  199. fn can_build_site_with_taxonomies() {
  200. let (site, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
  201. site.load().unwrap();
  202. {
  203. let mut library = site.library.write().unwrap();
  204. for (i, (_, page)) in library.pages_mut().iter_mut().enumerate() {
  205. page.meta.taxonomies = {
  206. let mut taxonomies = HashMap::new();
  207. taxonomies.insert(
  208. "categories".to_string(),
  209. vec![if i % 2 == 0 { "A" } else { "B" }.to_string()],
  210. );
  211. taxonomies
  212. };
  213. }
  214. }
  215. site.populate_taxonomies().unwrap();
  216. (site, false)
  217. });
  218. assert!(&public.exists());
  219. assert_eq!(site.taxonomies.len(), 1);
  220. assert!(file_exists!(public, "index.html"));
  221. assert!(file_exists!(public, "sitemap.xml"));
  222. assert!(file_exists!(public, "robots.txt"));
  223. assert!(file_exists!(public, "a-fixed-url/index.html"));
  224. assert!(file_exists!(public, "posts/python/index.html"));
  225. assert!(file_exists!(public, "posts/tutorials/devops/nix/index.html"));
  226. assert!(file_exists!(public, "posts/with-assets/index.html"));
  227. // Sections
  228. assert!(file_exists!(public, "posts/index.html"));
  229. assert!(file_exists!(public, "posts/tutorials/index.html"));
  230. assert!(file_exists!(public, "posts/tutorials/devops/index.html"));
  231. assert!(file_exists!(public, "posts/tutorials/programming/index.html"));
  232. // Categories are there
  233. assert!(file_exists!(public, "categories/index.html"));
  234. assert!(file_exists!(public, "categories/a/index.html"));
  235. assert!(file_exists!(public, "categories/b/index.html"));
  236. assert!(file_exists!(public, "categories/a/rss.xml"));
  237. assert!(file_contains!(
  238. public,
  239. "categories/a/rss.xml",
  240. "https://replace-this-with-your-url.com/categories/a/rss.xml"
  241. ));
  242. // Extending from a theme works
  243. assert!(file_contains!(public, "categories/a/index.html", "EXTENDED"));
  244. // Tags aren't
  245. assert_eq!(file_exists!(public, "tags/index.html"), false);
  246. // Categories are in the sitemap
  247. assert!(file_contains!(
  248. public,
  249. "sitemap.xml",
  250. "<loc>https://replace-this-with-your-url.com/categories/</loc>"
  251. ));
  252. assert!(file_contains!(
  253. public,
  254. "sitemap.xml",
  255. "<loc>https://replace-this-with-your-url.com/categories/a/</loc>"
  256. ));
  257. }
  258. #[test]
  259. fn can_build_site_and_insert_anchor_links() {
  260. let (_, _tmp_dir, public) = build_site("test_site");
  261. assert!(Path::new(&public).exists());
  262. // anchor link inserted
  263. assert!(file_contains!(
  264. public,
  265. "posts/something-else/index.html",
  266. "<h1 id=\"title\"><a class=\"zola-anchor\" href=\"#title\""
  267. ));
  268. }
  269. #[test]
  270. fn can_build_site_with_pagination_for_section() {
  271. let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
  272. site.load().unwrap();
  273. {
  274. let mut library = site.library.write().unwrap();
  275. for (_, section) in library.sections_mut() {
  276. if section.is_index() {
  277. continue;
  278. }
  279. section.meta.paginate_by = Some(2);
  280. section.meta.template = Some("section_paginated.html".to_string());
  281. }
  282. }
  283. (site, false)
  284. });
  285. assert!(&public.exists());
  286. assert!(file_exists!(public, "index.html"));
  287. assert!(file_exists!(public, "sitemap.xml"));
  288. assert!(file_exists!(public, "robots.txt"));
  289. assert!(file_exists!(public, "a-fixed-url/index.html"));
  290. assert!(file_exists!(public, "posts/python/index.html"));
  291. assert!(file_exists!(public, "posts/tutorials/devops/nix/index.html"));
  292. assert!(file_exists!(public, "posts/with-assets/index.html"));
  293. // Sections
  294. assert!(file_exists!(public, "posts/index.html"));
  295. // And pagination!
  296. assert!(file_exists!(public, "posts/page/1/index.html"));
  297. // even if there is no pages, only the section!
  298. assert!(file_exists!(public, "paginated/page/1/index.html"));
  299. assert!(file_exists!(public, "paginated/index.html"));
  300. // should redirect to posts/
  301. assert!(file_contains!(
  302. public,
  303. "posts/page/1/index.html",
  304. "http-equiv=\"refresh\" content=\"0;url=https://replace-this-with-your-url.com/posts/\""
  305. ));
  306. assert!(file_contains!(public, "posts/index.html", "Num pagers: 5"));
  307. assert!(file_contains!(public, "posts/index.html", "Page size: 2"));
  308. assert!(file_contains!(public, "posts/index.html", "Current index: 1"));
  309. assert!(!file_contains!(public, "posts/index.html", "has_prev"));
  310. assert!(file_contains!(public, "posts/index.html", "has_next"));
  311. assert!(file_contains!(
  312. public,
  313. "posts/index.html",
  314. "First: https://replace-this-with-your-url.com/posts/"
  315. ));
  316. assert!(file_contains!(
  317. public,
  318. "posts/index.html",
  319. "Last: https://replace-this-with-your-url.com/posts/page/5/"
  320. ));
  321. assert_eq!(file_contains!(public, "posts/index.html", "has_prev"), false);
  322. assert!(file_exists!(public, "posts/page/2/index.html"));
  323. assert!(file_contains!(public, "posts/page/2/index.html", "Num pagers: 5"));
  324. assert!(file_contains!(public, "posts/page/2/index.html", "Page size: 2"));
  325. assert!(file_contains!(public, "posts/page/2/index.html", "Current index: 2"));
  326. assert!(file_contains!(public, "posts/page/2/index.html", "has_prev"));
  327. assert!(file_contains!(public, "posts/page/2/index.html", "has_next"));
  328. assert!(file_contains!(
  329. public,
  330. "posts/page/2/index.html",
  331. "First: https://replace-this-with-your-url.com/posts/"
  332. ));
  333. assert!(file_contains!(
  334. public,
  335. "posts/page/2/index.html",
  336. "Last: https://replace-this-with-your-url.com/posts/page/5/"
  337. ));
  338. assert!(file_exists!(public, "posts/page/3/index.html"));
  339. assert!(file_contains!(public, "posts/page/3/index.html", "Num pagers: 5"));
  340. assert!(file_contains!(public, "posts/page/3/index.html", "Page size: 2"));
  341. assert!(file_contains!(public, "posts/page/3/index.html", "Current index: 3"));
  342. assert!(file_contains!(public, "posts/page/3/index.html", "has_prev"));
  343. assert!(file_contains!(public, "posts/page/3/index.html", "has_next"));
  344. assert!(file_contains!(
  345. public,
  346. "posts/page/3/index.html",
  347. "First: https://replace-this-with-your-url.com/posts/"
  348. ));
  349. assert!(file_contains!(
  350. public,
  351. "posts/page/3/index.html",
  352. "Last: https://replace-this-with-your-url.com/posts/page/5/"
  353. ));
  354. assert!(file_exists!(public, "posts/page/4/index.html"));
  355. assert!(file_contains!(public, "posts/page/4/index.html", "Num pagers: 5"));
  356. assert!(file_contains!(public, "posts/page/4/index.html", "Page size: 2"));
  357. assert!(file_contains!(public, "posts/page/4/index.html", "Current index: 4"));
  358. assert!(file_contains!(public, "posts/page/4/index.html", "has_prev"));
  359. assert!(file_contains!(public, "posts/page/4/index.html", "has_next"));
  360. assert!(file_contains!(
  361. public,
  362. "posts/page/4/index.html",
  363. "First: https://replace-this-with-your-url.com/posts/"
  364. ));
  365. assert!(file_contains!(
  366. public,
  367. "posts/page/4/index.html",
  368. "Last: https://replace-this-with-your-url.com/posts/page/5/"
  369. ));
  370. // sitemap contains the pager pages
  371. assert!(file_contains!(
  372. public,
  373. "sitemap.xml",
  374. "<loc>https://replace-this-with-your-url.com/posts/page/4/</loc>"
  375. ));
  376. }
  377. #[test]
  378. fn can_build_site_with_pagination_for_index() {
  379. let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
  380. site.load().unwrap();
  381. {
  382. let mut library = site.library.write().unwrap();
  383. {
  384. let index = library
  385. .get_section_mut(&site.base_path.join("content").join("_index.md"))
  386. .unwrap();
  387. index.meta.paginate_by = Some(2);
  388. index.meta.template = Some("index_paginated.html".to_string());
  389. }
  390. }
  391. (site, false)
  392. });
  393. assert!(&public.exists());
  394. assert!(file_exists!(public, "index.html"));
  395. assert!(file_exists!(public, "sitemap.xml"));
  396. assert!(file_exists!(public, "robots.txt"));
  397. assert!(file_exists!(public, "a-fixed-url/index.html"));
  398. assert!(file_exists!(public, "posts/python/index.html"));
  399. assert!(file_exists!(public, "posts/tutorials/devops/nix/index.html"));
  400. assert!(file_exists!(public, "posts/with-assets/index.html"));
  401. // And pagination!
  402. assert!(file_exists!(public, "page/1/index.html"));
  403. // even if there is no pages, only the section!
  404. assert!(file_exists!(public, "paginated/page/1/index.html"));
  405. assert!(file_exists!(public, "paginated/index.html"));
  406. // should redirect to index
  407. assert!(file_contains!(
  408. public,
  409. "page/1/index.html",
  410. "http-equiv=\"refresh\" content=\"0;url=https://replace-this-with-your-url.com/\""
  411. ));
  412. assert!(file_contains!(public, "index.html", "Num pages: 1"));
  413. assert!(file_contains!(public, "index.html", "Current index: 1"));
  414. assert!(file_contains!(public, "index.html", "First: https://replace-this-with-your-url.com/"));
  415. assert!(file_contains!(public, "index.html", "Last: https://replace-this-with-your-url.com/"));
  416. assert_eq!(file_contains!(public, "index.html", "has_prev"), false);
  417. assert_eq!(file_contains!(public, "index.html", "has_next"), false);
  418. // sitemap contains the pager pages
  419. assert!(file_contains!(
  420. public,
  421. "sitemap.xml",
  422. "<loc>https://replace-this-with-your-url.com/page/1/</loc>"
  423. ))
  424. }
  425. #[test]
  426. fn can_build_site_with_pagination_for_taxonomy() {
  427. let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
  428. site.config.taxonomies.push(Taxonomy {
  429. name: "tags".to_string(),
  430. paginate_by: Some(2),
  431. paginate_path: None,
  432. rss: true,
  433. lang: site.config.default_language.clone(),
  434. });
  435. site.load().unwrap();
  436. {
  437. let mut library = site.library.write().unwrap();
  438. for (i, (_, page)) in library.pages_mut().iter_mut().enumerate() {
  439. page.meta.taxonomies = {
  440. let mut taxonomies = HashMap::new();
  441. taxonomies.insert(
  442. "tags".to_string(),
  443. vec![if i % 2 == 0 { "A" } else { "B" }.to_string()],
  444. );
  445. taxonomies
  446. };
  447. }
  448. }
  449. site.populate_taxonomies().unwrap();
  450. (site, false)
  451. });
  452. assert!(&public.exists());
  453. assert!(file_exists!(public, "index.html"));
  454. assert!(file_exists!(public, "sitemap.xml"));
  455. assert!(file_exists!(public, "robots.txt"));
  456. assert!(file_exists!(public, "a-fixed-url/index.html"));
  457. assert!(file_exists!(public, "posts/python/index.html"));
  458. assert!(file_exists!(public, "posts/tutorials/devops/nix/index.html"));
  459. assert!(file_exists!(public, "posts/with-assets/index.html"));
  460. // Tags
  461. assert!(file_exists!(public, "tags/index.html"));
  462. // With RSS
  463. assert!(file_exists!(public, "tags/a/rss.xml"));
  464. assert!(file_exists!(public, "tags/b/rss.xml"));
  465. // And pagination!
  466. assert!(file_exists!(public, "tags/a/page/1/index.html"));
  467. assert!(file_exists!(public, "tags/b/page/1/index.html"));
  468. assert!(file_exists!(public, "tags/a/page/2/index.html"));
  469. assert!(file_exists!(public, "tags/b/page/2/index.html"));
  470. // should redirect to posts/
  471. assert!(file_contains!(
  472. public,
  473. "tags/a/page/1/index.html",
  474. "http-equiv=\"refresh\" content=\"0;url=https://replace-this-with-your-url.com/tags/a/\""
  475. ));
  476. assert!(file_contains!(public, "tags/a/index.html", "Num pagers: 6"));
  477. assert!(file_contains!(public, "tags/a/index.html", "Page size: 2"));
  478. assert!(file_contains!(public, "tags/a/index.html", "Current index: 1"));
  479. assert!(!file_contains!(public, "tags/a/index.html", "has_prev"));
  480. assert!(file_contains!(public, "tags/a/index.html", "has_next"));
  481. assert!(file_contains!(
  482. public,
  483. "tags/a/index.html",
  484. "First: https://replace-this-with-your-url.com/tags/a/"
  485. ));
  486. assert!(file_contains!(
  487. public,
  488. "tags/a/index.html",
  489. "Last: https://replace-this-with-your-url.com/tags/a/page/6/"
  490. ));
  491. assert_eq!(file_contains!(public, "tags/a/index.html", "has_prev"), false);
  492. // sitemap contains the pager pages
  493. assert!(file_contains!(
  494. public,
  495. "sitemap.xml",
  496. "<loc>https://replace-this-with-your-url.com/tags/a/page/6/</loc>"
  497. ))
  498. }
  499. #[test]
  500. fn can_build_rss_feed() {
  501. let (_, _tmp_dir, public) = build_site("test_site");
  502. assert!(&public.exists());
  503. assert!(file_exists!(public, "rss.xml"));
  504. // latest article is posts/extra-syntax.md
  505. assert!(file_contains!(public, "rss.xml", "Extra Syntax"));
  506. // Next is posts/simple.md
  507. assert!(file_contains!(public, "rss.xml", "Simple article with shortcodes"));
  508. }
  509. #[test]
  510. fn can_build_search_index() {
  511. let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
  512. site.config.build_search_index = true;
  513. (site, true)
  514. });
  515. assert!(Path::new(&public).exists());
  516. assert!(file_exists!(public, "elasticlunr.min.js"));
  517. assert!(file_exists!(public, "search_index.en.js"));
  518. }
  519. #[test]
  520. fn can_build_with_extra_syntaxes() {
  521. let (_, _tmp_dir, public) = build_site("test_site");
  522. assert!(&public.exists());
  523. assert!(file_exists!(public, "posts/extra-syntax/index.html"));
  524. assert!(file_contains!(
  525. public,
  526. "posts/extra-syntax/index.html",
  527. r#"<span style="color:#d08770;">test</span>"#
  528. ));
  529. }
  530. #[test]
  531. fn can_apply_page_templates() {
  532. let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf();
  533. path.push("test_site");
  534. let mut site = Site::new(&path, "config.toml").unwrap();
  535. site.load().unwrap();
  536. let template_path = path.join("content").join("applying_page_template");
  537. let library = site.library.read().unwrap();
  538. let template_section = library.get_section(&template_path.join("_index.md")).unwrap();
  539. assert_eq!(template_section.subsections.len(), 2);
  540. assert_eq!(template_section.pages.len(), 2);
  541. let from_section_config = library.get_page_by_key(template_section.pages[0]);
  542. assert_eq!(from_section_config.meta.template, Some("page_template.html".into()));
  543. assert_eq!(from_section_config.meta.title, Some("From section config".into()));
  544. let override_page_template = library.get_page_by_key(template_section.pages[1]);
  545. assert_eq!(override_page_template.meta.template, Some("page_template_override.html".into()));
  546. assert_eq!(override_page_template.meta.title, Some("Override".into()));
  547. // It should have applied recursively as well
  548. let another_section =
  549. library.get_section(&template_path.join("another_section").join("_index.md")).unwrap();
  550. assert_eq!(another_section.subsections.len(), 0);
  551. assert_eq!(another_section.pages.len(), 1);
  552. let changed_recursively = library.get_page_by_key(another_section.pages[0]);
  553. assert_eq!(changed_recursively.meta.template, Some("page_template.html".into()));
  554. assert_eq!(changed_recursively.meta.title, Some("Changed recursively".into()));
  555. // But it should not have override a children page_template
  556. let yet_another_section =
  557. library.get_section(&template_path.join("yet_another_section").join("_index.md")).unwrap();
  558. assert_eq!(yet_another_section.subsections.len(), 0);
  559. assert_eq!(yet_another_section.pages.len(), 1);
  560. let child = library.get_page_by_key(yet_another_section.pages[0]);
  561. assert_eq!(child.meta.template, Some("page_template_child.html".into()));
  562. assert_eq!(child.meta.title, Some("Local section override".into()));
  563. }
  564. // https://github.com/getzola/zola/issues/571
  565. #[test]
  566. fn can_build_site_custom_builtins_from_theme() {
  567. let (_, _tmp_dir, public) = build_site("test_site");
  568. assert!(&public.exists());
  569. // 404.html is a theme template.
  570. assert!(file_exists!(public, "404.html"));
  571. assert!(file_contains!(public, "404.html", "Oops"));
  572. }