1
1
Fork 0
mirror of https://code.mensbeam.com/MensBeam/Arsse.git synced 2024-12-22 21:22:40 +00:00

Convert NCNv1 tests to PHony

This commit is contained in:
J. King 2021-03-01 10:03:52 -05:00
parent 95812b8ba3
commit 75148bfbc6

View file

@ -23,6 +23,7 @@ use Laminas\Diactoros\Response\EmptyResponse;
class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest { class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
protected $h; protected $h;
protected $transaction; protected $transaction;
protected $userId;
protected $feeds = [ // expected sample output of a feed list from the database, and the resultant expected transformation by the REST handler protected $feeds = [ // expected sample output of a feed list from the database, and the resultant expected transformation by the REST handler
'db' => [ 'db' => [
[ [
@ -299,6 +300,10 @@ 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 { 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"; $prefix = "/index.php/apps/news/api/v1-2";
$url = $prefix.$target; $url = $prefix.$target;
if ($body) { if ($body) {
@ -315,13 +320,13 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
parent::setUp(); parent::setUp();
self::setConf(); self::setConf();
// create a mock user manager // create a mock user manager
Arsse::$user = \Phake::mock(User::class); $this->userId = "john.doe@example.com";
Arsse::$user->id = "john.doe@example.com"; $this->userMock = $this->mock(User::class);
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['admin' => true]); $this->userMock->auth->returns(true);
$this->userMock->propertiesGet->returns(['admin' => true]);
// create a mock database interface // create a mock database interface
Arsse::$db = \Phake::mock(Database::class); $this->dbMock = $this->mock(Database::class);
$this->transaction = \Phake::mock(Transaction::class); $this->dbMock->begin->returns($this->mock(Transaction::class));
\Phake::when(Arsse::$db)->begin->thenReturn($this->transaction);
//initialize a handler //initialize a handler
$this->h = new V1_2(); $this->h = new V1_2();
} }
@ -402,7 +407,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
['id' => 1, 'name' => "Software"], ['id' => 1, 'name' => "Software"],
['id' => 12, 'name' => "Hardware"], ['id' => 12, 'name' => "Hardware"],
]; ];
\Phake::when(Arsse::$db)->folderList(Arsse::$user->id, null, false)->thenReturn(new Result($this->v($list))); $this->dbMock->folderList->with($this->userId, null, false)->returns(new Result($this->v($list)));
$exp = new Response(['folders' => $out]); $exp = new Response(['folders' => $out]);
$this->assertMessage($exp, $this->req("GET", "/folders")); $this->assertMessage($exp, $this->req("GET", "/folders"));
} }
@ -410,18 +415,18 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideFolderCreations */ /** @dataProvider provideFolderCreations */
public function testAddAFolder(array $input, bool $body, $output, ResponseInterface $exp): void { public function testAddAFolder(array $input, bool $body, $output, ResponseInterface $exp): void {
if ($output instanceof ExceptionInput) { if ($output instanceof ExceptionInput) {
\Phake::when(Arsse::$db)->folderAdd->thenThrow($output); $this->dbMock->folderAdd->throws($output);
} else { } else {
\Phake::when(Arsse::$db)->folderAdd->thenReturn($output); $this->dbMock->folderAdd->returns($output);
\Phake::when(Arsse::$db)->folderPropertiesGet->thenReturn($this->v(['id' => $output, 'name' => $input['name'], 'parent' => null])); $this->dbMock->folderPropertiesGet->returns($this->v(['id' => $output, 'name' => $input['name'], 'parent' => null]));
} }
$act = $this->req("POST", "/folders", $input, [], true, $body); $act = $this->req("POST", "/folders", $input, [], true, $body);
$this->assertMessage($exp, $act); $this->assertMessage($exp, $act);
\Phake::verify(Arsse::$db)->folderAdd(Arsse::$user->id, $input); $this->dbMock->folderAdd->calledWith($this->userId, $input);
if ($output instanceof ExceptionInput) { if ($output instanceof ExceptionInput) {
\Phake::verify(Arsse::$db, \Phake::times(0))->folderPropertiesGet; $this->dbMock->folderPropertiesGet->never()->called();
} else { } else {
\Phake::verify(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, $output); $this->dbMock->folderPropertiesGet->calledWith($this->userId, $this->equalTo($output));
} }
} }
@ -439,25 +444,25 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testRemoveAFolder(): void { public function testRemoveAFolder(): void {
\Phake::when(Arsse::$db)->folderRemove(Arsse::$user->id, 1)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing")); $this->dbMock->folderRemove->with($this->userId, 1)->returns(true)->throws(new ExceptionInput("subjectMissing"));
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("DELETE", "/folders/1")); $this->assertMessage($exp, $this->req("DELETE", "/folders/1"));
// fail on the second invocation because it no longer exists // fail on the second invocation because it no longer exists
$exp = new EmptyResponse(404); $exp = new EmptyResponse(404);
$this->assertMessage($exp, $this->req("DELETE", "/folders/1")); $this->assertMessage($exp, $this->req("DELETE", "/folders/1"));
\Phake::verify(Arsse::$db, \Phake::times(2))->folderRemove(Arsse::$user->id, 1); $this->dbMock->folderRemove->times(2)->calledWith($this->userId, 1);
} }
/** @dataProvider provideFolderRenamings */ /** @dataProvider provideFolderRenamings */
public function testRenameAFolder(array $input, int $id, $output, ResponseInterface $exp): void { public function testRenameAFolder(array $input, int $id, $output, ResponseInterface $exp): void {
if ($output instanceof ExceptionInput) { if ($output instanceof ExceptionInput) {
\Phake::when(Arsse::$db)->folderPropertiesSet->thenThrow($output); $this->dbMock->folderPropertiesSet->throws($output);
} else { } else {
\Phake::when(Arsse::$db)->folderPropertiesSet->thenReturn($output); $this->dbMock->folderPropertiesSet->returns($output);
} }
$act = $this->req("PUT", "/folders/$id", $input); $act = $this->req("PUT", "/folders/$id", $input);
$this->assertMessage($exp, $act); $this->assertMessage($exp, $act);
\Phake::verify(Arsse::$db)->folderPropertiesSet(Arsse::$user->id, $id, $input); $this->dbMock->folderPropertiesSet->calledWith($this->userId, $id, $input);
} }
public function provideFolderRenamings(): array { public function provideFolderRenamings(): array {
@ -489,9 +494,9 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
'starredCount' => 5, 'starredCount' => 5,
'newestItemId' => 4758915, 'newestItemId' => 4758915,
]; ];
\Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result([]))->thenReturn(new Result($this->v($this->feeds['db']))); $this->dbMock->subscriptionList->with($this->userId)->returns(new Result([]))->returns(new Result($this->v($this->feeds['db'])));
\Phake::when(Arsse::$db)->articleStarred(Arsse::$user->id)->thenReturn($this->v(['total' => 0]))->thenReturn($this->v(['total' => 5])); $this->dbMock->articleStarred->with($this->userId)->returns($this->v(['total' => 0]))->returns($this->v(['total' => 5]));
\Phake::when(Arsse::$db)->editionLatest(Arsse::$user->id)->thenReturn(0)->thenReturn(4758915); $this->dbMock->editionLatest->with($this->userId)->returns(0)->returns(4758915);
$exp = new Response($exp1); $exp = new Response($exp1);
$this->assertMessage($exp, $this->req("GET", "/feeds")); $this->assertMessage($exp, $this->req("GET", "/feeds"));
$exp = new Response($exp2); $exp = new Response($exp2);
@ -501,31 +506,31 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideNewSubscriptions */ /** @dataProvider provideNewSubscriptions */
public function testAddASubscription(array $input, $id, int $latestEdition, array $output, $moveOutcome, ResponseInterface $exp): void { public function testAddASubscription(array $input, $id, int $latestEdition, array $output, $moveOutcome, ResponseInterface $exp): void {
if ($id instanceof \Exception) { if ($id instanceof \Exception) {
\Phake::when(Arsse::$db)->subscriptionAdd->thenThrow($id); $this->dbMock->subscriptionAdd->throws($id);
} else { } else {
\Phake::when(Arsse::$db)->subscriptionAdd->thenReturn($id); $this->dbMock->subscriptionAdd->returns($id);
} }
if ($moveOutcome instanceof \Exception) { if ($moveOutcome instanceof \Exception) {
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenThrow($moveOutcome); $this->dbMock->subscriptionPropertiesSet->throws($moveOutcome);
} else { } else {
\Phake::when(Arsse::$db)->subscriptionPropertiesSet->thenReturn($moveOutcome); $this->dbMock->subscriptionPropertiesSet->returns($moveOutcome);
} }
\Phake::when(Arsse::$db)->subscriptionPropertiesGet->thenReturn($this->v($output)); $this->dbMock->subscriptionPropertiesGet->returns($this->v($output));
\Phake::when(Arsse::$db)->editionLatest->thenReturn($latestEdition); $this->dbMock->editionLatest->returns($latestEdition);
$act = $this->req("POST", "/feeds", $input); $act = $this->req("POST", "/feeds", $input);
$this->assertMessage($exp, $act); $this->assertMessage($exp, $act);
\Phake::verify(Arsse::$db)->subscriptionAdd(Arsse::$user->id, $input['url'] ?? ""); $this->dbMock->subscriptionAdd->calledWith($this->userId, $input['url'] ?? "");
if ($id instanceof \Exception) { if ($id instanceof \Exception) {
\Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesSet; $this->dbMock->subscriptionPropertiesSet->never()->called();
\Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesGet; $this->dbMock->subscriptionPropertiesGet->never()->called();
\Phake::verify(Arsse::$db, \Phake::times(0))->editionLatest; $this->dbMock->editionLatest->never()->called();
} else { } else {
\Phake::verify(Arsse::$db)->subscriptionPropertiesGet(Arsse::$user->id, $id); $this->dbMock->subscriptionPropertiesGet->calledWith($this->userId, $id);
\Phake::verify(Arsse::$db)->editionLatest(Arsse::$user->id, (new Context)->subscription($id)->hidden(false)); $this->dbMock->editionLatest->calledWith($this->userId, $this->equalTo((new Context)->subscription($id)->hidden(false)));
if ($input['folderId'] ?? 0) { if ($input['folderId'] ?? 0) {
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, $id, ['folder' => (int) $input['folderId']]); $this->dbMock->subscriptionPropertiesSet->calledWith($this->userId, $id, ['folder' => (int) $input['folderId']]);
} else { } else {
\Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesSet; $this->dbMock->subscriptionPropertiesSet->never()->called();
} }
} }
} }
@ -543,13 +548,13 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testRemoveASubscription(): void { public function testRemoveASubscription(): void {
\Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 1)->thenReturn(true)->thenThrow(new ExceptionInput("subjectMissing")); $this->dbMock->subscriptionRemove->with($this->userId, 1)->returns(true)->throws(new ExceptionInput("subjectMissing"));
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("DELETE", "/feeds/1")); $this->assertMessage($exp, $this->req("DELETE", "/feeds/1"));
// fail on the second invocation because it no longer exists // fail on the second invocation because it no longer exists
$exp = new EmptyResponse(404); $exp = new EmptyResponse(404);
$this->assertMessage($exp, $this->req("DELETE", "/feeds/1")); $this->assertMessage($exp, $this->req("DELETE", "/feeds/1"));
\Phake::verify(Arsse::$db, \Phake::times(2))->subscriptionRemove(Arsse::$user->id, 1); $this->dbMock->subscriptionRemove->times(2)->calledWith($this->userId, 1);
} }
public function testMoveASubscription(): void { public function testMoveASubscription(): void {
@ -561,11 +566,11 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
['folderId' => -1], ['folderId' => -1],
[], [],
]; ];
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => 42])->thenReturn(true); $this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, ['folder' => 42])->returns(true);
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => null])->thenReturn(true); $this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, ['folder' => null])->returns(true);
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => 2112])->thenThrow(new ExceptionInput("idMissing")); // folder does not exist $this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, ['folder' => 2112])->throws(new ExceptionInput("idMissing")); // folder does not exist
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, ['folder' => -1])->thenThrow(new ExceptionInput("typeViolation")); // folder is invalid $this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, ['folder' => -1])->throws(new ExceptionInput("typeViolation")); // folder is invalid
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 42, $this->anything())->thenThrow(new ExceptionInput("subjectMissing")); // subscription does not exist $this->dbMock->subscriptionPropertiesSet->with($this->userId, 42, $this->anything())->throws(new ExceptionInput("subjectMissing")); // subscription does not exist
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/move", json_encode($in[0]))); $this->assertMessage($exp, $this->req("PUT", "/feeds/1/move", json_encode($in[0])));
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
@ -590,12 +595,12 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
['feedTitle' => "Feed does not exist"], ['feedTitle' => "Feed does not exist"],
[], [],
]; ];
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => null]))->thenReturn(true); $this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, $this->identicalTo(['title' => null]))->returns(true);
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => "Ook"]))->thenReturn(true); $this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, $this->identicalTo(['title' => "Ook"]))->returns(true);
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => " "]))->thenThrow(new ExceptionInput("whitespace")); $this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, $this->identicalTo(['title' => " "]))->throws(new ExceptionInput("whitespace"));
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => ""]))->thenThrow(new ExceptionInput("missing")); $this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, $this->identicalTo(['title' => ""]))->throws(new ExceptionInput("missing"));
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 1, $this->identicalTo(['title' => false]))->thenThrow(new ExceptionInput("missing")); $this->dbMock->subscriptionPropertiesSet->with($this->userId, 1, $this->identicalTo(['title' => false]))->throws(new ExceptionInput("missing"));
\Phake::when(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, 42, $this->anything())->thenThrow(new ExceptionInput("subjectMissing")); $this->dbMock->subscriptionPropertiesSet->with($this->userId, 42, $this->anything())->throws(new ExceptionInput("subjectMissing"));
$exp = new EmptyResponse(422); $exp = new EmptyResponse(422);
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/rename", json_encode($in[0]))); $this->assertMessage($exp, $this->req("PUT", "/feeds/1/rename", json_encode($in[0])));
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
@ -621,16 +626,16 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
'userId' => "", 'userId' => "",
], ],
]; ];
\Phake::when(Arsse::$db)->feedListStale->thenReturn($this->v(array_column($out, "id"))); $this->dbMock->feedListStale->returns($this->v(array_column($out, "id")));
$exp = new Response(['feeds' => $out]); $exp = new Response(['feeds' => $out]);
$this->assertMessage($exp, $this->req("GET", "/feeds/all")); $this->assertMessage($exp, $this->req("GET", "/feeds/all"));
} }
public function testListStaleFeedsWithoutAuthority(): void { public function testListStaleFeedsWithoutAuthority(): void {
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['admin' => false]); $this->userMock->propertiesGet->returns(['admin' => false]);
$exp = new EmptyResponse(403); $exp = new EmptyResponse(403);
$this->assertMessage($exp, $this->req("GET", "/feeds/all")); $this->assertMessage($exp, $this->req("GET", "/feeds/all"));
\Phake::verify(Arsse::$db, \Phake::times(0))->feedListStale; $this->dbMock->feedListStale->never()->called();
} }
public function testUpdateAFeed(): void { public function testUpdateAFeed(): void {
@ -641,9 +646,9 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
['feedId' => -1], // invalid ID ['feedId' => -1], // invalid ID
['feed' => 42], // invalid input ['feed' => 42], // invalid input
]; ];
\Phake::when(Arsse::$db)->feedUpdate(42)->thenReturn(true); $this->dbMock->feedUpdate->with(42)->returns(true);
\Phake::when(Arsse::$db)->feedUpdate(2112)->thenThrow(new ExceptionInput("subjectMissing")); $this->dbMock->feedUpdate->with(2112)->throws(new ExceptionInput("subjectMissing"));
\Phake::when(Arsse::$db)->feedUpdate($this->lessThan(1))->thenThrow(new ExceptionInput("typeViolation")); $this->dbMock->feedUpdate->with($this->lessThan(1))->throws(new ExceptionInput("typeViolation"));
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("GET", "/feeds/update", json_encode($in[0]))); $this->assertMessage($exp, $this->req("GET", "/feeds/update", json_encode($in[0])));
$exp = new EmptyResponse(404); $exp = new EmptyResponse(404);
@ -655,23 +660,23 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testUpdateAFeedWithoutAuthority(): void { public function testUpdateAFeedWithoutAuthority(): void {
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['admin' => false]); $this->userMock->propertiesGet->returns(['admin' => false]);
$exp = new EmptyResponse(403); $exp = new EmptyResponse(403);
$this->assertMessage($exp, $this->req("GET", "/feeds/update", ['feedId' => 42])); $this->assertMessage($exp, $this->req("GET", "/feeds/update", ['feedId' => 42]));
\Phake::verify(Arsse::$db, \Phake::times(0))->feedUpdate; $this->dbMock->feedUpdate->never()->called();
} }
/** @dataProvider provideArticleQueries */ /** @dataProvider provideArticleQueries */
public function testListArticles(string $url, array $in, Context $c, $out, ResponseInterface $exp): void { public function testListArticles(string $url, array $in, Context $c, $out, ResponseInterface $exp): void {
if ($out instanceof \Exception) { if ($out instanceof \Exception) {
\Phake::when(Arsse::$db)->articleList->thenThrow($out); $this->dbMock->articleList->throws($out);
} else { } else {
\Phake::when(Arsse::$db)->articleList->thenReturn($out); $this->dbMock->articleList->returns($out);
} }
$this->assertMessage($exp, $this->req("GET", $url, $in)); $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"]; $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"; $order = ($in['oldestFirst'] ?? false) ? "edition" : "edition desc";
\Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, $c, $columns, [$order]); $this->dbMock->articleList->calledWith($this->userId, $this->equalTo($c), $columns, [$order]);
} }
public function provideArticleQueries(): iterable { public function provideArticleQueries(): iterable {
@ -713,8 +718,8 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
public function testMarkAFolderRead(): void { public function testMarkAFolderRead(): void {
$read = ['read' => true]; $read = ['read' => true];
$in = json_encode(['newestItemId' => 2112]); $in = json_encode(['newestItemId' => 2112]);
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->folder(1)->latestEdition(2112)->hidden(false))->thenReturn(42); $this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->folder(1)->latestEdition(2112)->hidden(false)))->returns(42);
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->folder(42)->latestEdition(2112)->hidden(false))->thenThrow(new ExceptionInput("idMissing")); // folder doesn't exist $this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->folder(42)->latestEdition(2112)->hidden(false)))->throws(new ExceptionInput("idMissing")); // folder doesn't exist
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/folders/1/read", $in)); $this->assertMessage($exp, $this->req("PUT", "/folders/1/read", $in));
$this->assertMessage($exp, $this->req("PUT", "/folders/1/read?newestItemId=2112")); $this->assertMessage($exp, $this->req("PUT", "/folders/1/read?newestItemId=2112"));
@ -728,8 +733,8 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
public function testMarkASubscriptionRead(): void { public function testMarkASubscriptionRead(): void {
$read = ['read' => true]; $read = ['read' => true];
$in = json_encode(['newestItemId' => 2112]); $in = json_encode(['newestItemId' => 2112]);
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->subscription(1)->latestEdition(2112)->hidden(false))->thenReturn(42); $this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->subscription(1)->latestEdition(2112)->hidden(false)))->returns(42);
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->subscription(42)->latestEdition(2112)->hidden(false))->thenThrow(new ExceptionInput("idMissing")); // subscription doesn't exist $this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->subscription(42)->latestEdition(2112)->hidden(false)))->throws(new ExceptionInput("idMissing")); // subscription doesn't exist
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/read", $in)); $this->assertMessage($exp, $this->req("PUT", "/feeds/1/read", $in));
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/read?newestItemId=2112")); $this->assertMessage($exp, $this->req("PUT", "/feeds/1/read?newestItemId=2112"));
@ -743,7 +748,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
public function testMarkAllItemsRead(): void { public function testMarkAllItemsRead(): void {
$read = ['read' => true]; $read = ['read' => true];
$in = json_encode(['newestItemId' => 2112]); $in = json_encode(['newestItemId' => 2112]);
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->latestEdition(2112))->thenReturn(42); $this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->latestEdition(2112)))->returns(42);
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/items/read", $in)); $this->assertMessage($exp, $this->req("PUT", "/items/read", $in));
$this->assertMessage($exp, $this->req("PUT", "/items/read?newestItemId=2112")); $this->assertMessage($exp, $this->req("PUT", "/items/read?newestItemId=2112"));
@ -757,14 +762,14 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$unread = ['read' => false]; $unread = ['read' => false];
$star = ['starred' => true]; $star = ['starred' => true];
$unstar = ['starred' => false]; $unstar = ['starred' => false];
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->edition(1))->thenReturn(42); $this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->edition(1)))->returns(42);
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->edition(42))->thenThrow(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist $this->dbMock->articleMark->with($this->userId, $read, $this->equalTo((new Context)->edition(42)))->throws(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unread, (new Context)->edition(2))->thenReturn(42); $this->dbMock->articleMark->with($this->userId, $unread, $this->equalTo((new Context)->edition(2)))->returns(42);
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unread, (new Context)->edition(47))->thenThrow(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist $this->dbMock->articleMark->with($this->userId, $unread, $this->equalTo((new Context)->edition(47)))->throws(new ExceptionInput("subjectMissing")); // edition doesn't exist doesn't exist
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $star, (new Context)->article(3))->thenReturn(42); $this->dbMock->articleMark->with($this->userId, $star, $this->equalTo((new Context)->article(3)))->returns(42);
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $star, (new Context)->article(2112))->thenThrow(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist $this->dbMock->articleMark->with($this->userId, $star, $this->equalTo((new Context)->article(2112)))->throws(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unstar, (new Context)->article(4))->thenReturn(42); $this->dbMock->articleMark->with($this->userId, $unstar, $this->equalTo((new Context)->article(4)))->returns(42);
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $unstar, (new Context)->article(1337))->thenThrow(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist $this->dbMock->articleMark->with($this->userId, $unstar, $this->equalTo((new Context)->article(1337)))->throws(new ExceptionInput("subjectMissing")); // article doesn't exist doesn't exist
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/items/1/read")); $this->assertMessage($exp, $this->req("PUT", "/items/1/read"));
$this->assertMessage($exp, $this->req("PUT", "/items/2/unread")); $this->assertMessage($exp, $this->req("PUT", "/items/2/unread"));
@ -775,7 +780,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/47/unread"));
$this->assertMessage($exp, $this->req("PUT", "/items/1/2112/star")); $this->assertMessage($exp, $this->req("PUT", "/items/1/2112/star"));
$this->assertMessage($exp, $this->req("PUT", "/items/4400/1337/unstar")); $this->assertMessage($exp, $this->req("PUT", "/items/4400/1337/unstar"));
\Phake::verify(Arsse::$db, \Phake::times(8))->articleMark(Arsse::$user->id, $this->anything(), $this->anything()); $this->dbMock->articleMark->times(8)->calledWith($this->userId, $this->anything(), $this->anything());
} }
public function testChangeMarksOfMultipleArticles(): void { public function testChangeMarksOfMultipleArticles(): void {
@ -793,9 +798,9 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$inStar[$a][$b] = ['feedId' => 2112, 'guidHash' => $inStar[$a][$b]]; $inStar[$a][$b] = ['feedId' => 2112, 'guidHash' => $inStar[$a][$b]];
} }
} }
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), $this->anything())->thenReturn(42); $this->dbMock->articleMark->with($this->userId, $this->anything(), $this->anything())->returns(42);
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->editions([]))->thenThrow(new ExceptionInput("tooShort")); // data model function requires one valid integer for multiples $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
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->articles([]))->thenThrow(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
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("PUT", "/items/read/multiple")); $this->assertMessage($exp, $this->req("PUT", "/items/read/multiple"));
$this->assertMessage($exp, $this->req("PUT", "/items/unread/multiple")); $this->assertMessage($exp, $this->req("PUT", "/items/unread/multiple"));
@ -818,27 +823,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/star/multiple", json_encode(['items' => $inStar[1]])));
$this->assertMessage($exp, $this->req("PUT", "/items/unstar/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 // ensure the data model was queried appropriately for read/unread
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $read, (new Context)->editions([])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $read, $this->equalTo((new Context)->editions([])));
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $read, (new Context)->editions($in[0])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $read, $this->equalTo((new Context)->editions($in[0])));
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $read, (new Context)->editions($in[1])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $read, $this->equalTo((new Context)->editions($in[1])));
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unread, (new Context)->editions([])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unread, $this->equalTo((new Context)->editions([])));
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unread, (new Context)->editions($in[0])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unread, $this->equalTo((new Context)->editions($in[0])));
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unread, (new Context)->editions($in[1])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unread, $this->equalTo((new Context)->editions($in[1])));
// ensure the data model was queried appropriately for star/unstar // ensure the data model was queried appropriately for star/unstar
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $star, (new Context)->articles([])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $star, $this->equalTo((new Context)->articles([])));
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $star, (new Context)->articles($in[0])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $star, $this->equalTo((new Context)->articles($in[0])));
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $star, (new Context)->articles($in[1])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $star, $this->equalTo((new Context)->articles($in[1])));
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (new Context)->articles([])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unstar, $this->equalTo((new Context)->articles([])));
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (new Context)->articles($in[0])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unstar, $this->equalTo((new Context)->articles($in[0])));
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (new Context)->articles($in[1])); $this->dbMock->articleMark->atLeast(1)->calledWith($this->userId, $unstar, $this->equalTo((new Context)->articles($in[1])));
} }
public function testQueryTheServerStatus(): void { public function testQueryTheServerStatus(): void {
$interval = Arsse::$conf->serviceFrequency; $interval = Arsse::$conf->serviceFrequency;
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval); $valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
$invalid = $valid->sub($interval)->sub($interval); $invalid = $valid->sub($interval)->sub($interval);
\Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"))->thenReturn(Date::transform($invalid, "sql")); $this->dbMock->metaGet->with("service_last_checkin")->returns(Date::transform($valid, "sql"))->returns(Date::transform($invalid, "sql"));
\Phake::when(Arsse::$db)->driverCharsetAcceptable->thenReturn(true)->thenReturn(false); $this->dbMock->driverCharsetAcceptable->returns(true)->returns(false);
$arr1 = $arr2 = [ $arr1 = $arr2 = [
'version' => V1_2::VERSION, 'version' => V1_2::VERSION,
'arsse_version' => Arsse::VERSION, 'arsse_version' => Arsse::VERSION,
@ -854,38 +859,38 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
} }
public function testCleanUpBeforeUpdate(): void { public function testCleanUpBeforeUpdate(): void {
\Phake::when(Arsse::$db)->feedCleanup()->thenReturn(true); $this->dbMock->feedCleanup->with()->returns(true);
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("GET", "/cleanup/before-update")); $this->assertMessage($exp, $this->req("GET", "/cleanup/before-update"));
\Phake::verify(Arsse::$db)->feedCleanup(); $this->dbMock->feedCleanup->calledWith();
} }
public function testCleanUpBeforeUpdateWithoutAuthority(): void { public function testCleanUpBeforeUpdateWithoutAuthority(): void {
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['admin' => false]); $this->userMock->propertiesGet->returns(['admin' => false]);
$exp = new EmptyResponse(403); $exp = new EmptyResponse(403);
$this->assertMessage($exp, $this->req("GET", "/cleanup/before-update")); $this->assertMessage($exp, $this->req("GET", "/cleanup/before-update"));
\Phake::verify(Arsse::$db, \Phake::times(0))->feedCleanup; $this->dbMock->feedCleanup->never()->called();
} }
public function testCleanUpAfterUpdate(): void { public function testCleanUpAfterUpdate(): void {
\Phake::when(Arsse::$db)->articleCleanup()->thenReturn(true); $this->dbMock->articleCleanup->with()->returns(true);
$exp = new EmptyResponse(204); $exp = new EmptyResponse(204);
$this->assertMessage($exp, $this->req("GET", "/cleanup/after-update")); $this->assertMessage($exp, $this->req("GET", "/cleanup/after-update"));
\Phake::verify(Arsse::$db)->articleCleanup(); $this->dbMock->articleCleanup->calledWith();
} }
public function testCleanUpAfterUpdateWithoutAuthority(): void { public function testCleanUpAfterUpdateWithoutAuthority(): void {
\Phake::when(Arsse::$user)->propertiesGet->thenReturn(['admin' => false]); $this->userMock->propertiesGet->returns(['admin' => false]);
$exp = new EmptyResponse(403); $exp = new EmptyResponse(403);
$this->assertMessage($exp, $this->req("GET", "/cleanup/after-update")); $this->assertMessage($exp, $this->req("GET", "/cleanup/after-update"));
\Phake::verify(Arsse::$db, \Phake::times(0))->feedCleanup; $this->dbMock->feedCleanup->never()->called();
} }
public function testQueryTheUserStatus(): void { public function testQueryTheUserStatus(): void {
$act = $this->req("GET", "/user"); $act = $this->req("GET", "/user");
$exp = new Response([ $exp = new Response([
'userId' => Arsse::$user->id, 'userId' => $this->userId,
'displayName' => Arsse::$user->id, 'displayName' => $this->userId,
'lastLoginTimestamp' => $this->approximateTime($act->getPayload()['lastLoginTimestamp'], new \DateTimeImmutable), 'lastLoginTimestamp' => $this->approximateTime($act->getPayload()['lastLoginTimestamp'], new \DateTimeImmutable),
'avatar' => null, 'avatar' => null,
]); ]);
@ -897,10 +902,10 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$url = "/folders?name=Hardware"; $url = "/folders?name=Hardware";
$out1 = ['id' => 1, 'name' => "Software"]; $out1 = ['id' => 1, 'name' => "Software"];
$out2 = ['id' => 2, 'name' => "Hardware"]; $out2 = ['id' => 2, 'name' => "Hardware"];
\Phake::when(Arsse::$db)->folderAdd($this->anything(), $this->anything())->thenReturn(2); $this->dbMock->folderAdd->with($this->anything(), $this->anything())->returns(2);
\Phake::when(Arsse::$db)->folderAdd($this->anything(), $in)->thenReturn(1); $this->dbMock->folderAdd->with($this->anything(), $in)->returns(1);
\Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 1)->thenReturn($this->v($out1)); $this->dbMock->folderPropertiesGet->with($this->userId, 1)->returns($this->v($out1));
\Phake::when(Arsse::$db)->folderPropertiesGet(Arsse::$user->id, 2)->thenReturn($this->v($out2)); $this->dbMock->folderPropertiesGet->with($this->userId, 2)->returns($this->v($out2));
$exp = new Response(['folders' => [$out1]]); $exp = new Response(['folders' => [$out1]]);
$this->assertMessage($exp, $this->req("POST", "/folders?name=Hardware", json_encode($in))); $this->assertMessage($exp, $this->req("POST", "/folders?name=Hardware", json_encode($in)));
} }
@ -908,8 +913,8 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
public function testMeldJsonAndQueryParameters(): void { public function testMeldJsonAndQueryParameters(): void {
$in = ['oldestFirst' => true]; $in = ['oldestFirst' => true];
$url = "/items?type=2"; $url = "/items?type=2";
\Phake::when(Arsse::$db)->articleList->thenReturn(new Result([])); $this->dbMock->articleList->returns(new Result([]));
$this->req("GET", $url, json_encode($in)); $this->req("GET", $url, json_encode($in));
\Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true)->hidden(false), $this->anything(), ["edition"]); $this->dbMock->articleList->calledWith($this->userId, $this->equalTo((new Context)->starred(true)->hidden(false)), $this->anything(), ["edition"]);
} }
} }