Browse Source

make DatabaseTest work pass again, support reading & writing version 1 & 2 pastes & comments

El RIDO 7 years ago
parent
commit
6e15903f1e
3 changed files with 149 additions and 93 deletions
  1. 109 64
      lib/Data/Database.php
  2. 13 12
      tst/Bootstrap.php
  3. 27 17
      tst/Data/DatabaseTest.php

+ 109 - 64
lib/Data/Database.php

@@ -167,38 +167,43 @@ class Database extends AbstractData
             }
         }
 
-        $opendiscussion = $burnafterreading = false;
-        $attachment     = $attachmentname     = '';
-        $meta           = $paste['meta'];
-        unset($meta['postdate']);
-        $expire_date = 0;
-        if (array_key_exists('expire_date', $paste['meta'])) {
-            $expire_date = (int) $paste['meta']['expire_date'];
+        $expire_date      = 0;
+        $opendiscussion   = $burnafterreading = false;
+        $attachment       = $attachmentname   = null;
+        $meta             = $paste['meta'];
+        $isVersion1       = array_key_exists('data', $paste);
+        list($createdKey) = self::_getVersionedKeys($isVersion1 ? 1 : 2);
+        $created          = (int) $meta[$createdKey];
+        unset($meta[$createdKey], $paste['meta']);
+        if (array_key_exists('expire_date', $meta)) {
+            $expire_date = (int) $meta['expire_date'];
             unset($meta['expire_date']);
         }
-        if (array_key_exists('opendiscussion', $paste['meta'])) {
-            $opendiscussion = (bool) $paste['meta']['opendiscussion'];
+        if (array_key_exists('opendiscussion', $meta)) {
+            $opendiscussion = (bool) $meta['opendiscussion'];
             unset($meta['opendiscussion']);
         }
-        if (array_key_exists('burnafterreading', $paste['meta'])) {
-            $burnafterreading = (bool) $paste['meta']['burnafterreading'];
+        if (array_key_exists('burnafterreading', $meta)) {
+            $burnafterreading = (bool) $meta['burnafterreading'];
             unset($meta['burnafterreading']);
         }
-        if (array_key_exists('attachment', $paste['meta'])) {
-            $attachment = $paste['meta']['attachment'];
-            unset($meta['attachment']);
-        }
-        if (array_key_exists('attachmentname', $paste['meta'])) {
-            $attachmentname = $paste['meta']['attachmentname'];
-            unset($meta['attachmentname']);
+        if ($isVersion1) {
+            if (array_key_exists('attachment', $meta)) {
+                $attachment = $meta['attachment'];
+                unset($meta['attachment']);
+            }
+            if (array_key_exists('attachmentname', $meta)) {
+                $attachmentname = $meta['attachmentname'];
+                unset($meta['attachmentname']);
+            }
         }
         return self::_exec(
             'INSERT INTO ' . self::_sanitizeIdentifier('paste') .
             ' VALUES(?,?,?,?,?,?,?,?,?)',
             array(
                 $pasteid,
-                $paste['data'],
-                $paste['meta']['postdate'],
+                $isVersion1 ? $paste['data'] : json_encode($paste),
+                $created,
                 $expire_date,
                 (int) $opendiscussion,
                 (int) $burnafterreading,
@@ -229,46 +234,51 @@ class Database extends AbstractData
 
             if (false !== $paste) {
                 // create object
-                self::$_cache[$pasteid]       = new stdClass;
-                self::$_cache[$pasteid]->data = $paste['data'];
+                $data       = json_decode($paste['data']);
+                $isVersion2 = property_exists($data, 'v') && $data->v >= 2;
+                if ($isVersion2) {
+                    self::$_cache[$pasteid] = $data;
+                    list($createdKey) = self::_getVersionedKeys(2);
+                } else {
+                    self::$_cache[$pasteid]       = new stdClass;
+                    self::$_cache[$pasteid]->data = $paste['data'];
+                    list($createdKey) = self::_getVersionedKeys(1);
+                }
 
                 $meta = json_decode($paste['meta']);
                 if (!is_object($meta)) {
                     $meta = new stdClass;
                 }
 
-                // support older attachments
-                if (property_exists($meta, 'attachment')) {
-                    self::$_cache[$pasteid]->attachment = $meta->attachment;
-                    unset($meta->attachment);
-                    if (property_exists($meta, 'attachmentname')) {
-                        self::$_cache[$pasteid]->attachmentname = $meta->attachmentname;
-                        unset($meta->attachmentname);
+                if (!$isVersion2) {
+                    // support pre v1 attachments
+                    if (property_exists($meta, 'attachment')) {
+                        self::$_cache[$pasteid]->attachment = $meta->attachment;
+                        unset($meta->attachment);
+                        if (property_exists($meta, 'attachmentname')) {
+                            self::$_cache[$pasteid]->attachmentname = $meta->attachmentname;
+                            unset($meta->attachmentname);
+                        }
                     }
-                }
-                // support current attachments
-                elseif (array_key_exists('attachment', $paste) && strlen($paste['attachment'])) {
-                    self::$_cache[$pasteid]->attachment = $paste['attachment'];
-                    if (array_key_exists('attachmentname', $paste) && strlen($paste['attachmentname'])) {
-                        self::$_cache[$pasteid]->attachmentname = $paste['attachmentname'];
+                    // support v1 attachments
+                    elseif (array_key_exists('attachment', $paste) && strlen($paste['attachment'])) {
+                        self::$_cache[$pasteid]->attachment = $paste['attachment'];
+                        if (array_key_exists('attachmentname', $paste) && strlen($paste['attachmentname'])) {
+                            self::$_cache[$pasteid]->attachmentname = $paste['attachmentname'];
+                        }
                     }
                 }
-                self::$_cache[$pasteid]->meta           = $meta;
-                self::$_cache[$pasteid]->meta->postdate = (int) $paste['postdate'];
-                $expire_date                            = (int) $paste['expiredate'];
-                if (
-                    $expire_date > 0
-                ) {
+
+                self::$_cache[$pasteid]->meta = $meta;
+                self::$_cache[$pasteid]->meta->$createdKey = (int) $paste['postdate'];
+                $expire_date = (int) $paste['expiredate'];
+                if ($expire_date > 0) {
                     self::$_cache[$pasteid]->meta->expire_date = $expire_date;
                 }
-                if (
-                    $paste['opendiscussion']
-                ) {
+                if ($paste['opendiscussion']) {
                     self::$_cache[$pasteid]->meta->opendiscussion = true;
                 }
-                if (
-                    $paste['burnafterreading']
-                ) {
+                if ($paste['burnafterreading']) {
                     self::$_cache[$pasteid]->meta->burnafterreading = true;
                 }
             }
@@ -329,9 +339,19 @@ class Database extends AbstractData
      */
     public function createComment($pasteid, $parentid, $commentid, $comment)
     {
-        foreach (array('nickname', 'vizhash') as $key) {
-            if (!array_key_exists($key, $comment['meta'])) {
-                $comment['meta'][$key] = null;
+        if (array_key_exists('data', $comment)) {
+            $version = 1;
+            $data    = $comment['data'];
+        } else {
+            $version = 2;
+            $data    = json_encode($comment);
+        }
+        list($createdKey, $iconKey) = self::_getVersionedKeys($version);
+        $meta = $comment['meta'];
+        unset($comment['meta']);
+        foreach (array('nickname', $iconKey) as $key) {
+            if (!array_key_exists($key, $meta)) {
+                $meta[$key] = null;
             }
         }
         return self::_exec(
@@ -341,10 +361,10 @@ class Database extends AbstractData
                 $commentid,
                 $pasteid,
                 $parentid,
-                $comment['data'],
-                $comment['meta']['nickname'],
-                $comment['meta']['vizhash'],
-                $comment['meta']['postdate'],
+                $data,
+                $meta['nickname'],
+                $meta[$iconKey],
+                $meta[$createdKey],
             )
         );
     }
@@ -367,16 +387,24 @@ class Database extends AbstractData
         $comments = array();
         if (count($rows)) {
             foreach ($rows as $row) {
-                $i                            = $this->getOpenSlot($comments, (int) $row['postdate']);
-                $comments[$i]                 = new stdClass;
-                $comments[$i]->id             = $row['dataid'];
-                $comments[$i]->parentid       = $row['parentid'];
-                $comments[$i]->data           = $row['data'];
-                $comments[$i]->meta           = new stdClass;
-                $comments[$i]->meta->postdate = (int) $row['postdate'];
-                foreach (array('nickname', 'vizhash') as $key) {
-                    if (array_key_exists($key, $row) && !empty($row[$key])) {
-                        $comments[$i]->meta->$key = $row[$key];
+                $i = $this->getOpenSlot($comments, (int) $row['postdate']);
+                $data = json_decode($row['data']);
+                if (property_exists($data, 'v') && $data->v >= 2) {
+                    $version      = 2;
+                    $comments[$i] = $data;
+                } else {
+                    $version            = 1;
+                    $comments[$i]       = new stdClass;
+                    $comments[$i]->data = $row['data'];
+                }
+                list($createdKey, $iconKey) = self::_getVersionedKeys($version);
+                $comments[$i]->id                 = $row['dataid'];
+                $comments[$i]->parentid           = $row['parentid'];
+                $comments[$i]->meta               = new stdClass;
+                $comments[$i]->meta->$createdKey  = (int) $row['postdate'];
+                foreach (array('nickname' => 'nickname', 'vizhash' => $iconKey) as $rowKey => $commentKey) {
+                    if (array_key_exists($rowKey, $row) && !empty($row[$rowKey])) {
+                        $comments[$i]->meta->$commentKey = $row[$rowKey];
                     }
                 }
             }
@@ -465,6 +493,23 @@ class Database extends AbstractData
         return $result;
     }
 
+
+    /**
+     * get version dependent key names
+     *
+     * @access private
+     * @static
+     * @param  int $version
+     * @return array
+     */
+    private static function _getVersionedKeys(int $version)
+    {
+        if ($version === 1) {
+            return array('postdate', 'vizhash');
+        }
+        return array('created', 'icon');
+    }
+
     /**
      * get table list query, depending on the database type
      *

+ 13 - 12
tst/Bootstrap.php

@@ -64,11 +64,12 @@ class Helper
                 'zlib',
             ),
             'plaintext',
-            0,
+            1,
             0
         ),
         'meta' => array(
-            'expire' => '5min',
+            'expire'  => '5min',
+            'created' => 1344803344,
         ),
         'v' => 2,
         'ct' => 'ME5JF/YBEijp2uYMzLZozbKtWc5wfy6R59NBb7SmRig=',
@@ -119,7 +120,7 @@ class Helper
      * @param  array $meta
      * @return array
      */
-    public static function getPaste($version = 2, $meta = array())
+    public static function getPaste(int $version = 2, array $meta = array())
     {
         $example = self::getPasteWithAttachment($version, $meta);
         // v1 has the attachment stored in a separate property
@@ -136,9 +137,9 @@ class Helper
      * @param  array $meta
      * @return array
      */
-    public static function getPasteWithAttachment($version = 2, $meta = array())
+    public static function getPasteWithAttachment(int $version = 2, array $meta = array())
     {
-        $example                 = $version === 1 ? self::$pasteV1 :  self::$pasteV2;
+        $example                 = $version === 1 ? self::$pasteV1 : self::$pasteV2;
         $example['meta']['salt'] = ServerSalt::generate();
         $example['meta']         = array_merge($example['meta'], $meta);
         return $example;
@@ -151,7 +152,7 @@ class Helper
      * @param  array $meta
      * @return array
      */
-    public static function getPasteAsJson($version = 2, $meta = array())
+    public static function getPasteAsJson(int $version = 2, array $meta = array())
     {
         $example = self::getPaste($version);
         // the JSON shouldn't contain the salt
@@ -183,9 +184,9 @@ class Helper
      * @param  array $meta
      * @return array
      */
-    public static function getComment($version = 2, $meta = array())
+    public static function getComment(int $version = 2, array $meta = array())
     {
-        $example         = $version === 1 ? self::$commentV1 : self::getPaste($version);
+        $example         = $version === 1 ? self::$commentV1 : self::$pasteV2;
         if ($version === 2) {
             $example['pasteid'] = $example['parentid'] = self::getPasteId();
             $example['meta']['created'] = self::$commentV1['meta']['postdate'];
@@ -202,7 +203,7 @@ class Helper
      * @param  int $version
      * @return array
      */
-    public static function getCommentPost($version = 2)
+    public static function getCommentPost(int $version = 2)
     {
         $example = self::getComment($version);
         if ($version === 1) {
@@ -220,7 +221,7 @@ class Helper
      * @param string $path
      * @throws Exception
      */
-    public static function rmDir($path)
+    public static function rmDir(string $path)
     {
         if (is_dir($path)) {
             $path .= DIRECTORY_SEPARATOR;
@@ -279,7 +280,7 @@ class Helper
      * @param string $pathToFile
      * @param array $values
      */
-    public static function createIniFile($pathToFile, $values)
+    public static function createIniFile(string $pathToFile, array $values)
     {
         if (count($values)) {
             @unlink($pathToFile);
@@ -322,7 +323,7 @@ class Helper
      * @param bool $return
      * @return void|string
      */
-    public static function varExportMin($var, $return = false)
+    public static function varExportMin($var, bool $return = false)
     {
         if (is_array($var)) {
             $toImplode = array();

+ 27 - 17
tst/Data/DatabaseTest.php

@@ -36,7 +36,7 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
         $this->_model->delete(Helper::getPasteId());
 
         // storing pastes
-        $paste = Helper::getPaste(array('expire_date' => 1344803344));
+        $paste = Helper::getPaste();
         $this->assertFalse($this->_model->exists(Helper::getPasteId()), 'paste does not yet exist');
         $this->assertTrue($this->_model->create(Helper::getPasteId(), $paste), 'store new paste');
         $this->assertTrue($this->_model->exists(Helper::getPasteId()), 'paste exists after storing it');
@@ -44,14 +44,23 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(json_decode(json_encode($paste)), $this->_model->read(Helper::getPasteId()));
 
         // storing comments
-        $this->assertFalse($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment does not yet exist');
-        $this->assertTrue($this->_model->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), Helper::getComment()) !== false, 'store comment');
-        $this->assertTrue($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'comment exists after storing it');
-        $comment           = json_decode(json_encode(Helper::getComment()));
-        $comment->id       = Helper::getCommentId();
-        $comment->parentid = Helper::getPasteId();
+        $this->assertFalse($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'v1 comment does not yet exist');
+        $this->assertTrue($this->_model->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId(), Helper::getComment(1)) !== false, 'store v1 comment');
+        $this->assertTrue($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getCommentId()), 'v1 comment exists after storing it');
+        $this->assertFalse($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getPasteId()), 'v2 comment does not yet exist');
+        $this->assertTrue($this->_model->createComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getPasteId(), Helper::getComment(2)) !== false, 'store v2 comment');
+        $this->assertTrue($this->_model->existsComment(Helper::getPasteId(), Helper::getPasteId(), Helper::getPasteId()), 'v2 comment exists after storing it');
+        $comment1           = json_decode(json_encode(Helper::getComment(1)));
+        $comment1->id       = Helper::getCommentId();
+        $comment1->parentid = Helper::getPasteId();
+        $comment2           = json_decode(json_encode(Helper::getComment(2)));
+        $comment2->id       = Helper::getPasteId();
+        $comment2->parentid = Helper::getPasteId();
         $this->assertEquals(
-            array($comment->meta->postdate => $comment),
+            array(
+                $comment1->meta->postdate       => $comment1,
+                $comment2->meta->created . '.1' => $comment2,
+            ),
             $this->_model->readComments(Helper::getPasteId())
         );
 
@@ -64,8 +73,9 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
 
     public function testDatabaseBasedAttachmentStoreWorks()
     {
+        // this assumes a version 1 formatted paste
         $this->_model->delete(Helper::getPasteId());
-        $original                          = $paste                          = Helper::getPasteWithAttachment(array('expire_date' => 1344803344));
+        $original                          = $paste                                = Helper::getPasteWithAttachment(1, array('expire_date' => 1344803344));
         $paste['meta']['burnafterreading'] = $original['meta']['burnafterreading'] = true;
         $paste['meta']['attachment']       = $paste['attachment'];
         $paste['meta']['attachmentname']   = $paste['attachmentname'];
@@ -83,12 +93,12 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
     public function testPurge()
     {
         $this->_model->delete(Helper::getPasteId());
-        $expired = Helper::getPaste(array('expire_date' => 1344803344));
-        $paste   = Helper::getPaste(array('expire_date' => time() + 3600));
+        $expired = Helper::getPaste(2, array('expire_date' => 1344803344));
+        $paste   = Helper::getPaste(2, array('expire_date' => time() + 3600));
         $keys    = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'x', 'y', 'z');
         $ids     = array();
         foreach ($keys as $key) {
-            $ids[$key] = substr(md5($key), 0, 16);
+            $ids[$key] = hash('fnv1a64', $key);
             $this->_model->delete($ids[$key]);
             $this->assertFalse($this->_model->exists($ids[$key]), "paste $key does not yet exist");
             if (in_array($key, array('y', 'z'))) {
@@ -243,11 +253,11 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
         $this->_options['tbl'] = 'bar_';
         $model                 = Database::getInstance($this->_options);
 
-        $original                        = $paste                        = Helper::getPasteWithAttachment(array('expire_date' => 1344803344));
-        $paste['meta']['attachment']     = $paste['attachment'];
-        $paste['meta']['attachmentname'] = $paste['attachmentname'];
+        $original               = $paste = Helper::getPasteWithAttachment(1, array('expire_date' => 1344803344));
+        $meta                   = $paste['meta'];
+        $meta['attachment']     = $paste['attachment'];
+        $meta['attachmentname'] = $paste['attachmentname'];
         unset($paste['attachment'], $paste['attachmentname']);
-        $meta = $paste['meta'];
 
         $db = new PDO(
             $this->_options['dsn'],
@@ -261,7 +271,7 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
                 Helper::getPasteId(),
                 $paste['data'],
                 $paste['meta']['postdate'],
-                1344803344,
+                $paste['meta']['expire_date'],
                 0,
                 0,
                 json_encode($meta),