mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2025-01-03 14:32:40 +00:00
Convert remaining usage of Phony to Phake
This commit is contained in:
parent
1cd3f29fe3
commit
f1d3055f4c
27 changed files with 705 additions and 913 deletions
|
@ -23,3 +23,5 @@ if (function_exists("xdebug_set_filter")) {
|
|||
xdebug_set_filter(\XDEBUG_FILTER_CODE_COVERAGE, XDEBUG_PATH_WHITELIST, [BASE."lib/"]);
|
||||
}
|
||||
}
|
||||
|
||||
\Phake::setClient(\Phake::CLIENT_PHPUNIT9);
|
|
@ -7,7 +7,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace JKingWeb\Arsse\TestCase\CLI;
|
||||
|
||||
use Eloquent\Phony\Phpunit\Phony;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Conf;
|
||||
|
@ -210,7 +209,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
\Phake::when(Arsse::$user)->auth->thenReturn(false);
|
||||
\Phake::when(Arsse::$user)->auth("john.doe@example.com", "secret")->thenReturn(true);
|
||||
\Phake::when(Arsse::$user)->auth("jane.doe@example.com", "superman")->thenReturn(true);
|
||||
$fever = $this->mock(FeverUser::class);
|
||||
$fever = \Phake::mock(FeverUser::class);
|
||||
\Phake::when($fever)->authenticate->thenReturn(false);
|
||||
\Phake::when($fever)->authenticate("john.doe@example.com", "ashalla")->thenReturn(true);
|
||||
\Phake::when($fever)->authenticate("jane.doe@example.com", "thx1138")->thenReturn(true);
|
||||
|
|
|
@ -211,11 +211,10 @@ trait SeriesSubscription {
|
|||
public function testAddASubscriptionToAnExistingFeed(): void {
|
||||
$url = "http://example.com/feed1";
|
||||
$subID = $this->nextID("arsse_subscriptions");
|
||||
$db = $this->partialMock(Database::class, static::$drv);
|
||||
$db->feedUpdate->returns(true);
|
||||
Arsse::$db = $db->get();
|
||||
Arsse::$db = \Phake::partialMock(Database::class, static::$drv);
|
||||
\Phake::when($db)->feedUpdate->thenReturn(true);
|
||||
$this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url));
|
||||
$db->feedUpdate->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->feedUpdate(\Phake::anyParameters());
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_feeds' => ['id','url','username','password'],
|
||||
'arsse_subscriptions' => ['id','owner','feed'],
|
||||
|
@ -232,11 +231,10 @@ trait SeriesSubscription {
|
|||
$url = "http://example.org/feed1";
|
||||
$feedID = $this->nextID("arsse_feeds");
|
||||
$subID = $this->nextID("arsse_subscriptions");
|
||||
$db = $this->partialMock(Database::class, static::$drv);
|
||||
$db->feedUpdate->returns(true);
|
||||
Arsse::$db = $db->get();
|
||||
Arsse::$db = \Phake::partialMock(Database::class, static::$drv);
|
||||
\Phake::when(Arsse::$db)->feedUpdate->thenReturn(true);
|
||||
$this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url, "", "", false));
|
||||
$db->feedUpdate->calledWith($feedID, true, false);
|
||||
\Phake::verify($db)->feedUpdate($feedID, true, false);
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_feeds' => ['id','url','username','password'],
|
||||
'arsse_subscriptions' => ['id','owner','feed'],
|
||||
|
@ -255,11 +253,10 @@ trait SeriesSubscription {
|
|||
$discovered = "http://localhost:8000/Feed/Discovery/Feed";
|
||||
$feedID = $this->nextID("arsse_feeds");
|
||||
$subID = $this->nextID("arsse_subscriptions");
|
||||
$db = $this->partialMock(Database::class, static::$drv);
|
||||
$db->feedUpdate->returns(true);
|
||||
Arsse::$db = $db->get();
|
||||
Arsse::$db = \Phake::partialMock(Database::class, static::$drv);
|
||||
\Phake::when(Arsse::$db)->feedUpdate->thenReturn(true);
|
||||
$this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url, "", "", true));
|
||||
$db->feedUpdate->calledWith($feedID, true, false);
|
||||
\Phake::verify(Arsse::$db)->feedUpdate($feedID, true, false);
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_feeds' => ['id','url','username','password'],
|
||||
'arsse_subscriptions' => ['id','owner','feed'],
|
||||
|
@ -276,14 +273,13 @@ trait SeriesSubscription {
|
|||
public function testAddASubscriptionToAnInvalidFeed(): void {
|
||||
$url = "http://example.org/feed1";
|
||||
$feedID = $this->nextID("arsse_feeds");
|
||||
$db = $this->partialMock(Database::class, static::$drv);
|
||||
$db->feedUpdate->throws(new FeedException("", ['url' => $url], $this->mockGuzzleException(ClientException::class, "", 404)));
|
||||
Arsse::$db = $db->get();
|
||||
Arsse::$db = \Phake::partialMock(Database::class, static::$drv);
|
||||
\Phake::when(Arsse::$db)->feedUpdate->thenThrow(new FeedException("", ['url' => $url], $this->mockGuzzleException(ClientException::class, "", 404)));
|
||||
$this->assertException("invalidUrl", "Feed");
|
||||
try {
|
||||
Arsse::$db->subscriptionAdd($this->user, $url, "", "", false);
|
||||
} finally {
|
||||
$db->feedUpdate->calledWith($feedID, true, false);
|
||||
\Phake::verify(Arsse::$db)->feedUpdate($feedID, true, false);
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_feeds' => ['id','url','username','password'],
|
||||
'arsse_subscriptions' => ['id','owner','feed'],
|
||||
|
|
|
@ -17,28 +17,28 @@ class TestTransaction extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$drv = $this->mock(\JKingWeb\Arsse\Db\SQLite3\Driver::class);
|
||||
$drv->savepointRelease->returns(true);
|
||||
$drv->savepointUndo->returns(true);
|
||||
$drv->savepointCreate->returns(1, 2);
|
||||
$drv = \Phake::mock(\JKingWeb\Arsse\Db\SQLite3\Driver::class);
|
||||
\Phake::when($drv)->savepointRelease->thenReturn(true);
|
||||
\Phake::when($drv)->savepointUndo->thenReturn(true);
|
||||
\Phake::when($drv)->savepointCreate->thenReturn(1, 2);
|
||||
$this->drv = $drv;
|
||||
}
|
||||
|
||||
public function testManipulateTransactions(): void {
|
||||
$drv = $this->drv->get();
|
||||
$drv = $this->drv;
|
||||
$tr1 = new Transaction($drv);
|
||||
$tr2 = new Transaction($drv);
|
||||
$this->drv->savepointCreate->twice()->called();
|
||||
\Phake::verify($this->drv, \Phake::times(2))->savepointCreate();
|
||||
$this->assertSame(1, $tr1->getIndex());
|
||||
$this->assertSame(2, $tr2->getIndex());
|
||||
unset($tr1);
|
||||
$this->drv->savepointUndo->calledWith(1);
|
||||
\Phake::verify($this->drv)->savepointUndo(1);
|
||||
unset($tr2);
|
||||
$this->drv->savepointUndo->calledWith(2);
|
||||
\Phake::verify($this->drv)->savepointUndo(2);
|
||||
}
|
||||
|
||||
public function testCloseTransactions(): void {
|
||||
$drv = $this->drv->get();
|
||||
$drv = $this->drv;
|
||||
$tr1 = new Transaction($drv);
|
||||
$tr2 = new Transaction($drv);
|
||||
$this->assertTrue($tr1->isPending());
|
||||
|
@ -46,20 +46,20 @@ class TestTransaction extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$tr1->commit();
|
||||
$this->assertFalse($tr1->isPending());
|
||||
$this->assertTrue($tr2->isPending());
|
||||
$this->drv->savepointRelease->calledWith(1);
|
||||
\Phake::verify($this->drv)->savepointRelease(1);
|
||||
$tr2->rollback();
|
||||
$this->assertFalse($tr1->isPending());
|
||||
$this->assertFalse($tr2->isPending());
|
||||
$this->drv->savepointUndo->calledWith(2);
|
||||
\Phake::verify($this->drv)->savepointUndo(2);
|
||||
}
|
||||
|
||||
public function testIgnoreRollbackErrors(): void {
|
||||
$this->drv->savepointUndo->throws(new Exception("savepointStale"));
|
||||
$drv = $this->drv->get();
|
||||
\Phake::when($this->drv)->savepointUndo->thenThrow(new Exception("savepointStale"));
|
||||
$drv = $this->drv;
|
||||
$tr1 = new Transaction($drv);
|
||||
$tr2 = new Transaction($drv);
|
||||
unset($tr1, $tr2); // no exception should bubble up
|
||||
$this->drv->savepointUndo->calledWith(1);
|
||||
$this->drv->savepointUndo->calledWith(2);
|
||||
\Phake::verify($this->drv)->savepointUndo(1);
|
||||
\Phake::verify($this->drv)->savepointUndo(2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ use JKingWeb\Arsse\Feed;
|
|||
use JKingWeb\Arsse\Database;
|
||||
use JKingWeb\Arsse\Misc\Date;
|
||||
use JKingWeb\Arsse\Test\Result;
|
||||
use Eloquent\Phony\Phpunit\Phony;
|
||||
|
||||
/**
|
||||
* @covers \JKingWeb\Arsse\Feed
|
||||
|
@ -96,13 +95,12 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->base = self::$host."Feed/";
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->feedMatchLatest->with(Phony::wildcard())->returns(new Result([]));
|
||||
$this->dbMock->feedMatchLatest->with(1, Phony::any())->returns(new Result($this->latest));
|
||||
$this->dbMock->feedMatchIds->with(Phony::wildcard())->returns(new Result([]));
|
||||
$this->dbMock->feedMatchIds->with(1, Phony::wildcard())->returns(new Result($this->others));
|
||||
$this->dbMock->feedRulesGet->returns([]);
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->feedMatchLatest->thenReturn(new Result([]));
|
||||
\Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest));
|
||||
\Phake::when(Arsse::$db)->feedMatchIds->thenReturn(new Result([]));
|
||||
\Phake::when(Arsse::$db)->feedMatchIds(1, \Phake::ignoreRemaining())->thenReturn(new Result($this->others));
|
||||
\Phake::when(Arsse::$db)->feedRulesGet->thenReturn([]);
|
||||
}
|
||||
|
||||
public function testParseAFeed(): void {
|
||||
|
@ -343,10 +341,9 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testMatchLatestArticles(): void {
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->feedMatchLatest->with(Phony::wildcard())->returns(new Result([]));
|
||||
$this->dbMock->feedMatchLatest->with(1, Phony::any())->returns(new Result($this->latest));
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->feedMatchLatest(\Phake::anyParameters())->thenReturn(new Result([]));
|
||||
\Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest));
|
||||
$f = new Feed(1, $this->base."Matching/1");
|
||||
$this->assertCount(0, $f->newItems);
|
||||
$this->assertCount(0, $f->changedItems);
|
||||
|
@ -393,7 +390,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
'jack' => ['new' => [false, true, true, false, true], 'changed' => [7 => true, 47 => true, 2112 => false, 1 => true, 42 => false]],
|
||||
'sam' => ['new' => [false, true, false, false, false], 'changed' => [7 => false, 47 => true, 2112 => false, 1 => false, 42 => false]],
|
||||
];
|
||||
$this->dbMock->feedMatchIds->returns(new Result([
|
||||
\Phake::when(Arsse::$db)->feedMatchIds->thenReturn(new Result([
|
||||
// these are the sixth through tenth entries in the feed; the title hashes have been omitted for brevity
|
||||
['id' => 7, 'guid' => '0f2a218c311e3d8105f1b075142a5d26dabf056ffc61abe77e96c8f071bbf4a7', 'edited' => null, 'url_title_hash' => "", 'url_content_hash' => '', 'title_content_hash' => ''],
|
||||
['id' => 47, 'guid' => '1c19e3b9018bc246b7414ae919ddebc88d0c575129e8c4a57b84b826c00f6db5', 'edited' => null, 'url_title_hash' => "", 'url_content_hash' => '', 'title_content_hash' => ''],
|
||||
|
@ -401,11 +398,10 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 1, 'guid' => '436070cda5713a0d9a8fdc8652c7ab142f0550697acfd5206a16c18aee355039', 'edited' => null, 'url_title_hash' => "", 'url_content_hash' => '', 'title_content_hash' => ''],
|
||||
['id' => 42, 'guid' => '1a731433a1904220ef26e731ada7262e1d5bcecae53e7b5df9e1f5713af6e5d3', 'edited' => null, 'url_title_hash' => "", 'url_content_hash' => '', 'title_content_hash' => ''],
|
||||
]));
|
||||
$this->dbMock->feedRulesGet->returns([
|
||||
\Phake::when(Arsse::$db)->feedRulesGet->thenReturn([
|
||||
'jack' => ['keep' => "", 'block' => '`A|W|J|S`u'],
|
||||
'sam' => ['keep' => "`B|T|X`u", 'block' => '`C`u'],
|
||||
]);
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
$f = new Feed(5, $this->base."Filtering/1");
|
||||
$this->assertSame($exp, $f->filteredItems);
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ class TestFile extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
// create a mock Import/Export processor with stubbed underlying import/export routines
|
||||
$this->proc = $this->partialMock(AbstractImportExport::class);
|
||||
$this->proc->export->returns("EXPORT_FILE");
|
||||
$this->proc->import->returns(true);
|
||||
$this->proc = \Phake::partialMock(AbstractImportExport::class);
|
||||
\Phake::when($this->proc)->export->thenReturn("EXPORT_FILE");
|
||||
\Phake::when($this->proc)->import->thenReturn(true);
|
||||
$this->vfs = vfsStream::setup("root", null, [
|
||||
'exportGoodFile' => "",
|
||||
'exportGoodDir' => [],
|
||||
|
@ -51,13 +51,13 @@ class TestFile extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
try {
|
||||
if ($exp instanceof \JKingWeb\Arsse\AbstractException) {
|
||||
$this->assertException($exp);
|
||||
$this->proc->get()->exportFile($path, $user, $flat);
|
||||
$this->proc->exportFile($path, $user, $flat);
|
||||
} else {
|
||||
$this->assertSame($exp, $this->proc->get()->exportFile($path, $user, $flat));
|
||||
$this->assertSame($exp, $this->proc->exportFile($path, $user, $flat));
|
||||
$this->assertSame("EXPORT_FILE", $this->vfs->getChild($file)->getContent());
|
||||
}
|
||||
} finally {
|
||||
$this->proc->export->calledWith($user, $flat);
|
||||
\Phake::verify($this->proc)->export($user, $flat);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,12 +90,12 @@ class TestFile extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
try {
|
||||
if ($exp instanceof \JKingWeb\Arsse\AbstractException) {
|
||||
$this->assertException($exp);
|
||||
$this->proc->get()->importFile($path, $user, $flat, $replace);
|
||||
$this->proc->importFile($path, $user, $flat, $replace);
|
||||
} else {
|
||||
$this->assertSame($exp, $this->proc->get()->importFile($path, $user, $flat, $replace));
|
||||
$this->assertSame($exp, $this->proc->importFile($path, $user, $flat, $replace));
|
||||
}
|
||||
} finally {
|
||||
$this->proc->import->times((int) ($exp === true))->calledWith($user, "GOOD_FILE", $flat, $replace);
|
||||
\Phake::verify($this->proc, \Phake::times((int) ($exp === true)))->import($user, "GOOD_FILE", $flat, $replace);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,9 +29,9 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
// create a mock user manager
|
||||
Arsse::$user = $this->mock(\JKingWeb\Arsse\User::class)->get();
|
||||
Arsse::$user = \Phake::mock(\JKingWeb\Arsse\User::class);
|
||||
// create a mock Import/Export processor
|
||||
$this->proc = $this->partialMock(AbstractImportExport::class);
|
||||
$this->proc = \Phake::partialMock(AbstractImportExport::class);
|
||||
// initialize an SQLite memeory database
|
||||
static::setConf();
|
||||
try {
|
||||
|
@ -150,7 +150,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function testImportForAMissingUser(): void {
|
||||
$this->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||
$this->proc->get()->import("no.one@example.com", "", false, false);
|
||||
$this->proc->import("no.one@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testImportWithInvalidFolder(): void {
|
||||
|
@ -158,9 +158,9 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
], [1 =>
|
||||
['id' => 1, 'name' => "", 'parent' => 0],
|
||||
]];
|
||||
$this->proc->parse->returns($in);
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->assertException("invalidFolderName", "ImportExport");
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, false);
|
||||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testImportWithDuplicateFolder(): void {
|
||||
|
@ -169,9 +169,9 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 1, 'name' => "New", 'parent' => 0],
|
||||
['id' => 2, 'name' => "New", 'parent' => 0],
|
||||
]];
|
||||
$this->proc->parse->returns($in);
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->assertException("invalidFolderCopy", "ImportExport");
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, false);
|
||||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testMakeNoEffectiveChanges(): void {
|
||||
|
@ -190,11 +190,11 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 5, 'name' => "Local", 'parent' => 4],
|
||||
['id' => 6, 'name' => "National", 'parent' => 4],
|
||||
]];
|
||||
$this->proc->parse->returns($in);
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$exp = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, false);
|
||||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
$this->compareExpectations($this->drv, $exp);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, true);
|
||||
$this->proc->import("john.doe@example.com", "", false, true);
|
||||
$this->compareExpectations($this->drv, $exp);
|
||||
}
|
||||
|
||||
|
@ -215,8 +215,8 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 6, 'name' => "National", 'parent' => 4],
|
||||
['id' => 7, 'name' => "Nature", 'parent' => 0], // new folder
|
||||
]];
|
||||
$this->proc->parse->returns($in);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, true);
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->proc->import("john.doe@example.com", "", false, true);
|
||||
$exp = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$exp['arsse_subscriptions']['rows'][3] = [4, "john.doe@example.com", null, 4, "CBC"];
|
||||
$exp['arsse_folders']['rows'][] = [7, "john.doe@example.com", null, "Nature"];
|
||||
|
@ -227,8 +227,8 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$in = [[
|
||||
['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 0, 'tags' => ["frequent", "cryptic"]], //one existing tag and one new one
|
||||
], []];
|
||||
$this->proc->parse->returns($in);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, false);
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
$exp = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$exp['arsse_feeds']['rows'][] = [7, "http://localhost:8000/Import/some-feed", "Some feed"]; // author-supplied and user-supplied titles differ
|
||||
$exp['arsse_subscriptions']['rows'][] = [7, "john.doe@example.com", null, 7, "Some Feed"];
|
||||
|
@ -242,9 +242,9 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$in = [[
|
||||
['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 0, 'tags' => [""]],
|
||||
], []];
|
||||
$this->proc->parse->returns($in);
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->assertException("invalidTagName", "ImportExport");
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, false);
|
||||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testReplaceData(): void {
|
||||
|
@ -253,8 +253,8 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
], [1 =>
|
||||
['id' => 1, 'name' => "Photography", 'parent' => 0],
|
||||
]];
|
||||
$this->proc->parse->returns($in);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, true);
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->proc->import("john.doe@example.com", "", false, true);
|
||||
$exp = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$exp['arsse_feeds']['rows'][] = [7, "http://localhost:8000/Import/some-feed", "Some feed"]; // author-supplied and user-supplied titles differ
|
||||
$exp['arsse_subscriptions']['rows'] = [[7, "john.doe@example.com", 4, 7, "Some Feed"]];
|
||||
|
|
|
@ -83,12 +83,11 @@ OPML_EXPORT_SERIALIZATION;
|
|||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->userExists->returns(true);
|
||||
$this->dbMock->folderList->with("john.doe@example.com")->returns(new Result($this->folders));
|
||||
$this->dbMock->subscriptionList->with("john.doe@example.com")->returns(new Result($this->subscriptions));
|
||||
$this->dbMock->tagSummarize->with("john.doe@example.com")->returns(new Result($this->tags));
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->folderList("john.doe@example.com")->thenReturn(new Result($this->folders));
|
||||
\Phake::when(Arsse::$db)->subscriptionList("john.doe@example.com")->thenReturn(new Result($this->subscriptions));
|
||||
\Phake::when(Arsse::$db)->tagSummarize("john.doe@example.com")->thenReturn(new Result($this->tags));
|
||||
}
|
||||
|
||||
public function testExportToOpml(): void {
|
||||
|
@ -100,7 +99,7 @@ OPML_EXPORT_SERIALIZATION;
|
|||
}
|
||||
|
||||
public function testExportToOpmlAMissingUser(): void {
|
||||
$this->dbMock->userExists->returns(false);
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
|
||||
$this->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||
(new OPML)->export("john.doe@example.com");
|
||||
}
|
||||
|
|
|
@ -146,29 +146,26 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
protected function req($dataGet, $dataPost = "", string $method = "POST", ?string $type = null, string $target = "", ?string $user = null): ResponseInterface {
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
$this->h = $this->hMock->get();
|
||||
$prefix = "/fever/";
|
||||
$url = $prefix.$target;
|
||||
$type = $type ?? "application/x-www-form-urlencoded";
|
||||
return $this->h->dispatch($this->serverRequest($method, $url, $prefix, [], [], $dataPost, $type, $dataGet, $user));
|
||||
return $this->hMock->dispatch($this->serverRequest($method, $url, $prefix, [], [], $dataPost, $type, $dataGet, $user));
|
||||
}
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
self::setConf();
|
||||
// create a mock user manager
|
||||
$this->userMock = $this->mock(User::class);
|
||||
$this->userMock->auth->returns(true);
|
||||
Arsse::$user = $this->userMock->get();
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
\Phake::when(Arsse::$user)->auth->thenReturn(true);
|
||||
Arsse::$user->id = $this->userId;
|
||||
// create a mock database interface
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->begin->returns($this->mock(Transaction::class));
|
||||
$this->dbMock->tokenLookup->returns(['user' => "john.doe@example.com"]);
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(Transaction::class));
|
||||
\Phake::when(Arsse::$db)->tokenLookup->thenReturn(['user' => "john.doe@example.com"]);
|
||||
// instantiate the handler as a partial mock to simplify testing
|
||||
$this->hMock = $this->partialMock(API::class);
|
||||
$this->hMock->baseResponse->returns([]);
|
||||
$this->hMock = \Phake::partialMock(API::class);
|
||||
\Phake::when($this->hMock)->baseResponse->thenReturn([]);
|
||||
}
|
||||
|
||||
/** @dataProvider provideTokenAuthenticationRequests */
|
||||
|
@ -178,13 +175,13 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
'userSessionEnforced' => $tokenEnforced,
|
||||
], true);
|
||||
Arsse::$user->id = null;
|
||||
$this->dbMock->tokenLookup->throws(new ExceptionInput("subjectMissing"));
|
||||
$this->dbMock->tokenLookup->with("fever.login", "validtoken")->returns(['user' => "jane.doe@example.com"]);
|
||||
\Phake::when(Arsse::$db)->tokenLookup->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->tokenLookup("fever.login", "validtoken")->thenReturn(['user' => "jane.doe@example.com"]);
|
||||
// test only the authentication process
|
||||
$this->hMock->baseResponse->does(function(bool $authenticated) {
|
||||
\Phake::when($this->hMock)->baseResponse->thenReturnCallback(function(bool $authenticated) {
|
||||
return ['auth' => (int) $authenticated];
|
||||
});
|
||||
$this->hMock->processRequest->does(function($out, $G, $P) {
|
||||
\Phake::when($this->hMock)->processRequest->thenReturnCallback(function($out, $G, $P) {
|
||||
return $out;
|
||||
});
|
||||
$this->assertMessage($exp, $this->req($dataGet, $dataPost, "POST", null, "", $httpUser));
|
||||
|
@ -243,12 +240,12 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testListGroups(): void {
|
||||
$this->dbMock->tagList->with($this->userId)->returns(new Result([
|
||||
\Phake::when(Arsse::$db)->tagList($this->userId)->thenReturn(new Result([
|
||||
['id' => 1, 'name' => "Fascinating", 'subscriptions' => 2],
|
||||
['id' => 2, 'name' => "Interesting", 'subscriptions' => 2],
|
||||
['id' => 3, 'name' => "Boring", 'subscriptions' => 0],
|
||||
]));
|
||||
$this->dbMock->tagSummarize->with($this->userId)->returns(new Result([
|
||||
\Phake::when(Arsse::$db)->tagSummarize($this->userId)->thenReturn(new Result([
|
||||
['id' => 1, 'name' => "Fascinating", 'subscription' => 1],
|
||||
['id' => 1, 'name' => "Fascinating", 'subscription' => 2],
|
||||
['id' => 2, 'name' => "Interesting", 'subscription' => 1],
|
||||
|
@ -269,12 +266,12 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testListFeeds(): void {
|
||||
$this->dbMock->subscriptionList->with($this->userId)->returns(new Result([
|
||||
\Phake::when(Arsse::$db)->subscriptionList($this->userId)->thenReturn(new Result([
|
||||
['id' => 1, 'feed' => 5, 'title' => "Ankh-Morpork News", 'url' => "http://example.com/feed", 'source' => "http://example.com/", 'edited' => "2019-01-01 21:12:00", 'icon_url' => "http://example.com/favicon.ico", 'icon_id' => 42],
|
||||
['id' => 2, 'feed' => 9, 'title' => "Ook, Ook Eek Ook!", 'url' => "http://example.net/feed", 'source' => "http://example.net/", 'edited' => "1988-06-24 12:21:00", 'icon_url' => "", 'icon_id' => null],
|
||||
['id' => 3, 'feed' => 1, 'title' => "The Last Soul", 'url' => "http://example.org/feed", 'source' => "http://example.org/", 'edited' => "1991-08-12 03:22:00", 'icon_url' => "http://example.org/favicon.ico", 'icon_id' => 42],
|
||||
]));
|
||||
$this->dbMock->tagSummarize->with($this->userId)->returns(new Result([
|
||||
\Phake::when(Arsse::$db)->tagSummarize($this->userId)->thenReturn(new Result([
|
||||
['id' => 1, 'name' => "Fascinating", 'subscription' => 1],
|
||||
['id' => 1, 'name' => "Fascinating", 'subscription' => 2],
|
||||
['id' => 2, 'name' => "Interesting", 'subscription' => 1],
|
||||
|
@ -298,14 +295,14 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testListItems(string $url, Context $c, bool $desc): void {
|
||||
$fields = ["id", "subscription", "title", "author", "content", "url", "starred", "unread", "published_date"];
|
||||
$order = [$desc ? "id desc" : "id"];
|
||||
$this->dbMock->articleList->returns(new Result($this->articles['db']));
|
||||
$this->dbMock->articleCount->with($this->userId, (new Context)->hidden(false))->returns(1024);
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->articles['db']));
|
||||
\Phake::when(Arsse::$db)->articleCount($this->userId, (new Context)->hidden(false))->thenReturn(1024);
|
||||
$exp = HTTP::respJson([
|
||||
'items' => $this->articles['rest'],
|
||||
'total_items' => 1024,
|
||||
]);
|
||||
$this->assertMessage($exp, $this->req("api&$url"));
|
||||
$this->dbMock->articleList->calledWith($this->userId, $this->equalTo($c), $fields, $order);
|
||||
\Phake::verify(Arsse::$db)->articleList($this->userId, $this->equalTo($c), $fields, $order);
|
||||
}
|
||||
|
||||
public function provideItemListContexts(): iterable {
|
||||
|
@ -327,8 +324,8 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testListItemIds(): void {
|
||||
$saved = [['id' => 1],['id' => 2],['id' => 3]];
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->starred(true)->hidden(false))->returns(new Result($saved));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->unread(true)->hidden(false))->returns(new Result($unread));
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, (new Context)->starred(true)->hidden(false))->thenReturn(new Result($saved));
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, (new Context)->unread(true)->hidden(false))->thenReturn(new Result($unread));
|
||||
$exp = HTTP::respJson(['saved_item_ids' => "1,2,3"]);
|
||||
$this->assertMessage($exp, $this->req("api&saved_item_ids"));
|
||||
$exp = HTTP::respJson(['unread_item_ids' => "4,5,6"]);
|
||||
|
@ -345,16 +342,16 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testSetMarks(string $post, Context $c, array $data, array $out): void {
|
||||
$saved = [['id' => 1],['id' => 2],['id' => 3]];
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->starred(true)->hidden(false))->returns(new Result($saved));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->unread(true)->hidden(false))->returns(new Result($unread));
|
||||
$this->dbMock->articleMark->returns(0);
|
||||
$this->dbMock->articleMark->with($this->userId, $this->anything(), (new Context)->article(2112))->throws(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, (new Context)->starred(true)->hidden(false))->thenReturn(new Result($saved));
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, (new Context)->unread(true)->hidden(false))->thenReturn(new Result($unread));
|
||||
\Phake::when(Arsse::$db)->articleMark->thenReturn(0);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $this->anything(), (new Context)->article(2112))->thenThrow(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing"));
|
||||
$exp = HTTP::respJson($out);
|
||||
$this->assertMessage($exp, $this->req("api", $post));
|
||||
if ($c && $data) {
|
||||
$this->dbMock->articleMark->calledWith($this->userId, $data, $this->equalTo($c));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->userId, $data, $this->equalTo($c));
|
||||
} else {
|
||||
$this->dbMock->articleMark->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->articleMark(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,16 +359,16 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testSetMarksWithQuery(string $get, Context $c, array $data, array $out): void {
|
||||
$saved = [['id' => 1],['id' => 2],['id' => 3]];
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->starred(true)->hidden(false))->returns(new Result($saved));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->unread(true)->hidden(false))->returns(new Result($unread));
|
||||
$this->dbMock->articleMark->returns(0);
|
||||
$this->dbMock->articleMark->with($this->userId, $this->anything(), (new Context)->article(2112))->throws(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, (new Context)->starred(true)->hidden(false))->thenReturn(new Result($saved));
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, (new Context)->unread(true)->hidden(false))->thenReturn(new Result($unread));
|
||||
\Phake::when(Arsse::$db)->articleMark->thenReturn(0);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $this->anything(), (new Context)->article(2112))->thenThrow(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing"));
|
||||
$exp = HTTP::respJson($out);
|
||||
$this->assertMessage($exp, $this->req("api&$get"));
|
||||
if ($c && $data) {
|
||||
$this->dbMock->articleMark->calledWith($this->userId, $data, $this->equalTo($c));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->userId, $data, $this->equalTo($c));
|
||||
} else {
|
||||
$this->dbMock->articleMark->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->articleMark(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -429,23 +426,23 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testMakeABaseQuery(): void {
|
||||
$this->hMock->baseResponse->forwards();
|
||||
$this->hMock->logIn->returns(true);
|
||||
$this->dbMock->subscriptionRefreshed->with($this->userId)->returns(new \DateTimeImmutable("2000-01-01T00:00:00Z"));
|
||||
\Phake::when($this->hMock)->baseResponse->thenCallParent();
|
||||
\Phake::when($this->hMock)->logIn->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->subscriptionRefreshed($this->userId)->thenReturn(new \DateTimeImmutable("2000-01-01T00:00:00Z"));
|
||||
$exp = HTTP::respJson([
|
||||
'api_version' => API::LEVEL,
|
||||
'auth' => 1,
|
||||
'last_refreshed_on_time' => 946684800,
|
||||
]);
|
||||
$this->assertMessage($exp, $this->req("api"));
|
||||
$this->dbMock->subscriptionRefreshed->with($this->userId)->returns(null); // no subscriptions
|
||||
\Phake::when(Arsse::$db)->subscriptionRefreshed($this->userId)->thenReturn(null); // no subscriptions
|
||||
$exp = HTTP::respJson([
|
||||
'api_version' => API::LEVEL,
|
||||
'auth' => 1,
|
||||
'last_refreshed_on_time' => null,
|
||||
]);
|
||||
$this->assertMessage($exp, $this->req("api"));
|
||||
$this->hMock->logIn->returns(false);
|
||||
\Phake::when($this->hMock)->logIn->thenReturn(false);
|
||||
$exp = HTTP::respJson([
|
||||
'api_version' => API::LEVEL,
|
||||
'auth' => 0,
|
||||
|
@ -456,19 +453,19 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testUndoReadMarks(): void {
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
$out = ['unread_item_ids' => "4,5,6"];
|
||||
$this->dbMock->articleList->with($this->userId, $this->equalTo((new Context)->limit(1)->hidden(false)), ["marked_date"], ["marked_date desc"])->returns(new Result([['marked_date' => "2000-01-01 00:00:00"]]));
|
||||
$this->dbMock->articleList->with($this->userId, $this->equalTo((new Context)->unread(true)->hidden(false)))->returns(new Result($unread));
|
||||
$this->dbMock->articleMark->returns(0);
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, $this->equalTo((new Context)->limit(1)->hidden(false)), ["marked_date"], ["marked_date desc"])->thenReturn(new Result([['marked_date' => "2000-01-01 00:00:00"]]));
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, $this->equalTo((new Context)->unread(true)->hidden(false)))->thenReturn(new Result($unread));
|
||||
\Phake::when(Arsse::$db)->articleMark->thenReturn(0);
|
||||
$exp = HTTP::respJson($out);
|
||||
$this->assertMessage($exp, $this->req("api", ['unread_recently_read' => 1]));
|
||||
$this->dbMock->articleMark->calledWith($this->userId, ['read' => false], $this->equalTo((new Context)->unread(false)->markedRange("1999-12-31T23:59:45Z", null)->hidden(false)));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->limit(1)->hidden(false), ["marked_date"], ["marked_date desc"])->returns(new Result([]));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->userId, ['read' => false], $this->equalTo((new Context)->unread(false)->markedRange("1999-12-31T23:59:45Z", null)->hidden(false)));
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, (new Context)->limit(1)->hidden(false), ["marked_date"], ["marked_date desc"])->thenReturn(new Result([]));
|
||||
$this->assertMessage($exp, $this->req("api", ['unread_recently_read' => 1]));
|
||||
$this->dbMock->articleMark->once()->called(); // only called one time, above
|
||||
\Phake::verify(Arsse::$db, \Phake::times(1))->articleMark(\Phake::anyParameters()); // only called one time, above
|
||||
}
|
||||
|
||||
public function testOutputToXml(): void {
|
||||
$this->hMock->processRequest->returns([
|
||||
$this->hMock->processRequest->thenReturn([
|
||||
'items' => $this->articles['rest'],
|
||||
'total_items' => 1024,
|
||||
]);
|
||||
|
@ -479,7 +476,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testListFeedIcons(): void {
|
||||
$iconType = (new \ReflectionClassConstant(API::class, "GENERIC_ICON_TYPE"))->getValue();
|
||||
$iconData = (new \ReflectionClassConstant(API::class, "GENERIC_ICON_DATA"))->getValue();
|
||||
$this->dbMock->iconList->returns(new Result($this->v([
|
||||
\Phake::when(Arsse::$db)->iconList->thenReturn(new Result($this->v([
|
||||
['id' => 42, 'type' => "image/svg+xml", 'data' => "<svg/>"],
|
||||
['id' => 44, 'type' => null, 'data' => "IMAGE DATA"],
|
||||
['id' => 47, 'type' => null, 'data' => null],
|
||||
|
|
|
@ -18,42 +18,38 @@ use JKingWeb\Arsse\REST\Fever\User as FeverUser;
|
|||
/** @covers \JKingWeb\Arsse\REST\Fever\User<extended> */
|
||||
class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
protected $u;
|
||||
protected $h;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
// create a mock user manager
|
||||
$this->userMock = $this->mock(User::class);
|
||||
$this->userMock->auth->returns(true);
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
\Phake::when(Arsse::$user)->auth->thenReturn(true);
|
||||
// create a mock database interface
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->begin->returns($this->mock(Transaction::class));
|
||||
}
|
||||
|
||||
protected function prepTest(): FeverUser {
|
||||
Arsse::$user = $this->userMock->get();
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(Transaction::class));
|
||||
// instantiate the handler
|
||||
return new FeverUser;
|
||||
$this->h = new FeverUser;
|
||||
}
|
||||
|
||||
/** @dataProvider providePasswordCreations */
|
||||
public function testRegisterAUserPassword(string $user, ?string $password, $exp): void {
|
||||
$this->userMock->generatePassword->returns("RANDOM_PASSWORD");
|
||||
$this->dbMock->tokenCreate->does(function($user, $class, $id = null) {
|
||||
\Phake::when(Arsse::$user)->generatePassword->thenReturn("RANDOM_PASSWORD");
|
||||
\Phake::when(Arsse::$db)->tokenCreate->thenReturnCallback(function($user, $class, $id = null) {
|
||||
return $id ?? "RANDOM_TOKEN";
|
||||
});
|
||||
$this->dbMock->tokenCreate->with("john.doe@example.org", $this->anything(), $this->anything())->throws(new UserException("doesNotExist"));
|
||||
\Phake::when(Arsse::$db)->tokenCreate("john.doe@example.org", $this->anything(), $this->anything())->thenThrow(new UserException("doesNotExist"));
|
||||
try {
|
||||
if ($exp instanceof \JKingWeb\Arsse\AbstractException) {
|
||||
$this->assertException($exp);
|
||||
$this->prepTest()->register($user, $password);
|
||||
$this->h->register($user, $password);
|
||||
} else {
|
||||
$this->assertSame($exp, $this->prepTest()->register($user, $password));
|
||||
$this->assertSame($exp, $this->h->register($user, $password));
|
||||
}
|
||||
} finally {
|
||||
$this->dbMock->tokenRevoke->calledWith($user, "fever.login");
|
||||
$this->dbMock->tokenCreate->calledWith($user, "fever.login", md5($user.":".($password ?? "RANDOM_PASSWORD")));
|
||||
\Phake::verify(Arsse::$db)->tokenRevoke($user, "fever.login");
|
||||
\Phake::verify(Arsse::$db)->tokenCreate($user, "fever.login", md5($user.":".($password ?? "RANDOM_PASSWORD")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,20 +65,20 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testUnregisterAUser(): void {
|
||||
$this->dbMock->tokenRevoke->returns(3);
|
||||
$this->assertTrue($this->prepTest()->unregister("jane.doe@example.com"));
|
||||
$this->dbMock->tokenRevoke->calledWith("jane.doe@example.com", "fever.login");
|
||||
$this->dbMock->tokenRevoke->returns(0);
|
||||
$this->assertFalse($this->prepTest()->unregister("john.doe@example.com"));
|
||||
$this->dbMock->tokenRevoke->calledWith("john.doe@example.com", "fever.login");
|
||||
\Phake::when(Arsse::$db)->tokenRevoke->thenReturn(3);
|
||||
$this->assertTrue($this->h->unregister("jane.doe@example.com"));
|
||||
\Phake::verify(Arsse::$db)->tokenRevoke("jane.doe@example.com", "fever.login");
|
||||
\Phake::when(Arsse::$db)->tokenRevoke->thenReturn(0);
|
||||
$this->assertFalse($this->h->unregister("john.doe@example.com"));
|
||||
\Phake::verify(Arsse::$db)->tokenRevoke("john.doe@example.com", "fever.login");
|
||||
}
|
||||
|
||||
/** @dataProvider provideUserAuthenticationRequests */
|
||||
public function testAuthenticateAUserName(string $user, string $password, bool $exp): void {
|
||||
$this->dbMock->tokenLookup->throws(new ExceptionInput("constraintViolation"));
|
||||
$this->dbMock->tokenLookup->with("fever.login", md5("jane.doe@example.com:secret"))->returns(['user' => "jane.doe@example.com"]);
|
||||
$this->dbMock->tokenLookup->with("fever.login", md5("john.doe@example.com:superman"))->returns(['user' => "john.doe@example.com"]);
|
||||
$this->assertSame($exp, $this->prepTest()->authenticate($user, $password));
|
||||
\Phake::when(Arsse::$db)->tokenLookup->thenThrow(new ExceptionInput("constraintViolation"));
|
||||
\Phake::when(Arsse::$db)->tokenLookup("fever.login", md5("jane.doe@example.com:secret"))->thenReturn(['user' => "jane.doe@example.com"]);
|
||||
\Phake::when(Arsse::$db)->tokenLookup("fever.login", md5("john.doe@example.com:superman"))->thenReturn(['user' => "john.doe@example.com"]);
|
||||
$this->assertSame($exp, $this->h->authenticate($user, $password));
|
||||
}
|
||||
|
||||
public function provideUserAuthenticationRequests(): iterable {
|
||||
|
|
|
@ -19,20 +19,17 @@ class TestToken extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
protected const TOKEN = "Tk2o9YubmZIL2fm2w8Z4KlDEQJz532fNSOcTG0s2_xc=";
|
||||
|
||||
protected $transaction;
|
||||
protected $h;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
// create a mock database interface
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->transaction = $this->mock(Transaction::class);
|
||||
$this->dbMock->begin->returns($this->transaction);
|
||||
}
|
||||
|
||||
protected function prepTest(): Token {
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
$this->transaction = \Phake::mock(Transaction::class);
|
||||
\Phake::when(Arsse::$db)->begin->thenReturn($this->transaction);
|
||||
// instantiate the handler
|
||||
return new Token;
|
||||
$this->h = new Token;
|
||||
}
|
||||
|
||||
protected function v($value) {
|
||||
|
@ -40,10 +37,9 @@ class TestToken extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testGenerateTokens(): void {
|
||||
$this->dbMock->tokenCreate->returns("RANDOM TOKEN");
|
||||
$this->assertSame("RANDOM TOKEN", $this->prepTest()->tokenGenerate("ook", "Eek"));
|
||||
$this->dbMock->tokenCreate->calledWith("ook", "miniflux.login", "~", null, "Eek");
|
||||
$token = $this->dbMock->tokenCreate->firstCall()->argument(2);
|
||||
\Phake::when(Arsse::$db)->tokenCreate->thenReturn("RANDOM TOKEN");
|
||||
$this->assertSame("RANDOM TOKEN", $this->h->tokenGenerate("ook", "Eek"));
|
||||
\Phake::verify(Arsse::$db)->tokenCreate("ook", "miniflux.login", \Phake::capture($token), null, "Eek");
|
||||
$this->assertMatchesRegularExpression("/^[A-Za-z0-9_\-]{43}=$/", $token);
|
||||
}
|
||||
|
||||
|
@ -58,15 +54,15 @@ class TestToken extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['label' => "Eek", 'id' => "TOKEN 2"],
|
||||
['label' => "Ack", 'id' => "TOKEN 3"],
|
||||
];
|
||||
$this->dbMock->tokenList->returns(new Result($this->v($out)));
|
||||
$this->dbMock->userExists->returns(true);
|
||||
$this->assertSame($exp, $this->prepTest()->tokenList("john.doe@example.com"));
|
||||
$this->dbMock->tokenList->calledWith("john.doe@example.com", "miniflux.login");
|
||||
\Phake::when(Arsse::$db)->tokenList->thenReturn(new Result($this->v($out)));
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
|
||||
$this->assertSame($exp, $this->h->tokenList("john.doe@example.com"));
|
||||
\Phake::verify(Arsse::$db)->tokenList("john.doe@example.com", "miniflux.login");
|
||||
}
|
||||
|
||||
public function testListTheTokensOfAMissingUser(): void {
|
||||
$this->dbMock->userExists->returns(false);
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
|
||||
$this->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||
$this->prepTest()->tokenList("john.doe@example.com");
|
||||
$this->h->tokenList("john.doe@example.com");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace JKingWeb\Arsse\TestCase\REST\Miniflux;
|
||||
|
||||
use Eloquent\Phony\Mock\Handle\InstanceHandle;
|
||||
use Eloquent\Phony\Phpunit\Phony;
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Context\Context;
|
||||
use JKingWeb\Arsse\Context\RootContext;
|
||||
|
@ -60,11 +58,6 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
protected $transaction;
|
||||
|
||||
protected function req(string $method, string $target, $data = "", array $headers = [], ?string $user = "john.doe@example.com", bool $body = true): ResponseInterface {
|
||||
Arsse::$obj = $this->objMock->get();
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
if ($this->h instanceof InstanceHandle) {
|
||||
$this->h = $this->h->get();
|
||||
}
|
||||
$prefix = "/v1";
|
||||
$url = $prefix.$target;
|
||||
if ($body) {
|
||||
|
@ -80,16 +73,16 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
$this->transaction = \Phake::mock(Transaction::class);
|
||||
// create mock timestamps
|
||||
$this->objMock->get->with(\DateTimeImmutable::class)->returns(new \DateTimeImmutable(self::NOW));
|
||||
\Phake::when(Arsse::$obj)->get(\DateTimeImmutable::class)->thenReturn(new \DateTimeImmutable(self::NOW));
|
||||
// create a mock database interface
|
||||
$this->transaction = $this->mock(Transaction::class);
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->begin->returns($this->transaction->get());
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->begin->thenReturn($this->transaction);
|
||||
// create a mock user manager
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['num' => 42, 'admin' => false, 'root_folder_name' => null, 'tz' => "Asia/Gaza"]);
|
||||
\Phake::when(Arsse::$user)->begin->thenReturn($this->transaction->get());
|
||||
\Phake::when(Arsse::$user)->begin->thenReturn($this->transaction);
|
||||
//initialize a handler
|
||||
$this->h = new V1();
|
||||
}
|
||||
|
@ -114,8 +107,8 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$headers = [];
|
||||
}
|
||||
Arsse::$user->id = null;
|
||||
$this->dbMock->tokenLookup->throws(new ExceptionInput("subjectMissing"));
|
||||
$this->dbMock->tokenLookup->with("miniflux.login", self::TOKEN)->returns(['user' => $user]);
|
||||
\Phake::when(Arsse::$db)->tokenLookup->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->tokenLookup("miniflux.login", self::TOKEN)->thenReturn(['user' => $user]);
|
||||
$this->assertMessage($exp, $this->req("GET", "/", "", $headers, $auth ? "john.doe@example.com" : null));
|
||||
$this->assertSame($success ? $user : null, Arsse::$user->id);
|
||||
}
|
||||
|
@ -383,7 +376,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testListCategories(): void {
|
||||
$this->dbMock->folderList->returns(new Result($this->v([
|
||||
\Phake::when(Arsse::$db)->folderList->thenReturn(new Result($this->v([
|
||||
['id' => 1, 'name' => "Science"],
|
||||
['id' => 20, 'name' => "Technology"],
|
||||
])));
|
||||
|
@ -393,7 +386,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 21, 'title' => "Technology", 'user_id' => 42],
|
||||
]);
|
||||
$this->assertMessage($exp, $this->req("GET", "/categories"));
|
||||
$this->dbMock->folderList->calledWith("john.doe@example.com", null, false);
|
||||
\Phake::verify(Arsse::$db)->folderList("john.doe@example.com", null, false);
|
||||
// run test again with a renamed root folder
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['num' => 47, 'admin' => false, 'root_folder_name' => "Uncategorized"]);
|
||||
|
@ -408,13 +401,13 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/** @dataProvider provideCategoryAdditions */
|
||||
public function testAddACategory($title, ResponseInterface $exp): void {
|
||||
if (!strlen((string) $title)) {
|
||||
$this->dbMock->folderAdd->throws(new ExceptionInput("missing"));
|
||||
\Phake::when(Arsse::$db)->folderAdd->thenThrow(new ExceptionInput("missing"));
|
||||
} elseif (!strlen(trim((string) $title))) {
|
||||
$this->dbMock->folderAdd->throws(new ExceptionInput("whitespace"));
|
||||
\Phake::when(Arsse::$db)->folderAdd->thenThrow(new ExceptionInput("whitespace"));
|
||||
} elseif ($title === "Duplicate") {
|
||||
$this->dbMock->folderAdd->throws(new ExceptionInput("constraintViolation"));
|
||||
\Phake::when(Arsse::$db)->folderAdd->thenThrow(new ExceptionInput("constraintViolation"));
|
||||
} else {
|
||||
$this->dbMock->folderAdd->returns(2111);
|
||||
\Phake::when(Arsse::$db)->folderAdd->thenReturn(2111);
|
||||
}
|
||||
$this->assertMessage($exp, $this->req("POST", "/categories", ['title' => $title]));
|
||||
}
|
||||
|
@ -434,15 +427,15 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testRenameACategory(int $id, $title, $out, ResponseInterface $exp): void {
|
||||
\Phake::when(Arsse::$user)->propertiesSet->thenReturn(['root_folder_name' => $title]);
|
||||
if (is_string($out)) {
|
||||
$this->dbMock->folderPropertiesSet->throws(new ExceptionInput($out));
|
||||
\Phake::when(Arsse::$db)->folderPropertiesSet->thenThrow(new ExceptionInput($out));
|
||||
} else {
|
||||
$this->dbMock->folderPropertiesSet->returns($out);
|
||||
\Phake::when(Arsse::$db)->folderPropertiesSet->thenReturn($out);
|
||||
}
|
||||
$times = (int) ($id === 1 && is_string($title) && strlen(trim($title)));
|
||||
$this->assertMessage($exp, $this->req("PUT", "/categories/$id", ['title' => $title]));
|
||||
\Phake::verify(Arsse::$user, \Phake::times($times))->propertiesSet("john.doe@example.com", ['root_folder_name' => $title]);
|
||||
$times = (int) ($id !== 1 && is_string($title));
|
||||
$this->dbMock->folderPropertiesSet->times($times)->calledWith("john.doe@example.com", $id - 1, ['name' => $title]);
|
||||
\Phake::verify(Arsse::$db, \Phake::times($times))->folderPropertiesSet("john.doe@example.com", $id - 1, ['name' => $title]);
|
||||
}
|
||||
|
||||
public function provideCategoryUpdates(): iterable {
|
||||
|
@ -464,90 +457,90 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testDeleteARealCategory(): void {
|
||||
$this->dbMock->folderRemove->returns(true)->throws(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->folderRemove->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
$this->assertMessage(HTTP::respEmpty(204), $this->req("DELETE", "/categories/2112"));
|
||||
$this->dbMock->folderRemove->calledWith("john.doe@example.com", 2111);
|
||||
\Phake::verify(Arsse::$db)->folderRemove("john.doe@example.com", 2111);
|
||||
$this->assertMessage(V1::respError("404", 404), $this->req("DELETE", "/categories/47"));
|
||||
$this->dbMock->folderRemove->calledWith("john.doe@example.com", 46);
|
||||
\Phake::verify(Arsse::$db)->folderRemove("john.doe@example.com", 46);
|
||||
}
|
||||
|
||||
public function testDeleteTheSpecialCategory(): void {
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v([
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v([
|
||||
['id' => 1],
|
||||
['id' => 47],
|
||||
['id' => 2112],
|
||||
])));
|
||||
$this->dbMock->subscriptionRemove->returns(true);
|
||||
\Phake::when(Arsse::$db)->subscriptionRemove->thenReturn(true);
|
||||
$this->assertMessage(HTTP::respEmpty(204), $this->req("DELETE", "/categories/1"));
|
||||
Phony::inOrder(
|
||||
$this->dbMock->begin->calledWith(),
|
||||
$this->dbMock->subscriptionList->calledWith("john.doe@example.com", null, false),
|
||||
$this->dbMock->subscriptionRemove->calledWith("john.doe@example.com", 1),
|
||||
$this->dbMock->subscriptionRemove->calledWith("john.doe@example.com", 47),
|
||||
$this->dbMock->subscriptionRemove->calledWith("john.doe@example.com", 2112),
|
||||
$this->transaction->commit->called()
|
||||
\Phake::inOrder(
|
||||
\Phake::verify(Arsse::$db)->begin(),
|
||||
\Phake::verify(Arsse::$db)->subscriptionList("john.doe@example.com", null, false),
|
||||
\Phake::verify(Arsse::$db)->subscriptionRemove("john.doe@example.com", 1),
|
||||
\Phake::verify(Arsse::$db)->subscriptionRemove("john.doe@example.com", 47),
|
||||
\Phake::verify(Arsse::$db)->subscriptionRemove("john.doe@example.com", 2112),
|
||||
\Phake::verify($this->transaction)->commit()
|
||||
);
|
||||
}
|
||||
|
||||
public function testListFeeds(): void {
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v(self::FEEDS)));
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v(self::FEEDS)));
|
||||
$exp = HTTP::respJson(self::FEEDS_OUT);
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds"));
|
||||
}
|
||||
|
||||
public function testListFeedsOfACategory(): void {
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v(self::FEEDS)));
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v(self::FEEDS)));
|
||||
$exp = HTTP::respJson(self::FEEDS_OUT);
|
||||
$this->assertMessage($exp, $this->req("GET", "/categories/2112/feeds"));
|
||||
$this->dbMock->subscriptionList->calledWith(Arsse::$user->id, 2111, true);
|
||||
\Phake::verify(Arsse::$db)->subscriptionList(Arsse::$user->id, 2111, true);
|
||||
}
|
||||
|
||||
public function testListFeedsOfTheRootCategory(): void {
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v(self::FEEDS)));
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v(self::FEEDS)));
|
||||
$exp = HTTP::respJson(self::FEEDS_OUT);
|
||||
$this->assertMessage($exp, $this->req("GET", "/categories/1/feeds"));
|
||||
$this->dbMock->subscriptionList->calledWith(Arsse::$user->id, 0, false);
|
||||
\Phake::verify(Arsse::$db)->subscriptionList(Arsse::$user->id, 0, false);
|
||||
}
|
||||
|
||||
public function testListFeedsOfAMissingCategory(): void {
|
||||
$this->dbMock->subscriptionList->throws(new ExceptionInput("idMissing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenThrow(new ExceptionInput("idMissing"));
|
||||
$exp = V1::respError("404", 404);
|
||||
$this->assertMessage($exp, $this->req("GET", "/categories/2112/feeds"));
|
||||
$this->dbMock->subscriptionList->calledWith(Arsse::$user->id, 2111, true);
|
||||
\Phake::verify(Arsse::$db)->subscriptionList(Arsse::$user->id, 2111, true);
|
||||
}
|
||||
|
||||
public function testGetAFeed(): void {
|
||||
$this->dbMock->subscriptionPropertiesGet->returns($this->v(self::FEEDS[0]))->returns($this->v(self::FEEDS[1]));
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->thenReturn($this->v(self::FEEDS[0]))->thenReturn($this->v(self::FEEDS[1]));
|
||||
$this->assertMessage(HTTP::respJson(self::FEEDS_OUT[0]), $this->req("GET", "/feeds/1"));
|
||||
$this->dbMock->subscriptionPropertiesGet->calledWith(Arsse::$user->id, 1);
|
||||
$this->assertMessage(HTTP::respJson(self::FEEDS_OUT[1]), $this->req("GET", "/feeds/55"));
|
||||
$this->dbMock->subscriptionPropertiesGet->calledWith(Arsse::$user->id, 55);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 1);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 55);
|
||||
}
|
||||
|
||||
public function testGetAMissingFeed(): void {
|
||||
$this->dbMock->subscriptionPropertiesGet->throws(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
$this->assertMessage(V1::respError("404", 404), $this->req("GET", "/feeds/1"));
|
||||
$this->dbMock->subscriptionPropertiesGet->calledWith(Arsse::$user->id, 1);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 1);
|
||||
}
|
||||
|
||||
/** @dataProvider provideFeedCreations */
|
||||
public function testCreateAFeed(array $in, $out1, $out2, $out3, $out4, ResponseInterface $exp): void {
|
||||
if ($out1 instanceof \Exception) {
|
||||
$this->dbMock->feedAdd->throws($out1);
|
||||
\Phake::when(Arsse::$db)->feedAdd->thenThrow($out1);
|
||||
} else {
|
||||
$this->dbMock->feedAdd->returns($out1);
|
||||
\Phake::when(Arsse::$db)->feedAdd->thenReturn($out1);
|
||||
}
|
||||
if ($out2 instanceof \Exception) {
|
||||
$this->dbMock->subscriptionAdd->throws($out2);
|
||||
\Phake::when(Arsse::$db)->subscriptionAdd->thenThrow($out2);
|
||||
} else {
|
||||
$this->dbMock->subscriptionAdd->returns($out2);
|
||||
\Phake::when(Arsse::$db)->subscriptionAdd->thenReturn($out2);
|
||||
}
|
||||
if ($out3 instanceof \Exception) {
|
||||
$this->dbMock->subscriptionPropertiesSet->throws($out3);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenThrow($out3);
|
||||
} elseif ($out4 instanceof \Exception) {
|
||||
$this->dbMock->subscriptionPropertiesSet->returns($out3)->throws($out4);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenReturn($out3)->thenThrow($out4);
|
||||
} else {
|
||||
$this->dbMock->subscriptionPropertiesSet->returns($out3)->returns($out4);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenReturn($out3)->thenReturn($out4);
|
||||
}
|
||||
$this->assertMessage($exp, $this->req("POST", "/feeds", $in));
|
||||
$in1 = $out1 !== null;
|
||||
|
@ -555,37 +548,37 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$in3 = $out3 !== null;
|
||||
$in4 = $out4 !== null;
|
||||
if ($in1) {
|
||||
$this->dbMock->feedAdd->calledWith($in['feed_url'], $in['username'] ?? "", $in['password'] ?? "", false, $in['crawler'] ?? false);
|
||||
\Phake::verify(Arsse::$db)->feedAdd($in['feed_url'], $in['username'] ?? "", $in['password'] ?? "", false, $in['crawler'] ?? false);
|
||||
} else {
|
||||
$this->dbMock->feedAdd->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->feedAdd(\Phake::anyParameters());
|
||||
}
|
||||
if ($in2) {
|
||||
$this->dbMock->begin->calledWith();
|
||||
$this->dbMock->subscriptionAdd->calledWith("john.doe@example.com", $in['feed_url'], $in['username'] ?? "", $in['password'] ?? "", false, $in['crawler'] ?? false);
|
||||
\Phake::verify(Arsse::$db)->begin();
|
||||
\Phake::verify(Arsse::$db)->subscriptionAdd("john.doe@example.com", $in['feed_url'], $in['username'] ?? "", $in['password'] ?? "", false, $in['crawler'] ?? false);
|
||||
} else {
|
||||
$this->dbMock->begin->never()->called();
|
||||
$this->dbMock->subscriptionAdd->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->begin(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->subscriptionAdd(\Phake::anyParameters());
|
||||
}
|
||||
if ($in3) {
|
||||
$props = [
|
||||
'folder' => $in['category_id'] - 1,
|
||||
'scrape' => $in['crawler'] ?? false,
|
||||
];
|
||||
$this->dbMock->subscriptionPropertiesSet->calledWith("john.doe@example.com", $out2, $props);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet("john.doe@example.com", $out2, $props);
|
||||
if (!$out3 instanceof \Exception) {
|
||||
$this->transaction->commit->called();
|
||||
\Phake::verify($this->transaction)->commit();
|
||||
}
|
||||
} else {
|
||||
$this->dbMock->subscriptionPropertiesSet->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->subscriptionPropertiesSet(\Phake::anyParameters());
|
||||
}
|
||||
if ($in4) {
|
||||
$rules = [
|
||||
'keep_rule' => $in['keeplist_rules'] ?? null,
|
||||
'block_rule' => $in['blocklist_rules'] ?? null,
|
||||
];
|
||||
$this->dbMock->subscriptionPropertiesSet->calledWith("john.doe@example.com", $out2, $rules);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet("john.doe@example.com", $out2, $rules);
|
||||
} else {
|
||||
$this->dbMock->subscriptionPropertiesSet->atMost(1)->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::atMost(1))->subscriptionPropertiesSet(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -623,15 +616,15 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideFeedModifications */
|
||||
public function testModifyAFeed(array $in, array $data, $out, ResponseInterface $exp): void {
|
||||
$this->h = $this->partialMock(V1::class);
|
||||
$this->h->getFeed->returns(HTTP::respJson(self::FEEDS_OUT[0]));
|
||||
$this->h = \Phake::partialMock(V1::class);
|
||||
\Phake::when($this->h)->getFeed->thenReturn(HTTP::respJson(self::FEEDS_OUT[0]));
|
||||
if ($out instanceof \Exception) {
|
||||
$this->dbMock->subscriptionPropertiesSet->throws($out);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenThrow($out);
|
||||
} else {
|
||||
$this->dbMock->subscriptionPropertiesSet->returns($out);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenReturn($out);
|
||||
}
|
||||
$this->assertMessage($exp, $this->req("PUT", "/feeds/2112", $in));
|
||||
$this->dbMock->subscriptionPropertiesSet->calledWith(Arsse::$user->id, 2112, $data);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 2112, $data);
|
||||
}
|
||||
|
||||
public function provideFeedModifications(): iterable {
|
||||
|
@ -652,34 +645,34 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testModifyAFeedWithNoBody(): void {
|
||||
$this->h = $this->partialMock(V1::class);
|
||||
$this->h->getFeed->returns(HTTP::respJson(self::FEEDS_OUT[0]));
|
||||
$this->dbMock->subscriptionPropertiesSet->returns(true);
|
||||
$this->h = \Phake::partialMock(V1::class);
|
||||
\Phake::when($this->h)->getFeed->thenReturn(HTTP::respJson(self::FEEDS_OUT[0]));
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenReturn(true);
|
||||
$this->assertMessage(HTTP::respJson(self::FEEDS_OUT[0], 201), $this->req("PUT", "/feeds/2112", ""));
|
||||
$this->dbMock->subscriptionPropertiesSet->calledWith(Arsse::$user->id, 2112, []);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 2112, []);
|
||||
}
|
||||
|
||||
public function testDeleteAFeed(): void {
|
||||
$this->dbMock->subscriptionRemove->returns(true);
|
||||
\Phake::when(Arsse::$db)->subscriptionRemove->thenReturn(true);
|
||||
$this->assertMessage(HTTP::respEmpty(204), $this->req("DELETE", "/feeds/2112"));
|
||||
$this->dbMock->subscriptionRemove->calledWith(Arsse::$user->id, 2112);
|
||||
\Phake::verify(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 2112);
|
||||
}
|
||||
|
||||
public function testDeleteAMissingFeed(): void {
|
||||
$this->dbMock->subscriptionRemove->throws(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionRemove->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
$this->assertMessage(V1::respError("404", 404), $this->req("DELETE", "/feeds/2112"));
|
||||
$this->dbMock->subscriptionRemove->calledWith(Arsse::$user->id, 2112);
|
||||
\Phake::verify(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 2112);
|
||||
}
|
||||
|
||||
/** @dataProvider provideIcons */
|
||||
public function testGetTheIconOfASubscription($out, ResponseInterface $exp): void {
|
||||
if ($out instanceof \Exception) {
|
||||
$this->dbMock->subscriptionIcon->throws($out);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon->thenThrow($out);
|
||||
} else {
|
||||
$this->dbMock->subscriptionIcon->returns($this->v($out));
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon->thenReturn($this->v($out));
|
||||
}
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds/2112/icon"));
|
||||
$this->dbMock->subscriptionIcon->calledWith(Arsse::$user->id, 2112);
|
||||
\Phake::verify(Arsse::$db)->subscriptionIcon(Arsse::$user->id, 2112);
|
||||
}
|
||||
|
||||
public function provideIcons(): iterable {
|
||||
|
@ -695,28 +688,28 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideEntryQueries */
|
||||
public function testGetEntries(string $url, ?RootContext $c, ?array $order, $out, bool $count, ResponseInterface $exp): void {
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v(self::FEEDS)));
|
||||
$this->dbMock->articleCount->returns(2112);
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v(self::FEEDS)));
|
||||
\Phake::when(Arsse::$db)->articleCount->thenReturn(2112);
|
||||
if ($out instanceof \Exception) {
|
||||
$this->dbMock->articleList->throws($out);
|
||||
\Phake::when(Arsse::$db)->articleList->thenThrow($out);
|
||||
} else {
|
||||
$this->dbMock->articleList->returns(new Result($this->v($out)));
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->v($out)));
|
||||
}
|
||||
$this->assertMessage($exp, $this->req("GET", $url));
|
||||
if ($c) {
|
||||
$this->dbMock->articleList->calledWith(Arsse::$user->id, $this->equalTo($c), array_keys(self::ENTRIES[0]), $order);
|
||||
\Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, $this->equalTo($c), array_keys(self::ENTRIES[0]), $order);
|
||||
} else {
|
||||
$this->dbMock->articleList->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->articleList(\Phake::anyParameters());
|
||||
}
|
||||
if ($out && !$out instanceof \Exception) {
|
||||
$this->dbMock->subscriptionList->calledWith(Arsse::$user->id);
|
||||
\Phake::verify(Arsse::$db)->subscriptionList(Arsse::$user->id);
|
||||
} else {
|
||||
$this->dbMock->subscriptionList->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->subscriptionList(\Phake::anyParameters());
|
||||
}
|
||||
if ($count) {
|
||||
$this->dbMock->articleCount->calledWith(Arsse::$user->id, $this->equalTo((clone $c)->limit(0)->offset(0)));
|
||||
\Phake::verify(Arsse::$db)->articleCount(Arsse::$user->id, $this->equalTo((clone $c)->limit(0)->offset(0)));
|
||||
} else {
|
||||
$this->dbMock->articleCount->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->articleCount(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -786,22 +779,22 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideSingleEntryQueries */
|
||||
public function testGetASingleEntry(string $url, Context $c, $out, ResponseInterface $exp): void {
|
||||
$this->dbMock->subscriptionPropertiesGet->returns($this->v(self::FEEDS[1]));
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->thenReturn($this->v(self::FEEDS[1]));
|
||||
if ($out instanceof \Exception) {
|
||||
$this->dbMock->articleList->throws($out);
|
||||
\Phake::when(Arsse::$db)->articleList->thenThrow($out);
|
||||
} else {
|
||||
$this->dbMock->articleList->returns(new Result($this->v($out)));
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->v($out)));
|
||||
}
|
||||
$this->assertMessage($exp, $this->req("GET", $url));
|
||||
if ($c) {
|
||||
$this->dbMock->articleList->calledWith(Arsse::$user->id, $this->equalTo($c), array_keys(self::ENTRIES[0]));
|
||||
\Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, $this->equalTo($c), array_keys(self::ENTRIES[0]));
|
||||
} else {
|
||||
$this->dbMock->articleList->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->articleList(\Phake::anyParameters());
|
||||
}
|
||||
if ($out && is_array($out)) {
|
||||
$this->dbMock->subscriptionPropertiesGet->calledWith(Arsse::$user->id, 55);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 55);
|
||||
} else {
|
||||
$this->dbMock->subscriptionList->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->subscriptionList(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -825,12 +818,12 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideEntryMarkings */
|
||||
public function testMarkEntries(array $in, ?array $data, ResponseInterface $exp): void {
|
||||
$this->dbMock->articleMark->returns(0);
|
||||
\Phake::when(Arsse::$db)->articleMark->thenReturn(0);
|
||||
$this->assertMessage($exp, $this->req("PUT", "/entries", $in));
|
||||
if ($data) {
|
||||
$this->dbMock->articleMark->calledWith(Arsse::$user->id, $data, (new Context)->articles($in['entry_ids']));
|
||||
\Phake::verify(Arsse::$db)->articleMark(Arsse::$user->id, $data, (new Context)->articles($in['entry_ids']));
|
||||
} else {
|
||||
$this->dbMock->articleMark->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->articleMark(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -854,15 +847,15 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/** @dataProvider provideMassMarkings */
|
||||
public function testMassMarkEntries(string $url, Context $c, $out, ResponseInterface $exp): void {
|
||||
if ($out instanceof \Exception) {
|
||||
$this->dbMock->articleMark->throws($out);
|
||||
\Phake::when(Arsse::$db)->articleMark->thenThrow($out);
|
||||
} else {
|
||||
$this->dbMock->articleMark->returns($out);
|
||||
\Phake::when(Arsse::$db)->articleMark->thenReturn($out);
|
||||
}
|
||||
$this->assertMessage($exp, $this->req("PUT", $url));
|
||||
if ($out !== null) {
|
||||
$this->dbMock->articleMark->calledWith(Arsse::$user->id, ['read' => true], $this->equalTo($c));
|
||||
\Phake::verify(Arsse::$db)->articleMark(Arsse::$user->id, ['read' => true], $this->equalTo($c));
|
||||
} else {
|
||||
$this->dbMock->articleMark->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->articleMark(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -883,27 +876,27 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/** @dataProvider provideBookmarkTogglings */
|
||||
public function testToggleABookmark($before, ?bool $after, ResponseInterface $exp): void {
|
||||
$c = (new Context)->article(2112);
|
||||
$this->dbMock->articleMark->returns(1);
|
||||
\Phake::when(Arsse::$db)->articleMark->thenReturn(1);
|
||||
if ($before instanceof \Exception) {
|
||||
$this->dbMock->articleCount->throws($before);
|
||||
\Phake::when(Arsse::$db)->articleCount->thenThrow($before);
|
||||
} else {
|
||||
$this->dbMock->articleCount->returns($before);
|
||||
\Phake::when(Arsse::$db)->articleCount->thenReturn($before);
|
||||
}
|
||||
$this->assertMessage($exp, $this->req("PUT", "/entries/2112/bookmark"));
|
||||
if ($after !== null) {
|
||||
Phony::inOrder(
|
||||
$this->dbMock->begin->calledWith(),
|
||||
$this->dbMock->articleCount->calledWith(Arsse::$user->id, (clone $c)->starred(false)),
|
||||
$this->dbMock->articleMark->calledWith(Arsse::$user->id, ['starred' => $after], $c),
|
||||
$this->transaction->commit->called()
|
||||
\Phake::inOrder(
|
||||
\Phake::verify(Arsse::$db)->begin(),
|
||||
\Phake::verify(Arsse::$db)->articleCount(Arsse::$user->id, (clone $c)->starred(false)),
|
||||
\Phake::verify(Arsse::$db)->articleMark(Arsse::$user->id, ['starred' => $after], $c),
|
||||
\Phake::verify($this->transaction)->commit()
|
||||
);
|
||||
} else {
|
||||
Phony::inOrder(
|
||||
$this->dbMock->begin->calledWith(),
|
||||
$this->dbMock->articleCount->calledWith(Arsse::$user->id, (clone $c)->starred(false))
|
||||
\Phake::inOrder(
|
||||
\Phake::verify(Arsse::$db)->begin(),
|
||||
\Phake::verify(Arsse::$db)->articleCount(Arsse::$user->id, (clone $c)->starred(false))
|
||||
);
|
||||
$this->dbMock->articleMark->never()->called();
|
||||
$this->transaction->commit->never()->called();
|
||||
\Phake::verify($this->transaction, \Phake::never())->commit(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->articleMark(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -917,15 +910,15 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testRefreshAFeed(): void {
|
||||
$this->dbMock->subscriptionPropertiesGet->returns([]);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->thenReturn([]);
|
||||
$this->assertMessage(HTTP::respEmpty(204), $this->req("PUT", "/feeds/47/refresh"));
|
||||
$this->dbMock->subscriptionPropertiesGet->calledWith(Arsse::$user->id, 47);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 47);
|
||||
}
|
||||
|
||||
public function testRefreshAMissingFeed(): void {
|
||||
$this->dbMock->subscriptionPropertiesGet->throws(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
$this->assertMessage(V1::respError("404", 404), $this->req("PUT", "/feeds/2112/refresh"));
|
||||
$this->dbMock->subscriptionPropertiesGet->calledWith(Arsse::$user->id, 2112);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, 2112);
|
||||
}
|
||||
|
||||
public function testRefreshAllFeeds(): void {
|
||||
|
@ -934,12 +927,12 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideImports */
|
||||
public function testImport($out, ResponseInterface $exp): void {
|
||||
$opml = $this->mock(OPML::class);
|
||||
$this->objMock->get->with(OPML::class)->returns($opml);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$opml->import->$action($out);
|
||||
$opml = \Phake::mock(OPML::class);
|
||||
\Phake::when(Arsse::$obj)->get(OPML::class)->thenReturn($opml);
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenRreturn";
|
||||
\Phake::when($opml)->import->$action($out);
|
||||
$this->assertMessage($exp, $this->req("POST", "/import", "IMPORT DATA"));
|
||||
$opml->import->calledWith(Arsse::$user->id, "IMPORT DATA");
|
||||
\Phake::verify($opml)->import(Arsse::$user->id, "IMPORT DATA");
|
||||
}
|
||||
|
||||
public function provideImports(): iterable {
|
||||
|
@ -956,10 +949,10 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testExport(): void {
|
||||
$opml = $this->mock(OPML::class);
|
||||
$this->objMock->get->with(OPML::class)->returns($opml);
|
||||
$opml->export->returns("<EXPORT_DATA/>");
|
||||
$opml = \Phake::mock(OPML::class);
|
||||
\Phake::when(Arsse::$obj)->get(OPML::class)->thenReturn($opml);
|
||||
\Phake::when($opml)->export->thenReturn("<EXPORT_DATA/>");
|
||||
$this->assertMessage(HTTP::respText("<EXPORT_DATA/>", 200, ['Content-Type' => "application/xml"]), $this->req("GET", "/export"));
|
||||
$opml->export->calledWith(Arsse::$user->id);
|
||||
\Phake::verify($opml)->export(Arsse::$user->id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -300,9 +300,6 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
|
||||
protected function req(string $method, string $target, $data = "", array $headers = [], bool $authenticated = true, bool $body = true): ResponseInterface {
|
||||
Arsse::$obj = $this->objMock->get();
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
Arsse::$user = $this->userMock->get();
|
||||
Arsse::$user->id = $this->userId;
|
||||
$prefix = "/index.php/apps/news/api/v1-2";
|
||||
$url = $prefix.$target;
|
||||
|
@ -321,12 +318,12 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::setConf();
|
||||
// create a mock user manager
|
||||
$this->userId = "john.doe@example.com";
|
||||
$this->userMock = $this->mock(User::class);
|
||||
$this->userMock->auth->returns(true);
|
||||
$this->userMock->propertiesGet->returns(['admin' => true]);
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
\Phake::when(Arsse::$user)->auth->thenReturn(true);
|
||||
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['admin' => true]);
|
||||
// create a mock database interface
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->begin->returns($this->mock(Transaction::class));
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(Transaction::class));
|
||||
//initialize a handler
|
||||
$this->h = new V1_2();
|
||||
}
|
||||
|
@ -407,7 +404,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 1, 'name' => "Software"],
|
||||
['id' => 12, 'name' => "Hardware"],
|
||||
];
|
||||
$this->dbMock->folderList->with($this->userId, null, false)->returns(new Result($this->v($list)));
|
||||
\Phake::when(Arsse::$db)->folderList($this->userId, null, false)->thenReturn(new Result($this->v($list)));
|
||||
$exp = HTTP::respJson(['folders' => $out]);
|
||||
$this->assertMessage($exp, $this->req("GET", "/folders"));
|
||||
}
|
||||
|
@ -415,18 +412,18 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/** @dataProvider provideFolderCreations */
|
||||
public function testAddAFolder(array $input, bool $body, $output, ResponseInterface $exp): void {
|
||||
if ($output instanceof ExceptionInput) {
|
||||
$this->dbMock->folderAdd->throws($output);
|
||||
\Phake::when(Arsse::$db)->folderAdd->thenThrow($output);
|
||||
} else {
|
||||
$this->dbMock->folderAdd->returns($output);
|
||||
$this->dbMock->folderPropertiesGet->returns($this->v(['id' => $output, 'name' => $input['name'], 'parent' => null]));
|
||||
\Phake::when(Arsse::$db)->folderAdd->thenReturn($output);
|
||||
\Phake::when(Arsse::$db)->folderPropertiesGet->thenReturn($this->v(['id' => $output, 'name' => $input['name'], 'parent' => null]));
|
||||
}
|
||||
$act = $this->req("POST", "/folders", $input, [], true, $body);
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->dbMock->folderAdd->calledWith($this->userId, $input);
|
||||
\Phake::verify(Arsse::$db)->folderAdd($this->userId, $input);
|
||||
if ($output instanceof ExceptionInput) {
|
||||
$this->dbMock->folderPropertiesGet->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->folderPropertiesGet(\Phake::anyParameters());
|
||||
} else {
|
||||
$this->dbMock->folderPropertiesGet->calledWith($this->userId, $this->equalTo($output));
|
||||
\Phake::verify(Arsse::$db)->folderPropertiesGet($this->userId, $this->equalTo($output));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -444,25 +441,25 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testRemoveAFolder(): void {
|
||||
$this->dbMock->folderRemove->with($this->userId, 1)->returns(true)->throws(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->folderRemove($this->userId, 1)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
$exp = HTTP::respEmpty(204);
|
||||
$this->assertMessage($exp, $this->req("DELETE", "/folders/1"));
|
||||
// fail on the second invocation because it no longer exists
|
||||
$exp = HTTP::respEmpty(404);
|
||||
$this->assertMessage($exp, $this->req("DELETE", "/folders/1"));
|
||||
$this->dbMock->folderRemove->times(2)->calledWith($this->userId, 1);
|
||||
\Phake::verify(Arsse::$db, \Phake::times(2))->folderRemove($this->userId, 1);
|
||||
}
|
||||
|
||||
/** @dataProvider provideFolderRenamings */
|
||||
public function testRenameAFolder(array $input, int $id, $output, ResponseInterface $exp): void {
|
||||
if ($output instanceof ExceptionInput) {
|
||||
$this->dbMock->folderPropertiesSet->throws($output);
|
||||
\Phake::when(Arsse::$db)->folderPropertiesSet->thenThrow($output);
|
||||
} else {
|
||||
$this->dbMock->folderPropertiesSet->returns($output);
|
||||
\Phake::when(Arsse::$db)->folderPropertiesSet->thenReturn($output);
|
||||
}
|
||||
$act = $this->req("PUT", "/folders/$id", $input);
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->dbMock->folderPropertiesSet->calledWith($this->userId, $id, $input);
|
||||
\Phake::verify(Arsse::$db)->folderPropertiesSet($this->userId, $id, $input);
|
||||
}
|
||||
|
||||
public function provideFolderRenamings(): array {
|
||||
|
@ -494,9 +491,9 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
'starredCount' => 5,
|
||||
'newestItemId' => 4758915,
|
||||
];
|
||||
$this->dbMock->subscriptionList->with($this->userId)->returns(new Result([]))->returns(new Result($this->v($this->feeds['db'])));
|
||||
$this->dbMock->articleStarred->with($this->userId)->returns($this->v(['total' => 0]))->returns($this->v(['total' => 5]));
|
||||
$this->dbMock->editionLatest->with($this->userId)->returns(0)->returns(4758915);
|
||||
\Phake::when(Arsse::$db)->subscriptionList($this->userId)->theneturn(new Result([]))->thenReturn(new Result($this->v($this->feeds['db'])));
|
||||
\Phake::when(Arsse::$db)->articleStarred($this->userId)->thenReturn($this->v(['total' => 0]))->thenReturn($this->v(['total' => 5]));
|
||||
\Phake::when(Arsse::$db)->editionLatest($this->userId)->thenReturns(0)->thenReturn(4758915);
|
||||
$exp = HTTP::respJson($exp1);
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds"));
|
||||
$exp = HTTP::respJson($exp2);
|
||||
|
@ -506,31 +503,31 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/** @dataProvider provideNewSubscriptions */
|
||||
public function testAddASubscription(array $input, $id, int $latestEdition, array $output, $moveOutcome, ResponseInterface $exp): void {
|
||||
if ($id instanceof \Exception) {
|
||||
$this->dbMock->subscriptionAdd->throws($id);
|
||||
\Phake::when(Arsse::$db)->subscriptionAdd->thenThrow($id);
|
||||
} else {
|
||||
$this->dbMock->subscriptionAdd->returns($id);
|
||||
\Phake::when(Arsse::$db)->subscriptionAdd->thenReturn($id);
|
||||
}
|
||||
if ($moveOutcome instanceof \Exception) {
|
||||
$this->dbMock->subscriptionPropertiesSet->throws($moveOutcome);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenThrow($moveOutcome);
|
||||
} else {
|
||||
$this->dbMock->subscriptionPropertiesSet->returns($moveOutcome);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenReturn($moveOutcome);
|
||||
}
|
||||
$this->dbMock->subscriptionPropertiesGet->returns($this->v($output));
|
||||
$this->dbMock->editionLatest->returns($latestEdition);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->thenReturn($this->v($output));
|
||||
\Phake::when(Arsse::$db)->editionLatest->thenReturn($latestEdition);
|
||||
$act = $this->req("POST", "/feeds", $input);
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->dbMock->subscriptionAdd->calledWith($this->userId, $input['url'] ?? "");
|
||||
\Phake::verify(Arsse::$db)->subscriptionAdd($this->userId, $input['url'] ?? "");
|
||||
if ($id instanceof \Exception) {
|
||||
$this->dbMock->subscriptionPropertiesSet->never()->called();
|
||||
$this->dbMock->subscriptionPropertiesGet->never()->called();
|
||||
$this->dbMock->editionLatest->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesSet(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesGet(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db, \Phake::times(0))->editionLatest(\Phake::anyParameters());
|
||||
} else {
|
||||
$this->dbMock->subscriptionPropertiesGet->calledWith($this->userId, $id);
|
||||
$this->dbMock->editionLatest->calledWith($this->userId, $this->equalTo((new Context)->subscription($id)->hidden(false)));
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesGet($this->userId, $id);
|
||||
\Phake::verify(Arsse::$db)->editionLatest($this->userId, $this->equalTo((new Context)->subscription($id)->hidden(false)));
|
||||
if ($input['folderId'] ?? 0) {
|
||||
$this->dbMock->subscriptionPropertiesSet->calledWith($this->userId, $id, ['folder' => (int) $input['folderId']]);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet($this->userId, $id, ['folder' => (int) $input['folderId']]);
|
||||
} else {
|
||||
$this->dbMock->subscriptionPropertiesSet->never()->called();
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -548,13 +545,13 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testRemoveASubscription(): void {
|
||||
$this->dbMock->subscriptionRemove->with($this->userId, 1)->returns(true)->throws(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionRemove($this->userId, 1)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
$exp = HTTP::respEmpty(204);
|
||||
$this->assertMessage($exp, $this->req("DELETE", "/feeds/1"));
|
||||
// fail on the second invocation because it no longer exists
|
||||
$exp = HTTP::respEmpty(404);
|
||||
$this->assertMessage($exp, $this->req("DELETE", "/feeds/1"));
|
||||
$this->dbMock->subscriptionRemove->times(2)->calledWith($this->userId, 1);
|
||||
\Phake::verify(Arsse::$db, \Phake::times(2))->subscriptionRemove($this->userId, 1);
|
||||
}
|
||||
|
||||
public function testMoveASubscription(): void {
|
||||
|
@ -566,11 +563,11 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['folderId' => -1],
|
||||
[],
|
||||
];
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, ['folder' => 42])->returns(true);
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, ['folder' => null])->returns(true);
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, ['folder' => 2112])->throws(new ExceptionInput("idMissing")); // folder does not exist
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, ['folder' => -1])->throws(new ExceptionInput("typeViolation")); // folder is invalid
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 42, $this->anything())->throws(new ExceptionInput("subjectMissing")); // subscription does not exist
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 1, ['folder' => 42])->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 1, ['folder' => null])->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 1, ['folder' => 2112])->thenThrow(new ExceptionInput("idMissing")); // folder does not exist
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 1, ['folder' => -1])->thenThrow(new ExceptionInput("typeViolation")); // folder is invalid
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 42, $this->anything())->thenThrow(new ExceptionInput("subjectMissing")); // subscription does not exist
|
||||
$exp = HTTP::respEmpty(204);
|
||||
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/move", json_encode($in[0])));
|
||||
$exp = HTTP::respEmpty(204);
|
||||
|
@ -595,12 +592,12 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['feedTitle' => "Feed does not exist"],
|
||||
[],
|
||||
];
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, $this->identicalTo(['title' => null]))->returns(true);
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, $this->identicalTo(['title' => "Ook"]))->returns(true);
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, $this->identicalTo(['title' => " "]))->throws(new ExceptionInput("whitespace"));
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, $this->identicalTo(['title' => ""]))->throws(new ExceptionInput("missing"));
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, $this->identicalTo(['title' => false]))->throws(new ExceptionInput("missing"));
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 42, $this->anything())->throws(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 1, $this->identicalTo(['title' => null]))->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 1, $this->identicalTo(['title' => "Ook"]))->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 1, $this->identicalTo(['title' => " "]))->thenThrow(new ExceptionInput("whitespace"));
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 1, $this->identicalTo(['title' => ""]))->thenThrow(new ExceptionInput("missing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 1, $this->identicalTo(['title' => false]))->thenThrow(new ExceptionInput("missing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 42, $this->anything())->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
$exp = HTTP::respEmpty(422);
|
||||
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/rename", json_encode($in[0])));
|
||||
$exp = HTTP::respEmpty(204);
|
||||
|
@ -626,16 +623,16 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
'userId' => "",
|
||||
],
|
||||
];
|
||||
$this->dbMock->feedListStale->returns($this->v(array_column($out, "id")));
|
||||
\Phake::when(Arsse::$db)->feedListStale->thenReturn($this->v(array_column($out, "id")));
|
||||
$exp = HTTP::respJson(['feeds' => $out]);
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds/all"));
|
||||
}
|
||||
|
||||
public function testListStaleFeedsWithoutAuthority(): void {
|
||||
$this->userMock->propertiesGet->returns(['admin' => false]);
|
||||
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['admin' => false]);
|
||||
$exp = HTTP::respEmpty(403);
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds/all"));
|
||||
$this->dbMock->feedListStale->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->feedListStale(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function testUpdateAFeed(): void {
|
||||
|
@ -646,9 +643,9 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['feedId' => -1], // invalid ID
|
||||
['feed' => 42], // invalid input
|
||||
];
|
||||
$this->dbMock->feedUpdate->with(42)->returns(true);
|
||||
$this->dbMock->feedUpdate->with(2112)->throws(new ExceptionInput("subjectMissing"));
|
||||
$this->dbMock->feedUpdate->with($this->lessThan(1))->throws(new ExceptionInput("typeViolation"));
|
||||
\Phake::when(Arsse::$db)->feedUpdate(42)->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->feedUpdate(2112)->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->feedUpdate($this->lessThan(1))->thenThrow(new ExceptionInput("typeViolation"));
|
||||
$exp = HTTP::respEmpty(204);
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds/update", json_encode($in[0])));
|
||||
$exp = HTTP::respEmpty(404);
|
||||
|
@ -660,23 +657,23 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testUpdateAFeedWithoutAuthority(): void {
|
||||
$this->userMock->propertiesGet->returns(['admin' => false]);
|
||||
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['admin' => false]);
|
||||
$exp = HTTP::respEmpty(403);
|
||||
$this->assertMessage($exp, $this->req("GET", "/feeds/update", ['feedId' => 42]));
|
||||
$this->dbMock->feedUpdate->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->feedUpdate(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
/** @dataProvider provideArticleQueries */
|
||||
public function testListArticles(string $url, array $in, Context $c, $out, ResponseInterface $exp): void {
|
||||
if ($out instanceof \Exception) {
|
||||
$this->dbMock->articleList->throws($out);
|
||||
\Phake::when(Arsse::$db)->articleList->thenThrow($out);
|
||||
} else {
|
||||
$this->dbMock->articleList->returns($out);
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn($out);
|
||||
}
|
||||
$this->assertMessage($exp, $this->req("GET", $url, $in));
|
||||
$columns = ["edition", "guid", "id", "url", "title", "author", "edited_date", "content", "media_type", "media_url", "subscription", "unread", "starred", "modified_date", "fingerprint"];
|
||||
$order = ($in['oldestFirst'] ?? false) ? "edition" : "edition desc";
|
||||
$this->dbMock->articleList->calledWith($this->userId, $this->equalTo($c), $columns, [$order]);
|
||||
\Phake::verify(Arsse::$db)->articleList($this->userId, $this->equalTo($c), $columns, [$order]);
|
||||
}
|
||||
|
||||
public function provideArticleQueries(): iterable {
|
||||
|
@ -718,8 +715,8 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testMarkAFolderRead(): void {
|
||||
$read = ['read' => true];
|
||||
$in = json_encode(['newestItemId' => 2112]);
|
||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->folder(1)->editionRange(null, 2112)->hidden(false)))->returns(42);
|
||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->folder(42)->editionRange(null, 2112)->hidden(false)))->throws(new ExceptionInput("idMissing")); // folder doesn't exist
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $read, $this->equalTo((new Context)->folder(1)->editionRange(null, 2112)->hidden(false)))->thenReturn(42);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $read, $this->equalTo((new Context)->folder(42)->editionRange(null, 2112)->hidden(false)))->thenThrow(new ExceptionInput("idMissing")); // folder doesn't exist
|
||||
$exp = HTTP::respEmpty(204);
|
||||
$this->assertMessage($exp, $this->req("PUT", "/folders/1/read", $in));
|
||||
$this->assertMessage($exp, $this->req("PUT", "/folders/1/read?newestItemId=2112"));
|
||||
|
@ -733,8 +730,8 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testMarkASubscriptionRead(): void {
|
||||
$read = ['read' => true];
|
||||
$in = json_encode(['newestItemId' => 2112]);
|
||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->subscription(1)->editionRange(null, 2112)->hidden(false)))->returns(42);
|
||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->subscription(42)->editionRange(null, 2112)->hidden(false)))->throws(new ExceptionInput("idMissing")); // subscription doesn't exist
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $read, $this->equalTo((new Context)->subscription(1)->editionRange(null, 2112)->hidden(false)))->thenReturn(42);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $read, $this->equalTo((new Context)->subscription(42)->editionRange(null, 2112)->hidden(false)))->thenThrow(new ExceptionInput("idMissing")); // subscription doesn't exist
|
||||
$exp = HTTP::respEmpty(204);
|
||||
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/read", $in));
|
||||
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/read?newestItemId=2112"));
|
||||
|
@ -748,7 +745,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testMarkAllItemsRead(): void {
|
||||
$read = ['read' => true];
|
||||
$in = json_encode(['newestItemId' => 2112]);
|
||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->editionRange(null, 2112)))->returns(42);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $read, $this->equalTo((new Context)->editionRange(null, 2112)))->thenReturn(42);
|
||||
$exp = HTTP::respEmpty(204);
|
||||
$this->assertMessage($exp, $this->req("PUT", "/items/read", $in));
|
||||
$this->assertMessage($exp, $this->req("PUT", "/items/read?newestItemId=2112"));
|
||||
|
@ -762,14 +759,14 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$unread = ['read' => false];
|
||||
$star = ['starred' => true];
|
||||
$unstar = ['starred' => false];
|
||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->edition(1)))->returns(42);
|
||||
$this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->edition(42)))->throws(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist
|
||||
$this->dbMock->articleMark->with($this->userId, $unread, $this->equalTo((new Context)->edition(2)))->returns(42);
|
||||
$this->dbMock->articleMark->with($this->userId, $unread, $this->equalTo((new Context)->edition(47)))->throws(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist
|
||||
$this->dbMock->articleMark->with($this->userId, $star, $this->equalTo((new Context)->article(3)))->returns(42);
|
||||
$this->dbMock->articleMark->with($this->userId, $star, $this->equalTo((new Context)->article(2112)))->throws(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist
|
||||
$this->dbMock->articleMark->with($this->userId, $unstar, $this->equalTo((new Context)->article(4)))->returns(42);
|
||||
$this->dbMock->articleMark->with($this->userId, $unstar, $this->equalTo((new Context)->article(1337)))->throws(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $read, $this->equalTo((new Context)->edition(1)))->thenReturn(42);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $read, $this->equalTo((new Context)->edition(42)))->thenThrow(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $unread, $this->equalTo((new Context)->edition(2)))->thenReturn(42);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $unread, $this->equalTo((new Context)->edition(47)))->thenThrow(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $star, $this->equalTo((new Context)->article(3)))->thenReturn(42);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $star, $this->equalTo((new Context)->article(2112)))->thenThrow(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $unstar, $this->equalTo((new Context)->article(4)))->thenReturn(42);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $unstar, $this->equalTo((new Context)->article(1337)))->thenThrow(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist
|
||||
$exp = HTTP::respEmpty(204);
|
||||
$this->assertMessage($exp, $this->req("PUT", "/items/1/read"));
|
||||
$this->assertMessage($exp, $this->req("PUT", "/items/2/unread"));
|
||||
|
@ -780,7 +777,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("PUT", "/items/47/unread"));
|
||||
$this->assertMessage($exp, $this->req("PUT", "/items/1/2112/star"));
|
||||
$this->assertMessage($exp, $this->req("PUT", "/items/4400/1337/unstar"));
|
||||
$this->dbMock->articleMark->times(8)->calledWith($this->userId, $this->anything(), $this->anything());
|
||||
\Phake::verify(Arsse::$db, \Phake::times(8))->articleMark($this->userId, \Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function testChangeMarksOfMultipleArticles(): void {
|
||||
|
@ -798,9 +795,9 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$inStar[$a][$b] = ['feedId' => 2112, 'guidHash' => $inStar[$a][$b]];
|
||||
}
|
||||
}
|
||||
$this->dbMock->articleMark->with($this->userId, $this->anything(), $this->anything())->returns(42);
|
||||
$this->dbMock->articleMark->with($this->userId, $this->anything(), $this->equalTo((new Context)->editions([])))->throws(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples
|
||||
$this->dbMock->articleMark->with($this->userId, $this->anything(), $this->equalTo((new Context)->articles([])))->throws(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $this->anything(), $this->anything())->thenReturn(42);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $this->anything(), $this->equalTo((new Context)->editions([])))->thenThrow(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, $this->anything(), $this->equalTo((new Context)->articles([])))->thenThrow(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples
|
||||
$exp = HTTP::respEmpty(204);
|
||||
$this->assertMessage($exp, $this->req("PUT", "/items/read/multiple"));
|
||||
$this->assertMessage($exp, $this->req("PUT", "/items/unread/multiple"));
|
||||
|
@ -823,27 +820,27 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertMessage($exp, $this->req("PUT", "/items/star/multiple", json_encode(['items' => $inStar[1]])));
|
||||
$this->assertMessage($exp, $this->req("PUT", "/items/unstar/multiple", json_encode(['items' => $inStar[1]])));
|
||||
// ensure the data model was queried appropriately for read/unread
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $read, $this->equalTo((new Context)->editions([])));
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $read, $this->equalTo((new Context)->editions($in[0])));
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $read, $this->equalTo((new Context)->editions($in[1])));
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unread, $this->equalTo((new Context)->editions([])));
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unread, $this->equalTo((new Context)->editions($in[0])));
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unread, $this->equalTo((new Context)->editions($in[1])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $read, $this->equalTo((new Context)->editions([])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $read, $this->equalTo((new Context)->editions($in[0])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $read, $this->equalTo((new Context)->editions($in[1])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $unread, $this->equalTo((new Context)->editions([])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $unread, $this->equalTo((new Context)->editions($in[0])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $unread, $this->equalTo((new Context)->editions($in[1])));
|
||||
// ensure the data model was queried appropriately for star/unstar
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $star, $this->equalTo((new Context)->articles([])));
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $star, $this->equalTo((new Context)->articles($in[0])));
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $star, $this->equalTo((new Context)->articles($in[1])));
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unstar, $this->equalTo((new Context)->articles([])));
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unstar, $this->equalTo((new Context)->articles($in[0])));
|
||||
$this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unstar, $this->equalTo((new Context)->articles($in[1])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $star, $this->equalTo((new Context)->articles([])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $star, $this->equalTo((new Context)->articles($in[0])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $star, $this->equalTo((new Context)->articles($in[1])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $unstar, $this->equalTo((new Context)->articles([])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $unstar, $this->equalTo((new Context)->articles($in[0])));
|
||||
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark($this->userId, $unstar, $this->equalTo((new Context)->articles($in[1])));
|
||||
}
|
||||
|
||||
public function testQueryTheServerStatus(): void {
|
||||
$interval = Arsse::$conf->serviceFrequency;
|
||||
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
|
||||
$invalid = $valid->sub($interval)->sub($interval);
|
||||
$this->dbMock->metaGet->with("service_last_checkin")->returns(Date::transform($valid, "sql"))->returns(Date::transform($invalid, "sql"));
|
||||
$this->dbMock->driverCharsetAcceptable->returns(true)->returns(false);
|
||||
\Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"))->thenReturn(Date::transform($invalid, "sql"));
|
||||
\Phake::when(Arsse::$db)->driverCharsetAcceptable->thenReturn(true)->thenReturn(false);
|
||||
$arr1 = $arr2 = [
|
||||
'version' => V1_2::VERSION,
|
||||
'arsse_version' => Arsse::VERSION,
|
||||
|
@ -859,31 +856,31 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testCleanUpBeforeUpdate(): void {
|
||||
$this->dbMock->feedCleanup->with()->returns(true);
|
||||
\Phake::when(Arsse::$db)->feedCleanup()->thenReturn(true);
|
||||
$exp = HTTP::respEmpty(204);
|
||||
$this->assertMessage($exp, $this->req("GET", "/cleanup/before-update"));
|
||||
$this->dbMock->feedCleanup->calledWith();
|
||||
\Phake::verify(Arsse::$db)->feedCleanup();
|
||||
}
|
||||
|
||||
public function testCleanUpBeforeUpdateWithoutAuthority(): void {
|
||||
$this->userMock->propertiesGet->returns(['admin' => false]);
|
||||
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['admin' => false]);
|
||||
$exp = HTTP::respEmpty(403);
|
||||
$this->assertMessage($exp, $this->req("GET", "/cleanup/before-update"));
|
||||
$this->dbMock->feedCleanup->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->feedCleanup(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function testCleanUpAfterUpdate(): void {
|
||||
$this->dbMock->articleCleanup->with()->returns(true);
|
||||
\Phake::when(Arsse::$db)->articleCleanup()->thenReturn(true);
|
||||
$exp = HTTP::respEmpty(204);
|
||||
$this->assertMessage($exp, $this->req("GET", "/cleanup/after-update"));
|
||||
$this->dbMock->articleCleanup->calledWith();
|
||||
\Phake::verify(Arsse::$db)->articleCleanup();
|
||||
}
|
||||
|
||||
public function testCleanUpAfterUpdateWithoutAuthority(): void {
|
||||
$this->userMock->propertiesGet->returns(['admin' => false]);
|
||||
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['admin' => false]);
|
||||
$exp = HTTP::respEmpty(403);
|
||||
$this->assertMessage($exp, $this->req("GET", "/cleanup/after-update"));
|
||||
$this->dbMock->feedCleanup->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->feedCleanup(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function testQueryTheUserStatus(): void {
|
||||
|
@ -902,10 +899,10 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$url = "/folders?name=Hardware";
|
||||
$out1 = ['id' => 1, 'name' => "Software"];
|
||||
$out2 = ['id' => 2, 'name' => "Hardware"];
|
||||
$this->dbMock->folderAdd->with($this->anything(), $this->anything())->returns(2);
|
||||
$this->dbMock->folderAdd->with($this->anything(), $in)->returns(1);
|
||||
$this->dbMock->folderPropertiesGet->with($this->userId, 1)->returns($this->v($out1));
|
||||
$this->dbMock->folderPropertiesGet->with($this->userId, 2)->returns($this->v($out2));
|
||||
\Phake::when(Arsse::$db)->folderAdd($this->anything(), $this->anything())->thenReturn(2);
|
||||
\Phake::when(Arsse::$db)->folderAdd($this->anything(), $in)->thenReturn(1);
|
||||
\Phake::when(Arsse::$db)->folderPropertiesGet($this->userId, 1)->thenReturn($this->v($out1));
|
||||
\Phake::when(Arsse::$db)->folderPropertiesGet($this->userId, 2)->thenReturn($this->v($out2));
|
||||
$exp = HTTP::respJson(['folders' => [$out1]]);
|
||||
$this->assertMessage($exp, $this->req("POST", $url, json_encode($in)));
|
||||
}
|
||||
|
@ -913,8 +910,8 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testMeldJsonAndQueryParameters(): void {
|
||||
$in = ['oldestFirst' => true];
|
||||
$url = "/items?type=2";
|
||||
$this->dbMock->articleList->returns(new Result([]));
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn(new Result([]));
|
||||
$this->req("GET", $url, json_encode($in));
|
||||
$this->dbMock->articleList->calledWith($this->userId, $this->equalTo((new Context)->starred(true)->hidden(false)), $this->anything(), ["edition"]);
|
||||
\Phake::verify(Arsse::$db)->articleList($this->userId, $this->equalTo((new Context)->starred(true)->hidden(false)), $this->anything(), ["edition"]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,12 +62,11 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testAuthenticateRequests(array $serverParams, array $expAttr): void {
|
||||
$r = new REST();
|
||||
// create a mock user manager
|
||||
$this->userMock = $this->mock(User::class);
|
||||
$this->userMock->auth->returns(false);
|
||||
$this->userMock->auth->with("john.doe@example.com", "secret")->returns(true);
|
||||
$this->userMock->auth->with("john.doe@example.com", "")->returns(true);
|
||||
$this->userMock->auth->with("someone.else@example.com", "")->returns(true);
|
||||
Arsse::$user = $this->userMock->get();
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
\Phake::when(Arsse::$user)->auth->thenReturn(false);
|
||||
\Phake::when(Arsse::$user)->auth("john.doe@example.com", "secret")->thenReturn(true);
|
||||
\Phake::when(Arsse::$user)->auth("john.doe@example.com", "")->thenReturn(true);
|
||||
\Phake::when(Arsse::$user)->auth("someone.else@example.com", "")->thenReturn(true);
|
||||
// create an input server request
|
||||
$req = new ServerRequest("GET", "/", [], null, "1.1", $serverParams);
|
||||
// create the expected output
|
||||
|
@ -150,13 +149,13 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/** @dataProvider provideCorsNegotiations */
|
||||
public function testNegotiateCors($origin, bool $exp, ?string $allowed = null, ?string $denied = null): void {
|
||||
self::setConf();
|
||||
$rMock = $this->partialMock(REST::class);
|
||||
$rMock->corsNormalizeOrigin->does(function($origin) {
|
||||
$rMock = \Phake::partialMock(REST::class);
|
||||
\Phake::when($rMock)->corsNormalizeOrigin->thenReturnCallback(function($origin) {
|
||||
return $origin;
|
||||
});
|
||||
$headers = isset($origin) ? ['Origin' => $origin] : [];
|
||||
$req = new Request("GET", "", $headers);
|
||||
$act = $rMock->get()->corsNegotiate($req, $allowed, $denied);
|
||||
$act = $rMock->corsNegotiate($req, $allowed, $denied);
|
||||
$this->assertSame($exp, $act);
|
||||
}
|
||||
|
||||
|
@ -251,15 +250,15 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideUnnormalizedResponses */
|
||||
public function testNormalizeHttpResponses(ResponseInterface $res, ResponseInterface $exp, ?RequestInterface $req = null): void {
|
||||
$rMock = $this->partialMock(REST::class);
|
||||
$rMock->corsNegotiate->returns(true);
|
||||
$rMock->challenge->does(function($res) {
|
||||
$rMock = \Phake::partialMock(REST::class);
|
||||
\Phake::when($rMock)->corsNegotiate->thenReturn(true);
|
||||
\Phake::when($rMock)->challenge->thenReturnCallback(function($res) {
|
||||
return $res->withHeader("WWW-Authenticate", "Fake Value");
|
||||
});
|
||||
$rMock->corsApply->does(function($res) {
|
||||
\Phake::when($rMock)->corsApply->thenReturnCallback(function($res) {
|
||||
return $res;
|
||||
});
|
||||
$act = $rMock->get()->normalizeResponse($res, $req);
|
||||
$act = $rMock->normalizeResponse($res, $req);
|
||||
$this->assertMessage($exp, $act);
|
||||
}
|
||||
|
||||
|
@ -287,32 +286,30 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideMockRequests */
|
||||
public function testDispatchRequests(ServerRequest $req, string $method, bool $called, string $class = "", string $target = ""): void {
|
||||
$rMock = $this->partialMock(REST::class);
|
||||
$rMock->normalizeResponse->does(function($res) {
|
||||
$rMock = \Phake::partialMock(REST::class);
|
||||
\Phake::when($rMock)->normalizeResponse->thenReturnCallback(function($res) {
|
||||
return $res;
|
||||
});
|
||||
$rMock->authenticateRequest->does(function($req) {
|
||||
\Phake::when($rMock)->authenticateRequest->thenReturnCallback(function($req) {
|
||||
return $req;
|
||||
});
|
||||
if ($called) {
|
||||
$hMock = $this->mock($class);
|
||||
$hMock->dispatch->returns(HTTP::respEmpty(204));
|
||||
$this->objMock->get->with($class)->returns($hMock);
|
||||
Arsse::$obj = $this->objMock->get();
|
||||
$hMock = \Phake::mock($class);
|
||||
$hMock->dispatch->thenReturn(HTTP::respEmpty(204));
|
||||
\Phake::when(Arsse::$obj)->get($class)->thenReturn($hMock);
|
||||
}
|
||||
$out = $rMock->get()->dispatch($req);
|
||||
$out = $rMock->dispatch($req);
|
||||
$this->assertInstanceOf(ResponseInterface::class, $out);
|
||||
if ($called) {
|
||||
$rMock->authenticateRequest->called();
|
||||
$hMock->dispatch->once()->called();
|
||||
$in = $hMock->dispatch->firstCall()->argument();
|
||||
\Phake::verify($rMock, \Phake::atLeast(1))->authenticateRequest(\Phake::anyParameters());
|
||||
\Phake::verify($hMock)->dispatch(\Phake::capture($in));
|
||||
$this->assertSame($method, $in->getMethod());
|
||||
$this->assertSame($target, $in->getRequestTarget());
|
||||
} else {
|
||||
$this->assertSame(501, $out->getStatusCode());
|
||||
}
|
||||
$rMock->apiMatch->called();
|
||||
$rMock->normalizeResponse->called();
|
||||
\Phake::verify($rMock)->apiMatch(\Phake::anyParameters());
|
||||
\Phake::verify($rMock)->normalizeResponse(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function provideMockRequests(): iterable {
|
||||
|
|
|
@ -132,16 +132,16 @@ LONG_STRING;
|
|||
parent::setUp();
|
||||
self::setConf();
|
||||
// create mock timestamps
|
||||
$this->objMock->get->with(\DateTimeImmutable::class)->returns(new \DateTimeImmutable(self::NOW));
|
||||
\Phake::when(Arsse::$obj)->get(\DateTimeImmutable::class)->thenReturn(new \DateTimeImmutable(self::NOW));
|
||||
// create a mock user manager
|
||||
$this->userId = "john.doe@example.com";
|
||||
$this->userMock = $this->mock(User::class);
|
||||
$this->userMock->auth->returns(true);
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
\Phake::when(Arsse::$user)->auth->thenReturn(true);
|
||||
// create a mock database interface
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->begin->returns($this->mock(Transaction::class));
|
||||
$this->dbMock->sessionResume->throws(new \JKingWeb\Arsse\User\ExceptionSession("invalid"));
|
||||
$this->dbMock->sessionResume->with("PriestsOfSyrinx")->returns([
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(Transaction::class));
|
||||
\Phake::when(Arsse::$db)->sessionResume->thenThrow(new \JKingWeb\Arsse\User\ExceptionSession("invalid"));
|
||||
\Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([
|
||||
'id' => "PriestsOfSyrinx",
|
||||
'created' => "2000-01-01 00:00:00",
|
||||
'expires' => "2112-12-21 21:12:00",
|
||||
|
@ -151,9 +151,6 @@ LONG_STRING;
|
|||
}
|
||||
|
||||
protected function req($data, string $method = "POST", string $target = "", ?string $strData = null, ?string $user = null): ResponseInterface {
|
||||
Arsse::$obj = $this->objMock->get();
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
Arsse::$user = $this->userMock->get();
|
||||
Arsse::$user->id = $this->userId;
|
||||
$prefix = "/tt-rss/api";
|
||||
$url = $prefix.$target;
|
||||
|
@ -210,11 +207,11 @@ LONG_STRING;
|
|||
public function testLogIn(array $conf, $httpUser, array $data, $sessions): void {
|
||||
$this->userId = null;
|
||||
self::setConf($conf);
|
||||
$this->userMock->auth->returns(false);
|
||||
$this->userMock->auth->with("john.doe@example.com", "secret")->returns(true);
|
||||
$this->userMock->auth->with("jane.doe@example.com", "superman")->returns(true);
|
||||
$this->dbMock->sessionCreate->with("john.doe@example.com")->returns("PriestsOfSyrinx", "SolarFederation");
|
||||
$this->dbMock->sessionCreate->with("jane.doe@example.com")->returns("ClockworkAngels", "SevenCitiesOfGold");
|
||||
\Phake::when(Arsse::$user)->auth->thenReturn(false);
|
||||
\Phake::when(Arsse::$user)->auth("john.doe@example.com", "secret")->thenReturn(true);
|
||||
\Phake::when(Arsse::$user)->auth("jane.doe@example.com", "superman")->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->sessionCreate("john.doe@example.com")->thenReturn("PriestsOfSyrinx", "SolarFederation");
|
||||
\Phake::when(Arsse::$db)->sessionCreate("jane.doe@example.com")->thenReturn("ClockworkAngels", "SevenCitiesOfGold");
|
||||
if ($sessions instanceof ResponseInterface) {
|
||||
$exp1 = $sessions;
|
||||
$exp2 = $sessions;
|
||||
|
@ -233,7 +230,7 @@ LONG_STRING;
|
|||
}
|
||||
$this->assertMessage($exp2, $this->reqAuth($data, $httpUser));
|
||||
// logging in should never try to resume a session
|
||||
$this->dbMock->sessionResume->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->sessionResume(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function provideLoginRequests(): iterable {
|
||||
|
@ -244,13 +241,13 @@ LONG_STRING;
|
|||
public function testValidateASession(array $conf, $httpUser, string $data, $result): void {
|
||||
$this->userId = null;
|
||||
self::setConf($conf);
|
||||
$this->dbMock->sessionResume->with("PriestsOfSyrinx")->returns([
|
||||
\Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([
|
||||
'id' => "PriestsOfSyrinx",
|
||||
'created' => "2000-01-01 00:00:00",
|
||||
'expires' => "2112-12-21 21:12:00",
|
||||
'user' => "john.doe@example.com",
|
||||
]);
|
||||
$this->dbMock->sessionResume->with("ClockworkAngels")->returns([
|
||||
\Phake::when(Arsse::$db)->sessionResume("ClockworkAngels")->thenReturn([
|
||||
'id' => "ClockworkAngels",
|
||||
'created' => "2000-01-01 00:00:00",
|
||||
'expires' => "2112-12-21 21:12:00",
|
||||
|
@ -526,7 +523,7 @@ LONG_STRING;
|
|||
}
|
||||
|
||||
public function testHandleGenericError(): void {
|
||||
$this->userMock->auth->throws(new \JKingWeb\Arsse\Db\ExceptionTimeout("general"));
|
||||
\Phake::when(Arsse::$user)->auth->thenThrow(new \JKingWeb\Arsse\Db\ExceptionTimeout("general"));
|
||||
$data = [
|
||||
'op' => "login",
|
||||
'user' => $this->userId,
|
||||
|
@ -537,14 +534,14 @@ LONG_STRING;
|
|||
}
|
||||
|
||||
public function testLogOut(): void {
|
||||
$this->dbMock->sessionDestroy->returns(true);
|
||||
\Phake::when(Arsse::$db)->sessionDestroy->thenReturn(true);
|
||||
$data = [
|
||||
'op' => "logout",
|
||||
'sid' => "PriestsOfSyrinx",
|
||||
];
|
||||
$exp = $this->respGood(['status' => "OK"]);
|
||||
$this->assertMessage($exp, $this->req($data));
|
||||
$this->dbMock->sessionDestroy->calledWith($this->userId, "PriestsOfSyrinx");
|
||||
\Phake::verify(Arsse::$db)->sessionDestroy($this->userId, "PriestsOfSyrinx");
|
||||
}
|
||||
|
||||
public function testHandleUnknownMethods(): void {
|
||||
|
@ -595,19 +592,19 @@ LONG_STRING;
|
|||
/** @dataProvider provideCategoryAdditions */
|
||||
public function testAddACategory(array $in, array $data, $out, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "addCategory", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$this->dbMock->folderAdd->$action($out);
|
||||
$this->dbMock->folderList->with("~", null, false)->returns(new Result($this->v([
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$db)->folderAdd->$action($out);
|
||||
\Phake::when(Arsse::$db)->folderList($this->anything(), null, false)->thenReturn(new Result($this->v([
|
||||
['id' => 2, 'name' => "Software", 'parent' => null],
|
||||
['id' => 1, 'name' => "Politics", 'parent' => null],
|
||||
])));
|
||||
$this->dbMock->folderList->with("~", 1, false)->returns(new Result($this->v([
|
||||
\Phake::when(Arsse::$db)->folderList($this->anything(), 1, false)->thenReturn(new Result($this->v([
|
||||
['id' => 3, 'name' => "Hardware", 'parent' => 1],
|
||||
])));
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
$this->dbMock->folderAdd->calledWith($this->userId, $data);
|
||||
\Phake::verify(Arsse::$db)->folderAdd($this->userId, $data);
|
||||
if (!$out instanceof \Exception) {
|
||||
$this->dbMock->folderList->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->folderList(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -627,11 +624,11 @@ LONG_STRING;
|
|||
/** @dataProvider provideCategoryRemovals */
|
||||
public function testRemoveACategory(array $in, ?int $data, $out, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "removeCategory", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$this->dbMock->folderRemove->$action($out);
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$db)->folderRemove->$action($out);
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($data > 0) {
|
||||
$this->dbMock->folderRemove->calledWith($this->userId, (int) $data);
|
||||
\Phake::verify(Arsse::$db)->folderRemove($this->userId, (int) $data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -647,13 +644,13 @@ LONG_STRING;
|
|||
/** @dataProvider provideCategoryMoves */
|
||||
public function testMoveACategory(array $in, array $data, $out, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "moveCategory", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$this->dbMock->folderPropertiesSet->$action($out);
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$db)->folderPropertiesSet->$action($out);
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($out !== null) {
|
||||
$this->dbMock->folderPropertiesSet->calledWith(...$data);
|
||||
\Phake::verify(Arsse::$db)->folderPropertiesSet(...$data);
|
||||
} else {
|
||||
$this->dbMock->folderPropertiesSet->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->folderPropertiesSet(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -674,13 +671,13 @@ LONG_STRING;
|
|||
/** @dataProvider provideCategoryRenamings */
|
||||
public function testRenameACategory(array $in, ?array $data, $out, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "renameCategory", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$this->dbMock->folderPropertiesSet->$action($out);
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$db)->folderPropertiesSet->$action($out);
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($out !== null) {
|
||||
$this->dbMock->folderPropertiesSet->calledWith(...$data);
|
||||
\Phake::verify(Arsse::$db)->folderPropertiesSet(...$data);
|
||||
} else {
|
||||
$this->dbMock->folderPropertiesSet->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->folderPropertiesSet(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -701,27 +698,27 @@ LONG_STRING;
|
|||
/** @dataProvider provideFeedSubscriptions */
|
||||
public function testAddASubscription(array $in, ?array $data, $out, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "subscribeToFeed", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
$list = [
|
||||
['id' => 1, 'url' => "http://localhost:8000/Feed/Discovery/Feed"],
|
||||
['id' => 2, 'url' => "http://example.com/0"],
|
||||
['id' => 3, 'url' => "http://example.com/3"],
|
||||
['id' => 4, 'url' => "http://example.com/9"],
|
||||
];
|
||||
$this->dbMock->subscriptionAdd->$action($out);
|
||||
$this->dbMock->folderPropertiesGet->with($this->userId, 42)->returns($this->v(['id' => 42]));
|
||||
$this->dbMock->folderPropertiesGet->with($this->userId, 47)->returns($this->v(['id' => 47]));
|
||||
$this->dbMock->folderPropertiesGet->with($this->userId, 2112)->throws(new ExceptionInput("subjectMissing"));
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, "*")->returns(true);
|
||||
$this->dbMock->subscriptionPropertiesSet->with($this->userId, 4, "~")->throws(new ExceptionInput("idMissing"));
|
||||
$this->dbMock->subscriptionList->with($this->userId)->returns(new Result($this->v($list)));
|
||||
\Phake::when(Arsse::$db)->subscriptionAdd->$action($out);
|
||||
\Phake::when(Arsse::$db)->folderPropertiesGet($this->userId, 42)->thenReturn($this->v(['id' => 42]));
|
||||
\Phake::when(Arsse::$db)->folderPropertiesGet($this->userId, 47)->thenReturn($this->v(['id' => 47]));
|
||||
\Phake::when(Arsse::$db)->folderPropertiesGet($this->userId, 2112)->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, "*")->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet($this->userId, 4, $this->anything())->thenThrow(new ExceptionInput("idMissing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionList($this->userId)->thenReturn(new Result($this->v($list)));
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($data !== null) {
|
||||
$this->dbMock->subscriptionAdd->calledWith(...$data);
|
||||
\Phake::verify(Arsse::$db)->subscriptionAdd(...$data);
|
||||
} else {
|
||||
$this->dbMock->subscriptionAdd->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->subscriptionAdd(\Phake::anyParameters());
|
||||
}
|
||||
$this->dbMock->subscriptionPropertiesSet->never()->calledWith($this->userId, 4, ['folder' => 1]);
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->subscriptionPropertiesSet($this->userId, 4, ['folder' => 1]);
|
||||
}
|
||||
|
||||
public function provideFeedSubscriptions(): iterable {
|
||||
|
@ -746,13 +743,13 @@ LONG_STRING;
|
|||
/** @dataProvider provideFeedUnsubscriptions */
|
||||
public function testRemoveASubscription(array $in, ?array $data, $out, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$this->dbMock->subscriptionRemove->$action($out);
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$db)->subscriptionRemove->$action($out);
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($out !== null) {
|
||||
$this->dbMock->subscriptionRemove->calledWith(...$data);
|
||||
\Phake::verify(Arsse::$db)->subscriptionRemove(...$data);
|
||||
} else {
|
||||
$this->dbMock->subscriptionRemove->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->subscriptionRemove(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -768,13 +765,13 @@ LONG_STRING;
|
|||
/** @dataProvider provideFeedMoves */
|
||||
public function testMoveAFeed(array $in, ?array $data, $out, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "moveFeed", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$this->dbMock->subscriptionPropertiesSet->$action($out);
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->$action($out);
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($out !== null) {
|
||||
$this->dbMock->subscriptionPropertiesSet->calledWith(...$data);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$data);
|
||||
} else {
|
||||
$this->dbMock->subscriptionPropertiesSet->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->subscriptionPropertiesSet(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -795,13 +792,13 @@ LONG_STRING;
|
|||
/** @dataProvider provideFeedRenamings */
|
||||
public function testRenameAFeed(array $in, ?array $data, $out, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "renameFeed", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$this->dbMock->subscriptionPropertiesSet->$action($out);
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->$action($out);
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($out !== null) {
|
||||
$this->dbMock->subscriptionPropertiesSet->calledWith(...$data);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$data);
|
||||
} else {
|
||||
$this->dbMock->subscriptionPropertiesSet->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->subscriptionPropertiesSet(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -821,7 +818,7 @@ LONG_STRING;
|
|||
|
||||
public function testRetrieveTheGlobalUnreadCount(): void {
|
||||
$in = ['op' => "getUnread", 'sid' => "PriestsOfSyrinx"];
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v([
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v([
|
||||
['id' => 1, 'unread' => 2112],
|
||||
['id' => 2, 'unread' => 42],
|
||||
['id' => 3, 'unread' => 47],
|
||||
|
@ -835,8 +832,8 @@ LONG_STRING;
|
|||
$interval = Arsse::$conf->serviceFrequency;
|
||||
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
|
||||
$invalid = $valid->sub($interval)->sub($interval);
|
||||
$this->dbMock->metaGet->with("service_last_checkin")->returns(Date::transform($valid, "sql"), Date::transform($invalid, "sql"));
|
||||
$this->dbMock->subscriptionCount->with($this->userId)->returns(12, 2);
|
||||
\Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"), Date::transform($invalid, "sql"));
|
||||
\Phake::when(Arsse::$db)->subscriptionCount($this->userId)->thenReturn(12, 2);
|
||||
$this->assertMessage($this->respGood(['icons_dir' => "feed-icons", 'icons_url' => "feed-icons", 'daemon_is_running' => true, 'num_feeds' => 12]), $this->req($in));
|
||||
$this->assertMessage($this->respGood(['icons_dir' => "feed-icons", 'icons_url' => "feed-icons", 'daemon_is_running' => false, 'num_feeds' => 2]), $this->req($in));
|
||||
}
|
||||
|
@ -844,19 +841,19 @@ LONG_STRING;
|
|||
/** @dataProvider provideFeedUpdates */
|
||||
public function testUpdateAFeed(array $in, ?array $data, $out, ?int $id, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "updateFeed", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$this->dbMock->subscriptionPropertiesGet->$action($out);
|
||||
$this->dbMock->feedUpdate->returns(true);
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->$action($out);
|
||||
\Phake::when(Arsse::$db)->feedUpdate->thenReturn(true);
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($data !== null) {
|
||||
$this->dbMock->subscriptionPropertiesGet->calledWith(...$data);
|
||||
\Phake::verify(Arsse::$db)->subscriptionPropertiesGet(...$data);
|
||||
} else {
|
||||
$this->dbMock->subscriptionPropertiesGet->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->subscriptionPropertiesGet(\Phake::anyParameters());
|
||||
}
|
||||
if ($id !== null) {
|
||||
$this->dbMock->feedUpdate->calledWith($id);
|
||||
\Phake::verify(Arsse::$db)->feedUpdate($id);
|
||||
} else {
|
||||
$this->dbMock->feedUpdate->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->feedUpdate(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -872,19 +869,19 @@ LONG_STRING;
|
|||
/** @dataProvider provideLabelAdditions */
|
||||
public function testAddALabel(array $in, ?array $data1, $out1, ?array $data2, $out2, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "addLabel", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out1 instanceof \Exception) ? "throws" : "returns";
|
||||
$this->dbMock->labelAdd->$action($out1);
|
||||
$this->dbMock->labelPropertiesGet->returns($out2);
|
||||
$action = ($out1 instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$db)->labelAdd->$action($out1);
|
||||
\Phake::when(Arsse::$db)->labelPropertiesGet->thenReturn($out2);
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($out1 !== null) {
|
||||
$this->dbMock->labelAdd->calledWith(...$data1);
|
||||
\Phake::verify(Arsse::$db)->labelAdd(...$data1);
|
||||
} else {
|
||||
$this->dbMock->labelAdd->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->labelAdd(\Phake::anyParameters());
|
||||
}
|
||||
if ($out2 !== null) {
|
||||
$this->dbMock->labelPropertiesGet->calledWith(...$data2);
|
||||
\Phake::verify(Arsse::$db)->labelPropertiesGet(...$data2);
|
||||
} else {
|
||||
$this->dbMock->labelPropertiesGet->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->labelPropertiesGet(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -903,13 +900,13 @@ LONG_STRING;
|
|||
/** @dataProvider provideLabelRemovals */
|
||||
public function testRemoveALabel(array $in, ?array $data, $out, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "removeLabel", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$this->dbMock->labelRemove->$action($out);
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$db)->labelRemove->$action($out);
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($out !== null) {
|
||||
$this->dbMock->labelRemove->calledWith(...$data);
|
||||
\Phake::verify(Arsse::$db)->labelRemove(...$data);
|
||||
} else {
|
||||
$this->dbMock->labelRemove->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->labelRemove(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -927,13 +924,13 @@ LONG_STRING;
|
|||
/** @dataProvider provideLabelRenamings */
|
||||
public function testRenameALabel(array $in, ?array $data, $out, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "renameLabel", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$this->dbMock->labelPropertiesSet->$action($out);
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$db)->labelPropertiesSet->$action($out);
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($out !== null) {
|
||||
$this->dbMock->labelPropertiesSet->calledWith(...$data);
|
||||
\Phake::verify(Arsse::$db)->labelPropertiesSet(...$data);
|
||||
} else {
|
||||
$this->dbMock->labelPropertiesSet->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->labelPropertiesSet(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -955,12 +952,12 @@ LONG_STRING;
|
|||
/** @dataProvider provideCategoryListings */
|
||||
public function testRetrieveCategoryLists(array $in, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "getCategories", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$this->dbMock->folderList->with("~", null, true)->returns(new Result($this->v($this->folders)));
|
||||
$this->dbMock->folderList->with("~", null, false)->returns(new Result($this->v($this->topFolders)));
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v($this->subscriptions)));
|
||||
$this->dbMock->labelList->returns(new Result($this->v($this->labels)));
|
||||
$this->dbMock->articleCount->with("~", $this->equalTo((new Context)->hidden(false)->unread(true)->modifiedRange(Date::sub("PT24H", self::NOW), null)))->returns(7);
|
||||
$this->dbMock->articleStarred->returns($this->v($this->starred));
|
||||
\Phake::when(Arsse::$db)->folderList($this->anything(), null, true)->thenReturn(new Result($this->v($this->folders)));
|
||||
\Phake::when(Arsse::$db)->folderList($this->anything(), null, false)->thenReturn(new Result($this->v($this->topFolders)));
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v($this->subscriptions)));
|
||||
\Phake::when(Arsse::$db)->labelList->thenReturn(new Result($this->v($this->labels)));
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->hidden(false)->unread(true)->modifiedRange(Date::sub("PT24H", self::NOW), null)))->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleStarred->thenReturn($this->v($this->starred));
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
}
|
||||
|
||||
|
@ -1029,11 +1026,11 @@ LONG_STRING;
|
|||
|
||||
public function testRetrieveCounterList(): void {
|
||||
$in = ['op' => "getCounters", 'sid' => "PriestsOfSyrinx"];
|
||||
$this->dbMock->folderList->returns(new Result($this->v($this->folders)));
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v($this->subscriptions)));
|
||||
$this->dbMock->labelList->with("~", false)->returns(new Result($this->v($this->usedLabels)));
|
||||
$this->dbMock->articleCount->returns(7);
|
||||
$this->dbMock->articleStarred->returns($this->v($this->starred));
|
||||
\Phake::when(Arsse::$db)->folderList->thenReturn(new Result($this->v($this->folders)));
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v($this->subscriptions)));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
|
||||
\Phake::when(Arsse::$db)->articleCount->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleStarred->thenReturn($this->v($this->starred));
|
||||
$exp = [
|
||||
['id' => "global-unread", 'counter' => 35],
|
||||
['id' => "subscribed-feeds", 'counter' => 6],
|
||||
|
@ -1060,17 +1057,17 @@ LONG_STRING;
|
|||
['id' => -2, 'kind' => "cat", 'counter' => 6],
|
||||
];
|
||||
$this->assertMessage($this->respGood($exp), $this->req($in));
|
||||
$this->dbMock->articleCount->calledWith($this->userId, $this->equalTo((new Context)->hidden(false)->unread(true)->modifiedRange(Date::sub("PT24H", self::NOW), null)));
|
||||
\Phake::verify(Arsse::$db)->articleCount($this->userId, $this->equalTo((new Context)->hidden(false)->unread(true)->modifiedRange(Date::sub("PT24H", self::NOW), null)));
|
||||
}
|
||||
|
||||
/** @dataProvider provideLabelListings */
|
||||
public function testRetrieveTheLabelList(array $in, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "getLabels", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$this->dbMock->labelList->returns(new Result($this->v($this->labels)));
|
||||
$this->dbMock->articleLabelsGet->with("~", 1)->returns($this->v([1,3]));
|
||||
$this->dbMock->articleLabelsGet->with("~", 2)->returns($this->v([3]));
|
||||
$this->dbMock->articleLabelsGet->with("~", 3)->returns([]);
|
||||
$this->dbMock->articleLabelsGet->with("~", 4)->throws(new ExceptionInput("idMissing"));
|
||||
\Phake::when(Arsse::$db)->labelList->thenReturn(new Result($this->v($this->labels)));
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 1)->thenReturn($this->v([1,3]));
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 2)->thenReturn($this->v([3]));
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 3)->thenReturn([]);
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 4)->thenThrow(new ExceptionInput("idMissing"));
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
}
|
||||
|
||||
|
@ -1127,13 +1124,13 @@ LONG_STRING;
|
|||
/** @dataProvider provideLabelAssignments */
|
||||
public function testAssignArticlesToALabel(array $in, ?int $label, ?int $operation, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "setArticleLabel", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$this->dbMock->labelArticlesSet->with($this->userId, "~", "~", Database::ASSOC_REMOVE)->returns(42)->returns(47);
|
||||
$this->dbMock->labelArticlesSet->with($this->userId, "~", "~", Database::ASSOC_ADD)->returns(5)->returns(2);
|
||||
$this->dbMock->labelArticlesSet->with($this->userId, "~", $this->equalTo((new Context)->articles([])), "~")->throws(new ExceptionInput("tooShort"));
|
||||
\Phake::when(Arsse::$db)->labelArticlesSet($this->userId, $this->anything(), $this->anything(), Database::ASSOC_REMOVE)->thenReturn(42)->thenReturn(47);
|
||||
\Phake::when(Arsse::$db)->labelArticlesSet($this->userId, $this->anything(), $this->anything(), Database::ASSOC_ADD)->thenReturn(5)->thenReturn(2);
|
||||
\Phake::when(Arsse::$db)->labelArticlesSet($this->userId, $this->anything(), $this->equalTo((new Context)->articles([])), $this->anything())->thenThrow(new ExceptionInput("tooShort"));
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($label !== null) {
|
||||
$this->dbMock->labelArticlesSet->calledWith($this->userId, $label, $this->equalTo((new Context)->articles(range(1, 50))), $operation);
|
||||
$this->dbMock->labelArticlesSet->calledWith($this->userId, $label, $this->equalTo((new Context)->articles(range(51, 100))), $operation);
|
||||
\Phake::verify(Arsse::$db)->labelArticlesSet($this->userId, $label, $this->equalTo((new Context)->articles(range(1, 50))), $operation);
|
||||
\Phake::verify(Arsse::$db)->labelArticlesSet($this->userId, $label, $this->equalTo((new Context)->articles(range(51, 100))), $operation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1142,32 +1139,32 @@ LONG_STRING;
|
|||
['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx", 'include_empty' => true],
|
||||
['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx"],
|
||||
];
|
||||
$this->dbMock->folderList->with("~", null, true)->returns(new Result($this->v($this->folders)));
|
||||
$this->dbMock->subscriptionList->returns(new Result($this->v($this->subscriptions)));
|
||||
$this->dbMock->labelList->with("~", true)->returns(new Result($this->v($this->labels)));
|
||||
$this->dbMock->articleCount->returns(7);
|
||||
$this->dbMock->articleStarred->returns($this->v($this->starred));
|
||||
\Phake::when(Arsse::$db)->folderList($this->anything(), null, true)->thenReturn(new Result($this->v($this->folders)));
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenReturn(new Result($this->v($this->subscriptions)));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything(), true)->thenReturn(new Result($this->v($this->labels)));
|
||||
\Phake::when(Arsse::$db)->articleCount->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleStarred->thenReturn($this->v($this->starred));
|
||||
// the expectations are packed tightly since they're very verbose; one can use var_export() (or convert to JSON) to pretty-print them
|
||||
$exp = ['categories' => ['identifier' => 'id','label' => 'name','items' => [['name' => 'Special','id' => 'CAT:-1','bare_id' => -1,'type' => 'category','unread' => 0,'items' => [['name' => 'All articles','id' => 'FEED:-4','bare_id' => -4,'icon' => 'images/folder.png','unread' => 35,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Fresh articles','id' => 'FEED:-3','bare_id' => -3,'icon' => 'images/fresh.png','unread' => 7,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Starred articles','id' => 'FEED:-1','bare_id' => -1,'icon' => 'images/star.png','unread' => 4,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Published articles','id' => 'FEED:-2','bare_id' => -2,'icon' => 'images/feed.png','unread' => 0,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Archived articles','id' => 'FEED:0','bare_id' => 0,'icon' => 'images/archive.png','unread' => 0,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Recently read','id' => 'FEED:-6','bare_id' => -6,'icon' => 'images/time.png','unread' => 0,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => '']]],['name' => 'Labels','id' => 'CAT:-2','bare_id' => -2,'type' => 'category','unread' => 6,'items' => [['name' => 'Fascinating','id' => 'FEED:-1027','bare_id' => -1027,'unread' => 0,'icon' => 'images/label.png','type' => 'feed','auxcounter' => 0,'error' => '','updated' => '','fg_color' => '','bg_color' => ''],['name' => 'Interesting','id' => 'FEED:-1029','bare_id' => -1029,'unread' => 0,'icon' => 'images/label.png','type' => 'feed','auxcounter' => 0,'error' => '','updated' => '','fg_color' => '','bg_color' => ''],['name' => 'Logical','id' => 'FEED:-1025','bare_id' => -1025,'unread' => 0,'icon' => 'images/label.png','type' => 'feed','auxcounter' => 0,'error' => '','updated' => '','fg_color' => '','bg_color' => '']]],['name' => 'Photography','id' => 'CAT:4','bare_id' => 4,'parent_id' => null,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(0 feeds)','items' => []],['name' => 'Politics','id' => 'CAT:3','bare_id' => 3,'parent_id' => null,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(3 feeds)','items' => [['name' => 'Local','id' => 'CAT:5','bare_id' => 5,'parent_id' => 3,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(1 feed)','items' => [['name' => 'Toronto Star','id' => 'FEED:2','bare_id' => 2,'icon' => 'feed-icons/2.ico','error' => 'oops','param' => '2011-11-11T11:11:11Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]],['name' => 'National','id' => 'CAT:6','bare_id' => 6,'parent_id' => 3,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(2 feeds)','items' => [['name' => 'CBC News','id' => 'FEED:4','bare_id' => 4,'icon' => 'feed-icons/4.ico','error' => '','param' => '2017-10-09T15:58:34Z','unread' => 0,'auxcounter' => 0,'checkbox' => false],['name' => 'Ottawa Citizen','id' => 'FEED:5','bare_id' => 5,'icon' => false,'error' => '','param' => '2017-07-07T17:07:17Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]]]],['name' => 'Science','id' => 'CAT:1','bare_id' => 1,'parent_id' => null,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(2 feeds)','items' => [['name' => 'Rocketry','id' => 'CAT:2','bare_id' => 2,'parent_id' => 1,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(1 feed)','items' => [['name' => 'NASA JPL','id' => 'FEED:1','bare_id' => 1,'icon' => false,'error' => '','param' => '2017-09-15T22:54:16Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]],['name' => 'Ars Technica','id' => 'FEED:3','bare_id' => 3,'icon' => 'feed-icons/3.ico','error' => 'argh','param' => '2016-05-23T06:40:02Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]],['name' => 'Uncategorized','id' => 'CAT:0','bare_id' => 0,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'parent_id' => null,'param' => '(1 feed)','items' => [['name' => 'Eurogamer','id' => 'FEED:6','bare_id' => 6,'icon' => 'feed-icons/6.ico','error' => '','param' => '2010-02-12T20:08:47Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]]]]];
|
||||
$this->assertMessage($this->respGood($exp), $this->req($in[0]));
|
||||
$exp = ['categories' => ['identifier' => 'id','label' => 'name','items' => [['name' => 'Special','id' => 'CAT:-1','bare_id' => -1,'type' => 'category','unread' => 0,'items' => [['name' => 'All articles','id' => 'FEED:-4','bare_id' => -4,'icon' => 'images/folder.png','unread' => 35,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Fresh articles','id' => 'FEED:-3','bare_id' => -3,'icon' => 'images/fresh.png','unread' => 7,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Starred articles','id' => 'FEED:-1','bare_id' => -1,'icon' => 'images/star.png','unread' => 4,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Published articles','id' => 'FEED:-2','bare_id' => -2,'icon' => 'images/feed.png','unread' => 0,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Archived articles','id' => 'FEED:0','bare_id' => 0,'icon' => 'images/archive.png','unread' => 0,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => ''],['name' => 'Recently read','id' => 'FEED:-6','bare_id' => -6,'icon' => 'images/time.png','unread' => 0,'type' => 'feed','auxcounter' => 0,'error' => '','updated' => '']]],['name' => 'Labels','id' => 'CAT:-2','bare_id' => -2,'type' => 'category','unread' => 6,'items' => [['name' => 'Fascinating','id' => 'FEED:-1027','bare_id' => -1027,'unread' => 0,'icon' => 'images/label.png','type' => 'feed','auxcounter' => 0,'error' => '','updated' => '','fg_color' => '','bg_color' => ''],['name' => 'Interesting','id' => 'FEED:-1029','bare_id' => -1029,'unread' => 0,'icon' => 'images/label.png','type' => 'feed','auxcounter' => 0,'error' => '','updated' => '','fg_color' => '','bg_color' => ''],['name' => 'Logical','id' => 'FEED:-1025','bare_id' => -1025,'unread' => 0,'icon' => 'images/label.png','type' => 'feed','auxcounter' => 0,'error' => '','updated' => '','fg_color' => '','bg_color' => '']]],['name' => 'Politics','id' => 'CAT:3','bare_id' => 3,'parent_id' => null,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(3 feeds)','items' => [['name' => 'Local','id' => 'CAT:5','bare_id' => 5,'parent_id' => 3,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(1 feed)','items' => [['name' => 'Toronto Star','id' => 'FEED:2','bare_id' => 2,'icon' => 'feed-icons/2.ico','error' => 'oops','param' => '2011-11-11T11:11:11Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]],['name' => 'National','id' => 'CAT:6','bare_id' => 6,'parent_id' => 3,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(2 feeds)','items' => [['name' => 'CBC News','id' => 'FEED:4','bare_id' => 4,'icon' => 'feed-icons/4.ico','error' => '','param' => '2017-10-09T15:58:34Z','unread' => 0,'auxcounter' => 0,'checkbox' => false],['name' => 'Ottawa Citizen','id' => 'FEED:5','bare_id' => 5,'icon' => false,'error' => '','param' => '2017-07-07T17:07:17Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]]]],['name' => 'Science','id' => 'CAT:1','bare_id' => 1,'parent_id' => null,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(2 feeds)','items' => [['name' => 'Rocketry','id' => 'CAT:2','bare_id' => 2,'parent_id' => 1,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'param' => '(1 feed)','items' => [['name' => 'NASA JPL','id' => 'FEED:1','bare_id' => 1,'icon' => false,'error' => '','param' => '2017-09-15T22:54:16Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]],['name' => 'Ars Technica','id' => 'FEED:3','bare_id' => 3,'icon' => 'feed-icons/3.ico','error' => 'argh','param' => '2016-05-23T06:40:02Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]],['name' => 'Uncategorized','id' => 'CAT:0','bare_id' => 0,'type' => 'category','auxcounter' => 0,'unread' => 0,'child_unread' => 0,'checkbox' => false,'parent_id' => null,'param' => '(1 feed)','items' => [['name' => 'Eurogamer','id' => 'FEED:6','bare_id' => 6,'icon' => 'feed-icons/6.ico','error' => '','param' => '2010-02-12T20:08:47Z','unread' => 0,'auxcounter' => 0,'checkbox' => false]]]]]];
|
||||
$this->assertMessage($this->respGood($exp), $this->req($in[1]));
|
||||
$this->dbMock->articleCount->twice()->calledWith($this->userId, $this->equalTo((new Context)->hidden(false)->unread(true)->modifiedRange(Date::sub("PT24H", self::NOW), null)));
|
||||
\Phake::verify(Arsse::$db, \Phake::times(2))->articleCount($this->userId, $this->equalTo((new Context)->hidden(false)->unread(true)->modifiedRange(Date::sub("PT24H", self::NOW), null)));
|
||||
}
|
||||
|
||||
/** @dataProvider provideMassMarkings */
|
||||
public function testMarkFeedsAsRead(array $in, ?Context $c): void {
|
||||
$base = ['op' => "catchupFeed", 'sid' => "PriestsOfSyrinx"];
|
||||
$in = array_merge($base, $in);
|
||||
$this->dbMock->articleMark->throws(new ExceptionInput("typeViolation"));
|
||||
\Phake::when(Arsse::$db)->articleMark->thenThrow(new ExceptionInput("typeViolation"));
|
||||
// create a mock-current time
|
||||
$this->objMock->get->with(\DateTimeImmutable::class)->returns(new \DateTimeImmutable(self::NOW));
|
||||
\Phake::when(Arsse::$obj)->get(\DateTimeImmutable::class)->thenReturn(new \DateTimeImmutable(self::NOW));
|
||||
// TT-RSS always responds the same regardless of success or failure
|
||||
$this->assertMessage($this->respGood(['status' => "OK"]), $this->req($in));
|
||||
if (isset($c)) {
|
||||
$this->dbMock->articleMark->calledWith($this->userId, ['read' => true], $this->equalTo($c));
|
||||
\Phake::verify(Arsse::$db)->articleMark($this->userId, ['read' => true], $this->equalTo($c));
|
||||
} else {
|
||||
$this->dbMock->articleMark->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->articleMark(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1201,24 +1198,24 @@ LONG_STRING;
|
|||
public function testRetrieveFeedList(array $in, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "getFeeds", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
// statistical mocks
|
||||
$this->dbMock->articleStarred->returns($this->v($this->starred));
|
||||
$this->dbMock->articleCount->with("~", $this->equalTo((new Context)->unread(true)->hidden(false)->modifiedRange(Date::sub("PT24H", self::NOW), null)))->returns(7);
|
||||
$this->dbMock->articleCount->with("~", $this->equalTo((new Context)->unread(true)->hidden(false)))->returns(35);
|
||||
\Phake::when(Arsse::$db)->articleStarred->thenReturn($this->v($this->starred));
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->hidden(false)->modifiedRange(Date::sub("PT24H", self::NOW), null)))->thenReturn(7);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->hidden(false)))->thenReturn(35);
|
||||
// label mocks
|
||||
$this->dbMock->labelList->returns(new Result($this->v($this->labels)));
|
||||
$this->dbMock->labelList->with("~", false)->returns(new Result($this->v($this->usedLabels)));
|
||||
\Phake::when(Arsse::$db)->labelList->thenReturn(new Result($this->v($this->labels)));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
|
||||
// subscription and folder list and unread count mocks
|
||||
$this->dbMock->folderList->throws(new ExceptionInput("subjectMissing"));
|
||||
$this->dbMock->subscriptionList->throws(new ExceptionInput("subjectMissing"));
|
||||
$this->dbMock->folderList->with("~")->returns(new Result($this->v($this->folders)));
|
||||
$this->dbMock->subscriptionList->with("~", null, true)->returns(new Result($this->v($this->subscriptions)));
|
||||
$this->dbMock->subscriptionList->with("~", null, false)->returns(new Result($this->v($this->filterSubs(null))));
|
||||
$this->dbMock->folderList->with("~", null)->returns(new Result($this->v($this->folders)));
|
||||
$this->dbMock->folderList->with("~", null, false)->returns(new Result($this->v($this->filterFolders(null))));
|
||||
\Phake::when(Arsse::$db)->folderList->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionList->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->folderList($this->anything())->thenReturn(new Result($this->v($this->folders)));
|
||||
\Phake::when(Arsse::$db)->subscriptionList($this->anything(), null, true)->thenReturn(new Result($this->v($this->subscriptions)));
|
||||
\Phake::when(Arsse::$db)->subscriptionList($this->anything(), null, false)->thenReturn(new Result($this->v($this->filterSubs(null))));
|
||||
\Phake::when(Arsse::$db)->folderList($this->anything(), null)->thenReturn(new Result($this->v($this->folders)));
|
||||
\Phake::when(Arsse::$db)->folderList($this->anything(), null, false)->thenReturn(new Result($this->v($this->filterFolders(null))));
|
||||
foreach ($this->folders as $f) {
|
||||
$this->dbMock->folderList->with("~", $f['id'], false)->returns(new Result($this->v($this->filterFolders($f['id']))));
|
||||
$this->dbMock->articleCount->with("~", $this->equalTo((new Context)->unread(true)->hidden(false)->folder($f['id'])))->returns($this->reduceFolders($f['id']));
|
||||
$this->dbMock->subscriptionList->with("~", $f['id'], false)->returns(new Result($this->v($this->filterSubs($f['id']))));
|
||||
\Phake::when(Arsse::$db)->folderList($this->anything(), $f['id'], false)->thenReturn(new Result($this->v($this->filterFolders($f['id']))));
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->hidden(false)->folder($f['id'])))->thenReturn($this->reduceFolders($f['id']));
|
||||
\Phake::when(Arsse::$db)->subscriptionList($this->anything(), $f['id'], false)->thenReturn(new Result($this->v($this->filterSubs($f['id']))));
|
||||
}
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
}
|
||||
|
@ -1359,21 +1356,21 @@ LONG_STRING;
|
|||
/** @dataProvider provideArticleChanges */
|
||||
public function testChangeArticles(array $in, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "updateArticle", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$this->dbMock->articleMark->returns(1);
|
||||
$this->dbMock->articleMark->with($this->userId, ['starred' => false], $this->equalTo((new Context)->articles([42, 2112])))->returns(2);
|
||||
$this->dbMock->articleMark->with($this->userId, ['starred' => true], $this->equalTo((new Context)->articles([42, 2112])))->returns(4);
|
||||
$this->dbMock->articleMark->with($this->userId, ['starred' => false], $this->equalTo((new Context)->articles([42])))->returns(8);
|
||||
$this->dbMock->articleMark->with($this->userId, ['starred' => true], $this->equalTo((new Context)->articles([2112])))->returns(16);
|
||||
$this->dbMock->articleMark->with($this->userId, ['read' => true], $this->equalTo((new Context)->articles([42, 2112])))->returns(32); // false is read for TT-RSS
|
||||
$this->dbMock->articleMark->with($this->userId, ['read' => false], $this->equalTo((new Context)->articles([42, 2112])))->returns(64);
|
||||
$this->dbMock->articleMark->with($this->userId, ['read' => true], $this->equalTo((new Context)->articles([42])))->returns(128);
|
||||
$this->dbMock->articleMark->with($this->userId, ['read' => false], $this->equalTo((new Context)->articles([2112])))->returns(256);
|
||||
$this->dbMock->articleMark->with($this->userId, ['note' => ""], $this->equalTo((new Context)->articles([42, 2112])))->returns(512);
|
||||
$this->dbMock->articleMark->with($this->userId, ['note' => "eh"], $this->equalTo((new Context)->articles([42, 2112])))->returns(1024);
|
||||
$this->dbMock->articleList->with($this->userId, $this->equalTo((new Context)->articles([42, 2112])->starred(true)), "~")->returns(new Result($this->v([['id' => 42]])));
|
||||
$this->dbMock->articleList->with($this->userId, $this->equalTo((new Context)->articles([42, 2112])->starred(false)), "~")->returns(new Result($this->v([['id' => 2112]])));
|
||||
$this->dbMock->articleList->with($this->userId, $this->equalTo((new Context)->articles([42, 2112])->unread(true)), "~")->returns(new Result($this->v([['id' => 42]])));
|
||||
$this->dbMock->articleList->with($this->userId, $this->equalTo((new Context)->articles([42, 2112])->unread(false)), "~")->returns(new Result($this->v([['id' => 2112]])));
|
||||
\Phake::when(Arsse::$db)->articleMark->thenReturn(1);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, ['starred' => false], $this->equalTo((new Context)->articles([42, 2112])))->thenReturn(2);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, ['starred' => true], $this->equalTo((new Context)->articles([42, 2112])))->thenReturn(4);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, ['starred' => false], $this->equalTo((new Context)->articles([42])))->thenReturn(8);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, ['starred' => true], $this->equalTo((new Context)->articles([2112])))->thenReturn(16);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, ['read' => true], $this->equalTo((new Context)->articles([42, 2112])))->thenReturn(32); // false is read for TT-RSS
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, ['read' => false], $this->equalTo((new Context)->articles([42, 2112])))->thenReturn(64);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, ['read' => true], $this->equalTo((new Context)->articles([42])))->thenReturn(128);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, ['read' => false], $this->equalTo((new Context)->articles([2112])))->thenReturn(256);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, ['note' => ""], $this->equalTo((new Context)->articles([42, 2112])))->thenReturn(512);
|
||||
\Phake::when(Arsse::$db)->articleMark($this->userId, ['note' => "eh"], $this->equalTo((new Context)->articles([42, 2112])))->thenReturn(1024);
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, $this->equalTo((new Context)->articles([42, 2112])->starred(true)), $this->anything())->thenReturn(new Result($this->v([['id' => 42]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, $this->equalTo((new Context)->articles([42, 2112])->starred(false)), $this->anything())->thenReturn(new Result($this->v([['id' => 2112]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, $this->equalTo((new Context)->articles([42, 2112])->unread(true)), $this->anything())->thenReturn(new Result($this->v([['id' => 42]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->userId, $this->equalTo((new Context)->articles([42, 2112])->unread(false)), $this->anything())->thenReturn(new Result($this->v([['id' => 2112]])));
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
}
|
||||
|
||||
|
@ -1410,13 +1407,13 @@ LONG_STRING;
|
|||
/** @dataProvider provideArticleListings */
|
||||
public function testListArticles(array $in, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "getArticle", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$this->dbMock->labelList->with("~")->returns(new Result($this->v($this->labels)));
|
||||
$this->dbMock->labelList->with("~", false)->returns(new Result($this->v($this->usedLabels)));
|
||||
$this->dbMock->articleLabelsGet->with("~", 101)->returns([]);
|
||||
$this->dbMock->articleLabelsGet->with("~", 102)->returns($this->v([1,3]));
|
||||
$this->dbMock->articleList->with("~", $this->equalTo((new Context)->articles([101, 102])), "~")->returns(new Result($this->v($this->articles)));
|
||||
$this->dbMock->articleList->with("~", $this->equalTo((new Context)->articles([101])), "~")->returns(new Result($this->v([$this->articles[0]])));
|
||||
$this->dbMock->articleList->with("~", $this->equalTo((new Context)->articles([102])), "~")->returns(new Result($this->v([$this->articles[1]])));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels)));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 101)->thenReturn([]);
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 102)->thenReturn($this->v([1,3]));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((new Context)->articles([101, 102])), $this->anything())->thenReturn(new Result($this->v($this->articles)));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((new Context)->articles([101])), $this->anything())->thenReturn(new Result($this->v([$this->articles[0]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((new Context)->articles([102])), $this->anything())->thenReturn(new Result($this->v([$this->articles[1]])));
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
}
|
||||
|
||||
|
@ -1491,13 +1488,13 @@ LONG_STRING;
|
|||
/** @dataProvider provideArticleListingsWithoutLabels */
|
||||
public function testListArticlesWithoutLabels(array $in, ResponseInterface $exp): void {
|
||||
$in = array_merge(['op' => "getArticle", 'sid' => "PriestsOfSyrinx"], $in);
|
||||
$this->dbMock->labelList->with("~")->returns(new Result([]));
|
||||
$this->dbMock->labelList->with("~", false)->returns(new Result([]));
|
||||
$this->dbMock->articleLabelsGet->with("~", 101)->returns([]);
|
||||
$this->dbMock->articleLabelsGet->with("~", 102)->returns($this->v([1,3]));
|
||||
$this->dbMock->articleList->with("~", $this->equalTo((new Context)->articles([101, 102])), "~")->returns(new Result($this->v($this->articles)));
|
||||
$this->dbMock->articleList->with("~", $this->equalTo((new Context)->articles([101])), "~")->returns(new Result($this->v([$this->articles[0]])));
|
||||
$this->dbMock->articleList->with("~", $this->equalTo((new Context)->articles([102])), "~")->returns(new Result($this->v([$this->articles[1]])));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result([]));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result([]));
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 101)->thenReturn([]);
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 102)->thenReturn($this->v([1,3]));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((new Context)->articles([101, 102])), $this->anything())->thenReturn(new Result($this->v($this->articles)));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((new Context)->articles([101])), $this->anything())->thenReturn(new Result($this->v([$this->articles[0]])));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((new Context)->articles([102])), $this->anything())->thenReturn(new Result($this->v([$this->articles[1]])));
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
}
|
||||
|
||||
|
@ -1570,21 +1567,21 @@ LONG_STRING;
|
|||
public function testRetrieveHeadlines(bool $full, array $in, $out, Context $c, array $fields, array $order, ResponseInterface $exp): void {
|
||||
$base = ['op' => $full ? "getHeadlines" : "getCompactHeadlines", 'sid' => "PriestsOfSyrinx"];
|
||||
$in = array_merge($base, $in);
|
||||
$action = ($out instanceof \Exception) ? "throws" : "returns";
|
||||
$this->objMock->get->with(\DateTimeImmutable::class)->returns(new \DateTimeImmutable(self::NOW));
|
||||
$this->dbMock->labelList->returns(new Result($this->v($this->labels)));
|
||||
$this->dbMock->labelList->with("~", false)->returns(new Result($this->v($this->usedLabels)));
|
||||
$this->dbMock->articleLabelsGet->returns([]);
|
||||
$this->dbMock->articleLabelsGet->with("~", 2112)->returns($this->v([1,3]));
|
||||
$this->dbMock->articleCategoriesGet->returns([]);
|
||||
$this->dbMock->articleCategoriesGet->with("~", 2112)->returns(["Boring","Illogical"]);
|
||||
$this->dbMock->articleCount->returns(2);
|
||||
$this->dbMock->articleList->$action($out);
|
||||
$action = ($out instanceof \Exception) ? "thenThrow" : "thenReturn";
|
||||
\Phake::when(Arsse::$obj)->get(\DateTimeImmutable::class)->thenReturn(new \DateTimeImmutable(self::NOW));
|
||||
\Phake::when(Arsse::$db)->labelList->thenReturn(new Result($this->v($this->labels)));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet->thenReturn([]);
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 2112)->thenReturn($this->v([1,3]));
|
||||
\Phake::when(Arsse::$db)->articleCategoriesGet->thenReturn([]);
|
||||
\Phake::when(Arsse::$db)->articleCategoriesGet($this->anything(), 2112)->thenReturn(["Boring","Illogical"]);
|
||||
\Phake::when(Arsse::$db)->articleCount->thenReturn(2);
|
||||
\Phake::when(Arsse::$db)->articleList->$action($out);
|
||||
$this->assertMessage($exp, $this->req($in));
|
||||
if ($out) {
|
||||
$this->dbMock->articleList->calledWith($this->userId, $this->equalTo($c), $fields, $order);
|
||||
\Phake::verify(Arsse::$db)->articleList($this->userId, $this->equalTo($c), $fields, $order);
|
||||
} else {
|
||||
$this->dbMock->articleList->never()->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->articleList(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1672,15 +1669,15 @@ LONG_STRING;
|
|||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'skip' => 47, 'include_header' => true, 'order_by' => "date_reverse"],
|
||||
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4, 'show_excerpt' => true],
|
||||
];
|
||||
$this->dbMock->labelList->with("~")->returns(new Result($this->v($this->labels)));
|
||||
$this->dbMock->labelList->with("~", false)->returns(new Result($this->v($this->usedLabels)));
|
||||
$this->dbMock->articleLabelsGet->returns([]);
|
||||
$this->dbMock->articleLabelsGet->with("~", 2112)->returns($this->v([1,3]));
|
||||
$this->dbMock->articleCategoriesGet->returns([]);
|
||||
$this->dbMock->articleCategoriesGet->with("~", 2112)->returns(["Boring","Illogical"]);
|
||||
$this->dbMock->articleList->returns($this->generateHeadlines(1));
|
||||
$this->dbMock->articleCount->returns(0);
|
||||
$this->dbMock->articleCount->with("~", $this->equalTo((new Context)->unread(true)->hidden(false)))->returns(1);
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything())->thenReturn(new Result($this->v($this->labels)));
|
||||
\Phake::when(Arsse::$db)->labelList($this->anything(), false)->thenReturn(new Result($this->v($this->usedLabels)));
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet->thenReturn([]);
|
||||
\Phake::when(Arsse::$db)->articleLabelsGet($this->anything(), 2112)->thenReturn($this->v([1,3]));
|
||||
\Phake::when(Arsse::$db)->articleCategoriesGet->thenReturn([]);
|
||||
\Phake::when(Arsse::$db)->articleCategoriesGet($this->anything(), 2112)->thenReturn(["Boring","Illogical"]);
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn($this->generateHeadlines(1));
|
||||
\Phake::when(Arsse::$db)->articleCount->thenReturn(0);
|
||||
\Phake::when(Arsse::$db)->articleCount($this->anything(), $this->equalTo((new Context)->unread(true)->hidden(false)))->thenReturn(1);
|
||||
// sanity check; this makes sure extra fields are not included in default situations
|
||||
$test = $this->req($in[0]);
|
||||
$this->assertMessage($this->outputHeadlines(1), $test);
|
||||
|
@ -1731,7 +1728,7 @@ LONG_STRING;
|
|||
]);
|
||||
$this->assertMessage($exp, $test);
|
||||
// test 'include_header' with an erroneous result
|
||||
$this->dbMock->articleList->with("~", $this->equalTo((new Context)->limit(200)->subscription(2112)->hidden(false)), "~", ["edited_date desc"])->throws(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((new Context)->limit(200)->subscription(2112)->hidden(false)), $this->anything(), ["edited_date desc"])->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
$test = $this->req($in[6]);
|
||||
$exp = $this->respGood([
|
||||
['id' => 2112, 'is_cat' => false, 'first_id' => 0],
|
||||
|
@ -1746,7 +1743,7 @@ LONG_STRING;
|
|||
]);
|
||||
$this->assertMessage($exp, $test);
|
||||
// test 'include_header' with skip
|
||||
$this->dbMock->articleList->with("~", $this->equalTo((new Context)->limit(1)->subscription(42)->hidden(false)), "~", ["edited_date desc"])->returns($this->generateHeadlines(1867));
|
||||
\Phake::when(Arsse::$db)->articleList($this->anything(), $this->equalTo((new Context)->limit(1)->subscription(42)->hidden(false)), $this->anything(), ["edited_date desc"])->thenReturn($this->generateHeadlines(1867));
|
||||
$test = $this->req($in[8]);
|
||||
$exp = $this->respGood([
|
||||
['id' => 42, 'is_cat' => false, 'first_id' => 1867],
|
||||
|
|
|
@ -23,14 +23,13 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
Arsse::$user = $this->mock(User::class)->get();
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
// create a mock database interface
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
$this->h = new Icon();
|
||||
}
|
||||
|
||||
protected function req(string $target, string $method = "GET", ?string $user = null): ResponseInterface {
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
$prefix = "/tt-rss/feed-icons/";
|
||||
$url = $prefix.$target;
|
||||
$req = $this->serverRequest($method, $url, $prefix, [], [], null, "", [], $user);
|
||||
|
@ -46,11 +45,11 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testRetrieveFavion(): void {
|
||||
$this->dbMock->subscriptionIcon->returns(['url' => null]);
|
||||
$this->dbMock->subscriptionIcon->with($this->anything(), 1123, false)->throws(new ExceptionInput("subjectMissing"));
|
||||
$this->dbMock->subscriptionIcon->with($this->anything(), 42, false)->returns(['url' => "http://example.com/favicon.ico"]);
|
||||
$this->dbMock->subscriptionIcon->with($this->anything(), 2112, false)->returns(['url' => "http://example.net/logo.png"]);
|
||||
$this->dbMock->subscriptionIcon->with($this->anything(), 1337, false)->returns(['url' => "http://example.org/icon.gif\r\nLocation: http://bad.example.com/"]);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon->thenReturn(['url' => null]);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon($this->anything(), 1123, false)->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon($this->anything(), 42, false)->thenReturn(['url' => "http://example.com/favicon.ico"]);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon($this->anything(), 2112, false)->thenReturn(['url' => "http://example.net/logo.png"]);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon($this->anything(), 1337, false)->thenReturn(['url' => "http://example.org/icon.gif\r\nLocation: http://bad.example.com/"]);
|
||||
// these requests should succeed
|
||||
$exp = HTTP::respEmpty(301, ['Location' => "http://example.com/favicon.ico"]);
|
||||
$this->assertMessage($exp, $this->req("42.ico"));
|
||||
|
@ -72,13 +71,13 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function testRetrieveFavionWithHttpAuthentication(): void {
|
||||
$url = ['url' => "http://example.org/icon.gif\r\nLocation: http://bad.example.com/"];
|
||||
$this->dbMock->subscriptionIcon->returns(['url' => null]);
|
||||
$this->dbMock->subscriptionIcon->with($this->user, 42, false)->returns($url);
|
||||
$this->dbMock->subscriptionIcon->with("jane.doe", 2112, false)->returns($url);
|
||||
$this->dbMock->subscriptionIcon->with($this->user, 1337, false)->returns($url);
|
||||
$this->dbMock->subscriptionIcon->with(null, 42, false)->returns($url);
|
||||
$this->dbMock->subscriptionIcon->with(null, 2112, false)->returns($url);
|
||||
$this->dbMock->subscriptionIcon->with(null, 1337, false)->returns($url);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon->thenReturn(['url' => null]);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon($this->user, 42, false)->thenReturn($url);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon("jane.doe", 2112, false)->thenReturn($url);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon($this->user, 1337, false)->thenReturn($url);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon(null, 42, false)->thenReturn($url);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon(null, 2112, false)->thenReturn($url);
|
||||
\Phake::when(Arsse::$db)->subscriptionIcon(null, 1337, false)->thenReturn($url);
|
||||
// these requests should succeed
|
||||
$exp = HTTP::respEmpty(301, ['Location' => "http://example.org/icon.gif"]);
|
||||
$this->assertMessage($exp, $this->req("42.ico"));
|
||||
|
|
|
@ -44,13 +44,13 @@ class TestDaemon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
$this->daemon = $this->partialMock(Daemon::class);
|
||||
$this->daemon = \Phake::partialMock(Daemon::class);
|
||||
}
|
||||
|
||||
/** @dataProvider providePathResolutions */
|
||||
public function testResolveRelativePaths(string $path, $cwd, $exp): void {
|
||||
// set up mock daemon class
|
||||
$this->daemon->cwd->returns($cwd);
|
||||
\Phake::when($this->daemon)->cwd->thenReturn($cwd);
|
||||
$daemon = $this->daemon->get();
|
||||
// perform the test
|
||||
$this->AssertSame($exp, $daemon->resolveRelativePath($path));
|
||||
|
@ -83,7 +83,7 @@ class TestDaemon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
chmod($path."errors/write", 0555);
|
||||
chmod($path."errors/readwrite", 0111);
|
||||
// set up mock daemon class
|
||||
$this->daemon->resolveRelativePath->returns($accessible ? dirname($path.$file) : false);
|
||||
\Phake::when($this->daemon)->resolveRelativePath->thenReturn($accessible ? dirname($path.$file) : false);
|
||||
$daemon = $this->daemon->get();
|
||||
// perform the test
|
||||
if ($exp instanceof \Exception) {
|
||||
|
@ -119,8 +119,8 @@ class TestDaemon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
chmod($path."unreadable", 0333);
|
||||
chmod($path."unwritable", 0555);
|
||||
// set up mock daemon class
|
||||
$this->daemon->processExists->with(2112)->returns(true);
|
||||
$this->daemon->processExists->with(42)->returns(false);
|
||||
\Phake::when($this->daemon)->processExists(2112)->thenReturn(true);
|
||||
\Phake::when($this->daemon)->processExists(42)->thenReturn(false);
|
||||
$daemon = $this->daemon->get();
|
||||
// perform the test
|
||||
try {
|
||||
|
@ -169,8 +169,8 @@ class TestDaemon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
chmod($path."unreadable", 0333);
|
||||
chmod($path."unwritable", 0555);
|
||||
// set up mock daemon class
|
||||
$this->daemon->processExists->with(2112)->returns(true);
|
||||
$this->daemon->processExists->with(42)->returns(false);
|
||||
\Phake::when($this->daemon)->processExists(2112)->thenReturn(true);
|
||||
\Phake::when($this->daemon)->processExists(42)->thenReturn(false);
|
||||
$daemon = $this->daemon->get();
|
||||
// perform the test
|
||||
try {
|
||||
|
|
|
@ -17,8 +17,7 @@ class TestSerial extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
}
|
||||
|
||||
public function testConstruct(): void {
|
||||
|
@ -42,8 +41,8 @@ class TestSerial extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$d = new Driver;
|
||||
$d->queue(1, 4, 3);
|
||||
$this->assertSame(Arsse::$conf->serviceQueueWidth, $d->exec());
|
||||
$this->dbMock->feedUpdate->calledWith(1);
|
||||
$this->dbMock->feedUpdate->calledWith(4);
|
||||
$this->dbMock->feedUpdate->calledWith(3);
|
||||
\Phake::verify(Arsse::$db)->feedUpdate(1);
|
||||
\Phake::verify(Arsse::$db)->feedUpdate(4);
|
||||
\Phake::verify(Arsse::$db)->feedUpdate(3);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,16 +19,14 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
$this->srv = new Service();
|
||||
}
|
||||
|
||||
public function testCheckIn(): void {
|
||||
$now = time();
|
||||
$this->srv->checkIn();
|
||||
$this->dbMock->metaSet->calledWith("service_last_checkin", "~", "datetime");
|
||||
$then = $this->dbMock->metaSet->firstCall()->argument(1);
|
||||
\Phake::verify(Arsse::$db)->metaSet("service_last_checkin", \Phake::capture($then), "datetime");
|
||||
$this->assertTime($now, $then);
|
||||
}
|
||||
|
||||
|
@ -38,56 +36,52 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$interval = Arsse::$conf->serviceFrequency;
|
||||
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
|
||||
$invalid = $valid->sub($interval)->sub($interval);
|
||||
$this->dbMock->metaGet->with("service_last_checkin")->returns(Date::transform($valid, "sql"), Date::transform($invalid, "sql"));
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
\Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"), Date::transform($invalid, "sql"));
|
||||
$this->assertTrue(Service::hasCheckedIn());
|
||||
$this->assertFalse(Service::hasCheckedIn());
|
||||
}
|
||||
|
||||
public function testPerformPreCleanup(): void {
|
||||
$this->assertTrue(Service::cleanupPre());
|
||||
$this->dbMock->feedCleanup->called();
|
||||
$this->dbMock->iconCleanup->called();
|
||||
$this->dbMock->sessionCleanup->called();
|
||||
\Phake::verify(Arsse::$db)->feedCleanup(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db)->iconCleanup(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db)->sessionCleanup(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function testPerformShortPostCleanup(): void {
|
||||
$this->dbMock->articleCleanup->returns(0);
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
\Phake::when(Arsse::$db)->articleCleanup->thenReturn(0);
|
||||
$this->assertTrue(Service::cleanupPost());
|
||||
$this->dbMock->articleCleanup->Called();
|
||||
$this->dbMock->driverMaintenance->never()->called();
|
||||
\Phake::verify(Arsse::$db)->articleCleanup(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->driverMaintenance(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function testPerformFullPostCleanup(): void {
|
||||
$this->dbMock->articleCleanup->returns(1);
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
\Phake::when(Arsse::$db)->articleCleanup->thenReturn(1);
|
||||
$this->assertTrue(Service::cleanupPost());
|
||||
$this->dbMock->articleCleanup->called();
|
||||
$this->dbMock->driverMaintenance->called();
|
||||
\Phake::verify(Arsse::$db)->articleCleanup(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db)->driverMaintenance(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function testRefreshFeeds(): void {
|
||||
// set up mock database actions
|
||||
$this->dbMock->metaSet->returns(true);
|
||||
$this->dbMock->feedCleanup->returns(true);
|
||||
$this->dbMock->sessionCleanup->returns(true);
|
||||
$this->dbMock->articleCleanup->returns(0);
|
||||
$this->dbMock->feedListStale->returns([1,2,3]);
|
||||
\Phake::when(Arsse::$db)->metaSet->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->feedCleanup->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->sessionCleanup->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->articleCleanup->thenReturn(0);
|
||||
\Phake::when(Arsse::$db)->feedListStale->thenReturn([1,2,3]);
|
||||
// perform the test
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
$d = $this->mock(\JKingWeb\Arsse\Service\Driver::class);
|
||||
$s = new \JKingWeb\Arsse\Test\Service($d->get());
|
||||
$d = \Phake::mock(\JKingWeb\Arsse\Service\Driver::class);
|
||||
$s = new \JKingWeb\Arsse\Test\Service($d);
|
||||
$this->assertInstanceOf(\DateTimeInterface::class, $s->watch(false));
|
||||
// verify invocations
|
||||
$d->queue->calledWith(1, 2, 3);
|
||||
$d->exec->called();
|
||||
$d->clean->called();
|
||||
$this->dbMock->feedCleanup->called();
|
||||
$this->dbMock->iconCleanup->called();
|
||||
$this->dbMock->sessionCleanup->called();
|
||||
$this->dbMock->articleCleanup->called();
|
||||
$this->dbMock->metaSet->calledWith("service_last_checkin", $this->anything(), "datetime");
|
||||
\Phake::verify($d)->queue(1, 2, 3);
|
||||
\Phake::verify($d)->exec(\Phake::anyParameters());
|
||||
\Phake::verify($d)->clean(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db)->feedCleanup(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db)->iconCleanup(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db)->sessionCleanup(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db)->articleCleanup(\Phake::anyParameters());
|
||||
\Phake::verify(Arsse::$db)->metaSet("service_last_checkin", $this->anything(), "datetime");
|
||||
}
|
||||
|
||||
public function testReloadTheService(): void {
|
||||
|
|
|
@ -36,14 +36,13 @@ class TestSubprocess extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testRefreshFeeds(): void {
|
||||
$dMock = $this->partialMock(Driver::class);
|
||||
$dMock->execCmd->does(function(string $cmd) {
|
||||
$d = \Phake::partialMock(Driver::class);
|
||||
\Phake::when($d)->execCmd->thenReturnCallback(function(string $cmd) {
|
||||
// FIXME: Does this work in Windows?
|
||||
return popen("echo ".escapeshellarg($cmd), "r");
|
||||
});
|
||||
$d = $dMock->get();
|
||||
$this->assertSame(3, $d->queue(1, 4, 3));
|
||||
$this->assertSame(Arsse::$conf->serviceQueueWidth, $d->exec());
|
||||
$dMock->execCmd->times(3)->called();
|
||||
\Phake::verify($d, \Phake::times(3))->execCmd(\Phake::anyParameters());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,17 +14,15 @@ use JKingWeb\Arsse\User\Internal\Driver;
|
|||
|
||||
/** @covers \JKingWeb\Arsse\User\Internal\Driver */
|
||||
class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
protected $d;
|
||||
|
||||
public function setUp(): void {
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
// create a mock database interface
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->begin->returns($this->mock(\JKingWeb\Arsse\Db\Transaction::class));
|
||||
}
|
||||
|
||||
protected function prepTest(): Driver {
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
return new Driver;
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));
|
||||
$this->d = new Driver;
|
||||
}
|
||||
|
||||
public function testConstruct(): void {
|
||||
|
@ -40,12 +38,12 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
* @group slow
|
||||
*/
|
||||
public function testAuthenticateAUser(string $user, $password, bool $exp): void {
|
||||
$this->dbMock->userPasswordGet->with("john.doe@example.com")->returns('$2y$10$1zbqRJhxM8uUjeSBPp4IhO90xrqK0XjEh9Z16iIYEFRV4U.zeAFom'); // hash of "secret"
|
||||
$this->dbMock->userPasswordGet->with("jane.doe@example.com")->returns('$2y$10$bK1ljXfTSyc2D.NYvT.Eq..OpehLRXVbglW.23ihVuyhgwJCd.7Im'); // hash of "superman"
|
||||
$this->dbMock->userPasswordGet->with("owen.hardy@example.com")->returns("");
|
||||
$this->dbMock->userPasswordGet->with("kira.nerys@example.com")->throws(new \JKingWeb\Arsse\User\ExceptionConflict("doesNotExist"));
|
||||
$this->dbMock->userPasswordGet->with("007@example.com")->returns(null);
|
||||
$this->assertSame($exp, $this->prepTest()->auth($user, $password));
|
||||
\Phake::when(Arsse::$db)->userPasswordGet("john.doe@example.com")->thenReturn('$2y$10$1zbqRJhxM8uUjeSBPp4IhO90xrqK0XjEh9Z16iIYEFRV4U.zeAFom'); // hash of "secret"
|
||||
\Phake::when(Arsse::$db)->userPasswordGet("jane.doe@example.com")->thenReturn('$2y$10$bK1ljXfTSyc2D.NYvT.Eq..OpehLRXVbglW.23ihVuyhgwJCd.7Im'); // hash of "superman"
|
||||
\Phake::when(Arsse::$db)->userPasswordGet("owen.hardy@example.com")->thenReturn("");
|
||||
\Phake::when(Arsse::$db)->userPasswordGet("kira.nerys@example.com")->thenThrow(new \JKingWeb\Arsse\User\ExceptionConflict("doesNotExist"));
|
||||
\Phake::when(Arsse::$db)->userPasswordGet("007@example.com")->thenReturn(null);
|
||||
$this->assertSame($exp, $this->d->auth($user, $password));
|
||||
}
|
||||
|
||||
public function provideAuthentication(): iterable {
|
||||
|
@ -74,111 +72,111 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testListUsers(): void {
|
||||
$john = "john.doe@example.com";
|
||||
$jane = "jane.doe@example.com";
|
||||
$this->dbMock->userList->returns([$john, $jane])->returns([$jane, $john]);
|
||||
$driver = $this->prepTest();
|
||||
\Phake::when(Arsse::$db)->userList->thenReturn([$john, $jane])->thenReturn([$jane, $john]);
|
||||
$driver = $this->d;
|
||||
$this->assertSame([$john, $jane], $driver->userList());
|
||||
$this->assertSame([$jane, $john], $driver->userList());
|
||||
$this->dbMock->userList->times(2)->called();
|
||||
\Phake::verify(Arsse::$db, \Phake::times(2))->userList(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function testAddAUser(): void {
|
||||
$john = "john.doe@example.com";
|
||||
$this->dbMock->userAdd->does(function($user, $pass) {
|
||||
\Phake::when(Arsse::$db)->userAdd->thenReturnCallback(function($user, $pass) {
|
||||
return $pass;
|
||||
});
|
||||
$driver = $this->prepTest();
|
||||
$driver = $this->d;
|
||||
$this->assertNull($driver->userAdd($john));
|
||||
$this->assertNull($driver->userAdd($john, null));
|
||||
$this->assertSame("secret", $driver->userAdd($john, "secret"));
|
||||
$this->dbMock->userAdd->calledWith($john, "secret");
|
||||
$this->dbMock->userAdd->called();
|
||||
\Phake::verify(Arsse::$db)->userAdd($john, "secret");
|
||||
\Phake::verify(Arsse::$db)->userAdd(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function testRenameAUser(): void {
|
||||
$john = "john.doe@example.com";
|
||||
$this->dbMock->userExists->returns(true);
|
||||
$this->assertTrue($this->prepTest()->userRename($john, "jane.doe@example.com"));
|
||||
$this->assertFalse($this->prepTest()->userRename($john, $john));
|
||||
$this->dbMock->userExists->times(2)->calledWith($john);
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
|
||||
$this->assertTrue($this->d->userRename($john, "jane.doe@example.com"));
|
||||
$this->assertFalse($this->d->userRename($john, $john));
|
||||
\Phake::verify(Arsse::$db, \Phake::times(2))->userExists($john);
|
||||
}
|
||||
|
||||
public function testRenameAMissingUser(): void {
|
||||
$john = "john.doe@example.com";
|
||||
$this->dbMock->userExists->returns(false);
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
|
||||
$this->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||
$this->prepTest()->userRename($john, "jane.doe@example.com");
|
||||
$this->d->userRename($john, "jane.doe@example.com");
|
||||
}
|
||||
|
||||
public function testRemoveAUser(): void {
|
||||
$john = "john.doe@example.com";
|
||||
$this->dbMock->userRemove->returns(true)->throws(new \JKingWeb\Arsse\User\ExceptionConflict("doesNotExist"));
|
||||
$driver = $this->prepTest();
|
||||
\Phake::when(Arsse::$db)->userRemove->thenReturn(true)->thenThrow(new \JKingWeb\Arsse\User\ExceptionConflict("doesNotExist"));
|
||||
$driver = $this->d;
|
||||
$this->assertTrue($driver->userRemove($john));
|
||||
$this->dbMock->userRemove->calledWith($john);
|
||||
\Phake::verify(Arsse::$db)->userRemove($john);
|
||||
$this->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||
try {
|
||||
$this->assertFalse($driver->userRemove($john));
|
||||
} finally {
|
||||
$this->dbMock->userRemove->times(2)->calledWith($john);
|
||||
\Phake::verify(Arsse::$db, \Phake::times(2))->userRemove($john);
|
||||
}
|
||||
}
|
||||
|
||||
public function testSetAPassword(): void {
|
||||
$john = "john.doe@example.com";
|
||||
$this->dbMock->userExists->returns(true);
|
||||
$this->assertSame("superman", $this->prepTest()->userPasswordSet($john, "superman"));
|
||||
$this->assertSame(null, $this->prepTest()->userPasswordSet($john, null));
|
||||
$this->dbMock->userPasswordSet->never()->called();
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
|
||||
$this->assertSame("superman", $this->d->userPasswordSet($john, "superman"));
|
||||
$this->assertSame(null, $this->d->userPasswordSet($john, null));
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->userPasswordSet(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function testSetAPasswordForAMssingUser(): void {
|
||||
$this->dbMock->userExists->returns(false);
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
|
||||
$this->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||
$this->prepTest()->userPasswordSet("john.doe@example.com", "secret");
|
||||
$this->d->userPasswordSet("john.doe@example.com", "secret");
|
||||
}
|
||||
|
||||
public function testUnsetAPassword(): void {
|
||||
$this->dbMock->userExists->returns(true);
|
||||
$this->assertTrue($this->prepTest()->userPasswordUnset("john.doe@example.com"));
|
||||
$this->dbMock->userPasswordSet->never()->called();
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
|
||||
$this->assertTrue($this->d->userPasswordUnset("john.doe@example.com"));
|
||||
\Phake::verify(Arsse::$db, \Phake::never())->userPasswordSet(\Phake::anyParameters());
|
||||
}
|
||||
|
||||
public function testUnsetAPasswordForAMssingUser(): void {
|
||||
$this->dbMock->userExists->returns(false);
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
|
||||
$this->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||
$this->prepTest()->userPasswordUnset("john.doe@example.com");
|
||||
$this->d->userPasswordUnset("john.doe@example.com");
|
||||
}
|
||||
|
||||
public function testGetUserProperties(): void {
|
||||
$this->dbMock->userExists->returns(true);
|
||||
$this->assertSame([], $this->prepTest()->userPropertiesGet("john.doe@example.com"));
|
||||
$this->dbMock->userExists->calledWith("john.doe@example.com");
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
|
||||
$this->assertSame([], $this->d->userPropertiesGet("john.doe@example.com"));
|
||||
\Phake::verify(Arsse::$db)->userExists("john.doe@example.com");
|
||||
}
|
||||
|
||||
public function testGetPropertiesForAMissingUser(): void {
|
||||
$this->dbMock->userExists->returns(false);
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
|
||||
$this->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||
try {
|
||||
$this->prepTest()->userPropertiesGet("john.doe@example.com");
|
||||
$this->d->userPropertiesGet("john.doe@example.com");
|
||||
} finally {
|
||||
$this->dbMock->userExists->calledWith("john.doe@example.com");
|
||||
\Phake::verify(Arsse::$db)->userExists("john.doe@example.com");
|
||||
}
|
||||
}
|
||||
|
||||
public function testSetUserProperties(): void {
|
||||
$in = ['admin' => true];
|
||||
$this->dbMock->userExists->returns(true);
|
||||
$this->assertSame($in, $this->prepTest()->userPropertiesSet("john.doe@example.com", $in));
|
||||
$this->dbMock->userExists->calledWith("john.doe@example.com");
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
|
||||
$this->assertSame($in, $this->d->userPropertiesSet("john.doe@example.com", $in));
|
||||
\Phake::verify(Arsse::$db)->userExists("john.doe@example.com");
|
||||
}
|
||||
|
||||
public function testSetPropertiesForAMissingUser(): void {
|
||||
$this->dbMock->userExists->returns(false);
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
|
||||
$this->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||
try {
|
||||
$this->prepTest()->userPropertiesSet("john.doe@example.com", ['admin' => true]);
|
||||
$this->d->userPropertiesSet("john.doe@example.com", ['admin' => true]);
|
||||
} finally {
|
||||
$this->dbMock->userExists->calledWith("john.doe@example.com");
|
||||
\Phake::verify(Arsse::$db)->userExists("john.doe@example.com");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace JKingWeb\Arsse\TestCase\User;
|
||||
|
||||
use Eloquent\Phony\Phpunit\Phony;
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Database;
|
||||
use JKingWeb\Arsse\User;
|
||||
|
|
|
@ -7,8 +7,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace JKingWeb\Arsse\Test;
|
||||
|
||||
use Eloquent\Phony\Mock\Handle\InstanceHandle;
|
||||
use Eloquent\Phony\Phpunit\Phony;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use JKingWeb\Arsse\Exception;
|
||||
|
@ -372,20 +370,12 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
/** Guzzle's exception classes require some fairly complicated construction; this abstracts it all away so that only message and code need be supplied */
|
||||
protected function mockGuzzleException(string $class, ?string $message = null, ?int $code = null, ?\Throwable $e = null): GuzzleException {
|
||||
if (is_a($class, RequestException::class, true)) {
|
||||
$req = $this->mock(RequestInterface::class);
|
||||
$res = $this->mock(ResponseInterface::class);
|
||||
$res->getStatusCode->returns($code ?? 0);
|
||||
return new $class($message ?? "", $req->get(), $res->get(), $e);
|
||||
$req = \Phake::mock(RequestInterface::class);
|
||||
$res = \Phake::mock(ResponseInterface::class);
|
||||
\Phake::when($res)->getStatusCode->thenReturn($code ?? 0);
|
||||
return new $class($message ?? "", $req, $res, $e);
|
||||
} else {
|
||||
return new $class($message ?? "", $code ?? 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
protected function mock(string $class): InstanceHandle {
|
||||
return Phony::mock($class);
|
||||
}
|
||||
|
||||
protected function partialMock(string $class, ...$argument): InstanceHandle {
|
||||
return Phony::partialMock($class, $argument);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,11 +38,10 @@ trait Setup {
|
|||
// set up a file without read access
|
||||
chmod($this->path."ru.php", 0000);
|
||||
// make the test Lang class use the vfs files
|
||||
$this->l = $this->partialMock(Lang::class, $this->path);
|
||||
$this->l->globFiles->does(function(string $path): array {
|
||||
$this->l = \Phake::partialMock(Lang::class, $this->path);
|
||||
\Phake::when($this->l)->globFiles->thenReturnCallback(function(string $path): array {
|
||||
return Glob::glob($this->path."*.php");
|
||||
});
|
||||
$this->l = $this->l->get();
|
||||
self::clearData(false);
|
||||
Arsse::$lang = $this->l;
|
||||
// call the additional setup method if it exists
|
||||
|
|
4
vendor-bin/daux/composer.lock
generated
4
vendor-bin/daux/composer.lock
generated
|
@ -1405,8 +1405,8 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
"clue/arguments": "^2.0",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"webmozart/glob": "^4.1",
|
||||
"eloquent/phony-phpunit": "^6.0 || ^7.0",
|
||||
"phake/phake": "^4.4 | ^3.1.9"
|
||||
}
|
||||
}
|
||||
|
|
151
vendor-bin/phpunit/composer.lock
generated
151
vendor-bin/phpunit/composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "7f36badf6779ffc9f136290679dc0855",
|
||||
"content-hash": "428806f4a006a89c0f7044ca6a635eaa",
|
||||
"packages": [],
|
||||
"packages-dev": [
|
||||
{
|
||||
|
@ -189,155 +189,6 @@
|
|||
],
|
||||
"time": "2022-12-30T00:15:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "eloquent/phony",
|
||||
"version": "5.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eloquent/phony.git",
|
||||
"reference": "f34d67d6db6b6f351ea7e8aa8066107e756ec26b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/eloquent/phony/zipball/f34d67d6db6b6f351ea7e8aa8066107e756ec26b",
|
||||
"reference": "f34d67d6db6b6f351ea7e8aa8066107e756ec26b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3 || ^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"eloquent/code-style": "^1.0",
|
||||
"eloquent/phpstan-phony": "^0.7",
|
||||
"errors/exceptions": "^0.2",
|
||||
"ext-pdo": "*",
|
||||
"friendsofphp/php-cs-fixer": "^2",
|
||||
"hamcrest/hamcrest-php": "^2",
|
||||
"phpstan/extension-installer": "^1",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpstan/phpstan-phpunit": "^0.12",
|
||||
"phpunit/phpunit": "^9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/initialize.php",
|
||||
"src/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Eloquent\\Phony\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Erin Millard",
|
||||
"email": "ezzatron@gmail.com",
|
||||
"homepage": "http://ezzatron.com/"
|
||||
}
|
||||
],
|
||||
"description": "Mocks, stubs, and spies for PHP.",
|
||||
"homepage": "http://eloquent-software.com/phony/",
|
||||
"keywords": [
|
||||
"Double",
|
||||
"Dummy",
|
||||
"fake",
|
||||
"mock",
|
||||
"mocking",
|
||||
"spy",
|
||||
"stub",
|
||||
"stubbing",
|
||||
"test"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/eloquent/phony/issues",
|
||||
"source": "https://github.com/eloquent/phony/tree/5.0.2"
|
||||
},
|
||||
"abandoned": true,
|
||||
"time": "2021-02-17T01:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "eloquent/phony-phpunit",
|
||||
"version": "7.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eloquent/phony-phpunit.git",
|
||||
"reference": "e77ff95ea6235211d4aae7e5f53488a5faebc2e0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/eloquent/phony-phpunit/zipball/e77ff95ea6235211d4aae7e5f53488a5faebc2e0",
|
||||
"reference": "e77ff95ea6235211d4aae7e5f53488a5faebc2e0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"eloquent/phony": "^5",
|
||||
"php": "^7.3 || ^8",
|
||||
"phpunit/phpunit": "^9"
|
||||
},
|
||||
"require-dev": {
|
||||
"eloquent/code-style": "^1",
|
||||
"eloquent/phpstan-phony": "^0.7",
|
||||
"errors/exceptions": "^0.2",
|
||||
"friendsofphp/php-cs-fixer": "^2",
|
||||
"phpstan/extension-installer": "^1",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpstan/phpstan-phpunit": "^0.12"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "7.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/initialize.php",
|
||||
"src/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Eloquent\\Phony\\Phpunit\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Erin Millard",
|
||||
"email": "ezzatron@gmail.com",
|
||||
"homepage": "http://ezzatron.com/"
|
||||
}
|
||||
],
|
||||
"description": "Phony for PHPUnit.",
|
||||
"homepage": "http://eloquent-software.com/phony/",
|
||||
"keywords": [
|
||||
"Double",
|
||||
"Dummy",
|
||||
"fake",
|
||||
"mock",
|
||||
"mocking",
|
||||
"spy",
|
||||
"stub",
|
||||
"stubbing",
|
||||
"test"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/eloquent/phony-phpunit/issues",
|
||||
"source": "https://github.com/eloquent/phony-phpunit/tree/7.1.0"
|
||||
},
|
||||
"abandoned": true,
|
||||
"time": "2020-12-21T09:36:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mikey179/vfsstream",
|
||||
"version": "v1.6.12",
|
||||
|
|
Loading…
Reference in a new issue