Procházet zdrojové kódy

preparing unit test for model refactoring, refactoring traffic limiter

El RIDO před 11 roky
rodič
revize
211d3e4622
4 změnil soubory, kde provedl 213 přidání a 22 odebrání
  1. 48 4
      lib/trafficlimiter.php
  2. 3 13
      lib/zerobin.php
  3. 154 0
      tst/model.php
  4. 8 5
      tst/trafficlimiter.php

+ 48 - 4
lib/trafficlimiter.php

@@ -26,6 +26,15 @@ class trafficlimiter extends persistence
      */
     private static $_limit = 10;
 
+    /**
+     * key to fetch IP address
+     *
+     * @access private
+     * @static
+     * @var    string
+     */
+    private static $_ipKey = 'REMOTE_ADDR';
+
     /**
      * set the time limit in seconds
      *
@@ -39,6 +48,40 @@ class trafficlimiter extends persistence
         self::$_limit = $limit;
     }
 
+    /**
+     * set configuration options of the traffic limiter
+     *
+     * @access public
+     * @static
+     * @param configuration $conf
+     * @return void
+     */
+    public static function setConfiguration(configuration $conf)
+    {
+        self::setLimit($conf->getKey('limit', 'traffic'));
+        self::setPath($conf->getKey('dir', 'traffic'));
+        if (($option = $conf->getKey('header', 'traffic')) !== null)
+        {
+            $httpHeader = 'HTTP_' . $option;
+            if (array_key_exists($httpHeader, $_SERVER) && !empty($_SERVER[$httpHeader]))
+            {
+                self::$_ipKey = $httpHeader;
+            }
+        }
+    }
+
+    /**
+     * get the current visitors IP address
+     *
+     * @access public
+     * @static
+     * @return string
+     */
+    public static function getIp()
+    {
+        return $_SERVER[self::$_ipKey];
+    }
+
     /**
      * traffic limiter
      *
@@ -46,14 +89,15 @@ class trafficlimiter extends persistence
      *
      * @access public
      * @static
-     * @param  string $ip
      * @throws Exception
      * @return bool
      */
