mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 13:12:41 +00:00
Make database test helpers generic
This commit is contained in:
parent
12ef3e649f
commit
2628ff7bf4
13 changed files with 218 additions and 222 deletions
|
@ -8,11 +8,7 @@ namespace JKingWeb\Arsse\TestCase\Database;
|
|||
|
||||
use JKingWeb\Arsse\Test\Database;
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Conf;
|
||||
use JKingWeb\Arsse\User;
|
||||
use JKingWeb\Arsse\Misc\ValueInfo;
|
||||
use JKingWeb\Arsse\Db\Result;
|
||||
use JKingWeb\Arsse\Test\DatabaseInformation;
|
||||
use Phake;
|
||||
|
||||
abstract class Base extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
|
@ -84,7 +80,7 @@ abstract class Base extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->$setUp();
|
||||
// prime the database with series data if it hasn't already been done
|
||||
if (!$this->primed && isset($this->data)) {
|
||||
$this->primeDatabase($this->data);
|
||||
$this->primeDatabase(static::$drv, $this->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,121 +107,4 @@ abstract class Base extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
static::$failureReason = "";
|
||||
static::clearData();
|
||||
}
|
||||
|
||||
public function primeDatabase(array $data): bool {
|
||||
$drv = static::$drv;
|
||||
$tr = $drv->begin();
|
||||
foreach ($data as $table => $info) {
|
||||
$cols = array_map(function($v) {
|
||||
return '"'.str_replace('"', '""', $v).'"';
|
||||
}, array_keys($info['columns']));
|
||||
$cols = implode(",", $cols);
|
||||
$bindings = array_values($info['columns']);
|
||||
$params = implode(",", array_fill(0, sizeof($info['columns']), "?"));
|
||||
$s = $drv->prepareArray("INSERT INTO $table($cols) values($params)", $bindings);
|
||||
foreach ($info['rows'] as $row) {
|
||||
$s->runArray($row);
|
||||
}
|
||||
}
|
||||
$tr->commit();
|
||||
$this->primed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function compareExpectations(array $expected): bool {
|
||||
foreach ($expected as $table => $info) {
|
||||
$cols = array_map(function($v) {
|
||||
return '"'.str_replace('"', '""', $v).'"';
|
||||
}, array_keys($info['columns']));
|
||||
$cols = implode(",", $cols);
|
||||
$types = $info['columns'];
|
||||
$data = static::$drv->prepare("SELECT $cols from $table")->run()->getAll();
|
||||
$cols = array_keys($info['columns']);
|
||||
foreach ($info['rows'] as $index => $row) {
|
||||
$this->assertCount(sizeof($cols), $row, "The number of values for array index $index does not match the number of fields");
|
||||
$row = array_combine($cols, $row);
|
||||
foreach ($data as $index => $test) {
|
||||
foreach ($test as $col => $value) {
|
||||
switch ($types[$col]) {
|
||||
case "datetime":
|
||||
$test[$col] = $this->approximateTime($row[$col], $value);
|
||||
break;
|
||||
case "int":
|
||||
$test[$col] = ValueInfo::normalize($value, ValueInfo::T_INT | ValueInfo::M_DROP | valueInfo::M_NULL);
|
||||
break;
|
||||
case "float":
|
||||
$test[$col] = ValueInfo::normalize($value, ValueInfo::T_FLOAT | ValueInfo::M_DROP | valueInfo::M_NULL);
|
||||
break;
|
||||
case "bool":
|
||||
$test[$col] = (int) ValueInfo::normalize($value, ValueInfo::T_BOOL | ValueInfo::M_DROP | valueInfo::M_NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($row===$test) {
|
||||
$data[$index] = $test;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->assertContains($row, $data, "Table $table does not contain record at array index $index.");
|
||||
$found = array_search($row, $data, true);
|
||||
unset($data[$found]);
|
||||
}
|
||||
$this->assertSame([], $data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function primeExpectations(array $source, array $tableSpecs = null): array {
|
||||
$out = [];
|
||||
foreach ($tableSpecs as $table => $columns) {
|
||||
// make sure the source has the table we want
|
||||
$this->assertArrayHasKey($table, $source, "Source for expectations does not contain requested table $table.");
|
||||
$out[$table] = [
|
||||
'columns' => [],
|
||||
'rows' => array_fill(0, sizeof($source[$table]['rows']), []),
|
||||
];
|
||||
// make sure the source has all the columns we want for the table
|
||||
$cols = array_flip($columns);
|
||||
$cols = array_intersect_key($cols, $source[$table]['columns']);
|
||||
$this->assertSame(array_keys($cols), $columns, "Source for table $table does not contain all requested columns");
|
||||
// get a map of source value offsets and keys
|
||||
$targets = array_flip(array_keys($source[$table]['columns']));
|
||||
foreach ($cols as $key => $order) {
|
||||
// fill the column-spec
|
||||
$out[$table]['columns'][$key] = $source[$table]['columns'][$key];
|
||||
foreach ($source[$table]['rows'] as $index => $row) {
|
||||
// fill each row column-wise with re-ordered values
|
||||
$out[$table]['rows'][$index][$order] = $row[$targets[$key]];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function assertResult(array $expected, Result $data) {
|
||||
$data = $data->getAll();
|
||||
$this->assertCount(sizeof($expected), $data, "Number of result rows (".sizeof($data).") differs from number of expected rows (".sizeof($expected).")");
|
||||
if (sizeof($expected)) {
|
||||
// make sure the expectations are consistent
|
||||
foreach ($expected as $exp) {
|
||||
if (!isset($keys)) {
|
||||
$keys = $exp;
|
||||
continue;
|
||||
}
|
||||
$this->assertSame(array_keys($keys), array_keys($exp), "Result set expectations are irregular");
|
||||
}
|
||||
// filter the result set to contain just the desired keys (we don't care if the result has extra keys)
|
||||
$rows = [];
|
||||
foreach ($data as $row) {
|
||||
$rows[] = array_intersect_key($row, $keys);
|
||||
}
|
||||
// compare the result set to the expectations
|
||||
foreach ($rows as $row) {
|
||||
$this->assertContains($row, $expected, "Result set contains unexpected record.");
|
||||
$found = array_search($row, $expected);
|
||||
unset($expected[$found]);
|
||||
}
|
||||
$this->assertArraySubset($expected, [], false, "Expectations not in result set.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -581,7 +581,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][9][4] = $now;
|
||||
$state['arsse_marks']['rows'][11][2] = 0;
|
||||
$state['arsse_marks']['rows'][11][4] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesRead() {
|
||||
|
@ -596,7 +596,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][] = [13,6,1,0,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,7,1,0,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,8,1,0,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesUnstarred() {
|
||||
|
@ -607,7 +607,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][10][4] = $now;
|
||||
$state['arsse_marks']['rows'][11][3] = 0;
|
||||
$state['arsse_marks']['rows'][11][4] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesStarred() {
|
||||
|
@ -622,7 +622,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][] = [13,6,0,1,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,8,0,1,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesUnreadAndUnstarred() {
|
||||
|
@ -636,7 +636,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][11][2] = 0;
|
||||
$state['arsse_marks']['rows'][11][3] = 0;
|
||||
$state['arsse_marks']['rows'][11][4] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesReadAndStarred() {
|
||||
|
@ -654,7 +654,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][] = [13,6,1,1,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,7,1,1,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,8,1,1,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesUnreadAndStarred() {
|
||||
|
@ -672,7 +672,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][] = [13,6,0,1,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,8,0,1,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAllArticlesReadAndUnstarred() {
|
||||
|
@ -690,7 +690,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][] = [13,6,1,0,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,7,1,0,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,8,1,0,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testSetNoteForAllArticles() {
|
||||
|
@ -709,7 +709,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][] = [13,6,0,0,$now,'New note'];
|
||||
$state['arsse_marks']['rows'][] = [14,7,0,0,$now,'New note'];
|
||||
$state['arsse_marks']['rows'][] = [14,8,0,0,$now,'New note'];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkATreeFolder() {
|
||||
|
@ -720,7 +720,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][] = [13,6,1,0,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,7,1,0,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,8,1,0,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkALeafFolder() {
|
||||
|
@ -729,7 +729,7 @@ trait SeriesArticle {
|
|||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$state['arsse_marks']['rows'][] = [13,5,1,0,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [13,6,1,0,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAMissingFolder() {
|
||||
|
@ -743,7 +743,7 @@ trait SeriesArticle {
|
|||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$state['arsse_marks']['rows'][] = [13,5,1,0,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [13,6,1,0,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAMissingSubscription() {
|
||||
|
@ -757,7 +757,7 @@ trait SeriesArticle {
|
|||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$state['arsse_marks']['rows'][9][3] = 1;
|
||||
$state['arsse_marks']['rows'][9][4] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleArticles() {
|
||||
|
@ -767,7 +767,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][9][3] = 1;
|
||||
$state['arsse_marks']['rows'][9][4] = $now;
|
||||
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleArticlessUnreadAndStarred() {
|
||||
|
@ -780,7 +780,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][11][2] = 0;
|
||||
$state['arsse_marks']['rows'][11][4] = $now;
|
||||
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkTooFewMultipleArticles() {
|
||||
|
@ -803,7 +803,7 @@ trait SeriesArticle {
|
|||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$state['arsse_marks']['rows'][9][3] = 1;
|
||||
$state['arsse_marks']['rows'][9][4] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleEditions() {
|
||||
|
@ -813,13 +813,13 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][9][3] = 1;
|
||||
$state['arsse_marks']['rows'][9][4] = $now;
|
||||
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleMissingEditions() {
|
||||
$this->assertSame(0, Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->editions([500,501])));
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleEditionsUnread() {
|
||||
|
@ -830,7 +830,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][9][4] = $now;
|
||||
$state['arsse_marks']['rows'][11][2] = 0;
|
||||
$state['arsse_marks']['rows'][11][4] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleEditionsUnreadWithStale() {
|
||||
|
@ -839,7 +839,7 @@ trait SeriesArticle {
|
|||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$state['arsse_marks']['rows'][11][2] = 0;
|
||||
$state['arsse_marks']['rows'][11][4] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkMultipleEditionsUnreadAndStarredWithStale() {
|
||||
|
@ -851,7 +851,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][11][2] = 0;
|
||||
$state['arsse_marks']['rows'][11][4] = $now;
|
||||
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkTooFewMultipleEditions() {
|
||||
|
@ -866,7 +866,7 @@ trait SeriesArticle {
|
|||
public function testMarkAStaleEditionUnread() {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->edition(20)); // no changes occur
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAStaleEditionStarred() {
|
||||
|
@ -875,7 +875,7 @@ trait SeriesArticle {
|
|||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$state['arsse_marks']['rows'][9][3] = 1;
|
||||
$state['arsse_marks']['rows'][9][4] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAStaleEditionUnreadAndStarred() {
|
||||
|
@ -884,13 +884,13 @@ trait SeriesArticle {
|
|||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$state['arsse_marks']['rows'][9][3] = 1;
|
||||
$state['arsse_marks']['rows'][9][4] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAStaleEditionUnreadAndUnstarred() {
|
||||
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>false], (new Context)->edition(20)); // no changes occur
|
||||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkAMissingEdition() {
|
||||
|
@ -906,7 +906,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][8][4] = $now;
|
||||
$state['arsse_marks']['rows'][9][3] = 1;
|
||||
$state['arsse_marks']['rows'][9][4] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkByLatestEdition() {
|
||||
|
@ -919,7 +919,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][] = [13,6,0,1,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,8,0,1,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkByLastMarked() {
|
||||
|
@ -930,7 +930,7 @@ trait SeriesArticle {
|
|||
$state['arsse_marks']['rows'][8][4] = $now;
|
||||
$state['arsse_marks']['rows'][9][3] = 1;
|
||||
$state['arsse_marks']['rows'][9][4] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkByNotLastMarked() {
|
||||
|
@ -939,7 +939,7 @@ trait SeriesArticle {
|
|||
$state = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$state['arsse_marks']['rows'][] = [13,5,0,1,$now,''];
|
||||
$state['arsse_marks']['rows'][] = [14,7,0,1,$now,''];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMarkArticlesWithoutAuthority() {
|
||||
|
|
|
@ -161,7 +161,7 @@ trait SeriesCleanup {
|
|||
$state['arsse_feeds']['rows'][0][1] = null;
|
||||
unset($state['arsse_feeds']['rows'][1]);
|
||||
$state['arsse_feeds']['rows'][2][1] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpOrphanedFeedsWithUnlimitedRetention() {
|
||||
|
@ -175,7 +175,7 @@ trait SeriesCleanup {
|
|||
]);
|
||||
$state['arsse_feeds']['rows'][0][1] = null;
|
||||
$state['arsse_feeds']['rows'][2][1] = $now;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpOldArticlesWithStandardRetention() {
|
||||
|
@ -186,7 +186,7 @@ trait SeriesCleanup {
|
|||
foreach ([7,8,9] as $id) {
|
||||
unset($state['arsse_articles']['rows'][$id - 1]);
|
||||
}
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpOldArticlesWithUnlimitedReadRetention() {
|
||||
|
@ -200,7 +200,7 @@ trait SeriesCleanup {
|
|||
foreach ([7,8] as $id) {
|
||||
unset($state['arsse_articles']['rows'][$id - 1]);
|
||||
}
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpOldArticlesWithUnlimitedUnreadRetention() {
|
||||
|
@ -214,7 +214,7 @@ trait SeriesCleanup {
|
|||
foreach ([9] as $id) {
|
||||
unset($state['arsse_articles']['rows'][$id - 1]);
|
||||
}
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpOldArticlesWithUnlimitedRetention() {
|
||||
|
@ -226,7 +226,7 @@ trait SeriesCleanup {
|
|||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_articles' => ["id"]
|
||||
]);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpExpiredSessions() {
|
||||
|
@ -237,7 +237,7 @@ trait SeriesCleanup {
|
|||
foreach ([3,4,5] as $id) {
|
||||
unset($state['arsse_sessions']['rows'][$id - 1]);
|
||||
}
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCleanUpExpiredTokens() {
|
||||
|
@ -248,6 +248,6 @@ trait SeriesCleanup {
|
|||
foreach ([2] as $id) {
|
||||
unset($state['arsse_tokens']['rows'][$id - 1]);
|
||||
}
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,7 +204,7 @@ trait SeriesFeed {
|
|||
$state['arsse_marks']['rows'][3] = [6,4,0,0,$now];
|
||||
$state['arsse_marks']['rows'][6] = [1,3,0,0,$now];
|
||||
$state['arsse_feeds']['rows'][0] = [1,6];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
// update a valid feed which previously had an error
|
||||
Arsse::$db->feedUpdate(2);
|
||||
// update an erroneous feed which previously had no errors
|
||||
|
@ -214,12 +214,12 @@ trait SeriesFeed {
|
|||
]);
|
||||
$state['arsse_feeds']['rows'][1] = [2,0,""];
|
||||
$state['arsse_feeds']['rows'][2] = [3,1,'Feed URL "http://localhost:8000/Feed/Fetching/Error?code=404" is invalid'];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
// update the bad feed again, twice
|
||||
Arsse::$db->feedUpdate(3);
|
||||
Arsse::$db->feedUpdate(3);
|
||||
$state['arsse_feeds']['rows'][2] = [3,3,'Feed URL "http://localhost:8000/Feed/Fetching/Error?code=404" is invalid'];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testUpdateAMissingFeed() {
|
||||
|
@ -254,7 +254,7 @@ trait SeriesFeed {
|
|||
["Bodybuilders"],
|
||||
["Men"],
|
||||
];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testListStaleFeeds() {
|
||||
|
|
|
@ -105,7 +105,7 @@ trait SeriesFolder {
|
|||
Phake::verify(Arsse::$user)->authorize($user, "folderAdd");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
|
||||
$state['arsse_folders']['rows'][] = [$folderID, $user, null, "Entertainment"];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddADuplicateRootFolder() {
|
||||
|
@ -120,7 +120,7 @@ trait SeriesFolder {
|
|||
Phake::verify(Arsse::$user)->authorize($user, "folderAdd");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
|
||||
$state['arsse_folders']['rows'][] = [$folderID, $user, 2, "GNOME"];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddANestedFolderToAMissingParent() {
|
||||
|
@ -218,7 +218,7 @@ trait SeriesFolder {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderRemove");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
|
||||
array_pop($state['arsse_folders']['rows']);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAFolderTree() {
|
||||
|
@ -228,7 +228,7 @@ trait SeriesFolder {
|
|||
foreach ([0,1,2,5] as $index) {
|
||||
unset($state['arsse_folders']['rows'][$index]);
|
||||
}
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAMissingFolder() {
|
||||
|
@ -292,7 +292,7 @@ trait SeriesFolder {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
|
||||
$state['arsse_folders']['rows'][5][3] = "Opinion";
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRenameTheRootFolder() {
|
||||
|
@ -319,7 +319,7 @@ trait SeriesFolder {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
|
||||
$state['arsse_folders']['rows'][5][2] = 5; // parent should have changed
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMoveTheRootFolder() {
|
||||
|
|
|
@ -257,7 +257,7 @@ trait SeriesLabel {
|
|||
Phake::verify(Arsse::$user)->authorize($user, "labelAdd");
|
||||
$state = $this->primeExpectations($this->data, $this->checkLabels);
|
||||
$state['arsse_labels']['rows'][] = [$labelID, $user, "Entertaining"];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddADuplicateLabel() {
|
||||
|
@ -313,7 +313,7 @@ trait SeriesLabel {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove");
|
||||
$state = $this->primeExpectations($this->data, $this->checkLabels);
|
||||
array_shift($state['arsse_labels']['rows']);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveALabelByName() {
|
||||
|
@ -321,7 +321,7 @@ trait SeriesLabel {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove");
|
||||
$state = $this->primeExpectations($this->data, $this->checkLabels);
|
||||
array_shift($state['arsse_labels']['rows']);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAMissingLabel() {
|
||||
|
@ -397,7 +397,7 @@ trait SeriesLabel {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, $this->checkLabels);
|
||||
$state['arsse_labels']['rows'][0][2] = "Curious";
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRenameALabelByName() {
|
||||
|
@ -405,7 +405,7 @@ trait SeriesLabel {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, $this->checkLabels);
|
||||
$state['arsse_labels']['rows'][0][2] = "Curious";
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRenameALabelToTheEmptyString() {
|
||||
|
@ -487,14 +487,14 @@ trait SeriesLabel {
|
|||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_label_members']['rows'][4][3] = 1;
|
||||
$state['arsse_label_members']['rows'][] = [1,2,1,1];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearALabelFromArticles() {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([1,5]), Database::ASSOC_REMOVE);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_label_members']['rows'][0][3] = 0;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyALabelToArticlesByName() {
|
||||
|
@ -502,26 +502,26 @@ trait SeriesLabel {
|
|||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_label_members']['rows'][4][3] = 1;
|
||||
$state['arsse_label_members']['rows'][] = [1,2,1,1];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearALabelFromArticlesByName() {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", "Interesting", (new Context)->articles([1,5]), Database::ASSOC_REMOVE, true);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_label_members']['rows'][0][3] = 0;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyALabelToNoArticles() {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([10000]));
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearALabelFromNoArticles() {
|
||||
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([10000]), Database::ASSOC_REMOVE);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testReplaceArticlesOfALabel() {
|
||||
|
@ -531,7 +531,7 @@ trait SeriesLabel {
|
|||
$state['arsse_label_members']['rows'][2][3] = 0;
|
||||
$state['arsse_label_members']['rows'][4][3] = 1;
|
||||
$state['arsse_label_members']['rows'][] = [1,2,1,1];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testPurgeArticlesOfALabel() {
|
||||
|
@ -539,7 +539,7 @@ trait SeriesLabel {
|
|||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_label_members']['rows'][0][3] = 0;
|
||||
$state['arsse_label_members']['rows'][2][3] = 0;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyALabelToArticlesWithoutAuthority() {
|
||||
|
|
|
@ -28,7 +28,7 @@ trait SeriesMeta {
|
|||
// as far as tests are concerned the schema version is part of the expectations primed into the database
|
||||
array_unshift($this->data['arsse_meta']['rows'], ['schema_version', "".Database::SCHEMA_VERSION]);
|
||||
// but it's already been inserted by the driver, so we prime without it
|
||||
$this->primeDatabase($dataBare);
|
||||
$this->primeDatabase(static::$drv, $dataBare);
|
||||
}
|
||||
|
||||
protected function tearDownSeriesMeta() {
|
||||
|
@ -39,7 +39,7 @@ trait SeriesMeta {
|
|||
$this->assertTrue(Arsse::$db->metaSet("favourite", "Cygnus X-1"));
|
||||
$state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]);
|
||||
$state['arsse_meta']['rows'][] = ["favourite","Cygnus X-1"];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddANewTypedValue() {
|
||||
|
@ -52,14 +52,14 @@ trait SeriesMeta {
|
|||
$state['arsse_meta']['rows'][] = ["true","1"];
|
||||
$state['arsse_meta']['rows'][] = ["false","0"];
|
||||
$state['arsse_meta']['rows'][] = ["millennium","2000-01-01 00:00:00"];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testChangeAnExistingValue() {
|
||||
$this->assertTrue(Arsse::$db->metaSet("album", "Hemispheres"));
|
||||
$state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]);
|
||||
$state['arsse_meta']['rows'][1][1] = "Hemispheres";
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAValue() {
|
||||
|
@ -67,7 +67,7 @@ trait SeriesMeta {
|
|||
$this->assertFalse(Arsse::$db->metaRemove("album"));
|
||||
$state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]);
|
||||
unset($state['arsse_meta']['rows'][1]);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRetrieveAValue() {
|
||||
|
|
|
@ -69,7 +69,7 @@ trait SeriesSession {
|
|||
// sessions near timeout should be refreshed automatically
|
||||
$state = $this->primeExpectations($this->data, ['arsse_sessions' => ["id", "created", "expires", "user"]]);
|
||||
$state['arsse_sessions']['rows'][3][2] = Date::transform(Date::add(Arsse::$conf->userSessionTimeout, $now), "sql");
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
// session resumption should not check authorization
|
||||
Phake::when(Arsse::$user)->authorize->thenReturn(false);
|
||||
$this->assertArraySubset($exp1, Arsse::$db->sessionResume("80fa94c1a11f11e78667001e673b2560"));
|
||||
|
@ -96,7 +96,7 @@ trait SeriesSession {
|
|||
$now = time();
|
||||
$state = $this->primeExpectations($this->data, ['arsse_sessions' => ["id", "created", "expires", "user"]]);
|
||||
$state['arsse_sessions']['rows'][] = [$id, Date::transform($now, "sql"), Date::transform(Date::add(Arsse::$conf->userSessionTimeout, $now), "sql"), $user];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCreateASessionWithoutAuthority() {
|
||||
|
@ -111,7 +111,7 @@ trait SeriesSession {
|
|||
$this->assertTrue(Arsse::$db->sessionDestroy($user, $id));
|
||||
$state = $this->primeExpectations($this->data, ['arsse_sessions' => ["id", "created", "expires", "user"]]);
|
||||
unset($state['arsse_sessions']['rows'][0]);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
// destroying a session which does not exist is not an error
|
||||
$this->assertFalse(Arsse::$db->sessionDestroy($user, $id));
|
||||
}
|
||||
|
|
|
@ -160,7 +160,7 @@ trait SeriesSubscription {
|
|||
'arsse_subscriptions' => ['id','owner','feed'],
|
||||
]);
|
||||
$state['arsse_subscriptions']['rows'][] = [$subID,$this->user,1];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddASubscriptionToANewFeed() {
|
||||
|
@ -177,7 +177,7 @@ trait SeriesSubscription {
|
|||
]);
|
||||
$state['arsse_feeds']['rows'][] = [$feedID,$url,"",""];
|
||||
$state['arsse_subscriptions']['rows'][] = [$subID,$this->user,$feedID];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddASubscriptionToANewFeedViaDiscovery() {
|
||||
|
@ -195,7 +195,7 @@ trait SeriesSubscription {
|
|||
]);
|
||||
$state['arsse_feeds']['rows'][] = [$feedID,$discovered,"",""];
|
||||
$state['arsse_subscriptions']['rows'][] = [$subID,$this->user,$feedID];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddASubscriptionToAnInvalidFeed() {
|
||||
|
@ -211,7 +211,7 @@ trait SeriesSubscription {
|
|||
'arsse_feeds' => ['id','url','username','password'],
|
||||
'arsse_subscriptions' => ['id','owner','feed'],
|
||||
]);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
$this->assertException("invalidUrl", "Feed");
|
||||
throw $e;
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ trait SeriesSubscription {
|
|||
'arsse_subscriptions' => ['id','owner','feed'],
|
||||
]);
|
||||
array_shift($state['arsse_subscriptions']['rows']);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAMissingSubscription() {
|
||||
|
@ -377,15 +377,15 @@ trait SeriesSubscription {
|
|||
'arsse_subscriptions' => ['id','owner','feed','title','folder','pinned','order_type'],
|
||||
]);
|
||||
$state['arsse_subscriptions']['rows'][0] = [1,"john.doe@example.com",2,"Ook Ook",3,0,0];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
Arsse::$db->subscriptionPropertiesSet($this->user, 1, [
|
||||
'title' => null,
|
||||
]);
|
||||
$state['arsse_subscriptions']['rows'][0] = [1,"john.doe@example.com",2,null,3,0,0];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
// making no changes is a valid result
|
||||
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['unhinged' => true]);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testMoveASubscriptionToAMissingFolder() {
|
||||
|
|
|
@ -117,7 +117,7 @@ trait SeriesTag {
|
|||
Phake::verify(Arsse::$user)->authorize($user, "tagAdd");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTags);
|
||||
$state['arsse_tags']['rows'][] = [$tagID, $user, "Entertaining"];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddADuplicateTag() {
|
||||
|
@ -173,7 +173,7 @@ trait SeriesTag {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTags);
|
||||
array_shift($state['arsse_tags']['rows']);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveATagByName() {
|
||||
|
@ -181,7 +181,7 @@ trait SeriesTag {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTags);
|
||||
array_shift($state['arsse_tags']['rows']);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAMissingTag() {
|
||||
|
@ -255,7 +255,7 @@ trait SeriesTag {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTags);
|
||||
$state['arsse_tags']['rows'][0][2] = "Curious";
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRenameATagByName() {
|
||||
|
@ -263,7 +263,7 @@ trait SeriesTag {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet");
|
||||
$state = $this->primeExpectations($this->data, $this->checkTags);
|
||||
$state['arsse_tags']['rows'][0][2] = "Curious";
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRenameATagToTheEmptyString() {
|
||||
|
@ -345,14 +345,14 @@ trait SeriesTag {
|
|||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_tag_members']['rows'][1][2] = 1;
|
||||
$state['arsse_tag_members']['rows'][] = [1,4,1];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearATagFromSubscriptions() {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [1,3], Database::ASSOC_REMOVE);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_tag_members']['rows'][0][2] = 0;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyATagToSubscriptionsByName() {
|
||||
|
@ -360,26 +360,26 @@ trait SeriesTag {
|
|||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_tag_members']['rows'][1][2] = 1;
|
||||
$state['arsse_tag_members']['rows'][] = [1,4,1];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearATagFromSubscriptionsByName() {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [1,3], Database::ASSOC_REMOVE, true);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_tag_members']['rows'][0][2] = 0;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyATagToNoSubscriptionsByName() {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [], Database::ASSOC_ADD, true);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testClearATagFromNoSubscriptionsByName() {
|
||||
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [], Database::ASSOC_REMOVE, true);
|
||||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testReplaceSubscriptionsOfATag() {
|
||||
|
@ -389,7 +389,7 @@ trait SeriesTag {
|
|||
$state['arsse_tag_members']['rows'][1][2] = 1;
|
||||
$state['arsse_tag_members']['rows'][2][2] = 0;
|
||||
$state['arsse_tag_members']['rows'][] = [1,4,1];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testPurgeSubscriptionsOfATag() {
|
||||
|
@ -397,7 +397,7 @@ trait SeriesTag {
|
|||
$state = $this->primeExpectations($this->data, $this->checkMembers);
|
||||
$state['arsse_tag_members']['rows'][0][2] = 0;
|
||||
$state['arsse_tag_members']['rows'][2][2] = 0;
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testApplyATagToSubscriptionsWithoutAuthority() {
|
||||
|
|
|
@ -87,13 +87,13 @@ trait SeriesToken {
|
|||
$state = $this->primeExpectations($this->data, ['arsse_tokens' => ["id", "class", "expires", "user"]]);
|
||||
$id = Arsse::$db->tokenCreate($user, "fever.login");
|
||||
$state['arsse_tokens']['rows'][] = [$id, "fever.login", null, $user];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
$id = Arsse::$db->tokenCreate($user, "fever.login", null, new \DateTime("2020-01-01T00:00:00Z"));
|
||||
$state['arsse_tokens']['rows'][] = [$id, "fever.login", "2020-01-01 00:00:00", $user];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
Arsse::$db->tokenCreate($user, "fever.login", "token!", new \DateTime("2021-01-01T00:00:00Z"));
|
||||
$state['arsse_tokens']['rows'][] = ["token!", "fever.login", "2021-01-01 00:00:00", $user];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testCreateATokenForAMissingUser() {
|
||||
|
@ -113,7 +113,7 @@ trait SeriesToken {
|
|||
$this->assertTrue(Arsse::$db->tokenRevoke($user, "fever.login", $id));
|
||||
$state = $this->primeExpectations($this->data, ['arsse_tokens' => ["id", "expires", "user"]]);
|
||||
unset($state['arsse_tokens']['rows'][0]);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
// revoking a token which does not exist is not an error
|
||||
$this->assertFalse(Arsse::$db->tokenRevoke($user, "fever.login", $id));
|
||||
}
|
||||
|
@ -124,10 +124,10 @@ trait SeriesToken {
|
|||
$this->assertTrue(Arsse::$db->tokenRevoke($user, "fever.login"));
|
||||
unset($state['arsse_tokens']['rows'][0]);
|
||||
unset($state['arsse_tokens']['rows'][1]);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
$this->assertTrue(Arsse::$db->tokenRevoke($user, "class.class"));
|
||||
unset($state['arsse_tokens']['rows'][2]);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
// revoking tokens which do not exist is not an error
|
||||
$this->assertFalse(Arsse::$db->tokenRevoke($user, "unknown.class"));
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ trait SeriesUser {
|
|||
$this->assertFalse(Arsse::$db->userExists("jane.doe@example.org"));
|
||||
Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "userExists");
|
||||
Phake::verify(Arsse::$user)->authorize("jane.doe@example.org", "userExists");
|
||||
$this->compareExpectations($this->data);
|
||||
$this->compareExpectations(static::$drv, $this->data);
|
||||
}
|
||||
|
||||
public function testCheckThatAUserExistsWithoutAuthority() {
|
||||
|
@ -68,7 +68,7 @@ trait SeriesUser {
|
|||
Phake::verify(Arsse::$user)->authorize("john.doe@example.org", "userAdd");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]);
|
||||
$state['arsse_users']['rows'][] = ["john.doe@example.org"];
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testAddAnExistingUser() {
|
||||
|
@ -87,7 +87,7 @@ trait SeriesUser {
|
|||
Phake::verify(Arsse::$user)->authorize("admin@example.net", "userRemove");
|
||||
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]);
|
||||
array_shift($state['arsse_users']['rows']);
|
||||
$this->compareExpectations($state);
|
||||
$this->compareExpectations(static::$drv, $state);
|
||||
}
|
||||
|
||||
public function testRemoveAMissingUser() {
|
||||
|
|
|
@ -9,14 +9,15 @@ namespace JKingWeb\Arsse\Test;
|
|||
use JKingWeb\Arsse\Exception;
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Conf;
|
||||
use JKingWeb\Arsse\CLI;
|
||||
use JKingWeb\Arsse\Db\Driver;
|
||||
use JKingWeb\Arsse\Db\Result;
|
||||
use JKingWeb\Arsse\Misc\Date;
|
||||
use JKingWeb\Arsse\Misc\ValueInfo;
|
||||
use Psr\Http\Message\MessageInterface;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Zend\Diactoros\Response\JsonResponse;
|
||||
use Zend\Diactoros\Response\EmptyResponse;
|
||||
|
||||
/** @coversNothing */
|
||||
abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
||||
|
@ -135,4 +136,120 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function primeDatabase(Driver $drv, array $data): bool {
|
||||
$tr = $drv->begin();
|
||||
foreach ($data as $table => $info) {
|
||||
$cols = array_map(function($v) {
|
||||
return '"'.str_replace('"', '""', $v).'"';
|
||||
}, array_keys($info['columns']));
|
||||
$cols = implode(",", $cols);
|
||||
$bindings = array_values($info['columns']);
|
||||
$params = implode(",", array_fill(0, sizeof($info['columns']), "?"));
|
||||
$s = $drv->prepareArray("INSERT INTO $table($cols) values($params)", $bindings);
|
||||
foreach ($info['rows'] as $row) {
|
||||
$s->runArray($row);
|
||||
}
|
||||
}
|
||||
$tr->commit();
|
||||
$this->primed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function compareExpectations(Driver $drv, array $expected): bool {
|
||||
foreach ($expected as $table => $info) {
|
||||
$cols = array_map(function($v) {
|
||||
return '"'.str_replace('"', '""', $v).'"';
|
||||
}, array_keys($info['columns']));
|
||||
$cols = implode(",", $cols);
|
||||
$types = $info['columns'];
|
||||
$data = $drv->prepare("SELECT $cols from $table")->run()->getAll();
|
||||
$cols = array_keys($info['columns']);
|
||||
foreach ($info['rows'] as $index => $row) {
|
||||
$this->assertCount(sizeof($cols), $row, "The number of values for array index $index does not match the number of fields");
|
||||
$row = array_combine($cols, $row);
|
||||
foreach ($data as $index => $test) {
|
||||
foreach ($test as $col => $value) {
|
||||
switch ($types[$col]) {
|
||||
case "datetime":
|
||||
$test[$col] = $this->approximateTime($row[$col], $value);
|
||||
break;
|
||||
case "int":
|
||||
$test[$col] = ValueInfo::normalize($value, ValueInfo::T_INT | ValueInfo::M_DROP | valueInfo::M_NULL);
|
||||
break;
|
||||
case "float":
|
||||
$test[$col] = ValueInfo::normalize($value, ValueInfo::T_FLOAT | ValueInfo::M_DROP | valueInfo::M_NULL);
|
||||
break;
|
||||
case "bool":
|
||||
$test[$col] = (int) ValueInfo::normalize($value, ValueInfo::T_BOOL | ValueInfo::M_DROP | valueInfo::M_NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($row===$test) {
|
||||
$data[$index] = $test;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->assertContains($row, $data, "Table $table does not contain record at array index $index.");
|
||||
$found = array_search($row, $data, true);
|
||||
unset($data[$found]);
|
||||
}
|
||||
$this->assertSame([], $data);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function primeExpectations(array $source, array $tableSpecs = null): array {
|
||||
$out = [];
|
||||
foreach ($tableSpecs as $table => $columns) {
|
||||
// make sure the source has the table we want
|
||||
$this->assertArrayHasKey($table, $source, "Source for expectations does not contain requested table $table.");
|
||||
$out[$table] = [
|
||||
'columns' => [],
|
||||
'rows' => array_fill(0, sizeof($source[$table]['rows']), []),
|
||||
];
|
||||
// make sure the source has all the columns we want for the table
|
||||
$cols = array_flip($columns);
|
||||
$cols = array_intersect_key($cols, $source[$table]['columns']);
|
||||
$this->assertSame(array_keys($cols), $columns, "Source for table $table does not contain all requested columns");
|
||||
// get a map of source value offsets and keys
|
||||
$targets = array_flip(array_keys($source[$table]['columns']));
|
||||
foreach ($cols as $key => $order) {
|
||||
// fill the column-spec
|
||||
$out[$table]['columns'][$key] = $source[$table]['columns'][$key];
|
||||
foreach ($source[$table]['rows'] as $index => $row) {
|
||||
// fill each row column-wise with re-ordered values
|
||||
$out[$table]['rows'][$index][$order] = $row[$targets[$key]];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function assertResult(array $expected, Result $data) {
|
||||
$data = $data->getAll();
|
||||
$this->assertCount(sizeof($expected), $data, "Number of result rows (".sizeof($data).") differs from number of expected rows (".sizeof($expected).")");
|
||||
if (sizeof($expected)) {
|
||||
// make sure the expectations are consistent
|
||||
foreach ($expected as $exp) {
|
||||
if (!isset($keys)) {
|
||||
$keys = $exp;
|
||||
continue;
|
||||
}
|
||||
$this->assertSame(array_keys($keys), array_keys($exp), "Result set expectations are irregular");
|
||||
}
|
||||
// filter the result set to contain just the desired keys (we don't care if the result has extra keys)
|
||||
$rows = [];
|
||||
foreach ($data as $row) {
|
||||
$rows[] = array_intersect_key($row, $keys);
|
||||
}
|
||||
// compare the result set to the expectations
|
||||
foreach ($rows as $row) {
|
||||
$this->assertContains($row, $expected, "Result set contains unexpected record.");
|
||||
$found = array_search($row, $expected);
|
||||
unset($expected[$found]);
|
||||
}
|
||||
$this->assertArraySubset($expected, [], false, "Expectations not in result set.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue