zerobin.php 33 KB

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