zerobin.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947
  1. <?php
  2. class zerobinTest extends PHPUnit_Framework_TestCase
  3. {
  4. protected $_model;
  5. public function setUp()
  6. {
  7. /* Setup Routine */
  8. $this->_model = zerobin_data::getInstance(array('dir' => PATH . 'data'));
  9. serversalt::setPath(PATH . 'data');
  10. $this->reset();
  11. }
  12. public function tearDown()
  13. {
  14. /* Tear Down Routine */
  15. helper::confRestore();
  16. }
  17. public function reset()
  18. {
  19. $_POST = array();
  20. $_GET = array();
  21. $_SERVER = array();
  22. if ($this->_model->exists(helper::getPasteId()))
  23. $this->_model->delete(helper::getPasteId());
  24. helper::confRestore();
  25. }
  26. /**
  27. * @runInSeparateProcess
  28. */
  29. public function testView()
  30. {
  31. $this->reset();
  32. ob_start();
  33. new zerobin;
  34. $content = ob_get_contents();
  35. $this->assertContains(
  36. '<title>ZeroBin</title>',
  37. $content,
  38. 'outputs title correctly'
  39. );
  40. $this->assertNotContains(
  41. 'id="shortenbutton"',
  42. $content,
  43. 'doesn\'t output shortener button'
  44. );
  45. }
  46. /**
  47. * @runInSeparateProcess
  48. */
  49. public function testViewLanguageSelection()
  50. {
  51. $this->reset();
  52. $options = parse_ini_file(CONF, true);
  53. $options['main']['languageselection'] = true;
  54. helper::confBackup();
  55. helper::createIniFile(CONF, $options);
  56. $_COOKIE['lang'] = 'de';
  57. ob_start();
  58. new zerobin;
  59. $content = ob_get_contents();
  60. $this->assertContains(
  61. '<title>ZeroBin</title>',
  62. $content,
  63. 'outputs title correctly'
  64. );
  65. }
  66. /**
  67. * @runInSeparateProcess
  68. */
  69. public function testViewForceLanguageDefault()
  70. {
  71. $this->reset();
  72. $options = parse_ini_file(CONF, true);
  73. $options['main']['languageselection'] = false;
  74. $options['main']['languagedefault'] = 'fr';
  75. helper::confBackup();
  76. helper::createIniFile(CONF, $options);
  77. $_COOKIE['lang'] = 'de';
  78. ob_start();
  79. new zerobin;
  80. $content = ob_get_contents();
  81. $this->assertContains(
  82. '<title>ZeroBin</title>',
  83. $content,
  84. 'outputs title correctly'
  85. );
  86. }
  87. /**
  88. * @runInSeparateProcess
  89. */
  90. public function testViewUrlShortener()
  91. {
  92. $shortener = 'https://shortener.example.com/api?link=';
  93. $this->reset();
  94. $options = parse_ini_file(CONF, true);
  95. $options['main']['urlshortener'] = $shortener;
  96. helper::confBackup();
  97. helper::createIniFile(CONF, $options);
  98. $_COOKIE['lang'] = 'de';
  99. ob_start();
  100. new zerobin;
  101. $content = ob_get_contents();
  102. $this->assertRegExp(
  103. '#id="shortenbutton"[^>]*data-shortener="' . preg_quote($shortener) . '"#',
  104. $content,
  105. 'outputs configured shortener URL correctly'
  106. );
  107. }
  108. /**
  109. * @runInSeparateProcess
  110. */
  111. public function testHtaccess()
  112. {
  113. $this->reset();
  114. $dirs = array('cfg', 'lib');
  115. foreach ($dirs as $dir) {
  116. $file = PATH . $dir . DIRECTORY_SEPARATOR . '.htaccess';
  117. @unlink($file);
  118. }
  119. new zerobin;
  120. foreach ($dirs as $dir) {
  121. $file = PATH . $dir . DIRECTORY_SEPARATOR . '.htaccess';
  122. $this->assertFileExists(
  123. $file,
  124. "$dir htaccess recreated"
  125. );
  126. }
  127. }
  128. /**
  129. * @expectedException Exception
  130. * @expectedExceptionCode 2
  131. */
  132. public function testConf()
  133. {
  134. $this->reset();
  135. helper::confBackup();
  136. file_put_contents(CONF, '');
  137. ob_start();
  138. new zerobin;
  139. $content = ob_get_contents();
  140. }
  141. /**
  142. * @runInSeparateProcess
  143. */
  144. public function testCreate()
  145. {
  146. $this->reset();
  147. $options = parse_ini_file(CONF, true);
  148. $options['traffic']['limit'] = 0;
  149. helper::confBackup();
  150. helper::createIniFile(CONF, $options);
  151. $_POST = helper::getPaste();
  152. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  153. $_SERVER['REQUEST_METHOD'] = 'POST';
  154. $_SERVER['REMOTE_ADDR'] = '::1';
  155. ob_start();
  156. new zerobin;
  157. $content = ob_get_contents();
  158. $response = json_decode($content, true);
  159. $this->assertEquals(0, $response['status'], 'outputs status');
  160. $this->assertEquals(
  161. hash_hmac('sha1', $response['id'], serversalt::get()),
  162. $response['deletetoken'],
  163. 'outputs valid delete token'
  164. );
  165. $this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
  166. }
  167. /**
  168. * @runInSeparateProcess
  169. */
  170. public function testCreateInvalidTimelimit()
  171. {
  172. $this->reset();
  173. $_POST = helper::getPaste();
  174. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  175. $_SERVER['REQUEST_METHOD'] = 'POST';
  176. $_SERVER['REMOTE_ADDR'] = '::1';
  177. trafficlimiter::canPass();
  178. ob_start();
  179. new zerobin;
  180. $content = ob_get_contents();
  181. $response = json_decode($content, true);
  182. $this->assertEquals(1, $response['status'], 'outputs error status');
  183. $this->assertFalse($this->_model->exists(helper::getPasteId()), 'paste exists after posting data');
  184. }
  185. /**
  186. * @runInSeparateProcess
  187. */
  188. public function testCreateInvalidSize()
  189. {
  190. $this->reset();
  191. $options = parse_ini_file(CONF, true);
  192. $options['main']['sizelimit'] = 10;
  193. $options['traffic']['limit'] = 0;
  194. helper::confBackup();
  195. helper::createIniFile(CONF, $options);
  196. $_POST = helper::getPaste();
  197. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  198. $_SERVER['REQUEST_METHOD'] = 'POST';
  199. $_SERVER['REMOTE_ADDR'] = '::1';
  200. ob_start();
  201. new zerobin;
  202. $content = ob_get_contents();
  203. $response = json_decode($content, true);
  204. $this->assertEquals(1, $response['status'], 'outputs error status');
  205. $this->assertFalse($this->_model->exists(helper::getPasteId()), 'paste exists after posting data');
  206. }
  207. /**
  208. * @runInSeparateProcess
  209. */
  210. public function testCreateProxyHeader()
  211. {
  212. $this->reset();
  213. $options = parse_ini_file(CONF, true);
  214. $options['traffic']['header'] = 'X_FORWARDED_FOR';
  215. $options['traffic']['limit'] = 100;
  216. helper::confBackup();
  217. helper::createIniFile(CONF, $options);
  218. $_POST = helper::getPaste();
  219. $_SERVER['HTTP_X_FORWARDED_FOR'] = '::1';
  220. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  221. $_SERVER['REQUEST_METHOD'] = 'POST';
  222. $_SERVER['REMOTE_ADDR'] = '::1';
  223. ob_start();
  224. new zerobin;
  225. $content = ob_get_contents();
  226. $response = json_decode($content, true);
  227. $this->assertEquals(1, $response['status'], 'outputs error status');
  228. $this->assertFalse($this->_model->exists(helper::getPasteId()), 'paste exists after posting data');
  229. }
  230. /**
  231. * @runInSeparateProcess
  232. */
  233. public function testCreateDuplicateId()
  234. {
  235. $this->reset();
  236. $options = parse_ini_file(CONF, true);
  237. $options['traffic']['limit'] = 0;
  238. helper::confBackup();
  239. helper::createIniFile(CONF, $options);
  240. $this->_model->create(helper::getPasteId(), helper::getPaste());
  241. $_POST = helper::getPaste();
  242. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  243. $_SERVER['REQUEST_METHOD'] = 'POST';
  244. $_SERVER['REMOTE_ADDR'] = '::1';
  245. ob_start();
  246. new zerobin;
  247. $content = ob_get_contents();
  248. $response = json_decode($content, true);
  249. $this->assertEquals(1, $response['status'], 'outputs error status');
  250. $this->assertTrue($this->_model->exists(helper::getPasteId()), 'paste exists after posting data');
  251. }
  252. /**
  253. * @runInSeparateProcess
  254. */
  255. public function testCreateValidExpire()
  256. {
  257. $this->reset();
  258. $options = parse_ini_file(CONF, true);
  259. $options['traffic']['limit'] = 0;
  260. helper::confBackup();
  261. helper::createIniFile(CONF, $options);
  262. $_POST = helper::getPaste();
  263. $_POST['expire'] = '5min';
  264. $_POST['formatter'] = 'foo';
  265. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  266. $_SERVER['REQUEST_METHOD'] = 'POST';
  267. $_SERVER['REMOTE_ADDR'] = '::1';
  268. $time = time();
  269. ob_start();
  270. new zerobin;
  271. $content = ob_get_contents();
  272. $response = json_decode($content, true);
  273. $this->assertEquals(0, $response['status'], 'outputs status');
  274. $this->assertEquals(
  275. hash_hmac('sha1', $response['id'], serversalt::get()),
  276. $response['deletetoken'],
  277. 'outputs valid delete token'
  278. );
  279. $this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
  280. $paste = $this->_model->read($response['id']);
  281. $this->assertEquals($time + 300, $paste->meta->expire_date, 'time is set correctly');
  282. }
  283. /**
  284. * @runInSeparateProcess
  285. */
  286. public function testCreateValidExpireWithDiscussion()
  287. {
  288. $this->reset();
  289. $options = parse_ini_file(CONF, true);
  290. $options['traffic']['limit'] = 0;
  291. helper::confBackup();
  292. helper::createIniFile(CONF, $options);
  293. $_POST = helper::getPaste();
  294. $_POST['expire'] = '5min';
  295. $_POST['opendiscussion'] = '1';
  296. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  297. $_SERVER['REQUEST_METHOD'] = 'POST';
  298. $_SERVER['REMOTE_ADDR'] = '::1';
  299. ob_start();
  300. new zerobin;
  301. $content = ob_get_contents();
  302. $response = json_decode($content, true);
  303. $this->assertEquals(0, $response['status'], 'outputs status');
  304. $this->assertEquals(
  305. hash_hmac('sha1', $response['id'], serversalt::get()),
  306. $response['deletetoken'],
  307. 'outputs valid delete token'
  308. );
  309. $this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
  310. $paste = $this->_model->read($response['id']);
  311. $this->assertEquals(time() + 300, $paste->meta->expire_date, 'time is set correctly');
  312. $this->assertEquals(1, $paste->meta->opendiscussion, 'time is set correctly');
  313. }
  314. /**
  315. * @runInSeparateProcess
  316. */
  317. public function testCreateInvalidExpire()
  318. {
  319. $this->reset();
  320. $options = parse_ini_file(CONF, true);
  321. $options['traffic']['limit'] = 0;
  322. helper::confBackup();
  323. helper::createIniFile(CONF, $options);
  324. $_POST = helper::getPaste();
  325. $_POST['expire'] = 'foo';
  326. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  327. $_SERVER['REQUEST_METHOD'] = 'POST';
  328. $_SERVER['REMOTE_ADDR'] = '::1';
  329. ob_start();
  330. new zerobin;
  331. $content = ob_get_contents();
  332. $response = json_decode($content, true);
  333. $this->assertEquals(0, $response['status'], 'outputs status');
  334. $this->assertEquals(
  335. hash_hmac('sha1', $response['id'], serversalt::get()),
  336. $response['deletetoken'],
  337. 'outputs valid delete token'
  338. );
  339. $this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
  340. }
  341. /**
  342. * @runInSeparateProcess
  343. */
  344. public function testCreateInvalidBurn()
  345. {
  346. $this->reset();
  347. $options = parse_ini_file(CONF, true);
  348. $options['traffic']['limit'] = 0;
  349. helper::confBackup();
  350. helper::createIniFile(CONF, $options);
  351. $_POST = helper::getPaste();
  352. $_POST['burnafterreading'] = 'neither 1 nor 0';
  353. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  354. $_SERVER['REQUEST_METHOD'] = 'POST';
  355. $_SERVER['REMOTE_ADDR'] = '::1';
  356. ob_start();
  357. new zerobin;
  358. $content = ob_get_contents();
  359. $response = json_decode($content, true);
  360. $this->assertEquals(1, $response['status'], 'outputs error status');
  361. $this->assertFalse($this->_model->exists(helper::getPasteId()), 'paste exists after posting data');
  362. }
  363. /**
  364. * @runInSeparateProcess
  365. */
  366. public function testCreateInvalidOpenDiscussion()
  367. {
  368. $this->reset();
  369. $options = parse_ini_file(CONF, true);
  370. $options['traffic']['limit'] = 0;
  371. helper::confBackup();
  372. helper::createIniFile(CONF, $options);
  373. $_POST = helper::getPaste();
  374. $_POST['opendiscussion'] = 'neither 1 nor 0';
  375. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  376. $_SERVER['REQUEST_METHOD'] = 'POST';
  377. $_SERVER['REMOTE_ADDR'] = '::1';
  378. ob_start();
  379. new zerobin;
  380. $content = ob_get_contents();
  381. $response = json_decode($content, true);
  382. $this->assertEquals(1, $response['status'], 'outputs error status');
  383. $this->assertFalse($this->_model->exists(helper::getPasteId()), 'paste exists after posting data');
  384. }
  385. /**
  386. * @runInSeparateProcess
  387. */
  388. public function testCreateAttachment()
  389. {
  390. $this->reset();
  391. $options = parse_ini_file(CONF, true);
  392. $options['traffic']['limit'] = 0;
  393. $options['main']['fileupload'] = true;
  394. helper::confBackup();
  395. helper::createIniFile(CONF, $options);
  396. $_POST = helper::getPasteWithAttachment();
  397. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  398. $_SERVER['REQUEST_METHOD'] = 'POST';
  399. $_SERVER['REMOTE_ADDR'] = '::1';
  400. $this->assertFalse($this->_model->exists(helper::getPasteId()), 'paste does not exists before posting data');
  401. ob_start();
  402. new zerobin;
  403. $content = ob_get_contents();
  404. $response = json_decode($content, true);
  405. $this->assertEquals(0, $response['status'], 'outputs status');
  406. $this->assertEquals(
  407. hash_hmac('sha1', $response['id'], serversalt::get()),
  408. $response['deletetoken'],
  409. 'outputs valid delete token'
  410. );
  411. $this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
  412. $original = json_decode(json_encode($_POST));
  413. $stored = $this->_model->read($response['id']);
  414. foreach (array('data', 'attachment', 'attachmentname') as $key) {
  415. $this->assertEquals($original->$key, $stored->$key);
  416. }
  417. }
  418. /**
  419. * @runInSeparateProcess
  420. */
  421. public function testCreateValidNick()
  422. {
  423. $this->reset();
  424. $options = parse_ini_file(CONF, true);
  425. $options['traffic']['limit'] = 0;
  426. helper::confBackup();
  427. helper::createIniFile(CONF, $options);
  428. $_POST = helper::getPaste();
  429. $_POST['nickname'] = helper::getComment()['meta']['nickname'];
  430. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  431. $_SERVER['REQUEST_METHOD'] = 'POST';
  432. $_SERVER['REMOTE_ADDR'] = '::1';
  433. ob_start();
  434. new zerobin;
  435. $content = ob_get_contents();
  436. $response = json_decode($content, true);
  437. $this->assertEquals(0, $response['status'], 'outputs status');
  438. $this->assertEquals(
  439. hash_hmac('sha1', $response['id'], serversalt::get()),
  440. $response['deletetoken'],
  441. 'outputs valid delete token'
  442. );
  443. $this->assertTrue($this->_model->exists($response['id']), 'paste exists after posting data');
  444. }
  445. /**
  446. * @runInSeparateProcess
  447. */
  448. public function testCreateInvalidNick()
  449. {
  450. $this->reset();
  451. $options = parse_ini_file(CONF, true);
  452. $options['traffic']['limit'] = 0;
  453. helper::confBackup();
  454. helper::createIniFile(CONF, $options);
  455. $_POST = helper::getCommentPost();
  456. $_POST['pasteid'] = helper::getPasteId();
  457. $_POST['parentid'] = helper::getPasteId();
  458. $_POST['nickname'] = 'foo';
  459. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  460. $_SERVER['REQUEST_METHOD'] = 'POST';
  461. $_SERVER['REMOTE_ADDR'] = '::1';
  462. $this->_model->create(helper::getPasteId(), helper::getPaste());
  463. ob_start();
  464. new zerobin;
  465. $content = ob_get_contents();
  466. $response = json_decode($content, true);
  467. $this->assertEquals(1, $response['status'], 'outputs error status');
  468. $this->assertTrue($this->_model->exists(helper::getPasteId()), 'paste exists after posting data');
  469. }
  470. /**
  471. * @runInSeparateProcess
  472. */
  473. public function testCreateComment()
  474. {
  475. $this->reset();
  476. $options = parse_ini_file(CONF, true);
  477. $options['traffic']['limit'] = 0;
  478. helper::confBackup();
  479. helper::createIniFile(CONF, $options);
  480. $_POST = helper::getCommentPost();
  481. $_POST['pasteid'] = helper::getPasteId();
  482. $_POST['parentid'] = helper::getPasteId();
  483. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  484. $_SERVER['REQUEST_METHOD'] = 'POST';
  485. $_SERVER['REMOTE_ADDR'] = '::1';
  486. $this->_model->create(helper::getPasteId(), helper::getPaste());
  487. ob_start();
  488. new zerobin;
  489. $content = ob_get_contents();
  490. $response = json_decode($content, true);
  491. $this->assertEquals(0, $response['status'], 'outputs status');
  492. $this->assertTrue($this->_model->existsComment(helper::getPasteId(), helper::getPasteId(), $response['id']), 'paste exists after posting data');
  493. }
  494. /**
  495. * @runInSeparateProcess
  496. */
  497. public function testCreateInvalidComment()
  498. {
  499. $this->reset();
  500. $options = parse_ini_file(CONF, true);
  501. $options['traffic']['limit'] = 0;
  502. helper::confBackup();
  503. helper::createIniFile(CONF, $options);
  504. $_POST = helper::getCommentPost();
  505. $_POST['pasteid'] = helper::getPasteId();
  506. $_POST['parentid'] = 'foo';
  507. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  508. $_SERVER['REQUEST_METHOD'] = 'POST';
  509. $_SERVER['REMOTE_ADDR'] = '::1';
  510. $this->_model->create(helper::getPasteId(), helper::getPaste());
  511. ob_start();
  512. new zerobin;
  513. $content = ob_get_contents();
  514. $response = json_decode($content, true);
  515. $this->assertEquals(1, $response['status'], 'outputs error status');
  516. $this->assertFalse($this->_model->existsComment(helper::getPasteId(), helper::getPasteId(), helper::getCommentId()), 'paste exists after posting data');
  517. }
  518. /**
  519. * @runInSeparateProcess
  520. */
  521. public function testCreateCommentDiscussionDisabled()
  522. {
  523. $this->reset();
  524. $options = parse_ini_file(CONF, true);
  525. $options['traffic']['limit'] = 0;
  526. helper::confBackup();
  527. helper::createIniFile(CONF, $options);
  528. $_POST = helper::getCommentPost();
  529. $_POST['pasteid'] = helper::getPasteId();
  530. $_POST['parentid'] = helper::getPasteId();
  531. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  532. $_SERVER['REQUEST_METHOD'] = 'POST';
  533. $_SERVER['REMOTE_ADDR'] = '::1';
  534. $paste = helper::getPaste(array('opendiscussion' => false));
  535. $this->_model->create(helper::getPasteId(), $paste);
  536. ob_start();
  537. new zerobin;
  538. $content = ob_get_contents();
  539. $response = json_decode($content, true);
  540. $this->assertEquals(1, $response['status'], 'outputs error status');
  541. $this->assertFalse($this->_model->existsComment(helper::getPasteId(), helper::getPasteId(), helper::getCommentId()), 'paste exists after posting data');
  542. }
  543. /**
  544. * @runInSeparateProcess
  545. */
  546. public function testCreateCommentInvalidPaste()
  547. {
  548. $this->reset();
  549. $options = parse_ini_file(CONF, true);
  550. $options['traffic']['limit'] = 0;
  551. helper::confBackup();
  552. helper::createIniFile(CONF, $options);
  553. $_POST = helper::getCommentPost();
  554. $_POST['pasteid'] = helper::getPasteId();
  555. $_POST['parentid'] = helper::getPasteId();
  556. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  557. $_SERVER['REQUEST_METHOD'] = 'POST';
  558. $_SERVER['REMOTE_ADDR'] = '::1';
  559. ob_start();
  560. new zerobin;
  561. $content = ob_get_contents();
  562. $response = json_decode($content, true);
  563. $this->assertEquals(1, $response['status'], 'outputs error status');
  564. $this->assertFalse($this->_model->existsComment(helper::getPasteId(), helper::getPasteId(), helper::getCommentId()), 'paste exists after posting data');
  565. }
  566. /**
  567. * @runInSeparateProcess
  568. */
  569. public function testCreateDuplicateComment()
  570. {
  571. $this->reset();
  572. $options = parse_ini_file(CONF, true);
  573. $options['traffic']['limit'] = 0;
  574. helper::confBackup();
  575. helper::createIniFile(CONF, $options);
  576. $this->_model->create(helper::getPasteId(), helper::getPaste());
  577. $this->_model->createComment(helper::getPasteId(), helper::getPasteId(), helper::getCommentId(), helper::getComment());
  578. $this->assertTrue($this->_model->existsComment(helper::getPasteId(), helper::getPasteId(), helper::getCommentId()), 'comment exists before posting data');
  579. $_POST = helper::getCommentPost();
  580. $_POST['pasteid'] = helper::getPasteId();
  581. $_POST['parentid'] = helper::getPasteId();
  582. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  583. $_SERVER['REQUEST_METHOD'] = 'POST';
  584. $_SERVER['REMOTE_ADDR'] = '::1';
  585. ob_start();
  586. new zerobin;
  587. $content = ob_get_contents();
  588. $response = json_decode($content, true);
  589. $this->assertEquals(1, $response['status'], 'outputs error status');
  590. $this->assertTrue($this->_model->existsComment(helper::getPasteId(), helper::getPasteId(), helper::getCommentId()), 'paste exists after posting data');
  591. }
  592. /**
  593. * @runInSeparateProcess
  594. */
  595. public function testRead()
  596. {
  597. $this->reset();
  598. $this->_model->create(helper::getPasteId(), helper::getPaste());
  599. $_SERVER['QUERY_STRING'] = helper::getPasteId();
  600. ob_start();
  601. new zerobin;
  602. $content = ob_get_contents();
  603. $this->assertContains(
  604. '<div id="cipherdata" class="hidden">' .
  605. htmlspecialchars(helper::getPasteAsJson(), ENT_NOQUOTES) .
  606. '</div>',
  607. $content,
  608. 'outputs data correctly'
  609. );
  610. }
  611. /**
  612. * @runInSeparateProcess
  613. */
  614. public function testReadInvalidId()
  615. {
  616. $this->reset();
  617. $_SERVER['QUERY_STRING'] = 'foo';
  618. ob_start();
  619. new zerobin;
  620. $content = ob_get_contents();
  621. $this->assertRegExp(
  622. '#<div[^>]*id="errormessage"[^>]*>.*Invalid paste ID\.</div>#',
  623. $content,
  624. 'outputs error correctly'
  625. );
  626. }
  627. /**
  628. * @runInSeparateProcess
  629. */
  630. public function testReadNonexisting()
  631. {
  632. $this->reset();
  633. $_SERVER['QUERY_STRING'] = helper::getPasteId();
  634. ob_start();
  635. new zerobin;
  636. $content = ob_get_contents();
  637. $this->assertRegExp(
  638. '#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist[^<]*</div>#',
  639. $content,
  640. 'outputs error correctly'
  641. );
  642. }
  643. /**
  644. * @runInSeparateProcess
  645. */
  646. public function testReadExpired()
  647. {
  648. $this->reset();
  649. $expiredPaste = helper::getPaste(array('expire_date' => 1344803344));
  650. $this->_model->create(helper::getPasteId(), $expiredPaste);
  651. $_SERVER['QUERY_STRING'] = helper::getPasteId();
  652. ob_start();
  653. new zerobin;
  654. $content = ob_get_contents();
  655. $this->assertRegExp(
  656. '#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist[^<]*</div>#',
  657. $content,
  658. 'outputs error correctly'
  659. );
  660. }
  661. /**
  662. * @runInSeparateProcess
  663. */
  664. public function testReadBurn()
  665. {
  666. $this->reset();
  667. $burnPaste = helper::getPaste(array('burnafterreading' => true));
  668. $this->_model->create(helper::getPasteId(), $burnPaste);
  669. $_SERVER['QUERY_STRING'] = helper::getPasteId();
  670. ob_start();
  671. new zerobin;
  672. $content = ob_get_contents();
  673. $this->assertContains(
  674. '<div id="cipherdata" class="hidden">' .
  675. htmlspecialchars(helper::getPasteAsJson($burnPaste['meta']), ENT_NOQUOTES) .
  676. '</div>',
  677. $content,
  678. 'outputs data correctly'
  679. );
  680. }
  681. /**
  682. * @runInSeparateProcess
  683. */
  684. public function testReadJson()
  685. {
  686. $this->reset();
  687. $paste = helper::getPaste();
  688. $this->_model->create(helper::getPasteId(), $paste);
  689. $_SERVER['QUERY_STRING'] = helper::getPasteId();
  690. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  691. ob_start();
  692. new zerobin;
  693. $content = ob_get_contents();
  694. $response = json_decode($content, true);
  695. $this->assertEquals(0, $response['status'], 'outputs success status');
  696. $this->assertEquals(helper::getPasteId(), $response['id'], 'outputs data correctly');
  697. $this->assertStringEndsWith('?' . $response['id'], $response['url'], 'returned URL points to new paste');
  698. $this->assertEquals($paste['data'], $response['data'], 'outputs data correctly');
  699. $this->assertEquals($paste['meta']['formatter'], $response['meta']['formatter'], 'outputs format correctly');
  700. $this->assertEquals($paste['meta']['postdate'], $response['meta']['postdate'], 'outputs postdate correctly');
  701. $this->assertEquals($paste['meta']['opendiscussion'], $response['meta']['opendiscussion'], 'outputs opendiscussion correctly');
  702. $this->assertEquals(0, $response['comment_count'], 'outputs comment_count correctly');
  703. $this->assertEquals(0, $response['comment_offset'], 'outputs comment_offset correctly');
  704. }
  705. /**
  706. * @runInSeparateProcess
  707. */
  708. public function testReadInvalidJson()
  709. {
  710. $this->reset();
  711. $_SERVER['QUERY_STRING'] = helper::getPasteId();
  712. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  713. ob_start();
  714. new zerobin;
  715. $content = ob_get_contents();
  716. $response = json_decode($content, true);
  717. $this->assertEquals(1, $response['status'], 'outputs error status');
  718. }
  719. /**
  720. * @runInSeparateProcess
  721. */
  722. public function testReadOldSyntax()
  723. {
  724. $this->reset();
  725. $oldPaste = helper::getPaste();
  726. $meta = array(
  727. 'syntaxcoloring' => true,
  728. 'postdate' => $oldPaste['meta']['postdate'],
  729. 'opendiscussion' => $oldPaste['meta']['opendiscussion'],
  730. );
  731. $oldPaste['meta'] = $meta;
  732. $this->_model->create(helper::getPasteId(), $oldPaste);
  733. $_SERVER['QUERY_STRING'] = helper::getPasteId();
  734. ob_start();
  735. new zerobin;
  736. $content = ob_get_contents();
  737. $meta['formatter'] = 'syntaxhighlighting';
  738. $this->assertContains(
  739. '<div id="cipherdata" class="hidden">' .
  740. htmlspecialchars(helper::getPasteAsJson($meta), ENT_NOQUOTES) .
  741. '</div>',
  742. $content,
  743. 'outputs data correctly'
  744. );
  745. }
  746. /**
  747. * @runInSeparateProcess
  748. */
  749. public function testReadOldFormat()
  750. {
  751. $this->reset();
  752. $oldPaste = helper::getPaste();
  753. unset($oldPaste['meta']['formatter']);
  754. $this->_model->create(helper::getPasteId(), $oldPaste);
  755. $_SERVER['QUERY_STRING'] = helper::getPasteId();
  756. ob_start();
  757. new zerobin;
  758. $content = ob_get_contents();
  759. $oldPaste['meta']['formatter'] = 'plaintext';
  760. $this->assertContains(
  761. '<div id="cipherdata" class="hidden">' .
  762. htmlspecialchars(helper::getPasteAsJson($oldPaste['meta']), ENT_NOQUOTES) .
  763. '</div>',
  764. $content,
  765. 'outputs data correctly'
  766. );
  767. }
  768. /**
  769. * @runInSeparateProcess
  770. */
  771. public function testDelete()
  772. {
  773. $this->reset();
  774. $this->_model->create(helper::getPasteId(), helper::getPaste());
  775. $this->assertTrue($this->_model->exists(helper::getPasteId()), 'paste exists before deleting data');
  776. $_GET['pasteid'] = helper::getPasteId();
  777. $_GET['deletetoken'] = hash_hmac('sha1', helper::getPasteId(), serversalt::get());
  778. ob_start();
  779. new zerobin;
  780. $content = ob_get_contents();
  781. $this->assertRegExp(
  782. '#<div[^>]*id="status"[^>]*>.*Paste was properly deleted[^<]*</div>#s',
  783. $content,
  784. 'outputs deleted status correctly'
  785. );
  786. $this->assertFalse($this->_model->exists(helper::getPasteId()), 'paste successfully deleted');
  787. }
  788. /**
  789. * @runInSeparateProcess
  790. */
  791. public function testDeleteInvalidId()
  792. {
  793. $this->reset();
  794. $this->_model->create(helper::getPasteId(), helper::getPaste());
  795. $_GET['pasteid'] = 'foo';
  796. $_GET['deletetoken'] = 'bar';
  797. ob_start();
  798. new zerobin;
  799. $content = ob_get_contents();
  800. $this->assertRegExp(
  801. '#<div[^>]*id="errormessage"[^>]*>.*Invalid paste ID\.</div>#',
  802. $content,
  803. 'outputs delete error correctly'
  804. );
  805. $this->assertTrue($this->_model->exists(helper::getPasteId()), 'paste exists after failing to delete data');
  806. }
  807. /**
  808. * @runInSeparateProcess
  809. */
  810. public function testDeleteInexistantId()
  811. {
  812. $this->reset();
  813. $_GET['pasteid'] = helper::getPasteId();
  814. $_GET['deletetoken'] = 'bar';
  815. ob_start();
  816. new zerobin;
  817. $content = ob_get_contents();
  818. $this->assertRegExp(
  819. '#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist[^<]*</div>#',
  820. $content,
  821. 'outputs delete error correctly'
  822. );
  823. }
  824. /**
  825. * @runInSeparateProcess
  826. */
  827. public function testDeleteInvalidToken()
  828. {
  829. $this->reset();
  830. $this->_model->create(helper::getPasteId(), helper::getPaste());
  831. $_GET['pasteid'] = helper::getPasteId();
  832. $_GET['deletetoken'] = 'bar';
  833. ob_start();
  834. new zerobin;
  835. $content = ob_get_contents();
  836. $this->assertRegExp(
  837. '#<div[^>]*id="errormessage"[^>]*>.*Wrong deletion token[^<]*</div>#',
  838. $content,
  839. 'outputs delete error correctly'
  840. );
  841. $this->assertTrue($this->_model->exists(helper::getPasteId()), 'paste exists after failing to delete data');
  842. }
  843. /**
  844. * @runInSeparateProcess
  845. */
  846. public function testDeleteBurnAfterReading()
  847. {
  848. $this->reset();
  849. $burnPaste = helper::getPaste(array('burnafterreading' => true));
  850. $this->_model->create(helper::getPasteId(), $burnPaste);
  851. $this->assertTrue($this->_model->exists(helper::getPasteId()), 'paste exists before deleting data');
  852. $_POST['deletetoken'] = 'burnafterreading';
  853. $_SERVER['QUERY_STRING'] = helper::getPasteId();
  854. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  855. $_SERVER['REQUEST_METHOD'] = 'POST';
  856. ob_start();
  857. new zerobin;
  858. $content = ob_get_contents();
  859. $response = json_decode($content, true);
  860. $this->assertEquals(0, $response['status'], 'outputs status');
  861. $this->assertFalse($this->_model->exists(helper::getPasteId()), 'paste successfully deleted');
  862. }
  863. /**
  864. * @runInSeparateProcess
  865. */
  866. public function testDeleteInvalidBurnAfterReading()
  867. {
  868. $this->reset();
  869. $this->_model->create(helper::getPasteId(), helper::getPaste());
  870. $this->assertTrue($this->_model->exists(helper::getPasteId()), 'paste exists before deleting data');
  871. $_POST['deletetoken'] = 'burnafterreading';
  872. $_SERVER['QUERY_STRING'] = helper::getPasteId();
  873. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  874. $_SERVER['REQUEST_METHOD'] = 'POST';
  875. ob_start();
  876. new zerobin;
  877. $content = ob_get_contents();
  878. $response = json_decode($content, true);
  879. $this->assertEquals(1, $response['status'], 'outputs status');
  880. $this->assertTrue($this->_model->exists(helper::getPasteId()), 'paste successfully deleted');
  881. }
  882. /**
  883. * @runInSeparateProcess
  884. */
  885. public function testDeleteExpired()
  886. {
  887. $this->reset();
  888. $expiredPaste = helper::getPaste(array('expire_date' => 1000));
  889. $this->assertFalse($this->_model->exists(helper::getPasteId()), 'paste does not exist before being created');
  890. $this->_model->create(helper::getPasteId(), $expiredPaste);
  891. $this->assertTrue($this->_model->exists(helper::getPasteId()), 'paste exists before deleting data');
  892. $_GET['pasteid'] = helper::getPasteId();
  893. $_GET['deletetoken'] = 'does not matter in this context, but has to be set';
  894. ob_start();
  895. new zerobin;
  896. $content = ob_get_contents();
  897. $this->assertRegExp(
  898. '#<div[^>]*id="errormessage"[^>]*>.*Paste does not exist[^<]*</div>#',
  899. $content,
  900. 'outputs error correctly'
  901. );
  902. $this->assertFalse($this->_model->exists(helper::getPasteId()), 'paste successfully deleted');
  903. }
  904. }