sitemaps-renderer.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. <?php
  2. /**
  3. * @group sitemaps
  4. */
  5. class Test_WP_Sitemaps_Renderer extends WP_Test_XML_TestCase {
  6. public function test_get_sitemap_stylesheet_url() {
  7. $sitemap_renderer = new WP_Sitemaps_Renderer();
  8. $stylesheet_url = $sitemap_renderer->get_sitemap_stylesheet_url();
  9. $this->assertStringEndsWith( '/?sitemap-stylesheet=sitemap', $stylesheet_url );
  10. }
  11. public function test_get_sitemap_stylesheet_url_pretty_permalinks() {
  12. // Set permalinks for testing.
  13. $this->set_permalink_structure( '/%year%/%postname%/' );
  14. $sitemap_renderer = new WP_Sitemaps_Renderer();
  15. $stylesheet_url = $sitemap_renderer->get_sitemap_stylesheet_url();
  16. // Clean up permalinks.
  17. $this->set_permalink_structure();
  18. $this->assertStringEndsWith( '/wp-sitemap.xsl', $stylesheet_url );
  19. }
  20. public function test_get_sitemap_index_stylesheet_url() {
  21. $sitemap_renderer = new WP_Sitemaps_Renderer();
  22. $stylesheet_url = $sitemap_renderer->get_sitemap_index_stylesheet_url();
  23. $this->assertStringEndsWith( '/?sitemap-stylesheet=index', $stylesheet_url );
  24. }
  25. public function test_get_sitemap_index_stylesheet_url_pretty_permalinks() {
  26. // Set permalinks for testing.
  27. $this->set_permalink_structure( '/%year%/%postname%/' );
  28. $sitemap_renderer = new WP_Sitemaps_Renderer();
  29. $stylesheet_url = $sitemap_renderer->get_sitemap_index_stylesheet_url();
  30. // Clean up permalinks.
  31. $this->set_permalink_structure();
  32. $this->assertStringEndsWith( '/wp-sitemap-index.xsl', $stylesheet_url );
  33. }
  34. /**
  35. * Test XML output for the sitemap index renderer.
  36. */
  37. public function test_get_sitemap_index_xml() {
  38. $entries = array(
  39. array(
  40. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-posts-post-1.xml',
  41. ),
  42. array(
  43. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-posts-page-1.xml',
  44. ),
  45. array(
  46. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-taxonomies-category-1.xml',
  47. ),
  48. array(
  49. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-taxonomies-post_tag-1.xml',
  50. ),
  51. array(
  52. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-users-1.xml',
  53. ),
  54. );
  55. $renderer = new WP_Sitemaps_Renderer();
  56. $actual = $renderer->get_sitemap_index_xml( $entries );
  57. $expected = '<?xml version="1.0" encoding="UTF-8"?>' .
  58. '<?xml-stylesheet type="text/xsl" href="http://' . WP_TESTS_DOMAIN . '/?sitemap-stylesheet=index" ?>' .
  59. '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' .
  60. '<sitemap><loc>http://' . WP_TESTS_DOMAIN . '/wp-sitemap-posts-post-1.xml</loc></sitemap>' .
  61. '<sitemap><loc>http://' . WP_TESTS_DOMAIN . '/wp-sitemap-posts-page-1.xml</loc></sitemap>' .
  62. '<sitemap><loc>http://' . WP_TESTS_DOMAIN . '/wp-sitemap-taxonomies-category-1.xml</loc></sitemap>' .
  63. '<sitemap><loc>http://' . WP_TESTS_DOMAIN . '/wp-sitemap-taxonomies-post_tag-1.xml</loc></sitemap>' .
  64. '<sitemap><loc>http://' . WP_TESTS_DOMAIN . '/wp-sitemap-users-1.xml</loc></sitemap>' .
  65. '</sitemapindex>';
  66. $this->assertXMLEquals( $expected, $actual, 'Sitemap index markup incorrect.' );
  67. }
  68. /**
  69. * Test XML output for the sitemap index renderer with lastmod attributes.
  70. */
  71. public function test_get_sitemap_index_xml_with_lastmod() {
  72. $entries = array(
  73. array(
  74. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-posts-post-1.xml',
  75. 'lastmod' => '2005-01-01',
  76. ),
  77. array(
  78. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-posts-page-1.xml',
  79. 'lastmod' => '2005-01-01',
  80. ),
  81. array(
  82. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-taxonomies-category-1.xml',
  83. 'lastmod' => '2005-01-01',
  84. ),
  85. array(
  86. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-taxonomies-post_tag-1.xml',
  87. 'lastmod' => '2005-01-01',
  88. ),
  89. array(
  90. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-users-1.xml',
  91. 'lastmod' => '2005-01-01',
  92. ),
  93. );
  94. $renderer = new WP_Sitemaps_Renderer();
  95. $actual = $renderer->get_sitemap_index_xml( $entries );
  96. $expected = '<?xml version="1.0" encoding="UTF-8"?>' .
  97. '<?xml-stylesheet type="text/xsl" href="http://' . WP_TESTS_DOMAIN . '/?sitemap-stylesheet=index" ?>' .
  98. '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' .
  99. '<sitemap><loc>http://' . WP_TESTS_DOMAIN . '/wp-sitemap-posts-post-1.xml</loc><lastmod>2005-01-01</lastmod></sitemap>' .
  100. '<sitemap><loc>http://' . WP_TESTS_DOMAIN . '/wp-sitemap-posts-page-1.xml</loc><lastmod>2005-01-01</lastmod></sitemap>' .
  101. '<sitemap><loc>http://' . WP_TESTS_DOMAIN . '/wp-sitemap-taxonomies-category-1.xml</loc><lastmod>2005-01-01</lastmod></sitemap>' .
  102. '<sitemap><loc>http://' . WP_TESTS_DOMAIN . '/wp-sitemap-taxonomies-post_tag-1.xml</loc><lastmod>2005-01-01</lastmod></sitemap>' .
  103. '<sitemap><loc>http://' . WP_TESTS_DOMAIN . '/wp-sitemap-users-1.xml</loc><lastmod>2005-01-01</lastmod></sitemap>' .
  104. '</sitemapindex>';
  105. $this->assertXMLEquals( $expected, $actual, 'Sitemap index markup incorrect.' );
  106. }
  107. /**
  108. * Test that all children of Q{http://www.sitemaps.org/schemas/sitemap/0.9}sitemap in the
  109. * rendered index XML are defined in the Sitemaps spec (i.e., loc, lastmod).
  110. *
  111. * Note that when a means of adding elements in extension namespaces is settled on,
  112. * this test will need to be updated accordingly.
  113. *
  114. * @expectedIncorrectUsage WP_Sitemaps_Renderer::get_sitemap_index_xml
  115. */
  116. public function test_get_sitemap_index_xml_extra_elements() {
  117. $url_list = array(
  118. array(
  119. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-posts-post-1.xml',
  120. 'unknown' => 'this is a test',
  121. ),
  122. array(
  123. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-posts-page-1.xml',
  124. 'unknown' => 'that was a test',
  125. ),
  126. );
  127. $renderer = new WP_Sitemaps_Renderer();
  128. $xml_dom = $this->loadXML( $renderer->get_sitemap_index_xml( $url_list ) );
  129. $xpath = new DOMXPath( $xml_dom );
  130. $xpath->registerNamespace( 'sitemap', 'http://www.sitemaps.org/schemas/sitemap/0.9' );
  131. $this->assertEquals(
  132. 0,
  133. $xpath->evaluate( "count( /sitemap:sitemapindex/sitemap:sitemap/*[ namespace-uri() != 'http://www.sitemaps.org/schemas/sitemap/0.9' or not( local-name() = 'loc' or local-name() = 'lastmod' ) ] )" ),
  134. 'Invalid child of "sitemap:sitemap" in rendered index XML.'
  135. );
  136. }
  137. /**
  138. * Test XML output for the sitemap index renderer when stylesheet is disabled.
  139. */
  140. public function test_get_sitemap_index_xml_without_stylesheet() {
  141. $entries = array(
  142. array(
  143. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/wp-sitemap-posts-post-1.xml',
  144. ),
  145. );
  146. add_filter( 'wp_sitemaps_stylesheet_index_url', '__return_false' );
  147. $renderer = new WP_Sitemaps_Renderer();
  148. $xml_dom = $this->loadXML( $renderer->get_sitemap_index_xml( $entries ) );
  149. $xpath = new DOMXPath( $xml_dom );
  150. $this->assertSame(
  151. 0,
  152. $xpath->query( '//processing-instruction( "xml-stylesheet" )' )->length,
  153. 'Sitemap index incorrectly contains the xml-stylesheet processing instruction.'
  154. );
  155. }
  156. /**
  157. * Test XML output for the sitemap page renderer.
  158. */
  159. public function test_get_sitemap_xml() {
  160. $url_list = array(
  161. array(
  162. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/2019/10/post-1',
  163. ),
  164. array(
  165. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/2019/10/post-2',
  166. ),
  167. array(
  168. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/2019/10/post-3',
  169. ),
  170. array(
  171. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/2019/10/post-4',
  172. ),
  173. array(
  174. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/2019/10/post-5',
  175. ),
  176. );
  177. $renderer = new WP_Sitemaps_Renderer();
  178. $actual = $renderer->get_sitemap_xml( $url_list );
  179. $expected = '<?xml version="1.0" encoding="UTF-8"?>' .
  180. '<?xml-stylesheet type="text/xsl" href="http://' . WP_TESTS_DOMAIN . '/?sitemap-stylesheet=sitemap" ?>' .
  181. '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' .
  182. '<url><loc>http://' . WP_TESTS_DOMAIN . '/2019/10/post-1</loc></url>' .
  183. '<url><loc>http://' . WP_TESTS_DOMAIN . '/2019/10/post-2</loc></url>' .
  184. '<url><loc>http://' . WP_TESTS_DOMAIN . '/2019/10/post-3</loc></url>' .
  185. '<url><loc>http://' . WP_TESTS_DOMAIN . '/2019/10/post-4</loc></url>' .
  186. '<url><loc>http://' . WP_TESTS_DOMAIN . '/2019/10/post-5</loc></url>' .
  187. '</urlset>';
  188. $this->assertXMLEquals( $expected, $actual, 'Sitemap page markup incorrect.' );
  189. }
  190. /**
  191. * Test XML output for the sitemap page renderer when stylesheet is disabled.
  192. */
  193. public function test_get_sitemap_xml_without_stylesheet() {
  194. $url_list = array(
  195. array(
  196. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/2019/10/post-1',
  197. ),
  198. );
  199. add_filter( 'wp_sitemaps_stylesheet_url', '__return_false' );
  200. $renderer = new WP_Sitemaps_Renderer();
  201. $xml_dom = $this->loadXML( $renderer->get_sitemap_xml( $url_list ) );
  202. $xpath = new DOMXPath( $xml_dom );
  203. $this->assertSame(
  204. 0,
  205. $xpath->query( '//processing-instruction( "xml-stylesheet" )' )->length,
  206. 'Sitemap incorrectly contains the xml-stylesheet processing instruction.'
  207. );
  208. }
  209. /**
  210. * Test that all children of Q{http://www.sitemaps.org/schemas/sitemap/0.9}url in the
  211. * rendered sitemap XML are defined in the Sitemaps spec (i.e., loc, lastmod, changefreq, priority).
  212. *
  213. * Note that when a means of adding elements in extension namespaces is settled on,
  214. * this test will need to be updated accordingly.
  215. *
  216. * @expectedIncorrectUsage WP_Sitemaps_Renderer::get_sitemap_xml
  217. */
  218. public function test_get_sitemap_xml_extra_elements() {
  219. $url_list = array(
  220. array(
  221. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/2019/10/post-1',
  222. 'string' => 'value',
  223. 'number' => 200,
  224. ),
  225. array(
  226. 'loc' => 'http://' . WP_TESTS_DOMAIN . '/2019/10/post-2',
  227. 'string' => 'another value',
  228. 'number' => 300,
  229. ),
  230. );
  231. $renderer = new WP_Sitemaps_Renderer();
  232. $xml_dom = $this->loadXML( $renderer->get_sitemap_xml( $url_list ) );
  233. $xpath = new DOMXPath( $xml_dom );
  234. $xpath->registerNamespace( 'sitemap', 'http://www.sitemaps.org/schemas/sitemap/0.9' );
  235. $this->assertEquals(
  236. 0,
  237. $xpath->evaluate( "count( /sitemap:urlset/sitemap:url/*[ namespace-uri() != 'http://www.sitemaps.org/schemas/sitemap/0.9' or not( local-name() = 'loc' or local-name() = 'lastmod' or local-name() = 'changefreq' or local-name() = 'priority' ) ] )" ),
  238. 'Invalid child of "sitemap:url" in rendered XML.'
  239. );
  240. }
  241. }