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

This commit is contained in:
El RIDO 2019-05-05 14:36:47 +02:00
parent bbdcb3fb0f
commit 6e15903f1e
No known key found for this signature in database
GPG key ID: 0F5C940A6BD81F92
3 changed files with 150 additions and 94 deletions

View file

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

View file

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

View file

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