ReaderTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Feed
  17. * @subpackage UnitTests
  18. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. require_once 'Zend/Feed/Reader.php';
  23. require_once 'Zend/Cache.php';
  24. /**
  25. * @category Zend
  26. * @package Zend_Feed
  27. * @subpackage UnitTests
  28. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  29. * @license http://framework.zend.com/license/new-bsd New BSD License
  30. * @group Zend_Feed
  31. * @group Zend_Feed_Reader
  32. */
  33. class Zend_Feed_ReaderTest extends PHPUnit_Framework_TestCase
  34. {
  35. protected $_feedSamplePath = null;
  36. public function setup()
  37. {
  38. $this->_feedSamplePath = dirname(__FILE__) . '/Reader/_files';
  39. }
  40. public function tearDown()
  41. {
  42. Zend_Feed_Reader::reset();
  43. }
  44. public function testDetectsFeedIsRss20()
  45. {
  46. $feed = Zend_Feed_Reader::importString(
  47. file_get_contents($this->_feedSamplePath.'/Reader/rss20.xml'));
  48. $type = Zend_Feed_Reader::detectType($feed);
  49. $this->assertEquals(Zend_Feed_Reader::TYPE_RSS_20, $type);
  50. }
  51. public function testDetectsFeedIsRss094()
  52. {
  53. $feed = Zend_Feed_Reader::importString(
  54. file_get_contents($this->_feedSamplePath.'/Reader/rss094.xml'));
  55. $type = Zend_Feed_Reader::detectType($feed);
  56. $this->assertEquals(Zend_Feed_Reader::TYPE_RSS_094, $type);
  57. }
  58. public function testDetectsFeedIsRss093()
  59. {
  60. $feed = Zend_Feed_Reader::importString(
  61. file_get_contents($this->_feedSamplePath.'/Reader/rss093.xml'));
  62. $type = Zend_Feed_Reader::detectType($feed);
  63. $this->assertEquals(Zend_Feed_Reader::TYPE_RSS_093, $type);
  64. }
  65. public function testDetectsFeedIsRss092()
  66. {
  67. $feed = Zend_Feed_Reader::importString(
  68. file_get_contents($this->_feedSamplePath.'/Reader/rss092.xml'));
  69. $type = Zend_Feed_Reader::detectType($feed);
  70. $this->assertEquals(Zend_Feed_Reader::TYPE_RSS_092, $type);
  71. }
  72. public function testDetectsFeedIsRss091()
  73. {
  74. $feed = Zend_Feed_Reader::importString(
  75. file_get_contents($this->_feedSamplePath.'/Reader/rss091.xml'));
  76. $type = Zend_Feed_Reader::detectType($feed);
  77. $this->assertEquals(Zend_Feed_Reader::TYPE_RSS_091, $type);
  78. }
  79. public function testDetectsFeedIsRss10()
  80. {
  81. $feed = Zend_Feed_Reader::importString(
  82. file_get_contents($this->_feedSamplePath.'/Reader/rss10.xml'));
  83. $type = Zend_Feed_Reader::detectType($feed);
  84. $this->assertEquals(Zend_Feed_Reader::TYPE_RSS_10, $type);
  85. }
  86. public function testDetectsFeedIsRss090()
  87. {
  88. $feed = Zend_Feed_Reader::importString(
  89. file_get_contents($this->_feedSamplePath.'/Reader/rss090.xml'));
  90. $type = Zend_Feed_Reader::detectType($feed);
  91. $this->assertEquals(Zend_Feed_Reader::TYPE_RSS_090, $type);
  92. }
  93. public function testDetectsFeedIsAtom10()
  94. {
  95. $feed = Zend_Feed_Reader::importString(
  96. file_get_contents($this->_feedSamplePath.'/Reader/atom10.xml'));
  97. $type = Zend_Feed_Reader::detectType($feed);
  98. $this->assertEquals(Zend_Feed_Reader::TYPE_ATOM_10, $type);
  99. }
  100. public function testDetectsFeedIsAtom03()
  101. {
  102. $feed = Zend_Feed_Reader::importString(
  103. file_get_contents($this->_feedSamplePath.'/Reader/atom03.xml'));
  104. $type = Zend_Feed_Reader::detectType($feed);
  105. $this->assertEquals(Zend_Feed_Reader::TYPE_ATOM_03, $type);
  106. }
  107. /**
  108. * @group ZF-9723
  109. */
  110. public function testDetectsTypeFromStringOrToRemindPaddyAboutForgettingATestWhichLetsAStupidTypoSurviveUnnoticedForMonths()
  111. {
  112. $feed = '<?xml version="1.0" encoding="utf-8" ?><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/"><channel></channel></rdf:RDF>';
  113. $type = Zend_Feed_Reader::detectType($feed);
  114. $this->assertEquals(Zend_Feed_Reader::TYPE_RSS_10, $type);
  115. }
  116. public function testGetEncoding()
  117. {
  118. $feed = Zend_Feed_Reader::importString(
  119. file_get_contents(dirname(__FILE__) . '/Reader/Entry/_files/Atom/title/plain/atom10.xml')
  120. );
  121. $this->assertEquals('utf-8', $feed->getEncoding());
  122. $this->assertEquals('utf-8', $feed->current()->getEncoding());
  123. }
  124. public function testImportsFile()
  125. {
  126. try {
  127. $feed = Zend_Feed_Reader::importFile(
  128. dirname(__FILE__) . '/Reader/Entry/_files/Atom/title/plain/atom10.xml'
  129. );
  130. } catch(Exception $e) {
  131. $this->fail($e->getMessage());
  132. }
  133. }
  134. public function testImportsUri()
  135. {
  136. if (!defined('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  137. || !constant('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  138. ) {
  139. $this->markTestSkipped('testImportsUri() requires a network connection');
  140. return;
  141. }
  142. try {
  143. $feed = Zend_Feed_Reader::import('http://www.planet-php.net/rdf/');
  144. } catch(Exception $e) {
  145. $this->fail($e->getMessage());
  146. }
  147. }
  148. /**
  149. * @group ZF-8328
  150. * @expectedException Zend_Feed_Exception
  151. */
  152. public function testImportsUriAndThrowsExceptionIfNotAFeed()
  153. {
  154. if (!defined('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  155. || !constant('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  156. ) {
  157. $this->markTestSkipped('testImportsUri() requires a network connection');
  158. return;
  159. }
  160. $feed = Zend_Feed_Reader::import('http://twitter.com/alganet');
  161. }
  162. public function testGetsFeedLinksAsValueObject()
  163. {
  164. if (!defined('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  165. || !constant('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  166. ) {
  167. $this->markTestSkipped('testGetsFeedLinksAsValueObject() requires a network connection');
  168. return;
  169. }
  170. try {
  171. $links = Zend_Feed_Reader::findFeedLinks('http://www.planet-php.net');
  172. } catch(Exception $e) {
  173. $this->fail($e->getMessage());
  174. }
  175. $this->assertEquals('http://www.planet-php.org/rss/', $links->rss);
  176. }
  177. public function testCompilesLinksAsArrayObject()
  178. {
  179. if (!defined('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  180. || !constant('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  181. ) {
  182. $this->markTestSkipped('testGetsFeedLinksAsValueObject() requires a network connection');
  183. return;
  184. }
  185. $links = Zend_Feed_Reader::findFeedLinks('http://www.planet-php.net');
  186. $this->assertTrue($links instanceof Zend_Feed_Reader_FeedSet);
  187. $this->assertEquals(array(
  188. 'rel' => 'alternate', 'type' => 'application/rss+xml', 'href' => 'http://www.planet-php.org/rss/'
  189. ), (array) $links->getIterator()->current());
  190. }
  191. public function testFeedSetLoadsFeedObjectWhenFeedArrayKeyAccessed()
  192. {
  193. if (!defined('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  194. || !constant('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  195. ) {
  196. $this->markTestSkipped('testGetsFeedLinksAsValueObject() requires a network connection');
  197. return;
  198. }
  199. $links = Zend_Feed_Reader::findFeedLinks('http://www.planet-php.net');
  200. $link = $links->getIterator()->current();
  201. $this->assertTrue($link['feed'] instanceof Zend_Feed_Reader_Feed_Rss);
  202. }
  203. public function testZeroCountFeedSetReturnedFromEmptyList()
  204. {
  205. if (!defined('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  206. || !constant('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  207. ) {
  208. $this->markTestSkipped('testGetsFeedLinksAsValueObject() requires a network connection');
  209. return;
  210. }
  211. $links = Zend_Feed_Reader::findFeedLinks('http://www.example.com');
  212. $this->assertEquals(0, count($links));
  213. }
  214. /**
  215. * @group ZF-8327
  216. */
  217. public function testGetsFeedLinksAndTrimsNewlines()
  218. {
  219. if (!defined('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  220. || !constant('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  221. ) {
  222. $this->markTestSkipped('testGetsFeedLinksAsValueObject() requires a network connection');
  223. return;
  224. }
  225. try {
  226. $links = Zend_Feed_Reader::findFeedLinks('http://www.infopod.com.br');
  227. } catch(Exception $e) {
  228. $this->fail($e->getMessage());
  229. }
  230. $this->assertEquals('http://feeds.feedburner.com/jonnyken/infoblog', $links->rss);
  231. }
  232. /**
  233. * @group ZF-8330
  234. */
  235. public function testGetsFeedLinksAndNormalisesRelativeUrls()
  236. {
  237. if (!defined('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  238. || !constant('TESTS_ZEND_FEED_READER_ONLINE_ENABLED')
  239. ) {
  240. $this->markTestSkipped('testGetsFeedLinksAsValueObject() requires a network connection');
  241. return;
  242. }
  243. try {
  244. $links = Zend_Feed_Reader::findFeedLinks('http://meiobit.com');
  245. } catch(Exception $e) {
  246. $this->fail($e->getMessage());
  247. }
  248. $this->assertEquals('http://meiobit.com/rss.xml', $links->rss);
  249. }
  250. /**
  251. * @group ZF-8330
  252. */
  253. public function testGetsFeedLinksAndNormalisesRelativeUrlsOnUriWithPath()
  254. {
  255. try {
  256. $currClient = Zend_Feed_Reader::getHttpClient();
  257. $testAdapter = new Zend_Http_Client_Adapter_Test();
  258. $testAdapter->setResponse(new Zend_Http_Response(200, array(), '<!DOCTYPE html><html><head><link rel="alternate" type="application/rss+xml" href="../test.rss"><link rel="alternate" type="application/atom+xml" href="/test.atom"></head><body></body></html>'));
  259. Zend_Feed_Reader::setHttpClient(new Zend_Http_Client(null, array('adapter' => $testAdapter)));
  260. $links = Zend_Feed_Reader::findFeedLinks('http://foo/bar');
  261. Zend_Feed_Reader::setHttpClient($currClient);
  262. } catch(Exception $e) {
  263. $this->fail($e->getMessage());
  264. }
  265. $this->assertEquals('http://foo/test.rss', $links->rss);
  266. $this->assertEquals('http://foo/test.atom', $links->atom);
  267. }
  268. public function testAddsPrefixPath()
  269. {
  270. Zend_Feed_Reader::addPrefixPath('A_B_C', '/A/B/C');
  271. $prefixPaths = Zend_Feed_Reader::getPluginLoader()->getPaths();
  272. $this->assertEquals('/A/B/C/', $prefixPaths['A_B_C_'][0]);
  273. }
  274. public function testRegistersUserExtension()
  275. {
  276. try {
  277. Zend_Feed_Reader::addPrefixPath('My_FeedReader_Extension',dirname(__FILE__) . '/Reader/_files/My/Extension');
  278. Zend_Feed_Reader::registerExtension('JungleBooks');
  279. } catch(Exception $e) {
  280. $this->fail($e->getMessage());
  281. }
  282. $this->assertTrue(Zend_Feed_Reader::isRegistered('JungleBooks'));
  283. }
  284. /**
  285. * @group ZF-11184
  286. */
  287. public function testImportingUriWithEmptyResponseBodyTriggersException()
  288. {
  289. $currClient = Zend_Feed_Reader::getHttpClient();
  290. $testAdapter = new Zend_Http_Client_Adapter_Test();
  291. $testAdapter->setResponse(new Zend_Http_Response(200,array(),''));
  292. Zend_Feed_Reader::setHttpClient(new Zend_Http_Client(null, array(
  293. 'adapter'=>$testAdapter
  294. )));
  295. $this->setExpectedException('Zend_Feed_Exception', 'Feed failed to load');
  296. $result = Zend_Feed_Reader::import('http://www.example.com');
  297. }
  298. public function testXxePreventionOnFeedParsing()
  299. {
  300. $string = file_get_contents($this->_feedSamplePath.'/Reader/xxe-atom10.xml');
  301. $string = str_replace('XXE_URI', $this->_feedSamplePath.'/Reader/xxe-info.txt', $string);
  302. $this->setExpectedException('Zend_Feed_Exception');
  303. $feed = Zend_Feed_Reader::importString($string);
  304. }
  305. protected function _getTempDirectory()
  306. {
  307. $tmpdir = array();
  308. foreach (array($_ENV, $_SERVER) as $tab) {
  309. foreach (array('TMPDIR', 'TEMP', 'TMP', 'windir', 'SystemRoot') as $key) {
  310. if (isset($tab[$key])) {
  311. if (($key == 'windir') or ($key == 'SystemRoot')) {
  312. $dir = realpath($tab[$key] . '\\temp');
  313. } else {
  314. $dir = realpath($tab[$key]);
  315. }
  316. if ($this->_isGoodTmpDir($dir)) {
  317. return $dir;
  318. }
  319. }
  320. }
  321. }
  322. if (function_exists('sys_get_temp_dir')) {
  323. $dir = sys_get_temp_dir();
  324. if ($this->_isGoodTmpDir($dir)) {
  325. return $dir;
  326. }
  327. }
  328. $tempFile = tempnam(md5(uniqid(rand(), TRUE)), '');
  329. if ($tempFile) {
  330. $dir = realpath(dirname($tempFile));
  331. unlink($tempFile);
  332. if ($this->_isGoodTmpDir($dir)) {
  333. return $dir;
  334. }
  335. }
  336. if ($this->_isGoodTmpDir('/tmp')) {
  337. return '/tmp';
  338. }
  339. if ($this->_isGoodTmpDir('\\temp')) {
  340. return '\\temp';
  341. }
  342. }
  343. protected function _isGoodTmpDir($dir)
  344. {
  345. if (is_readable($dir) && is_writable($dir)) {
  346. return true;
  347. }
  348. return false;
  349. }
  350. }