-    public static function canPass($ip)
+    public static function canPass()
     {
-    	// disable limits if set to less then 1
-    	if (self::$_limit < 1) return true;
+        $ip = self::getIp();
+
+        // disable limits if set to less then 1
+        if (self::$_limit < 1) return true;
 
         $file = 'traffic_limiter.php';
         if (!self::_exists($file))

+ 3 - 13
lib/zerobin.php

@@ -215,18 +215,8 @@ class zerobin
         $attachmentname = $has_attachmentname ? $_POST['attachmentname'] : '';
 
         // Make sure last paste from the IP address was more than X seconds ago.
-        trafficlimiter::setLimit($this->_conf->getKey('limit', 'traffic'));
-        trafficlimiter::setPath($this->_conf->getKey('dir', 'traffic'));
-        $ipKey = 'REMOTE_ADDR';
-        if (($option = $this->_conf->getKey('header', 'traffic')) !== null)
-        {
-            $header = 'HTTP_' . $option;
-            if (array_key_exists($header, $_SERVER) && !empty($_SERVER[$header]))
-            {
-                $ipKey = $header;
-            }
-        }
-        if (!trafficlimiter::canPass($_SERVER[$ipKey])) return $this->_return_message(
+        trafficlimiter::setConfiguration($this->_conf);
+        if (!trafficlimiter::canPass()) return $this->_return_message(
             1,
             i18n::_(
                 'Please wait %d seconds between each post.',
@@ -334,7 +324,7 @@ class zerobin
             {
                 $meta['nickname'] = $nick;
                 $vz = new vizhash16x16();
-                $pngdata = $vz->generate($_SERVER['REMOTE_ADDR']);
+                $pngdata = $vz->generate(trafficlimiter::getIp());
                 if ($pngdata != '')
                 {
                     $meta['vizhash'] = 'data:image/png;base64,' . base64_encode($pngdata);

+ 154 - 0
tst/model.php

@@ -0,0 +1,154 @@
+<?php
+class modelTest extends PHPUnit_Framework_TestCase
+{
+    private $_conf;
+
+    private $_model;
+
+    public function setUp()
+    {
+        /* Setup Routine */
+        $options = parse_ini_file(CONF, true);
+        $options['model'] = array(
+            'class' => 'zerobin_db',
+        );
+        $options['model_options'] = array(
+            'dsn' => 'sqlite::memory:',
+            'usr' => null,
+            'pwd' => null,
+            'opt' => array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION),
+        );
+        helper::confBackup();
+        helper::createIniFile(CONF, $options);
+        $this->_conf = new configuration;
+        $this->_model = new model($this->_conf);
+    }
+
+    public function tearDown()
+    {
+        /* Tear Down Routine */
+    }
+
+    public function testBasicWorkflow()
+    {
+        // storing pastes
+        $pasteData = helper::getPaste();
+        $this->_model->getPaste(helper::getPasteId())->delete();
+        $paste = $this->_model->getPaste(helper::getPasteId());
+        $this->assertFalse($paste->exists(), 'paste does not yet exist');
+
+        $paste = $this->_model->getPaste();
+        $paste->setData($pasteData['data']);
+        $paste->setOpendiscussion();
+        $paste->setFormatter($pasteData['meta']['formatter']);
+        $paste->store();
+
+        $paste = $this->_model->getPaste(helper::getPasteId());
+        $this->assertTrue($paste->exists(), 'paste exists after storing it');
+        $paste = $paste->get();
+        foreach (array('data', 'opendiscussion', 'formatter') as $key) {
+            $this->assertEquals($pasteData[$key], $paste->$key);
+        }
+
+        // storing comments
+        $commentData = helper::getComment();
+        $comment = $paste->getComment(helper::getPasteId(), helper::getCommentId());
+        $this->assertFalse($comment->exists(), 'comment does not yet exist');
+
+        $comment = $paste->getComment(helper::getPasteId());
+        $comment->setData($commentData['data']);
+        $comment->setNickname($commentData['meta']['nickname']);
+        $comment->store();
+
+        $comment = $paste->getComment(helper::getPasteId(), helper::getCommentId());
+        $this->assertTrue($comment->exists(), 'comment exists after storing it');
+        $comment = $comment->get();
+        $this->assertEquals($commentData['data'], $comment->data);
+        $this->assertEquals($commentData['meta']['nickname'], $comment->meta->nickname);
+
+        // deleting pastes
+        $this->_model->getPaste(helper::getPasteId())->delete();
+        $paste = $this->_model->getPaste(helper::getPasteId());
+        $this->assertFalse($paste->exists(), 'paste successfully deleted');
+        $this->assertEquals(array(), $paste->getComments(), 'comment was deleted with paste');
+    }
+
+    /**
+     * @expectedException Exception
+     * @expectedExceptionCode 60
+     */
+    public function testPasteDuplicate()
+    {
+        $pasteData = helper::getPaste();
+
+        $this->_model->getPaste(helper::getPasteId())->delete();
+        $paste = $this->_model->getPaste();
+        $paste->setData($pasteData['data']);
+        $paste->setOpendiscussion();
+        $paste->setFormatter($pasteData['meta']['formatter']);
+        $paste->store();
+
+        $paste = $this->_model->getPaste();
+        $paste->setData($pasteData['data']);
+        $paste->setOpendiscussion();
+        $paste->setFormatter($pasteData['meta']['formatter']);
+        $paste->store();
+    }
+
+    /**
+     * @expectedException Exception
+     * @expectedExceptionCode 60
+     */
+    public function testCommentDuplicate()
+    {
+        $pasteData = helper::getPaste();
+        $commentData = helper::getComment();
+        $this->_model->getPaste(helper::getPasteId())->delete();
+
+        $paste = $this->_model->getPaste();
+        $paste->setData($pasteData['data']);
+        $paste->setOpendiscussion();
+        $paste->setFormatter($pasteData['meta']['formatter']);
+        $paste->store();
+
+        $comment = $paste->getComment(helper::getPasteId());
+        $comment->setData($commentData['data']);
+        $comment->setNickname($commentData['meta']['nickname']);
+        $comment->store();
+
+        $comment = $paste->getComment(helper::getPasteId());
+        $comment->setData($commentData['data']);
+        $comment->setNickname($commentData['meta']['nickname']);
+        $comment->store();
+    }
+
+    public function testImplicitDefaults()
+    {
+        $pasteData = helper::getPaste();
+        $commentData = helper::getComment();
+        $this->_model->getPaste(helper::getPasteId())->delete();
+
+        $paste = $this->_model->getPaste();
+        $paste->setData($pasteData['data']);
+        $paste->setBurnafterreading();
+        $paste->setOpendiscussion();
+        // not setting a formatter, should use default one
+        $paste->store();
+
+        $paste = $this->_model->getPaste(helper::getPasteId())->get(); // ID was set based on data
+        $this->assertEquals(true, $paste->meta->burnafterreading, 'burn after reading takes precedence');
+        $this->assertEquals(false, $paste->meta->opendiscussion, 'opendiscussion is overiden');
+        $this->assertEquals($this->_conf->getKey('defaultformatter'), $paste->meta->formatter, 'default formatter is set');
+
+        $_SERVER['REMOTE_ADDR'] = '::1';
+        $vz = new vizhash16x16();
+        $pngdata = 'data:image/png;base64,' . base64_encode($vz->generate($_SERVER['REMOTE_ADDR']));
+        $comment = $this->_model->getPaste(helper::getPasteId())->getComment(helper::getPasteId());
+        $comment->setData($commentData['data']);
+        $comment->setNickname($commentData['meta']['nickname']);
+        $comment->store();
+
+        $comment = $paste->getComment(helper::getPasteId(), helper::getCommentId());
+        $this->assertEquals($pngdata, $comment->meta->vizhash, 'nickname triggers vizhash to be set');
+    }
+}

+ 8 - 5
tst/trafficlimiter.php

@@ -22,12 +22,15 @@ class trafficlimiterTest extends PHPUnit_Framework_TestCase
         $file = 'baz';
         $this->assertEquals($this->_path . DIRECTORY_SEPARATOR . $file, trafficlimiter::getPath($file));
         trafficlimiter::setLimit(4);
-        $this->assertTrue(trafficlimiter::canPass('127.0.0.1'), 'first request may pass');
+        $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
+        $this->assertTrue(trafficlimiter::canPass(), 'first request may pass');
         sleep(2);
-        $this->assertFalse(trafficlimiter::canPass('127.0.0.1'), 'second request is to fast, may not pass');
+        $this->assertFalse(trafficlimiter::canPass(), 'second request is to fast, may not pass');
         sleep(3);
-        $this->assertTrue(trafficlimiter::canPass('127.0.0.1'), 'third request waited long enough and may pass');
-        $this->assertTrue(trafficlimiter::canPass('2001:1620:2057:dead:beef::cafe:babe'), 'fourth request has different ip and may pass');
-        $this->assertFalse(trafficlimiter::canPass('127.0.0.1'), 'fifth request is to fast, may not pass');
+        $this->assertTrue(trafficlimiter::canPass(), 'third request waited long enough and may pass');
+        $_SERVER['REMOTE_ADDR'] = '2001:1620:2057:dead:beef::cafe:babe';
+        $this->assertTrue(trafficlimiter::canPass(), 'fourth request has different ip and may pass');
+        $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
+        $this->assertFalse(trafficlimiter::canPass(), 'fifth request is to fast, may not pass');
     }
 }